From 788f610d3f900830ec37e92319adf07afd94546a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=88=AA=E5=AE=87?= <3364451258@qq.com> Date: Fri, 10 Jul 2026 15:28:13 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E4=BF=AE=E5=A4=8D=20EPUB=20=E7=BC=BA?= =?UTF-8?q?=E5=A4=B1=E4=BE=9D=E8=B5=96=E6=B5=8B=E8=AF=95=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +++++++++++--- tests/test_splitters_epub.py | 28 ++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index cb1fc9d..f2bc35b 100644 --- a/README.md +++ b/README.md @@ -224,7 +224,15 @@ md-vector-db/ │ │ ├── db.py # ChromaDB 封装(线程安全) │ │ ├── embedder.py # 嵌入器(Local/OpenAI/Dashscope) │ │ ├── ingest.py # 混合分块 + 入库 -│ │ └── search.py # 语义检索 +│ │ ├── search.py # 语义检索 +│ │ └── splitters/ # 文档分块器包 +│ │ ├── base.py # Splitter(Protocol) + BaseTextSplitter(ABC) +│ │ ├── markdown.py # MarkdownSplitter +│ │ ├── text.py # TextSplitter +│ │ ├── pdf.py # PDFSplitter +│ │ ├── html.py # HTMLSplitter +│ │ ├── epub.py # EPUBSplitter +│ │ └── registry.py # 扩展名 → Splitter 自动选择 │ ├── server/ # FastAPI HTTP 层 │ │ ├── app.py # 路由 + 中间件 │ │ ├── deps.py # 依赖注入(AppState) @@ -236,7 +244,7 @@ md-vector-db/ ├── scripts/ │ ├── serve.py # 快速启动脚本 │ └── ingest_obsidian.py # 批量入库 Obsidian 知识库 -└── tests/ # 测试(46 个) +└── tests/ # 测试(115+ 个) ``` ## 测试 @@ -250,7 +258,7 @@ uv run pytest tests/ -v --cov=src --cov-report=term-missing # 覆盖率 ## 架构 -**数据流**: MD 文件 → `MarkdownSplitter.split()` (标题→段落分块) → `batch_embed()` (分批嵌入) → `ChromaDB collection.add()` → `Searcher.search()` 查询 +**数据流**: 文件 → `get_splitter(path)` 自动选择 → `Splitter.split()` → `batch_embed()` (分批嵌入) → `ChromaDB collection.add()` → `Searcher.search()` 查询 **依赖方向**: `config` ← `db` ← `embedder` ← `ingest` / `search` ← `server` / `cli` diff --git a/tests/test_splitters_epub.py b/tests/test_splitters_epub.py index c695f45..9885c8f 100644 --- a/tests/test_splitters_epub.py +++ b/tests/test_splitters_epub.py @@ -1,11 +1,30 @@ """EPUBSplitter 测试.""" import pytest -ebooklib = pytest.importorskip("ebooklib", reason="ebooklib 未安装") + +class TestEPUBSplitterMissingDep: + """缺失依赖时的行为测试(不 skip 整个文件).""" + + def test_split_raises_clear_import_error(self, monkeypatch): + """未安装 ebooklib 时给出明确提示.""" + from src.core.splitters.epub import EPUBSplitter + s = EPUBSplitter() + import builtins + original_import = builtins.__import__ + + def mock_import(name, *args, **kwargs): + if name == "ebooklib" or name.startswith("ebooklib."): + raise ImportError("No module named 'ebooklib'") + return original_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, "__import__", mock_import) + with pytest.raises(ImportError, match="ebooklib"): + s.split("dummy.epub", source_file="test.epub") class TestEPUBSplitter: """EPUBSplitter 测试(需 ebooklib).""" + ebooklib = pytest.importorskip("ebooklib", reason="ebooklib 未安装") def test_split_simple_epub(self, tmp_path): """用 ebooklib 创建一个简单 EPUB 并测试分块.""" @@ -47,10 +66,3 @@ class TestEPUBSplitter: from src.core.splitters.epub import EPUBSplitter s = EPUBSplitter() assert hasattr(s, "split") - - def test_epub_missing_dependency_message(self): - """EPUBSplitter.split() 在未安装 ebooklib 时应给出明确提示.""" - from src.core.splitters.epub import EPUBSplitter - s = EPUBSplitter() - # 验证 split 方法存在且可调用(有明确的 import error 信息) - assert callable(s.split)