Browse Source

refactoring, injecting deps

Daniel Zlotin 8 years ago
parent
commit
bdeeab12a8

+ 7
- 5
src/Navigation.js View File

@@ -1,19 +1,21 @@
1
-import * as ContainerRegistry from './containers/ContainerRegistry';
2
-
3
-import nativeCommandsSender from './adapters/NativeCommandsSender';
1
+import NativeCommandsSender from './adapters/NativeCommandsSender';
4 2
 import NativeEventsReceiver from './adapters/NativeEventsReceiver';
5 3
 import UniqueIdProvider from './adapters/UniqueIdProvider';
4
+
5
+import Store from './containers/Store';
6
+import ContainerRegistry from './containers/ContainerRegistry';
6 7
 import Commands from './commands/Commands';
7 8
 
8 9
 class Navigation {
9 10
   constructor() {
10 11
     this.nativeEventsReceiver = new NativeEventsReceiver();
11 12
     this.uniqueIdProvider = new UniqueIdProvider();
12
-    this.commands = new Commands(nativeCommandsSender, this.uniqueIdProvider);
13
+    this.containerRegistry = new ContainerRegistry(new Store());
14
+    this.commands = new Commands(new NativeCommandsSender(), this.uniqueIdProvider);
13 15
   }
14 16
 
15 17
   registerContainer(containerName, getContainerFunc) {
16
-    ContainerRegistry.registerContainer(containerName, getContainerFunc);
18
+    this.containerRegistry.registerContainer(containerName, getContainerFunc);
17 19
   }
18 20
 
19 21
   startApp(params) {

+ 4
- 7
src/Navigation.test.js View File

@@ -1,26 +1,23 @@
1 1
 describe('Navigation', () => {
2 2
   let Navigation;
3
-  let ContainerRegistry;
4 3
 
5 4
   beforeEach(() => {
6
-    jest.mock('./containers/ContainerRegistry');
7
-    ContainerRegistry = require('./containers/ContainerRegistry');
8
-
9 5
     jest.mock('./adapters/UniqueIdProvider');
10 6
     jest.mock('./adapters/NativeCommandsSender');
11 7
     jest.mock('./adapters/NativeEventsReceiver');
12 8
 
9
+    jest.mock('./containers/ContainerRegistry');
13 10
     jest.mock('./commands/Commands');
14 11
 
15 12
     Navigation = require('./Navigation');
16 13
   });
17 14
 
18 15
   it('registerContainer delegates to ContainerRegistry', () => {
19
-    expect(ContainerRegistry.registerContainer).not.toHaveBeenCalled();
16
+    expect(Navigation.containerRegistry.registerContainer).not.toHaveBeenCalled();
20 17
     const fn = jest.fn();
21 18
     Navigation.registerContainer('name', fn);
22
-    expect(ContainerRegistry.registerContainer).toHaveBeenCalledTimes(1);
23
-    expect(ContainerRegistry.registerContainer).toHaveBeenCalledWith('name', fn);
19
+    expect(Navigation.containerRegistry.registerContainer).toHaveBeenCalledTimes(1);
20
+    expect(Navigation.containerRegistry.registerContainer).toHaveBeenCalledWith('name', fn);
24 21
   });
25 22
 
26 23
   it('startApp delegates to Commands', () => {

+ 9
- 2
src/adapters/NativeCommandsSender.js View File

@@ -1,4 +1,11 @@
1 1
 import {NativeModules} from 'react-native';
2 2
 
3
-const singleton = NativeModules.RNNBridgeModule;
4
-export default singleton;
3
+export default class NativeCommandsSender {
4
+  constructor() {
5
+    this.nativeCommandsModule = NativeModules.RNNBridgeModule;
6
+  }
7
+
8
+  startApp(layoutTree) {
9
+    this.nativeCommandsModule.startApp(layoutTree);
10
+  }
11
+}

+ 17
- 0
src/adapters/NativeCommandsSender.test.js View File

@@ -0,0 +1,17 @@
1
+describe('NativeCommandsSender', () => {
2
+  let uut, mockNativeModule;
3
+
4
+  beforeEach(() => {
5
+    mockNativeModule = {
6
+      startApp: jest.fn()
7
+    };
8
+    require('react-native').NativeModules.RNNBridgeModule = mockNativeModule;
9
+    const NativeCommandsSender = require('./NativeCommandsSender').default;
10
+    uut = new NativeCommandsSender();
11
+  });
12
+
13
+  it('delegates to native', () => {
14
+    uut.startApp();
15
+    expect(mockNativeModule.startApp).toHaveBeenCalledTimes(1);
16
+  });
17
+});

+ 4
- 4
src/commands/Commands.test.js View File

@@ -1,15 +1,15 @@
1 1
 describe('Commands', () => {
2 2
   let uut;
3
-  const nativeCommandsSender = {
3
+  const mockCommandsSender = {
4 4
     startApp: jest.fn()
5 5
   };
6
-  const uniqueIdProvider = {
6
+  const mockIdProvider = {
7 7
     generate: (prefix) => `${prefix}UNIQUE`
8 8
   };
9 9
 
10 10
   beforeEach(() => {
11 11
     const Commands = require('./Commands').default;
12
-    uut = new Commands(nativeCommandsSender, uniqueIdProvider);
12
+    uut = new Commands(mockCommandsSender, mockIdProvider);
13 13
   });
14 14
 
15 15
   describe('startApp', () => {
@@ -19,7 +19,7 @@ describe('Commands', () => {
19 19
           name: 'com.example.MyScreen'
20 20
         }
21 21
       });
22
-      expect(nativeCommandsSender.startApp).toHaveBeenCalledTimes(1);
22
+      expect(mockCommandsSender.startApp).toHaveBeenCalledTimes(1);
23 23
       //TODO
24 24
     });
25 25
   });

+ 91
- 91
src/commands/ValidCommands.js View File

@@ -1,91 +1,91 @@
1
-export const singleScreenApp = {
2
-  container: {
3
-    name: 'com.example.MyScreen'
4
-  }
5
-};
6
-
7
-export const tabBasedApp = {
8
-  tabs: [
9
-    {
10
-      container: {
11
-        name: 'com.example.FirstTab'
12
-      }
13
-    },
14
-    {
15
-      container: {
16
-        name: 'com.example.SecondTab'
17
-      }
18
-    },
19
-    {
20
-      container: {
21
-        name: 'com.example.FirstTab'
22
-      }
23
-    }
24
-  ]
25
-};
26
-
27
-export const singleWithSideMenu = {
28
-  container: {
29
-    name: 'com.example.MyScreen'
30
-  },
31
-  sideMenu: {
32
-    left: {
33
-      container: {
34
-        name: 'com.example.MyScreen'
35
-      }
36
-    }
37
-  }
38
-};
39
-
40
-export const singleWithRightSideMenu = {
41
-  container: {
42
-    name: 'com.example.MyScreen'
43
-  },
44
-  sideMenu: {
45
-    right: {
46
-      name: 'com.example.Menu'
47
-    }
48
-  }
49
-};
50
-
51
-export const singleWithBothMenus = {
52
-  container: {
53
-    name: 'com.example.MyScreen'
54
-  },
55
-  sideMenu: {
56
-    left: {
57
-      name: 'com.example.Menu1'
58
-    },
59
-    right: {
60
-      name: 'com.example.Menu2'
61
-    }
62
-  }
63
-};
64
-
65
-export const tabBasedWithSideMenu = {
66
-  tabs: [
67
-    {
68
-      container: {
69
-        name: 'com.example.FirstTab'
70
-      }
71
-    },
72
-    {
73
-      container: {
74
-        name: 'com.example.SecondTab'
75
-      }
76
-    },
77
-    {
78
-      container: {
79
-        name: 'com.example.FirstTab'
80
-      }
81
-    }
82
-  ],
83
-  sideMenu: {
84
-    left: {
85
-      name: 'com.example.Menu1'
86
-    },
87
-    right: {
88
-      name: 'com.example.Menu2'
89
-    }
90
-  }
91
-};
1
+//export const singleScreenApp = {
2
+//  container: {
3
+//    name: 'com.example.MyScreen'
4
+//  }
5
+//};
6
+//
7
+//export const tabBasedApp = {
8
+//  tabs: [
9
+//    {
10
+//      container: {
11
+//        name: 'com.example.FirstTab'
12
+//      }
13
+//    },
14
+//    {
15
+//      container: {
16
+//        name: 'com.example.SecondTab'
17
+//      }
18
+//    },
19
+//    {
20
+//      container: {
21
+//        name: 'com.example.FirstTab'
22
+//      }
23
+//    }
24
+//  ]
25
+//};
26
+//
27
+//export const singleWithSideMenu = {
28
+//  container: {
29
+//    name: 'com.example.MyScreen'
30
+//  },
31
+//  sideMenu: {
32
+//    left: {
33
+//      container: {
34
+//        name: 'com.example.MyScreen'
35
+//      }
36
+//    }
37
+//  }
38
+//};
39
+//
40
+//export const singleWithRightSideMenu = {
41
+//  container: {
42
+//    name: 'com.example.MyScreen'
43
+//  },
44
+//  sideMenu: {
45
+//    right: {
46
+//      name: 'com.example.Menu'
47
+//    }
48
+//  }
49
+//};
50
+//
51
+//export const singleWithBothMenus = {
52
+//  container: {
53
+//    name: 'com.example.MyScreen'
54
+//  },
55
+//  sideMenu: {
56
+//    left: {
57
+//      name: 'com.example.Menu1'
58
+//    },
59
+//    right: {
60
+//      name: 'com.example.Menu2'
61
+//    }
62
+//  }
63
+//};
64
+//
65
+//export const tabBasedWithSideMenu = {
66
+//  tabs: [
67
+//    {
68
+//      container: {
69
+//        name: 'com.example.FirstTab'
70
+//      }
71
+//    },
72
+//    {
73
+//      container: {
74
+//        name: 'com.example.SecondTab'
75
+//      }
76
+//    },
77
+//    {
78
+//      container: {
79
+//        name: 'com.example.FirstTab'
80
+//      }
81
+//    }
82
+//  ],
83
+//  sideMenu: {
84
+//    left: {
85
+//      name: 'com.example.Menu1'
86
+//    },
87
+//    right: {
88
+//      name: 'com.example.Menu2'
89
+//    }
90
+//  }
91
+//};

+ 13
- 39
src/containers/ContainerRegistry.js View File

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

+ 14
- 105
src/containers/ContainerRegistry.test.js View File

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

+ 33
- 0
src/containers/ContainerWrapper.js View File

@@ -0,0 +1,33 @@
1
+import React, {Component} from 'react';
2
+
3
+export default class ContainerWrapper {
4
+  static wrap(containerName, OriginalContainer, propStore) {
5
+    return class extends Component {
6
+      constructor(props) {
7
+        super(props);
8
+        if (!props.containerId) {
9
+          throw new Error(`Container ${containerName} does not have a containerId!`);
10
+        }
11
+        this.state = {
12
+          containerId: props.containerId,
13
+          allProps: {...props, ...propStore.getPropsForContainerId(props.containerId)}
14
+        };
15
+      }
16
+
17
+      componentWillReceiveProps(nextProps) {
18
+        this.setState({
19
+          allProps: {...nextProps, ...propStore.getPropsForContainerId(this.state.containerId)}
20
+        });
21
+      }
22
+
23
+      render() {
24
+        return (
25
+          <OriginalContainer
26
+            {...this.state.allProps}
27
+            containerId={this.state.containerId}
28
+          />
29
+        );
30
+      }
31
+    };
32
+  }
33
+}

+ 99
- 0
src/containers/ContainerWrapper.test.js View File

@@ -0,0 +1,99 @@
1
+import React, {Component} from 'react';
2
+import {AppRegistry, Text} from 'react-native';
3
+import renderer from 'react-test-renderer';
4
+
5
+describe('ContainerWrapper', () => {
6
+  let ContainerWrapper;
7
+  let myContainerRef;
8
+  let testParentRef;
9
+  let store;
10
+  const containerName = 'example.MyContainer';
11
+
12
+  class MyContainer extends Component {
13
+    constructor(props) {
14
+      super(props);
15
+      myContainerRef = this; //eslint-disable-line
16
+    }
17
+
18
+    render() {
19
+      return <Text>{'Hello, World!'}</Text>;
20
+    }
21
+  }
22
+
23
+  class TestParent extends Component { //eslint-disable-line
24
+    constructor(props) {
25
+      super(props);
26
+      testParentRef = this; //eslint-disable-line
27
+      this.ChildClass = props.ChildClass;
28
+      this.state = {propsFromState: {}};
29
+    }
30
+
31
+    render() {
32
+      const Child = this.ChildClass;
33
+      return (
34
+        <Child containerId="container1" {...this.state.propsFromState}/>
35
+      );
36
+    }
37
+  }
38
+
39
+  beforeEach(() => {
40
+    ContainerWrapper = require('./ContainerWrapper').default;
41
+    const Store = require('./Store').default;
42
+    store = new Store();
43
+  });
44
+
45
+  it('must have containerId as prop', () => {
46
+    const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
47
+    expect(() => {
48
+      renderer.create(<NavigationContainer/>);
49
+    }).toThrow(new Error('Container example.MyContainer does not have a containerId!'));
50
+  });
51
+
52
+  it('wraps the container and saves to store', () => {
53
+    const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
54
+    expect(NavigationContainer).not.toBeInstanceOf(MyContainer);
55
+    const tree = renderer.create(<NavigationContainer containerId={'container1'}/>);
56
+    expect(tree.toJSON().children).toEqual(['Hello, World!']);
57
+    expect(myContainerRef).toBeInstanceOf(MyContainer);
58
+  });
59
+
60
+  it('injects props from wrapper into original container', () => {
61
+    const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
62
+    renderer.create(<NavigationContainer containerId={'container1'} myProp={'yo'}/>);
63
+    expect(myContainerRef.props.myProp).toEqual('yo');
64
+  });
65
+
66
+  it('updates props from wrapper into original container', () => {
67
+    const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
68
+    renderer.create(<TestParent ChildClass={NavigationContainer}/>);
69
+    expect(myContainerRef.props.foo).toEqual(undefined);
70
+    testParentRef.setState({propsFromState: {foo: 'yo'}});
71
+    expect(myContainerRef.props.foo).toEqual('yo');
72
+  });
73
+
74
+  it('pulls props from the store and injects them into the inner container', () => {
75
+    store.setPropsForContainerId('container123', {numberProp: 1, stringProp: 'hello', objectProp: {a: 2}});
76
+    const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
77
+    renderer.create(<NavigationContainer containerId={'container123'}/>);
78
+    expect(myContainerRef.props).toEqual({containerId: 'container123', numberProp: 1, stringProp: 'hello', objectProp: {a: 2}});
79
+  });
80
+
81
+  it('updates props from store into inner container', () => {
82
+    const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
83
+    renderer.create(<TestParent ChildClass={NavigationContainer}/>);
84
+    store.setPropsForContainerId('container1', {myProp: 'hello'});
85
+    expect(myContainerRef.props.foo).toEqual(undefined);
86
+    expect(myContainerRef.props.myProp).toEqual(undefined);
87
+    testParentRef.setState({propsFromState: {foo: 'yo'}});
88
+    expect(myContainerRef.props.foo).toEqual('yo');
89
+    expect(myContainerRef.props.myProp).toEqual('hello');
90
+  });
91
+
92
+  it('protects containerId from change', () => {
93
+    const NavigationContainer = ContainerWrapper.wrap(containerName, MyContainer, store);
94
+    renderer.create(<TestParent ChildClass={NavigationContainer}/>);
95
+    expect(myContainerRef.props.containerId).toEqual('container1');
96
+    testParentRef.setState({propsFromState: {containerId: 'ERROR'}});
97
+    expect(myContainerRef.props.containerId).toEqual('container1');
98
+  });
99
+});

+ 17
- 15
src/containers/Store.js View File

@@ -1,22 +1,24 @@
1 1
 import _ from 'lodash';
2 2
 
3
-const state = {
4
-  propsByContainerId: {},
5
-  containersByName: {}
6
-};
3
+export default class Store {
4
+  constructor() {
5
+    this.propsByContainerId = {};
6
+    this.containersByName = {};
7
+  }
7 8
 
8
-export function setPropsForContainerId(containerId, props) {
9
-  _.set(state.propsByContainerId, containerId, props);
10
-}
9
+  setPropsForContainerId(containerId, props) {
10
+    _.set(this.propsByContainerId, containerId, props);
11
+  }
11 12
 
12
-export function getPropsForContainerId(containerId) {
13
-  return _.get(state.propsByContainerId, containerId, {});
14
-}
13
+  getPropsForContainerId(containerId) {
14
+    return _.get(this.propsByContainerId, containerId, {});
15
+  }
15 16
 
16
-export function setContainerClass(containerName, ContainerClass) {
17
-  state.containersByName[containerName] = ContainerClass;
18
-}
17
+  setContainerClass(containerName, ContainerClass) {
18
+    this.containersByName[containerName] = ContainerClass;
19
+  }
19 20
 
20
-export function getContainerClass(containerName) {
21
-  return state.containersByName[containerName];
21
+  getContainerClass(containerName) {
22
+    return this.containersByName[containerName];
23
+  }
22 24
 }

+ 2
- 1
src/containers/Store.test.js View File

@@ -2,7 +2,8 @@ describe('Store', () => {
2 2
   let uut;
3 3
 
4 4
   beforeEach(() => {
5
-    uut = require('./Store');
5
+    const Store = require('./Store').default;
6
+    uut = new Store();
6 7
   });
7 8
 
8 9
   it('initial state', () => {