diff --git a/scripts/snippets/model.py b/scripts/snippets/model.py index 4c7c4f913..3c274f1b7 100644 --- a/scripts/snippets/model.py +++ b/scripts/snippets/model.py @@ -2,6 +2,7 @@ from dataclasses import dataclass from enum import Enum +from pathlib import Path @dataclass(frozen=True) @@ -191,3 +192,21 @@ class CandidateConditionIssue: rule: CandidateConditionRule span: Span message: str + + +@dataclass(frozen=True) +class Diagnostic: + path: Path + span: Span + code: str + message: str + remediation: str | None = None + + def format(self) -> str: + rendered = ( + f"{self.path}:{self.span.line}:{self.span.column}: " + f"{self.code}: {self.message}" + ) + if self.remediation is not None: + rendered += f"\n remediation: {self.remediation}" + return rendered diff --git a/tests/test_snippet_diagnostic_format.py b/tests/test_snippet_diagnostic_format.py new file mode 100644 index 000000000..528072b25 --- /dev/null +++ b/tests/test_snippet_diagnostic_format.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from pathlib import Path + +from scripts.snippets.model import Diagnostic, Span + + +def test_formats_page_line_column_code_and_message() -> None: + diagnostic = Diagnostic( + path=Path("docs-main/validator.source.mdx"), + span=Span(start=20, end=30, line=7, column=3), + code="SNIP008", + message="Unsupported snippet source", + ) + + assert diagnostic.format() == ( + "docs-main/validator.source.mdx:7:3: " + "SNIP008: Unsupported snippet source" + ) + + +def test_appends_remediation_on_indented_line() -> None: + diagnostic = Diagnostic( + path=Path("docs-main/validator.source.mdx"), + span=Span(start=20, end=30, line=7, column=3), + code="SNIP007", + message="Local snippet references are preview-only", + remediation="Resolve the local reference before pushing.", + ) + + assert diagnostic.format().endswith( + "\n remediation: Resolve the local reference before pushing." + )