Skip to content

Commit

Permalink
fix(di): Add errors when base component is empty for extending component
Browse files Browse the repository at this point in the history
  • Loading branch information
Ilya Kulygin authored and yarastqt committed Dec 27, 2019
1 parent ed044a3 commit 8595d01
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 14 deletions.
21 changes: 14 additions & 7 deletions packages/di/di.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,23 +77,28 @@ export interface IRegistryOptions {
overridable?: boolean
}

const registryHocMark = 'RegistryHoc';
const registryHocMark = 'RegistryHoc'
function getBaseComponentNotFoundMessage<T>(hoc: HOC<T>) {
return `Not found base component for enhance HOC: ${hoc.toString()}`
}

export type HOC<T> = (WrappedComponent: ComponentType) => ComponentType<T>

type IRegistryEntity<T = any> = ComponentType<T> | IRegistryHOC<T>
type IRegistryComponents = Record<string, IRegistryEntity>

interface IRegistryHOC<T> {
interface IRegistryHOC<T> extends React.FC<T> {
$symbol: typeof registryHocMark
hoc: HOC<T>
}

function withBase<T>(hoc: HOC<T>): IRegistryHOC<T> {
return {
$symbol: registryHocMark,
hoc
}
const fakeComponent: IRegistryHOC<T> = () => { throw new Error(getBaseComponentNotFoundMessage(hoc)) }

fakeComponent.$symbol = registryHocMark as typeof registryHocMark
fakeComponent.hoc = hoc

return fakeComponent
}

function isHoc<T>(component: IRegistryEntity<T>): component is IRegistryHOC<T> {
Expand Down Expand Up @@ -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

Expand All @@ -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)))
Expand Down
5 changes: 5 additions & 0 deletions packages/di/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 23 additions & 5 deletions packages/di/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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
Expand Down
10 changes: 8 additions & 2 deletions packages/di/test/di.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@ describe('@bem-react/di', () => {
return () => <div>extended <Base/></div>
})

const otherCompositorRegistry = new Registry({ id: 'Compositor' })
otherCompositorRegistry.extends('Element1', Base => () => <Base/>)
otherCompositorRegistry.set('Element2', Element2)

interface ICompositorRegistry {
Element1: React.ComponentType<ICommonProps>
Element2: React.ComponentType<ICommonProps>
Expand All @@ -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(<OverridedCompositor />)).to.throw()
expect(() => render(<OverridenCompositor />)).to.throw('Not found base component for enhance HOC')
expect(() => render(<OtherCompositor />)).to.throw('Not found base component for enhance HOC')
})

it('should allow to use any registry in context', () => {
Expand Down

0 comments on commit 8595d01

Please sign in to comment.