From 1e3bf9245a8f95759b4e9b37c15e19621bfd984f Mon Sep 17 00:00:00 2001 From: regevbr Date: Sun, 12 Apr 2020 12:23:14 +0300 Subject: [PATCH] feat: Add all resolvers unit tests #12 --- src/utils/memoize/memoize.ts | 37 +++++++++++++++++---- src/utils/nodeVersions/impl/nodeVersions.ts | 6 ++-- test/src/utils/memoize/memoize.spec.ts | 4 +-- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/utils/memoize/memoize.ts b/src/utils/memoize/memoize.ts index f8309e8a..11e855c6 100644 --- a/src/utils/memoize/memoize.ts +++ b/src/utils/memoize/memoize.ts @@ -2,8 +2,8 @@ const cacheProp = Symbol.for(`[memoize]`); export type GenericFunction = (...args: A) => R; -const defaultKeyBuilder = (v: any): any => { - return v; +const defaultKeyBuilder: GenericFunction<[], string> = (): string => { + return `__no_args__`; }; const getCache = (target: any): Record> => { @@ -24,8 +24,12 @@ const getKeyCache = (target: any, key: string): Map => { return dict[key]; }; -const memoizeFn = (namespace: string, func: GenericFunction, keyBuilder: GenericFunction): GenericFunction => { - return function (this: any, ...args: any[]): any { +const memoizeFn = ( + namespace: string, + func: GenericFunction, + keyBuilder: GenericFunction +): GenericFunction => { + return function (this: any, ...args: A): any { const cache = getKeyCache(this, namespace); const key = keyBuilder.apply(this, args); if (cache.has(key)) { @@ -37,13 +41,34 @@ const memoizeFn = (namespace: string, func: GenericFunction, keyBuilder: Generic }; }; -export const memoize = < +type MemoizeReturn< + T extends Function, + A extends any[] = T extends (...args: infer AReal) => any ? AReal : any[], + R = T extends (...args: any) => infer RReal ? RReal : any +> = (_: object, propertyKey: string, descriptor: TypedPropertyDescriptor>) => void; + +type Memoize = { + < + T extends Function, + A extends [] = T extends (...args: []) => any ? [] : never, + R = T extends (...args: any) => infer RReal ? RReal : any + >(): MemoizeReturn; + < + T extends Function, + A extends any[] = T extends (...args: infer AReal) => any ? AReal : any[], + R = T extends (...args: any) => infer RReal ? RReal : any + >( + keyBuilder: GenericFunction + ): MemoizeReturn; +}; + +export const memoize: Memoize = < T extends Function, A extends any[] = T extends (...args: infer AReal) => any ? AReal : any[], R = T extends (...args: any) => infer RReal ? RReal : any >( keyBuilder?: GenericFunction -) => { +): MemoizeReturn => { return (_: object, propertyKey: string, descriptor: TypedPropertyDescriptor>): void => { descriptor.value = memoizeFn(propertyKey, descriptor.value!, keyBuilder || defaultKeyBuilder); }; diff --git a/src/utils/nodeVersions/impl/nodeVersions.ts b/src/utils/nodeVersions/impl/nodeVersions.ts index ef6691bc..513b8b7b 100644 --- a/src/utils/nodeVersions/impl/nodeVersions.ts +++ b/src/utils/nodeVersions/impl/nodeVersions.ts @@ -40,7 +40,7 @@ export class NodeVersions extends INodeVersions { this.logger = loggerFactory.getLogger(`Node Versions`); } - @memoize((options: INodeVersionsLtsOptions): string => options.codename.toLowerCase()) + @memoize(({ codename }: INodeVersionsLtsOptions): string => codename.toLowerCase()) public async resolveLtsVersion({ codename }: INodeVersionsLtsOptions): Promise { codename = codename.toLowerCase(); this.logger.debug(`Resolving LTS version of ${codename}`); @@ -57,7 +57,7 @@ export class NodeVersions extends INodeVersions { return lts; } - @memoize((options: INodeVersionsLatestOptions): string => options.date.toJSON()) + @memoize(({ date }: INodeVersionsLatestOptions): string => date.toJSON()) public async resolveLatestLtsVersion({ date }: INodeVersionsLatestOptions): Promise { this.logger.debug(`Resolving latest lts version in ${date.toJSON()}`); const versions = await this.getAllVersions(); @@ -76,7 +76,7 @@ export class NodeVersions extends INodeVersions { return latest; } - @memoize((options: INodeVersionsLatestOptions): string => options.date.toJSON()) + @memoize(({ date }: INodeVersionsLatestOptions): string => date.toJSON()) public async resolveStableVersion({ date }: INodeVersionsLatestOptions): Promise { this.logger.debug(`Resolving stable version in ${date.toJSON()}`); const versions = await this.getAllVersions(); diff --git a/test/src/utils/memoize/memoize.spec.ts b/test/src/utils/memoize/memoize.spec.ts index c234cdc2..b6a75b5b 100644 --- a/test/src/utils/memoize/memoize.spec.ts +++ b/test/src/utils/memoize/memoize.spec.ts @@ -26,8 +26,8 @@ describe(`memoize`, () => { } @memoize() - public method1(...args: any[]): string { - return this.method1Mock(...args); + public method1(arg: string): string { + return this.method1Mock(arg); } @memoize((...args: any[]) => args.join(`:`))