feat: 实现模板库metadata和跨域字体引用系统
实现了统一的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>
This commit is contained in:
@@ -2,17 +2,22 @@
|
||||
|
||||
## Purpose
|
||||
|
||||
字体主题系统提供可复用的字体配置管理能力,允许用户在 metadata 中定义字体配置模板,通过引用方式应用到元素,实现统一的字体样式管理。
|
||||
字体主题系统提供可复用的字体配置管理能力,允许用户在 metadata 中定义字体配置模板,通过引用方式应用到元素,实现统一的字体样式管理。支持文档和模板库的字体作用域隔离,以及跨域字体引用。
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: 系统必须支持在 metadata 中定义 fonts 字段
|
||||
|
||||
系统 SHALL 支持在 YAML metadata 中定义 fonts 字段,用于存储可复用的字体配置。
|
||||
系统 SHALL 支持在文档和模板库的 YAML metadata 中定义 fonts 字段,用于存储可复用的字体配置。模板库的 fonts 与文档的 fonts 使用相同的定义和验证规则。
|
||||
|
||||
#### Scenario: 定义 fonts 字段
|
||||
#### Scenario: 定义 fonts 字段(文档)
|
||||
|
||||
- **WHEN** metadata 中定义 fonts 字段
|
||||
- **WHEN** 文档 metadata 中定义 fonts 字段
|
||||
- **THEN** 系统成功解析并存储字体配置字典
|
||||
|
||||
#### Scenario: 定义 fonts 字段(模板库)
|
||||
|
||||
- **WHEN** 模板库 metadata 中定义 fonts 字段
|
||||
- **THEN** 系统成功解析并存储字体配置字典
|
||||
|
||||
#### Scenario: fonts 字段为空字典
|
||||
@@ -39,15 +44,48 @@ fonts 字段 SHALL 包含一个或多个命名字体配置,每个配置是一
|
||||
- **WHEN** fonts 中定义 title、subtitle、body 等多个配置
|
||||
- **THEN** 系统为每个配置创建独立的字体对象
|
||||
|
||||
### Requirement: 文档 metadata 必须支持 version 和 author 字段
|
||||
|
||||
文档 metadata SHALL 支持可选的 `version` 和 `author` 字段。
|
||||
|
||||
#### Scenario: 文档包含 version 和 author
|
||||
|
||||
- **WHEN** 文档 metadata 包含 version: "1.0" 和 author: "作者名"
|
||||
- **THEN** 系统成功解析并存储这些字段
|
||||
|
||||
#### Scenario: 文档不包含 version 和 author
|
||||
|
||||
- **WHEN** 文档 metadata 不包含 version 和 author 字段
|
||||
- **THEN** 系统正常处理,这些字段为可选项
|
||||
|
||||
### Requirement: 系统必须支持 fonts_default 字段
|
||||
|
||||
系统 SHALL 支持在 metadata 中定义可选的 fonts_default 字段,指定默认字体配置的引用。
|
||||
系统 SHALL 支持在文档和模板库的 metadata 中定义可选的 fonts_default 字段,指定默认字体配置的引用。文档的 fonts_default 可以引用文档或模板库的 fonts,模板库的 fonts_default 只能引用模板库的 fonts。
|
||||
|
||||
#### Scenario: 定义 fonts_default 引用
|
||||
#### Scenario: 定义 fonts_default 引用(文档)
|
||||
|
||||
- **WHEN** metadata 中定义 fonts_default: "@body"
|
||||
- **WHEN** 文档 metadata 中定义 fonts_default: "@body"
|
||||
- **AND** body 存在于文档 metadata.fonts 中
|
||||
- **THEN** 系统将 fonts_default 解析为对 fonts.body 的引用
|
||||
|
||||
#### Scenario: 定义 fonts_default 引用(模板库)
|
||||
|
||||
- **WHEN** 模板库 metadata 中定义 fonts_default: "@base"
|
||||
- **AND** base 存在于模板库 metadata.fonts 中
|
||||
- **THEN** 系统将 fonts_default 解析为对 fonts.base 的引用
|
||||
|
||||
#### Scenario: 文档 fonts_default 引用模板库字体
|
||||
|
||||
- **WHEN** 文档 metadata.fonts_default: "@template-base"
|
||||
- **AND** template-base 存在于模板库 metadata.fonts 中
|
||||
- **THEN** 系统成功解析默认字体
|
||||
|
||||
#### Scenario: 模板库 fonts_default 不能引用文档字体
|
||||
|
||||
- **WHEN** 模板库 metadata.fonts_default: "@doc-body"
|
||||
- **AND** doc-body 只存在于文档 metadata.fonts 中
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `FONT_DEFAULT_INVALID`
|
||||
|
||||
#### Scenario: fonts_default 未定义
|
||||
|
||||
- **WHEN** metadata 中未定义 fonts_default 字段
|
||||
@@ -55,27 +93,82 @@ fonts 字段 SHALL 包含一个或多个命名字体配置,每个配置是一
|
||||
|
||||
#### Scenario: fonts_default 引用不存在的配置
|
||||
|
||||
- **WHEN** fonts_default: "@undefined" 且 fonts.undefined 不存在
|
||||
- **THEN** 系统抛出 ERROR,提示引用的字体配置不存在
|
||||
- **WHEN** fonts_default: "@undefined" 且 undefined 不存在
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `FONT_DEFAULT_INVALID`
|
||||
|
||||
#### Scenario: fonts_default 必须引用 fonts 中的配置
|
||||
#### Scenario: fonts_default 必须是引用格式
|
||||
|
||||
- **WHEN** fonts_default: "Arial"(直接字体名称)
|
||||
- **THEN** 系统抛出 ERROR,提示 fonts_default 必须是引用格式
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `FONT_DEFAULT_INVALID`
|
||||
|
||||
### Requirement: 元素 font 字段必须支持三种引用方式
|
||||
### Requirement: 文档元素和内联模板元素必须支持跨域引用字体
|
||||
|
||||
元素 font 字段 SHALL 支持字符串引用(整体引用)、字典引用(继承覆盖或独立定义)两种形式。
|
||||
文档中的元素和内联模板(文档中定义的 templates)中的元素 SHALL 优先引用文档的 fonts,文档没有时可引用模板库的 fonts。
|
||||
|
||||
#### Scenario: 字符串整体引用
|
||||
#### Scenario: 元素引用文档中存在的字体
|
||||
|
||||
- **WHEN** 元素定义 font: "@title"
|
||||
- **THEN** 系统使用 fonts.title 的所有属性
|
||||
- **WHEN** 文档元素定义 font: "@title"
|
||||
- **AND** title 存在于文档 metadata.fonts 中
|
||||
- **THEN** 系统使用文档的 title 配置
|
||||
|
||||
#### Scenario: 元素引用文档不存在但模板库存在的字体
|
||||
|
||||
- **WHEN** 文档元素定义 font: "@template-title"
|
||||
- **AND** template-title 不存在于文档 fonts 中
|
||||
- **AND** template-title 存在于模板库 metadata.fonts 中
|
||||
- **THEN** 系统使用模板库的 template-title 配置
|
||||
|
||||
#### Scenario: 元素引用不存在的字体(文档和模板库都没有)
|
||||
|
||||
- **WHEN** 文档元素定义 font: "@nonexistent"
|
||||
- **AND** nonexistent 不存在于文档和模板库的 fonts 中
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `FONT_NOT_FOUND`
|
||||
- **AND** 错误消息包含"引用的字体配置不存在"
|
||||
|
||||
#### Scenario: 同名字体时优先使用文档的
|
||||
|
||||
- **WHEN** 文档元素定义 font: "@title"
|
||||
- **AND** title 同时存在于文档 fonts 和模板库 fonts 中
|
||||
- **THEN** 系统使用文档的 title 配置(不使用模板库的)
|
||||
|
||||
#### Scenario: 内联模板元素引用文档字体
|
||||
|
||||
- **WHEN** 内联模板(文档 templates 中定义)的元素定义 font: "@body"
|
||||
- **AND** body 存在于文档 metadata.fonts 中
|
||||
- **THEN** 系统使用文档的 body 配置
|
||||
|
||||
#### Scenario: 内联模板元素引用模板库字体
|
||||
|
||||
- **WHEN** 内联模板的元素定义 font: "@template-body"
|
||||
- **AND** template-body 只存在于模板库 metadata.fonts 中
|
||||
- **THEN** 系统使用模板库的 template-body 配置
|
||||
|
||||
### Requirement: 元素 font 字段必须支持多种引用方式
|
||||
|
||||
元素 font 字段 SHALL 支持字符串引用(整体引用)、字典引用(继承覆盖或独立定义)两种形式。引用的目标根据元素所在作用域决定。
|
||||
|
||||
#### Scenario: 文档元素引用文档字体
|
||||
|
||||
- **WHEN** 文档元素定义 font: "@title"
|
||||
- **AND** title 存在于文档 metadata.fonts 中
|
||||
- **THEN** 系统使用文档的 title 配置
|
||||
|
||||
#### Scenario: 文档元素引用模板库字体
|
||||
|
||||
- **WHEN** 文档元素定义 font: "@template-title"
|
||||
- **AND** template-title 只存在于模板库 metadata.fonts 中
|
||||
- **THEN** 系统使用模板库的 template-title 配置
|
||||
|
||||
#### Scenario: 模板元素只能引用模板库字体
|
||||
|
||||
- **WHEN** 外部模板元素定义 font: "@title"
|
||||
- **AND** title 只存在于文档 metadata.fonts 中
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `TEMPLATE_FONT_REF_DOC_FORBIDDEN`
|
||||
|
||||
#### Scenario: 字典继承覆盖
|
||||
|
||||
- **WHEN** 元素定义 font: {parent: "@title", size: 60}
|
||||
- **THEN** 系统继承 fonts.title 的所有属性,覆盖 size 为 60
|
||||
- **THEN** 系统继承引用字体的所有属性,覆盖 size 为 60
|
||||
|
||||
#### Scenario: 字典独立定义
|
||||
|
||||
@@ -87,40 +180,131 @@ fonts 字段 SHALL 包含一个或多个命名字体配置,每个配置是一
|
||||
- **WHEN** 元素未定义 font 字段
|
||||
- **THEN** 元素使用 fonts_default 或系统默认字体
|
||||
|
||||
### Requirement: parent 字段必须引用 fonts 中的配置
|
||||
### Requirement: 文档 fonts 的 parent 必须支持跨域引用
|
||||
|
||||
font 字典中的 parent 字段 SHALL 引用 fonts 中已定义的配置名称。
|
||||
文档 metadata.fonts 中定义的字体配置,其 parent 字段 SHALL 可以引用文档内部的字体配置或模板库的字体配置。
|
||||
|
||||
#### Scenario: parent 引用存在的配置
|
||||
#### Scenario: parent 引用文档内部的字体
|
||||
|
||||
- **WHEN** parent: "@title" 且 fonts.title 存在
|
||||
- **THEN** 系统成功继承 fonts.title 的属性
|
||||
- **WHEN** 文档 metadata.fonts 中定义 heading: {parent: "@base"}
|
||||
- **AND** base 存在于文档 fonts 中
|
||||
- **THEN** 系统成功继承 base 的属性
|
||||
|
||||
#### Scenario: parent 引用模板库的字体
|
||||
|
||||
- **WHEN** 文档 metadata.fonts 中定义 custom: {parent: "@template-base"}
|
||||
- **AND** template-base 存在于模板库 metadata.fonts 中
|
||||
- **THEN** 系统成功继承 template-base 的属性
|
||||
|
||||
#### Scenario: parent 引用不存在的字体(文档和模板库都没有)
|
||||
|
||||
- **WHEN** 文档 metadata.fonts 中定义 heading: {parent: "@nonexistent"}
|
||||
- **AND** nonexistent 不存在于文档和模板库的 fonts 中
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `FONT_NOT_FOUND`
|
||||
- **AND** 错误消息包含"引用的字体配置不存在"
|
||||
|
||||
#### Scenario: 同名字体时 parent 优先引用文档的
|
||||
|
||||
- **WHEN** 文档 metadata.fonts 中定义 heading: {parent: "@base"}
|
||||
- **AND** base 同时存在于文档 fonts 和模板库 fonts 中
|
||||
- **THEN** 系统使用文档的 base 配置
|
||||
|
||||
### Requirement: parent 字段必须引用有效域中的字体配置
|
||||
|
||||
font 字典中的 parent 字段 SHALL 引用有效域中的配置。文档 fonts 的 parent 可以引用文档或模板库的 fonts,模板库 fonts 的 parent 只能引用模板库的 fonts。
|
||||
|
||||
#### Scenario: 文档字体 parent 引用文档字体
|
||||
|
||||
- **WHEN** 文档 fonts 中定义 heading: {parent: "@title"}
|
||||
- **AND** title 存在于文档 metadata.fonts 中
|
||||
- **THEN** 系统成功继承 title 的属性
|
||||
|
||||
#### Scenario: 文档字体 parent 引用模板库字体
|
||||
|
||||
- **WHEN** 文档 fonts 中定义 custom: {parent: "@template-base"}
|
||||
- **AND** template-base 存在于模板库 metadata.fonts 中
|
||||
- **THEN** 系统成功继承 template-base 的属性
|
||||
|
||||
#### Scenario: 模板库字体 parent 引用模板库字体
|
||||
|
||||
- **WHEN** 模板库 fonts 中定义 heading: {parent: "@base"}
|
||||
- **AND** base 存在于模板库 metadata.fonts 中
|
||||
- **THEN** 系统成功继承 base 的属性
|
||||
|
||||
#### Scenario: 模板库字体 parent 引用文档字体(禁止)
|
||||
|
||||
- **WHEN** 模板库 fonts 中定义 custom: {parent: "@doc-base"}
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `TEMPLATE_PARENT_REF_DOC_FORBIDDEN`
|
||||
|
||||
#### Scenario: parent 引用不存在的配置
|
||||
|
||||
- **WHEN** parent: "@undefined" 且 fonts.undefined 不存在
|
||||
- **THEN** 系统抛出 ERROR,提示引用的字体配置不存在
|
||||
- **WHEN** parent: "@undefined" 且 undefined 不存在
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `FONT_NOT_FOUND`
|
||||
|
||||
#### Scenario: parent 必须是引用格式
|
||||
|
||||
- **WHEN** parent: "Arial"(直接字体名称)
|
||||
- **THEN** 系统抛出 ERROR,提示 parent 必须是引用格式
|
||||
- **THEN** 系统抛出 ERROR
|
||||
|
||||
### Requirement: 系统必须检测跨域循环引用
|
||||
|
||||
系统 SHALL 在解析字体引用时检测跨域循环引用,包括文档和模板库之间的循环。
|
||||
|
||||
#### Scenario: 文档内部循环引用
|
||||
|
||||
- **WHEN** 文档 fonts.a.parent: "@b" 且 fonts.b.parent: "@a"
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `CIRCULAR_REFERENCE`
|
||||
- **AND** 错误消息包含"检测到字体引用循环"和完整路径
|
||||
|
||||
#### Scenario: 模板库内部循环引用
|
||||
|
||||
- **WHEN** 模板库 fonts.x.parent: "@y" 且 fonts.y.parent: "@x"
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `CIRCULAR_REFERENCE`
|
||||
- **AND** 错误消息包含"检测到字体引用循环"和完整路径
|
||||
|
||||
#### Scenario: 跨域循环引用
|
||||
|
||||
- **WHEN** 文档 fonts.a.parent: "@template-b"
|
||||
- **AND** 模板库 fonts.b.parent: "@template-c"
|
||||
- **AND** 模板库 fonts.c.parent: "@doc-a"
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `CIRCULAR_REFERENCE`
|
||||
- **AND** 错误消息包含"检测到跨域字体引用循环"和完整路径
|
||||
|
||||
#### Scenario: 跨域引用链不循环
|
||||
|
||||
- **WHEN** 文档 fonts.a.parent: "@template-b"
|
||||
- **AND** 模板库 fonts.b.parent: "@template-c"
|
||||
- **AND** 模板库 fonts.c 没有引用其他字体
|
||||
- **THEN** 系统成功解析,不报错
|
||||
|
||||
### Requirement: 系统必须检测并拒绝引用循环
|
||||
|
||||
系统 SHALL 在解析字体引用时检测循环引用,检测到循环时抛出 ERROR。
|
||||
系统 SHALL 在解析字体引用时检测循环引用,包括单域内部循环和跨域循环,检测到循环时抛出 ERROR。
|
||||
|
||||
#### Scenario: 直接循环引用
|
||||
|
||||
- **WHEN** fonts.title.parent: "@title"(引用自身)
|
||||
- **THEN** 系统抛出 ERROR,提示检测到自引用
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `CIRCULAR_REFERENCE`
|
||||
|
||||
#### Scenario: 间接循环引用
|
||||
#### Scenario: 间接循环引用(单域)
|
||||
|
||||
- **WHEN** fonts.a.parent: "@b" 且 fonts.b.parent: "@a"
|
||||
- **THEN** 系统抛出 ERROR,显示完整的引用循环路径
|
||||
|
||||
#### Scenario: 深层循环引用
|
||||
#### Scenario: 跨域循环引用
|
||||
|
||||
- **WHEN** 文档 fonts.a 引用模板库 fonts.b
|
||||
- **AND** 模板库 fonts.b 引用模板库 fonts.c
|
||||
- **AND** 模板库 fonts.c 引用文档 fonts.a
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `CIRCULAR_REFERENCE`
|
||||
- **AND** 错误消息包含"检测到跨域字体引用循环"
|
||||
|
||||
#### Scenario: 深层引用但不循环
|
||||
|
||||
- **WHEN** 引用链深度超过 5 层但没有循环
|
||||
- **THEN** 系统成功解析
|
||||
|
||||
#### Scenario: 引用链深度超过限制
|
||||
|
||||
- **WHEN** 引用链深度超过 10 层
|
||||
- **THEN** 系统抛出 ERROR,提示引用深度超限
|
||||
@@ -128,17 +312,64 @@ font 字典中的 parent 字段 SHALL 引用 fonts 中已定义的配置名称
|
||||
#### Scenario: 错误信息包含引用路径
|
||||
|
||||
- **WHEN** 系统检测到循环引用
|
||||
- **THEN** 错误信息包含完整的引用路径,如 "fonts.title -> fonts.subtitle -> fonts.title"
|
||||
- **THEN** 错误信息包含完整的引用路径
|
||||
|
||||
### Requirement: 文档和模板库的 fonts_default 必须独立验证
|
||||
|
||||
文档的 metadata.fonts_default SHALL 只能引用文档或模板库中存在的字体配置,模板库的 metadata.fonts_default SHALL 只能引用模板库中存在的字体配置。
|
||||
|
||||
#### Scenario: 文档 fonts_default 引用文档字体
|
||||
|
||||
- **WHEN** 文档 metadata.fonts_default: "@body"
|
||||
- **AND** body 存在于文档 metadata.fonts 中
|
||||
- **THEN** 系统成功解析默认字体
|
||||
|
||||
#### Scenario: 文档 fonts_default 引用模板库字体
|
||||
|
||||
- **WHEN** 文档 metadata.fonts_default: "@template-base"
|
||||
- **AND** template-base 存在于模板库 metadata.fonts 中
|
||||
- **THEN** 系统成功解析默认字体
|
||||
|
||||
#### Scenario: 文档 fonts_default 引用不存在的字体
|
||||
|
||||
- **WHEN** 文档 metadata.fonts_default: "@nonexistent"
|
||||
- **AND** nonexistent 不存在于文档和模板库的 fonts 中
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `FONT_DEFAULT_INVALID`
|
||||
- **AND** 错误消息包含"fonts_default 引用的字体配置不存在"
|
||||
|
||||
#### Scenario: 模板库 fonts_default 引用模板库字体
|
||||
|
||||
- **WHEN** 模板库 metadata.fonts_default: "@base"
|
||||
- **AND** base 存在于模板库 metadata.fonts 中
|
||||
- **THEN** 系统成功解析默认字体
|
||||
|
||||
#### Scenario: 模板库 fonts_default 引用文档字体
|
||||
|
||||
- **WHEN** 模板库 metadata.fonts_default: "@doc-body"
|
||||
- **AND** doc-body 只存在于文档 metadata.fonts 中
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `FONT_DEFAULT_INVALID`
|
||||
- **AND** 错误消息包含"模板库 fonts_default 只能引用模板库内部的字体配置"
|
||||
|
||||
### Requirement: 系统必须支持属性继承链
|
||||
|
||||
字体属性解析 SHALL 按照优先级顺序继承:parent → 当前定义 → fonts_default → 系统默认。
|
||||
字体属性解析 SHALL 按照优先级顺序继承:parent → 当前定义 → fonts_default → 系统默认。跨域继承时,文档可继承模板库的,模板库不能继承文档的。
|
||||
|
||||
#### Scenario: parent 定义了基础属性
|
||||
|
||||
- **WHEN** fonts.title 定义 size: 44,元素定义 font: {parent: "@title", bold: true}
|
||||
- **THEN** 元素使用 size: 44(继承)、bold: true(覆盖)
|
||||
|
||||
#### Scenario: 文档字体 parent 继承模板库字体属性
|
||||
|
||||
- **WHEN** 文档 fonts.custom 定义 parent: "@template-base"
|
||||
- **AND** 模板库 fonts.base 定义 family: "Arial", size: 18
|
||||
- **THEN** custom 继承 family 和 size
|
||||
|
||||
#### Scenario: 模板库字体 parent 不能继承文档字体属性
|
||||
|
||||
- **WHEN** 模板库 fonts.custom 定义 parent: "@doc-base"
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `TEMPLATE_PARENT_REF_DOC_FORBIDDEN`
|
||||
|
||||
#### Scenario: parent 未定义的属性继承 fonts_default
|
||||
|
||||
- **WHEN** fonts_default 定义 size: 18,元素定义 font: {parent: "@title"} 且 title 未定义 size
|
||||
@@ -151,12 +382,25 @@ font 字典中的 parent 字段 SHALL 引用 fonts 中已定义的配置名称
|
||||
|
||||
### Requirement: 模板元素必须支持继承 fonts_default
|
||||
|
||||
模板中未定义 font 的元素 SHALL 继承 metadata.fonts_default 配置。
|
||||
模板中未定义 font 的元素 SHALL 继承 fonts_default 配置。对于外部模板,级联顺序为:文档 fonts_default → 模板库 fonts_default → 系统默认。
|
||||
|
||||
#### Scenario: 模板元素未定义 font
|
||||
#### Scenario: 外部模板元素未定义 font,文档有 fonts_default
|
||||
|
||||
- **WHEN** 模板元素未定义 font 字段
|
||||
- **THEN** 元素继承 metadata.fonts_default 的配置
|
||||
- **WHEN** 外部模板元素未定义 font
|
||||
- **AND** 文档定义了 metadata.fonts_default: "@body"
|
||||
- **THEN** 元素使用文档的 fonts_default 配置
|
||||
|
||||
#### Scenario: 外部模板元素未定义 font,文档没有 fonts_default
|
||||
|
||||
- **WHEN** 外部模板元素未定义 font
|
||||
- **AND** 文档未定义 fonts_default
|
||||
- **AND** 模板库定义了 metadata.fonts_default: "@base"
|
||||
- **THEN** 元素使用模板库的 fonts_default 配置
|
||||
|
||||
#### Scenario: 内联模板元素未定义 font
|
||||
|
||||
- **WHEN** 内联模板(文档中定义)元素未定义 font
|
||||
- **THEN** 元素继承文档的 fonts_default 配置
|
||||
|
||||
#### Scenario: 模板元素定义了 font
|
||||
|
||||
@@ -165,7 +409,8 @@ font 字典中的 parent 字段 SHALL 引用 fonts 中已定义的配置名称
|
||||
|
||||
#### Scenario: fonts_default 未定义时模板元素行为
|
||||
|
||||
- **WHEN** 模板元素未定义 font 且 metadata 未定义 fonts_default
|
||||
- **WHEN** 模板元素未定义 font
|
||||
- **AND** 文档和模板库都未定义 fonts_default
|
||||
- **THEN** 元素使用系统默认字体
|
||||
|
||||
### Requirement: 表格元素必须支持 font 和 header_font 字段
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Purpose
|
||||
|
||||
Template library 提供集中的模板管理机制,允许将多个模板定义存储在单个 YAML 文件中,通过模板名称引用。
|
||||
Template library 提供集中的模板管理机制,允许将多个模板定义存储在单个 YAML 文件中,通过模板名称引用。模板库支持独立的 metadata 结构,包括字体主题和尺寸定义。
|
||||
|
||||
## Requirements
|
||||
|
||||
@@ -28,20 +28,173 @@ Template library 提供集中的模板管理机制,允许将多个模板定义
|
||||
- **THEN** 系统抛出错误,错误代码为 `TEMPLATE_LIBRARY_MISSING_TEMPLATES_FIELD`
|
||||
- **AND** 错误消息包含"'templates' 必须是字典"
|
||||
|
||||
### Requirement: 模板库文件必须支持元数据字段
|
||||
### Requirement: 模板库文件必须包含元数据字段
|
||||
|
||||
模板库文件 SHALL 支持可选的元数据字段,包括 `description`、`version`、`author` 等。
|
||||
模板库文件 SHALL 必须包含 metadata 字段,元数据结构与文档相同,包含 `size`(必填)、`version`、`author`、`description`、`fonts`、`fonts_default`。
|
||||
|
||||
#### Scenario: 加载包含元数据的模板库文件
|
||||
#### Scenario: 加载包含完整元数据的模板库文件
|
||||
|
||||
- **WHEN** 模板库文件包含 `description`、`version`、`author` 等字段
|
||||
- **WHEN** 模板库文件包含 metadata 字段,包含 size、version、author、description、fonts、fonts_default
|
||||
- **THEN** 系统成功加载这些元数据字段
|
||||
- **AND** 元数据不影响模板的加载和使用
|
||||
- **AND** size 字段必须为有效值
|
||||
- **AND** fonts 和 fonts_default 按字体主题规则验证
|
||||
|
||||
#### Scenario: 不包含元数据字段时正常加载
|
||||
#### Scenario: 模板库 metadata 缺少必填的 size 字段
|
||||
|
||||
- **WHEN** 模板库文件仅包含 `templates` 字段,不包含任何元数据
|
||||
- **THEN** 系统正常加载,不要求元数据字段
|
||||
- **WHEN** 模板库 metadata 中缺少 size 字段
|
||||
- **THEN** 系统抛出错误,错误代码为 `TEMPLATE_LIBRARY_METADATA_MISSING_SIZE`
|
||||
|
||||
#### Scenario: 模板库缺少 metadata 字段
|
||||
|
||||
- **WHEN** 模板库文件不包含 metadata 字段
|
||||
- **THEN** 系统抛出错误,错误代码为 `TEMPLATE_LIBRARY_MISSING_METADATA`
|
||||
- **AND** 错误消息包含"模板库必须包含 metadata 字段"
|
||||
|
||||
### Requirement: 模板库必须包含 metadata 结构
|
||||
|
||||
模板库文件 SHALL 必须包含 metadata 字段,与文档使用相同的结构,包含 `size`(必填)、`version`、`author`、`description`、`fonts`、`fonts_default`。
|
||||
|
||||
#### Scenario: 模板库包含完整的 metadata
|
||||
|
||||
- **WHEN** 模板库文件包含 metadata 字段,包含 size、version、author、description、fonts、fonts_default
|
||||
- **THEN** 系统成功解析并存储这些元数据
|
||||
|
||||
#### Scenario: 模板库缺少 metadata 字段
|
||||
|
||||
- **WHEN** 模板库文件不包含 metadata 字段
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `TEMPLATE_LIBRARY_MISSING_METADATA`
|
||||
- **AND** 错误消息包含"模板库必须包含 metadata 字段"
|
||||
|
||||
#### Scenario: 模板库 metadata 缺少 size 字段
|
||||
|
||||
- **WHEN** 模板库包含 metadata 但缺少 size 字段
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `TEMPLATE_LIBRARY_METADATA_MISSING_SIZE`
|
||||
- **AND** 错误消息包含"模板库 metadata 缺少必填字段 'size'"
|
||||
|
||||
#### Scenario: 模板库 metadata 的 size 值无效
|
||||
|
||||
- **WHEN** 模板库 metadata.size 不是有效的尺寸值(如 "16:9" 或 "4:3")
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `TEMPLATE_LIBRARY_METADATA_INVALID_SIZE`
|
||||
|
||||
### Requirement: 模板库 metadata 必须使用与文档相同的验证规则
|
||||
|
||||
模板库 metadata 的字段验证 SHALL 与文档 metadata 使用相同的规则。
|
||||
|
||||
#### Scenario: 模板库 metadata.fonts 验证
|
||||
|
||||
- **WHEN** 模板库 metadata.fonts 中定义字体配置
|
||||
- **THEN** 系统使用与文档 fonts 相同的验证规则
|
||||
|
||||
#### Scenario: 模板库 metadata.fonts_default 验证
|
||||
|
||||
- **WHEN** 模板库 metadata.fonts_default 引用字体配置
|
||||
- **THEN** 系统验证引用存在于模板库 metadata.fonts 中
|
||||
|
||||
#### Scenario: 模板库 metadata.version 和 author 可选
|
||||
|
||||
- **WHEN** 模板库 metadata 包含或不含 version、author 字段
|
||||
- **THEN** 系统正常处理,这些字段为可选项
|
||||
|
||||
### Requirement: 系统必须校验文档和模板库的 size 一致性
|
||||
|
||||
系统 SHALL 在加载模板库时校验文档的 metadata.size 与模板库的 metadata.size 是否一致。
|
||||
|
||||
#### Scenario: 文档和模板库 size 一致
|
||||
|
||||
- **WHEN** 文档 metadata.size 为 "16:9" 且模板库 metadata.size 也为 "16:9"
|
||||
- **THEN** 系统正常加载,不报错
|
||||
|
||||
#### Scenario: 文档和模板库 size 不一致
|
||||
|
||||
- **WHEN** 文档 metadata.size 为 "16:9" 但模板库 metadata.size 为 "4:3"
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `SIZE_MISMATCH`
|
||||
- **AND** 错误消息包含"文档尺寸 '16:9' 与模板库尺寸 '4:3' 不一致"
|
||||
|
||||
### Requirement: 模板库 fonts 的 parent 只能引用模板库内部
|
||||
|
||||
模板库 metadata.fonts 中定义的字体配置,其 parent 字段 SHALL 只能引用模板库内部的字体配置。
|
||||
|
||||
#### Scenario: parent 引用模板库内部的字体
|
||||
|
||||
- **WHEN** 模板库 metadata.fonts 中定义 heading: {parent: "@base"} 且 base 存在于模板库 fonts 中
|
||||
- **THEN** 系统成功解析继承关系
|
||||
|
||||
#### Scenario: parent 引用文档的字体
|
||||
|
||||
- **WHEN** 模板库 metadata.fonts 中定义 custom: {parent: "@doc-font"}
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `TEMPLATE_PARENT_REF_DOC_FORBIDDEN`
|
||||
- **AND** 错误消息包含"模板库字段的 parent 不能引用文档的字体配置"
|
||||
|
||||
#### Scenario: parent 引用不存在的字体
|
||||
|
||||
- **WHEN** 模板库 metadata.fonts 中定义 heading: {parent: "@nonexistent"}
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `FONT_NOT_FOUND`
|
||||
- **AND** 错误消息包含"引用的字体配置不存在"
|
||||
|
||||
### Requirement: 外部模板元素只能引用模板库的 fonts
|
||||
|
||||
外部模板(模板库中定义的模板)中的元素 SHALL 只能引用模板库 metadata.fonts 中定义的字体配置。
|
||||
|
||||
#### Scenario: 模板元素引用模板库的字体
|
||||
|
||||
- **WHEN** 外部模板元素定义 font: "@title" 且 title 存在于模板库 fonts 中
|
||||
- **THEN** 系统成功应用字体配置
|
||||
|
||||
#### Scenario: 模板元素引用文档的字体
|
||||
|
||||
- **WHEN** 外部模板元素定义 font: "@doc-title" 且 doc-title 只存在于文档 fonts 中
|
||||
- **THEN** 系统抛出 ERROR,错误代码为 `TEMPLATE_FONT_REF_DOC_FORBIDDEN`
|
||||
- **AND** 错误消息包含"模板元素不能引用文档的字体配置"
|
||||
|
||||
#### Scenario: 模板元素引用同名字体(只使用模板库的)
|
||||
|
||||
- **WHEN** 外部模板元素定义 font: "@title"
|
||||
- **AND** title 同时存在于文档 fonts 和模板库 fonts 中
|
||||
- **THEN** 系统只使用模板库的 title 配置(不查找文档)
|
||||
|
||||
### Requirement: 模板元素的 fonts_default 级联规则
|
||||
|
||||
外部模板元素未定义 font 时 SHALL 级联使用 fonts_default:优先文档 fonts_default,文档没有则使用模板库 fonts_default。
|
||||
|
||||
#### Scenario: 模板元素未定义 font,文档有 fonts_default
|
||||
|
||||
- **WHEN** 模板元素未定义 font
|
||||
- **AND** 文档定义了 metadata.fonts_default: "@body"
|
||||
- **THEN** 元素使用文档的 fonts_default 配置
|
||||
|
||||
#### Scenario: 模板元素未定义 font,文档没有 fonts_default
|
||||
|
||||
- **WHEN** 模板元素未定义 font
|
||||
- **AND** 文档未定义 fonts_default
|
||||
- **AND** 模板库定义了 metadata.fonts_default: "@base"
|
||||
- **THEN** 元素使用模板库的 fonts_default 配置
|
||||
|
||||
#### Scenario: 模板元素未定义 font,都没有 fonts_default
|
||||
|
||||
- **WHEN** 模板元素未定义 font
|
||||
- **AND** 文档和模板库都未定义 fonts_default
|
||||
- **THEN** 元素使用系统默认字体
|
||||
|
||||
### Requirement: 表格元素的双字体字段应用相同规则
|
||||
|
||||
表格元素的 font 和 header_font 字段 SHALL 应用与普通元素相同的字体引用规则。
|
||||
|
||||
#### Scenario: 表格的 font 引用模板库字体
|
||||
|
||||
- **WHEN** 模板中的表格定义 font: "@table-body"
|
||||
- **AND** table-body 存在于模板库 fonts 中
|
||||
- **THEN** 系统成功应用字体配置
|
||||
|
||||
#### Scenario: 表格的 header_font 引用模板库字体
|
||||
|
||||
- **WHEN** 模板中的表格定义 header_font: "@table-header"
|
||||
- **AND** table-header 存在于模板库 fonts 中
|
||||
- **THEN** 系统成功应用字体配置
|
||||
|
||||
#### Scenario: 表格的 font 为 null
|
||||
|
||||
- **WHEN** 模板中的表格定义 font: null 或未定义
|
||||
- **THEN** 系统按 fonts_default 级联规则处理
|
||||
|
||||
### Requirement: 模板库文件必须递归验证每个模板的结构
|
||||
|
||||
|
||||
Reference in New Issue
Block a user