Skip to content

Commit e4f5f05

Browse files
committed
refactor(test): reorganize integration tests by functionality
Split the large integration.test.ts file into 7 feature-specific test files: - integration.basic.test.ts: basic operations and variables - integration.boolean.test.ts: boolean logic - integration.math.test.ts: Math functions - integration.objects.test.ts: object access and methods - integration.functions.test.ts: custom functions - integration.optimization.test.ts: optimization options - integration.complex.test.ts: complex scenarios
1 parent fd70675 commit e4f5f05

8 files changed

Lines changed: 807 additions & 799 deletions

src/integration.basic.test.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { expect, test } from "bun:test";
2+
import { z } from "zod";
3+
import { compile, evaluate, expr, variable } from "./index";
4+
5+
test("集成测试:完整的表达式流程", () => {
6+
// 定义变量
7+
const x = variable(z.number());
8+
const y = variable(z.number());
9+
10+
// 构建表达式
11+
const sum = expr({ x, y })("x + y");
12+
const product = expr({ x, y })("x * y");
13+
const result = expr({ sum, product })("sum + product");
14+
15+
// 编译(默认内联优化)
16+
const data = compile(result, { x, y });
17+
expect(data[0]).toEqual(["x", "y"]);
18+
expect(data.length).toBe(2); // 变量名 + 内联后的单个表达式
19+
20+
// 执行
21+
const value = evaluate<number>(data, { x: 2, y: 3 });
22+
expect(value).toBe(11); // 2+3 + 2*3 = 5 + 6 = 11
23+
});
24+
25+
test("集成测试:基础变量和表达式", () => {
26+
const a = variable(z.number());
27+
const b = variable(z.number());
28+
29+
const simple = expr({ a, b })("a + b");
30+
const compiled = compile(simple, { a, b });
31+
32+
const result = evaluate<number>(compiled, { a: 10, b: 20 });
33+
expect(result).toBe(30);
34+
});
35+
36+
test("集成测试:多层嵌套表达式", () => {
37+
const a = variable(z.number());
38+
const b = variable(z.number());
39+
const c = variable(z.number());
40+
41+
const layer1 = expr({ a, b })("a + b");
42+
const layer2 = expr({ layer1, c })("layer1 * c");
43+
const layer3 = expr({ layer2 })("layer2 + 1");
44+
45+
const compiled = compile(layer3, { a, b, c });
46+
47+
// 验证编译结果的结构
48+
expect(compiled[0]).toEqual(["a", "b", "c"]);
49+
50+
// 执行
51+
const result = evaluate<number>(compiled, { a: 2, b: 3, c: 4 });
52+
// (2+3) * 4 + 1 = 5 * 4 + 1 = 20 + 1 = 21
53+
expect(result).toBe(21);
54+
});
55+
56+
test("集成测试:连续算术运算", () => {
57+
const x = variable(z.number());
58+
59+
const expr1 = expr({ x })("x + 1");
60+
const expr2 = expr({ expr1 })("expr1 * 2");
61+
const expr3 = expr({ expr2 })("expr3 - 3");
62+
63+
// 此处应该捕获错误:expr3 在上下文中不存在
64+
expect(() => {
65+
compile(expr3, { x });
66+
}).toThrow();
67+
});
68+
69+
test("集成测试:正确的链式计算", () => {
70+
const x = variable(z.number());
71+
72+
const expr1 = expr({ x })("x + 1");
73+
const expr2 = expr({ expr1 })("expr1 * 2");
74+
const expr3 = expr({ expr2 })("expr2 - 3");
75+
76+
const compiled = compile(expr3, { x });
77+
const result = evaluate<number>(compiled, { x: 5 });
78+
// ((5+1)*2) - 3 = (6*2) - 3 = 12 - 3 = 9
79+
expect(result).toBe(9);
80+
});
81+
82+
test("集成测试:简单字符串表达式", () => {
83+
const a = variable(z.string());
84+
const b = variable(z.string());
85+
86+
const combined = expr({ a, b })("a + b");
87+
const compiled = compile(combined, { a, b });
88+
const result = evaluate<string>(compiled, { a: "Hello", b: "World" });
89+
expect(result).toBe("HelloWorld");
90+
});
91+
92+
test("集成测试:数字类型保持一致", () => {
93+
const p = variable(z.number());
94+
const q = variable(z.number());
95+
96+
const calc = expr({ p, q })("p + q * 2");
97+
const compiled = compile(calc, { p, q });
98+
const result = evaluate<number>(compiled, { p: 10, q: 5 });
99+
expect(result).toBe(20); // 10 + 5*2 = 10 + 10 = 20
100+
});

