import React, {Component} from 'react'; import {AppRegistry, Text} from 'react-native'; import renderer from 'react-test-renderer'; describe('ComponentRegistry', () => { let uut; let myScreenRef; let testParentRef; let screenStore; class MyScreen extends Component { constructor(props) { super(props); myScreenRef = 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('./ScreenRegistry'); screenStore = require('./ScreenStore'); }); afterEach(() => { myScreenRef = null; testParentRef = null; }); describe('registerScreen', () => { beforeEach(() => { AppRegistry.registerComponent = jest.fn(AppRegistry.registerComponent); }); it('registers screen component by screenKey into AppRegistry', () => { expect(AppRegistry.registerComponent).not.toHaveBeenCalled(); uut.registerScreen('example.MyScreen.key', () => MyScreen); expect(AppRegistry.registerComponent).toHaveBeenCalledTimes(1); expect(AppRegistry.registerComponent.mock.calls[0][0]).toEqual('example.MyScreen.key'); }); it('resulting in a normal component', () => { uut.registerScreen('example.MyScreen.key', () => MyScreen); const Screen = AppRegistry.registerComponent.mock.calls[0][1](); const tree = renderer.create(); expect(tree.toJSON().children).toEqual(['Hello, World!']); }); }); describe('NavigationScreen wrapping', () => { const screenKey = 'example.MyScreen'; beforeEach(() => { uut.registerScreen(screenKey, () => MyScreen); }); it('must have screenId as prop', () => { const NavigationScreen = screenStore.getScreenClass(screenKey); expect(() => { renderer.create(); }).toThrow(new Error('Screen example.MyScreen does not have a screenId!')); }); it('wraps the screen and saves to store', () => { const NavigationScreen = screenStore.getScreenClass(screenKey); expect(NavigationScreen).not.toBeInstanceOf(MyScreen); const tree = renderer.create(); expect(tree.toJSON().children).toEqual(['Hello, World!']); expect(myScreenRef).toBeInstanceOf(MyScreen); }); it('injects props from wrapper into original screen', () => { const NavigationScreen = screenStore.getScreenClass(screenKey); renderer.create(); expect(myScreenRef.props.myProp).toEqual('yo'); }); it('updates props from wrapper into original screen', () => { const NavigationScreen = screenStore.getScreenClass(screenKey); renderer.create(); expect(myScreenRef.props.foo).toEqual(undefined); testParentRef.setState({propsFromState: {foo: 'yo'}}); expect(myScreenRef.props.foo).toEqual('yo'); }); it('pulls props from the PropsStore and injects them into the inner screen', () => { require('./PropsStore').setPropsForScreenId('screen123', {numberProp: 1, stringProp: 'hello', objectProp: {a: 2}}); const NavigationScreen = screenStore.getScreenClass(screenKey); renderer.create(); expect(myScreenRef.props).toEqual({screenId: 'screen123', numberProp: 1, stringProp: 'hello', objectProp: {a: 2}}); }); it('updates props from PropsStore into inner screen', () => { const NavigationScreen = screenStore.getScreenClass(screenKey); renderer.create(); require('./PropsStore').setPropsForScreenId('screen1', {myProp: 'hello'}); expect(myScreenRef.props.foo).toEqual(undefined); expect(myScreenRef.props.myProp).toEqual(undefined); testParentRef.setState({propsFromState: {foo: 'yo'}}); expect(myScreenRef.props.foo).toEqual('yo'); expect(myScreenRef.props.myProp).toEqual('hello'); }); it('protects screenId from change', () => { const NavigationScreen = screenStore.getScreenClass(screenKey); renderer.create(); expect(myScreenRef.props.screenId).toEqual('screen1'); testParentRef.setState({propsFromState: {screenId: 'ERROR'}}); expect(myScreenRef.props.screenId).toEqual('screen1'); }); }); });