Просмотр исходного кода

changed setOptions to receive RNNNavigationOptions and added topBarTextColor (#1616)

* created RNNNavigationOptions

* created RNNRootViewControllerTest and added a test for the topBarBackgroundColor style

* working

* process navigationOptions colors

* created a test for new RNNRootViewController functionality

* changed RNNRootViewController to init with name, navigationOptions and container id, instead of node

* changed RNNRootViewController to get a new type - RNNavigationOptions

* refactored statusBarHidden test and implementation, all tests pass

* added setup to RNNRootViewControllerTest.m and refactored tests

* added test for title and implemented static title

* minor fixes

* removed redundant eslint config

* added topBarTextColor to RNNNavigationOptions

* topBarTextColor RNNRootViewController test

* changed setOptions to receive RNNNavigationOptions. created OptionsProcessor to process colors in both layoutTreeCrawler and Commands

* minor fix

* create setOptionsDynamically in RNNNavigationOptions to make dynamic options merge with static option instead of overriding them

* findcontainerId returns a RNNRootViewController , setOptions now merges styles with the static styles of the view
bogobogo 7 лет назад
Родитель
Сommit
f0856b7360

+ 5
- 14
lib/ios/RNNCommandsHandler.m Просмотреть файл

@@ -3,6 +3,8 @@
3 3
 
4 4
 #import "RNNModalManager.h"
5 5
 #import "RNNNavigationStackManager.h"
6
+#import "RNNNavigationOptions.h"
7
+#import "RNNRootViewController.h"
6 8
 
7 9
 @implementation RNNCommandsHandler {
8 10
 	RNNControllerFactory *_controllerFactory;
@@ -35,20 +37,9 @@
35 37
 
36 38
 -(void) setOptions:(NSString*)containerId options:(NSDictionary*)options {
37 39
 	[self assertReady];
38
-	UIViewController* vc = [_store findContainerForId:containerId];
39
-	
40
-	NSString* title = options[@"title"];
41
-	NSString* topBarTextColor = options[@"topBarTextColor"];
42
-	
43
-	[vc setTitle:title];
44
-	
45
-	int rgb = [[topBarTextColor substringFromIndex:1] intValue];
46
-	UIColor* color = [UIColor colorWithRed:((float)((rgb & 0xFF0000) >> 16))/255.0 \
47
-									 green:((float)((rgb & 0x00FF00) >>  8))/255.0 \
48
-									  blue:((float)((rgb & 0x0000FF) >>  0))/255.0 \
49
-									 alpha:1.0];
50
-	vc.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName: color};
51
-	
40
+	RNNRootViewController* vc = [_store findContainerForId:containerId];
41
+	[vc.navigationOptions setOptionsDynamically:options];
42
+	[vc.navigationOptions apply:vc];
52 43
 }
53 44
 
54 45
 -(void) push:(NSString*)containerId layout:(NSDictionary*)layout {

+ 2
- 1
lib/ios/RNNModalManager.m Просмотреть файл

@@ -1,4 +1,5 @@
1 1
 #import "RNNModalManager.h"
2
+#import "RNNRootViewController.h"
2 3
 
3 4
 @implementation RNNModalManager {
4 5
 	RNNStore *_store;
@@ -33,7 +34,7 @@
33 34
 -(void)removePendingNextModalIfOnTop {
34 35
 	NSString *containerId = [[_store pendingModalIdsToDismiss] lastObject];
35 36
 	
36
-	UIViewController *modalToDismiss = [_store findContainerForId:containerId];
37
+	RNNRootViewController *modalToDismiss = [_store findContainerForId:containerId];
37 38
 	
38 39
 	if(!modalToDismiss) {
39 40
 		return;

+ 2
- 0
lib/ios/RNNNavigationOptions.h Просмотреть файл

@@ -4,12 +4,14 @@
4 4
 @interface RNNNavigationOptions : NSObject
5 5
 
6 6
 @property (nonatomic, strong) NSNumber* topBarBackgroundColor;
7
+@property (nonatomic, strong) NSNumber* topBarTextColor;
7 8
 @property (nonatomic, strong) NSNumber* statusBarHidden;
8 9
 @property (nonatomic, strong) NSString* title;
9 10
 
10 11
 -(instancetype)initWithDict:(NSDictionary *)navigationOptions;
11 12
 
12 13
 -(void)apply:(UIViewController*)viewController;
14
+-(void)setOptionsDynamically:(NSDictionary*)dynamicOptions;
13 15
 
14 16
 @end
15 17
 

+ 11
- 2
lib/ios/RNNNavigationOptions.m Просмотреть файл

@@ -9,9 +9,16 @@
9 9
 	self.topBarBackgroundColor = [navigationOptions objectForKey:@"topBarBackgroundColor"];
10 10
 	self.statusBarHidden = [navigationOptions objectForKey:@"statusBarHidden"];
11 11
 	self.title = [navigationOptions objectForKey:@"title"];
12
+	self.topBarTextColor = [navigationOptions objectForKey:@"topBarTextColor"];
12 13
 	return self;
13 14
 }
14 15
 
16
+-(void)setOptionsDynamically:(NSDictionary *)dynamicOptions {
17
+	for(id key in dynamicOptions) {
18
+		[self setValue:[dynamicOptions objectForKey:key] forKey:key];
19
+	}
20
+}
21
+
15 22
 -(void)apply:(UIViewController*)viewController{
16 23
 	if (self.topBarBackgroundColor) {
17 24
 		UIColor* backgroundColor = [RCTConvert UIColor:self.topBarBackgroundColor];
@@ -20,8 +27,10 @@
20 27
 	if (self.title) {
21 28
 		viewController.navigationItem.title = self.title;
22 29
 	}
23
-	
24
-
30
+	if (self.topBarTextColor) {
31
+		UIColor* textColor = [RCTConvert UIColor:self.topBarTextColor];
32
+		viewController.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:textColor};
33
+	}
25 34
 }
26 35
 
27 36
 

+ 5
- 4
lib/ios/RNNNavigationStackManager.m Просмотреть файл

@@ -1,4 +1,5 @@
1 1
 #import "RNNNavigationStackManager.h"
2
+#import "RNNRootViewController.h"
2 3
 
3 4
 @implementation RNNNavigationStackManager {
4 5
 	RNNStore *_store;
@@ -11,12 +12,12 @@
11 12
 }
12 13
 
13 14
 -(void)push:(UIViewController *)newTop onTop:(NSString *)containerId {
14
-	UIViewController *vc = [_store findContainerForId:containerId];
15
+	RNNRootViewController *vc = [_store findContainerForId:containerId];
15 16
 	[[vc navigationController] pushViewController:newTop animated:YES];
16 17
 }
17 18
 
18 19
 -(void)pop:(NSString *)containerId {
19
-	UIViewController* vc = [_store findContainerForId:containerId];
20
+	RNNRootViewController* vc = [_store findContainerForId:containerId];
20 21
 	UINavigationController* nvc = [vc navigationController];
21 22
 	if ([nvc topViewController] == vc) {
22 23
 		[nvc popViewControllerAnimated:YES];
@@ -29,7 +30,7 @@
29 30
 }
30 31
 
31 32
 -(void)popTo:(NSString*)containerId {
32
-	UIViewController *vc = [_store findContainerForId:containerId];
33
+	RNNRootViewController *vc = [_store findContainerForId:containerId];
33 34
 	
34 35
 	if (vc) {
35 36
 		UINavigationController *nvc = [vc navigationController];
@@ -41,7 +42,7 @@
41 42
 }
42 43
 
43 44
 -(void) popToRoot:(NSString*)containerId {
44
-	UIViewController* vc = [_store findContainerForId:containerId];
45
+	RNNRootViewController* vc = [_store findContainerForId:containerId];
45 46
 	UINavigationController* nvc = [vc navigationController];
46 47
 	NSArray* poppedVCs = [nvc popToRootViewControllerAnimated:YES];
47 48
 	[self removePopedViewControllers:poppedVCs];

+ 3
- 0
lib/ios/RNNRootViewController.h Просмотреть файл

@@ -8,10 +8,13 @@
8 8
 
9 9
 @interface RNNRootViewController : UIViewController
10 10
 
11
+@property (nonatomic, strong) RNNNavigationOptions* navigationOptions;
12
+
11 13
 -(instancetype)initWithName:(NSString*)name
12 14
 				withOptions:(RNNNavigationOptions*)options
13 15
 			withContainerId:(NSString*)containerId
14 16
 			rootViewCreator:(id<RNNRootViewCreator>)creator
15 17
 			   eventEmitter:(RNNEventEmitter*)eventEmitter;
16 18
 
19
+
17 20
 @end

+ 0
- 2
lib/ios/RNNRootViewController.m Просмотреть файл

@@ -8,7 +8,6 @@
8 8
 @property (nonatomic, strong) NSString* containerName;
9 9
 @property (nonatomic, strong) RNNEventEmitter *eventEmitter;
10 10
 @property (nonatomic) BOOL _statusBarHidden;
11
-@property (nonatomic, strong) RNNNavigationOptions* navigationOptions;
12 11
 
13 12
 @end
14 13
 
@@ -35,7 +34,6 @@
35 34
 	return [self.navigationOptions.statusBarHidden boolValue]; // || self.navigationController.isNavigationBarHidden;
36 35
 }
37 36
 
38
-
39 37
 -(void)viewDidAppear:(BOOL)animated {
40 38
 	[super viewDidAppear:animated];
41 39
 	[self.eventEmitter sendContainerStart:self.containerId];

+ 2
- 1
lib/ios/RNNStore.h Просмотреть файл

@@ -1,10 +1,11 @@
1 1
 
2 2
 #import <Foundation/Foundation.h>
3 3
 #import <UIKit/UIKit.h>
4
+#import "RNNRootViewController.h"
4 5
 
5 6
 @interface RNNStore : NSObject
6 7
 
7
--(UIViewController*) findContainerForId:(NSString*)containerId;
8
+-(RNNRootViewController*) findContainerForId:(NSString*)containerId;
8 9
 -(void) setContainer:(UIViewController*)viewController containerId:(NSString*)containerId;
9 10
 -(void) removeContainer:(NSString*)containerId;
10 11
 -(void) removeContainerByViewControllerInstance:(UIViewController*)containerInstance;

+ 3
- 3
lib/ios/RNNStore.m Просмотреть файл

@@ -1,6 +1,6 @@
1 1
 
2 2
 #import "RNNStore.h"
3
-
3
+#import "RNNRootViewController.h"
4 4
 @interface RNNStore ()
5 5
 
6 6
 @end
@@ -19,12 +19,12 @@
19 19
 	return self;
20 20
 }
21 21
 
22
--(UIViewController *)findContainerForId:(NSString *)containerId {
22
+-(RNNRootViewController *)findContainerForId:(NSString *)containerId {
23 23
 	return [_containerStore objectForKey:containerId];
24 24
 }
25 25
 
26 26
 - (void)setContainer:(UIViewController*)viewController containerId:(NSString*)containerId {
27
-	UIViewController *existingVewController = [self findContainerForId:containerId];
27
+	RNNRootViewController *existingVewController = [self findContainerForId:containerId];
28 28
 	if (existingVewController) {
29 29
 		@throw [NSException exceptionWithName:@"MultipleContainerId" reason:[@"Container id already exists " stringByAppendingString:containerId] userInfo:nil];
30 30
 	}

+ 1
- 1
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj Просмотреть файл

@@ -323,11 +323,11 @@
323 323
 				7BA500771E254908001B9E1B /* RNNSplashScreen.m */,
324 324
 				7BEF0D1A1E43771B003E96B0 /* RNNLayoutNode.h */,
325 325
 				7BEF0D1B1E43771B003E96B0 /* RNNLayoutNode.m */,
326
-				7BC9346C1E26886E00EFA125 /* RNNControllerFactory.h */,
327 326
 				7BC9346D1E26886E00EFA125 /* RNNControllerFactory.m */,
328 327
 				7BEF0D161E437684003E96B0 /* RNNRootViewController.h */,
329 328
 				7BEF0D171E437684003E96B0 /* RNNRootViewController.m */,
330 329
 				263905D41E4C94970023D7D3 /* RNNSideMenuController.h */,
330
+				7BC9346C1E26886E00EFA125 /* RNNControllerFactory.h */,
331 331
 				263905D51E4C94970023D7D3 /* RNNSideMenuController.m */,
332 332
 				263905E41E4CAC950023D7D3 /* RNNSideMenuChildVC.h */,
333 333
 				263905E51E4CAC950023D7D3 /* RNNSideMenuChildVC.m */,

+ 39
- 2
lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m Просмотреть файл

@@ -1,17 +1,38 @@
1 1
 #import <XCTest/XCTest.h>
2 2
 #import <objc/runtime.h>
3 3
 #import "RNNCommandsHandler.h"
4
+#import "RNNNavigationOptions.h"
5
+#import "RNNTestRootViewCreator.h"
6
+#import "RNNRootViewController.h"
4 7
 
5 8
 @interface RNNCommandsHandlerTest : XCTestCase
6 9
 
10
+@property (nonatomic, strong) id<RNNRootViewCreator> creator;
11
+@property (nonatomic, strong) NSString* pageName;
12
+@property (nonatomic, strong) NSString* containerId;
13
+@property (nonatomic, strong) id emitter;
14
+@property (nonatomic, strong) RNNStore* store;
15
+@property (nonatomic, strong) RNNNavigationOptions* options;
16
+@property (nonatomic, strong) RNNRootViewController* viewController;
17
+@property (nonatomic, strong) RNNCommandsHandler* cmdHandler;
18
+
7 19
 @end
8 20
 
9 21
 @implementation RNNCommandsHandlerTest
10 22
 
11 23
 - (void)setUp {
12 24
 	[super setUp];
13
-	
14
-	
25
+	self.creator = [[RNNTestRootViewCreator alloc] init];
26
+	self.pageName = @"somename";
27
+	self.containerId = @"cntId";
28
+	self.emitter = nil;
29
+	self.options = [[RNNNavigationOptions alloc] initWithDict:@{@"title" : @"static title"}];
30
+	self.store = [RNNStore new];
31
+	self.viewController = [[RNNRootViewController alloc] initWithName:self.pageName withOptions:self.options withContainerId:self.containerId rootViewCreator:self.creator eventEmitter:self.emitter];
32
+	[self.store setReadyToReceiveCommands:true];
33
+	__unused UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:self.viewController];
34
+	[self.store setContainer:self.viewController containerId:self.containerId];
35
+	self.cmdHandler = [[RNNCommandsHandler alloc] initWithStore:self.store controllerFactory:nil];
15 36
 }
16 37
 
17 38
 
@@ -53,6 +74,22 @@
53 74
 	return result;
54 75
 }
55 76
 
77
+-(void)testDynamicTopBarBackgroundColor_validColor {
78
+	NSDictionary* dictFromJs = @{@"topBarBackgroundColor" :@(0xFFFF0000)};
79
+	UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
80
+	[self.cmdHandler setOptions:self.containerId options:dictFromJs];
81
+	XCTAssertTrue([self.viewController.navigationController.navigationBar.barTintColor isEqual:expectedColor]);
82
+}
83
+
84
+-(void)testDynamicStylesMergeWithStaticStyles {
85
+	NSDictionary* dictFromJs = @{@"topBarBackgroundColor" :@(0xFFFF0000)};
86
+	UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
87
+	[self.cmdHandler setOptions:self.containerId options:dictFromJs];
88
+	XCTAssertTrue([self.viewController.navigationController.navigationBar.barTintColor isEqual:expectedColor]);
89
+	XCTAssertTrue([self.viewController.navigationItem.title isEqual:@"static title"]);
90
+}
91
+
92
+
56 93
 
57 94
 
58 95
 @end

+ 20
- 0
lib/ios/ReactNativeNavigationTests/RNNNavigationOptionsTest.m Просмотреть файл

@@ -15,6 +15,26 @@
15 15
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:@{}];
16 16
 	XCTAssertTrue([options isKindOfClass:[RNNNavigationOptions class]]);
17 17
 }
18
+-(void)testAddsStyleFromDictionaryWithInit{
19
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:@{@"topBarBackgroundColor" : @(0xff0000ff)}];
20
+	XCTAssertTrue(options.topBarBackgroundColor);
21
+}
22
+-(void)testReturnsNilWhenStyleDoesNotExist{
23
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:@{@"topBarBackgroundColor" : @(0xff0000ff)}];
24
+	XCTAssertNil(options.topBarTextColor);
25
+}
18 26
 
27
+-(void)testChangeRNNNavigationOptionsDynamically{
28
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:@{@"topBarBackgroundColor" : @(0xff0000ff)}];
29
+	NSDictionary* dynamicOptions = @{@"topBarTextColor" : @(0xffff00ff), @"title" : @"hello"};
30
+    [options setOptionsDynamically:dynamicOptions];
31
+	XCTAssertTrue([options.title isEqual:@"hello"]);
32
+	
33
+}
19 34
 
35
+-(void)testChangeRNNNavigationOptionsWithInvalidProperties{
36
+	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:@{@"topBarBackgroundColor" : @(0xff0000ff)}];
37
+	NSDictionary* dynamicOptions = @{@"titleeeee" : @"hello"};
38
+	XCTAssertThrows([options setOptionsDynamically:dynamicOptions]);
39
+}
20 40
 @end

