react-native-navigation的迁移库

ContainerWrapper.test.js 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. expect(() => {
  41. renderer.create(<NavigationContainer />);
  42. }).toThrow(new Error('Container example.MyContainer does not have an id!'));
  43. });
  44. it('wraps the container', () => {
  45. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  46. expect(NavigationContainer).not.toBeInstanceOf(MyContainer);
  47. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  48. expect(tree.toJSON().children).toEqual(['Hello, World!']);
  49. expect(myContainerRef).toBeInstanceOf(MyContainer);
  50. });
  51. it('injects props from wrapper into original container', () => {
  52. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  53. renderer.create(<NavigationContainer id={'container1'} myProp={'yo'} />);
  54. expect(myContainerRef.props.myProp).toEqual('yo');
  55. });
  56. it('updates props from wrapper into original container', () => {
  57. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  58. renderer.create(<TestParent ChildClass={NavigationContainer} />);
  59. expect(myContainerRef.props.foo).toEqual(undefined);
  60. testParentRef.setState({ propsFromState: { foo: 'yo' } });
  61. expect(myContainerRef.props.foo).toEqual('yo');
  62. });
  63. it('pulls props from the store and injects them into the inner container', () => {
  64. store.setPropsForContainerId('container123', { numberProp: 1, stringProp: 'hello', objectProp: { a: 2 } });
  65. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  66. renderer.create(<NavigationContainer id={'container123'} />);
  67. expect(myContainerRef.props).toEqual({ id: 'container123', numberProp: 1, stringProp: 'hello', objectProp: { a: 2 } });
  68. });
  69. it('updates props from store into inner container', () => {
  70. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  71. renderer.create(<TestParent ChildClass={NavigationContainer} />);
  72. store.setPropsForContainerId('container1', { myProp: 'hello' });
  73. expect(myContainerRef.props.foo).toEqual(undefined);
  74. expect(myContainerRef.props.myProp).toEqual(undefined);
  75. testParentRef.setState({ propsFromState: { foo: 'yo' } });
  76. expect(myContainerRef.props.foo).toEqual('yo');
  77. expect(myContainerRef.props.myProp).toEqual('hello');
  78. });
  79. it('protects id from change', () => {
  80. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  81. renderer.create(<TestParent ChildClass={NavigationContainer} />);
  82. expect(myContainerRef.props.id).toEqual('container1');
  83. testParentRef.setState({ propsFromState: { id: 'ERROR' } });
  84. expect(myContainerRef.props.id).toEqual('container1');
  85. });
  86. it('assignes key by id', () => {
  87. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  88. renderer.create(<NavigationContainer id={'container1'} />);
  89. expect(myContainerRef.props.id).toEqual('container1');
  90. expect(myContainerRef._reactInternalInstance._currentElement.key).toEqual('container1');
  91. });
  92. it('saves self ref into store', () => {
  93. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  94. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  95. expect(store.getRefForId('container1')).toBeDefined();
  96. expect(store.getRefForId('container1')).toBe(tree.getInstance());
  97. });
  98. it('cleans ref from store on unMount', () => {
  99. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  100. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  101. expect(store.getRefForId('container1')).toBeDefined();
  102. tree.unmount();
  103. expect(store.getRefForId('container1')).toBeUndefined();
  104. });
  105. it('holds ref to OriginalContainer', () => {
  106. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  107. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  108. expect(tree.getInstance().originalContainerRef).toBe(myContainerRef);
  109. });
  110. it('cleans ref to internal container on unount', () => {
  111. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  112. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  113. const instance = tree.getInstance();
  114. expect(instance.originalContainerRef).toBeInstanceOf(Component);
  115. tree.unmount();
  116. expect(instance.originalContainerRef).toBeFalsy();
  117. });
  118. describe('container lifecycle', () => {
  119. const onStartCallback = jest.fn();
  120. const onStopCallback = jest.fn();
  121. class MyLifecycleContainer extends MyContainer {
  122. onStart() {
  123. onStartCallback();
  124. }
  125. onStop() {
  126. onStopCallback();
  127. }
  128. }
  129. it('onStart and onStop are optional', () => {
  130. const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
  131. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  132. expect(() => tree.getInstance().onStart()).not.toThrow();
  133. expect(() => tree.getInstance().onStop()).not.toThrow();
  134. });
  135. it('calls onStart on OriginalContainer', () => {
  136. const NavigationContainer = ContainerWrapper.wrap(containerName, MyLifecycleContainer, store);
  137. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  138. expect(onStartCallback).toHaveBeenCalledTimes(0);
  139. tree.getInstance().onStart();
  140. expect(onStartCallback).toHaveBeenCalledTimes(1);
  141. });
  142. it('calls onSop on OriginalContainer', () => {
  143. const NavigationContainer = ContainerWrapper.wrap(containerName, MyLifecycleContainer, store);
  144. const tree = renderer.create(<NavigationContainer id={'container1'} />);
  145. expect(onStopCallback).toHaveBeenCalledTimes(0);
  146. tree.getInstance().onStop();
  147. expect(onStopCallback).toHaveBeenCalledTimes(1);
  148. });
  149. });
  150. });