import { describe, expect, it } from "vitest" import { evaluateExpression, resolvePath } from "../src/core/expression" import type { ScopeFrame } from "../src/core/expression" const scopes: ScopeFrame[] = [ { type: "data", values: { user: { name: "张三", level: 4, type: "developer", isVip: true }, tags: ["important", "draft"], items: [ { title: "A", price: 1 }, { title: "B", price: 2 } ], disabled: false } } ] describe("expression evaluator", () => { it("resolves nested paths and array access", () => { expect(resolvePath("user.name", scopes)).toMatchObject({ found: true, value: "张三" }) expect(resolvePath("items[0].title", scopes)).toMatchObject({ found: true, value: "A" }) }) it("evaluates comparisons", () => { expect(evaluateExpression("user.level >= 3", scopes)).toMatchObject({ ok: true, value: true }) expect(evaluateExpression("user.type == \"developer\"", scopes)).toMatchObject({ ok: true, value: true }) }) it("evaluates logical operators", () => { expect(evaluateExpression("user.isVip && user.level >= 3", scopes)).toMatchObject({ ok: true, value: true }) expect(evaluateExpression("!disabled", scopes)).toMatchObject({ ok: true, value: true }) }) it("evaluates contains", () => { expect(evaluateExpression("tags contains \"important\"", scopes)).toMatchObject({ ok: true, value: true }) }) it("evaluates length access", () => { expect(evaluateExpression("items.length > 0", scopes)).toMatchObject({ ok: true, value: true }) }) it("evaluates nullish fallback", () => { expect(evaluateExpression("missing.name ?? \"未命名\"", scopes)).toMatchObject({ ok: true, value: "未命名" }) }) })