generated from coulomb/repo-seed
151 lines
3.8 KiB
Python
151 lines
3.8 KiB
Python
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from infospace_bench import add_artifact, create_infospace
|
|
from infospace_bench.markdown_adapter import (
|
|
extract_section_text,
|
|
parse_markdown_artifact,
|
|
validate_infospace_artifacts,
|
|
)
|
|
|
|
|
|
CONTRACT = """# Source Artifact Contract
|
|
|
|
```yaml contract
|
|
id: source-artifact-v1
|
|
document:
|
|
type: source-artifact
|
|
sections:
|
|
- id: summary
|
|
title: Summary
|
|
presence: required
|
|
level: 2
|
|
- id: evidence
|
|
title: Evidence
|
|
presence: required
|
|
level: 2
|
|
```
|
|
"""
|
|
|
|
|
|
VALID_SOURCE = """---
|
|
document_type: source-artifact
|
|
status: draft
|
|
---
|
|
|
|
# Source A
|
|
|
|
## Summary
|
|
|
|
This source describes the first artifact.
|
|
|
|
## Evidence
|
|
|
|
The required evidence section is present.
|
|
"""
|
|
|
|
|
|
INVALID_SOURCE = """---
|
|
document_type: source-artifact
|
|
---
|
|
|
|
# Source B
|
|
|
|
## Summary
|
|
|
|
This source is missing evidence.
|
|
"""
|
|
|
|
|
|
def cli_env() -> dict[str, str]:
|
|
env = os.environ.copy()
|
|
env["PYTHONPATH"] = "src:/home/worsch/markitect-tool/src"
|
|
return env
|
|
|
|
|
|
def test_parse_markdown_artifact_uses_markitect_tool_sections(tmp_path: Path) -> None:
|
|
source = tmp_path / "source.md"
|
|
source.write_text(VALID_SOURCE, encoding="utf-8")
|
|
|
|
parsed = parse_markdown_artifact(source)
|
|
|
|
assert parsed.frontmatter["document_type"] == "source-artifact"
|
|
assert [heading.text for heading in parsed.headings] == [
|
|
"Source A",
|
|
"Summary",
|
|
"Evidence",
|
|
]
|
|
assert extract_section_text(parsed, "Summary") == (
|
|
"This source describes the first artifact."
|
|
)
|
|
|
|
|
|
def test_validate_infospace_artifacts_uses_configured_contract(tmp_path: Path) -> None:
|
|
infospace = create_infospace(tmp_path, "pilot", name="Pilot")
|
|
contract = infospace.root / "contracts" / "source.contract.md"
|
|
contract.parent.mkdir()
|
|
contract.write_text(CONTRACT, encoding="utf-8")
|
|
|
|
config = infospace.root / "infospace.yaml"
|
|
config.write_text(
|
|
config.read_text(encoding="utf-8").replace(
|
|
"schemas: {}\n", "schemas:\n source: contracts/source.contract.md\n"
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
|
|
valid = tmp_path / "valid.md"
|
|
valid.write_text(VALID_SOURCE, encoding="utf-8")
|
|
invalid = tmp_path / "invalid.md"
|
|
invalid.write_text(INVALID_SOURCE, encoding="utf-8")
|
|
add_artifact(infospace.root, valid, kind="source", title="Valid")
|
|
add_artifact(infospace.root, invalid, kind="source", title="Invalid")
|
|
|
|
results = validate_infospace_artifacts(infospace.root)
|
|
|
|
by_id = {result.artifact_id: result for result in results}
|
|
assert by_id["source/valid.md"].valid is True
|
|
assert by_id["source/invalid.md"].valid is False
|
|
assert by_id["source/invalid.md"].diagnostics[0].code == "contract.section.missing"
|
|
|
|
|
|
def test_cli_validate_outputs_json_results(tmp_path: Path) -> None:
|
|
infospace = create_infospace(tmp_path, "pilot", name="Pilot")
|
|
contract = infospace.root / "contracts" / "source.contract.md"
|
|
contract.parent.mkdir()
|
|
contract.write_text(CONTRACT, encoding="utf-8")
|
|
config = infospace.root / "infospace.yaml"
|
|
config.write_text(
|
|
config.read_text(encoding="utf-8").replace(
|
|
"schemas: {}\n", "schemas:\n source: contracts/source.contract.md\n"
|
|
),
|
|
encoding="utf-8",
|
|
)
|
|
source = tmp_path / "invalid.md"
|
|
source.write_text(INVALID_SOURCE, encoding="utf-8")
|
|
add_artifact(infospace.root, source, kind="source", title="Invalid")
|
|
|
|
result = subprocess.run(
|
|
[
|
|
sys.executable,
|
|
"-m",
|
|
"infospace_bench",
|
|
"validate",
|
|
str(infospace.root),
|
|
],
|
|
check=False,
|
|
env=cli_env(),
|
|
text=True,
|
|
capture_output=True,
|
|
)
|
|
|
|
assert result.returncode == 1
|
|
payload = json.loads(result.stdout)
|
|
assert payload["valid"] is False
|
|
assert payload["results"][0]["diagnostics"][0]["code"] == (
|
|
"contract.section.missing"
|
|
)
|