Browse Source

refactoring and fixing dependencies

Daniel Zlotin 8 years ago
parent
commit
c52fe4cacd

+ 1
- 1
ios/RNNBridgeModule.m View File

5
 
5
 
6
 @implementation RNNBridgeModule
6
 @implementation RNNBridgeModule
7
 
7
 
8
-RCT_EXPORT_MODULE(NativeNavigation);
8
+RCT_EXPORT_MODULE();
9
 
9
 
10
 - (dispatch_queue_t)methodQueue
10
 - (dispatch_queue_t)methodQueue
11
 {
11
 {

+ 6
- 5
src/Navigation.js View File

1
 import * as ContainerRegistry from './containers/ContainerRegistry';
1
 import * as ContainerRegistry from './containers/ContainerRegistry';
2
-import * as Commands from './commands/Commands';
3
 
2
 
3
+import nativeCommandsSender from './adapters/NativeCommandsSender';
4
 import NativeEventsReceiver from './adapters/NativeEventsReceiver';
4
 import NativeEventsReceiver from './adapters/NativeEventsReceiver';
5
+import UniqueIdProvider from './adapters/UniqueIdProvider';
6
+import Commands from './commands/Commands';
5
 
7
 
6
 class Navigation {
8
 class Navigation {
7
   constructor() {
9
   constructor() {
8
     this.nativeEventsReceiver = new NativeEventsReceiver();
10
     this.nativeEventsReceiver = new NativeEventsReceiver();
11
+    this.uniqueIdProvider = new UniqueIdProvider();
12
+    this.commands = new Commands(nativeCommandsSender, this.uniqueIdProvider);
9
   }
13
   }
10
 
14
 
11
   registerContainer(containerName, getContainerFunc) {
15
   registerContainer(containerName, getContainerFunc) {
13
   }
17
   }
14
 
18
 
15
   startApp(params) {
19
   startApp(params) {
16
-    Commands.startApp(params);
20
+    this.commands.startApp(params);
17
   }
21
   }
18
 
22
 
19
   onAppLaunched(fn) {
23
   onAppLaunched(fn) {
20
     this.nativeEventsReceiver.onAppLaunched(fn);
24
     this.nativeEventsReceiver.onAppLaunched(fn);
21
   }
25
   }
22
-
23
 }
26
 }
24
 
27
 
25
 const singleton = new Navigation();
28
 const singleton = new Navigation();
26
-
27
 module.exports = singleton;
29
 module.exports = singleton;
28
-

+ 11
- 12
src/Navigation.test.js View File

1
 describe('Navigation', () => {
1
 describe('Navigation', () => {
2
   let Navigation;
2
   let Navigation;
3
-  let ContainerRegistry, Commands;
4
-  let mockNativeEventsReceiver;
3
+  let ContainerRegistry;
5
 
4
 
6
   beforeEach(() => {
5
   beforeEach(() => {
7
     jest.mock('./containers/ContainerRegistry');
6
     jest.mock('./containers/ContainerRegistry');
8
-    jest.mock('./commands/Commands');
9
     ContainerRegistry = require('./containers/ContainerRegistry');
7
     ContainerRegistry = require('./containers/ContainerRegistry');
10
-    Commands = require('./commands/Commands');
11
 
8
 
12
-    mockNativeEventsReceiver = {
13
-      onAppLaunched: jest.fn()
14
-    };
9
+    jest.mock('./adapters/UniqueIdProvider');
10
+    jest.mock('./adapters/NativeCommandsSender');
11
+    jest.mock('./adapters/NativeEventsReceiver');
15
 
12
 
16
-    jest.mock('./adapters/NativeEventsReceiver', () => () => mockNativeEventsReceiver);
13
+    jest.mock('./commands/Commands');
17
 
14
 
18
     Navigation = require('./Navigation');
15
     Navigation = require('./Navigation');
19
   });
16
   });
29
   it('startApp delegates to Commands', () => {
26
   it('startApp delegates to Commands', () => {
30
     const params = {};
27
     const params = {};
31
     Navigation.startApp(params);
28
     Navigation.startApp(params);
32
-    expect(Commands.startApp).toHaveBeenCalledTimes(1);
33
-    expect(Commands.startApp).toHaveBeenCalledWith(params);
29
+    expect(Navigation.commands.startApp).toHaveBeenCalledTimes(1);
30
+    expect(Navigation.commands.startApp).toHaveBeenCalledWith(params);
34
   });
31
   });
35
 
32
 
36
   it('onAppLaunched delegates to NativeEventsReceiver', () => {
33
   it('onAppLaunched delegates to NativeEventsReceiver', () => {
37
-    Navigation.onAppLaunched(jest.fn());
38
-    expect(mockNativeEventsReceiver.onAppLaunched).toHaveBeenCalledTimes(1);
34
+    const fn = jest.fn();
35
+    Navigation.onAppLaunched(fn);
36
+    expect(Navigation.nativeEventsReceiver.onAppLaunched).toHaveBeenCalledTimes(1);
37
+    expect(Navigation.nativeEventsReceiver.onAppLaunched).toHaveBeenCalledWith(fn);
39
   });
38
   });
40
 });
39
 });

+ 4
- 0
src/adapters/NativeCommandsSender.js View File

1
+import {NativeModules} from 'react-native';
2
+
3
+const singleton = NativeModules.RNNBridgeModule;
4
+export default singleton;

+ 4
- 2
src/adapters/UniqueIdProvider.js View File

1
 import _ from 'lodash';
1
 import _ from 'lodash';
2
 
2
 
3
-export function uniqueId(prefix) {
4
-  return _.uniqueId(prefix);
3
+export default class UniqueIdProvider {
4
+  generate(prefix) {
5
+    return _.uniqueId(prefix);
6
+  }
5
 }
7
 }

+ 7
- 6
src/adapters/UniqueIdProvider.test.js View File

2
   let uut;
2
   let uut;
3
 
3
 
4
   beforeEach(() => {
4
   beforeEach(() => {
5
-    uut = require('./UniqueIdProvider');
5
+    const UniqueIdProvider = require('./UniqueIdProvider').default;
6
+    uut = new UniqueIdProvider();
6
   });
7
   });
7
 
8
 
8
   it('provides uniqueId', () => {
9
   it('provides uniqueId', () => {
9
-    expect(uut.uniqueId()).toEqual('1');
10
-    expect(uut.uniqueId()).toEqual('2');
10
+    expect(uut.generate()).toEqual('1');
11
+    expect(uut.generate()).toEqual('2');
11
   });
12
   });
12
 
13
 
13
   it('provides with prefix', () => {
14
   it('provides with prefix', () => {
14
-    expect(uut.uniqueId('prefix')).toEqual('prefix1');
15
-    expect(uut.uniqueId('prefix')).toEqual('prefix2');
16
-    expect(uut.uniqueId('other')).toEqual('other3');
15
+    expect(uut.generate('prefix')).toEqual('prefix1');
16
+    expect(uut.generate('prefix')).toEqual('prefix2');
17
+    expect(uut.generate('other')).toEqual('other3');
17
   });
18
   });
18
 });
