Skip to content

Commit

Permalink
refactor(parser): add mock generator and remove analyzer (#107)
Browse files Browse the repository at this point in the history
* refactor(parser): add mock generator and remove analyzer

Add MockGenerator
Remove ClassAnalyzer moving all the logics into ClassParser

BREAKING CHANGE: ClassAnalayzer has been removed and all the logic has been moved to ClassParser

* test(parser): add (move) mock generator integration test

* chore(parser): config jest and typescript to run integration test

* fix(mockingbird-ts): use mock generator differently (singleton)

Remove mock generator from mockingbird-ts and import it from @mockinbird/parser instead
mock generator acts as a singleton now

* refactor(mockingbird-ts): fix mock factory

* chore(mockingbird-ts): config jest to collect coverage properly
  • Loading branch information
omermorad committed Sep 11, 2021
1 parent b4d51ff commit 32c0ff6
Show file tree
Hide file tree
Showing 35 changed files with 148 additions and 207 deletions.
2 changes: 1 addition & 1 deletion packages/mockingbird/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ module.exports = {
roots: [...base.roots, '<rootDir>/test'],
name: packageJson.name,
displayName: packageJson.name,
collectCoverageFrom: ['src/**/*.ts', 'test/**/*.test.js'],
collectCoverageFrom: ['src/**/*.ts', 'test/**/*.ts'],
coveragePathIgnorePatterns: ['index.ts', 'test-classes.ts'],
};
8 changes: 2 additions & 6 deletions packages/mockingbird/src/lib/builder/mock-builder.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { MockBuilder } from './mock-builder';
import { Faker, ClassParser, Mock } from '../../';
import { MockGenerator } from '../generator/mock-generator';
import { Mock } from '../../index';

class Bird {
@Mock()
Expand Down Expand Up @@ -28,10 +27,7 @@ describe('MockBuilder Integration Test', () => {
let builder: MockBuilder<Bird>;

beforeAll(() => {
const parser = new ClassParser(Faker);
const generator = new MockGenerator(parser);

createNewBuilder = (): MockBuilder<Bird> => new MockBuilder<Bird>(Bird, generator);
createNewBuilder = (): MockBuilder<Bird> => new MockBuilder<Bird>(Bird);
});

scenario('mutating some values', () => {
Expand Down
5 changes: 2 additions & 3 deletions packages/mockingbird/src/lib/builder/mock-builder.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ClassLiteral, Class } from '@mockinbird/common';
import { Keys, Mutations } from './types';
import { MockProducer } from './mock-producer';
import { MockGenerator } from '../generator/mock-generator';

export interface MockBuilder<TClass = any> {
/**
Expand Down Expand Up @@ -101,8 +100,8 @@ export class MockBuilder<TClass = any> extends MockProducer<TClass> {
private omitKeys: Keys<TClass> = [];
private pickKeys: Keys<TClass> = [];

public constructor(targetClass: Class<TClass>, mockGenerator: MockGenerator) {
super(targetClass, mockGenerator);
public constructor(targetClass: Class<TClass>) {
super(targetClass);
}

private clean(): void {
Expand Down
11 changes: 4 additions & 7 deletions packages/mockingbird/src/lib/builder/mock-producer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Class } from '@mockinbird/common';
import { MockGenerator } from '../generator/mock-generator';
import { Keys, Mutations } from './types';
import { mockGenerator } from '@mockinbird/parser';

interface ExtraKeys<TClass> {
omit?: Keys<TClass>;
Expand All @@ -12,10 +12,7 @@ interface ExtraKeys<TClass> {
export class MockProducer<TClass = any> {
protected locale = 'en';

protected constructor(
protected readonly targetClass: Class<TClass>,
protected readonly mockGenerator: MockGenerator
) {}
protected constructor(protected readonly targetClass: Class<TClass>) {}

public setLocale(locale: string): void {
this.locale = locale;
Expand All @@ -25,7 +22,7 @@ export class MockProducer<TClass = any> {
const { locale } = this;
const { mutations = {}, plain = false, pick = [], omit = [] } = config;

return this.mockGenerator.create(this.targetClass, {
return mockGenerator.generate(this.targetClass, {
locale,
mutations,
pick,
Expand All @@ -39,7 +36,7 @@ export class MockProducer<TClass = any> {
const { locale } = this;
const { mutations = {}, plain = false, pick = [], omit = [] } = config;

return this.mockGenerator.create(this.targetClass, {
return mockGenerator.generate(this.targetClass, {
locale,
mutations,
pick,
Expand Down
6 changes: 1 addition & 5 deletions packages/mockingbird/src/lib/factory/mock-factory.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Class } from '@mockinbird/common';
import { classParser } from '@mockinbird/parser';
import { MockBuilder } from '../builder';
import { MockGenerator } from '../generator/mock-generator';

/**
* MockFactory take the target class as a parameter and returns
Expand All @@ -12,7 +10,5 @@ import { MockGenerator } from '../generator/mock-generator';
* @returns {MockBuilder<TClass>} new builder to compose a mock
*/
export function MockFactory<TClass>(target: Class<TClass>): MockBuilder<TClass> {
const generator = new MockGenerator(classParser);

return new MockBuilder<TClass>(target, generator);
return new MockBuilder<TClass>(target);
}
3 changes: 2 additions & 1 deletion packages/parser/.eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist
dist
jest.config.js
5 changes: 3 additions & 2 deletions packages/parser/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ const packageJson = require('./package');

module.exports = {
...base,
roots: [...base.roots, '<rootDir>/test'],
name: packageJson.name,
displayName: packageJson.name,
collectCoverageFrom: ['src/**/*.ts', 'test/**/*.test.js'],
coveragePathIgnorePatterns: ['index.ts'],
collectCoverageFrom: ['src/**/*.ts', 'test/**/*.ts'],
coveragePathIgnorePatterns: ['index.ts', 'test-classes.ts'],
};
8 changes: 4 additions & 4 deletions packages/parser/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Container } from 'typedi';
import { ClassParser } from './lib/parser/class-parser';
import { MockGenerator } from './lib/generator/mock-generator';
import { Faker } from '@mockinbird/common';
import RandExp from 'randexp';

export * from './types/types';
export { ClassParser };
export * from './lib/types/types';
export * from './lib/generator/mock-generator';

Container.set('Faker', Faker);
Container.set('RandExp', RandExp);

export const classParser = Container.get(ClassParser);
export const mockGenerator = Container.get(MockGenerator);
90 changes: 0 additions & 90 deletions packages/parser/src/lib/analyzer/class-analyzer.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ClassParser } from '@mockinbird/parser';
import { MockGenerator } from './mock-generator';
import { ClassParser } from '../parser/class-parser';

/**
* The full test of MockGenerator can be found under the 'test' folder,
Expand All @@ -13,7 +13,7 @@ describe('MockGenerator Unit Test', () => {
}

const parserMock = {
setFakerLocale: jest.fn(),
setLocale: jest.fn(),
parse: jest.fn(),
} as unknown as jest.Mocked<ClassParser>;

Expand All @@ -25,10 +25,10 @@ describe('MockGenerator Unit Test', () => {
scenario('generate a SIMPLE mock from a class', () => {
given('I want to generate a new mock from a class', () => {
when('I call the create method with no configurations', () => {
beforeAll(() => generator.create(TestClass));
beforeAll(() => generator.generate(TestClass));

test('then setup parser with the default locale', () => {
expect(parserMock.setFakerLocale).toHaveBeenCalledWith('en');
expect(parserMock.setLocale).toHaveBeenCalledWith('en');
});

test('then call parse one time only', () => {
Expand All @@ -41,17 +41,17 @@ describe('MockGenerator Unit Test', () => {
scenario('generate mock from a class with a different configurations', () => {
given('I want to generate a mock with different locale', () => {
when('creating a new mock from generator passing the proper params', () => {
beforeAll(() => generator.create(TestClass, { locale: 'arbitrary-locale' }));
beforeAll(() => generator.generate(TestClass, { locale: 'arbitrary-locale' }));

then('setup the parser with the locale from the options', () => {
expect(parserMock.setFakerLocale).toHaveBeenCalledWith('arbitrary-locale');
expect(parserMock.setLocale).toHaveBeenCalledWith('arbitrary-locale');
});
});
});

given('I want to generate a mock and mutate different values', () => {
when('creating a new mock from generator passing the proper param', () => {
beforeAll(() => generator.create(TestClass, { mutations: { test: 'value' } }));
beforeAll(() => generator.generate(TestClass, { mutations: { test: 'value' } }));

then('call parse with the valid options', () => {
expect(parserMock.parse).toHaveBeenCalledWith(TestClass, { mutations: { test: 'value' } });
Expand All @@ -61,7 +61,7 @@ describe('MockGenerator Unit Test', () => {

given('I want to generate a mock and omit different values', () => {
when('creating a new mock from generator passing the proper param', () => {
beforeAll(() => generator.create(TestClass, { omit: ['test'] }));
beforeAll(() => generator.generate(TestClass, { omit: ['test'] }));

then('call parse with the valid options', () => {
expect(parserMock.parse).toHaveBeenCalledWith(TestClass, { omit: ['test'] });
Expand All @@ -82,7 +82,7 @@ describe('MockGenerator Unit Test', () => {
})()
);

result = generator.create(TestClass, { plain: true });
result = generator.generate(TestClass, { plain: true });
});

then('', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Service } from 'typedi';
import { Class, ClassLiteral, isPrimitive } from '@mockinbird/common';
import { ClassParser } from '@mockinbird/parser';
import { MockGeneratorOptions } from '../../types/mock-generator-options.interface';
import { MockGeneratorOptions } from '../types/mock-generator-options.interface';
import { ClassParser } from '../parser/class-parser';

@Service()
export class MockGenerator {
private static readonly DEFAULT_LOCALE = 'en';

public constructor(private readonly classParser: ClassParser) {}

private static classToPlain<TClass>(targetClass: TClass): ClassLiteral<TClass> {
Expand Down Expand Up @@ -37,7 +37,7 @@ export class MockGenerator {
* @param targetClass {Class<TClass>}
* @returns {TClass}
*/
public create<TClass = any>(targetClass: Class<TClass>): TClass;
public generate<TClass = any>(targetClass: Class<TClass>): TClass;

/**
* Return an array of objects with all the properties decorated by the
Expand All @@ -55,12 +55,12 @@ export class MockGenerator {
* @param targetClass
* @param options
*/
public create<TClass = any>(
public generate<TClass = any>(
targetClass: Class<TClass>,
options: MockGeneratorOptions<TClass>
): TClass | ClassLiteral<TClass>;

public create<TClass = any>(
public generate<TClass = any>(
targetClass: Class<TClass>,
options: MockGeneratorOptions<TClass>
): TClass[] | ClassLiteral<TClass>[];
Expand All @@ -72,13 +72,13 @@ export class MockGenerator {
* @param targetClass
* @param options
*/
public create<TClass = any>(
public generate<TClass = any>(
targetClass: Class<TClass>,
options: MockGeneratorOptions<TClass> = {}
): TClass | TClass[] | ClassLiteral<TClass> | ClassLiteral<TClass>[] {
const { count = 1, locale = MockGenerator.DEFAULT_LOCALE, plain = false, ...config } = options || {};
const { count = 1, plain = false, locale = 'en', ...config } = options || {};

this.classParser.setFakerLocale(locale);
this.classParser.setLocale(locale);

if (count === 1) {
const parsedClass = this.classParser.parse(targetClass, config);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Service } from 'typedi';
import { Container, Service } from 'typedi';
import { isPrimitive } from '@mockinbird/common';
import { Property } from '@mockinbird/reflect';
import { ExactValue, MultiClass } from '@mockinbird/common';
import { PrimitiveHandler } from './primitive-handler';
import { ValueHandler } from '../types/value-handler.interface';
import { ClassAnalyzer } from '../lib/analyzer/class-analyzer';
import { ClassParser } from '../parser/class-parser';

@Service()
export class ArrayValueHandler implements ValueHandler {
Expand Down Expand Up @@ -34,10 +34,10 @@ export class ArrayValueHandler implements ValueHandler {
}

const instances = new Array<TClass>(count);
const analyzer = ClassAnalyzer.create<TClass>(type);
const parser = Container.get<ClassParser>(ClassParser);

for (let index = 0; index < count; index++) {
instances[index] = analyzer.analyzeProps();
instances[index] = parser.parse(type);
}

return instances;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import RandExp from 'randexp';
import { Inject, Service } from 'typedi';
import { Property } from '@mockinbird/reflect';
import { ValueHandler } from '../types/value-handler.interface';
import { Class } from '../../../common';
import { Class } from '@mockinbird/common';

@Service()
export class RegexValueHandler implements ValueHandler {
Expand Down
Loading

0 comments on commit 32c0ff6

Please sign in to comment.