Skip to content

Commit

Permalink
fix error when constructor not setup
Browse files Browse the repository at this point in the history
  • Loading branch information
Roaders committed Oct 16, 2023
1 parent fae1506 commit 9e7dfa0
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 23 deletions.
2 changes: 1 addition & 1 deletion main/helper/lookup-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export function getLookup<T, C extends ConstructorFunction<T>, U extends LookupT
lookupType: U,
): FunctionCallLookup<T, C, U> {
switch (lookupType) {
case 'constructor':
case 'constructorFunction':
return mock.constructorCallLookup as FunctionCallLookup<T, C, U>;
case 'function':
return mock.functionCallLookup as FunctionCallLookup<T, C, U>;
Expand Down
14 changes: 7 additions & 7 deletions main/mock/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export type LookupParams<
C extends ConstructorFunction<T>,
U extends LookupType,
K extends FunctionName<T, C, U>,
> = U extends 'constructor'
> = U extends 'constructorFunction'
? ConstructorParams<C>
: U extends FunctionTypes
? FunctionParams<LookupFunction<T, C, U, K>>
Expand All @@ -75,10 +75,10 @@ export type InstanceLookupTypes = 'function' | 'getter' | 'setter';
export type SetterTypes = 'staticSetter' | 'setter';
export type GetterTypes = 'staticGetter' | 'getter';
export type FunctionTypes = 'staticFunction' | 'function';
export type LookupType = StaticLookupTypes | InstanceLookupTypes | 'constructor';
export type LookupType = StaticLookupTypes | InstanceLookupTypes | 'constructorFunction';

export type VerifierTarget<T, C extends ConstructorFunction<T>, U extends LookupType> = U extends 'constructor'
? { constructor: C }
export type VerifierTarget<T, C extends ConstructorFunction<T>, U extends LookupType> = U extends 'constructorFunction'
? { constructorFunction: C }
: U extends StaticLookupTypes
? U extends FunctionTypes
? FunctionsOnly<C>
Expand Down Expand Up @@ -158,7 +158,7 @@ export interface IMocked<T, C extends ConstructorFunction<T> = never> {
*/
mockConstructor: C;

constructorCallLookup: FunctionCallLookup<T, C, 'constructor'>;
constructorCallLookup: FunctionCallLookup<T, C, 'constructorFunction'>;
functionCallLookup: FunctionCallLookup<T, C, 'function'>;
setterCallLookup: FunctionCallLookup<T, C, 'setter'>;
getterCallLookup: FunctionCallLookup<T, C, 'getter'>;
Expand All @@ -182,7 +182,7 @@ export interface IMocked<T, C extends ConstructorFunction<T> = never> {
*/
setup(...operators: OperatorFunction<T, C>[]): IMocked<T, C>;

setupConstructor(): IFunctionWithParametersVerification<ConstructorParams<C>, T, 'constructor', C>;
setupConstructor(): IFunctionWithParametersVerification<ConstructorParams<C>, T, 'constructorFunction', C>;

/**
* Sets up a single function and returns a function verifier to verify calls made and parameters passed.
Expand Down Expand Up @@ -258,7 +258,7 @@ export interface IMocked<T, C extends ConstructorFunction<T> = never> {
* expect(myMock.withFunction("functionName")).wasCalledOnce():
* expect(myMock.withFunction("functionName").withParameters("one", 2)).wasCalledOnce():
*/
withConstructor(): IFunctionWithParametersVerification<ConstructorParams<C>, T, 'constructor', C>;
withConstructor(): IFunctionWithParametersVerification<ConstructorParams<C>, T, 'constructorFunction', C>;

/**
* Verifies calls to a previously setup function.
Expand Down
12 changes: 6 additions & 6 deletions main/mock/operators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ import {
*/
export function setupConstructor<T, C extends ConstructorFunction<T>>(): OperatorFunction<T, C> {
return (mocked: IMocked<T, C>) => {
(mocked.mockConstructor = class MockConstructor {
mocked.mockConstructor = class MockConstructor {
constructor(...args: ConstructorParams<C>) {
trackConstructorCall(mocked, args as any);
}
} as C),
(mocked.constructorCallLookup['constructor'] = []);
} as C;
mocked.constructorCallLookup['constructorFunction'] = [];

return mocked;
};
Expand Down Expand Up @@ -266,11 +266,11 @@ function definePropertyImpl<

export function trackConstructorCall<T, C extends ConstructorFunction<T>>(
mock: IMocked<T, C>,
params: LookupParams<T, C, 'constructor', 'constructor'>,
params: LookupParams<T, C, 'constructorFunction', 'constructorFunction'>,
) {
const lookup = getLookup(mock, 'constructor');
const lookup = getLookup(mock, 'constructorFunction');

trackCall(lookup, 'constructor', params);
trackCall(lookup, 'constructorFunction', params);
}

function trackFunctionCall<
Expand Down
27 changes: 18 additions & 9 deletions main/mock/verifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ export type VerifierParams<

export function createConstructorParameterVerifier<T, C extends ConstructorFunction<T>>(
mocked: IMocked<T, C>,
): IFunctionWithParametersVerification<ConstructorParams<C>, T, 'constructor', C> {
): IFunctionWithParametersVerification<ConstructorParams<C>, T, 'constructorFunction', C> {
return {
...createFunctionVerifier(mocked, 'constructor', 'constructor'),
...createFunctionVerifier(mocked, 'constructorFunction', 'constructorFunction'),
/**
* withParameters and withParametersEqualTo should have signatures:
*
Expand All @@ -44,9 +44,9 @@ export function createConstructorParameterVerifier<T, C extends ConstructorFunct
* so we internally type the function as any. This does not affect the extrnal facing function type
*/
withParameters: ((...parameters: ParameterMatcher<any>[]) =>
verifyParameters(parameters, mocked, 'constructor', 'constructor', false)) as any,
verifyParameters(parameters, mocked, 'constructorFunction', 'constructorFunction', false)) as any,
withParametersEqualTo: ((...parameters: ParameterMatcher<any>[]) =>
verifyParameters(parameters, mocked, 'constructor', 'constructor', true)) as any,
verifyParameters(parameters, mocked, 'constructorFunction', 'constructorFunction', true)) as any,
};
}

Expand Down Expand Up @@ -167,10 +167,16 @@ export function verifyFunctionCalled<T, C extends ConstructorFunction<T>, U exte
let errorMessageSetupFunction: string;
let errorMessageDescription: string;

const functionCalls: LookupParams<T, C, U, any>[] | undefined = getLookup(mock, type)[functionName];
const functionCallsLookup = getLookup(mock, type);

console.log(`functionCallsLookup`, { functionCallsLookup });

const functionCalls: LookupParams<T, C, U, any>[] | undefined = functionCallsLookup[functionName];

console.log(`functionCalls`, { functionCalls });

switch (type) {
case 'constructor':
case 'constructorFunction':
expectationMessage = `Expected constructor to be called`;
errorMessageSetupFunction = `Mock.setupConstructor()`;
errorMessageDescription = `Constructor`;
Expand Down Expand Up @@ -213,9 +219,12 @@ export function verifyFunctionCalled<T, C extends ConstructorFunction<T>, U exte
}

if (functionCalls === undefined) {
return createCustomMatcherFailResult(
`${errorMessageDescription} "${functionName}" has not been setup. Please setup using ${errorMessageSetupFunction} before verifying calls.`,
);
const message =
type === 'constructorFunction'
? `Constructor has not been setup. Please setup using ${errorMessageSetupFunction} before verifying calls.`
: `${errorMessageDescription} "${functionName}" has not been setup. Please setup using ${errorMessageSetupFunction} before verifying calls.`;

return createCustomMatcherFailResult(message);
}

const parameterMatchResults = functionCalls.map((params) => matchParameters(params, parameterMatchers));
Expand Down
8 changes: 8 additions & 0 deletions spec/mock/mock.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@ describe('mock', () => {
`Property "propertyTwo" has not been setup. Please setup using Mock.setupProperty() before verifying calls.`,
);
});

it('withConstructor will fail with a meaningful error if we try to assert a function that is not setup', () => {
verifyFailure(
mocked.withConstructor(),
matchers.wasNotCalled(),
`Constructor has not been setup. Please setup using Mock.setupConstructor() before verifying calls.`,
);
});
});

describe('withFunction', () => {
Expand Down

0 comments on commit 9e7dfa0

Please sign in to comment.