Skip to content

Commit

Permalink
feat(registerMock): allow use of mocked generics in register mock fac…
Browse files Browse the repository at this point in the history
…tory
  • Loading branch information
Pmyl committed Dec 8, 2020
1 parent 46bcc06 commit 512e150
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/register-mock.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NoTransformerError } from './errors/no-transformer.error';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function registerMock<T extends object>(factory: () => T): void {
export function registerMock<T extends object>(factory: (...args) => T): void {
throw new Error(NoTransformerError);
}
39 changes: 37 additions & 2 deletions src/transformer/mockDefiner/mockDefiner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { GetProperties } from '../descriptor/properties/properties';
import { GetTypeofEnumDescriptor } from '../descriptor/typeQuery/enumTypeQuery';
import { TypescriptCreator } from '../helper/creator';
import { createImportOnIdentifier } from '../helper/import';
import { MockIdentifierGenericParameter } from '../mockIdentifier/mockIdentifier';
import {
MockIdentifierGenericParameter,
MockIdentifierGenericParameterValue,
} from '../mockIdentifier/mockIdentifier';
import { PrivateIdentifier } from '../privateIdentifier/privateIdentifier';
import { Scope } from '../scope/scope';
import { DeclarationCache } from './cache/declarationCache';
Expand Down Expand Up @@ -194,7 +197,11 @@ export class MockDefiner {

this._registerMockFactoryCache.set(declaration, key);

return this._getCallRegisterMock(this._fileName, key, factory);
return this._getCallRegisterMock(
this._fileName,
key,
this._wrapRegisterMockFactory(factory)
);
}

public hasMockForDeclaration(declaration: ts.Declaration): boolean {
Expand Down Expand Up @@ -358,6 +365,34 @@ export class MockDefiner {
);
}

private _wrapRegisterMockFactory(factory: ts.Expression): ts.Expression {
return TypescriptCreator.createArrowFunction(
TypescriptCreator.createCall(factory, [
ts.createSpread(
TypescriptCreator.createCall(
ts.createPropertyAccess(
ts.createIdentifier('generics'),
ts.createIdentifier('map')
),
[
TypescriptCreator.createArrowFunction(
TypescriptCreator.createCall(
ts.createPropertyAccess(
ts.createIdentifier('g'),
MockIdentifierGenericParameterValue
),
[]
),
[TypescriptCreator.createParameter('g')]
),
]
)
),
]),
[TypescriptCreator.createParameter('generics')]
);
}

private _getCallRegisterMock(
fileName: string,
key: string,
Expand Down
55 changes: 55 additions & 0 deletions test/registerMock/generics/generics.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { createMock, registerMock } from 'ts-auto-mock';

describe('registerMock of type with generics', () => {
it('should provide mocked version of generics as parameters', () => {
type GenericsType<T> = {
internalProp: T;
};

type GenericsInterface<T, K> = {
internalProp: T;
internalProp2: K;
};

type GenericsInterface2<T, K> = {
internalProp: T;
internalProp2: K;
};

interface AParentInterface {
prop: GenericsType<string>;
prop2: GenericsInterface<number, 'Test'>;
prop3: GenericsInterface2<string, GenericsType<string>>;
}

registerMock<GenericsType<unknown>>((generic: unknown) => ({
internalProp: (generic as object).toString() + '-mocked',
}));

registerMock<GenericsInterface<unknown, unknown>>(
(genericNumber: unknown, genericString: unknown) => ({
internalProp: (genericNumber as number) + 5,
internalProp2: (genericString as object).toString() + '-mocked',
})
);

registerMock<GenericsInterface2<unknown, unknown>>(
(genericString: unknown, genericObject: unknown) => {
(genericObject as GenericsType<string>).internalProp += '-mocked';
return {
internalProp: (genericString as object).toString() + '-mocked',
internalProp2: genericObject,
};
}
);
const mock: AParentInterface = createMock<AParentInterface>();

expect(mock.prop.internalProp).toBe('-mocked');
expect(mock.prop2.internalProp).toBe(5);
expect(mock.prop2.internalProp2).toBe('Test-mocked');
expect(mock.prop3.internalProp).toBe('-mocked');
expect(mock.prop3.internalProp2).toEqual({
internalProp: '-mocked-mocked',
});
});
});

0 comments on commit 512e150

Please sign in to comment.