From 2ceb9f825696e43941adde78349ae91751633c3c Mon Sep 17 00:00:00 2001 From: jero Date: Fri, 24 Jan 2020 20:28:18 +0300 Subject: [PATCH] refactor(uselazy): take and array of imports instead of Alien modules is not necessary to have two concepts of "module" just with redux modules is enough #43 --- .../store/config/alienStore/useAlien.test.tsx | 48 +++++++------------ src/app/store/config/alienStore/useAlien.tsx | 26 +++++----- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/src/app/store/config/alienStore/useAlien.test.tsx b/src/app/store/config/alienStore/useAlien.test.tsx index c586cc54..90c6d555 100644 --- a/src/app/store/config/alienStore/useAlien.test.tsx +++ b/src/app/store/config/alienStore/useAlien.test.tsx @@ -6,7 +6,13 @@ import alien from './alien'; import useAlien from './useAlien'; -import { reduxModule, reduxModuleNoReducers, reduxModuleA, reduxModuleB } from './helpers/modules'; +import { + reduxModule, + reduxModuleNoId, + reduxModuleNoReducers, + reduxModuleA, + reduxModuleB, +} from './helpers/modules'; import { withProvider, WrapperType } from './helpers/withProvider'; const WRONG_COMPONENT_PATH = './some/wrong/component/path'; @@ -29,15 +35,9 @@ describe('useAlien', () => { type ReduxModuleBType = Promise; it('should render "null" at first and then resolve each module', async () => { - const alienModuleA = { - id: 'alien-module-a', - getModule: (): ReduxModuleAType => Promise.resolve(reduxModuleA), - }; + const alienModuleA = (): ReduxModuleAType => Promise.resolve(reduxModuleA); - const alienModuleB = { - id: 'alien-module-b', - getModule: (): ReduxModuleBType => Promise.resolve(reduxModuleB), - }; + const alienModuleB = (): ReduxModuleBType => Promise.resolve(reduxModuleB); const { result, waitForNextUpdate } = renderHook(() => useAlien([alienModuleA, alienModuleB]), { wrapper, @@ -63,10 +63,7 @@ describe('useAlien', () => { }); it('should call cb when unmounting', async () => { - const alienModule = { - id: 'some-alien-module', - getModule: (): ReduxModuleType => Promise.resolve(reduxModule), - }; + const alienModule = (): ReduxModuleType => Promise.resolve(reduxModule); const cb = jest.fn(); @@ -93,30 +90,24 @@ describe('useAlien', () => { expect(cb).toHaveBeenCalledTimes(1); }); - it('should throw when alien module has no "id" or when is empty string', async () => { - const alienModule = { - getModule: (): ReduxModuleType => Promise.resolve(reduxModule), - }; - + it('should throw when a redux module has no "id" or when is empty string', async () => { // @ts-ignore - "id" doesn't exist for testing purposes - const { result } = renderHook(() => useAlien([alienModule]), { + const alienModule = (): ReduxModuleType => Promise.resolve(reduxModuleNoId); + + const { result, waitForNextUpdate } = renderHook(() => useAlien([alienModule]), { wrapper, }); - // here there's no need to resolve the promise cuz it doesn't even get to be called - // await waitForNextUpdate(); + await waitForNextUpdate(); expect(() => { expect(result.current).not.toBe(undefined); - }).toThrow(Error('useAlienModule Error: Alien Module has no id')); + }).toThrow(Error('useAlienModule Error: Redux Module has no id')); }); it('should throw when wrong import path', async () => { const mockDispatch = jest.spyOn(store, 'dispatch'); - const alienModule = { - id: 'some-alien-module', - getModule: (): ReduxModuleType => import(WRONG_COMPONENT_PATH), - }; + const alienModule = (): ReduxModuleType => import(WRONG_COMPONENT_PATH); const { result, waitForNextUpdate } = renderHook(() => useAlien([alienModule]), { wrapper, @@ -138,10 +129,7 @@ describe('useAlien', () => { it('should throw when redux module has no reducers', async () => { type ReduxModuleNoReducersType = Promise; - const alienModule = { - id: 'some-alien-module', - getModule: (): ReduxModuleNoReducersType => Promise.resolve(reduxModuleNoReducers), - }; + const alienModule = (): ReduxModuleNoReducersType => Promise.resolve(reduxModuleNoReducers); const { result, waitForNextUpdate } = renderHook(() => useAlien([alienModule]), { wrapper, diff --git a/src/app/store/config/alienStore/useAlien.tsx b/src/app/store/config/alienStore/useAlien.tsx index ba0c9ac1..d966d500 100644 --- a/src/app/store/config/alienStore/useAlien.tsx +++ b/src/app/store/config/alienStore/useAlien.tsx @@ -6,6 +6,7 @@ import { isEmpty, isNil, anyPass, any } from 'ramda'; import { AlienStore } from './alien'; export interface ReduxModule { + id: string; reducers: { [K: string]: Reducer; }; @@ -20,12 +21,10 @@ export interface ReduxModule { export type AlienResult = Omit; export interface AlienModule { - id: string; - getModule: () => Promise>; initialActions?: Array; } -const check: (obj: T) => boolean = anyPass([isNil, isEmpty]); +const check: (thing: T) => boolean = anyPass([isNil, isEmpty]); function errorHandler(errorOrObj: T): T { if (errorOrObj) { @@ -39,7 +38,7 @@ function errorHandler(errorOrObj: T): T { } function useAlien( - alienModules: [AlienModule], + reduxImports: [() => Promise>], // eslint-disable-next-line @typescript-eslint/explicit-function-return-type cb: () => void = () => {}, ): AlienResult | null { @@ -52,15 +51,18 @@ function useAlien( useEffect(() => { (async (): Promise => { try { - if (any(({ id }) => check(id), alienModules)) { - throw new Error('Alien Module has no id'); - } - const promises = alienModules.map(alienModule => alienModule.getModule()); + const nextReduxModule = {} as ReduxModule; + + const promises = reduxImports.map(reduxImport => reduxImport()); - const resolvedModules = await Promise.all(promises); + const reduxModules = await Promise.all(promises); + + const result = reduxModules.reduce( + (acc, { id, reducers, actions, selectors }: ReduxModule) => { + if (check(id)) { + throw new Error('Redux Module has no id'); + } - const result = resolvedModules.reduce( - (acc, { reducers, actions, selectors }: ReduxModule) => { if (check(reducers)) { throw new Error('Redux Module has no reducers'); } @@ -82,7 +84,7 @@ function useAlien( }), }; }, - {}, + nextReduxModule, ); setAlien(result);