Skip to content

Commit b14bd5c

Browse files
marcmrfuittorio
andauthored
fix(registerMock): allow to use mocks defined in variables (#330)
* fix(registerMock): allow to use mocks defined in variables * test(registerMock): fix wrong test description Co-authored-by: Vittorio Guerriero <[email protected]>
1 parent 2b1c8cd commit b14bd5c

File tree

3 files changed

+58
-36
lines changed

3 files changed

+58
-36
lines changed

src/transformer/mock/mock.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,9 @@ export function getMockForList(nodeToMock: ts.TypeNode, node: ts.CallExpression)
6666
export function storeRegisterMock(typeToMock: ts.TypeNode, node: ts.CallExpression): ts.Node {
6767
if (ts.isTypeReferenceNode(typeToMock)) {
6868
const factory: ts.FunctionExpression = node.arguments[0] as ts.FunctionExpression;
69-
MockDefiner.instance.storeRegisterMockFor(TypescriptHelper.GetDeclarationFromNode(typeToMock.typeName), factory);
69+
return MockDefiner.instance.registerMockFor(TypescriptHelper.GetDeclarationFromNode(typeToMock.typeName), factory);
7070
} else {
7171
Logger('RegisterMock').error('registerMock can be used only to mock type references.');
72+
return ts.createEmptyStatement();
7273
}
73-
74-
return ts.createEmptyStatement();
7574
}

src/transformer/mockDefiner/mockDefiner.ts

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ export class MockDefiner {
3333
private _neededImportIdentifierPerFile: { [key: string]: Array<ModuleNameIdentifier> } = {};
3434
private _internalModuleImportIdentifierPerFile: { [key: string]: { [key in ModuleName]: ts.Identifier } } = {};
3535
private _factoryRegistrationsPerFile: FactoryRegistrationPerFile = {};
36-
private _registerMockFactoryRegistrationsPerFile: FactoryRegistrationPerFile = {};
3736
private _factoryIntersectionsRegistrationsPerFile: FactoryIntersectionRegistrationPerFile = {};
3837
private _factoryCache: DeclarationCache;
3938
private _registerMockFactoryCache: DeclarationCache;
@@ -93,7 +92,6 @@ export class MockDefiner {
9392
...this._getImportsToAddInFile(sourceFile),
9493
...this._getExportsToAddInFile(sourceFile),
9594
...this._getExportsIntersectionToAddInFile(sourceFile),
96-
...this._getRegisterMockInFile(sourceFile),
9795
];
9896
}
9997

@@ -105,7 +103,6 @@ export class MockDefiner {
105103
}
106104
this._factoryRegistrationsPerFile[sourceFile.fileName] = [];
107105
this._factoryIntersectionsRegistrationsPerFile[sourceFile.fileName] = [];
108-
this._registerMockFactoryRegistrationsPerFile[sourceFile.fileName] = [];
109106
}
110107

111108
public createMockFactory(declaration: ts.Declaration): void {
@@ -157,16 +154,12 @@ export class MockDefiner {
157154
return this._declarationCache.get(declaration) as string;
158155
}
159156

160-
public storeRegisterMockFor(declaration: ts.Declaration, factory: ts.FunctionExpression): void {
157+
public registerMockFor(declaration: ts.Declaration, factory: ts.FunctionExpression): ts.Node {
161158
const key: string = this.getDeclarationKeyMap(declaration);
162159

163160
this._registerMockFactoryCache.set(declaration, key);
164161

165-
this._registerMockFactoryRegistrationsPerFile[this._fileName] = this._registerMockFactoryRegistrationsPerFile[this._fileName] || [];
166-
this._registerMockFactoryRegistrationsPerFile[this._fileName].push({
167-
key: declaration,
168-
factory,
169-
});
162+
return this._getCallRegisterMock(this._fileName, key, factory);
170163
}
171164

172165
public hasMockForDeclaration(declaration: ts.Declaration): boolean {
@@ -283,33 +276,20 @@ export class MockDefiner {
283276
return [];
284277
}
285278

286-
private _getRegisterMockInFile(sourceFile: ts.SourceFile): ts.Statement[] {
287-
if (this._registerMockFactoryRegistrationsPerFile[sourceFile.fileName]) {
288-
return this._registerMockFactoryRegistrationsPerFile[sourceFile.fileName]
289-
.map((reg: { key: ts.Declaration; factory: ts.Expression }) => {
290-
// NOTE: this._registerMockFactoryCache and
291-
// this._registerMockFactoryCache are populated in the same routine
292-
// and if the former is defined the latter will be too!
293-
// eslint-disable-next-line
294-
const key: string = this._registerMockFactoryCache.get(reg.key)!;
295-
296-
return this._createRegistration(sourceFile.fileName, key, reg.factory);
297-
});
298-
}
299-
300-
return [];
301-
}
302-
303279
private _createRegistration(fileName: string, key: string, factory: ts.Expression): ts.Statement {
304280
return ts.createExpressionStatement(
305-
ts.createCall(
306-
ts.createPropertyAccess(
307-
this._mockRepositoryAccess(fileName),
308-
ts.createIdentifier('registerFactory'),
309-
),
310-
[],
311-
[ts.createStringLiteral(key), factory],
281+
this._getCallRegisterMock(fileName, key, factory)
282+
);
283+
}
284+
285+
private _getCallRegisterMock(fileName: string, key: string, factory: ts.Expression): ts.CallExpression {
286+
return ts.createCall(
287+
ts.createPropertyAccess(
288+
this._mockRepositoryAccess(fileName),
289+
ts.createIdentifier('registerFactory'),
312290
),
291+
[],
292+
[ts.createStringLiteral(key), factory],
313293
);
314294
}
315295

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { createMock, registerMock } from 'ts-auto-mock';
2+
3+
describe('registerMock using vars from the scope', () => {
4+
it('should override standard behaviour of mock creation using values from the scope', () => {
5+
interface APropInterface {
6+
internalProp: string;
7+
call: () => APropInterface;
8+
}
9+
10+
interface AParentInterface {
11+
prop: APropInterface;
12+
}
13+
14+
const propInstance: APropInterface = { internalProp: 'whaaat', call: () => propInstance };
15+
16+
registerMock<APropInterface>(() => propInstance);
17+
18+
const mock: AParentInterface = createMock<AParentInterface>();
19+
20+
expect(mock.prop).toBe(propInstance);
21+
expect(mock.prop.call()).toBe(propInstance);
22+
});
23+
24+
it('should override standard behaviour of mock creation using values from createMock', () => {
25+
interface APropInterface {
26+
internalProp: string;
27+
call: () => APropInterface;
28+
}
29+
30+
interface AParentInterface {
31+
prop: APropInterface;
32+
}
33+
34+
const propInstance: APropInterface = createMock<APropInterface>();
35+
36+
registerMock<APropInterface>(() => propInstance);
37+
38+
const mock: AParentInterface = createMock<AParentInterface>();
39+
40+
expect(mock.prop).toBe(propInstance);
41+
expect(mock.prop.call()).toBe(propInstance);
42+
});
43+
});

0 commit comments

Comments
 (0)