import assert from "node:assert/strict"; import { test } from "node:test"; import type { VariableConfig } from "../../lib/config/schema"; import { coerceVariables, parseVarFlags } from "./variables"; function stringVar(name: string, overrides: Partial = {}): VariableConfig { return { type: "string", name, required: false, secret: false, passAs: "arg", joinWith: ",", multiline: false, ...overrides, } as VariableConfig; } function boolVar(name: string): VariableConfig { return { type: "boolean", name, required: false, secret: false, passAs: "flag", joinWith: ",", default: false, } as VariableConfig; } function numberVar(name: string): VariableConfig { return { type: "number", name, required: false, secret: false, passAs: "arg", joinWith: ",", } as VariableConfig; } function multiselectVar(name: string, choices: string[]): VariableConfig { return { type: "multiselect", name, required: false, secret: false, passAs: "arg", joinWith: ",", choices, default: [], } as VariableConfig; } test("parseVarFlags groups repeated names into arrays", () => { const grouped = parseVarFlags(["environment=staging", "tag=a", "tag=b"]); assert.deepEqual(grouped, { environment: ["staging"], tag: ["a", "b"] }); }); test("parseVarFlags rejects a flag with no '='", () => { assert.throws(() => parseVarFlags(["oops"]), /missing '='/); }); test("coerceVariables coerces booleans and numbers, passes strings through", () => { const variables = [stringVar("environment"), boolVar("dryRun"), numberVar("replicas")]; const values = coerceVariables(variables, { environment: ["staging"], dryRun: ["true"], replicas: ["3"], }); assert.deepEqual(values, { environment: "staging", dryRun: true, replicas: 3 }); }); test("coerceVariables rejects an invalid boolean/number", () => { assert.throws(() => coerceVariables([boolVar("dryRun")], { dryRun: ["yes"] }), /must be 'true' or 'false'/); assert.throws(() => coerceVariables([numberVar("replicas")], { replicas: ["abc"] }), /not a valid number/); }); test("coerceVariables collects a multiselect variable's repeats into an array", () => { const values = coerceVariables([multiselectVar("tags", ["a", "b", "c"])], { tags: ["a", "c"], }); assert.deepEqual(values, { tags: ["a", "c"] }); }); test("coerceVariables rejects a non-multiselect variable given more than once", () => { assert.throws( () => coerceVariables([stringVar("environment")], { environment: ["a", "b"] }), /given 2 times/, ); }); test("coerceVariables rejects an unknown variable name", () => { assert.throws( () => coerceVariables([stringVar("environment")], { nope: ["x"] }), /does not match any variable/, ); });