src/integration.boolean.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { expect, test } from "bun:test";
2+
import { z } from "zod";
3+
import { compile, evaluate, expr, variable } from "./index";
4+
5+
test("集成测试:布尔表达式", () => {
6+
const age = variable(z.number());
7+
8+
const isAdult = expr({ age })("age >= 18");
9+
const compiled = compile(isAdult, { age });
10+
11+
const result1 = evaluate<boolean>(compiled, { age: 25 });
12+
expect(result1).toBe(true);
13+
14+
const result2 = evaluate<boolean>(compiled, { age: 15 });
15+
expect(result2).toBe(false);
16+
});
17+
18+
test("集成测试:多变量布尔逻辑", () => {
19+
const x = variable(z.number());
20+
const y = variable(z.number());
21+
22+
const isGreater = expr({ x, y })("x > y");
23+
const isEqual = expr({ x, y })("x === y");
24+
const combined = expr({ isGreater, isEqual })("isGreater || isEqual");
25+
26+
const compiled = compile(combined, { x, y });
27+
28+
const result1 = evaluate<boolean>(compiled, { x: 10, y: 5 });
29+
expect(result1).toBe(true); // 10 > 5
30+
31+
const result2 = evaluate<boolean>(compiled, { x: 5, y: 5 });
32+
expect(result2).toBe(true); // 5 === 5
33+
34+
const result3 = evaluate<boolean>(compiled, { x: 3, y: 7 });
35+
expect(result3).toBe(false); // !(3 > 7) && !(3 === 7)
36+
});

src/integration.complex.test.ts

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { expect, test } from "bun:test";
2+
import { z } from "zod";
3+
import { compile, evaluate, expr, variable } from "./index";
4+
5+
test("集成测试:复杂的数学运算", () => {
6+
const x = variable(z.number());
7+
const y = variable(z.number());
8+
9+
const expr1 = expr({ x, y })("x * y");
10+
const expr2 = expr({ x, y })("x + y");
11+
const expr3 = expr({ expr1, expr2 })("expr1 - expr2");
12+
13+
const compiled = compile(expr3, { x, y });
14+
const result = evaluate<number>(compiled, { x: 5, y: 3 });
15+
// 5*3 - (5+3) = 15 - 8 = 7
16+
expect(result).toBe(7);
17+
});
18+
19+
test("集成测试:多个独立表达式链", () => {
20+
const a = variable(z.number());
21+
const b = variable(z.number());
22+
const c = variable(z.number());
23+
24+
// 链 1: a 和 b
25+
const sum = expr({ a, b })("a + b");
26+
27+
// 链 2: 从链1和 c
28+
const multiple = expr({ sum, c })("sum * c");
29+
30+
// 链 3: 从链2
31+
const final = expr({ multiple })("multiple + 10");
32+
33+
const compiled = compile(final, { a, b, c });
34+
const result = evaluate<number>(compiled, { a: 1, b: 2, c: 3 });
35+
// ((1+2)*3) + 10 = (3*3) + 10 = 9 + 10 = 19
36+
expect(result).toBe(19);
37+
});
38+
39+
test("集成测试:对象属性与函数组合", () => {
40+
// 测试表达式 double(obj.value),组合对象属性和函数调用
41+
const double = variable(z.function({ input: [z.number()], output: z.number() }));
42+
const obj = variable(
43+
z.object({
44+
value: z.number(),
45+
})
46+
);
47+
48+
const combinedExpr = expr({ double, obj })("double(obj.value)");
49+
const combinedCompiled = compile(combinedExpr, { double, obj });
50+
51+
const result = evaluate<number>(combinedCompiled, {
52+
double: (n: number) => n * 2,
53+
obj: { value: 15 },
54+
});
55+
expect(result).toBe(30);
56+
});
57+
58+
test("集成测试:嵌套的方法调用与运算", () => {
59+
// 测试表达式 obj.user.age * 2 或类似的组合
60+
const obj = variable(
61+
z.object({
62+
user: z.object({
63+
name: z.string(),
64+
age: z.number(),
65+
}),
66+
})
67+
);
68+
69+
const ageCalcExpr = expr({ obj })("obj.user.age * 2");
70+
const ageCalcCompiled = compile(ageCalcExpr, { obj });
71+
72+
const result = evaluate<number>(ageCalcCompiled, {
73+
obj: { user: { name: "Charlie", age: 25 } },
74+
});
75+
expect(result).toBe(50);
76+
77+
// 更复杂的计算
78+
const complexExpr = expr({ obj })("obj.user.age * 2 + 10");
79+
const complexCompiled = compile(complexExpr, { obj });
80+
81+
const complexResult = evaluate<number>(complexCompiled, {
82+
obj: { user: { name: "Diana", age: 30 } },
83+
});
84+
expect(complexResult).toBe(70); // 30 * 2 + 10 = 70
85+
});
86+
87+
test("集成测试:在复杂表达式中使用多个导入", () => {
88+
// 使用多个对象和函数的组合表达式
89+
const multiply = variable(z.function({ input: [z.number(), z.number()], output: z.number() }));
90+
const add = variable(z.function({ input: [z.number(), z.number()], output: z.number() }));
91+
92+
const data = variable(
93+
z.object({
94+
x: z.number(),
95+
y: z.number(),
96+
})
97+
);
98+
99+
// 复合表达式:multiply(data.x, data.y) + add(data.x, data.y)
100+
const complexExpr = expr({ multiply, add, data })("multiply(data.x, data.y) + add(data.x, data.y)");
101+
const complexCompiled = compile(complexExpr, { multiply, add, data });
102+
103+
const result = evaluate<number>(complexCompiled, {
104+
multiply: (a: number, b: number) => a * b,
105+
add: (a: number, b: number) => a + b,
106+
data: { x: 3, y: 4 },
107+
});
108+
expect(result).toBe(19); // (3*4) + (3+4) = 12 + 7 = 19
109+
110+
// 另一个组合:multiply(add(data.x, data.y), data.x)
111+
const nestedExpr = expr({ multiply, add, data })("multiply(add(data.x, data.y), data.x)");
112+
const nestedCompiled = compile(nestedExpr, { multiply, add, data });
113+
114+
const nestedResult = evaluate<number>(nestedCompiled, {
115+
multiply: (a: number, b: number) => a * b,
116+
add: (a: number, b: number) => a + b,
117+
data: { x: 5, y: 2 },
118+
});
119+
expect(nestedResult).toBe(35); // (5+2) * 5 = 7 * 5 = 35
120+
});

