""" Convert 命令端到端测试 测试 yaml2pptx.py convert 命令的完整功能 """ import pytest import subprocess import sys from pathlib import Path from pptx import Presentation class TestConvertCmd: """convert 命令测试类""" def run_convert(self, *args): """辅助函数:运行 convert 命令""" cmd = [sys.executable, "-m", "uv", "run", "python", "yaml2pptx.py", "convert"] cmd.extend(args) result = subprocess.run( cmd, capture_output=True, text=True, cwd=Path(__file__).parent.parent.parent ) return result def test_basic_conversion(self, sample_yaml, temp_dir): """测试基本转换""" output = temp_dir / "output.pptx" result = self.run_convert(str(sample_yaml), str(output)) assert result.returncode == 0 assert output.exists() assert output.stat().st_size > 0 def test_auto_output_filename(self, sample_yaml, temp_dir): """测试自动生成输出文件名""" # 在 temp_dir 中运行 result = subprocess.run( [sys.executable, "-m", "uv", "run", "python", "yaml2pptx.py", "convert", str(sample_yaml)], capture_output=True, text=True, cwd=temp_dir ) assert result.returncode == 0 # 应该生成与输入同名的 .pptx 文件 expected_output = temp_dir / "test.pptx" assert expected_output.exists() def test_conversion_with_template(self, temp_dir, sample_template): """测试使用模板转换""" yaml_content = f""" metadata: size: "16:9" slides: - template: title-slide vars: title: "Template Test" """ yaml_path = temp_dir / "test.yaml" yaml_path.write_text(yaml_content) output = temp_dir / "output.pptx" result = self.run_convert( str(yaml_path), str(output), "--template-dir", str(sample_template) ) assert result.returncode == 0 assert output.exists() def test_skip_validation(self, sample_yaml, temp_dir): """测试跳过验证""" output = temp_dir / "output.pptx" result = self.run_convert( str(sample_yaml), str(output), "--skip-validation" ) assert result.returncode == 0 assert output.exists() def test_force_overwrite(self, sample_yaml, temp_dir): """测试强制覆盖""" output = temp_dir / "output.pptx" # 先创建一个存在的文件 output.write_text("existing") # 使用 --force 应该覆盖 result = self.run_convert( str(sample_yaml), str(output), "--force" ) assert result.returncode == 0 # 文件应该是有效的 PPTX,不是原来的文本 assert output.stat().st_size > 1000 def test_existing_file_without_force(self, sample_yaml, temp_dir): """测试文件已存在且不使用 --force""" output = temp_dir / "output.pptx" # 先创建一个存在的文件 output.write_text("existing") # 不使用 --force 应该失败或提示 result = self.run_convert(str(sample_yaml), str(output)) # 程序应该拒绝覆盖 assert result.returncode != 0 or "已存在" in result.stderr def test_invalid_input_file(self, temp_dir): """测试无效输入文件""" nonexistent = temp_dir / "nonexistent.yaml" output = temp_dir / "output.pptx" result = self.run_convert(str(nonexistent), str(output)) assert result.returncode != 0 def test_conversion_with_all_element_types(self, temp_dir, sample_image): """测试转换包含所有元素类型的 YAML""" fixtures_yaml = Path(__file__).parent.parent / "fixtures" / "yaml_samples" / "full_features.yaml" if not fixtures_yaml.exists(): pytest.skip("full_features.yaml not found") output = temp_dir / "output.pptx" result = self.run_convert(str(fixtures_yaml), str(output)) assert result.returncode == 0 assert output.exists() # 验证生成的 PPTX prs = Presentation(str(output)) assert len(prs.slides) >= 1 def test_conversion_preserves_chinese_content(self, temp_dir): """测试转换保留中文内容""" yaml_content = """ metadata: size: "16:9" slides: - elements: - type: text box: [1, 1, 8, 1] content: "测试中文内容" font: size: 24 """ yaml_path = temp_dir / "test.yaml" yaml_path.write_text(yaml_content, encoding='utf-8') output = temp_dir / "output.pptx" result = self.run_convert(str(yaml_path), str(output)) assert result.returncode == 0 assert output.exists() # 验证内容 prs = Presentation(str(output)) text_content = prs.slides[0].shapes[0].text_frame.text assert "测试中文内容" in text_content def test_different_slide_sizes(self, temp_dir): """测试不同的幻灯片尺寸""" for size in ["16:9", "4:3"]: yaml_content = f""" metadata: size: {size} slides: - elements: - type: text box: [1, 1, 8, 1] content: "Size {size}" font: size: 24 """ yaml_path = temp_dir / f"test_{size.replace(':', '')}.yaml" yaml_path.write_text(yaml_content) output = temp_dir / f"output_{size.replace(':', '')}.pptx" result = self.run_convert(str(yaml_path), str(output)) assert result.returncode == 0, f"Failed for size {size}" assert output.exists() # 验证尺寸 prs = Presentation(str(output)) if size == "16:9": assert abs(prs.slide_width.inches - 10.0) < 0.01 assert abs(prs.slide_height.inches - 5.625) < 0.01 else: # 4:3 assert abs(prs.slide_width.inches - 10.0) < 0.01 assert abs(prs.slide_height.inches - 7.5) < 0.01