@player-tools/fluent 0.12.1--canary.241.6077
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +2396 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/index.legacy-esm.js +2276 -0
- package/dist/index.mjs +2276 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +38 -0
- package/src/core/base-builder/__tests__/fluent-builder-base.test.ts +2423 -0
- package/src/core/base-builder/__tests__/fluent-partial.test.ts +179 -0
- package/src/core/base-builder/__tests__/id-generator.test.ts +658 -0
- package/src/core/base-builder/__tests__/registry.test.ts +534 -0
- package/src/core/base-builder/__tests__/resolution-mixed-arrays.test.ts +319 -0
- package/src/core/base-builder/__tests__/resolution-pipeline.test.ts +416 -0
- package/src/core/base-builder/__tests__/resolution-switches.test.ts +468 -0
- package/src/core/base-builder/__tests__/resolution-templates.test.ts +255 -0
- package/src/core/base-builder/__tests__/switch.test.ts +815 -0
- package/src/core/base-builder/__tests__/template.test.ts +596 -0
- package/src/core/base-builder/__tests__/value-extraction.test.ts +200 -0
- package/src/core/base-builder/__tests__/value-storage.test.ts +459 -0
- package/src/core/base-builder/conditional/index.ts +64 -0
- package/src/core/base-builder/context.ts +152 -0
- package/src/core/base-builder/errors.ts +69 -0
- package/src/core/base-builder/fluent-builder-base.ts +308 -0
- package/src/core/base-builder/guards.ts +137 -0
- package/src/core/base-builder/id/generator.ts +290 -0
- package/src/core/base-builder/id/registry.ts +152 -0
- package/src/core/base-builder/index.ts +72 -0
- package/src/core/base-builder/resolution/path-resolver.ts +116 -0
- package/src/core/base-builder/resolution/pipeline.ts +103 -0
- package/src/core/base-builder/resolution/steps/__tests__/nested-asset-wrappers.test.ts +206 -0
- package/src/core/base-builder/resolution/steps/asset-id.ts +77 -0
- package/src/core/base-builder/resolution/steps/asset-wrappers.ts +64 -0
- package/src/core/base-builder/resolution/steps/builders.ts +84 -0
- package/src/core/base-builder/resolution/steps/mixed-arrays.ts +95 -0
- package/src/core/base-builder/resolution/steps/nested-asset-wrappers.ts +124 -0
- package/src/core/base-builder/resolution/steps/static-values.ts +35 -0
- package/src/core/base-builder/resolution/steps/switches.ts +71 -0
- package/src/core/base-builder/resolution/steps/templates.ts +40 -0
- package/src/core/base-builder/resolution/value-resolver.ts +333 -0
- package/src/core/base-builder/storage/auxiliary-storage.ts +82 -0
- package/src/core/base-builder/storage/value-storage.ts +282 -0
- package/src/core/base-builder/types.ts +266 -0
- package/src/core/base-builder/utils.ts +10 -0
- package/src/core/flow/__tests__/index.test.ts +292 -0
- package/src/core/flow/index.ts +118 -0
- package/src/core/index.ts +8 -0
- package/src/core/mocks/generated/action.builder.ts +92 -0
- package/src/core/mocks/generated/choice-item.builder.ts +120 -0
- package/src/core/mocks/generated/choice.builder.ts +134 -0
- package/src/core/mocks/generated/collection.builder.ts +93 -0
- package/src/core/mocks/generated/field-collection.builder.ts +86 -0
- package/src/core/mocks/generated/index.ts +10 -0
- package/src/core/mocks/generated/info.builder.ts +64 -0
- package/src/core/mocks/generated/input.builder.ts +63 -0
- package/src/core/mocks/generated/overview-collection.builder.ts +65 -0
- package/src/core/mocks/generated/splash-collection.builder.ts +93 -0
- package/src/core/mocks/generated/text.builder.ts +47 -0
- package/src/core/mocks/index.ts +1 -0
- package/src/core/mocks/types/action.ts +92 -0
- package/src/core/mocks/types/choice.ts +129 -0
- package/src/core/mocks/types/collection.ts +140 -0
- package/src/core/mocks/types/info.ts +7 -0
- package/src/core/mocks/types/input.ts +7 -0
- package/src/core/mocks/types/text.ts +5 -0
- package/src/core/schema/__tests__/index.test.ts +127 -0
- package/src/core/schema/index.ts +195 -0
- package/src/core/schema/types.ts +7 -0
- package/src/core/switch/__tests__/index.test.ts +156 -0
- package/src/core/switch/index.ts +81 -0
- package/src/core/tagged-template/README.md +448 -0
- package/src/core/tagged-template/__tests__/extract-bindings-from-schema.test.ts +207 -0
- package/src/core/tagged-template/__tests__/index.test.ts +190 -0
- package/src/core/tagged-template/__tests__/schema-std-integration.test.ts +580 -0
- package/src/core/tagged-template/binding.ts +95 -0
- package/src/core/tagged-template/expression.ts +92 -0
- package/src/core/tagged-template/extract-bindings-from-schema.ts +120 -0
- package/src/core/tagged-template/index.ts +5 -0
- package/src/core/tagged-template/std.ts +472 -0
- package/src/core/tagged-template/types.ts +123 -0
- package/src/core/template/__tests__/index.test.ts +380 -0
- package/src/core/template/index.ts +196 -0
- package/src/core/utils/index.ts +160 -0
- package/src/fp/README.md +411 -0
- package/src/fp/__tests__/index.test.ts +1178 -0
- package/src/fp/index.ts +386 -0
- package/src/gen/common.ts +15 -0
- package/src/index.ts +5 -0
- package/src/types.ts +203 -0
- package/types/core/base-builder/conditional/index.d.ts +21 -0
- package/types/core/base-builder/context.d.ts +39 -0
- package/types/core/base-builder/errors.d.ts +45 -0
- package/types/core/base-builder/fluent-builder-base.d.ts +147 -0
- package/types/core/base-builder/guards.d.ts +58 -0
- package/types/core/base-builder/id/generator.d.ts +69 -0
- package/types/core/base-builder/id/registry.d.ts +93 -0
- package/types/core/base-builder/index.d.ts +9 -0
- package/types/core/base-builder/resolution/path-resolver.d.ts +15 -0
- package/types/core/base-builder/resolution/pipeline.d.ts +27 -0
- package/types/core/base-builder/resolution/steps/asset-id.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/asset-wrappers.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/builders.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/mixed-arrays.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/nested-asset-wrappers.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/static-values.d.ts +14 -0
- package/types/core/base-builder/resolution/steps/switches.d.ts +15 -0
- package/types/core/base-builder/resolution/steps/templates.d.ts +14 -0
- package/types/core/base-builder/resolution/value-resolver.d.ts +62 -0
- package/types/core/base-builder/storage/auxiliary-storage.d.ts +50 -0
- package/types/core/base-builder/storage/value-storage.d.ts +82 -0
- package/types/core/base-builder/types.d.ts +183 -0
- package/types/core/base-builder/utils.d.ts +2 -0
- package/types/core/flow/index.d.ts +23 -0
- package/types/core/index.d.ts +8 -0
- package/types/core/mocks/index.d.ts +2 -0
- package/types/core/mocks/types/action.d.ts +58 -0
- package/types/core/mocks/types/choice.d.ts +95 -0
- package/types/core/mocks/types/collection.d.ts +102 -0
- package/types/core/mocks/types/info.d.ts +7 -0
- package/types/core/mocks/types/input.d.ts +7 -0
- package/types/core/mocks/types/text.d.ts +5 -0
- package/types/core/schema/index.d.ts +34 -0
- package/types/core/schema/types.d.ts +5 -0
- package/types/core/switch/index.d.ts +21 -0
- package/types/core/tagged-template/binding.d.ts +19 -0
- package/types/core/tagged-template/expression.d.ts +11 -0
- package/types/core/tagged-template/extract-bindings-from-schema.d.ts +7 -0
- package/types/core/tagged-template/index.d.ts +6 -0
- package/types/core/tagged-template/std.d.ts +174 -0
- package/types/core/tagged-template/types.d.ts +69 -0
- package/types/core/template/index.d.ts +97 -0
- package/types/core/utils/index.d.ts +47 -0
- package/types/fp/index.d.ts +149 -0
- package/types/gen/common.d.ts +6 -0
- package/types/index.d.ts +3 -0
- package/types/types.d.ts +163 -0
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
import { describe, test, expect, beforeEach, vi } from "vitest";
|
|
2
|
+
import type { BaseBuildContext, SwitchMetadata } from "../types";
|
|
3
|
+
import { StorageKeys } from "../types";
|
|
4
|
+
import { AuxiliaryStorage } from "../storage/auxiliary-storage";
|
|
5
|
+
import { resolveSwitches } from "../resolution/steps/switches";
|
|
6
|
+
|
|
7
|
+
// Mock setValueAtPath for path resolution testing
|
|
8
|
+
vi.mock("../resolution/path-resolver", () => ({
|
|
9
|
+
setValueAtPath: vi.fn((result, path, value) => {
|
|
10
|
+
if (path.length === 1) {
|
|
11
|
+
result[String(path[0])] = value;
|
|
12
|
+
} else if (path.length === 2) {
|
|
13
|
+
const key = String(path[0]);
|
|
14
|
+
if (!result[key]) result[key] = [];
|
|
15
|
+
(result[key] as unknown[])[path[1] as number] = value;
|
|
16
|
+
}
|
|
17
|
+
}),
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
import { setValueAtPath } from "../resolution/path-resolver";
|
|
21
|
+
|
|
22
|
+
describe("resolveSwitches - Case Index Tracking", () => {
|
|
23
|
+
let auxiliaryStorage: AuxiliaryStorage;
|
|
24
|
+
let arrayProperties: ReadonlySet<string>;
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
vi.clearAllMocks();
|
|
28
|
+
auxiliaryStorage = new AuxiliaryStorage();
|
|
29
|
+
arrayProperties = new Set(["values"]);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("starts global case index at 0", () => {
|
|
33
|
+
let capturedCaseIndex: number | undefined;
|
|
34
|
+
|
|
35
|
+
const switchFn = vi.fn((_ctx: BaseBuildContext, caseIndex: number) => {
|
|
36
|
+
capturedCaseIndex = caseIndex;
|
|
37
|
+
return {
|
|
38
|
+
staticSwitch: [{ case: true, asset: { id: "test-1", type: "text" } }],
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
43
|
+
{ path: ["value"], switchFn },
|
|
44
|
+
];
|
|
45
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
46
|
+
|
|
47
|
+
const result: Record<string, unknown> = {};
|
|
48
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
49
|
+
|
|
50
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
51
|
+
|
|
52
|
+
expect(capturedCaseIndex).toBe(0);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("increments by number of cases in first switch", () => {
|
|
56
|
+
const capturedCaseIndices: number[] = [];
|
|
57
|
+
|
|
58
|
+
const firstSwitchFn = vi.fn((_ctx: BaseBuildContext, caseIndex: number) => {
|
|
59
|
+
capturedCaseIndices.push(caseIndex);
|
|
60
|
+
return {
|
|
61
|
+
staticSwitch: [
|
|
62
|
+
{ case: "cond1", asset: { id: "test-1", type: "text" } },
|
|
63
|
+
{ case: "cond2", asset: { id: "test-2", type: "text" } },
|
|
64
|
+
{ case: true, asset: { id: "test-3", type: "text" } },
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const secondSwitchFn = vi.fn(
|
|
70
|
+
(_ctx: BaseBuildContext, caseIndex: number) => {
|
|
71
|
+
capturedCaseIndices.push(caseIndex);
|
|
72
|
+
return {
|
|
73
|
+
staticSwitch: [{ case: true, asset: { id: "test-4", type: "text" } }],
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
79
|
+
{ path: ["value"], switchFn: firstSwitchFn },
|
|
80
|
+
{ path: ["label"], switchFn: secondSwitchFn },
|
|
81
|
+
];
|
|
82
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
83
|
+
|
|
84
|
+
const result: Record<string, unknown> = {};
|
|
85
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
86
|
+
|
|
87
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
88
|
+
|
|
89
|
+
expect(capturedCaseIndices).toEqual([0, 3]); // Second switch starts at index 3
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("correctly offsets second switch case indices", () => {
|
|
93
|
+
const capturedCaseIndices: number[] = [];
|
|
94
|
+
|
|
95
|
+
const createSwitchFn =
|
|
96
|
+
(numCases: number) => (_ctx: BaseBuildContext, caseIndex: number) => {
|
|
97
|
+
capturedCaseIndices.push(caseIndex);
|
|
98
|
+
return {
|
|
99
|
+
staticSwitch: Array(numCases)
|
|
100
|
+
.fill(null)
|
|
101
|
+
.map((_, i) => ({
|
|
102
|
+
case: i === numCases - 1 ? true : `cond${i}`,
|
|
103
|
+
asset: { id: `test-${i}`, type: "text" },
|
|
104
|
+
})),
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
109
|
+
{ path: ["value"], switchFn: createSwitchFn(2) },
|
|
110
|
+
{ path: ["label"], switchFn: createSwitchFn(3) },
|
|
111
|
+
{ path: ["title"], switchFn: createSwitchFn(1) },
|
|
112
|
+
];
|
|
113
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
114
|
+
|
|
115
|
+
const result: Record<string, unknown> = {};
|
|
116
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
117
|
+
|
|
118
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
119
|
+
|
|
120
|
+
// First: 0, Second: 0+2=2, Third: 2+3=5
|
|
121
|
+
expect(capturedCaseIndices).toEqual([0, 2, 5]);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("handles switches with varying case counts", () => {
|
|
125
|
+
const capturedCaseIndices: number[] = [];
|
|
126
|
+
|
|
127
|
+
// Switch with 5 cases
|
|
128
|
+
const largeSwitchFn = vi.fn((_ctx: BaseBuildContext, caseIndex: number) => {
|
|
129
|
+
capturedCaseIndices.push(caseIndex);
|
|
130
|
+
return {
|
|
131
|
+
staticSwitch: [
|
|
132
|
+
{ case: "c1", asset: { id: "1" } },
|
|
133
|
+
{ case: "c2", asset: { id: "2" } },
|
|
134
|
+
{ case: "c3", asset: { id: "3" } },
|
|
135
|
+
{ case: "c4", asset: { id: "4" } },
|
|
136
|
+
{ case: true, asset: { id: "5" } },
|
|
137
|
+
],
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Switch with 1 case
|
|
142
|
+
const smallSwitchFn = vi.fn((_ctx: BaseBuildContext, caseIndex: number) => {
|
|
143
|
+
capturedCaseIndices.push(caseIndex);
|
|
144
|
+
return {
|
|
145
|
+
dynamicSwitch: [{ case: true, asset: { id: "6" } }],
|
|
146
|
+
};
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
150
|
+
{ path: ["large"], switchFn: largeSwitchFn },
|
|
151
|
+
{ path: ["small"], switchFn: smallSwitchFn },
|
|
152
|
+
];
|
|
153
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
154
|
+
|
|
155
|
+
const result: Record<string, unknown> = {};
|
|
156
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
157
|
+
|
|
158
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
159
|
+
|
|
160
|
+
expect(capturedCaseIndices).toEqual([0, 5]);
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
describe("resolveSwitches - Array Property Wrapping", () => {
|
|
165
|
+
let auxiliaryStorage: AuxiliaryStorage;
|
|
166
|
+
|
|
167
|
+
beforeEach(() => {
|
|
168
|
+
vi.clearAllMocks();
|
|
169
|
+
auxiliaryStorage = new AuxiliaryStorage();
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
test("wraps switch result in array for array properties", () => {
|
|
173
|
+
const arrayProperties = new Set(["values"]);
|
|
174
|
+
|
|
175
|
+
const switchFn = vi.fn(() => ({
|
|
176
|
+
staticSwitch: [{ case: true, asset: { id: "test", type: "text" } }],
|
|
177
|
+
}));
|
|
178
|
+
|
|
179
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
180
|
+
{ path: ["values"], switchFn },
|
|
181
|
+
];
|
|
182
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
183
|
+
|
|
184
|
+
const result: Record<string, unknown> = {};
|
|
185
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
186
|
+
|
|
187
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
188
|
+
|
|
189
|
+
// Should wrap in array when path.length === 1 and property is array type
|
|
190
|
+
expect(setValueAtPath).toHaveBeenCalledWith(
|
|
191
|
+
result,
|
|
192
|
+
["values"],
|
|
193
|
+
[{ staticSwitch: [{ case: true, asset: { id: "test", type: "text" } }] }],
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test("does not wrap for non-array properties", () => {
|
|
198
|
+
const arrayProperties = new Set(["values"]);
|
|
199
|
+
|
|
200
|
+
const switchFn = vi.fn(() => ({
|
|
201
|
+
staticSwitch: [{ case: true, asset: { id: "test", type: "text" } }],
|
|
202
|
+
}));
|
|
203
|
+
|
|
204
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
205
|
+
{ path: ["label"], switchFn },
|
|
206
|
+
];
|
|
207
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
208
|
+
|
|
209
|
+
const result: Record<string, unknown> = {};
|
|
210
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
211
|
+
|
|
212
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
213
|
+
|
|
214
|
+
// Should NOT wrap because 'label' is not in arrayProperties
|
|
215
|
+
expect(setValueAtPath).toHaveBeenCalledWith(result, ["label"], {
|
|
216
|
+
staticSwitch: [{ case: true, asset: { id: "test", type: "text" } }],
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
test("does not wrap when path length > 1", () => {
|
|
221
|
+
const arrayProperties = new Set(["values"]);
|
|
222
|
+
|
|
223
|
+
const switchFn = vi.fn(() => ({
|
|
224
|
+
staticSwitch: [{ case: true, asset: { id: "test", type: "text" } }],
|
|
225
|
+
}));
|
|
226
|
+
|
|
227
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
228
|
+
{ path: ["values", 0], switchFn },
|
|
229
|
+
];
|
|
230
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
231
|
+
|
|
232
|
+
const result: Record<string, unknown> = { values: [] };
|
|
233
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
234
|
+
|
|
235
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
236
|
+
|
|
237
|
+
// Should NOT wrap because path.length > 1 (specific element)
|
|
238
|
+
expect(setValueAtPath).toHaveBeenCalledWith(result, ["values", 0], {
|
|
239
|
+
staticSwitch: [{ case: true, asset: { id: "test", type: "text" } }],
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
describe("resolveSwitches - Path Resolution", () => {
|
|
245
|
+
let auxiliaryStorage: AuxiliaryStorage;
|
|
246
|
+
let arrayProperties: ReadonlySet<string>;
|
|
247
|
+
|
|
248
|
+
beforeEach(() => {
|
|
249
|
+
vi.clearAllMocks();
|
|
250
|
+
auxiliaryStorage = new AuxiliaryStorage();
|
|
251
|
+
arrayProperties = new Set();
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test("sets value at single-segment path", () => {
|
|
255
|
+
const switchFn = vi.fn(() => ({
|
|
256
|
+
staticSwitch: [{ case: true, asset: { id: "test" } }],
|
|
257
|
+
}));
|
|
258
|
+
|
|
259
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
260
|
+
{ path: ["value"], switchFn },
|
|
261
|
+
];
|
|
262
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
263
|
+
|
|
264
|
+
const result: Record<string, unknown> = {};
|
|
265
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
266
|
+
|
|
267
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
268
|
+
|
|
269
|
+
expect(setValueAtPath).toHaveBeenCalledWith(
|
|
270
|
+
result,
|
|
271
|
+
["value"],
|
|
272
|
+
expect.objectContaining({ staticSwitch: expect.any(Array) }),
|
|
273
|
+
);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
test("sets value at multi-segment path", () => {
|
|
277
|
+
const switchFn = vi.fn(() => ({
|
|
278
|
+
staticSwitch: [{ case: true, asset: { id: "test" } }],
|
|
279
|
+
}));
|
|
280
|
+
|
|
281
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
282
|
+
{ path: ["nested", "deep"], switchFn },
|
|
283
|
+
];
|
|
284
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
285
|
+
|
|
286
|
+
const result: Record<string, unknown> = {};
|
|
287
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
288
|
+
|
|
289
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
290
|
+
|
|
291
|
+
expect(setValueAtPath).toHaveBeenCalledWith(
|
|
292
|
+
result,
|
|
293
|
+
["nested", "deep"],
|
|
294
|
+
expect.objectContaining({ staticSwitch: expect.any(Array) }),
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe("resolveSwitches - Edge Cases", () => {
|
|
300
|
+
let auxiliaryStorage: AuxiliaryStorage;
|
|
301
|
+
let arrayProperties: ReadonlySet<string>;
|
|
302
|
+
|
|
303
|
+
beforeEach(() => {
|
|
304
|
+
vi.clearAllMocks();
|
|
305
|
+
auxiliaryStorage = new AuxiliaryStorage();
|
|
306
|
+
arrayProperties = new Set();
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
test("returns early when no switches in storage", () => {
|
|
310
|
+
// Don't set any switches
|
|
311
|
+
const result: Record<string, unknown> = { existingValue: "test" };
|
|
312
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
313
|
+
|
|
314
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
315
|
+
|
|
316
|
+
// Result should be unchanged
|
|
317
|
+
expect(result).toEqual({ existingValue: "test" });
|
|
318
|
+
expect(setValueAtPath).not.toHaveBeenCalled();
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
test("returns early when empty switches array in storage", () => {
|
|
322
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, []);
|
|
323
|
+
|
|
324
|
+
const result: Record<string, unknown> = { existingValue: "test" };
|
|
325
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
326
|
+
|
|
327
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
328
|
+
|
|
329
|
+
expect(result).toEqual({ existingValue: "test" });
|
|
330
|
+
expect(setValueAtPath).not.toHaveBeenCalled();
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
test("returns early when no context provided", () => {
|
|
334
|
+
const switchFn = vi.fn(() => ({
|
|
335
|
+
staticSwitch: [{ case: true, asset: { id: "test" } }],
|
|
336
|
+
}));
|
|
337
|
+
|
|
338
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
339
|
+
{ path: ["value"], switchFn },
|
|
340
|
+
];
|
|
341
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
342
|
+
|
|
343
|
+
const result: Record<string, unknown> = {};
|
|
344
|
+
|
|
345
|
+
resolveSwitches(auxiliaryStorage, result, undefined, arrayProperties);
|
|
346
|
+
|
|
347
|
+
expect(switchFn).not.toHaveBeenCalled();
|
|
348
|
+
expect(setValueAtPath).not.toHaveBeenCalled();
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
test("handles dynamicSwitch correctly", () => {
|
|
352
|
+
const capturedCaseIndex: number[] = [];
|
|
353
|
+
|
|
354
|
+
const firstSwitchFn = vi.fn((_ctx: BaseBuildContext, caseIndex: number) => {
|
|
355
|
+
capturedCaseIndex.push(caseIndex);
|
|
356
|
+
return {
|
|
357
|
+
dynamicSwitch: [
|
|
358
|
+
{ case: "cond", asset: { id: "1" } },
|
|
359
|
+
{ case: true, asset: { id: "2" } },
|
|
360
|
+
],
|
|
361
|
+
};
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
const secondSwitchFn = vi.fn(
|
|
365
|
+
(_ctx: BaseBuildContext, caseIndex: number) => {
|
|
366
|
+
capturedCaseIndex.push(caseIndex);
|
|
367
|
+
return {
|
|
368
|
+
staticSwitch: [{ case: true, asset: { id: "3" } }],
|
|
369
|
+
};
|
|
370
|
+
},
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
374
|
+
{ path: ["first"], switchFn: firstSwitchFn },
|
|
375
|
+
{ path: ["second"], switchFn: secondSwitchFn },
|
|
376
|
+
];
|
|
377
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
378
|
+
|
|
379
|
+
const result: Record<string, unknown> = {};
|
|
380
|
+
const context: BaseBuildContext = { parentId: "test" };
|
|
381
|
+
|
|
382
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
383
|
+
|
|
384
|
+
// First has 2 cases (dynamicSwitch), second starts at index 2
|
|
385
|
+
expect(capturedCaseIndex).toEqual([0, 2]);
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
describe("resolveSwitches - Context Creation", () => {
|
|
390
|
+
let auxiliaryStorage: AuxiliaryStorage;
|
|
391
|
+
let arrayProperties: ReadonlySet<string>;
|
|
392
|
+
|
|
393
|
+
beforeEach(() => {
|
|
394
|
+
vi.clearAllMocks();
|
|
395
|
+
auxiliaryStorage = new AuxiliaryStorage();
|
|
396
|
+
arrayProperties = new Set();
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
test("creates switch context with property name in parentId", () => {
|
|
400
|
+
let capturedContext: BaseBuildContext | undefined;
|
|
401
|
+
|
|
402
|
+
const switchFn = vi.fn((ctx: BaseBuildContext) => {
|
|
403
|
+
capturedContext = ctx;
|
|
404
|
+
return { staticSwitch: [{ case: true, asset: { id: "test" } }] };
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
408
|
+
{ path: ["label"], switchFn },
|
|
409
|
+
];
|
|
410
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
411
|
+
|
|
412
|
+
const result: Record<string, unknown> = {};
|
|
413
|
+
const context: BaseBuildContext = { parentId: "parent" };
|
|
414
|
+
|
|
415
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
416
|
+
|
|
417
|
+
expect(capturedContext).toBeDefined();
|
|
418
|
+
expect(capturedContext?.parentId).toBe("parent-label");
|
|
419
|
+
expect(capturedContext?.branch).toBeUndefined();
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
test("handles context without parentId", () => {
|
|
423
|
+
let capturedContext: BaseBuildContext | undefined;
|
|
424
|
+
|
|
425
|
+
const switchFn = vi.fn((ctx: BaseBuildContext) => {
|
|
426
|
+
capturedContext = ctx;
|
|
427
|
+
return { staticSwitch: [{ case: true, asset: { id: "test" } }] };
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
431
|
+
{ path: ["label"], switchFn },
|
|
432
|
+
];
|
|
433
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
434
|
+
|
|
435
|
+
const result: Record<string, unknown> = {};
|
|
436
|
+
const context: BaseBuildContext = { parentId: undefined };
|
|
437
|
+
|
|
438
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
439
|
+
|
|
440
|
+
expect(capturedContext).toBeDefined();
|
|
441
|
+
expect(capturedContext?.parentId).toBe("label");
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
test("clears branch from switch context", () => {
|
|
445
|
+
let capturedContext: BaseBuildContext | undefined;
|
|
446
|
+
|
|
447
|
+
const switchFn = vi.fn((ctx: BaseBuildContext) => {
|
|
448
|
+
capturedContext = ctx;
|
|
449
|
+
return { staticSwitch: [{ case: true, asset: { id: "test" } }] };
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
const switches: SwitchMetadata<BaseBuildContext>[] = [
|
|
453
|
+
{ path: ["value"], switchFn },
|
|
454
|
+
];
|
|
455
|
+
auxiliaryStorage.set(StorageKeys.SWITCHES, switches);
|
|
456
|
+
|
|
457
|
+
const result: Record<string, unknown> = {};
|
|
458
|
+
const context: BaseBuildContext = {
|
|
459
|
+
parentId: "parent",
|
|
460
|
+
branch: { type: "slot", name: "test" },
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
resolveSwitches(auxiliaryStorage, result, context, arrayProperties);
|
|
464
|
+
|
|
465
|
+
expect(capturedContext).toBeDefined();
|
|
466
|
+
expect(capturedContext?.branch).toBeUndefined();
|
|
467
|
+
});
|
|
468
|
+
});
|