from __future__ import annotations import tempfile import unittest from pathlib import Path from claridoc.corpus import build_query_from_brief, collect_sources from claridoc.models import Brief from claridoc.utils import read_json ROOT = Path(__file__).resolve().parents[1] CORPUS = ROOT / "examples" / "corpus" / "llm-wiki-mini" class CorpusTests(unittest.TestCase): def test_decision_rationale_chunk_ranks_first(self) -> None: pack = collect_sources( CORPUS, "application-core Spring DI 수동 Configuration 보일러플레이트 선택 이유 대안 가드레일", top_k=8, ) self.assertGreaterEqual(len(pack.sources), 4) first = pack.sources[0] self.assertEqual(first.path, "raw/branch-notes/feature-application-port-usecase-contract.md") self.assertEqual(first.heading, "결정 사항") self.assertIn("수동 등록", first.facts[0]) self.assertIn("D13", first.decision_ids) def test_paths_are_repository_relative_and_line_ranges_are_recorded(self) -> None: pack = collect_sources(CORPUS, "application-core 경계 검증", top_k=6) self.assertTrue(pack.sources) for source in pack.sources: self.assertFalse(source.path.startswith("/")) self.assertTrue(source.url.startswith("repo:///")) self.assertIsNotNone(source.line_start) self.assertIsNotNone(source.line_end) self.assertGreaterEqual(source.line_end or 0, source.line_start or 0) def test_brief_query_retrieves_rationale_and_current_state(self) -> None: brief = Brief.from_dict( read_json(ROOT / "examples" / "briefs" / "application-core-spring-di-blog.json") ) pack = collect_sources(CORPUS, build_query_from_brief(brief), top_k=12) paths = {source.path for source in pack.sources} self.assertIn("raw/branch-notes/feature-application-port-usecase-contract.md", paths) self.assertIn("wiki/projects/ca-tmpl/clean-architecture-package-layout.md", paths) def test_heading_without_body_is_not_collected_as_evidence(self) -> None: pack = collect_sources(CORPUS, "Spring component stereotype scanning", top_k=20) self.assertFalse( any( source.heading == "Spring component stereotype and scanning notes" and source.facts == ["# Spring component stereotype and scanning notes"] for source in pack.sources ) ) def test_missing_default_directories_are_allowed(self) -> None: with tempfile.TemporaryDirectory() as temp: root = Path(temp) (root / "wiki/projects").mkdir(parents=True) (root / "wiki/projects/example.md").write_text( "# Example\n\n## 결정\n\n선택 이유와 대안을 기록한다.\n", encoding="utf-8", ) pack = collect_sources(root, "선택 이유 대안") self.assertEqual(len(pack.sources), 1) if __name__ == "__main__": unittest.main()