19
 });

+ 0
- 3
src/adapters/__mocks__/UniqueIdProvider.js View File

1
-export function uniqueId(prefix) {
2
-  return `${prefix}UNIQUE`;
3
-}

+ 10
- 5
src/commands/Commands.js View File

1
-import {NativeModules} from 'react-native';
2
-const {NativeNavigation} = NativeModules;
3
-import * as LayoutBuilder from './LayoutBuilder';
1
+import LayoutTreeParser from './LayoutTreeParser';
4
 
2
 
5
-export function startApp(params) {
6
-  NativeNavigation.startApp(LayoutBuilder.parse(params));
3
+export default class Commands {
4
+  constructor(nativeCommandsSender, uniqueIdProvider) {
5
+    this.nativeCommandsSender = nativeCommandsSender;
6
+    this.layoutTreeParser = new LayoutTreeParser(uniqueIdProvider);
7
+  }
8
+
9
+  startApp(params) {
10
+    this.nativeCommandsSender.startApp(this.layoutTreeParser.parse(params));
11
+  }
7
 }
12
 }

+ 11
- 8
src/commands/Commands.test.js View File

1
 describe('Commands', () => {
1
 describe('Commands', () => {
2
   let uut;
2
   let uut;
3
-  let mockNativeNavigation;
3
+  const nativeCommandsSender = {
4
+    startApp: jest.fn()
5
+  };
6
+  const uniqueIdProvider = {
7
+    generate: (prefix) => `${prefix}UNIQUE`
8
+  };
4
 
9
 
5
   beforeEach(() => {
10
   beforeEach(() => {
6
-    mockNativeNavigation = {
7
-      startApp: jest.fn()
8
-    };
9
-    require('react-native').NativeModules.NativeNavigation = mockNativeNavigation;
10
-    uut = require('./Commands');
11
+    const Commands = require('./Commands').default;
12
+    uut = new Commands(nativeCommandsSender, uniqueIdProvider);
11
   });
13
   });
12
 
14
 
13
   describe('startApp', () => {
15
   describe('startApp', () => {
14
-    it('sends startApp to native', () => {
16
+    it('sends startApp to native after parsing into layoutTree', () => {
15
       uut.startApp({
17
       uut.startApp({
16
         container: {
18
         container: {
17
           name: 'com.example.MyScreen'
19
           name: 'com.example.MyScreen'
18
         }
20
         }
19
       });
21
       });
20
-      expect(mockNativeNavigation.startApp).toHaveBeenCalledTimes(1);
22
+      expect(nativeCommandsSender.startApp).toHaveBeenCalledTimes(1);
23
+      //TODO
21
     });
24
     });
22
   });
25
   });
23
 });
26
 });

