react-native-navigation的迁移库

ContainerWrapper.test.js 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /* eslint-disable consistent-this, react/no-multi-comp */
  2. import React, { Component } from 'react';
  3. import { AppRegistry, Text } from 'react-native';
  4. import renderer from 'react-test-renderer';
  5. import ContainerWrapper from './ContainerWrapper';
  6. import Store from './Store';
  7. describe('ContainerWrapper', () => {
  8. let myContainerRef;
  9. let testParentRef;
  10. let store;
  11. const containerName = 'example.MyContainer';
  12. class MyContainer extends Component {
  13. constructor(props) {
  14. super(props);
  15. myContainerRef = this;
  16. }
  17. render() {
  18. return <Text>{'Hello, World!'}</Text>;
  19. }
  20. }
  21. class TestParent extends Component {
  22. constructor(props) {
  23. super(props);
  24. testParentRef = this;
  25. this.ChildClass = props.ChildClass;
  26. this.state = { propsFromState: {} };
  27. }
  28. render() {
  29. const Child = this.ChildClass;
  30. return (
  31. <Child id="container1" {...this.state.propsFromState} />
  32. );
  33. }
  34. }
  35. beforeEach(() => {
  36. store = new Store();
  37. });
  38. it('must have id as prop', () => {
  39. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  40. const orig = console.error; //eslint-disable-line
  41. console.error = (a) => a; //eslint-disable-line
  42. expect(() => {
  43. renderer.create(<NavigationContainer />);
  44. }).toThrow(new Error('Container example.MyContainer does not have an id!'));
  45. console.error = orig; //eslint-disable-line
  46. });
  47. it('wraps the container', () => {
  48. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  49. expect(NavigationContainer).not.toBeInstanceOf(MyContainer);
  50. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  51. expect(tree.toJSON().children).toEqual(['Hello, World!']);
  52. expect(myContainerRef).toBeInstanceOf(MyContainer);
  53. });
  54. it('injects props from wrapper into original container', () => {
  55. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  56. renderer.create(<NavigationContainer id={'container1'} myProp={'yo'} />);
  57. expect(myContainerRef.props.myProp).toEqual('yo');
  58. });
  59. it('updates props from wrapper into original container', () => {
  60. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  61. renderer.create(<TestParent ChildClass={NavigationContainer} />);
  62. expect(myContainerRef.props.foo).toEqual(undefined);
  63. testParentRef.setState({ propsFromState: { foo: 'yo' } });
  64. expect(myContainerRef.props.foo).toEqual('yo');
  65. });
  66. it('pulls props from the store and injects them into the inner container', () => {
  67. store.setPropsForContainerId('container123', { numberProp: 1, stringProp: 'hello', objectProp: { a: 2 } });
  68. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  69. renderer.create(<NavigationContainer id={'container123'} />);
  70. expect(myContainerRef.props).toEqual({ id: 'container123', numberProp: 1, stringProp: 'hello', objectProp: { a: 2 } });
  71. });
  72. it('updates props from store into inner container', () => {
  73. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  74. renderer.create(<TestParent ChildClass={NavigationContainer} />);
  75. store.setPropsForContainerId('container1', { myProp: 'hello' });
  76. expect(myContainerRef.props.foo).toEqual(undefined);
  77. expect(myContainerRef.props.myProp).toEqual(undefined);
  78. testParentRef.setState({ propsFromState: { foo: 'yo' } });
  79. expect(myContainerRef.props.foo).toEqual('yo');
  80. expect(myContainerRef.props.myProp).toEqual('hello');
  81. });
  82. it('protects id from change', () => {
  83. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  84. renderer.create(<TestParent ChildClass={NavigationContainer} />);
  85. expect(myContainerRef.props.id).toEqual('container1');
  86. testParentRef.setState({ propsFromState: { id: 'ERROR' } });
  87. expect(myContainerRef.props.id).toEqual('container1');
  88. });
  89. it('assignes key by id', () => {
  90. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  91. renderer.create(<NavigationContainer id={'container1'} />);
  92. expect(myContainerRef.props.id).toEqual('container1');
  93. expect(myContainerRef._reactInternalInstance.key).toEqual('container1');
  94. });
  95. it('saves self ref into store', () => {
  96. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  97. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  98. expect(store.getRefForId('container1')).toBeDefined();
  99. expect(store.getRefForId('container1')).toBe(tree.getInstance());
  100. });
  101. it('cleans ref from store on unMount', () => {
  102. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  103. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  104. expect(store.getRefForId('container1')).toBeDefined();
  105. tree.unmount();
  106. expect(store.getRefForId('container1')).toBeUndefined();
  107. });
  108. it('holds ref to OriginalContainer', () => {
  109. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  110. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  111. expect(tree.getInstance().originalContainerRef).toBe(myContainerRef);
  112. });
  113. it('cleans ref to internal container on unount', () => {
  114. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  115. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  116. const instance = tree.getInstance();
  117. expect(instance.originalContainerRef).toBeInstanceOf(Component);
  118. tree.unmount();
  119. expect(instance.originalContainerRef).toBeFalsy();
  120. });
  121. describe('container lifecycle', () => {
  122. const onStartCallback = jest.fn();
  123. const onStopCallback = jest.fn();
  124. class MyLifecycleContainer extends MyContainer {
  125. onStart() {
  126. onStartCallback();
  127. }
  128. onStop() {
  129. onStopCallback();
  130. }
  131. }
  132. it('onStart and onStop are optional', () => {
  133. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  134. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  135. expect(() => tree.getInstance().onStart()).not.toThrow();
  136. expect(() => tree.getInstance().onStop()).not.toThrow();
  137. });
  138. it('calls onStart on OriginalContainer', () => {
  139. const NavigationContainer = ContainerWrapper.wrap(containerName, MyLifecycleContainer, store);
  140. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  141. expect(onStartCallback).toHaveBeenCalledTimes(0);
  142. tree.getInstance().onStart();
  143. expect(onStartCallback).toHaveBeenCalledTimes(1);
  144. });
  145. it('calls onSop on OriginalContainer', () => {
  146. const NavigationContainer = ContainerWrapper.wrap(containerName, MyLifecycleContainer, store);
  147. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  148. expect(onStopCallback).toHaveBeenCalledTimes(0);
  149. tree.getInstance().onStop();
  150. expect(onStopCallback).toHaveBeenCalledTimes(1);
  151. });
  152. });
  153. });