Ctrl K
ComunidadGuías…

tests/test_excerpts_resolve.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""索引裡的鍵要真的讀得回內容。

一個查得到、但摘要是空的命中,比查不到更糟:它佔掉一個名額,然後什麼都
沒給你。而顯示層在摘要為空時會退回顯示標題,所以它看起來一直很正常——
這種「優雅降級」把一個缺陷藏了好幾個月。

兩件真的發生過的事:

  路徑疊了兩層   索引鍵是 wiki/topics/x.md#標題,呼叫端拿掉 wiki/ 之後傳
                 topics/x.md,而 WIKI_TOPICS_DIR 本身就以 topics 結尾。
                 於是每一個 wiki 命中的摘要都是空的——不是部分,是全部。

  後綴沒被剝掉   索引用 @N 標示切塊、~N 標示同名標題的第幾個,都加在 # 之後。
                 讀取端拿「做法-Workflow~2」去找標題,找不到。實測 895 個。

這個測試對真實索引抽樣,所以它同時擋住「路徑組錯」與「又加了一種後綴卻
忘了教讀取端」。
"""
from __future__ import annotations

import json
import re
import sys
import unittest
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts"))

import continuity_recall as cr
import xkb_paths

SAMPLE = 120
# 索引不完美,允許少量鍵指向已經被改掉的標題(頁面會變,索引是增量的)。
MIN_RESOLVED = 0.9


def _wiki_keys() -> list[str]:
    if not xkb_paths.VECTOR_FILE.exists():
        return []
    data = json.loads(xkb_paths.VECTOR_FILE.read_text(encoding="utf-8"))
    keys = data.get("vectors", data)
    return [k for k in keys if k.startswith("wiki/")]


class ExcerptsResolveTest(unittest.TestCase):
    def _rate(self, keys: list[str]) -> float:
        if not keys:
            self.skipTest("這台機器上沒有索引")
        resolved = 0
        for key in keys[:SAMPLE]:
            rest, _, section = key[len("wiki/"):].partition("#")
            if cr._section_text(rest, cr._base_heading(rest, section)):
                resolved += 1
        return resolved / min(SAMPLE, len(keys))

    def test_ordinary_keys_resolve(self) -> None:
        """路徑組錯的話這裡會是 0——而且顯示層看起來仍然正常。"""
        keys = [k for k in _wiki_keys() if not re.search(r"[@~]\d+$", k)]
        rate = self._rate(keys)
        self.assertGreaterEqual(rate, MIN_RESOLVED, f"只有 {rate:.0%} 的 wiki 鍵讀得回內容")

    def test_suffixed_keys_resolve(self) -> None:
        """@N / ~N 是索引自己加的,讀取端要認得。"""
        keys = [k for k in _wiki_keys() if re.search(r"[@~]\d+$", k)]
        rate = self._rate(keys)
        self.assertGreaterEqual(rate, MIN_RESOLVED, f"只有 {rate:.0%} 的帶後綴鍵讀得回內容")

    def test_a_real_suffix_is_not_stripped_blindly(self) -> None:
        """標題本身就以 ~2 結尾時,不能被當成索引後綴砍掉。"""
        self.assertEqual(cr._base_heading("does-not-exist.md", "核心概念"), "核心概念")


if __name__ == "__main__":
    unittest.main()