Skip to content

Commit 49d7b1c

Browse files
committed
Faker Args
1 parent a0ca7c9 commit 49d7b1c

File tree

2 files changed

+206
-11
lines changed

2 files changed

+206
-11
lines changed

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

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,4 +495,180 @@ describe('Script Generation', () => {
495495
}
496496
});
497497
});
498+
499+
describe('Faker Arguments', () => {
500+
it('should handle string arguments', () => {
501+
const schema = {
502+
name: {
503+
mongoType: 'string',
504+
fakerMethod: 'person.firstName',
505+
fakerArgs: ['male'],
506+
},
507+
};
508+
509+
const result = generateScript(schema, {
510+
databaseName: 'testdb',
511+
collectionName: 'users',
512+
documentCount: 1,
513+
});
514+
515+
expect(result.success).to.equal(true);
516+
if (result.success) {
517+
expect(result.script).to.contain("faker.person.firstName('male')");
518+
}
519+
});
520+
521+
it('should handle number arguments', () => {
522+
const schema = {
523+
age: {
524+
mongoType: 'number',
525+
fakerMethod: 'number.int',
526+
fakerArgs: [18, 65],
527+
},
528+
};
529+
530+
const result = generateScript(schema, {
531+
databaseName: 'testdb',
532+
collectionName: 'users',
533+
documentCount: 1,
534+
});
535+
536+
expect(result.success).to.equal(true);
537+
if (result.success) {
538+
expect(result.script).to.contain('faker.number.int(18, 65)');
539+
}
540+
});
541+
542+
it('should handle boolean arguments', () => {
543+
const schema = {
544+
active: {
545+
mongoType: 'boolean',
546+
fakerMethod: 'datatype.boolean',
547+
fakerArgs: [0.8],
548+
},
549+
};
550+
551+
const result = generateScript(schema, {
552+
databaseName: 'testdb',
553+
collectionName: 'users',
554+
documentCount: 1,
555+
});
556+
557+
expect(result.success).to.equal(true);
558+
if (result.success) {
559+
expect(result.script).to.contain('faker.datatype.boolean(0.8)');
560+
}
561+
});
562+
563+
it('should handle JSON object arguments', () => {
564+
const schema = {
565+
score: {
566+
mongoType: 'number',
567+
fakerMethod: 'number.int',
568+
fakerArgs: [{ json: '{"min":0,"max":100}' }],
569+
},
570+
};
571+
572+
const result = generateScript(schema, {
573+
databaseName: 'testdb',
574+
collectionName: 'tests',
575+
documentCount: 1,
576+
});
577+
578+
expect(result.success).to.equal(true);
579+
if (result.success) {
580+
expect(result.script).to.contain(
581+
'faker.number.int({"min":0,"max":100})'
582+
);
583+
}
584+
});
585+
586+
it('should handle JSON arguments', () => {
587+
const schema = {
588+
color: {
589+
mongoType: 'string',
590+
fakerMethod: 'helpers.arrayElement',
591+
fakerArgs: [{ json: "['red', 'blue', 'green']" }],
592+
},
593+
};
594+
595+
const result = generateScript(schema, {
596+
databaseName: 'testdb',
597+
collectionName: 'items',
598+
documentCount: 1,
599+
});
600+
601+
expect(result.success).to.equal(true);
602+
if (result.success) {
603+
expect(result.script).to.contain(
604+
"faker.helpers.arrayElement(['red', 'blue', 'green'])"
605+
);
606+
}
607+
});
608+
609+
it('should handle mixed argument types', () => {
610+
const schema = {
611+
description: {
612+
mongoType: 'string',
613+
fakerMethod: 'lorem.words',
614+
fakerArgs: [5, true],
615+
},
616+
};
617+
618+
const result = generateScript(schema, {
619+
databaseName: 'testdb',
620+
collectionName: 'posts',
621+
documentCount: 1,
622+
});
623+
624+
expect(result.success).to.equal(true);
625+
if (result.success) {
626+
expect(result.script).to.contain('faker.lorem.words(5, true)');
627+
}
628+
});
629+
630+
it('should escape quotes in string arguments', () => {
631+
const schema = {
632+
quote: {
633+
mongoType: 'string',
634+
fakerMethod: 'lorem.sentence',
635+
fakerArgs: ["It's a 'test' string"],
636+
},
637+
};
638+
639+
const result = generateScript(schema, {
640+
databaseName: 'testdb',
641+
collectionName: 'quotes',
642+
documentCount: 1,
643+
});
644+
645+
expect(result.success).to.equal(true);
646+
if (result.success) {
647+
expect(result.script).to.contain(
648+
"faker.lorem.sentence('It\\'s a \\'test\\' string')"
649+
);
650+
}
651+
});
652+
653+
it('should handle empty arguments array', () => {
654+
const schema = {
655+
id: {
656+
mongoType: 'string',
657+
fakerMethod: 'string.uuid',
658+
fakerArgs: [],
659+
},
660+
};
661+
662+
const result = generateScript(schema, {
663+
databaseName: 'testdb',
664+
collectionName: 'items',
665+
documentCount: 1,
666+
});
667+
668+
expect(result.success).to.equal(true);
669+
if (result.success) {
670+
expect(result.script).to.contain('faker.string.uuid()');
671+
}
672+
});
673+
});
498674
});

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

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
export type FakerArg = string | number | boolean | { json: string };
2+
13
export interface FieldMapping {
24
mongoType: string;
35
fakerMethod: string;
4-
fakerArgs: any[]; // TODO: type this properly later
6+
fakerArgs: FakerArg[];
57
}
68

