"""질의 확장 검증 (수정사항 4번).""" from config.glossary import parse_glossary, synonym_map from index.db import fts_or, query_tokens from query import expand def test_parse_glossary_ignores_nested_and_comments(): g = parse_glossary( "# 주석\n" "총계정원장: [G/L, GL, ACDOCT]\n" "tags:\n" " - 전표\n" "입고: [GR, 101]\n" ) assert g == {"총계정원장": ["G/L", "GL", "ACDOCT"], "입고": ["GR", "101"]} def test_synonym_map_is_bidirectional(tmp_path): p = tmp_path / "g.yaml" p.write_text("입고: [GR, MSEG, 101]\n", encoding="utf-8") m = synonym_map(p) # 대표어로 물어도, 동의어로 물어도 나머지가 나온다 assert set(m["입고"]) == {"GR", "MSEG", "101"} assert "입고" in m["GR"] and "MSEG" in m["GR"] assert "입고" in m["101"] def test_expansion_terms_excludes_query_itself(): terms = expand.expansion_terms("총계정원장") assert terms, "사전에 있는 용어는 동의어가 나와야 한다" assert "총계정원장" not in terms assert "ACDOCT" in [t.upper() for t in terms] def test_expansion_terms_empty_for_unknown_word(): assert expand.expansion_terms("zzz알수없는말") == [] def test_match_exprs_separates_primary_and_expanded(): primary, expanded = expand.match_exprs("총계정원장") assert '"총계정원장"' in primary # 동의어는 별 식으로 나와야 한다 — 같은 OR 버킷에 섞으면 정밀도가 떨어진다 assert expanded is not None assert "ACDOCT" in expanded.upper() assert "ACDOCT" not in primary.upper() def test_no_expansion_returns_none(): _, expanded = expand.match_exprs("zzz알수없는말") assert expanded is None def test_expanded_weight_is_a_penalty(): assert 0 < expand.EXPANDED_WEIGHT < 1, "동의어 히트는 원질의 히트보다 낮게 점수화돼야 한다" def test_fts_or_quotes_and_adds_bigrams(): expr = fts_or(["총계정원장"]) assert '"총계정원장"' in expr assert '"총계' in expr and " OR " in expr def test_fts_or_strips_quotes_to_keep_match_valid(): assert '""' not in fts_or(['A"B']).replace('"A', "").replace('B"', "") assert fts_or([]) == '""' def test_query_tokens_drops_punctuation(): assert query_tokens("총계정원장, 잔액 조회!") == ["총계정원장", "잔액", "조회"]