#!/usr/bin/env python3 from __future__ import annotations import importlib.util import json import sys import tempfile import unittest from pathlib import Path from unittest.mock import patch INDEXER_PATH = Path(__file__).with_name("indexer.py") SPEC = importlib.util.spec_from_file_location("aiw_indexer", INDEXER_PATH) indexer = importlib.util.module_from_spec(SPEC) assert SPEC.loader is not None sys.modules[SPEC.name] = indexer SPEC.loader.exec_module(indexer) class IndexerTests(unittest.TestCase): def test_build_skips_templates_and_searches_canonical_files(self) -> None: with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) real = root / "project-knowledge" / "03-context" / "project.md" template = root / "project-knowledge" / "09-templates" / "daily.md" real.parent.mkdir(parents=True) template.parent.mkdir(parents=True) real.write_text("# XFlow\nDismissal lifecycle context", encoding="utf-8") template.write_text("# XFlow\nTemplate-only text", encoding="utf-8") with patch.object(indexer, "ROOT", root), patch.object(indexer, "INDEX_ROOT", root / ".aiw" / "indexes"): manifest = indexer.write_index("fidelity") result = indexer.search_index("fidelity", "dismissal lifecycle", limit=5) self.assertEqual(manifest["file_count"], 1) self.assertEqual(len(result["matches"]), 1) self.assertIn("03-context/project.md", result["matches"][0]["path"]) def test_status_reports_unindexed_profile(self) -> None: with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) with patch.object(indexer, "ROOT", root), patch.object(indexer, "INDEX_ROOT", root / ".aiw" / "indexes"): result = indexer.status("fidelity") self.assertFalse(result["indexed"]) self.assertIn(".aiw/indexes/fidelity/project-knowledge.jsonl", result["index_path"]) def test_cli_search_payload_is_json_serializable(self) -> None: payload = {"matches": [{"path": "project-knowledge/01-current/current-work.md", "score": 1.0}]} self.assertIsInstance(json.dumps(payload), str) if __name__ == "__main__": unittest.main()