feat: 增强模板条件渲染表达式支持
使用 simpleeval 库替换原有的简单正则匹配,支持复杂的条件表达式评估。新增 ConditionEvaluator 类处理条件逻辑,支持比较运算、逻辑运算、成员测试、数学计算和内置函数,同时保持向后兼容性。
This commit is contained in:
179
openspec/specs/enhanced-condition-evaluation/spec.md
Normal file
179
openspec/specs/enhanced-condition-evaluation/spec.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# Enhanced Condition Evaluation
|
||||
|
||||
## Purpose
|
||||
|
||||
增强条件评估能力提供基于 simpleeval 的安全表达式评估引擎,支持复杂的条件判断、逻辑运算、数学计算和成员测试。该能力用于模板系统的 visible 字段,允许用户使用 Python 风格的表达式来控制元素的显示条件。
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: 系统必须支持比较运算符
|
||||
|
||||
系统 SHALL 支持所有标准的比较运算符,用于数值和字符串的比较。
|
||||
|
||||
#### Scenario: 数值大于比较
|
||||
|
||||
- **WHEN** 表达式为 `{count > 0}` 且变量 `count` 的值为 5
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 数值小于等于比较
|
||||
|
||||
- **WHEN** 表达式为 `{price <= 100}` 且变量 `price` 的值为 100
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 字符串相等比较
|
||||
|
||||
- **WHEN** 表达式为 `{status == 'active'}` 且变量 `status` 的值为 "active"
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 字符串不等比较
|
||||
|
||||
- **WHEN** 表达式为 `{status != 'inactive'}` 且变量 `status` 的值为 "active"
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
### Requirement: 系统必须支持逻辑运算符
|
||||
|
||||
系统 SHALL 支持逻辑运算符 and、or、not,用于组合多个条件。
|
||||
|
||||
#### Scenario: 逻辑与运算
|
||||
|
||||
- **WHEN** 表达式为 `{count > 0 and status == 'active'}` 且变量 `count` 为 5,`status` 为 "active"
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 逻辑或运算
|
||||
|
||||
- **WHEN** 表达式为 `{count > 0 or status == 'active'}` 且变量 `count` 为 0,`status` 为 "active"
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 逻辑非运算
|
||||
|
||||
- **WHEN** 表达式为 `{not (count == 0)}` 且变量 `count` 为 5
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 复杂逻辑组合
|
||||
|
||||
- **WHEN** 表达式为 `{(score >= 60 and score <= 100) or is_admin}` 且变量 `score` 为 75,`is_admin` 为 False
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
### Requirement: 系统必须支持成员测试
|
||||
|
||||
系统 SHALL 支持 in 和 not in 运算符,用于测试值是否在集合中。
|
||||
|
||||
#### Scenario: 列表成员测试
|
||||
|
||||
- **WHEN** 表达式为 `{status in ['draft', 'review', 'published']}` 且变量 `status` 为 "draft"
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 列表非成员测试
|
||||
|
||||
- **WHEN** 表达式为 `{status not in ['draft', 'review']}` 且变量 `status` 为 "active"
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 字符串包含测试
|
||||
|
||||
- **WHEN** 表达式为 `{'test' in status}` 且变量 `status` 为 "test-version"
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 元组成员测试
|
||||
|
||||
- **WHEN** 表达式为 `{level in (1, 2, 3)}` 且变量 `level` 为 2
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
### Requirement: 系统必须支持数学运算
|
||||
|
||||
系统 SHALL 支持基本的数学运算符,用于条件判断中的计算。
|
||||
|
||||
#### Scenario: 加法运算
|
||||
|
||||
- **WHEN** 表达式为 `{(price + tax) > 100}` 且变量 `price` 为 90,`tax` 为 15
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 乘法运算
|
||||
|
||||
- **WHEN** 表达式为 `{(price * discount) > 50}` 且变量 `price` 为 100,`discount` 为 0.8
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 除法运算
|
||||
|
||||
- **WHEN** 表达式为 `{(total / count) >= 10}` 且变量 `total` 为 100,`count` 为 5
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
### Requirement: 系统必须支持内置函数
|
||||
|
||||
系统 SHALL 支持安全的内置函数,用于类型转换和基本操作。
|
||||
|
||||
#### Scenario: 类型转换函数
|
||||
|
||||
- **WHEN** 表达式为 `{int(value) > 100}` 且变量 `value` 为 "150"
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 长度函数
|
||||
|
||||
- **WHEN** 表达式为 `{len(items) > 0}` 且变量 `items` 为 [1, 2, 3]
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
#### Scenario: 布尔转换函数
|
||||
|
||||
- **WHEN** 表达式为 `{bool(value)}` 且变量 `value` 为 "text"
|
||||
- **THEN** 表达式评估结果为 True
|
||||
|
||||
### Requirement: 系统必须提供详细的错误信息
|
||||
|
||||
系统 SHALL 在表达式评估失败时提供清晰的错误信息,帮助用户快速定位问题。
|
||||
|
||||
#### Scenario: 变量未定义错误
|
||||
|
||||
- **WHEN** 表达式为 `{undefined_var > 0}` 但变量 `undefined_var` 未提供
|
||||
- **THEN** 系统抛出错误,提示"条件表达式中的变量未定义: undefined_var",并列出可用变量
|
||||
|
||||
#### Scenario: 函数未定义错误
|
||||
|
||||
- **WHEN** 表达式为 `{custom_func(value)}` 但函数 `custom_func` 不在白名单中
|
||||
- **THEN** 系统抛出错误,提示"条件表达式中使用了不支持的函数: custom_func",并列出支持的函数
|
||||
|
||||
#### Scenario: 语法错误
|
||||
|
||||
- **WHEN** 表达式为 `{count > }` 包含语法错误
|
||||
- **THEN** 系统抛出错误,提示"条件表达式语法错误",并显示具体的语法问题
|
||||
|
||||
### Requirement: 系统必须实施安全限制
|
||||
|
||||
系统 SHALL 限制表达式的复杂度和能力,防止恶意或危险的操作。
|
||||
|
||||
#### Scenario: 表达式长度限制
|
||||
|
||||
- **WHEN** 表达式长度超过 500 字符
|
||||
- **THEN** 系统抛出错误,提示"条件表达式过长"
|
||||
|
||||
#### Scenario: 禁止属性访问
|
||||
|
||||
- **WHEN** 表达式为 `{obj.attr}` 尝试访问对象属性
|
||||
- **THEN** 系统抛出错误,提示"不支持的语法特性"
|
||||
|
||||
#### Scenario: 禁止函数定义
|
||||
|
||||
- **WHEN** 表达式包含 lambda 或 def 关键字
|
||||
- **THEN** 系统抛出错误,提示"不支持的语法特性"
|
||||
|
||||
#### Scenario: 白名单函数限制
|
||||
|
||||
- **WHEN** 表达式使用了不在白名单中的函数(如 eval、exec、open)
|
||||
- **THEN** 系统拒绝执行,抛出错误
|
||||
|
||||
### Requirement: 系统必须支持表达式提取
|
||||
|
||||
系统 SHALL 能够从 `{expression}` 格式的字符串中提取实际的表达式内容。
|
||||
|
||||
#### Scenario: 提取带花括号的表达式
|
||||
|
||||
- **WHEN** 条件字符串为 `{count > 0}`
|
||||
- **THEN** 系统提取出表达式 `count > 0`
|
||||
|
||||
#### Scenario: 提取带空白的表达式
|
||||
|
||||
- **WHEN** 条件字符串为 `{ count > 0 }`
|
||||
- **THEN** 系统提取出表达式 `count > 0`(去除首尾空白)
|
||||
|
||||
#### Scenario: 处理不带花括号的表达式
|
||||
|
||||
- **WHEN** 条件字符串为 `count > 0`(不带花括号)
|
||||
- **THEN** 系统直接使用该字符串作为表达式
|
||||
Reference in New Issue
Block a user