import { describe, expect, test } from "bun:test"; import { extractVariables, resolveVariables } from "../../../src/server/config/variables"; describe("extractVariables", () => { test("空对象返回空 variables", () => { const result = extractVariables({}); expect(result.variables.size).toBe(0); expect(result.issues.length).toBe(0); }); test("无 variables 字段返回空", () => { const result = extractVariables({ server: {} }); expect(result.variables.size).toBe(0); }); test("variables 非对象报错", () => { const result = extractVariables({ variables: "bad" }); expect(result.issues.length).toBe(1); expect(result.issues[0]!.code).toBe("invalid-type"); }); test("提取有效变量", () => { const result = extractVariables({ variables: { HOST: "127.0.0.1", PORT: 3000 } }); expect(result.variables.get("HOST")).toBe("127.0.0.1"); expect(result.variables.get("PORT")).toBe(3000); }); test("无效变量名报错", () => { const result = extractVariables({ variables: { "123bad": "val" } }); expect(result.issues.length).toBe(1); expect(result.issues[0]!.code).toBe("invalid-format"); }); test("null 值报错", () => { const result = extractVariables({ variables: { KEY: null } }); expect(result.issues.length).toBe(1); expect(result.issues[0]!.code).toBe("invalid-type"); }); test("数组值报错", () => { const result = extractVariables({ variables: { KEY: [1, 2] } }); expect(result.issues.length).toBe(1); }); }); describe("resolveVariables", () => { test("${KEY} 从 variables 解析", () => { const result = resolveVariables({ server: { listen: { host: "${MY_HOST}" } }, variables: { MY_HOST: "0.0.0.0" }, }); const server = (result.config as Record)["server"] as Record; const listen = server["listen"] as Record; expect(listen["host"]).toBe("0.0.0.0"); }); test("${KEY|default} 使用默认值", () => { const result = resolveVariables({ server: { listen: { host: "${MY_HOST|0.0.0.0}" } }, }); const server = (result.config as Record)["server"] as Record; const listen = server["listen"] as Record; expect(listen["host"]).toBe("0.0.0.0"); }); test("${KEY|} 空默认值", () => { const result = resolveVariables({ server: { listen: { host: "${MY_HOST|}" } }, }); const server = (result.config as Record)["server"] as Record; const listen = server["listen"] as Record; expect(listen["host"]).toBe(""); }); test("$${KEY} 转义不解析", () => { const result = resolveVariables({ server: { listen: { host: "$${NOT_A_VAR}" } }, }); const server = (result.config as Record)["server"] as Record; const listen = server["listen"] as Record; expect(listen["host"]).toBe("${NOT_A_VAR}"); }); test("variables 优先于 process.env", () => { const prev = process.env["TEST_PRIORITY"]; process.env["TEST_PRIORITY"] = "from-env"; try { const result = resolveVariables({ server: { listen: { host: "${TEST_PRIORITY}" } }, variables: { TEST_PRIORITY: "from-var" }, }); const server = (result.config as Record)["server"] as Record; const listen = server["listen"] as Record; expect(listen["host"]).toBe("from-var"); } finally { if (prev === undefined) delete process.env["TEST_PRIORITY"]; else process.env["TEST_PRIORITY"] = prev; } }); test("process.env fallback", () => { const prev = process.env["TEST_FALLBACK"]; process.env["TEST_FALLBACK"] = "from-env"; try { const result = resolveVariables({ server: { listen: { host: "${TEST_FALLBACK}" } }, }); const server = (result.config as Record)["server"] as Record; const listen = server["listen"] as Record; expect(listen["host"]).toBe("from-env"); } finally { if (prev === undefined) delete process.env["TEST_FALLBACK"]; else process.env["TEST_FALLBACK"] = prev; } }); test("完整引用保留类型 - number", () => { const result = resolveVariables({ server: { listen: { port: "${PORT|3000}" } }, }); const server = (result.config as Record)["server"] as Record; const listen = server["listen"] as Record; expect(listen["port"]).toBe(3000); expect(typeof listen["port"]).toBe("number"); }); test("完整引用保留类型 - boolean", () => { const result = resolveVariables({ server: { listen: { host: "${FLAG|false}" } }, }); const server = (result.config as Record)["server"] as Record; const listen = server["listen"] as Record; expect(listen["host"]).toBe(false); }); test("部分插值转为 string", () => { const prev = process.env["PARTIAL_HOST"]; process.env["PARTIAL_HOST"] = "192.168"; try { const result = resolveVariables({ server: { listen: { host: "prefix-${PARTIAL_HOST}-suffix" } }, }); const server = (result.config as Record)["server"] as Record; const listen = server["listen"] as Record; expect(listen["host"]).toBe("prefix-192.168-suffix"); expect(typeof listen["host"]).toBe("string"); } finally { if (prev === undefined) delete process.env["PARTIAL_HOST"]; else process.env["PARTIAL_HOST"] = prev; } }); test("unresolved-variable 报错", () => { const result = resolveVariables({ server: { listen: { host: "${UNDEFINED_VAR}" } }, }); expect(result.issues.length).toBe(1); expect(result.issues[0]!.code).toBe("unresolved-variable"); expect(result.issues[0]!.message).toContain("UNDEFINED_VAR"); }); test("variables 段被移除", () => { const result = resolveVariables({ server: { listen: { host: "test" } }, variables: { KEY: "val" }, }); const config = result.config as Record; expect(config["variables"]).toBeUndefined(); }); });