"""不需要数据库的单元测试:证据校验、格式识别、文字层。""" from __future__ import annotations import pytest from bid_doctor.checklist.extract import check_basis, check_evidence, is_marked from bid_doctor.core.errors import AppError from bid_doctor.core.events import _sid # pyright: ignore[reportPrivateUsage] from bid_doctor.document.formats import detect from bid_doctor.document.pipeline.text_layer import Sentence, extract from tests.conftest import FIXTURES def sent(text: str, runs: list[tuple[int, int, str]] | None = None, seq: int = 1) -> Sentence: return Sentence(key=f"d:p1:s{seq}", page_no=1, seq=seq, text=text, quads=[[0, 0, 1, 1]], fmt_runs=runs or []) def test_evidence_checks() -> None: s = sent("★投标人须具备有效的信息系统集成服务资质证书。") by_id = {"p1s1": s} assert check_evidence({"sid": "p1s1", "quote": "投标人须具备有效的信息"}, by_id) is None assert check_evidence({"sid": "p9s9", "quote": "投标人须具备有效的信息"}, by_id) == "id" assert check_evidence({"sid": "p1s1", "quote": "投标人须具备"}, by_id) == "quote" # 少于 8 个字 assert check_evidence({"sid": "p1s1", "quote": "这句话是模型改写的"}, by_id) == "quote" def test_basis_check() -> None: star = sent("★服务器内存不低于32GB。") plain = sent("投标人应按要求提供售后服务方案。") iu = sent("投标人须提供原厂授权书。", [(0, 12, "iu")]) assert check_basis("star", [star], [star], set()) assert not check_basis("star", [plain], [plain], set()) # 斜体下划线只在文件声明过时才算(07 F1) assert not check_basis("italic_underline", [iu], [iu], set()) assert check_basis("italic_underline", [iu], [iu], {"italic_underline"}) invalid = sent("未提供的,其投标无效。", seq=2) assert check_basis("explicit_invalid", [plain], [plain, invalid], set()) assert not check_basis("unknown", [star], [star], set()) def test_marker_fallback() -> None: assert is_marked(sent("★采用国产化CPU芯片。"), set()) == "star" iu = sent("投标人须提供原厂授权书。", [(0, 12, "iu")]) assert is_marked(iu, set()) is None assert is_marked(iu, {"italic_underline"}) == "italic_underline" def test_marked_text_for_model() -> None: s = sent("须提供授权书,否则无效", [(3, 6, "iu"), (9, 11, "u")]) assert s.marked == "须提供授权书,否则无效" def test_detect_formats() -> None: pdf = (FIXTURES / "tender-mini.pdf").read_bytes() d = detect(pdf, "采购文件.pdf") assert (d.format, d.page_count, d.extension_mismatch) == ("pdf", 1, False) assert detect(pdf, "采购文件.doc").extension_mismatch with pytest.raises(AppError) as e: detect(b"hello", "a.doc") assert e.value.code == "file_format_unsupported" def test_text_layer_normalizes_radicals_and_keys() -> None: pages = extract("doc1", (FIXTURES / "tender-mini.pdf").read_bytes()) texts = [s.text for s in pages[0].sentences] assert any("项目" in t for t in texts) and not any("⽬" in t for t in texts) # 「目」不是康熙部首 assert any("彩页" in t for t in texts) keys = [s.key for s in pages[0].sentences] assert keys[0] == "doc1:p1:s1" and len(set(keys)) == len(keys) def test_stream_id_compare() -> None: assert _sid("1700000000000-1") > _sid("999-5") assert _sid("bad") == (0, 0)