Browse Source

containers

Daniel Zlotin 8 years ago
parent
commit
ea6cc23b56

+ 3
- 3
src2/Navigation.js View File

@@ -1,7 +1,7 @@
1
-import * as ScreenRegistry from './screens/ScreenRegistry';
1
+import * as ContainerRegistry from './containers/ContainerRegistry';
2 2
 
3
-export function registerScreen(screenKey, getScreenFunc) {
4
-  ScreenRegistry.registerScreen(screenKey, getScreenFunc);
3
+export function registerContainer(containerKey, getContainerFunc) {
4
+  ContainerRegistry.registerContainer(containerKey, getContainerFunc);
5 5
 }
6 6
 
7 7
 export function startApp(params) {

+ 9
- 9
src2/Navigation.test.js View File

@@ -3,18 +3,18 @@ import _ from 'lodash';
3 3
 describe('Navigation', () => {
4 4
   let Navigation;
5 5
   let Commands;
6
-  let ScreenRegistry;
6
+  let ContainerRegistry;
7 7
 
8 8
   beforeEach(() => {
9
-    jest.mock('./screens/ScreenRegistry');
9
+    jest.mock('./containers/ContainerRegistry');
10 10
     Navigation = require('./Navigation');
11 11
     Commands = require('./commands/Commands');
12
-    ScreenRegistry = require('./screens/ScreenRegistry');
12
+    ContainerRegistry = require('./containers/ContainerRegistry');
13 13
   });
14 14
 
15 15
   it('exposes static commands', () => {
16 16
     _.forEach([
17
-      Navigation.registerScreen,
17
+      Navigation.registerContainer,
18 18
       Navigation.startApp,
19 19
       Navigation.push,
20 20
       Navigation.pop,
@@ -30,11 +30,11 @@ describe('Navigation', () => {
30 30
     ], (f) => expect(f).toBeInstanceOf(Function));
31 31
   });
32 32
 
33
-  it('delegates register screen to screen registry', () => {
34
-    expect(ScreenRegistry.registerScreen).not.toHaveBeenCalled();
33
+  it('delegates register container to container registry', () => {
34
+    expect(ContainerRegistry.registerContainer).not.toHaveBeenCalled();
35 35
     const fn = jest.fn();
36
-    Navigation.registerScreen('key', fn);
37
-    expect(ScreenRegistry.registerScreen).toHaveBeenCalledTimes(1);
38
-    expect(ScreenRegistry.registerScreen).toHaveBeenCalledWith('key', fn);
36
+    Navigation.registerContainer('key', fn);
37
+    expect(ContainerRegistry.registerContainer).toHaveBeenCalledTimes(1);
38
+    expect(ContainerRegistry.registerContainer).toHaveBeenCalledWith('key', fn);
39 39
   });
40 40
 });

+ 2
- 2
src2/commands/Commands.js View File

@@ -9,10 +9,10 @@ function validateParams(params) {
9 9
   if (!params) {
10 10
     throw new Error(msg);
11 11
   }
12
-  if (params.screenKey) {
12
+  if (params.containerKey) {
13 13
     return true;
14 14
   }
15
-  if (params.tabs && params.tabs.length > 0 && _.every(params.tabs, (t) => t.screenKey)) {
15
+  if (params.tabs && params.tabs.length > 0 && _.every(params.tabs, (t) => t.containerKey)) {
16 16
     return true;
17 17
   }
18 18
   throw new Error(msg);

+ 7
- 7
src2/commands/Commands.test.js View File

@@ -8,25 +8,25 @@ describe('Commands', () => {
8 8
   describe('startApp', () => {
9 9
     it('receives params object', () => {
10 10
       uut.startApp({
11
-        screenKey: {
12
-          screen: 'example.MyScreen'
11
+        containerKey: {
12
+          container: 'example.MyContainer'
13 13
         },
14 14
         drawer: {
15 15
           left: {
16
-            screen: 'example.SideMenu'
16
+            container: 'example.SideMenu'
17 17
           }
18 18
         }
19 19
       });
20 20
     });
21 21
 
22
-    it('expects to get screenKey, or tabs with screenKeys', () => {
23
-      expect(() => uut.startApp({screenKey: 'example.MyScreen'})).not.toThrow();
24
-      expect(() => uut.startApp({tabs: [{screenKey: 'example.Tab1'}]})).not.toThrow();
22
+    it('expects to get containerKey, or tabs with containerKeys', () => {
23
+      expect(() => uut.startApp({containerKey: 'example.MyContainer'})).not.toThrow();
24
+      expect(() => uut.startApp({tabs: [{containerKey: 'example.Tab1'}]})).not.toThrow();
25 25
       expect(() => uut.startApp()).toThrow();
26 26
       expect(() => uut.startApp({})).toThrow();
27 27
       expect(() => uut.startApp({tabs: []})).toThrow();
28 28
       expect(() => uut.startApp({tabs: [{}]})).toThrow();
29
-      expect(() => uut.startApp({tabs: [{screenKey: 'example.Tab1'}, {}]})).toThrow();
29
+      expect(() => uut.startApp({tabs: [{containerKey: 'example.Tab1'}, {}]})).toThrow();
30 30
     });
31 31
   });
32 32
 });

+ 21
- 21
src2/commands/valid-commands.js View File

@@ -1,32 +1,32 @@
1
-export const singleScreenApp = {
2
-  screen: {
3
-    key: 'com.example.FirstTabScreen'
1
+export const singleContainerApp = {
2
+  container: {
3
+    key: 'com.example.FirstTabContainer'
4 4
   }
5 5
 };
6 6
 
7 7
 export const tabBasedApp = {
8 8
   tabs: [
9 9
     {
10
-      screen: {
11
-        key: 'com.example.FirstTabScreen'
10
+      container: {
11
+        key: 'com.example.FirstTabContainer'
12 12
       }
13 13
     },
14 14
     {
15
-      screen: {
16
-        key: 'com.example.SecondTabScreen'
15
+      container: {
16
+        key: 'com.example.SecondTabContainer'
17 17
       }
18 18
     },
19 19
     {
20
-      screen: {
21
-        key: 'com.example.FirstTabScreen'
20
+      container: {
21
+        key: 'com.example.FirstTabContainer'
22 22
       }
23 23
     }
24 24
   ]
25 25
 };
26 26
 
27 27
 export const singleWithSideMenu = {
28
-  screen: {
29
-    key: 'com.example.MyScreen'
28
+  container: {
29
+    key: 'com.example.MyContainer'
30 30
   },
31 31
   sideMenu: {
32 32
     left: {
@@ -36,8 +36,8 @@ export const singleWithSideMenu = {
36 36
 };
37 37
 
38 38
 export const singleWithRightSideMenu = {
39
-  screen: {
40
-    key: 'com.example.MyScreen'
39
+  container: {
40
+    key: 'com.example.MyContainer'
41 41
   },
42 42
   sideMenu: {
43 43
     right: {
@@ -47,8 +47,8 @@ export const singleWithRightSideMenu = {
47 47
 };
48 48
 
49 49
 export const singleWithBothMenus = {
50
-  screen: {
51
-    key: 'com.example.MyScreen'
50
+  container: {
51
+    key: 'com.example.MyContainer'
52 52
   },
53 53
   sideMenu: {
54 54
     left: {
@@ -63,18 +63,18 @@ export const singleWithBothMenus = {
63 63
 export const tabBasedWithSideMenu = {
64 64
   tabs: [
65 65
     {
66
-      screen: {
67
-        key: 'com.example.FirstTabScreen'
66
+      container: {
67
+        key: 'com.example.FirstTabContainer'
68 68
       }
69 69
     },
70 70
     {
71
-      screen: {
72
-        key: 'com.example.SecondTabScreen'
71
+      container: {
72
+        key: 'com.example.SecondTabContainer'
73 73
       }
74 74
     },
75 75
     {
76
-      screen: {
77
-        key: 'com.example.FirstTabScreen'
76
+      container: {
77
+        key: 'com.example.FirstTabContainer'
78 78
       }
79 79
     }
80 80
   ],

+ 44
- 0
src2/containers/ContainerRegistry.js View File

@@ -0,0 +1,44 @@
1
+import React, {Component} from 'react';
2
+import {AppRegistry} from 'react-native';
3
+import * as PropsStore from './PropsStore';
4
+import * as ContainerStore from './ContainerStore';
5
+
6
+export function registerContainer(containerKey, getContainerFunc) {
7
+  const OriginalContainer = getContainerFunc();
8
+  const NavigationContainer = wrapContainer(containerKey, OriginalContainer);
9
+  ContainerStore.setContainerClass(containerKey, NavigationContainer);
10
+  AppRegistry.registerComponent(containerKey, () => NavigationContainer);
11
+}
12
+
13
+export const bla = {};
14
+
15
+function wrapContainer(containerKey, OriginalContainer) {
16
+  return class extends Component {
17
+    constructor(props) {
18
+      super(props);
19
+      if (!props.containerId) {
20
+        throw new Error(`Container ${containerKey} does not have a containerId!`);
21
+      }
22
+      this.state = {
23
+        containerId: props.containerId,
24
+        allProps: {...props, ...PropsStore.getPropsForContainerId(props.containerId)}
25
+      };
26
+    }
27
+
28
+    componentWillReceiveProps(nextProps) {
29
+      this.setState({
30
+        allProps: {...nextProps, ...PropsStore.getPropsForContainerId(this.state.containerId)}
31
+      });
32
+    }
33
+
34
+    render() {
35
+      return (
36
+        <OriginalContainer
37
+          ref={(r) => bla.ref = r}
38
+          {...this.state.allProps}
39
+          containerId={this.state.containerId}
40
+        />
41
+      );
42
+    }
43
+  };
44
+}

+ 130
- 0
src2/containers/ContainerRegistry.test.js View File

@@ -0,0 +1,130 @@
1
+import React, {Component} from 'react';
2
+import {AppRegistry, Text} from 'react-native';
3
+import renderer from 'react-test-renderer';
4
+
5
+describe('ComponentRegistry', () => {
6
+  let uut;
7
+  let myContainerRef;
8
+  let testParentRef;
9
+  let containerStore;
10
+
11
+  class MyContainer extends Component {
12
+    constructor(props) {
13
+      super(props);
14
+      myContainerRef = this; //eslint-disable-line
15
+    }
16
+
17
+    render() {
18
+      return <Text>{'Hello, World!'}</Text>;
19
+    }
20
+  }
21
+
22
+  class TestParent extends Component { //eslint-disable-line
23
+    constructor(props) {
24
+      super(props);
25
+      testParentRef = this; //eslint-disable-line
26
+      this.ChildClass = props.ChildClass;
27
+      this.state = {propsFromState: {}};
28
+    }
29
+
30
+    render() {
31
+      const Child = this.ChildClass;
32
+      return (
33
+        <Child containerId="container1" {...this.state.propsFromState}/>
34
+      );
35
+    }
36
+  }
37
+
38
+  beforeEach(() => {
39
+    uut = require('./ContainerRegistry');
40
+    containerStore = require('./ContainerStore');
41
+  });
42
+
43
+  afterEach(() => {
44
+    myContainerRef = null;
45
+    testParentRef = null;
46
+  });
47
+
48
+  describe('registerContainer', () => {
49
+    beforeEach(() => {
50
+      AppRegistry.registerComponent = jest.fn(AppRegistry.registerComponent);
51
+    });
52
+
53
+    it('registers container component by containerKey into AppRegistry', () => {
54
+      expect(AppRegistry.registerComponent).not.toHaveBeenCalled();
55
+      uut.registerContainer('example.MyContainer.key', () => MyContainer);
56
+      expect(AppRegistry.registerComponent).toHaveBeenCalledTimes(1);
57
+      expect(AppRegistry.registerComponent.mock.calls[0][0]).toEqual('example.MyContainer.key');
58
+    });
59
+
60
+    it('resulting in a normal component', () => {
61
+      uut.registerContainer('example.MyContainer.key', () => MyContainer);
62
+      const Container = AppRegistry.registerComponent.mock.calls[0][1]();
63
+      const tree = renderer.create(<Container containerId="123"/>);
64
+      expect(tree.toJSON().children).toEqual(['Hello, World!']);
65
+    });
66
+  });
67
+
68
+  describe('NavigationContainer wrapping', () => {
69
+    const containerKey = 'example.MyContainer';
70
+
71
+    beforeEach(() => {
72
+      uut.registerContainer(containerKey, () => MyContainer);
73
+    });
74
+
75
+    it('must have containerId as prop', () => {
76
+      const NavigationContainer = containerStore.getContainerClass(containerKey);
77
+      expect(() => {
78
+        renderer.create(<NavigationContainer/>);
79
+      }).toThrow(new Error('Container example.MyContainer does not have a containerId!'));
80
+    });
81
+
82
+    it('wraps the container and saves to store', () => {
83
+      const NavigationContainer = containerStore.getContainerClass(containerKey);
84
+      expect(NavigationContainer).not.toBeInstanceOf(MyContainer);
85
+      const tree = renderer.create(<NavigationContainer containerId={'container1'}/>);
86
+      expect(tree.toJSON().children).toEqual(['Hello, World!']);
87
+      expect(myContainerRef).toBeInstanceOf(MyContainer);
88
+    });
89
+
90
+    it('injects props from wrapper into original container', () => {
91
+      const NavigationContainer = containerStore.getContainerClass(containerKey);
92
+      renderer.create(<NavigationContainer containerId={'container1'} myProp={'yo'}/>);
93
+      expect(myContainerRef.props.myProp).toEqual('yo');
94
+    });
95
+
96
+    it('updates props from wrapper into original container', () => {
97
+      const NavigationContainer = containerStore.getContainerClass(containerKey);
98
+      renderer.create(<TestParent ChildClass={NavigationContainer}/>);
99
+      expect(myContainerRef.props.foo).toEqual(undefined);
100
+      testParentRef.setState({propsFromState: {foo: 'yo'}});
101
+      expect(myContainerRef.props.foo).toEqual('yo');
102
+    });
103
+
104
+    it('pulls props from the PropsStore and injects them into the inner container', () => {
105
+      require('./PropsStore').setPropsForContainerId('container123', {numberProp: 1, stringProp: 'hello', objectProp: {a: 2}});
106
+      const NavigationContainer = containerStore.getContainerClass(containerKey);
107
+      renderer.create(<NavigationContainer containerId={'container123'}/>);
108
+      expect(myContainerRef.props).toEqual({containerId: 'container123', numberProp: 1, stringProp: 'hello', objectProp: {a: 2}});
109
+    });
110
+
111
+    it('updates props from PropsStore into inner container', () => {
112
+      const NavigationContainer = containerStore.getContainerClass(containerKey);
113
+      renderer.create(<TestParent ChildClass={NavigationContainer}/>);
114
+      require('./PropsStore').setPropsForContainerId('container1', {myProp: 'hello'});
115
+      expect(myContainerRef.props.foo).toEqual(undefined);
116
+      expect(myContainerRef.props.myProp).toEqual(undefined);
117
+      testParentRef.setState({propsFromState: {foo: 'yo'}});
118
+      expect(myContainerRef.props.foo).toEqual('yo');
119
+      expect(myContainerRef.props.myProp).toEqual('hello');
120
+    });
121
+
122
+    it('protects containerId from change', () => {
123
+      const NavigationContainer = containerStore.getContainerClass(containerKey);
124
+      renderer.create(<TestParent ChildClass={NavigationContainer}/>);
125
+      expect(myContainerRef.props.containerId).toEqual('container1');
126
+      testParentRef.setState({propsFromState: {containerId: 'ERROR'}});
127
+      expect(myContainerRef.props.containerId).toEqual('container1');
128
+    });
129
+  });
130
+});

+ 11
- 0
src2/containers/ContainerStore.js View File

@@ -0,0 +1,11 @@
1
+const state = {
2
+  containersByKey: {}
3
+};
4
+
5
+export function setContainerClass(containerKey, ContainerClass) {
6
+  state.containersByKey[containerKey] = ContainerClass;
7
+}
8
+
9
+export function getContainerClass(containerKey) {
10
+  return state.containersByKey[containerKey];
11
+}

+ 19
- 0
src2/containers/ContainerStore.test.js View File

@@ -0,0 +1,19 @@
1
+describe('ContainerStore', () => {
2
+  let uut;
3
+
4
+  beforeEach(() => {
5
+    uut = require('./ContainerStore');
6
+  });
7
+
8
+  class Component {
9
+    //
10
+  }
11
+  class MyComponent extends Component {
12
+    //
13
+  }
14
+
15
+  it('holds containers classes by containerKey', () => {
16
+    uut.setContainerClass('example.mykey', MyComponent);
17
+    expect(uut.getContainerClass('example.mykey')).toEqual(MyComponent);
18
+  });
19
+});

+ 11
- 0
src2/containers/PropsStore.js View File

@@ -0,0 +1,11 @@
1
+import _ from 'lodash';
2
+
3
+const propsByContainerId = {};
4
+
5
+export function setPropsForContainerId(containerId, props) {
6
+  _.set(propsByContainerId, containerId, props);
7
+}
8
+
9
+export function getPropsForContainerId(containerId) {
10
+  return _.get(propsByContainerId, containerId, {});
11
+}

+ 22
- 0
src2/containers/PropsStore.test.js View File

@@ -0,0 +1,22 @@
1
+describe('PropsStore', () => {
2
+  let uut;
3
+
4
+  beforeEach(() => {
5
+    uut = require('./PropsStore');
6
+  });
7
+
8
+  it('initial state', () => {
9
+    expect(uut.getPropsForContainerId('container1')).toEqual({});
10
+  });
11
+
12
+  it('holds props by containerId', () => {
13
+    uut.setPropsForContainerId('container1', {a: 1, b: 2});
14
+    expect(uut.getPropsForContainerId('container1')).toEqual({a: 1, b: 2});
15
+  });
16
+
17
+  it('defensive for invalid containerId and props', () => {
18
+    uut.setPropsForContainerId('container1', undefined);
19
+    uut.setPropsForContainerId(undefined, undefined);
20
+    expect(uut.getPropsForContainerId('container1')).toEqual({});
21
+  });
22
+});

+ 2
- 2
src2/integration/remx-support-component.js View File

@@ -5,7 +5,7 @@ import {connect} from 'remx/react-native';
5 5
 
6 6
 import * as store from './remx-support-store';
7 7
 
8
-class MyScreen extends Component {
8
+class MyContainer extends Component {
9 9
   constructor(props) {
10 10
     super(props);
11 11
     this.renders = 0;
@@ -19,4 +19,4 @@ class MyScreen extends Component {
19 19
   }
20 20
 }
21 21
 
22
-export default MyScreen;
22
+export default MyContainer;

+ 4
- 4
src2/integration/remx-support.test.js View File

@@ -1,24 +1,24 @@
1 1
 xdescribe('remx support', () => {
2 2
   let React;
3 3
   let renderer;
4
-  let MyConnectedScreen;
4
+  let MyConnectedContainer;
5 5
   let store;
6 6
 
7 7
   beforeEach(() => {
8 8
     require('react-native');
9 9
     React = require('react');
10 10
     renderer = require('react-test-renderer');
11
-    MyConnectedScreen = require('./remx-support-component').default;
11
+    MyConnectedContainer = require('./remx-support-component').default;
12 12
     store = require('./remx-support-store');
13 13
   });
14 14
 
15 15
   it('renders normally', () => {
16
-    const tree = renderer.create(<MyConnectedScreen/>);
16
+    const tree = renderer.create(<MyConnectedContainer/>);
17 17
     expect(tree.toJSON().children).toEqual(['no name']);
18 18
   });
19 19
 
20 20
   it('rerenders as a result of an underlying state change (by selector)', () => {
21
-    const tree = renderer.create(<MyConnectedScreen/>);
21
+    const tree = renderer.create(<MyConnectedContainer/>);
22 22
     const instance = tree.getInstance();
23 23
     expect(tree.toJSON().children).toEqual(['no name']);
24 24
     expect(instance.renders).toEqual(1);

+ 0
- 11
src2/screens/PropsStore.js View File

@@ -1,11 +0,0 @@
1
-import _ from 'lodash';
2
-
3
-const propsByScreenId = {};
4
-
5
-export function setPropsForScreenId(screenId, props) {
6
-  _.set(propsByScreenId, screenId, props);
7
-}
8
-
9
-export function getPropsForScreenId(screenId) {
10
-  return _.get(propsByScreenId, screenId, {});
11
-}

+ 0
- 22
src2/screens/PropsStore.test.js View File

@@ -1,22 +0,0 @@
1
-describe('PropsStore', () => {
2
-  let uut;
3
-
4
-  beforeEach(() => {
5
-    uut = require('./PropsStore');
6
-  });
7
-
8
-  it('initial state', () => {
9
-    expect(uut.getPropsForScreenId('screen1')).toEqual({});
10
-  });
11
-
12
-  it('holds props by screenId', () => {
13
-    uut.setPropsForScreenId('screen1', {a: 1, b: 2});
14
-    expect(uut.getPropsForScreenId('screen1')).toEqual({a: 1, b: 2});
15
-  });
16
-
17
-  it('defensive for invalid screenId and props', () => {
18
-    uut.setPropsForScreenId('screen1', undefined);
19
-    uut.setPropsForScreenId(undefined, undefined);
20
-    expect(uut.getPropsForScreenId('screen1')).toEqual({});
21
-  });
22
-});

+ 0
- 44
src2/screens/ScreenRegistry.js View File

@@ -1,44 +0,0 @@
1
-import React, {Component} from 'react';
2
-import {AppRegistry} from 'react-native';
3
-import * as PropsStore from './PropsStore';
4
-import * as ScreenStore from './ScreenStore';
5
-
6
-export function registerScreen(screenKey, getScreenFunc) {
7
-  const OriginalScreen = getScreenFunc();
8
-  const NavigationScreen = wrapScreen(screenKey, OriginalScreen);
9
-  ScreenStore.saveScreenClass(screenKey, NavigationScreen);
10
-  AppRegistry.registerComponent(screenKey, () => NavigationScreen);
11
-}
12
-
13
-export const bla = {};
14
-
15
-function wrapScreen(screenKey, OriginalScreen) {
16
-  return class extends Component {
17
-    constructor(props) {
18
-      super(props);
19
-      if (!props.screenId) {
20
-        throw new Error(`Screen ${screenKey} does not have a screenId!`);
21
-      }
22
-      this.state = {
23
-        screenId: props.screenId,
24
-        allProps: {...props, ...PropsStore.getPropsForScreenId(props.screenId)}
25
-      };
26
-    }
27
-
28
-    componentWillReceiveProps(nextProps) {
29
-      this.setState({
30
-        allProps: {...nextProps, ...PropsStore.getPropsForScreenId(this.state.screenId)}
31
-      });
32
-    }
33
-
34
-    render() {
35
-      return (
36
-        <OriginalScreen
37
-          ref={(r) => bla.ref = r}
38
-          {...this.state.allProps}
39
-          screenId={this.state.screenId}
40
-        />
41
-      );
42
-    }
43
-  };
44
-}

+ 0
- 130
src2/screens/ScreenRegistry.test.js View File

@@ -1,130 +0,0 @@
1
-import React, {Component} from 'react';
2
-import {AppRegistry, Text} from 'react-native';
3
-import renderer from 'react-test-renderer';
4
-
5
-describe('ComponentRegistry', () => {
6
-  let uut;
7
-  let myScreenRef;
8
-  let testParentRef;
9
-  let screenStore;
10
-
11
-  class MyScreen extends Component {
12
-    constructor(props) {
13
-      super(props);
14
-      myScreenRef = this; //eslint-disable-line
15
-    }
16
-
17
-    render() {
18
-      return <Text>{'Hello, World!'}</Text>;
19
-    }
20
-  }
21
-
22
-  class TestParent extends Component { //eslint-disable-line
23
-    constructor(props) {
24
-      super(props);
25
-      testParentRef = this; //eslint-disable-line
26
-      this.ChildClass = props.ChildClass;
27
-      this.state = {propsFromState: {}};
28
-    }
29
-
30
-    render() {
31
-      const Child = this.ChildClass;
32
-      return (
33
-        <Child screenId="screen1" {...this.state.propsFromState}/>
34
-      );
35
-    }
36
-  }
37
-
38
-  beforeEach(() => {
39
-    uut = require('./ScreenRegistry');
40
-    screenStore = require('./ScreenStore');
41
-  });
42
-
43
-  afterEach(() => {
44
-    myScreenRef = null;
45
-    testParentRef = null;
46
-  });
47
-
48
-  describe('registerScreen', () => {
49
-    beforeEach(() => {
50
-      AppRegistry.registerComponent = jest.fn(AppRegistry.registerComponent);
51
-    });
52
-
53
-    it('registers screen component by screenKey into AppRegistry', () => {
54
-      expect(AppRegistry.registerComponent).not.toHaveBeenCalled();
55
-      uut.registerScreen('example.MyScreen.key', () => MyScreen);
56
-      expect(AppRegistry.registerComponent).toHaveBeenCalledTimes(1);
57
-      expect(AppRegistry.registerComponent.mock.calls[0][0]).toEqual('example.MyScreen.key');
58
-    });
59
-
60
-    it('resulting in a normal component', () => {
61
-      uut.registerScreen('example.MyScreen.key', () => MyScreen);
62
-      const Screen = AppRegistry.registerComponent.mock.calls[0][1]();
63
-      const tree = renderer.create(<Screen screenId="123"/>);
64
-      expect(tree.toJSON().children).toEqual(['Hello, World!']);
65
-    });
66
-  });
67
-
68
-  describe('NavigationScreen wrapping', () => {
69
-    const screenKey = 'example.MyScreen';
70
-
71
-    beforeEach(() => {
72
-      uut.registerScreen(screenKey, () => MyScreen);
73
-    });
74
-
75
-    it('must have screenId as prop', () => {
76
-      const NavigationScreen = screenStore.getScreenClass(screenKey);
77
-      expect(() => {
78
-        renderer.create(<NavigationScreen/>);
79
-      }).toThrow(new Error('Screen example.MyScreen does not have a screenId!'));
80
-    });
81
-
82
-    it('wraps the screen and saves to store', () => {
83
-      const NavigationScreen = screenStore.getScreenClass(screenKey);
84
-      expect(NavigationScreen).not.toBeInstanceOf(MyScreen);
85
-      const tree = renderer.create(<NavigationScreen screenId={'screen1'}/>);
86
-      expect(tree.toJSON().children).toEqual(['Hello, World!']);
87
-      expect(myScreenRef).toBeInstanceOf(MyScreen);
88
-    });
89
-
90
-    it('injects props from wrapper into original screen', () => {
91
-      const NavigationScreen = screenStore.getScreenClass(screenKey);
92
-      renderer.create(<NavigationScreen screenId={'screen1'} myProp={'yo'}/>);
93
-      expect(myScreenRef.props.myProp).toEqual('yo');
94
-    });
95
-
96
-    it('updates props from wrapper into original screen', () => {
97
-      const NavigationScreen = screenStore.getScreenClass(screenKey);
98
-      renderer.create(<TestParent ChildClass={NavigationScreen}/>);
99
-      expect(myScreenRef.props.foo).toEqual(undefined);
100
-      testParentRef.setState({propsFromState: {foo: 'yo'}});
101
-      expect(myScreenRef.props.foo).toEqual('yo');
102
-    });
103
-
104
-    it('pulls props from the PropsStore and injects them into the inner screen', () => {
105
-      require('./PropsStore').setPropsForScreenId('screen123', {numberProp: 1, stringProp: 'hello', objectProp: {a: 2}});
106
-      const NavigationScreen = screenStore.getScreenClass(screenKey);
107
-      renderer.create(<NavigationScreen screenId={'screen123'}/>);
108
-      expect(myScreenRef.props).toEqual({screenId: 'screen123', numberProp: 1, stringProp: 'hello', objectProp: {a: 2}});
109
-    });
110
-
111
-    it('updates props from PropsStore into inner screen', () => {
112
-      const NavigationScreen = screenStore.getScreenClass(screenKey);
113
-      renderer.create(<TestParent ChildClass={NavigationScreen}/>);
114
-      require('./PropsStore').setPropsForScreenId('screen1', {myProp: 'hello'});
115
-      expect(myScreenRef.props.foo).toEqual(undefined);
116
-      expect(myScreenRef.props.myProp).toEqual(undefined);
117
-      testParentRef.setState({propsFromState: {foo: 'yo'}});
118
-      expect(myScreenRef.props.foo).toEqual('yo');
119
-      expect(myScreenRef.props.myProp).toEqual('hello');
120
-    });
121
-
122
-    it('protects screenId from change', () => {
123
-      const NavigationScreen = screenStore.getScreenClass(screenKey);
124
-      renderer.create(<TestParent ChildClass={NavigationScreen}/>);
125
-      expect(myScreenRef.props.screenId).toEqual('screen1');
126
-      testParentRef.setState({propsFromState: {screenId: 'ERROR'}});
127
-      expect(myScreenRef.props.screenId).toEqual('screen1');
128
-    });
129
-  });
130
-});

+ 0
- 11
src2/screens/ScreenStore.js View File

@@ -1,11 +0,0 @@
1
-const state = {
2
-  screensByKey: {}
3
-};
4
-
5
-export function saveScreenClass(screenKey, ScreenClass) {
6
-  state.screensByKey[screenKey] = ScreenClass;
7
-}
8
-
9
-export function getScreenClass(screenKey) {
10
-  return state.screensByKey[screenKey];
11
-}

+ 0
- 19
src2/screens/ScreenStore.test.js View File

@@ -1,19 +0,0 @@
1
-describe('ScreenStore', () => {
2
-  let uut;
3
-
4
-  beforeEach(() => {
5
-    uut = require('./ScreenStore');
6
-  });
7
-
8
-  class Component {
9
-    //
10
-  }
11
-  class MyComponent extends Component {
12
-    //
13
-  }
14
-
15
-  it('holds screens classes by screenKey', () => {
16
-    uut.saveScreenClass('example.mykey', MyComponent);
17
-    expect(uut.getScreenClass('example.mykey')).toEqual(MyComponent);
18
-  });
19
-});