import importlib.util import json import tempfile import unittest from pathlib import Path def load_rebuilder(): script_path = Path(__file__).resolve().parents[1] / "scripts" / "rebuild_indexes.py" spec = importlib.util.spec_from_file_location("rebuild_indexes", script_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) return module class RebuildIndexesTests(unittest.TestCase): def write_json(self, root, relative_path, data): path = root / relative_path path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(data, ensure_ascii=False, indent=2), encoding="utf-8") def write_library_without_indexes(self, root): self.write_json(root, "models/qpi.model.json", { "model_id": "qpi", "model_name": "QPI 三元定性模型", "model_type": "routing_model", "pipeline_position": "pre_analysis", "status": "draft", "source_articles": ["article_qpi_primary_001"], "source_evidence": ["excerpt_qpi_001"], "stability_profile": {"stability_level": "B"}, "regression_status": "pending", "version": "0.1", "last_updated": "2026-06-16" }) (root / "cards").mkdir(parents=True, exist_ok=True) (root / "cards" / "qpi.md").write_text("# QPI\n", encoding="utf-8") self.write_json(root, "tests/regression_cases.json", { "regression_cases": [ {"case_id": "case_1", "model_id": "qpi"}, {"case_id": "case_2", "model_id": "qpi"} ] }) def test_write_rebuilds_model_and_card_indexes(self): rebuilder = load_rebuilder() with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) self.write_library_without_indexes(root) result = rebuilder.rebuild_indexes(root, write=True) self.assertFalse(result.drift_found) model_index = json.loads((root / "models" / "model_index.json").read_text(encoding="utf-8")) self.assertEqual(model_index["models"][0]["model_id"], "qpi") self.assertEqual(model_index["models"][0]["regression_case_count"], 2) self.assertEqual(model_index["models"][0]["status"], "draft") card_index = (root / "cards" / "card_index.md").read_text(encoding="utf-8") self.assertIn("| qpi | QPI 三元定性模型 | routing_model | pre_analysis |", card_index) self.assertTrue((root / "reports" / "index_rebuild_report.md").exists()) def test_check_reports_drift_without_writing(self): rebuilder = load_rebuilder() with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) self.write_library_without_indexes(root) (root / "models" / "model_index.json").write_text("{}\n", encoding="utf-8") (root / "cards" / "card_index.md").write_text("# stale\n", encoding="utf-8") result = rebuilder.rebuild_indexes(root, write=False) self.assertTrue(result.drift_found) self.assertEqual((root / "models" / "model_index.json").read_text(encoding="utf-8"), "{}\n") if __name__ == "__main__": unittest.main()