test(workflow): erp-workflow 单元测试从 16 增至 63 — 覆盖 model/error/parser/expression/executor
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled

- model.rs: 13 个 FlowGraph 测试(build/outgoing/incoming/start-end 边界)
- error.rs: 7 个 WorkflowError → AppError 转换测试
- parser.rs: 11 个新增验证边界测试(空图/多起点/幽灵边/网关约束)
- expression.rs: 13 个新增求值测试(float/bool/string/复合表达式/空白容错)
- executor.rs: 3 个 is_join_gateway 纯函数测试
This commit is contained in:
iven
2026-04-28 18:04:06 +08:00
parent 5941a6b764
commit dde6b09017
5 changed files with 733 additions and 0 deletions

View File

@@ -328,4 +328,105 @@ mod tests {
let result = ExpressionEvaluator::eval("justavariable", &vars);
assert!(result.is_err());
}
// ---- 扩展边界测试 ----
#[test]
fn test_less_or_equal() {
let vars = make_vars();
assert!(ExpressionEvaluator::eval("amount <= 1500", &vars).unwrap());
assert!(ExpressionEvaluator::eval("amount <= 2000", &vars).unwrap());
assert!(!ExpressionEvaluator::eval("amount <= 1000", &vars).unwrap());
}
#[test]
fn test_boolean_equality() {
let vars = make_vars();
assert!(ExpressionEvaluator::eval("active == true", &vars).unwrap());
assert!(!ExpressionEvaluator::eval("active == false", &vars).unwrap());
}
#[test]
fn test_string_literal_with_single_quotes() {
let vars = make_vars();
assert!(ExpressionEvaluator::eval("status == 'approved'", &vars).unwrap());
}
#[test]
fn test_float_comparison() {
let mut vars = HashMap::new();
vars.insert("temperature".to_string(), json!(36.5));
assert!(ExpressionEvaluator::eval("temperature >= 36.0", &vars).unwrap());
assert!(ExpressionEvaluator::eval("temperature < 37.0", &vars).unwrap());
assert!(!ExpressionEvaluator::eval("temperature > 37.5", &vars).unwrap());
}
#[test]
fn test_integer_float_cross_comparison() {
let mut vars = HashMap::new();
vars.insert("val".to_string(), json!(10));
assert!(ExpressionEvaluator::eval("val == 10.0", &vars).unwrap());
assert!(ExpressionEvaluator::eval("val >= 9.5", &vars).unwrap());
}
#[test]
fn test_string_comparison_lexicographic() {
let vars = make_vars();
// name = "Alice"
assert!(!ExpressionEvaluator::eval("name > \"Alice\"", &vars).unwrap());
assert!(ExpressionEvaluator::eval("name >= \"Alice\"", &vars).unwrap());
assert!(ExpressionEvaluator::eval("name < \"Bob\"", &vars).unwrap());
assert!(ExpressionEvaluator::eval("name == \"Alice\"", &vars).unwrap());
}
#[test]
fn test_compound_and_or() {
let vars = make_vars();
// amount > 1000 (true) && score > 80 (true) || amount > 3000 (false)
// OR 先绑定,所以是 amount>1000 && score>80 (true) || amount>3000 (false)
// 注意:当前实现从左到右先匹配 ||,所以实际解析为:
// amount > 1000 && score > 80 || amount > 3000
// find_logical_op 先找 || → split at ||
// left = "amount > 1000 && score > 80", right = "amount > 3000"
// left = true, right = false → true || false = true
assert!(ExpressionEvaluator::eval(
"amount > 1000 && score > 80 || amount > 3000", &vars
).unwrap());
}
#[test]
fn test_compound_all_false() {
let vars = make_vars();
assert!(!ExpressionEvaluator::eval(
"amount > 2000 && score > 90", &vars
).unwrap());
}
#[test]
fn test_number_not_equals() {
let vars = make_vars();
assert!(ExpressionEvaluator::eval("amount != 1000", &vars).unwrap());
assert!(!ExpressionEvaluator::eval("amount != 1500", &vars).unwrap());
}
#[test]
fn test_expression_with_extra_whitespace() {
let vars = make_vars();
assert!(ExpressionEvaluator::eval(" amount > 1000 ", &vars).unwrap());
}
#[test]
fn test_unresolvable_variable_returns_error() {
let vars = HashMap::new();
let result = ExpressionEvaluator::eval("missing_var > 10", &vars);
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("未知的变量"));
}
#[test]
fn test_empty_expression_returns_error() {
let vars = HashMap::new();
let result = ExpressionEvaluator::eval("", &vars);
assert!(result.is_err());
}
}