From 967fdbcc581476cf0a1ad220841f7b894e5cbbde Mon Sep 17 00:00:00 2001 From: Neal Granger Date: Thu, 3 Sep 2020 11:20:44 -0700 Subject: [PATCH] feat: add buildSync method to Mocker class Add a new `buildSync` method alongside the existing `build` method to allow the generator to be used where synchronous flow is required. This is a simple non-breaking surface-level change. The library does not currently include any internal async logic. The async behavior of the `build` method is designed to avoid an unwanted breaking interface change in the future if async logic is added (discussed [here](https://github.com/danibram/mocker-data-generator/issues/100)). If async generators are added in the future, I suggest that they be excluded from the set of generators available for use when calling `buildSync` - this could be achieved cleanly in typescript by giving the `Mocker` class a generic `Schema` type that is referenced in conditional types on the `build` and `buildSync` methods. This would also require adding strict type inference to the schema interface, but doing so could have the added benefit of returning non-opaque typed data. --- README.md | 17 ++++++++++ src/lib/Mocker.ts | 54 +++++++++++++++++------------- src/lib/tests/Mocker.build.spec.ts | 35 +++++++++++++++++++ 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 07d10e0..fd10eea 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,22 @@ mocker() }, err => console.error(err) ) + +// Synchronously + +// This returns an object +// { +// user:[array of users], +// group: [array of groups], +// conditionalField: [array of conditionalFields] +// } +var data = mocker() + .schema('user', user, 2) + .schema('group', group, 2) + .schema('conditionalField', conditionalField, 2) + .buildSync() + +console.log(util.inspect(data, { depth: 10 })) ``` ## Documentation @@ -144,6 +160,7 @@ Data generation goes with model based composed by generators, the generators can * **_reset()_**: Clean the internal DB. * **_restart()_**: Clean the internal DB and all the schemas inside. * **_build(callback)_**: This methods start to produce the data and wrap it to the callback function, the callback funtion have 2 parameters, error and data generated. +- **_buildSync()_**: Synchronous version of `build(callback)`. Returns generated data or throws an error. ### Schema definition diff --git a/src/lib/Mocker.ts b/src/lib/Mocker.ts index 3e13240..2bc81b8 100644 --- a/src/lib/Mocker.ts +++ b/src/lib/Mocker.ts @@ -36,34 +36,40 @@ export class Mocker { return this } - build(cb?: (error: Error | null, _?: any) => void): Promise - build(cb?: (error: Error | null, _?: any) => void): void - build(cb?: (error: Error | null, _?: any) => void): any { - try { - this.schemas.reduce((acc, schema) => { - let instances + buildSync() { + this.schemas.reduce((acc, schema) => { + let instances + + try { + instances = schema.build(acc) + } catch (e) { + throw new Error('Schema: "' + schema.name + '" ' + e) + } - try { - instances = schema.build(acc) - } catch (e) { - throw new Error('Schema: "' + schema.name + '" ' + e) - } + // Clean virtuals + if (schema.virtualPaths.length > 0) { + instances.forEach((x) => + cleanVirtuals(schema.virtualPaths, x, { + strict: true, + symbol: ',' + }) + ) + } - // Clean virtuals - if (schema.virtualPaths.length > 0) { - instances.forEach((x) => - cleanVirtuals(schema.virtualPaths, x, { - strict: true, - symbol: ',' - }) - ) - } + // Add to db + acc[schema.name] = instances - // Add to db - acc[schema.name] = instances + return acc + }, this.DB) - return acc - }, this.DB) + return this.DB + } + + build(cb?: (error: Error | null, _?: any) => void): Promise + build(cb?: (error: Error | null, _?: any) => void): void + build(cb?: (error: Error | null, _?: any) => void): any { + try { + this.buildSync() } catch (e) { return cb ? cb(e) : Promise.reject(e) } diff --git a/src/lib/tests/Mocker.build.spec.ts b/src/lib/tests/Mocker.build.spec.ts index 32478ac..8d0bc3f 100644 --- a/src/lib/tests/Mocker.build.spec.ts +++ b/src/lib/tests/Mocker.build.spec.ts @@ -152,3 +152,38 @@ test('Should build with Promised old style', async (t) => { .build() .then((db) => t.deepEqual(db, result)) }) + +test('Should build synchronously', (t) => { + let result = { + users: [ + { + hello: 'world' + } + ] + } + let mock = new Mocker() + let db = mock.schema('users', { hello: { static: 'world' } }, 1).buildSync() + + t.deepEqual(db, result) +}) + +test('Should throw synchronously', (t) => { + let result = { + users: [ + { + hello: 'world' + } + ] + } + let mock = new Mocker() + const error = t.throws(() => + mock + .schema('users', { hello: { faker: 'worldrqwerqw' } }, 1) + .buildSync() + ) + + t.is( + error.message, + 'Schema: "users" Error: "faker" This faker method doesnt exists \'worldrqwerqw\'.' + ) +})