Files
markitect-tool/tests/test_schema_contract.py

165 lines
4.8 KiB
Python

from pathlib import Path
from click.testing import CliRunner
from markitect_tool.cli import main
from markitect_tool.schema import (
InvalidSchemaFormatError,
SchemaNotFoundError,
load_schema_file,
validate_markdown_file,
validate_schema,
)
SCHEMA_TEXT = """---
schema-id: "https://example.test/schemas/document/v1"
version: "1.0.0"
status: "stable"
---
# Document Schema
## Schema Definition
```json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Document Schema",
"type": "object",
"required": ["frontmatter", "headings"],
"properties": {
"frontmatter": {
"type": "object",
"required": ["title"],
"properties": {
"title": {"type": "string"}
}
},
"headings": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": ["level", "text"],
"properties": {
"level": {"type": "integer"},
"text": {"type": "string"}
}
}
}
}
}
```
"""
def test_load_schema_file_extracts_metadata_and_json_schema(tmp_path: Path):
schema_file = tmp_path / "document-schema.md"
schema_file.write_text(SCHEMA_TEXT, encoding="utf-8")
loaded = load_schema_file(schema_file)
assert loaded.metadata["schema-id"] == "https://example.test/schemas/document/v1"
assert loaded.metadata["status"] == "stable"
assert loaded.schema["title"] == "Document Schema"
assert loaded.schema["x-markitect-source"]["format"] == "markdown"
assert loaded.source_path == str(schema_file)
def test_load_schema_file_requires_json_block(tmp_path: Path):
schema_file = tmp_path / "missing.md"
schema_file.write_text("# Missing\n\nNo schema.", encoding="utf-8")
try:
load_schema_file(schema_file)
except SchemaNotFoundError as exc:
assert "No JSON schema found" in str(exc)
else:
raise AssertionError("expected SchemaNotFoundError")
def test_load_schema_file_rejects_invalid_json(tmp_path: Path):
schema_file = tmp_path / "invalid.md"
schema_file.write_text("```json\n{invalid json}\n```", encoding="utf-8")
try:
load_schema_file(schema_file)
except InvalidSchemaFormatError as exc:
assert "Invalid JSON schema block" in str(exc)
else:
raise AssertionError("expected InvalidSchemaFormatError")
def test_validate_markdown_file_returns_valid_result(tmp_path: Path):
schema_file = tmp_path / "document-schema.md"
schema_file.write_text(SCHEMA_TEXT, encoding="utf-8")
markdown_file = tmp_path / "document.md"
markdown_file.write_text("---\ntitle: Example\n---\n\n# Example\n\nBody.", encoding="utf-8")
result = validate_markdown_file(markdown_file, schema_file)
assert result.valid is True
assert result.violations == []
assert result.document_path == str(markdown_file)
assert result.schema_path == str(schema_file)
def test_validate_markdown_file_reports_violations(tmp_path: Path):
schema_file = tmp_path / "document-schema.md"
schema_file.write_text(SCHEMA_TEXT, encoding="utf-8")
markdown_file = tmp_path / "document.md"
markdown_file.write_text("# Missing Title\n\nBody.", encoding="utf-8")
result = validate_markdown_file(markdown_file, schema_file)
assert result.valid is False
assert result.violations
assert result.violations[0].path == "$.frontmatter"
assert "title" in result.violations[0].message
def test_validate_schema_reports_invalid_schema():
result = validate_schema({"type": 7})
assert result.valid is False
assert result.violations
def test_mkt_validate_exits_zero_for_valid_document(tmp_path: Path):
schema_file = tmp_path / "document-schema.md"
schema_file.write_text(SCHEMA_TEXT, encoding="utf-8")
markdown_file = tmp_path / "document.md"
markdown_file.write_text("---\ntitle: Example\n---\n\n# Example\n", encoding="utf-8")
result = CliRunner().invoke(
main, ["validate", str(markdown_file), "--schema", str(schema_file)]
)
assert result.exit_code == 0
assert "valid" in result.output
def test_mkt_validate_exits_nonzero_for_invalid_document(tmp_path: Path):
schema_file = tmp_path / "document-schema.md"
schema_file.write_text(SCHEMA_TEXT, encoding="utf-8")
markdown_file = tmp_path / "document.md"
markdown_file.write_text("# Missing Title\n", encoding="utf-8")
result = CliRunner().invoke(
main, ["validate", str(markdown_file), "--schema", str(schema_file)]
)
assert result.exit_code == 1
assert "invalid" in result.output
def test_mkt_schema_validate(tmp_path: Path):
schema_file = tmp_path / "document-schema.md"
schema_file.write_text(SCHEMA_TEXT, encoding="utf-8")
result = CliRunner().invoke(main, ["schema", "validate", str(schema_file)])
assert result.exit_code == 0
assert "valid" in result.output