""" 图片适配模式集成测试 测试图片 fit 模式在 PPTX 和 HTML 渲染中的完整流程。 """ import pytest from pathlib import Path from PIL import Image from pptx import Presentation from core.presentation import Presentation as CorePresentation from renderers.pptx_renderer import PptxGenerator from renderers.html_renderer import HtmlRenderer @pytest.fixture def test_image_path(tmp_path): """创建测试图片""" img_path = tmp_path / "test_image.png" # 创建 200x100 的测试图片 img = Image.new("RGB", (200, 100), color="red") img.save(img_path) return img_path @pytest.fixture def yaml_dir(tmp_path): """创建临时 YAML 目录""" return tmp_path class TestPptxImageFitModes: """测试 PPTX 渲染器的图片适配模式""" def test_stretch_mode(self, yaml_dir, test_image_path, tmp_path): """测试 stretch 模式的 PPTX 渲染""" yaml_content = f""" metadata: size: "16:9" dpi: 96 slides: - elements: - type: image src: "{test_image_path.name}" box: [1, 1, 4, 3] """ yaml_path = yaml_dir / "test.yaml" yaml_path.write_text(yaml_content) # 加载并渲染 pres = CorePresentation(str(yaml_path)) gen = PptxGenerator(size='16:9', dpi=96) for slide_data in pres.data.get('slides', []): rendered = pres.render_slide(slide_data) gen.add_slide(rendered, base_path=yaml_dir) # 保存并验证 output_path = tmp_path / "stretch.pptx" gen.save(output_path) assert output_path.exists() # 验证 PPTX 可以打开 pptx = Presentation(str(output_path)) assert len(pptx.slides) == 1 def test_contain_mode_larger_image(self, yaml_dir, tmp_path): """测试 contain 模式(图片比 box 大)""" # 创建 400x300 的大图片 img_path = yaml_dir / "large_image.png" img = Image.new("RGB", (400, 300), color="blue") img.save(img_path) yaml_content = f""" metadata: size: "16:9" dpi: 96 slides: - elements: - type: image src: "{img_path.name}" box: [1, 1, 3, 2] fit: contain """ yaml_path = yaml_dir / "test.yaml" yaml_path.write_text(yaml_content) pres = CorePresentation(str(yaml_path)) gen = PptxGenerator(size='16:9', dpi=96) for slide_data in pres.data.get('slides', []): rendered = pres.render_slide(slide_data) gen.add_slide(rendered, base_path=yaml_dir) output_path = tmp_path / "contain_large.pptx" gen.save(output_path) assert output_path.exists() def test_contain_mode_smaller_image(self, yaml_dir, tmp_path): """测试 contain 模式(图片比 box 小)""" # 创建 50x50 的小图片 img_path = yaml_dir / "small_image.png" img = Image.new("RGB", (50, 50), color="green") img.save(img_path) yaml_content = f""" metadata: size: "16:9" dpi: 96 slides: - elements: - type: image src: "{img_path.name}" box: [1, 1, 4, 3] fit: contain """ yaml_path = yaml_dir / "test.yaml" yaml_path.write_text(yaml_content) pres = CorePresentation(str(yaml_path)) gen = PptxGenerator(size='16:9', dpi=96) for slide_data in pres.data.get('slides', []): rendered = pres.render_slide(slide_data) gen.add_slide(rendered, base_path=yaml_dir) output_path = tmp_path / "contain_small.pptx" gen.save(output_path) assert output_path.exists() def test_contain_mode_with_background(self, yaml_dir, test_image_path, tmp_path): """测试 contain 模式(带背景色)""" yaml_content = f""" metadata: size: "16:9" dpi: 96 slides: - elements: - type: image src: "{test_image_path.name}" box: [1, 1, 4, 3] fit: contain background: "#f0f0f0" """ yaml_path = yaml_dir / "test.yaml" yaml_path.write_text(yaml_content) pres = CorePresentation(str(yaml_path)) gen = PptxGenerator(size='16:9', dpi=96) for slide_data in pres.data.get('slides', []): rendered = pres.render_slide(slide_data) gen.add_slide(rendered, base_path=yaml_dir) output_path = tmp_path / "contain_bg.pptx" gen.save(output_path) assert output_path.exists() def test_cover_mode(self, yaml_dir, test_image_path, tmp_path): """测试 cover 模式""" yaml_content = f""" metadata: size: "16:9" dpi: 96 slides: - elements: - type: image src: "{test_image_path.name}" box: [1, 1, 4, 3] fit: cover """ yaml_path = yaml_dir / "test.yaml" yaml_path.write_text(yaml_content) pres = CorePresentation(str(yaml_path)) gen = PptxGenerator(size='16:9', dpi=96) for slide_data in pres.data.get('slides', []): rendered = pres.render_slide(slide_data) gen.add_slide(rendered, base_path=yaml_dir) output_path = tmp_path / "cover.pptx" gen.save(output_path) assert output_path.exists() def test_center_mode_with_background(self, yaml_dir, test_image_path, tmp_path): """测试 center 模式(带背景色)""" yaml_content = f""" metadata: size: "16:9" dpi: 96 slides: - elements: - type: image src: "{test_image_path.name}" box: [1, 1, 4, 3] fit: center background: "#ffffff" """ yaml_path = yaml_dir / "test.yaml" yaml_path.write_text(yaml_content) pres = CorePresentation(str(yaml_path)) gen = PptxGenerator(size='16:9', dpi=96) for slide_data in pres.data.get('slides', []): rendered = pres.render_slide(slide_data) gen.add_slide(rendered, base_path=yaml_dir) output_path = tmp_path / "center_bg.pptx" gen.save(output_path) assert output_path.exists() def test_different_dpi_values(self, yaml_dir, test_image_path, tmp_path): """测试不同 DPI 配置""" for dpi in [72, 96, 150, 300]: yaml_content = f""" metadata: size: "16:9" dpi: {dpi} slides: - elements: - type: image src: "{test_image_path.name}" box: [1, 1, 4, 3] fit: contain """ yaml_path = yaml_dir / f"test_dpi_{dpi}.yaml" yaml_path.write_text(yaml_content) pres = CorePresentation(str(yaml_path)) gen = PptxGenerator(size='16:9', dpi=dpi) for slide_data in pres.data.get('slides', []): rendered = pres.render_slide(slide_data) gen.add_slide(rendered, base_path=yaml_dir) output_path = tmp_path / f"dpi_{dpi}.pptx" gen.save(output_path) assert output_path.exists() class TestHtmlImageFitModes: """测试 HTML 渲染器的图片适配模式""" def test_html_fit_modes(self, yaml_dir, test_image_path): """测试 HTML 渲染器的四种 fit 模式""" for fit_mode in ['stretch', 'contain', 'cover', 'center']: yaml_content = f""" metadata: size: "16:9" dpi: 96 slides: - elements: - type: image src: "{test_image_path.name}" box: [1, 1, 4, 3] fit: {fit_mode} """ yaml_path = yaml_dir / f"test_{fit_mode}.yaml" yaml_path.write_text(yaml_content) pres = CorePresentation(str(yaml_path)) renderer = HtmlRenderer(dpi=96) for slide_data in pres.data.get('slides', []): rendered = pres.render_slide(slide_data) html = renderer.render_slide(rendered, 0, base_path=yaml_dir) # 验证 HTML 包含图片元素 assert '