p-elements-core 1.2.32-rc1 → 1.2.32-rc11

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.
@@ -0,0 +1,294 @@
1
+ /**
2
+ * Tests for Maquette mapping module
3
+ */
4
+
5
+ import { describe, it, expect } from 'vitest';
6
+ import { createMapping } from './mapping.js';
7
+
8
+ describe('Maquette mapping', () => {
9
+ describe('createMapping', () => {
10
+ interface TestSource {
11
+ id: number;
12
+ name: string;
13
+ }
14
+
15
+ interface TestTarget {
16
+ sourceId: number;
17
+ displayName: string;
18
+ }
19
+
20
+ it('should create a mapping instance', () => {
21
+ const mapping = createMapping<TestSource, TestTarget>(
22
+ (source) => source.id,
23
+ (source) => ({ sourceId: source.id, displayName: source.name }),
24
+ (source, target) => {
25
+ target.displayName = source.name;
26
+ }
27
+ );
28
+
29
+ expect(mapping).toBeDefined();
30
+ expect(mapping.results).toBeDefined();
31
+ expect(mapping.map).toBeDefined();
32
+ expect(Array.isArray(mapping.results)).toBe(true);
33
+ });
34
+
35
+ it('should create initial results from sources', () => {
36
+ const mapping = createMapping<TestSource, TestTarget>(
37
+ (source) => source.id,
38
+ (source) => ({ sourceId: source.id, displayName: source.name }),
39
+ (source, target) => {
40
+ target.displayName = source.name;
41
+ }
42
+ );
43
+
44
+ const sources = [
45
+ { id: 1, name: 'Alice' },
46
+ { id: 2, name: 'Bob' },
47
+ { id: 3, name: 'Charlie' },
48
+ ];
49
+
50
+ mapping.map(sources);
51
+
52
+ expect(mapping.results.length).toBe(3);
53
+ expect(mapping.results[0].sourceId).toBe(1);
54
+ expect(mapping.results[0].displayName).toBe('Alice');
55
+ expect(mapping.results[1].sourceId).toBe(2);
56
+ expect(mapping.results[2].sourceId).toBe(3);
57
+ });
58
+
59
+ it('should update existing results when sources change', () => {
60
+ let createCount = 0;
61
+ let updateCount = 0;
62
+
63
+ const mapping = createMapping<TestSource, TestTarget>(
64
+ (source) => source.id,
65
+ (source) => {
66
+ createCount++;
67
+ return { sourceId: source.id, displayName: source.name };
68
+ },
69
+ (source, target) => {
70
+ updateCount++;
71
+ target.displayName = source.name;
72
+ }
73
+ );
74
+
75
+ // Initial mapping
76
+ mapping.map([
77
+ { id: 1, name: 'Alice' },
78
+ { id: 2, name: 'Bob' },
79
+ ]);
80
+
81
+ expect(createCount).toBe(2);
82
+ expect(updateCount).toBe(0);
83
+
84
+ // Update with same keys but different names
85
+ mapping.map([
86
+ { id: 1, name: 'Alice Updated' },
87
+ { id: 2, name: 'Bob Updated' },
88
+ ]);
89
+
90
+ expect(createCount).toBe(2); // No new creates
91
+ expect(updateCount).toBe(2); // Both updated
92
+ expect(mapping.results[0].displayName).toBe('Alice Updated');
93
+ expect(mapping.results[1].displayName).toBe('Bob Updated');
94
+ });
95
+
96
+ it('should add new items', () => {
97
+ let createCount = 0;
98
+
99
+ const mapping = createMapping<TestSource, TestTarget>(
100
+ (source) => source.id,
101
+ (source) => {
102
+ createCount++;
103
+ return { sourceId: source.id, displayName: source.name };
104
+ },
105
+ (source, target) => {
106
+ target.displayName = source.name;
107
+ }
108
+ );
109
+
110
+ mapping.map([{ id: 1, name: 'Alice' }]);
111
+ expect(createCount).toBe(1);
112
+
113
+ mapping.map([
114
+ { id: 1, name: 'Alice' },
115
+ { id: 2, name: 'Bob' },
116
+ { id: 3, name: 'Charlie' },
117
+ ]);
118
+
119
+ expect(createCount).toBe(3);
120
+ expect(mapping.results.length).toBe(3);
121
+ expect(mapping.results[2].sourceId).toBe(3);
122
+ });
123
+
124
+ it('should remove items', () => {
125
+ const mapping = createMapping<TestSource, TestTarget>(
126
+ (source) => source.id,
127
+ (source) => ({ sourceId: source.id, displayName: source.name }),
128
+ (source, target) => {
129
+ target.displayName = source.name;
130
+ }
131
+ );
132
+
133
+ mapping.map([
134
+ { id: 1, name: 'Alice' },
135
+ { id: 2, name: 'Bob' },
136
+ { id: 3, name: 'Charlie' },
137
+ ]);
138
+
139
+ expect(mapping.results.length).toBe(3);
140
+
141
+ mapping.map([{ id: 2, name: 'Bob' }]);
142
+
143
+ expect(mapping.results.length).toBe(1);
144
+ expect(mapping.results[0].sourceId).toBe(2);
145
+ });
146
+
147
+ it('should handle reordering of items', () => {
148
+ let createCount = 0;
149
+ let updateCount = 0;
150
+
151
+ const mapping = createMapping<TestSource, TestTarget>(
152
+ (source) => source.id,
153
+ (source) => {
154
+ createCount++;
155
+ return { sourceId: source.id, displayName: source.name };
156
+ },
157
+ (source, target) => {
158
+ updateCount++;
159
+ target.displayName = source.name;
160
+ }
161
+ );
162
+
163
+ mapping.map([
164
+ { id: 1, name: 'Alice' },
165
+ { id: 2, name: 'Bob' },
166
+ { id: 3, name: 'Charlie' },
167
+ ]);
168
+
169
+ const originalResults = [...mapping.results];
170
+
171
+ // Reverse order
172
+ mapping.map([
173
+ { id: 3, name: 'Charlie' },
174
+ { id: 2, name: 'Bob' },
175
+ { id: 1, name: 'Alice' },
176
+ ]);
177
+
178
+ // Should reuse existing results, not create new ones
179
+ expect(createCount).toBe(3);
180
+ expect(mapping.results.length).toBe(3);
181
+ expect(mapping.results[0].sourceId).toBe(3);
182
+ expect(mapping.results[1].sourceId).toBe(2);
183
+ expect(mapping.results[2].sourceId).toBe(1);
184
+
185
+ // Results should be reordered, not recreated
186
+ expect(mapping.results[0]).toBe(originalResults[2]);
187
+ expect(mapping.results[1]).toBe(originalResults[1]);
188
+ expect(mapping.results[2]).toBe(originalResults[0]);
189
+ });
190
+
191
+ it('should handle mixed add, remove, reorder operations', () => {
192
+ const mapping = createMapping<TestSource, TestTarget>(
193
+ (source) => source.id,
194
+ (source) => ({ sourceId: source.id, displayName: source.name }),
195
+ (source, target) => {
196
+ target.displayName = source.name;
197
+ }
198
+ );
199
+
200
+ mapping.map([
201
+ { id: 1, name: 'Alice' },
202
+ { id: 2, name: 'Bob' },
203
+ { id: 3, name: 'Charlie' },
204
+ ]);
205
+
206
+ mapping.map([
207
+ { id: 4, name: 'David' }, // New
208
+ { id: 2, name: 'Bob' }, // Existing, reordered
209
+ { id: 5, name: 'Eve' }, // New
210
+ ]);
211
+
212
+ expect(mapping.results.length).toBe(3);
213
+ expect(mapping.results[0].sourceId).toBe(4);
214
+ expect(mapping.results[1].sourceId).toBe(2);
215
+ expect(mapping.results[2].sourceId).toBe(5);
216
+ });
217
+
218
+ it('should handle string keys', () => {
219
+ interface StringKeySource {
220
+ key: string;
221
+ value: number;
222
+ }
223
+
224
+ const mapping = createMapping<StringKeySource, { val: number }>(
225
+ (source) => source.key,
226
+ (source) => ({ val: source.value }),
227
+ (source, target) => {
228
+ target.val = source.value;
229
+ }
230
+ );
231
+
232
+ mapping.map([
233
+ { key: 'a', value: 1 },
234
+ { key: 'b', value: 2 },
235
+ ]);
236
+
237
+ expect(mapping.results.length).toBe(2);
238
+ expect(mapping.results[0].val).toBe(1);
239
+ expect(mapping.results[1].val).toBe(2);
240
+ });
241
+
242
+ it('should pass correct index to createResult and updateResult', () => {
243
+ const createdIndexes: number[] = [];
244
+ const updatedIndexes: number[] = [];
245
+
246
+ const mapping = createMapping<TestSource, TestTarget>(
247
+ (source) => source.id,
248
+ (source, index) => {
249
+ createdIndexes.push(index);
250
+ return { sourceId: source.id, displayName: source.name };
251
+ },
252
+ (source, target, index) => {
253
+ updatedIndexes.push(index);
254
+ target.displayName = source.name;
255
+ }
256
+ );
257
+
258
+ mapping.map([
259
+ { id: 1, name: 'Alice' },
260
+ { id: 2, name: 'Bob' },
261
+ { id: 3, name: 'Charlie' },
262
+ ]);
263
+
264
+ expect(createdIndexes).toEqual([0, 1, 2]);
265
+
266
+ mapping.map([
267
+ { id: 1, name: 'Alice' },
268
+ { id: 2, name: 'Bob' },
269
+ { id: 3, name: 'Charlie' },
270
+ ]);
271
+
272
+ expect(updatedIndexes).toEqual([0, 1, 2]);
273
+ });
274
+
275
+ it('should handle empty arrays', () => {
276
+ const mapping = createMapping<TestSource, TestTarget>(
277
+ (source) => source.id,
278
+ (source) => ({ sourceId: source.id, displayName: source.name }),
279
+ (source, target) => {
280
+ target.displayName = source.name;
281
+ }
282
+ );
283
+
284
+ mapping.map([]);
285
+ expect(mapping.results.length).toBe(0);
286
+
287
+ mapping.map([{ id: 1, name: 'Alice' }]);
288
+ expect(mapping.results.length).toBe(1);
289
+
290
+ mapping.map([]);
291
+ expect(mapping.results.length).toBe(0);
292
+ });
293
+ });
294
+ });