from __future__ import annotations from pathlib import Path import sys import tempfile import unittest RUNTIME = Path(__file__).resolve().parents[1] / "runtime" sys.path.insert(0, str(RUNTIME)) import quality_gate # noqa: E402 class QualityGateTest(unittest.TestCase): def test_read_only_pass_and_transport_token_failure(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) path = root / "notes/example.md" path.parent.mkdir(parents=True) path.write_text("# 예시\n", encoding="utf-8") before = path.read_bytes() result = quality_gate.run( root, [path], include_graph=False, require_moc_convergence=False, ) self.assertEqual(result["status"], "PASS", result) self.assertEqual(path.read_bytes(), before) self.assertEqual(result["checked_paths"], result["touched_paths"]) self.assertIn("source-hygiene", {item["name"] for item in result["checks"]}) path.write_text("# 예시\n\n", encoding="utf-8") failed = quality_gate.run( root, [path], include_graph=False, require_moc_convergence=False, ) self.assertEqual(failed["status"], "FAIL") self.assertIn("SOURCE_HYGIENE_VIOLATION", {item["code"] for item in failed["findings"]}) def test_unresolved_placeholder_and_duplicate_section_id_fail(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) path = root / "notes/example.md" path.parent.mkdir(parents=True) path.write_text( "# 예시\n{{missing}}\n\n\n", encoding="utf-8", ) result = quality_gate.run( root, [path], include_graph=False, require_moc_convergence=False, ) self.assertEqual( {item["code"] for item in result["findings"]}, {"UNRESOLVED_PLACEHOLDER", "DUPLICATE_SECTION_ID"}, ) def test_public_extensions_are_fail_closed_and_reported(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) path = root / "notes/example.md" path.parent.mkdir(parents=True) path.write_text("# 예시\n", encoding="utf-8") extension = quality_gate.QualityExtension( "typed-contract", lambda _root: { "schema_version": "typed-contract-check-result/v1", "status": "FAIL", "findings": [{"code": "STALE_REVISION", "path": "notes/example.md"}], }, ) result = quality_gate.run( root, [path], include_graph=False, require_moc_convergence=False, extensions=[extension], ) self.assertEqual(result["status"], "FAIL") self.assertIn("STALE_REVISION", {item["code"] for item in result["findings"]}) typed = next(item for item in result["checks"] if item["name"] == "typed-contract") self.assertEqual(typed["schema_version"], "typed-contract-check-result/v1") self.assertEqual(typed["status"], "FAIL") def test_required_extension_cannot_silently_skip(self) -> None: with tempfile.TemporaryDirectory() as directory: root = Path(directory) path = root / "notes/example.md" path.parent.mkdir(parents=True) path.write_text("# 예시\n", encoding="utf-8") result = quality_gate.run( root, [path], include_graph=False, require_moc_convergence=False, extensions=[quality_gate.QualityExtension("semantic-certificate", lambda _root: {"status": "SKIP", "findings": []})], ) self.assertIn("REQUIRED_EXTENSION_SKIPPED", {item["code"] for item in result["findings"]}) if __name__ == "__main__": unittest.main()