Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions scripts/snippets/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,10 @@ class DirectiveSyntaxRule(str, Enum):
ELSE_SELF_CLOSING = "else_self_closing"
CLOSING_ATTRIBUTES = "closing_attributes"
ELSE_ATTRIBUTES = "else_attributes"


@dataclass(frozen=True)
class ConditionPageValidation:
tags: tuple[IfVersionTag | ElseTag, ...]
conditions: tuple[IfVersionCondition, ...]
diagnostics: tuple[Diagnostic, ...]
50 changes: 50 additions & 0 deletions scripts/snippets/page_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from __future__ import annotations

from pathlib import Path

from .diagnostics import (
directive_syntax_diagnostic,
if_version_attribute_diagnostics,
if_version_structure_diagnostics,
)
from .model import ConditionPageValidation, IfVersionTag
from .registry import RepositoryRegistry
from .syntax import DirectiveSyntaxError, parse_if_version_tags
from .validation import (
validate_if_version_attributes,
validate_if_version_structure,
)


def validate_condition_page(
text: str, *, path: Path, registry: RepositoryRegistry
) -> ConditionPageValidation:
"""Parse and validate conditional declarations without inspecting snippets."""

try:
tags = parse_if_version_tags(text)
except DirectiveSyntaxError as error:
return ConditionPageValidation(
tags=(),
conditions=(),
diagnostics=(directive_syntax_diagnostic(path, error),),
)

diagnostics = list(
if_version_structure_diagnostics(
path, validate_if_version_structure(text, tags)
)
)
conditions = []
for tag in tags:
if not isinstance(tag, IfVersionTag) or tag.closing:
continue
result = validate_if_version_attributes(tag, registry)
diagnostics.extend(if_version_attribute_diagnostics(path, result.issues))
if result.condition is not None:
conditions.append(result.condition)
return ConditionPageValidation(
tags=tags,
conditions=tuple(conditions),
diagnostics=tuple(diagnostics),
)
68 changes: 68 additions & 0 deletions tests/test_condition_page_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from __future__ import annotations

from pathlib import Path

from scripts.snippets.model import ConditionPageValidation
from scripts.snippets.page_validation import validate_condition_page
from scripts.snippets.registry import (
RepositoryConfig,
RepositoryRegistry,
RepositoryVisibility,
)

PATH = Path("docs-main/validator.source.mdx")
REGISTRY = RepositoryRegistry(
(
RepositoryConfig(
name="canton-network/splice",
url="https://github.com/canton-network/splice",
default_branch="main",
visibility=RepositoryVisibility.PUBLIC,
),
)
)


def validate(text: str) -> ConditionPageValidation:
return validate_condition_page(text, path=PATH, registry=REGISTRY)


def test_returns_validated_condition() -> None:
result = validate(
"""<IfVersion repository="https://github.com/canton-network/splice" containsPullRequest={6123}>
new
</IfVersion>"""
)

assert result.diagnostics == ()
assert len(result.conditions) == 1
assert result.conditions[0].repository == "canton-network/splice"


def test_reports_conditional_syntax_error() -> None:
result = validate(
'<IfVersion repository="https://github.com/canton-network/splice" />'
)

assert [diagnostic.code for diagnostic in result.diagnostics] == [
"SNIP019"
]


def test_reports_conditional_structure_error() -> None:
result = validate("<Else>orphan</Else>")

assert "SNIP025" in {
diagnostic.code for diagnostic in result.diagnostics
}


def test_reports_condition_attribute_error() -> None:
result = validate(
'<IfVersion repository="not-a-url" containsPullRequest={6123}>'
"new</IfVersion>"
)

assert "SNIP021" in {
diagnostic.code for diagnostic in result.diagnostics
}