实现了统一的metadata结构和字体作用域系统,支持文档和模板库之间的单向字体引用。 主要变更: - 模板库必须包含metadata字段(包括size、fonts、fonts_default) - 实现文档和模板库的size一致性校验 - 实现字体作用域系统(文档可引用模板库字体,反之不可) - 实现跨域循环引用检测 - 实现fonts_default级联规则(模板库→文档→系统默认) - 添加错误代码常量(SIZE_MISMATCH、FONT_NOT_FOUND等) - 更新文档和开发者指南 测试覆盖: - 新增33个测试(单元测试20个,集成测试13个) - 所有457个测试通过 Breaking Changes: - 模板库文件必须包含metadata字段 - 模板库metadata.size为必填字段 - 文档和模板库的size必须一致 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
141 lines
4.2 KiB
Python
141 lines
4.2 KiB
Python
"""
|
|
fonts_default 级联和验证测试
|
|
"""
|
|
|
|
import pytest
|
|
from utils.font_resolver import FontResolver
|
|
from loaders.yaml_loader import validate_template_library_yaml, YAMLError
|
|
|
|
|
|
class TestFontsDefaultCascade:
|
|
"""fonts_default 级联测试类"""
|
|
|
|
def test_fonts_default_basic_resolution(self):
|
|
"""测试基本的 fonts_default 解析"""
|
|
fonts = {
|
|
"body": {"family": "Arial", "size": 18}
|
|
}
|
|
|
|
resolver = FontResolver(
|
|
fonts=fonts,
|
|
fonts_default="@body",
|
|
scope="document"
|
|
)
|
|
|
|
# 元素未定义 font 时使用 fonts_default
|
|
result = resolver.resolve_font(None)
|
|
assert result.family == "Arial"
|
|
assert result.size == 18
|
|
|
|
def test_document_fonts_default_can_reference_template_fonts(self):
|
|
"""测试文档 fonts_default 可以引用模板库字体"""
|
|
template_fonts = {
|
|
"base": {"family": "SimSun", "size": 18}
|
|
}
|
|
|
|
resolver = FontResolver(
|
|
fonts={},
|
|
fonts_default="@base",
|
|
scope="document",
|
|
template_fonts=template_fonts
|
|
)
|
|
|
|
result = resolver.resolve_font(None)
|
|
assert result.family == "SimSun"
|
|
assert result.size == 18
|
|
|
|
def test_fonts_default_with_parent_inheritance(self):
|
|
"""测试 fonts_default 的 parent 继承"""
|
|
fonts = {
|
|
"base": {"family": "Arial", "size": 18},
|
|
"body": {"parent": "@base", "color": "#000000"}
|
|
}
|
|
|
|
resolver = FontResolver(
|
|
fonts=fonts,
|
|
fonts_default="@body",
|
|
scope="document"
|
|
)
|
|
|
|
result = resolver.resolve_font(None)
|
|
assert result.family == "Arial"
|
|
assert result.size == 18
|
|
assert result.color == "#000000"
|
|
|
|
|
|
class TestTemplatLibraryFontsDefaultValidation:
|
|
"""模板库 fonts_default 验证测试类"""
|
|
|
|
def test_template_library_fonts_default_valid(self):
|
|
"""测试模板库 fonts_default 引用有效字体"""
|
|
data = {
|
|
"metadata": {
|
|
"size": "16:9",
|
|
"fonts": {
|
|
"base": {"family": "SimSun", "size": 18}
|
|
},
|
|
"fonts_default": "@base"
|
|
},
|
|
"templates": {
|
|
"test": {"elements": []}
|
|
}
|
|
}
|
|
|
|
# 应该不抛出异常
|
|
validate_template_library_yaml(data, "test.yaml")
|
|
|
|
def test_template_library_fonts_default_invalid_reference(self):
|
|
"""测试模板库 fonts_default 引用不存在的字体"""
|
|
data = {
|
|
"metadata": {
|
|
"size": "16:9",
|
|
"fonts": {
|
|
"base": {"family": "SimSun", "size": 18}
|
|
},
|
|
"fonts_default": "@nonexistent"
|
|
},
|
|
"templates": {
|
|
"test": {"elements": []}
|
|
}
|
|
}
|
|
|
|
# 应该抛出错误
|
|
with pytest.raises(YAMLError, match="fonts_default.*不存在"):
|
|
validate_template_library_yaml(data, "test.yaml")
|
|
|
|
def test_template_library_fonts_default_not_reference_format(self):
|
|
"""测试模板库 fonts_default 不是引用格式"""
|
|
data = {
|
|
"metadata": {
|
|
"size": "16:9",
|
|
"fonts": {
|
|
"base": {"family": "SimSun", "size": 18}
|
|
},
|
|
"fonts_default": "Arial"
|
|
},
|
|
"templates": {
|
|
"test": {"elements": []}
|
|
}
|
|
}
|
|
|
|
# 应该抛出错误
|
|
with pytest.raises(YAMLError, match="fonts_default 必须是引用格式"):
|
|
validate_template_library_yaml(data, "test.yaml")
|
|
|
|
def test_template_library_without_fonts_default(self):
|
|
"""测试模板库没有 fonts_default 时正常工作"""
|
|
data = {
|
|
"metadata": {
|
|
"size": "16:9",
|
|
"fonts": {
|
|
"base": {"family": "SimSun", "size": 18}
|
|
}
|
|
},
|
|
"templates": {
|
|
"test": {"elements": []}
|
|
}
|
|
}
|
|
|
|
# 应该不抛出异常
|
|
validate_template_library_yaml(data, "test.yaml")
|