src/integration.functions.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { expect, test } from "bun:test";
2+
import { z } from "zod";
3+
import { compile, evaluate, expr, variable } from "./index";
4+
5+
test("集成测试:基础函数调用", () => {
6+
// 定义单参数函数 double(x: number) => x * 2
7+
const double = variable(z.function({ input: [z.number()], output: z.number() }));
8+
const x = variable(z.number());
9+
10+
const doubleCallExpr = expr({ double, x })("double(x)");
11+
const doubleCompiled = compile(doubleCallExpr, { double, x });
12+
13+
const result = evaluate<number>(doubleCompiled, {
14+
double: (n: number) => n * 2,
15+
x: 5,
16+
});
17+
expect(result).toBe(10);
18+
});
19+
20+
test("集成测试:多参数函数", () => {
21+
// 定义多参数函数 add(a: number, b: number) => a + b
22+
const add = variable(z.function({ input: [z.number(), z.number()], output: z.number() }));
23+
const a = variable(z.number());
24+
const b = variable(z.number());
25+
26+
const addExpr = expr({ add, a, b })("add(a, b)");
27+
const addCompiled = compile(addExpr, { add, a, b });
28+
29+
const result = evaluate<number>(addCompiled, {
30+
add: (x: number, y: number) => x + y,
31+
a: 7,
32+
b: 3,
33+
});
34+
expect(result).toBe(10);
35+
36+
// 测试另外的值
37+
const result2 = evaluate<number>(addCompiled, {
38+
add: (x: number, y: number) => x + y,
39+
a: 100,
40+
b: 50,
41+
});
42+
expect(result2).toBe(150);
43+
});
44+
45+
test("集成测试:函数返回对象", () => {
46+
// 定义返回对象的函数 getUser() => ({ name: string, age: number })
47+
const getUser = variable(z.function({ input: [], output: z.object({ name: z.string(), age: z.number() }) }));
48+
49+
// 调用函数并访问返回对象的属性
50+
const userNameExpr = expr({ getUser })("getUser().name");
51+
const userNameCompiled = compile(userNameExpr, { getUser });
52+
53+
const result = evaluate<string>(userNameCompiled, {
54+
getUser: () => ({ name: "Bob", age: 28 }),
55+
});
56+
expect(result).toBe("Bob");
57+
58+
// 访问返回对象的 age 属性
59+
const userAgeExpr = expr({ getUser })("getUser().age");
60+
const userAgeCompiled = compile(userAgeExpr, { getUser });
61+
62+
const ageResult = evaluate<number>(userAgeCompiled, {
63+
getUser: () => ({ name: "Bob", age: 28 }),
64+
});
65+
expect(ageResult).toBe(28);
66+
});

0 commit comments

Comments
 (0)