1
0
Files
PPTX/tests/integration/test_font_system.py
lanyuanxiaoyao bd12fce14b feat: 实现字体主题系统和东亚字体支持
实现完整的字体主题系统,支持可复用字体配置、预设类别和扩展属性。
同时修复中文字体渲染问题,确保 Source Han Sans 等东亚字体正确显示。

核心功能:
- 字体主题配置:metadata.fonts 和 fonts_default
- 三种引用方式:整体引用、继承覆盖、独立定义
- 预设字体类别:sans、serif、mono、cjk-sans、cjk-serif
- 扩展字体属性:family、underline、strikethrough、line_spacing、
  space_before、space_after、baseline、caps
- 表格字体字段:font 和 header_font 替代旧的 style.font_size
- 引用循环检测和属性继承链
- 模板字体继承支持

东亚字体修复:
- 添加 _set_font_with_eastasian() 方法
- 同时设置拉丁字体、东亚字体和复杂脚本字体
- 修复中文字符使用默认字体的问题

测试:
- 58 个单元测试覆盖所有字体系统功能
- 3 个集成测试验证端到端场景
- 移除旧语法相关测试

文档:
- 更新 README.md 添加字体主题系统使用说明
- 更新 README_DEV.md 添加技术文档
- 创建 4 个示例 YAML 文件
- 同步 delta specs 到主 specs

归档:
- 归档 font-theme-system 变更到 openspec/changes/archive/

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-03-05 10:38:59 +08:00

155 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
字体系统集成测试
本测试文件包含字体主题系统的集成测试,验证完整的工作流程:
1. 多行文本扩展属性应用
- 验证扩展属性line_spacing、space_before、space_after应用到所有段落
- 测试从 YAML 加载到渲染的完整流程
2. 模板字体继承
- 验证模板元素继承 fonts_default
- 测试内联模板的字体配置
3. 引用循环错误
- 验证循环引用在渲染时被检测并抛出错误
- 测试错误信息的准确性
测试策略:
- 使用临时 YAML 文件模拟真实场景
- 测试完整的加载 → 解析 → 渲染流程
- 验证错误处理和边界情况
注意:
- 这些测试验证字体系统与其他模块的集成
- 单元测试在 test_font_system.py 中
- 渲染器测试在 test_pptx_renderer.py 中
"""
import pytest
from pathlib import Path
from core.presentation import Presentation
from renderers.pptx_renderer import PptxGenerator
class TestMultilineTextExtendedProperties:
"""多行文本扩展属性应用集成测试"""
def test_multiline_text_with_extended_properties(self, tmp_path):
"""测试多行文本应用扩展属性到所有段落"""
# 创建测试 YAML 文件
yaml_content = """
metadata:
size: "16:9"
fonts:
body:
family: "Arial"
size: 18
line_spacing: 1.5
space_before: 12
space_after: 6
slides:
- elements:
- type: text
content: "第一行\\n第二行\\n第三行"
box: [1, 1, 8, 2]
font: "@body"
"""
yaml_file = tmp_path / "test.yaml"
yaml_file.write_text(yaml_content)
# 加载并渲染
pres = Presentation(yaml_file)
gen = PptxGenerator(pres.size, fonts=pres.fonts, fonts_default=pres.fonts_default)
slide_data = pres.data.get('slides', [])[0]
rendered = pres.render_slide(slide_data)
# 验证元素被正确解析
assert len(rendered['elements']) == 1
elem = rendered['elements'][0]
# YAML 会将 \n 解析为实际的换行符
assert elem.content == "第一行\n第二行\n第三行"
class TestTemplateFontInheritance:
"""模板字体继承集成测试"""
def test_template_inherits_fonts_default(self, tmp_path):
"""测试模板元素继承 fonts_default"""
# 创建测试 YAML 文件
yaml_content = """
metadata:
size: "16:9"
fonts:
body:
family: "Arial"
size: 18
color: "#333333"
fonts_default: "@body"
templates:
simple:
elements:
- type: text
content: "模板文本"
box: [1, 1, 8, 1]
slides:
- template: simple
"""
yaml_file = tmp_path / "test.yaml"
yaml_file.write_text(yaml_content)
# 加载并渲染
pres = Presentation(yaml_file)
gen = PptxGenerator(pres.size, fonts=pres.fonts, fonts_default=pres.fonts_default)
slide_data = pres.data.get('slides', [])[0]
rendered = pres.render_slide(slide_data)
# 验证模板元素被渲染
assert len(rendered['elements']) == 1
class TestCircularReferenceError:
"""引用循环错误集成测试"""
def test_circular_reference_in_yaml_raises_error(self, tmp_path):
"""测试 YAML 中的循环引用抛出错误"""
# 创建包含循环引用的 YAML 文件
yaml_content = """
metadata:
size: "16:9"
fonts:
a:
parent: "@b"
size: 44
b:
parent: "@a"
size: 18
slides:
- elements:
- type: text
content: "测试"
box: [1, 1, 8, 1]
font: "@a"
"""
yaml_file = tmp_path / "test.yaml"
yaml_file.write_text(yaml_content)
# 加载演示文稿
pres = Presentation(yaml_file)
gen = PptxGenerator(pres.size, fonts=pres.fonts, fonts_default=pres.fonts_default)
slide_data = pres.data.get('slides', [])[0]
# 渲染时应该抛出循环引用错误
with pytest.raises(ValueError, match="检测到字体引用循环"):
rendered = pres.render_slide(slide_data)
# 触发字体解析
for elem in rendered['elements']:
gen.font_resolver.resolve_font(elem.font)