generated from coulomb/repo-seed
T01: markidocx inspect (FR-806) and markidocx test (FR-810) CLI commands
T02: markidocx evidence get/list CLI commands (FR-1409, FR-814)
T03: list_styles() / GET /styles / MCP list_styles with real style data (FR-907)
T04: Evidence assembly — EvidenceSet summary via REST and MCP (FR-1406–1408)
T05: LEVEL3 edge-case tests — diagram mutation, renderer version check,
bibliography duplicate keys / missing refs / special chars (FR-534, FR-538, FR-542)
T06: markidocx template extract + Word-first round-trip regression test (FR-606)
New: differ._compare_diagram_blocks tracks fenced diagram source drift (FR-534)
New: diagrams.check_renderer_version emits warning for outdated renderers (FR-538)
New: bibliography.validate_citations detects duplicate keys and missing entries (FR-542)
New: templates.extract_template / TemplateExtractionResult / list_styles / StyleEntry
New: REST POST /template/extract; MCP extract_template tool
278 tests pass, ruff+mypy clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
136 lines
4.3 KiB
Python
136 lines
4.3 KiB
Python
"""Tests for T01 — markidocx inspect and markidocx test CLI commands (FR-806, FR-810)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import textwrap
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
SIMPLE_MANIFEST = textwrap.dedent("""\
|
|
project:
|
|
name: "Test Document"
|
|
feature_level: level1
|
|
family: article
|
|
|
|
sources:
|
|
- path: doc.md
|
|
|
|
output:
|
|
dir: ./dist
|
|
""")
|
|
|
|
SIMPLE_MARKDOWN = textwrap.dedent("""\
|
|
# Hello
|
|
|
|
A paragraph.
|
|
""")
|
|
|
|
|
|
@pytest.fixture()
|
|
def tmp_project(tmp_path: Path) -> Path:
|
|
(tmp_path / "doc.md").write_text(SIMPLE_MARKDOWN, encoding="utf-8")
|
|
(tmp_path / "manifest.yaml").write_text(SIMPLE_MANIFEST, encoding="utf-8")
|
|
(tmp_path / "dist").mkdir()
|
|
return tmp_path
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# inspect command
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestInspectCommand:
|
|
def test_inspect_human_readable(self, tmp_project: Path) -> None:
|
|
from typer.testing import CliRunner
|
|
|
|
from markidocx.cli import app
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(app, ["inspect", str(tmp_project / "manifest.yaml")])
|
|
assert result.exit_code == 0
|
|
assert "Test Document" in result.output
|
|
assert "article" in result.output
|
|
assert "level1" in result.output
|
|
|
|
def test_inspect_json_output(self, tmp_project: Path) -> None:
|
|
from typer.testing import CliRunner
|
|
|
|
from markidocx.cli import app
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(app, ["inspect", str(tmp_project / "manifest.yaml"), "--json"])
|
|
assert result.exit_code == 0
|
|
data = json.loads(result.output.strip())
|
|
assert data["status"] == "ok"
|
|
assert data["project"] == "Test Document"
|
|
assert data["family"] == "article"
|
|
assert data["feature_level"] == "level1"
|
|
assert isinstance(data["sources"], list)
|
|
assert isinstance(data["level3"], dict)
|
|
|
|
def test_inspect_invalid_manifest(self, tmp_path: Path) -> None:
|
|
from typer.testing import CliRunner
|
|
|
|
from markidocx.cli import app
|
|
|
|
bad = tmp_path / "bad.yaml"
|
|
bad.write_text("not: valid: manifest", encoding="utf-8")
|
|
runner = CliRunner()
|
|
result = runner.invoke(app, ["inspect", str(bad)])
|
|
assert result.exit_code == 1
|
|
|
|
def test_inspect_json_invalid_manifest(self, tmp_path: Path) -> None:
|
|
from typer.testing import CliRunner
|
|
|
|
from markidocx.cli import app
|
|
|
|
bad = tmp_path / "bad.yaml"
|
|
bad.write_text("not: valid: manifest", encoding="utf-8")
|
|
runner = CliRunner()
|
|
result = runner.invoke(app, ["inspect", str(bad), "--json"])
|
|
data = json.loads(result.output.strip())
|
|
assert data["status"] == "error"
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# test command
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class TestRunTestsCommand:
|
|
def test_run_tests_passes(self, tmp_project: Path) -> None:
|
|
from typer.testing import CliRunner
|
|
|
|
from markidocx.cli import app
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(app, ["test", str(tmp_project / "manifest.yaml")])
|
|
# Command exists and runs
|
|
assert result.exit_code in (0, 1)
|
|
assert "run_id" in result.output or "passed" in result.output or "failed" in result.output
|
|
|
|
def test_run_tests_json_output(self, tmp_project: Path) -> None:
|
|
from typer.testing import CliRunner
|
|
|
|
from markidocx.cli import app
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(app, ["test", str(tmp_project / "manifest.yaml"), "--json"])
|
|
data = json.loads(result.output.strip())
|
|
assert "status" in data
|
|
assert "classification" in data
|
|
assert "steps" in data
|
|
|
|
def test_run_tests_exit_code_reflects_result(self, tmp_project: Path) -> None:
|
|
from typer.testing import CliRunner
|
|
|
|
from markidocx.cli import app
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(app, ["test", str(tmp_project / "manifest.yaml"), "--json"])
|
|
data = json.loads(result.output.strip())
|
|
expected_exit = 0 if data["status"] == "ok" else 1
|
|
assert result.exit_code == expected_exit
|