79
// Hierarchical array length map that mirrors document structure
@@ -239,15 +241,9 @@ export function generateScript(
239241
.replace(/'/g, "\\'")
240242
.replace(/`/g, '\\`');
241243

242-
// Validate document count
243-
const documentCount = Math.max(
244-
1,
245-
Math.min(10000, Math.floor(options.documentCount)) // TODO
246-
);
247-
248244
const script = `// Mock Data Generator Script
249245
// Generated for collection: ${escapedDbName}.${escapedCollectionName}
250-
// Document count: ${documentCount}
246+
// Document count: ${options.documentCount}
251247
252248
const { faker } = require('@faker-js/faker');
253249
@@ -261,7 +257,7 @@ function generateDocument() {
261257
262258
// Generate and insert documents
263259
const documents = [];
264-
for (let i = 0; i < ${documentCount}; i++) {
260+
for (let i = 0; i < ${options.documentCount}; i++) {
265261
documents.push(generateDocument());
266262
}
267263
@@ -394,8 +390,8 @@ function generateFakerCall(mapping: FieldMapping): string {
394390
? getDefaultFakerMethod(mapping.mongoType)
395391
: mapping.fakerMethod;
396392

397-
// TODO: Handle arguments properly
398-
return `faker.${method}()`;
393+
const args = formatFakerArgs(mapping.fakerArgs);
394+
return `faker.${method}(${args})`;
399395
}
400396

401397
/**
@@ -424,3 +420,26 @@ export function getDefaultFakerMethod(mongoType: string): string {
424420
return 'lorem.word';
425421
}
426422
}
423+
424+
/**
425+
* Converts faker arguments to JavaScript code
426+
*/
427+
export function formatFakerArgs(fakerArgs: FakerArg[]): string {
428+
const stringifiedArgs: string[] = [];
429+
430+
for (const arg of fakerArgs) {
431+
if (typeof arg === 'string') {
432+
// Escape single quotes for JS strings (and backticks for security)
433+
const escapedArg = arg.replace(/[`']/g, '\\$&');
434+
stringifiedArgs.push(`'${escapedArg}'`);
435+
} else if (typeof arg === 'number' || typeof arg === 'boolean') {
436+
stringifiedArgs.push(`${arg}`);
437+
} else if (typeof arg === 'object' && arg !== null && 'json' in arg) {
438+
// Pre-serialized JSON objects
439+
const jsonArg = arg as { json: string };
440+
stringifiedArgs.push(jsonArg.json);
441+
}
442+
}
443+
444+
return stringifiedArgs.join(', ');
445+
}

0 commit comments

Comments
 (0)