import {AppRegistry, Text} from 'react-native'; import React, {Component} from 'react'; import renderer from 'react-test-renderer'; describe('ComponentRegistry', () => { let uut; let myContainerRef; let testParentRef; let containerStore; class MyContainer extends Component { constructor(props) { super(props); myContainerRef = this; //eslint-disable-line } render() { return {'Hello, World!'}; } } class TestParent extends Component { //eslint-disable-line constructor(props) { super(props); testParentRef = this; //eslint-disable-line this.ChildClass = props.ChildClass; this.state = {propsFromState: {}}; } render() { const Child = this.ChildClass; return ( ); } } beforeEach(() => { uut = require('./ContainerRegistry'); containerStore = require('./ContainerStore'); }); afterEach(() => { myContainerRef = null; testParentRef = null; }); describe('registerContainer', () => { beforeEach(() => { AppRegistry.registerComponent = jest.fn(AppRegistry.registerComponent); }); it('registers container component by containerKey into AppRegistry', () => { expect(AppRegistry.registerComponent).not.toHaveBeenCalled(); uut.registerContainer('example.MyContainer.key', () => MyContainer); expect(AppRegistry.registerComponent).toHaveBeenCalledTimes(1); expect(AppRegistry.registerComponent.mock.calls[0][0]).toEqual('example.MyContainer.key'); }); it('resulting in a normal component', () => { uut.registerContainer('example.MyContainer.key', () => MyContainer); const Container = AppRegistry.registerComponent.mock.calls[0][1](); const tree = renderer.create(); expect(tree.toJSON().children).toEqual(['Hello, World!']); }); }); describe('NavigationContainer wrapping', () => { const containerKey = 'example.MyContainer'; beforeEach(() => { uut.registerContainer(containerKey, () => MyContainer); }); it('must have screenId as prop', () => { const NavigationContainer = containerStore.getContainerClass(containerKey); expect(() => { renderer.create(); }).toThrow(new Error('Screen example.MyContainer does not have a screenId!')); }); it('wraps the container and saves to store', () => { const NavigationContainer = containerStore.getContainerClass(containerKey); expect(NavigationContainer).not.toBeInstanceOf(MyContainer); const tree = renderer.create(); expect(tree.toJSON().children).toEqual(['Hello, World!']); expect(myContainerRef).toBeInstanceOf(MyContainer); }); it('injects props from wrapper into original container', () => { const NavigationContainer = containerStore.getContainerClass(containerKey); renderer.create(); expect(myContainerRef.props.myProp).toEqual('yo'); }); it('updates props from wrapper into original container', () => { const NavigationContainer = containerStore.getContainerClass(containerKey); renderer.create(); expect(myContainerRef.props.foo).toEqual(undefined); testParentRef.setState({propsFromState: {foo: 'yo'}}); expect(myContainerRef.props.foo).toEqual('yo'); }); it('pulls props from the PropsStore and injects them into the inner container', () => { require('./PropsStore').setPropsForScreenId('screen123', {numberProp: 1, stringProp: 'hello', objectProp: {a: 2}}); const NavigationContainer = containerStore.getContainerClass(containerKey); renderer.create(); expect(myContainerRef.props).toEqual({screenId: 'screen123', numberProp: 1, stringProp: 'hello', objectProp: {a: 2}}); }); it('updates props from PropsStore into inner container', () => { const NavigationContainer = containerStore.getContainerClass(containerKey); renderer.create(); require('./PropsStore').setPropsForScreenId('screen1', {myProp: 'hello'}); expect(myContainerRef.props.foo).toEqual(undefined); expect(myContainerRef.props.myProp).toEqual(undefined); testParentRef.setState({propsFromState: {foo: 'yo'}}); expect(myContainerRef.props.foo).toEqual('yo'); expect(myContainerRef.props.myProp).toEqual('hello'); }); it('protects screenId from change', () => { const NavigationContainer = containerStore.getContainerClass(containerKey); renderer.create(); expect(myContainerRef.props.screenId).toEqual('screen1'); testParentRef.setState({propsFromState: {screenId: 'ERROR'}}); expect(myContainerRef.props.screenId).toEqual('screen1'); }); }); });