generated from coulomb/repo-seed
165 lines
4.8 KiB
Python
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
|