feat: 添加 --advice 参数,支持快速获取执行建议

- 新增 scripts/core/advice_generator.py 建议生成器模块
- 在 config.py 中添加 DEPENDENCIES 依赖配置
- 在 lyxy_document_reader.py 中添加 -a/--advice 参数
- 复用 Reader 实例的 supports 方法检测文件类型
- 支持平台检测,对 macOS x86_64 PDF 返回特殊命令
- 添加单元测试和集成测试
- 更新 SKILL.md,引导优先使用 --advice 参数
- 更新 README.md,添加项目结构说明
- 添加 openspec/specs/cli-advice/spec.md 规范文档
This commit is contained in:
2026-03-09 18:13:00 +08:00
parent 9daff73589
commit aaa1171e60
9 changed files with 757 additions and 103 deletions

View File

@@ -0,0 +1,195 @@
"""测试 advice_generator 模块。"""
import pytest
from unittest.mock import patch
from core.advice_generator import (
detect_file_type_light,
get_platform,
get_dependencies,
generate_uv_command,
generate_python_command,
format_advice,
generate_advice,
)
from readers import READERS, PdfReader, DocxReader, HtmlReader
@pytest.fixture
def readers():
"""提供已实例化的 readers 列表。"""
return [ReaderCls() for ReaderCls in READERS]
class TestDetectFileTypeLight:
"""测试轻量文件类型检测函数。"""
def test_detect_pdf(self, readers):
"""测试检测 PDF 文件。"""
reader_cls = detect_file_type_light("test.pdf", readers)
assert reader_cls == PdfReader
def test_detect_docx(self, readers):
"""测试检测 DOCX 文件。"""
reader_cls = detect_file_type_light("test.docx", readers)
assert reader_cls == DocxReader
def test_detect_html(self, readers):
"""测试检测 HTML 文件。"""
reader_cls = detect_file_type_light("test.html", readers)
assert reader_cls == HtmlReader
def test_detect_url(self, readers):
"""测试检测 URL。"""
reader_cls = detect_file_type_light("https://example.com", readers)
assert reader_cls == HtmlReader
def test_detect_unknown(self, readers):
"""测试检测未知文件类型。"""
reader_cls = detect_file_type_light("test.xyz", readers)
assert reader_cls is None
class TestGetPlatform:
"""测试平台检测函数。"""
def test_get_platform_format(self):
"""测试平台标识格式正确。"""
platform_id = get_platform()
# 格式应该是 {system}-{machine}
assert "-" in platform_id
# 至少包含两个部分
assert len(platform_id.split("-")) >= 2
class TestGetDependencies:
"""测试依赖获取函数。"""
def test_get_default_dependencies(self):
"""测试获取默认依赖配置。"""
python_ver, deps = get_dependencies(DocxReader, "Unknown-Platform")
assert python_ver is None
assert len(deps) > 0
assert "docling" in deps
def test_get_pdf_dependencies(self):
"""测试获取 PDF 依赖。"""
python_ver, deps = get_dependencies(PdfReader, "Darwin-arm64")
assert python_ver is None
assert "docling" in deps
def test_get_html_dependencies(self):
"""测试获取 HTML 依赖。"""
python_ver, deps = get_dependencies(HtmlReader, "Linux-x86_64")
assert python_ver is None
assert "trafilatura" in deps
class TestGenerateUvCommand:
"""测试 uv 命令生成函数。"""
def test_generate_simple_command(self):
"""测试生成简单的 uv 命令。"""
cmd = generate_uv_command(
["pkg1", "pkg2"],
"input.pdf",
script_path="scripts/lyxy_document_reader.py"
)
assert "uv run" in cmd
assert "--with pkg1" in cmd
assert "--with pkg2" in cmd
assert "input.pdf" in cmd
def test_generate_with_python_version(self):
"""测试生成带 python 版本的 uv 命令。"""
cmd = generate_uv_command(
["pkg1"],
"input.pdf",
python_version="3.12",
script_path="scripts/lyxy_document_reader.py"
)
assert "--python 3.12" in cmd
def test_generate_with_quoted_deps(self):
"""测试生成带引号的依赖(如 unstructured[pdf])。"""
cmd = generate_uv_command(
["unstructured[pdf]", "pkg2"],
"input.pdf",
script_path="scripts/lyxy_document_reader.py"
)
assert '--with "unstructured[pdf]"' in cmd
class TestGeneratePythonCommand:
"""测试 python 命令生成函数。"""
def test_generate_python_command(self):
"""测试生成 python 命令。"""
python_cmd, pip_cmd = generate_python_command(
["pkg1", "pkg2"],
"input.pdf",
script_path="scripts/lyxy_document_reader.py"
)
assert python_cmd == "python scripts/lyxy_document_reader.py input.pdf"
assert pip_cmd == "pip install pkg1 pkg2"
class TestFormatAdvice:
"""测试建议格式化输出函数。"""
def test_format_without_platform(self):
"""测试无平台特殊配置的格式化输出。"""
output = format_advice(
"pdf",
"test.pdf",
"Darwin-arm64",
"uv run --with docling ...",
"python scripts/lyxy_document_reader.py test.pdf",
"pip install docling ...",
has_platform_specific=False
)
assert "文件类型: PDF" in output
assert "输入路径: test.pdf" in output
assert "平台:" not in output
assert "[uv 命令]" in output
assert "[python 命令]" in output
def test_format_with_platform(self):
"""测试有平台特殊配置的格式化输出。"""
output = format_advice(
"pdf",
"test.pdf",
"Darwin-x86_64",
"uv run --python 3.12 ...",
"python ...",
"pip install ...",
has_platform_specific=True
)
assert "平台: Darwin-x86_64" in output
class TestGenerateAdvice:
"""测试完整建议生成函数。"""
def test_generate_advice_pdf(self, readers):
"""测试生成 PDF 的建议。"""
advice = generate_advice("test.pdf", readers, "scripts/lyxy_document_reader.py")
assert advice is not None
assert "文件类型: PDF" in advice
assert "[uv 命令]" in advice
assert "[python 命令]" in advice
def test_generate_advice_url(self, readers):
"""测试生成 URL 的建议。"""
advice = generate_advice(
"https://example.com",
readers,
"scripts/lyxy_document_reader.py"
)
assert advice is not None
assert "文件类型: HTML" in advice
def test_generate_advice_unknown(self, readers):
"""测试生成未知类型的建议。"""
advice = generate_advice("test.xyz", readers, "scripts/lyxy_document_reader.py")
assert advice is None