react-native-navigation的迁移库

ComponentWrapper.test.js 8.3KB

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