From aba964bef9f8976fbe876cef7cf3c3af018af9f2 Mon Sep 17 00:00:00 2001 From: Martin Jesper Low Madsen Date: Sat, 16 May 2020 15:29:31 +0200 Subject: [PATCH] chore(*): Rename __factory identifier to __ident and apply it to mocked methods as well --- src/extension/method/provider/provider.ts | 7 ++++- src/repository/repository.ts | 33 ++-------------------- src/utils/applyIdentityProperty.ts | 34 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 src/utils/applyIdentityProperty.ts diff --git a/src/extension/method/provider/provider.ts b/src/extension/method/provider/provider.ts index e6b50dd72..e20c931a0 100644 --- a/src/extension/method/provider/provider.ts +++ b/src/extension/method/provider/provider.ts @@ -1,3 +1,4 @@ +import { applyIdentityProperty } from '../../../utils/applyIdentityProperty'; import { functionMethod } from './functionMethod'; // eslint-disable-next-line @typescript-eslint/no-explicit-any type Method = (name: string, value: any) => () => any; @@ -45,6 +46,10 @@ export class Provider { return this._method(name, value()); } - return this._method(name, value); + // FIXME: Do this smarter, it's a bit counter intuitive to return a new + // proxy every single time this function is called. It should probably mock + // based on name if that ends up being a string representing the type + // signature. + return applyIdentityProperty(this._method, name)(name, value); } } diff --git a/src/repository/repository.ts b/src/repository/repository.ts index 5f3f4ac02..8a5706a52 100644 --- a/src/repository/repository.ts +++ b/src/repository/repository.ts @@ -1,3 +1,5 @@ +import { applyIdentityProperty } from '../utils/applyIdentityProperty'; + // eslint-disable-next-line type Factory = (...args: any[]) => any; @@ -16,36 +18,7 @@ export class Repository { } public registerFactory(key: string, factory: Factory): void { - const proxy: Factory = new Proxy( - factory, - { - apply(target: Factory, _this: unknown, args: Parameters): ReturnType { - const mock: ReturnType = target(...args); - - if (typeof mock === 'undefined') { - return; - } - - if (!(mock instanceof Object)) { - return mock; - } - - if (typeof mock.__factory !== 'undefined') { - return mock; - } - - Object.defineProperty(mock, '__factory', { - enumerable: false, - writable: false, - value: key, - }); - - return mock; - }, - }, - ); - - this._repository[key] = proxy; + this._repository[key] = applyIdentityProperty(factory, key); } public getFactory(key: string): Factory { diff --git a/src/utils/applyIdentityProperty.ts b/src/utils/applyIdentityProperty.ts new file mode 100644 index 000000000..1b8ce0181 --- /dev/null +++ b/src/utils/applyIdentityProperty.ts @@ -0,0 +1,34 @@ +// eslint-disable-next-line +type Function = (...args: any[]) => K; +type IdentityFlavored = K & { __ident?: string }; + +export function applyIdentityProperty>(target: T, identity: string): T { + return new Proxy( + target, + { + apply(func: T, _this: unknown, args: Parameters): IdentityFlavored | undefined { + const t: IdentityFlavored = func(...args); + + if (typeof t === 'undefined') { + return; + } + + if (!(t instanceof Object)) { + return t; + } + + if (typeof t.__ident !== 'undefined') { + return t; + } + + Object.defineProperty(t, '__ident', { + enumerable: false, + writable: false, + value: identity, + }); + + return t; + }, + }, + ); +}