Skip to content

Commit

Permalink
Add test to ComponentRegistry
Browse files Browse the repository at this point in the history
  • Loading branch information
guyca committed May 24, 2020
1 parent 13a6c3e commit a453b04
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 35 deletions.
21 changes: 20 additions & 1 deletion lib/src/components/ComponentRegistry.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { ComponentRegistry } from './ComponentRegistry';
import { Store } from './Store';
import { mock, instance, verify, anyFunction } from 'ts-mockito';
import { mock, instance, verify, anyFunction, when, anyString, anything } from 'ts-mockito';
import { ComponentWrapper } from './ComponentWrapper';
import { ComponentEventsObserver } from '../events/ComponentEventsObserver';
import { AppRegistryService } from '../adapters/AppRegistryService';
import * as React from 'react';
import { ComponentProvider } from 'react-native';

const DummyComponent = () => null;

class MyComponent extends React.Component<any, any> {
}

describe('ComponentRegistry', () => {
let mockedStore: Store;
let mockedComponentEventsObserver: ComponentEventsObserver;
Expand Down Expand Up @@ -48,4 +52,19 @@ describe('ComponentRegistry', () => {
uut.registerComponent('example.MyComponent.name', generator);
expect(generator).toHaveBeenCalledTimes(0);
});

it('should create ComponentWrapper only once', () => {
jest.spyOn(uut, 'wrapComponent');
let _store: Record<string, ComponentProvider> = {};
when(mockedStore.hasRegisteredWrappedComponent(anyString())).thenCall(name => name in _store);
when(mockedStore.getComponentClassForName(anyString())).thenCall(name => _store[name]);
when(mockedStore.setComponentClassForName(anyString(), anything())).thenCall((name, component) => _store[name] = component);
when(mockedComponentWrapper.wrap).thenReturn(() => MyComponent);

const generator: ComponentProvider = () => DummyComponent;
uut.registerComponent('example.MyComponent.name', generator);
uut.registerComponent('example.MyComponent.name', generator);

expect(uut.wrapComponent).toHaveBeenCalledTimes(1);
});
});
42 changes: 23 additions & 19 deletions lib/src/components/ComponentRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,37 @@ export class ComponentRegistry {
private componentWrapper: ComponentWrapper,
private appRegistryService: AppRegistryService
) {}

registerComponent(
componentName: string | number,
componentProvider: ComponentProvider,
concreteComponentProvider?: ComponentProvider,
ReduxProvider?: any,
reduxStore?: any
): ComponentProvider {
const NavigationComponent = () => {
if (this.store.hasRegisteredWrappedComponent(componentName)) {
return this.store.getWrappedComponent(componentName);
} else {
const wrappedComponent = this.componentWrapper.wrap(
componentName.toString(),
componentProvider,
this.store,
this.componentEventsObserver,
concreteComponentProvider,
ReduxProvider,
reduxStore
);
this.store.setWrappedComponent(componentName, wrappedComponent);
return wrappedComponent;
}
};
this.store.setComponentClassForName(componentName.toString(), NavigationComponent);
const NavigationComponent = this.store.hasRegisteredWrappedComponent(componentName) ?
this.store.getComponentClassForName(componentName)! :
this.wrapComponent(componentName, componentProvider, concreteComponentProvider, ReduxProvider, reduxStore);
this.appRegistryService.registerComponent(componentName.toString(), NavigationComponent);
return NavigationComponent;
}

wrapComponent(
componentName: string | number,
componentProvider: ComponentProvider,
concreteComponentProvider?: ComponentProvider,
ReduxProvider?: any,
reduxStore?: any
): ComponentProvider {
const NavigationComponent = () => this.componentWrapper.wrap(
componentName.toString(),
componentProvider,
this.store,
this.componentEventsObserver,
concreteComponentProvider,
ReduxProvider,
reduxStore
);
this.store.setComponentClassForName(componentName.toString(), NavigationComponent);
return NavigationComponent;
}
}
2 changes: 1 addition & 1 deletion lib/src/components/ComponentWrapper.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ describe('ComponentWrapper', () => {
const componentGenerator = jest.fn(() => MyComponent);
uut.wrap(componentName, componentGenerator, store, componentEventsObserver);

expect(componentGenerator.mock.calls.length).toBe(1);
expect(componentGenerator).toHaveBeenCalledTimes(1);
});

describe(`register with redux store`, () => {
Expand Down
18 changes: 4 additions & 14 deletions lib/src/components/Store.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import * as React from 'react';
import { ComponentProvider } from 'react-native';
import { IWrappedComponent } from './ComponentWrapper';

export class Store {
private componentsByName: Record<string, ComponentProvider> = {};
private propsById: Record<string, any> = {};
private componentsInstancesById: Record<string, IWrappedComponent> = {};
private wrappedComponents: Record<string, React.ComponentClass<any>> = {};

updateProps(componentId: string, props: any) {
this.propsById[componentId] = props;
Expand All @@ -33,23 +31,15 @@ export class Store {
return this.componentsByName[componentName.toString()];
}

hasRegisteredWrappedComponent(componentName: string | number): boolean {
return componentName in this.componentsByName;
}

setComponentInstance(id: string, component: IWrappedComponent): void {
this.componentsInstancesById[id] = component;
}

getComponentInstance(id: string): IWrappedComponent {
return this.componentsInstancesById[id];
}

setWrappedComponent(componentName: string | number, wrappedComponent: React.ComponentClass<any>): void {
this.wrappedComponents[componentName] = wrappedComponent;
}

hasRegisteredWrappedComponent(componentName: string | number): boolean {
return componentName in this.wrappedComponents;
}

getWrappedComponent(componentName: string | number): React.ComponentClass<any> {
return this.wrappedComponents[componentName];
}
}

0 comments on commit a453b04

Please sign in to comment.