import { describe, expect, test } from "bun:test"; import { readBackupFile } from "../src/index.ts"; import { collectRuleDefinitions, compileRule, compileWorkflow } from "../src/compiler.ts"; import examples, { conditionBeforeAction, eventTurnOn, mergedTriggers } from "../src/rules/index.ts"; const now = 1_760_000_000_000; const devices = (await import("../src/devices.json")).default; describe("规则编译", () => { test("单条事件触发开灯规则生成稳定 JSON", () => { const { rule } = compileRule(eventTurnOn, { now }); expect(rule).toEqual({ id: String(now), cfg: { id: String(now), userData: { name: "示例-事件触发开灯", transform: { x: 0, y: 0, scale: 1, rotate: 0 }, lastUpdateTime: now, version: 0, }, uiType: "test", enable: true, }, nodes: [ { id: "DI1", type: "deviceInput", props: { did: "blt.3.1htiptpdgco00", siid: 2, eiid: 1008, }, inputs: {}, outputs: { output: ["DO1.trigger"] }, cfg: { urn: "urn:miot-spec-v2:device:motion-sensor:0000A014:xiaomi-pir1:2", name: "deviceInput", version: 1, pos: { x: 240, y: 180, width: 450, height: 206 }, }, }, { id: "DO1", type: "deviceOutput", props: { did: "group.1815373077765824512", siid: 2, piid: 1, value: true, }, inputs: { trigger: null }, outputs: { output: [] }, cfg: { urn: "urn:miot-spec-v2:device:light:0000A001:mijia-group3:3:0000C802", name: "deviceOutput", version: 1, pos: { x: 800, y: 180, width: 528, height: 164 }, }, }, ], }); }); test("状态判断后动作会生成 deviceGet 并连接满足路径", () => { const { rule } = compileRule(conditionBeforeAction, { now }); expect(rule.nodes.map((node) => node.type)).toEqual(["deviceInput", "deviceGet", "deviceOutput"]); expect(rule.nodes[0]!.outputs.output).toEqual(["DG1.input"]); expect(rule.nodes[1]!.outputs.output).toEqual(["DO1.trigger"]); expect(rule.nodes[1]!.outputs.output2).toEqual([]); }); test("多个触发器会生成 signalOr 合并节点", () => { const { rule } = compileRule(mergedTriggers, { now }); expect(rule.nodes.map((node) => node.type)).toEqual(["deviceInput", "deviceInput", "signalOr", "deviceOutput"]); expect(rule.nodes[0]!.outputs.output).toEqual(["SO1.input0"]); expect(rule.nodes[1]!.outputs.output).toEqual(["SO1.input1"]); expect(rule.nodes[2]!.outputs.output).toEqual(["DO1.trigger"]); }); test("模块导出收集支持默认数组和命名规则", async () => { const moduleExports = await import("../src/rules/index.ts"); const definitions = collectRuleDefinitions(moduleExports); expect(definitions.map((definition) => definition.name)).toEqual(examples.map((definition) => definition.name)); }); });