From 8595d01194ae00af4216a5d5824205c62d1e1161 Mon Sep 17 00:00:00 2001 From: Ilya Kulygin Date: Mon, 23 Dec 2019 13:44:42 +0300 Subject: [PATCH] fix(di): Add errors when base component is empty for extending component --- packages/di/di.tsx | 21 ++++++++++++++------- packages/di/package-lock.json | 5 +++++ packages/di/package.json | 28 +++++++++++++++++++++++----- packages/di/test/di.test.tsx | 10 ++++++++-- 4 files changed, 50 insertions(+), 14 deletions(-) create mode 100644 packages/di/package-lock.json diff --git a/packages/di/di.tsx b/packages/di/di.tsx index 415ec318..6d6c1098 100644 --- a/packages/di/di.tsx +++ b/packages/di/di.tsx @@ -77,23 +77,28 @@ export interface IRegistryOptions { overridable?: boolean } -const registryHocMark = 'RegistryHoc'; +const registryHocMark = 'RegistryHoc' +function getBaseComponentNotFoundMessage(hoc: HOC) { + return `Not found base component for enhance HOC: ${hoc.toString()}` +} export type HOC = (WrappedComponent: ComponentType) => ComponentType type IRegistryEntity = ComponentType | IRegistryHOC type IRegistryComponents = Record -interface IRegistryHOC { +interface IRegistryHOC extends React.FC { $symbol: typeof registryHocMark hoc: HOC } function withBase(hoc: HOC): IRegistryHOC { - return { - $symbol: registryHocMark, - hoc - } + const fakeComponent: IRegistryHOC = () => { throw new Error(getBaseComponentNotFoundMessage(hoc)) } + + fakeComponent.$symbol = registryHocMark as typeof registryHocMark + fakeComponent.hoc = hoc + + return fakeComponent } function isHoc(component: IRegistryEntity): component is IRegistryHOC { @@ -178,7 +183,7 @@ export class Registry { */ merge(otherRegistry?: Registry) { const clone = new Registry({ id: this.id, overridable: this.overridable }) - clone.fill(this.components); + clone.fill(this.components) if (!otherRegistry) return clone @@ -204,6 +209,8 @@ export class Registry { */ private mergeComponents(base: IRegistryEntity, overrides: IRegistryEntity): IRegistryEntity { if (isHoc(overrides)) { + if (!base) throw new Error(getBaseComponentNotFoundMessage(overrides.hoc)) + if (isHoc(base)) { // If both components are hocs, then create compose-hoc return withBase(Base => overrides.hoc(base.hoc(Base))) diff --git a/packages/di/package-lock.json b/packages/di/package-lock.json new file mode 100644 index 00000000..c08a83a6 --- /dev/null +++ b/packages/di/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "@bem-react/di", + "version": "2.2.0", + "lockfileVersion": 1 +} diff --git a/packages/di/package.json b/packages/di/package.json index ccd1426f..2a6b2b2a 100644 --- a/packages/di/package.json +++ b/packages/di/package.json @@ -4,13 +4,23 @@ "description": "BEM React Dependency Injection", "homepage": "https://github.com/bem/bem-react/tree/master/packages/di", "repository": "https://github.com/bem/bem-react", - "keywords": ["bem", "level", "dependency", "di", "dependency injection", "react"], + "keywords": [ + "bem", + "level", + "dependency", + "di", + "dependency injection", + "react" + ], "main": "index.js", "typings": "di.d.ts", "publishConfig": { "access": "public" }, - "files": ["build", "di.d.ts"], + "files": [ + "build", + "di.d.ts" + ], "license": "MPL-2.0", "scripts": { "prepublishOnly": "npm run build", @@ -23,9 +33,17 @@ "react": "^16.8.0" }, "nyc": { - "include": ["di.tsx"], - "extension": [".ts", ".tsx"], - "reporter": ["text", "html"], + "include": [ + "di.tsx" + ], + "extension": [ + ".ts", + ".tsx" + ], + "reporter": [ + "text", + "html" + ], "sourceMap": true, "instrument": true, "all": true diff --git a/packages/di/test/di.test.tsx b/packages/di/test/di.test.tsx index 320bc80d..f259ea45 100644 --- a/packages/di/test/di.test.tsx +++ b/packages/di/test/di.test.tsx @@ -320,6 +320,10 @@ describe('@bem-react/di', () => { return () =>
extended
}) + const otherCompositorRegistry = new Registry({ id: 'Compositor' }) + otherCompositorRegistry.extends('Element1', Base => () => ) + otherCompositorRegistry.set('Element2', Element2) + interface ICompositorRegistry { Element1: React.ComponentType Element2: React.ComponentType @@ -337,9 +341,11 @@ describe('@bem-react/di', () => { ) const Compositor = withRegistry(compositorRegistry)(CompositorPresenter) - const OverridedCompositor = withRegistry(overridedCompositorRegistry)(Compositor) + const OverridenCompositor = withRegistry(overridedCompositorRegistry)(Compositor) + const OtherCompositor = withRegistry(otherCompositorRegistry)(CompositorPresenter) - expect(() => render()).to.throw() + expect(() => render()).to.throw('Not found base component for enhance HOC') + expect(() => render()).to.throw('Not found base component for enhance HOC') }) it('should allow to use any registry in context', () => {