Browse Source

refactor OptionsProcessor

Daniel Zlotin 7 years ago
parent
commit
99e4108fbd

+ 5
- 4
lib/src/commands/Commands.ts View File

5
   private nativeCommandsSender;
5
   private nativeCommandsSender;
6
   private layoutTreeParser;
6
   private layoutTreeParser;
7
   private layoutTreeCrawler;
7
   private layoutTreeCrawler;
8
+  private optionsProcessor = new OptionsProcessor();
8
 
9
 
9
   constructor(nativeCommandsSender, layoutTreeParser, layoutTreeCrawler) {
10
   constructor(nativeCommandsSender, layoutTreeParser, layoutTreeCrawler) {
10
     this.nativeCommandsSender = nativeCommandsSender;
11
     this.nativeCommandsSender = nativeCommandsSender;
21
 
22
 
22
   setDefaultOptions(options) {
23
   setDefaultOptions(options) {
23
     const input = _.cloneDeep(options);
24
     const input = _.cloneDeep(options);
24
-    OptionsProcessor.processOptions(input, this.layoutTreeCrawler.store);
25
+    this.optionsProcessor.processOptions(input, this.layoutTreeCrawler.store);
25
     this.nativeCommandsSender.setDefaultOptions(input);
26
     this.nativeCommandsSender.setDefaultOptions(input);
26
   }
27
   }
27
 
28
 
28
   setOptions(componentId, options) {
29
   setOptions(componentId, options) {
29
     const input = _.cloneDeep(options);
30
     const input = _.cloneDeep(options);
30
-    OptionsProcessor.processOptions(input, this.layoutTreeCrawler.store);
31
+    this.optionsProcessor.processOptions(input, this.layoutTreeCrawler.store);
31
     this.nativeCommandsSender.setOptions(componentId, input);
32
     this.nativeCommandsSender.setOptions(componentId, input);
32
   }
33
   }
33
 
34
 
48
 
49
 
49
   push(onComponentId, componentData) {
50
   push(onComponentId, componentData) {
50
     const input = _.cloneDeep(componentData);
51
     const input = _.cloneDeep(componentData);
51
-    OptionsProcessor.processOptions(input, this.layoutTreeCrawler.store);
52
+    this.optionsProcessor.processOptions(input, this.layoutTreeCrawler.store);
52
     const layout = this.layoutTreeParser.parse(input);
53
     const layout = this.layoutTreeParser.parse(input);
53
     this.layoutTreeCrawler.crawl(layout);
54
     this.layoutTreeCrawler.crawl(layout);
54
     return this.nativeCommandsSender.push(onComponentId, layout);
55
     return this.nativeCommandsSender.push(onComponentId, layout);
68
 
69
 
69
   showOverlay(componentData) {
70
   showOverlay(componentData) {
70
     const input = _.cloneDeep(componentData);
71
     const input = _.cloneDeep(componentData);
71
-    OptionsProcessor.processOptions(input, this.layoutTreeCrawler.store);
72
+    this.optionsProcessor.processOptions(input, this.layoutTreeCrawler.store);
72
 
73
 
73
     const layout = this.layoutTreeParser.parse(input);
74
     const layout = this.layoutTreeParser.parse(input);
74
     this.layoutTreeCrawler.crawl(layout);
75
     this.layoutTreeCrawler.crawl(layout);

+ 2
- 1
lib/src/commands/LayoutTreeCrawler.ts View File

15
 }
15
 }
16
 
16
 
17
 export class LayoutTreeCrawler {
17
 export class LayoutTreeCrawler {
18
+  private optionsProcessor = new OptionsProcessor();
18
   constructor(
19
   constructor(
19
     private readonly uniqueIdProvider: any,
20
     private readonly uniqueIdProvider: any,
20
     public readonly store: any) {
21
     public readonly store: any) {
29
     if (node.type === LayoutType.Component) {
30
     if (node.type === LayoutType.Component) {
30
       this._handleComponent(node);
31
       this._handleComponent(node);
31
     }
32
     }
32
-    OptionsProcessor.processOptions(node.data.options, this.store);
33
+    this.optionsProcessor.processOptions(node.data.options, this.store);
33
     _.forEach(node.children, this.crawl);
34
     _.forEach(node.children, this.crawl);
34
   }
35
   }
35
 
36
 

+ 30
- 19
lib/src/commands/OptionsProcessor.test.ts View File

1
 import { OptionsProcessor } from './OptionsProcessor';
1
 import { OptionsProcessor } from './OptionsProcessor';
2
-import { Store } from '../components/Store.mock';
2
+import { Store } from '../components/Store';
3
 
3
 
4
 describe('navigation options', () => {
4
 describe('navigation options', () => {
5
+  let uut: OptionsProcessor;
5
   let options;
6
   let options;
6
-  let store;
7
+  let store: Store;
7
   beforeEach(() => {
8
   beforeEach(() => {
8
     options = {};
9
     options = {};
9
     store = new Store();
10
     store = new Store();
11
+    uut = new OptionsProcessor();
10
   });
12
   });
11
 
13
 
12
   it('processes colors into numeric AARRGGBB', () => {
14
   it('processes colors into numeric AARRGGBB', () => {
13
     options.someKeyColor = 'red';
15
     options.someKeyColor = 'red';
14
     options.color = 'blue';
16
     options.color = 'blue';
15
-    OptionsProcessor.processOptions(options, store);
17
+    uut.processOptions(options, store);
16
     expect(options.someKeyColor).toEqual(0xffff0000);
18
     expect(options.someKeyColor).toEqual(0xffff0000);
17
     expect(options.color).toEqual(0xff0000ff);
19
     expect(options.color).toEqual(0xff0000ff);
18
 
20
 
19
     options.someKeyColor = 'yellow';
21
     options.someKeyColor = 'yellow';
20
-    OptionsProcessor.processOptions(options, store);
22
+    uut.processOptions(options, store);
21
     expect(options.someKeyColor).toEqual(0xffffff00);
23
     expect(options.someKeyColor).toEqual(0xffffff00);
22
   });
24
   });
23
 
25
 
24
   it('processes numeric colors', () => {
26
   it('processes numeric colors', () => {
25
     options.someKeyColor = '#123456';
27
     options.someKeyColor = '#123456';
26
-    OptionsProcessor.processOptions(options, store);
28
+    uut.processOptions(options, store);
27
     expect(options.someKeyColor).toEqual(0xff123456);
29
     expect(options.someKeyColor).toEqual(0xff123456);
28
 
30
 
29
     options.someKeyColor = 0x123456ff; // wut
31
     options.someKeyColor = 0x123456ff; // wut
30
-    OptionsProcessor.processOptions(options, store);
32
+    uut.processOptions(options, store);
31
     expect(options.someKeyColor).toEqual(0xff123456);
33
     expect(options.someKeyColor).toEqual(0xff123456);
32
   });
34
   });
33
 
35
 
34
   it('process colors with rgb functions', () => {
36
   it('process colors with rgb functions', () => {
35
     options.someKeyColor = 'rgb(255, 0, 255)';
37
     options.someKeyColor = 'rgb(255, 0, 255)';
36
-    OptionsProcessor.processOptions(options, store);
38
+    uut.processOptions(options, store);
37
     expect(options.someKeyColor).toEqual(0xffff00ff);
39
     expect(options.someKeyColor).toEqual(0xffff00ff);
38
   });
40
   });
39
 
41
 
40
   it('process colors with special words', () => {
42
   it('process colors with special words', () => {
41
     options.someKeyColor = 'fuchsia';
43
     options.someKeyColor = 'fuchsia';
42
-    OptionsProcessor.processOptions(options, store);
44
+    uut.processOptions(options, store);
43
     expect(options.someKeyColor).toEqual(0xffff00ff);
45
     expect(options.someKeyColor).toEqual(0xffff00ff);
44
   });
46
   });
45
 
47
 
46
   it('process colors with hsla functions', () => {
48
   it('process colors with hsla functions', () => {
47
     options.someKeyColor = 'hsla(360, 100%, 100%, 1.0)';
49
     options.someKeyColor = 'hsla(360, 100%, 100%, 1.0)';
48
-    OptionsProcessor.processOptions(options, store);
50
+    uut.processOptions(options, store);
49
 
51
 
50
     expect(options.someKeyColor).toEqual(0xffffffff);
52
     expect(options.someKeyColor).toEqual(0xffffffff);
51
   });
53
   });
52
 
54
 
53
   it('unknown colors return undefined', () => {
55
   it('unknown colors return undefined', () => {
54
     options.someKeyColor = 'wut';
56
     options.someKeyColor = 'wut';
55
-    OptionsProcessor.processOptions(options, store);
57
+    uut.processOptions(options, store);
56
     expect(options.someKeyColor).toEqual(undefined);
58
     expect(options.someKeyColor).toEqual(undefined);
57
   });
59
   });
58
 
60
 
60
     options.otherKeyColor = 'red';
62
     options.otherKeyColor = 'red';
61
     options.yetAnotherColor = 'blue';
63
     options.yetAnotherColor = 'blue';
62
     options.andAnotherColor = 'rgb(0, 255, 0)';
64
     options.andAnotherColor = 'rgb(0, 255, 0)';
63
-    OptionsProcessor.processOptions(options, store);
65
+    uut.processOptions(options, store);
64
     expect(options.otherKeyColor).toEqual(0xffff0000);
66
     expect(options.otherKeyColor).toEqual(0xffff0000);
65
     expect(options.yetAnotherColor).toEqual(0xff0000ff);
67
     expect(options.yetAnotherColor).toEqual(0xff0000ff);
66
     expect(options.andAnotherColor).toEqual(0xff00ff00);
68
     expect(options.andAnotherColor).toEqual(0xff00ff00);
68
 
70
 
69
   it('keys ending with Color case sensitive', () => {
71
   it('keys ending with Color case sensitive', () => {
70
     options.otherKey_color = 'red'; // eslint-disable-line camelcase
72
     options.otherKey_color = 'red'; // eslint-disable-line camelcase
71
-    OptionsProcessor.processOptions(options, store);
73
+    uut.processOptions(options, store);
72
     expect(options.otherKey_color).toEqual('red');
74
     expect(options.otherKey_color).toEqual('red');
73
   });
75
   });
74
 
76
 
75
   it('any nested recursive keys ending with Color', () => {
77
   it('any nested recursive keys ending with Color', () => {
76
     options.topBar = { textColor: 'red' };
78
     options.topBar = { textColor: 'red' };
77
     options.topBar.innerMostObj = { anotherColor: 'yellow' };
79
     options.topBar.innerMostObj = { anotherColor: 'yellow' };
78
-    OptionsProcessor.processOptions(options, store);
80
+    uut.processOptions(options, store);
79
     expect(options.topBar.textColor).toEqual(0xffff0000);
81
     expect(options.topBar.textColor).toEqual(0xffff0000);
80
     expect(options.topBar.innerMostObj.anotherColor).toEqual(0xffffff00);
82
     expect(options.topBar.innerMostObj.anotherColor).toEqual(0xffffff00);
81
   });
83
   });
88
       myIcon: 'require("https://wix.github.io/react-native-navigation/_images/logo.png");',
90
       myIcon: 'require("https://wix.github.io/react-native-navigation/_images/logo.png");',
89
       myOtherValue: 'value'
91
       myOtherValue: 'value'
90
     };
92
     };
91
-    OptionsProcessor.processOptions(options, store);
93
+    uut.processOptions(options, store);
92
 
94
 
93
     // As we can't import external images and we don't want to add an image here
95
     // As we can't import external images and we don't want to add an image here
94
     // I assign the icons to strings (what the require would generally look like)
96
     // I assign the icons to strings (what the require would generally look like)
100
     expect(options.topBar.myOtherValue).toEqual('value');
102
     expect(options.topBar.myOtherValue).toEqual('value');
101
   });
103
   });
102
 
104
 
103
-  it('register props for button options', () => {
105
+  it('passProps for Buttons options', () => {
104
     const passProps = { prop: 'prop' };
106
     const passProps = { prop: 'prop' };
105
     options.rightButtons = [{ passProps, id: '1' }];
107
     options.rightButtons = [{ passProps, id: '1' }];
106
 
108
 
107
-    OptionsProcessor.processOptions({ o: options }, store);
109
+    uut.processOptions({ o: options }, store);
108
 
110
 
109
-    expect(store.setPropsForId).toBeCalledWith('1', passProps);
111
+    expect(store.getPropsForId('1')).toEqual(passProps);
112
+  });
113
+
114
+  it('passProps must be with id next to it', () => {
115
+    const passProps = { prop: 'prop' };
116
+    options.rightButtons = [{ passProps }];
117
+
118
+    uut.processOptions({ o: options }, store);
119
+
120
+    expect(store.getPropsForId('1')).toEqual({});
110
   });
121
   });
111
 
122
 
112
   it('processes Options object', () => {
123
   it('processes Options object', () => {
114
     options.topBar = { textColor: 'red' };
125
     options.topBar = { textColor: 'red' };
115
     options.topBar.innerMostObj = { anotherColor: 'yellow' };
126
     options.topBar.innerMostObj = { anotherColor: 'yellow' };
116
 
127
 
117
-    OptionsProcessor.processOptions({ o: options }, store);
128
+    uut.processOptions({ o: options }, store);
118
 
129
 
119
     expect(options.topBar.textColor).toEqual(0xffff0000);
130
     expect(options.topBar.textColor).toEqual(0xffff0000);
120
   });
131
   });
121
 
132
 
122
   it('undefined value return undefined ', () => {
133
   it('undefined value return undefined ', () => {
123
     options.someImage = undefined;
134
     options.someImage = undefined;
124
-    OptionsProcessor.processOptions(options, store);
135
+    uut.processOptions(options, store);
125
 
136
 
126
     expect(options.someImage).toEqual(undefined);
137
     expect(options.someImage).toEqual(undefined);
127
   });
138
   });

+ 10
- 5
lib/src/commands/OptionsProcessor.ts View File

3
 import * as resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
3
 import * as resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
4
 
4
 
5
 export class OptionsProcessor {
5
 export class OptionsProcessor {
6
-  static processOptions(options, store) {
6
+  public processOptions(options, store) {
7
     _.forEach(options, (value, key) => {
7
     _.forEach(options, (value, key) => {
8
       if (!value) { return; }
8
       if (!value) { return; }
9
 
9
 
10
       if (_.isEqual(key, 'color') || _.endsWith(key, 'Color')) {
10
       if (_.isEqual(key, 'color') || _.endsWith(key, 'Color')) {
11
         options[key] = processColor(value);
11
         options[key] = processColor(value);
12
       }
12
       }
13
+
13
       if (_.isEqual(key, 'icon') || _.isEqual(key, 'image') || _.endsWith(key, 'Icon') || _.endsWith(key, 'Image')) {
14
       if (_.isEqual(key, 'icon') || _.isEqual(key, 'image') || _.endsWith(key, 'Icon') || _.endsWith(key, 'Image')) {
14
         options[key] = resolveAssetSource(options[key]);
15
         options[key] = resolveAssetSource(options[key]);
15
       }
16
       }
17
+
18
+      if (_.endsWith(key, 'Buttons')) {
19
+        this.saveButtonsPassProps(value, store);
20
+      }
21
+
16
       if (_.isObject(value) || _.isArray(value)) {
22
       if (_.isObject(value) || _.isArray(value)) {
17
-        OptionsProcessor.processOptions(value, store);
18
-        OptionsProcessor.processArrayOptions(key, value, store);
23
+        this.processOptions(value, store);
19
       }
24
       }
20
     });
25
     });
21
   }
26
   }
22
 
27
 
23
-  static processArrayOptions(key, array, store) {
28
+  private saveButtonsPassProps(array, store) {
24
     _.forEach(array, (value) => {
29
     _.forEach(array, (value) => {
25
-      if (_.endsWith(key, 'Buttons') && value.passProps) {
30
+      if (value.passProps && value.id) {
26
         store.setPropsForId(value.id, value.passProps);
31
         store.setPropsForId(value.id, value.passProps);
27
       }
32
       }
28
     });
33
     });

+ 0
- 1
lib/src/components/Store.mock.ts View File

1
-export const { Store } = jest.genMockFromModule('./Store');