From 9e7dfa02b4391aada78e98b4175556785922321c Mon Sep 17 00:00:00 2001 From: Giles Roadnight <10414642+Roaders@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:37:16 +0100 Subject: [PATCH] fix error when constructor not setup --- main/helper/lookup-helper.ts | 2 +- main/mock/contracts.ts | 14 +++++++------- main/mock/operators.ts | 12 ++++++------ main/mock/verifiers.ts | 27 ++++++++++++++++++--------- spec/mock/mock.spec.ts | 8 ++++++++ 5 files changed, 40 insertions(+), 23 deletions(-) diff --git a/main/helper/lookup-helper.ts b/main/helper/lookup-helper.ts index 9321975..4288473 100644 --- a/main/helper/lookup-helper.ts +++ b/main/helper/lookup-helper.ts @@ -5,7 +5,7 @@ export function getLookup, U extends LookupT lookupType: U, ): FunctionCallLookup { switch (lookupType) { - case 'constructor': + case 'constructorFunction': return mock.constructorCallLookup as FunctionCallLookup; case 'function': return mock.functionCallLookup as FunctionCallLookup; diff --git a/main/mock/contracts.ts b/main/mock/contracts.ts index 024bf07..76a6110 100644 --- a/main/mock/contracts.ts +++ b/main/mock/contracts.ts @@ -50,7 +50,7 @@ export type LookupParams< C extends ConstructorFunction, U extends LookupType, K extends FunctionName, -> = U extends 'constructor' +> = U extends 'constructorFunction' ? ConstructorParams : U extends FunctionTypes ? FunctionParams> @@ -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, U extends LookupType> = U extends 'constructor' - ? { constructor: C } +export type VerifierTarget, U extends LookupType> = U extends 'constructorFunction' + ? { constructorFunction: C } : U extends StaticLookupTypes ? U extends FunctionTypes ? FunctionsOnly @@ -158,7 +158,7 @@ export interface IMocked = never> { */ mockConstructor: C; - constructorCallLookup: FunctionCallLookup; + constructorCallLookup: FunctionCallLookup; functionCallLookup: FunctionCallLookup; setterCallLookup: FunctionCallLookup; getterCallLookup: FunctionCallLookup; @@ -182,7 +182,7 @@ export interface IMocked = never> { */ setup(...operators: OperatorFunction[]): IMocked; - setupConstructor(): IFunctionWithParametersVerification, T, 'constructor', C>; + setupConstructor(): IFunctionWithParametersVerification, T, 'constructorFunction', C>; /** * Sets up a single function and returns a function verifier to verify calls made and parameters passed. @@ -258,7 +258,7 @@ export interface IMocked = never> { * expect(myMock.withFunction("functionName")).wasCalledOnce(): * expect(myMock.withFunction("functionName").withParameters("one", 2)).wasCalledOnce(): */ - withConstructor(): IFunctionWithParametersVerification, T, 'constructor', C>; + withConstructor(): IFunctionWithParametersVerification, T, 'constructorFunction', C>; /** * Verifies calls to a previously setup function. diff --git a/main/mock/operators.ts b/main/mock/operators.ts index 289ddd0..0a8e2a3 100644 --- a/main/mock/operators.ts +++ b/main/mock/operators.ts @@ -24,12 +24,12 @@ import { */ export function setupConstructor>(): OperatorFunction { return (mocked: IMocked) => { - (mocked.mockConstructor = class MockConstructor { + mocked.mockConstructor = class MockConstructor { constructor(...args: ConstructorParams) { trackConstructorCall(mocked, args as any); } - } as C), - (mocked.constructorCallLookup['constructor'] = []); + } as C; + mocked.constructorCallLookup['constructorFunction'] = []; return mocked; }; @@ -266,11 +266,11 @@ function definePropertyImpl< export function trackConstructorCall>( mock: IMocked, - params: LookupParams, + params: LookupParams, ) { - const lookup = getLookup(mock, 'constructor'); + const lookup = getLookup(mock, 'constructorFunction'); - trackCall(lookup, 'constructor', params); + trackCall(lookup, 'constructorFunction', params); } function trackFunctionCall< diff --git a/main/mock/verifiers.ts b/main/mock/verifiers.ts index 0fc73ec..cb5acd3 100644 --- a/main/mock/verifiers.ts +++ b/main/mock/verifiers.ts @@ -29,9 +29,9 @@ export type VerifierParams< export function createConstructorParameterVerifier>( mocked: IMocked, -): IFunctionWithParametersVerification, T, 'constructor', C> { +): IFunctionWithParametersVerification, T, 'constructorFunction', C> { return { - ...createFunctionVerifier(mocked, 'constructor', 'constructor'), + ...createFunctionVerifier(mocked, 'constructorFunction', 'constructorFunction'), /** * withParameters and withParametersEqualTo should have signatures: * @@ -44,9 +44,9 @@ export function createConstructorParameterVerifier[]) => - verifyParameters(parameters, mocked, 'constructor', 'constructor', false)) as any, + verifyParameters(parameters, mocked, 'constructorFunction', 'constructorFunction', false)) as any, withParametersEqualTo: ((...parameters: ParameterMatcher[]) => - verifyParameters(parameters, mocked, 'constructor', 'constructor', true)) as any, + verifyParameters(parameters, mocked, 'constructorFunction', 'constructorFunction', true)) as any, }; } @@ -167,10 +167,16 @@ export function verifyFunctionCalled, U exte let errorMessageSetupFunction: string; let errorMessageDescription: string; - const functionCalls: LookupParams[] | undefined = getLookup(mock, type)[functionName]; + const functionCallsLookup = getLookup(mock, type); + + console.log(`functionCallsLookup`, { functionCallsLookup }); + + const functionCalls: LookupParams[] | undefined = functionCallsLookup[functionName]; + + console.log(`functionCalls`, { functionCalls }); switch (type) { - case 'constructor': + case 'constructorFunction': expectationMessage = `Expected constructor to be called`; errorMessageSetupFunction = `Mock.setupConstructor()`; errorMessageDescription = `Constructor`; @@ -213,9 +219,12 @@ export function verifyFunctionCalled, 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)); diff --git a/spec/mock/mock.spec.ts b/spec/mock/mock.spec.ts index 1ce315d..e4fd98b 100644 --- a/spec/mock/mock.spec.ts +++ b/spec/mock/mock.spec.ts @@ -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', () => {