diff --git a/scripts/snippets/diagnostics.py b/scripts/snippets/diagnostics.py index 1baf73c18..e75284d53 100644 --- a/scripts/snippets/diagnostics.py +++ b/scripts/snippets/diagnostics.py @@ -3,6 +3,8 @@ from pathlib import Path from .model import ( + ConditionStructureIssue, + ConditionStructureRule, Diagnostic, IfVersionAttributeIssue, IfVersionAttributeRule, @@ -41,6 +43,13 @@ IfVersionAttributeRule.UNREGISTERED_REPOSITORY: "SNIP022", IfVersionAttributeRule.INVALID_PULL_REQUEST: "SNIP023", } +IF_VERSION_STRUCTURE_CODES = { + ConditionStructureRule.UNEXPECTED_CLOSE: "SNIP012", + ConditionStructureRule.ELSE_NOT_DIRECT_CHILD: "SNIP025", + ConditionStructureRule.UNCLOSED_TAG: "SNIP026", + ConditionStructureRule.MULTIPLE_ELSE: "SNIP029", + ConditionStructureRule.ELSE_NOT_FINAL: "SNIP030", +} def local_source_policy_diagnostic( @@ -119,3 +128,19 @@ def if_version_attribute_diagnostics( ) for issue in issues ) + + +def if_version_structure_diagnostics( + path: Path, issues: tuple[ConditionStructureIssue, ...] +) -> tuple[Diagnostic, ...]: + """Assign stable diagnostic codes to conditional structure failures.""" + + return tuple( + Diagnostic( + path=path, + span=issue.span, + code=IF_VERSION_STRUCTURE_CODES[issue.rule], + message=issue.message, + ) + for issue in issues + ) diff --git a/tests/test_if_version_structure_diagnostics.py b/tests/test_if_version_structure_diagnostics.py new file mode 100644 index 000000000..a1c519d6f --- /dev/null +++ b/tests/test_if_version_structure_diagnostics.py @@ -0,0 +1,37 @@ +from __future__ import annotations + +from pathlib import Path + +import pytest + +from scripts.snippets.diagnostics import if_version_structure_diagnostics +from scripts.snippets.model import ( + ConditionStructureIssue, + ConditionStructureRule, + Span, +) + +PATH = Path("docs-main/validator.source.mdx") +SPAN = Span(start=20, end=30, line=7, column=3) + + +@pytest.mark.parametrize( + ("rule", "code"), + [ + (ConditionStructureRule.UNEXPECTED_CLOSE, "SNIP012"), + (ConditionStructureRule.ELSE_NOT_DIRECT_CHILD, "SNIP025"), + (ConditionStructureRule.UNCLOSED_TAG, "SNIP026"), + (ConditionStructureRule.MULTIPLE_ELSE, "SNIP029"), + (ConditionStructureRule.ELSE_NOT_FINAL, "SNIP030"), + ], +) +def test_maps_structure_rule_to_stable_code( + rule: ConditionStructureRule, code: str +) -> None: + diagnostics = if_version_structure_diagnostics( + PATH, + (ConditionStructureIssue(rule=rule, span=SPAN, message="failure"),), + ) + + assert diagnostics[0].code == code + assert diagnostics[0].span == SPAN