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');
});
});
});