import json from typer.testing import CliRunner from tht.cli import app def test_evidence_authoring_commands_are_distinct_from_runtime_preprocessing(): result = CliRunner().invoke(app, ["evidence", "--help"]) assert result.exit_code == 0 assert "prepare" in result.output assert "resolve" in result.output assert "validate" in result.output def test_evidence_resolve_json_is_pristine(monkeypatch, tmp_path): from tht.cli import evidence_cmd from tht.evidence.authoring import EvidenceResolutionReport monkeypatch.setattr(evidence_cmd, "_canonical_worktree", lambda root: root) monkeypatch.setattr(evidence_cmd, "resolve_workspace_evidence", lambda *args, **kwargs: EvidenceResolutionReport( action="retired", evidence_id="evidence:fascia-pediatrica", source_file=None, findings=(), )) result = CliRunner().invoke(app, [ "evidence", "resolve", str(tmp_path), "evidence:fascia-pediatrica", "--retire", "--json", ]) assert result.exit_code == 0 assert result.stderr == "" assert json.loads(result.stdout) == { "action": "retired", "evidenceId": "evidence:fascia-pediatrica", "findings": [], "operation": "evidence_resolve", "schemaVersion": 1, "sourceFile": None, "status": "resolved", } def test_evidence_resolve_reports_unsafe_source_as_cli_misuse(monkeypatch, tmp_path): from tht.cli import evidence_cmd from tht.evidence import EvidencePreparationError monkeypatch.setattr(evidence_cmd, "_canonical_worktree", lambda root: root) monkeypatch.setattr( evidence_cmd, "resolve_workspace_evidence", lambda *args, **kwargs: (_ for _ in ()).throw(EvidencePreparationError("source_invalid")), ) result = CliRunner().invoke(app, [ "evidence", "resolve", str(tmp_path), "evidence:fascia-pediatrica", "--source", "source/domain/x.md", "--json", ]) assert result.exit_code == 2 assert result.stderr == "" assert json.loads(result.stdout) == { "code": "source_invalid", "operation": "evidence_resolve", "schemaVersion": 1, "status": "failed", } def test_evidence_resolve_reports_structural_findings_as_operational_failure(monkeypatch, tmp_path): from tht.cli import evidence_cmd from tht.evidence import ValidationFinding from tht.evidence.authoring import EvidenceResolutionReport monkeypatch.setattr(evidence_cmd, "_canonical_worktree", lambda root: root) monkeypatch.setattr(evidence_cmd, "resolve_workspace_evidence", lambda *args, **kwargs: EvidenceResolutionReport( action="relinked", evidence_id="evidence:fascia-pediatrica", source_file="source/domain/patient.md", findings=(ValidationFinding( "error", "supporting_excerpt_missing", "source/domain/patient.md", "Excerpt missing.", ),), )) result = CliRunner().invoke(app, [ "evidence", "resolve", str(tmp_path), "evidence:fascia-pediatrica", "--source", "source/domain/patient.md", ]) assert result.exit_code == 1 def test_evidence_validate_json_is_pristine_and_reports_review_required(monkeypatch, tmp_path): from tht.cli import evidence_cmd from tht.evidence import ValidationFinding, ValidationReport monkeypatch.setattr(evidence_cmd, "_canonical_worktree", lambda root: root) monkeypatch.setattr(evidence_cmd, "validate_workspace_evidence", lambda root: ValidationReport(( ValidationFinding("error", "unresolved_review_item", "curated/domain/x.md", "Review needed."), ))) result = CliRunner().invoke(app, ["evidence", "validate", str(tmp_path), "--json"]) assert result.exit_code == 3 assert result.stderr == "" assert json.loads(result.stdout) == { "findings": [{ "code": "unresolved_review_item", "message": "Review needed.", "path": "curated/domain/x.md", "severity": "error", }], "operation": "evidence_validate", "publishable": False, "schemaVersion": 1, "status": "review_required", }