+ 9
- 0
lib/ios/ReactNativeNavigationTests/RNNRootViewControllerTest.m Просмотреть файл

@@ -83,5 +83,14 @@
83 83
 	XCTAssertNil(self.uut.navigationItem.title);
84 84
 }
85 85
 
86
+-(void)testTopBarTextColor_validColor{
87
+	NSNumber* inputColor = @(0xFFFF0000);
88
+	self.options.topBarTextColor = inputColor;
89
+	__unused UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:self.uut];
90
+	[self.uut viewWillAppear:false];
91
+	UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
92
+	XCTAssertTrue([self.uut.navigationController.navigationBar.titleTextAttributes[@"NSColor"] isEqual:expectedColor]);
93
+}
94
+
86 95
 
87 96
 @end

+ 2
- 0
lib/src/commands/Commands.js Просмотреть файл

@@ -1,4 +1,5 @@
1 1
 import _ from 'lodash';
2
+import optionsProcessor from './OptionsProcessor';
2 3
 
3 4
 export default class Commands {
4 5
   constructor(nativeCommandsSender, layoutTreeParser, layoutTreeCrawler) {
@@ -16,6 +17,7 @@ export default class Commands {
16 17
 
17 18
   setOptions(containerId, options) {
18 19
     const input = _.cloneDeep(options);
20
+    optionsProcessor(input);
19 21
     this.nativeCommandsSender.setOptions(containerId, input);
20 22
   }
21 23
 

+ 2
- 12
lib/src/commands/LayoutTreeCrawler.js Просмотреть файл

@@ -1,6 +1,7 @@
1 1
 import _ from 'lodash';
2 2
 import { processColor } from 'react-native';
3 3
 import LayoutTypes from './LayoutTypes';
4
+import optionsProcessor from './OptionsProcessor';
4 5
 
5 6
 export default class LayoutTreeCrawler {
6 7
   constructor(uniqueIdProvider, store) {
@@ -25,18 +26,7 @@ export default class LayoutTreeCrawler {
25 26
     this.store.setPropsForContainerId(node.id, node.data.passProps);
26 27
     const clazz = this.store.getOriginalContainerClassForName(node.data.name);
27 28
     node.data.navigationOptions = _.cloneDeep(_.get(clazz, 'navigationOptions', {}));
28
-    this._processNavigationOptionsColors(node.data.navigationOptions);
29
-  }
30
-
31
-  _processNavigationOptionsColors(navigationOptions) {
32
-    _.forEach(navigationOptions, (value, key) => {
33
-      if (_.endsWith(key, 'Color')) {
34
-        navigationOptions[key] = processColor(value);
35
-      }
36
-      if (_.isPlainObject(value)) {
37
-        this._processNavigationOptionsColors(value);
38
-      }
39
-    });
29
+    optionsProcessor(node.data.navigationOptions);
40 30
   }
41 31
 
42 32
   _assertKnownLayoutType(type) {

+ 13
- 0
lib/src/commands/OptionsProcessor.js Просмотреть файл

@@ -0,0 +1,13 @@
1
+import _ from 'lodash';
2
+import { processColor } from 'react-native';
3
+
4
+export default function optionsProcessor(navigationOptions) {
5
+  _.forEach(navigationOptions, (value, key) => {
6
+    if (_.endsWith(key, 'Color')) {
7
+      navigationOptions[key] = processColor(value);
8
+    }
9
+    if (_.isPlainObject(value)) {
10
+      optionsProcessor(value);
11
+    }
12
+  });
13
+}

+ 78
- 0
lib/src/commands/OptionsProcessor.test.js Просмотреть файл

@@ -0,0 +1,78 @@
1
+import optionsProcessor from './OptionsProcessor';
2
+ 
3
+describe('navigation options', () => {
4
+  let navigationOptions;
5
+
6
+  beforeEach(() => {
7
+    navigationOptions = {};
8
+  });
9
+
10
+  it('processes colors into numeric AARRGGBB', () => {
11
+    navigationOptions.someKeyColor = 'red';
12
+    optionsProcessor(navigationOptions);
13
+    expect(navigationOptions.someKeyColor).toEqual(0xffff0000);
14
+
15
+    navigationOptions.someKeyColor = 'yellow';
16
+    optionsProcessor(navigationOptions);
17
+    expect(navigationOptions.someKeyColor).toEqual(0xffffff00);
18
+  });
19
+
20
+  it('processes numeric colors', () => {
21
+    navigationOptions.someKeyColor = '#123456';
22
+    optionsProcessor(navigationOptions);
23
+    expect(navigationOptions.someKeyColor).toEqual(0xff123456);
24
+
25
+    navigationOptions.someKeyColor = 0x123456ff; // wut
26
+    optionsProcessor(navigationOptions);
27
+    expect(navigationOptions.someKeyColor).toEqual(0xff123456);
28
+  });
29
+
30
+  it('process colors with rgb functions', () => {
31
+    navigationOptions.someKeyColor = 'rgb(255, 0, 255)';
32
+    optionsProcessor(navigationOptions);
33
+    expect(navigationOptions.someKeyColor).toEqual(0xffff00ff);
34
+  });
35
+
36
+  it('process colors with special words', () => {
37
+    navigationOptions.someKeyColor = 'fuchsia';
38
+    optionsProcessor(navigationOptions);
39
+    expect(navigationOptions.someKeyColor).toEqual(0xffff00ff);
40
+  });
41
+
42
+  it('process colors with hsla functions', () => {
43
+    navigationOptions.someKeyColor = 'hsla(360, 100%, 100%, 1.0)';
44
+    optionsProcessor(navigationOptions);
45
+
46
+    expect(navigationOptions.someKeyColor).toEqual(0xffffffff);
47
+  });
48
+
49
+  it('unknown colors return undefined', () => {
50
+    navigationOptions.someKeyColor = 'wut';
51
+    optionsProcessor(navigationOptions);
52
+    expect(navigationOptions.someKeyColor).toEqual(undefined);
53
+  });
54
+
55
+  it('any keys ending with Color', () => {
56
+    navigationOptions.otherKeyColor = 'red';
57
+    navigationOptions.yetAnotherColor = 'blue';
58
+    navigationOptions.andAnotherColor = 'rgb(0, 255, 0)';
59
+    optionsProcessor(navigationOptions);
60
+    expect(navigationOptions.otherKeyColor).toEqual(0xffff0000);
61
+    expect(navigationOptions.yetAnotherColor).toEqual(0xff0000ff);
62
+    expect(navigationOptions.andAnotherColor).toEqual(0xff00ff00);
63
+  });
64
+
65
+  it('keys ending with Color case sensitive', () => {
66
+    navigationOptions.otherKey_color = 'red';
67
+    optionsProcessor(navigationOptions);
68
+    expect(navigationOptions.otherKey_color).toEqual('red');
69
+  });
70
+
71
+  it('any nested recursive keys ending with Color', () => {
72
+    navigationOptions.innerObj = { theKeyColor: 'red' };
73
+    navigationOptions.innerObj.innerMostObj = { anotherColor: 'yellow' };
74
+    optionsProcessor(navigationOptions);
75
+    expect(navigationOptions.innerObj.theKeyColor).toEqual(0xffff0000);
76
+    expect(navigationOptions.innerObj.innerMostObj.anotherColor).toEqual(0xffffff00);
77
+  });
78
+});

+ 2
- 1
playground/src/containers/OptionsScreen.js Просмотреть файл

@@ -34,7 +34,8 @@ class OptionsScreen extends Component {
34 34
   onClickDynamicOptions() {
35 35
     Navigation.setOptions(this.props.containerId, {
36 36
       title: 'Dynamic Title',
37
-      topBarTextColor: '#123456'
37
+      topBarTextColor: '#00FFFF',
38
+      topBarBackgroundColor: 'green'
38 39
     });
39 40
   }
40 41
 }