"""CLI 测试专用 fixtures。""" import pytest import sys from pathlib import Path from io import StringIO from contextlib import redirect_stdout, redirect_stderr @pytest.fixture def cli_runner(): """CLI 运行器 fixture,用于调用 main() 函数并捕获输出。 Returns: function: 接受 args 列表,返回 (stdout, stderr, exit_code) 元组 """ def _run_cli(args): """运行 CLI 并捕获输出。 Args: args: 命令行参数列表(不包含程序名) Returns: tuple: (stdout, stderr, exit_code) """ # 将 scripts/ 目录添加到 sys.path project_root = Path(__file__).resolve().parent.parent.parent # tests/test_cli/ 的父目录是 tests/,再父目录是项目根目录 scripts_dir = project_root / "scripts" if str(scripts_dir) not in sys.path: sys.path.insert(0, str(scripts_dir)) from lyxy_document_reader import main # 保存原始 sys.argv 和 sys.exit original_argv = sys.argv original_exit = sys.exit stdout_capture = StringIO() stderr_capture = StringIO() exit_code = 0 def mock_exit(code=0): nonlocal exit_code exit_code = code raise SystemExit(code) try: # 设置命令行参数 sys.argv = ['lyxy_document_reader'] + args sys.exit = mock_exit # 捕获输出 with redirect_stdout(stdout_capture), redirect_stderr(stderr_capture): try: main() except SystemExit: pass finally: # 恢复原始状态 sys.argv = original_argv sys.exit = original_exit return stdout_capture.getvalue(), stderr_capture.getvalue(), exit_code return _run_cli @pytest.fixture def temp_test_file(tmp_path, temp_docx, temp_pdf, temp_html, temp_pptx, temp_xlsx): """根据格式类型创建临时测试文件的 fixture 工厂。 Args: format_type: 文件格式类型 ('docx', 'pdf', 'html', 'pptx', 'xlsx') **kwargs: 传递给对应 fixture 的参数 Returns: str: 临时文件路径 """ def _create_file(format_type, **kwargs): if format_type == 'docx': return temp_docx(**kwargs) elif format_type == 'pdf': return temp_pdf(**kwargs) elif format_type == 'html': return temp_html(**kwargs) elif format_type == 'pptx': return temp_pptx(**kwargs) elif format_type == 'xlsx': return temp_xlsx(**kwargs) else: raise ValueError(f"不支持的格式类型: {format_type}") return _create_file