Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
f4ce18b
WIP
jcobis Sep 9, 2025
c56d0ad
WIP
jcobis Sep 9, 2025
4a65473
Connect and upload
jcobis Sep 10, 2025
a6cc38d
Indentation
jcobis Sep 10, 2025
dfacd16
Array lengths
jcobis Sep 10, 2025
a0ca7c9
Unrecognized
jcobis Sep 10, 2025
49d7b1c
Faker Args
jcobis Sep 10, 2025
662cf63
Probability
jcobis Sep 10, 2025
a8f6aac
More Validation
jcobis Sep 11, 2025
0a011a3
Extract constants
jcobis Sep 11, 2025
4cb73c3
Tests are more readable
jcobis Sep 12, 2025
36f7327
Array length map nesting
jcobis Sep 12, 2025
8e9dd61
Update array map, reorg tests
jcobis Sep 12, 2025
b84b769
Address comments: move function, remove fallback
jcobis Sep 12, 2025
43c70db
Tweak type
jcobis Sep 12, 2025
1847b05
Rename methods
jcobis Sep 12, 2025
d5056c0
Rename variable
jcobis Sep 12, 2025
578a632
use JSON.stringify to escape characters
jcobis Sep 12, 2025
df8ead5
Json.Stringify
jcobis Sep 12, 2025
ca42248
Make javadoc more descriptive
jcobis Sep 12, 2025
dca8dc0
Fix object
jcobis Sep 12, 2025
5ede61a
Tests
jcobis Sep 12, 2025
a2c071e
Tests
jcobis Sep 15, 2025
2d85620
Include more defaults for all BSON types
jcobis Sep 15, 2025
7d1d32c
More tests
jcobis Sep 15, 2025
9847721
Faker version
jcobis Sep 15, 2025
dbcf751
Merge branch 'main' of github.com:mongodb-js/compass into mock_data_s…
jcobis Sep 15, 2025
834979c
Faker version
jcobis Sep 15, 2025
6e6d615
Merge branch 'main' into mock_data_script_generation_copy
kpamaran Sep 15, 2025
3d06135
Fix api contract and anticipate future change
kpamaran Sep 16, 2025
be29465
Merge branch 'main' into fix-api-contract-and-anticipate-change
kpamaran Sep 16, 2025
bd5483f
Merge branch 'fix-api-contract-and-anticipate-change' into mock_data_…
kpamaran Sep 16, 2025
4fe0d45
Implement rough form of mock data generator preview
kpamaran Sep 16, 2025
4d64eff
Rename type
jcobis Sep 16, 2025
9da51cf
Regex alternative
jcobis Sep 16, 2025
64b659c
Escape names
jcobis Sep 16, 2025
d7b15db
Merge branch 'main' of github.com:mongodb-js/compass into mock_data_s…
jcobis Sep 17, 2025
2144bab
Type mongoType, ignore null and undefined
jcobis Sep 17, 2025
2d6038e
Merge branch 'mock_data_script_generation' into mock-data-generator-p…
kpamaran Sep 17, 2025
64d47de
generate documents with faker for PreviewScreen
kpamaran Sep 17, 2025
c6346cc
Merge branch 'main' into mock-data-generator-preview-screen
kpamaran Sep 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,14 @@ describe('MockDataGeneratorModal', () => {
atlasAiService: {
getMockDataSchema: () => {
return Promise.resolve({
content: {
fields: [
{
fieldPath: 'name',
mongoType: 'string',
fakerMethod: 'person.firstName',
fakerArgs: [],
isArray: false,
probability: 1.0,
},
],
},
fields: [
{
fieldPath: 'name',
mongoType: 'string',
fakerMethod: 'person.firstName',
fakerArgs: [],
},
],
} as MockDataSchemaResponse);
},
},
Expand Down Expand Up @@ -287,42 +283,32 @@ describe('MockDataGeneratorModal', () => {
const mockServicesWithMockDataResponse = createMockServices();
mockServicesWithMockDataResponse.atlasAiService.getMockDataSchema = () =>
Promise.resolve({
content: {
fields: [
{
fieldPath: 'name',
mongoType: 'string',
fakerMethod: 'person.firstName',
fakerArgs: [],
isArray: false,
probability: 1.0,
},
{
fieldPath: 'age',
mongoType: 'int',
fakerMethod: 'number.int',
fakerArgs: [],
isArray: false,
probability: 1.0,
},
{
fieldPath: 'email',
mongoType: 'string',
fakerMethod: 'internet',
fakerArgs: [],
isArray: false,
probability: 1.0,
},
{
fieldPath: 'username',
mongoType: 'string',
fakerMethod: 'noSuchMethod',
fakerArgs: [],
isArray: false,
probability: 1.0,
},
],
},
fields: [
{
fieldPath: 'name',
mongoType: 'string',
fakerMethod: 'person.firstName',
fakerArgs: [],
},
{
fieldPath: 'age',
mongoType: 'int',
fakerMethod: 'number.int',
fakerArgs: [],
},
{
fieldPath: 'email',
mongoType: 'string',
fakerMethod: 'internet',
fakerArgs: [],
},
{
fieldPath: 'username',
mongoType: 'string',
fakerMethod: 'noSuchMethod',
fakerArgs: [],
},
],
});

it('shows a loading spinner when the faker schema generation is in progress', async () => {
Expand All @@ -332,9 +318,7 @@ describe('MockDataGeneratorModal', () => {
setTimeout(
() =>
resolve({
content: {
fields: [],
},
fields: [],
}),
1000
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
spacing,
} from '@mongodb-js/compass-components';

import type { ValidatedFakerSchemaMapping } from './types';
import { type MockDataGeneratorState, MockDataGeneratorStep } from './types';
import { StepButtonLabelMap } from './constants';
import type { CollectionState } from '../../modules/collection-tab';
Expand All @@ -25,6 +26,7 @@ import {
import RawSchemaConfirmationScreen from './raw-schema-confirmation-screen';
import FakerSchemaEditorScreen from './faker-schema-editor-screen';
import ScriptScreen from './script-screen';
import PreviewScreen from './preview-screen';

const footerStyles = css`
flex-direction: row;
Expand Down Expand Up @@ -79,9 +81,22 @@ const MockDataGeneratorModal = ({
/>
);
case MockDataGeneratorStep.DOCUMENT_COUNT:
return <></>; // TODO: CLOUDP-333856
return <></>; // TODO(CLOUDP-333856)
case MockDataGeneratorStep.PREVIEW_DATA:
return <></>; // TODO: CLOUDP-333857
// TODO(CLOUDP-333855): Apply results from schema editor confirmation
//
// function validateFakerSchema(input: FakerSchemaMapping): asserts input is ValidatedFakerSchemaMapping {
// ...
// }
return (
<PreviewScreen
confirmedFakerSchema={
(fakerSchemaGenerationState.status === 'completed'
? fakerSchemaGenerationState.fakerSchema
: []) as ValidatedFakerSchemaMapping[]
}
/>
);
case MockDataGeneratorStep.GENERATE_DATA:
return <ScriptScreen />;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useMemo } from 'react';
import { css, spacing, Body, Code } from '@mongodb-js/compass-components';
import type { ValidatedFakerSchemaMapping } from './types';
import { generateDocument } from './script-generation-utils';

const descriptionStyles = css({
marginBottom: spacing[200],
});

interface PreviewScreenProps {
confirmedFakerSchema: ValidatedFakerSchemaMapping[];
}

const NUM_SAMPLE_DOCUMENTS = 5;

function PreviewScreen({ confirmedFakerSchema }: PreviewScreenProps) {
const sampleDocuments = useMemo(() => {
const documents = [];
for (let i = 0; i < NUM_SAMPLE_DOCUMENTS; i++) {
documents.push(generateDocument(confirmedFakerSchema));
}

return documents;
}, [confirmedFakerSchema]);

return (
<div data-testid="preview-screen">
<Body as="h2" baseFontSize={16} weight="medium">
Preview Mock Data
</Body>
<Body className={descriptionStyles}>
Below is a sample of documents that will be generated based on your
script
</Body>
<Code language="javascript" copyable={false}>
{JSON.stringify(sampleDocuments, null, 2)}
</Code>
</div>
);
}

export default PreviewScreen;
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import { expect } from 'chai';
import { faker } from '@faker-js/faker/locale/en';
import {
generateScript,
generateDocument,
type FakerFieldMapping,
} from './script-generation-utils';
import type { ValidatedFakerSchemaMapping } from './types';

/**
* Helper function to test that generated document code is executable
Expand Down Expand Up @@ -1255,4 +1257,135 @@ describe('Script Generation', () => {
}
});
});

describe('generateDocument', () => {
const createValidatedSchemaMapping = (
fieldPath: string,
fakerMethod: string,
mongoType: string = 'String',
fakerArgs: any[] = []
) =>
({
fieldPath,
fakerMethod,
mongoType,
fakerArgs,
} as ValidatedFakerSchemaMapping);

it('should generate document with simple flat fields of mixed types', () => {
const schema: ValidatedFakerSchemaMapping[] = [
createValidatedSchemaMapping('name', 'person.fullName'),
createValidatedSchemaMapping('age', 'number.int', 'Number'),
createValidatedSchemaMapping('isActive', 'datatype.boolean', 'Boolean'),
createValidatedSchemaMapping('createdAt', 'date.recent', 'Date'),
createValidatedSchemaMapping(
'_id',
'database.mongodbObjectId',
'ObjectId'
),
];

const document = generateDocument(schema);

expect(document).to.be.an('object');
expect(document).to.have.property('name');
expect(document.name).to.be.a('string').and.not.be.empty;
expect(document).to.have.property('age');
expect(document.age).to.be.a('number');
expect(document).to.have.property('isActive');
expect(document.isActive).to.be.a('boolean');
expect(document).to.have.property('createdAt');
expect(document.createdAt).to.be.a('date');
expect(document).to.have.property('_id');
expect(document._id).to.be.a('string');
});

it('should generate document with multi-dimensional arrays of mixed types', () => {
const schema: ValidatedFakerSchemaMapping[] = [
createValidatedSchemaMapping(
'numberMatrix[][]',
'number.int',
'Number'
),
createValidatedSchemaMapping('stringMatrix[][]', 'lorem.word'),
createValidatedSchemaMapping(
'booleanGrid[][]',
'datatype.boolean',
'Boolean'
),
];

const arrayLengthMap = {
numberMatrix: [2, 3],
stringMatrix: [2, 2],
booleanGrid: [3, 2],
};

const document = generateDocument(schema, arrayLengthMap);

expect(document).to.be.an('object');
expect(document).to.have.property('numberMatrix');
expect(document.numberMatrix).to.be.an('array').with.length(2);
expect(document.numberMatrix[0]).to.be.an('array').with.length(3);
expect(document.numberMatrix[0][0]).to.be.a('number');

expect(document).to.have.property('stringMatrix');
expect(document.stringMatrix).to.be.an('array').with.length(2);
expect(document.stringMatrix[0]).to.be.an('array').with.length(2);
expect(document.stringMatrix[0][0]).to.be.a('string').and.not.be.empty;

expect(document).to.have.property('booleanGrid');
expect(document.booleanGrid).to.be.an('array').with.length(3);
expect(document.booleanGrid[0]).to.be.an('array').with.length(2);
expect(document.booleanGrid[0][0]).to.be.a('boolean');
});

it('should handle complex nested structures with arrays and objects', () => {
const schema: ValidatedFakerSchemaMapping[] = [
createValidatedSchemaMapping('company.name', 'company.name'),
createValidatedSchemaMapping(
'company.employees[].name',
'person.fullName'
),
createValidatedSchemaMapping(
'company.employees[].email',
'internet.email'
),
createValidatedSchemaMapping(
'company.employees[].skills[]',
'lorem.word'
),
createValidatedSchemaMapping('company.founded', 'date.past', 'Date'),
createValidatedSchemaMapping(
'company.isActive',
'datatype.boolean',
'Boolean'
),
];

const document = generateDocument(schema);

expect(document).to.be.an('object');
expect(document).to.have.property('company');
expect(document.company).to.be.an('object');
expect(document.company).to.have.property('name');
expect(document.company.name).to.be.a('string').and.not.be.empty;
expect(document.company).to.have.property('founded');
expect(document.company.founded).to.be.a('date');
expect(document.company).to.have.property('isActive');
expect(document.company.isActive).to.be.a('boolean');
expect(document.company).to.have.property('employees');
expect(document.company.employees).to.be.an('array').with.length(3);

const firstEmployee = document.company.employees[0];
expect(firstEmployee).to.be.an('object');
expect(firstEmployee).to.have.property('name');
expect(firstEmployee.name).to.be.a('string').and.not.be.empty;
expect(firstEmployee).to.have.property('email');
expect(firstEmployee.email).to.be.a('string').and.include('@');
expect(firstEmployee).to.have.property('skills');
expect(firstEmployee.skills).to.be.an('array').with.length(3);
expect(firstEmployee.skills[0]).to.be.a('string').and.not.be.empty;
});
});
});
Loading
Loading