+ 0
- 21
src/commands/LayoutBuilder.js View File

1
-import _ from 'lodash';
2
-import {uniqueId} from '../adapters/UniqueIdProvider';
3
-
4
-export function parse(params) {
5
-  const layout = _.merge({}, params);
6
-  if (layout.container) {
7
-    layout.container.id = uniqueId(`container`);
8
-  }
9
-  if (layout.sideMenu) {
10
-    if (layout.sideMenu.left) {
11
-      layout.sideMenu.left.id = uniqueId(`container`);
12
-    }
13
-    if (layout.sideMenu.right) {
14
-      layout.sideMenu.right.id = uniqueId(`container`);
15
-    }
16
-  }
17
-  if (layout.tabs) {
18
-    _.forEach(layout.tabs, (t) => t.container.id = uniqueId(`container`));
19
-  }
20
-  return layout;
21
-}

+ 26
- 0
src/commands/LayoutTreeParser.js View File

1
+import _ from 'lodash';
2
+
3
+export default class LayoutTreeParser {
4
+  constructor(uniqueIdProvider) {
5
+    this.uniqueIdProvider = uniqueIdProvider;
6
+  }
7
+
8
+  parse(params) {
9
+    const layout = _.merge({}, params);
10
+    if (layout.container) {
11
+      layout.container.id = this.uniqueIdProvider.generate(`container`);
12
+    }
13
+    if (layout.sideMenu) {
14
+      if (layout.sideMenu.left) {
15
+        layout.sideMenu.left.id = this.uniqueIdProvider.generate(`container`);
16
+      }
17
+      if (layout.sideMenu.right) {
18
+        layout.sideMenu.right.id = this.uniqueIdProvider.generate(`container`);
19
+      }
20
+    }
21
+    if (layout.tabs) {
22
+      _.forEach(layout.tabs, (t) => t.container.id = this.uniqueIdProvider.generate(`container`));
23
+    }
24
+    return layout;
25
+  }
26
+}

src/commands/LayoutBuilder.test.js → src/commands/LayoutTreeParser.test.js View File

1
-describe('LayoutBuilder', () => {
1
+xdescribe('LayoutTreeParser', () => {
2
   let LayoutBuilder;
2
   let LayoutBuilder;
3
 
3
 
4
   beforeEach(() => {
4
   beforeEach(() => {
5
     jest.mock('../adapters/UniqueIdProvider');
5
     jest.mock('../adapters/UniqueIdProvider');
6
-    LayoutBuilder = require('./LayoutBuilder');
6
+    LayoutBuilder = require('./LayoutTreeParser');
7
   });
7
   });
8
 
8
 
9
   describe('parse', () => {
9
   describe('parse', () => {

+ 1
- 0
src/containers/ContainerRegistry.js View File

1
 import React, {Component} from 'react';
1
 import React, {Component} from 'react';
2
 import {AppRegistry} from 'react-native';
2
 import {AppRegistry} from 'react-native';
3
+
3
 import * as Store from './Store';
4
 import * as Store from './Store';
4
 
5
 
5
 export function registerContainer(containerName, getContainerFunc) {
6
 export function registerContainer(containerName, getContainerFunc) {

+ 4
- 2
src/index.test.js View File

1
+jest.mock('./Navigation', () => ({startApp: () => 'import'}));
1
 import Navigation from './index';
2
 import Navigation from './index';
2
 
3
 
3
 describe('index', () => {
4
 describe('index', () => {
4
   let uut;
5
   let uut;
5
 
6
 
6
   beforeEach(() => {
7
   beforeEach(() => {
8
+    jest.mock('./Navigation', () => ({startApp: () => 'require'}));
7
     uut = require('./index');
9
     uut = require('./index');
8
   });
10
   });
9
 
11
 
10
   it('exposes Navigation', () => {
12
   it('exposes Navigation', () => {
11
-    expect(uut.startApp).toBeInstanceOf(Function);
12
-    expect(Navigation.startApp).toBeInstanceOf(Function);
13
+    expect(uut.startApp()).toEqual('require');
14
+    expect(Navigation.startApp()).toEqual('import');
13
   });
15
   });
14
 });
16
 });