179 lines
8.3 KiB
JSON
179 lines
8.3 KiB
JSON
{
|
|
"_comment": "公式引擎共享测试向量:前端 vitest 与 Java JUnit 读同一份文件,防止两套实现漂移。expect 为落库口径原始值(decimal 用字符串,null 表示空值)。",
|
|
"fields": [
|
|
{ "b_field": "b_qty", "b_type": "number" },
|
|
{ "b_field": "b_price", "b_type": "money" },
|
|
{ "b_field": "b_amount", "b_type": "money" },
|
|
{ "b_field": "b_rate", "b_type": "number" },
|
|
{ "b_field": "b_name", "b_type": "input" },
|
|
{ "b_field": "b_no", "b_type": "input" },
|
|
{ "b_field": "b_flag", "b_type": "checkbox" },
|
|
{ "b_field": "b_day", "b_type": "date" },
|
|
{ "b_field": "b_end", "b_type": "date" }
|
|
],
|
|
"evaluate": [
|
|
{ "id": "arith_literals", "formula": "1 + 2", "expect": "3" },
|
|
{ "id": "arith_precedence", "formula": "2 + 3 * 4", "expect": "14" },
|
|
{ "id": "arith_parens", "formula": "(2 + 3) * 4", "expect": "20" },
|
|
{ "id": "unary_minus", "formula": "-3 + 10", "expect": "7" },
|
|
{ "id": "decimal_no_float_error", "formula": "0.1 + 0.2", "expect": "0.3" },
|
|
{ "id": "decimal_mul", "formula": "1.1 * 3", "expect": "3.3" },
|
|
{ "id": "division", "formula": "10 / 4", "expect": "2.5" },
|
|
{ "id": "division_by_zero", "formula": "1 / 0", "expect": null },
|
|
{ "id": "modulo", "formula": "10 % 3", "expect": "1" },
|
|
{ "id": "modulo_negative", "formula": "MOD(-7, 3)", "expect": "-1" },
|
|
{ "id": "modulo_by_zero", "formula": "10 % 0", "expect": null },
|
|
{
|
|
"id": "field_multiply",
|
|
"formula": "b_qty * b_price",
|
|
"values": { "b_qty": 3, "b_price": "12.50" },
|
|
"expect": "37.5"
|
|
},
|
|
{
|
|
"id": "field_chain_discount",
|
|
"formula": "ROUND(b_qty * b_price * (1 - b_rate), 2)",
|
|
"values": { "b_qty": 3, "b_price": "10.00", "b_rate": "0.13" },
|
|
"expect": "26.1"
|
|
},
|
|
{ "id": "round_half_up", "formula": "ROUND(2.345, 2)", "expect": "2.35" },
|
|
{ "id": "round_negative_half_up", "formula": "ROUND(-2.345, 2)", "expect": "-2.35" },
|
|
{ "id": "round_no_digits", "formula": "ROUND(2.5)", "expect": "3" },
|
|
{ "id": "roundup", "formula": "ROUNDUP(2.341, 2)", "expect": "2.35" },
|
|
{ "id": "rounddown", "formula": "ROUNDDOWN(2.349, 2)", "expect": "2.34" },
|
|
{ "id": "abs", "formula": "ABS(-5)", "expect": "5" },
|
|
{ "id": "ceil", "formula": "CEIL(1.1)", "expect": "2" },
|
|
{ "id": "ceil_negative", "formula": "CEIL(-1.1)", "expect": "-1" },
|
|
{ "id": "floor", "formula": "FLOOR(1.9)", "expect": "1" },
|
|
{ "id": "floor_negative", "formula": "FLOOR(-1.1)", "expect": "-2" },
|
|
{ "id": "pow", "formula": "POW(2, 10)", "expect": "1024" },
|
|
{ "id": "sqrt", "formula": "SQRT(9)", "expect": "3" },
|
|
{ "id": "sqrt_negative", "formula": "SQRT(-4)", "expect": null },
|
|
{ "id": "min_max", "formula": "MAX(1, 5, 3) - MIN(2, 1)", "expect": "4" },
|
|
{
|
|
"id": "if_true",
|
|
"formula": "IF(b_qty > 0, b_price, 0)",
|
|
"values": { "b_qty": 2, "b_price": "9.5" },
|
|
"expect": "9.5"
|
|
},
|
|
{ "id": "if_false", "formula": "IF(0 > 0, 1, 2)", "expect": "2" },
|
|
{ "id": "if_null_condition", "formula": "IF(NULL, 1, 2)", "expect": "2" },
|
|
{
|
|
"id": "ifblank",
|
|
"formula": "IFBLANK(b_price, 0)",
|
|
"values": { "b_price": null },
|
|
"expect": "0"
|
|
},
|
|
{
|
|
"id": "coalesce",
|
|
"formula": "COALESCE(b_price, b_name, 'x')",
|
|
"values": { "b_price": null, "b_name": "a" },
|
|
"expect": "a"
|
|
},
|
|
{ "id": "isblank", "formula": "ISBLANK(b_price)", "values": { "b_price": null }, "expect": true },
|
|
{ "id": "null_arithmetic", "formula": "b_qty + 1", "values": { "b_qty": null }, "expect": "1" },
|
|
{
|
|
"id": "text_concat",
|
|
"formula": "b_name & '-' & b_no",
|
|
"values": { "b_name": "A", "b_no": "01" },
|
|
"expect": "A-01"
|
|
},
|
|
{
|
|
"id": "text_concat_null",
|
|
"formula": "b_name & b_no",
|
|
"values": { "b_name": "A", "b_no": null },
|
|
"expect": "A"
|
|
},
|
|
{ "id": "and_three_valued", "formula": "TRUE AND NULL", "expect": null },
|
|
{ "id": "and_false_wins", "formula": "FALSE AND NULL", "expect": false },
|
|
{ "id": "or_true_wins", "formula": "TRUE OR NULL", "expect": true },
|
|
{ "id": "or_three_valued", "formula": "FALSE OR NULL", "expect": null },
|
|
{ "id": "not_boolean", "formula": "NOT(b_flag)", "values": { "b_flag": 0 }, "expect": true },
|
|
{ "id": "compare_true", "formula": "b_qty >= 3", "values": { "b_qty": 3 }, "expect": true },
|
|
{ "id": "compare_null", "formula": "b_qty > 3", "values": { "b_qty": null }, "expect": null },
|
|
{ "id": "checkbox_equals", "formula": "b_flag == TRUE", "values": { "b_flag": 1 }, "expect": true },
|
|
{
|
|
"id": "text_functions",
|
|
"formula": "UPPER(LEFT(b_name, 2)) & TRIM(' x ')",
|
|
"values": { "b_name": "abcd" },
|
|
"expect": "ABx"
|
|
},
|
|
{
|
|
"id": "text_len_mid",
|
|
"formula": "LEN(MID(b_name, 2, 2))",
|
|
"values": { "b_name": "abcd" },
|
|
"expect": "2"
|
|
},
|
|
{ "id": "text_replace", "formula": "REPLACE(b_no, '0', '')", "values": { "b_no": "A001" }, "expect": "A1" },
|
|
{ "id": "text_cast", "formula": "TEXT(b_qty)", "values": { "b_qty": 3 }, "expect": "3" },
|
|
{ "id": "number_cast", "formula": "NUMBER('2.50')", "expect": "2.5" },
|
|
{ "id": "number_cast_invalid", "formula": "NUMBER('abc')", "expect": null },
|
|
{ "id": "datediff_days", "formula": "DATEDIFF('2026-01-01', '2026-03-15', 'day')", "expect": "73" },
|
|
{ "id": "datediff_months", "formula": "DATEDIFF('2026-01-15', '2026-03-14', 'month')", "expect": "1" },
|
|
{ "id": "dateadd_month_clamp", "formula": "DATEADD('2026-01-31', 1, 'month')", "expect": "2026-02-28" },
|
|
{ "id": "dateadd_day", "formula": "DATEADD('2026-02-28', 1, 'day')", "expect": "2026-03-01" },
|
|
{
|
|
"id": "date_parts",
|
|
"formula": "YEAR(b_day) * 100 + MONTH(b_day)",
|
|
"values": { "b_day": "2026-03-15" },
|
|
"expect": "202603"
|
|
},
|
|
{ "id": "formatdate", "formula": "FORMATDATE('2026-03-05', 'yyyy/MM/dd')", "expect": "2026/03/05" },
|
|
{ "id": "err_unknown_function", "formula": "FOO(1)", "expectError": "E_FUNC_UNKNOWN" },
|
|
{ "id": "err_deferred_aggregate", "formula": "SUM(b_amount)", "expectError": "E_AGG_DEFERRED" },
|
|
{ "id": "err_arity", "formula": "ROUND(1, 2, 3)", "expectError": "E_FUNC_ARGS" },
|
|
{
|
|
"id": "err_type_operand",
|
|
"formula": "b_name * 2",
|
|
"values": { "b_name": "abc" },
|
|
"expectError": "E_TYPE_OPERAND"
|
|
}
|
|
],
|
|
"validate": [
|
|
{ "id": "ok_basic", "formula": "ROUND(b_qty * b_price, 2)", "expect": [] },
|
|
{ "id": "ok_concat", "formula": "b_name & '-' & b_no", "expect": [] },
|
|
{ "id": "ok_ifblank", "formula": "IFBLANK(b_amount, 0)", "expect": [] },
|
|
{ "id": "err_aggregate", "formula": "SUM(b_amount)", "expect": ["E_AGG_DEFERRED"] },
|
|
{ "id": "err_volatile_today", "formula": "TODAY()", "expect": ["E_FUNC_VOLATILE"] },
|
|
{ "id": "err_volatile_now", "formula": "NOW()", "expect": ["E_FUNC_VOLATILE"] },
|
|
{ "id": "err_relation_scope", "formula": "lines.b_amount", "expect": ["E_FIELD_SCOPE_DEFERRED"] },
|
|
{ "id": "err_unknown_field", "formula": "b_nope + 1", "expect": ["E_FIELD_UNKNOWN"] },
|
|
{ "id": "err_null_compare", "formula": "b_amount == NULL", "expect": ["E_NULL_COMPARE"] },
|
|
{ "id": "err_type_operand", "formula": "b_name * 2", "expect": ["E_TYPE_OPERAND"] },
|
|
{ "id": "err_compare_chained", "formula": "b_qty < 1 < 2", "expect": ["E_COMPARE_CHAINED"] },
|
|
{ "id": "err_syntax_tail", "formula": "b_qty +", "expect": ["E_OPERAND_EXPECTED"] },
|
|
{ "id": "err_func_args", "formula": "DATEDIFF(b_day)", "expect": ["E_FUNC_ARGS"] },
|
|
{ "id": "err_unknown_function", "formula": "FOO(b_qty)", "expect": ["E_FUNC_UNKNOWN"] },
|
|
{ "id": "err_empty", "formula": " ", "expect": ["E_FORMULA_EMPTY"] },
|
|
{
|
|
"id": "err_target_type",
|
|
"formula": "b_qty * b_price",
|
|
"targetType": "text",
|
|
"expect": ["E_TYPE_TARGET"]
|
|
}
|
|
],
|
|
"graph": {
|
|
"chain": {
|
|
"fields": ["b_qty", "b_price", "b_amount"],
|
|
"formulas": {
|
|
"b_amount": "b_qty * b_price",
|
|
"b_price": "b_amount / 2"
|
|
},
|
|
"expectCycle": true
|
|
},
|
|
"acyclic": {
|
|
"fields": ["b_qty", "b_price", "b_amount"],
|
|
"formulas": {
|
|
"b_amount": "ROUND(b_qty * b_price, 2)"
|
|
},
|
|
"expectCycle": false,
|
|
"expectOrder": ["main:b_amount"]
|
|
}
|
|
},
|
|
"revision": {
|
|
"nodes": [
|
|
{ "field": "b_amount", "formula": "b_qty * b_price", "overridable": false },
|
|
{ "field": "b_price", "formula": "1 + 2", "overridable": true }
|
|
],
|
|
"expect": "fnv1a64:e4bcb9ebe6caeac0"
|
|
}
|
|
} |