Skip to content

Commit 36f7327

Browse files
committed
Array length map nesting
1 parent 4cb73c3 commit 36f7327

File tree

2 files changed

+50
-44
lines changed

2 files changed

+50
-44
lines changed

packages/compass-collection/src/components/mock-data-generator-modal/script-generation-utils.spec.ts

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ describe('Script Generation', () => {
256256
collectionName: 'posts',
257257
documentCount: 1,
258258
arrayLengthMap: {
259-
tags: 5,
259+
tags: [5],
260260
},
261261
});
262262

@@ -277,7 +277,7 @@ describe('Script Generation', () => {
277277
documentCount: 1,
278278
arrayLengthMap: {
279279
users: {
280-
tags: 4,
280+
tags: [4],
281281
},
282282
},
283283
});
@@ -289,55 +289,57 @@ describe('Script Generation', () => {
289289
}
290290
});
291291

292-
it('should handle hierarchical array length map', () => {
292+
it('should handle zero-length arrays', () => {
293293
const schema = {
294-
'departments[].employees[].skills[]': createFieldMapping('lorem.word'),
294+
'tags[]': createFieldMapping('lorem.word'),
295+
'categories[]': createFieldMapping('lorem.word'),
295296
};
296297

297298
const result = generateScript(schema, {
298299
databaseName: 'testdb',
299-
collectionName: 'company',
300+
collectionName: 'posts',
300301
documentCount: 1,
301302
arrayLengthMap: {
302-
departments: {
303-
employees: {
304-
skills: 3,
305-
},
306-
},
303+
tags: [0],
304+
categories: [2],
307305
},
308306
});
309307

310308
expect(result.success).to.equal(true);
311309
if (result.success) {
312-
expect(result.script).to.contain('Array.from({length: 3}');
310+
// Should have tags array with length 0 (empty array)
311+
expect(result.script).to.contain('Array.from({length: 0}');
312+
// Should have categories array with length 2
313+
expect(result.script).to.contain('Array.from({length: 2}');
314+
// Verify both arrays are present
315+
expect(result.script).to.contain('tags:');
316+
expect(result.script).to.contain('categories:');
313317
}
314318
});
315319

316-
it('should handle zero-length arrays', () => {
320+
it('should handle multi-dimensional arrays with custom lengths', () => {
317321
const schema = {
318-
'tags[]': createFieldMapping('lorem.word'),
319-
'categories[]': createFieldMapping('lorem.word'),
322+
'matrix[][]': createFieldMapping('number.int'),
323+
'cube[][][]': createFieldMapping('number.float'),
320324
};
321325

322326
const result = generateScript(schema, {
323327
databaseName: 'testdb',
324-
collectionName: 'posts',
328+
collectionName: 'data',
325329
documentCount: 1,
326330
arrayLengthMap: {
327-
tags: 0,
328-
categories: 2,
331+
matrix: [2, 5], // 2x5 matrix
332+
cube: [3, 4, 2], // 3x4x2 cube
329333
},
330334
});
331335

332336
expect(result.success).to.equal(true);
333337
if (result.success) {
334-
// Should have tags array with length 0 (empty array)
335-
expect(result.script).to.contain('Array.from({length: 0}');
336-
// Should have categories array with length 2
337-
expect(result.script).to.contain('Array.from({length: 2}');
338-
// Verify both arrays are present
339-
expect(result.script).to.contain('tags:');
340-
expect(result.script).to.contain('categories:');
338+
const expectedReturnBlock = `return {
339+
matrix: Array.from({length: 2}, () => Array.from({length: 5}, () => faker.number.int())),
340+
cube: Array.from({length: 3}, () => Array.from({length: 4}, () => Array.from({length: 2}, () => faker.number.float())))
341+
};`;
342+
expect(result.script).to.contain(expectedReturnBlock);
341343
}
342344
});
343345
});

packages/compass-collection/src/components/mock-data-generator-modal/script-generation-utils.ts

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export interface FieldMapping {
1212

1313
// Hierarchical array length map that mirrors document structure
1414
export type ArrayLengthMap = {
15-
[fieldName: string]: number | ArrayLengthMap;
15+
[fieldName: string]: number[] | ArrayLengthMap;
1616
};
1717

1818
export interface ScriptOptions {
@@ -351,24 +351,24 @@ function generateDocumentCode(
351351
}
352352
} else if ('type' in value && value.type === 'array') {
353353
// It's an array
354-
const nestedArrayLengthMap =
355-
typeof arrayLengthMap[fieldName] === 'object'
356-
? arrayLengthMap[fieldName]
357-
: {};
358354
const arrayCode = generateArrayCode(
359355
value as ArrayStructure,
360356
indent + INDENT_SIZE,
361357
fieldName,
362358
arrayLengthMap,
363-
nestedArrayLengthMap
359+
0 // Start at dimension 0
364360
);
365361
rootLevelFields.push(`${fieldIndent}${fieldName}: ${arrayCode}`);
366362
} else {
367363
// It's a nested object: recursive call
364+
365+
// Type Validation/ Fallback for misconfigured array length map
366+
const arrayDimensions = arrayLengthMap[fieldName];
368367
const nestedArrayLengthMap =
369-
typeof arrayLengthMap[fieldName] === 'object'
370-
? arrayLengthMap[fieldName]
371-
: arrayLengthMap;
368+
typeof arrayDimensions === 'object' && !Array.isArray(arrayDimensions)
369+
? arrayDimensions
370+
: {};
371+
372372
const nestedCode = generateDocumentCode(
373373
value as DocumentStructure,
374374
indent + INDENT_SIZE,
@@ -393,33 +393,37 @@ function generateArrayCode(
393393
arrayStructure: ArrayStructure,
394394
indent: number = INDENT_SIZE,
395395
fieldName: string = '',
396-
parentArrayLengthMap: ArrayLengthMap = {},
397-
nestedArrayLengthMap: ArrayLengthMap = {}
396+
arrayLengthMap: ArrayLengthMap = {},
397+
dimensionIndex: number = 0
398398
): string {
399399
const elementType = arrayStructure.elementType;
400400

401-
// Get array length from map or use default
402-
const arrayLength =
403-
typeof parentArrayLengthMap[fieldName] === 'number'
404-
? parentArrayLengthMap[fieldName]
405-
: DEFAULT_ARRAY_LENGTH;
401+
// Get array length for this dimension
402+
const arrayDimensions = arrayLengthMap[fieldName];
403+
const arrayLength = Array.isArray(arrayDimensions)
404+
? arrayDimensions[dimensionIndex] ?? DEFAULT_ARRAY_LENGTH
405+
: DEFAULT_ARRAY_LENGTH; // Fallback for misconfigured array length map
406406

407407
if ('mongoType' in elementType) {
408408
// Array of primitives
409409
const fakerCall = generateFakerCall(elementType as FieldMapping);
410410
return `Array.from({length: ${arrayLength}}, () => ${fakerCall})`;
411411
} else if ('type' in elementType && elementType.type === 'array') {
412-
// Nested array (e.g., matrix[][])
412+
// Nested array (e.g., matrix[][]) - keep same fieldName, increment dimension
413413
const nestedArrayCode = generateArrayCode(
414414
elementType as ArrayStructure,
415415
indent,
416-
'', // No specific field name for nested arrays
417-
nestedArrayLengthMap,
418-
{}
416+
fieldName,
417+
arrayLengthMap,
418+
dimensionIndex + 1 // Next dimension
419419
);
420420
return `Array.from({length: ${arrayLength}}, () => ${nestedArrayCode})`;
421421
} else {
422422
// Array of objects
423+
const nestedArrayLengthMap =
424+
typeof arrayDimensions === 'object' && !Array.isArray(arrayDimensions)
425+
? arrayDimensions
426+
: {}; // Fallback for misconfigured array length map
423427
const objectCode = generateDocumentCode(
424428
elementType as DocumentStructure,
425429
indent,

0 commit comments

Comments
 (0)