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:
@@ -4,6 +4,41 @@ import pytest
|
||||
import os
|
||||
|
||||
|
||||
class TestCLIAdviceOption:
|
||||
"""测试 CLI --advice 参数功能。"""
|
||||
|
||||
def test_advice_option_pdf(self, cli_runner):
|
||||
"""测试 -a/--advice 选项对 PDF 文件。"""
|
||||
stdout, stderr, exit_code = cli_runner(["test.pdf", "-a"])
|
||||
|
||||
assert exit_code == 0
|
||||
assert "文件类型: PDF" in stdout
|
||||
assert "[uv 命令]" in stdout
|
||||
assert "[python 命令]" in stdout
|
||||
|
||||
def test_advice_option_docx(self, cli_runner):
|
||||
"""测试 --advice 选项对 DOCX 文件。"""
|
||||
stdout, stderr, exit_code = cli_runner(["test.docx", "--advice"])
|
||||
|
||||
assert exit_code == 0
|
||||
assert "文件类型: DOCX" in stdout
|
||||
|
||||
def test_advice_option_url(self, cli_runner):
|
||||
"""测试 --advice 选项对 URL。"""
|
||||
stdout, stderr, exit_code = cli_runner(["https://example.com", "--advice"])
|
||||
|
||||
assert exit_code == 0
|
||||
assert "文件类型: HTML" in stdout
|
||||
|
||||
def test_advice_option_unknown(self, cli_runner):
|
||||
"""测试 --advice 选项对未知文件类型。"""
|
||||
stdout, stderr, exit_code = cli_runner(["test.xyz", "--advice"])
|
||||
|
||||
assert exit_code != 0
|
||||
output = stdout + stderr
|
||||
assert "无法识别" in output or "错误" in output
|
||||
|
||||
|
||||
class TestCLIDefaultOutput:
|
||||
"""测试 CLI 默认输出功能。"""
|
||||
|
||||
|
||||
195
tests/test_core/test_advice_generator.py
Normal file
195
tests/test_core/test_advice_generator.py
Normal 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
|
||||
Reference in New Issue
Block a user