Sfoglia il codice sorgente

Fixes unnecessary rendering of the last viewController in setStackRoot (#5358)

* Fixes unnecessary rendering of the last viewController in setStackRoot, Closes #5355

* Add setStackRoot unit tests
Yogev Ben David 5 anni fa
parent
commit
4cc6b56e44

+ 3
- 1
lib/ios/RNNCommandsHandler.m Vedi File

173
 	
173
 	
174
 	NSArray<UIViewController *> *childViewControllers = [_controllerFactory createChildrenLayout:children];
174
 	NSArray<UIViewController *> *childViewControllers = [_controllerFactory createChildrenLayout:children];
175
 	for (UIViewController<RNNLayoutProtocol>* viewController in childViewControllers) {
175
 	for (UIViewController<RNNLayoutProtocol>* viewController in childViewControllers) {
176
-		[viewController renderTreeAndWait:NO perform:nil];
176
+		if (![viewController isEqual:childViewControllers.lastObject]) {
177
+			[viewController renderTreeAndWait:NO perform:nil];
178
+		}
177
 	}
179
 	}
178
 	UIViewController *newVC = childViewControllers.lastObject;
180
 	UIViewController *newVC = childViewControllers.lastObject;
179
 	UIViewController *fromVC = [RNNLayoutManager findComponentForId:componentId];
181
 	UIViewController *fromVC = [RNNLayoutManager findComponentForId:componentId];

+ 46
- 8
lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m Vedi File

120
 	initialOptions.topBar.title.text = [[Text alloc] initWithValue:@"the title"];
120
 	initialOptions.topBar.title.text = [[Text alloc] initWithValue:@"the title"];
121
 	RNNLayoutInfo* layoutInfo = [RNNLayoutInfo new];
121
 	RNNLayoutInfo* layoutInfo = [RNNLayoutInfo new];
122
 	RNNTestRootViewCreator* creator = [[RNNTestRootViewCreator alloc] init];
122
 	RNNTestRootViewCreator* creator = [[RNNTestRootViewCreator alloc] init];
123
-
123
+	
124
 	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
124
 	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
125
 	RNNRootViewController* vc = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:creator eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil];
125
 	RNNRootViewController* vc = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:creator eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil];
126
-
126
+	
127
 	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:creator options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init] eventEmitter:nil childViewControllers:@[vc]];
127
 	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:creator options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init] eventEmitter:nil childViewControllers:@[vc]];
128
 	
128
 	
129
 	[vc viewWillAppear:false];
129
 	[vc viewWillAppear:false];
130
 	XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
130
 	XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
131
-
131
+	
132
 	[self.uut setReadyToReceiveCommands:true];
132
 	[self.uut setReadyToReceiveCommands:true];
133
-
133
+	
134
 	NSDictionary* dictFromJs = @{@"topBar": @{@"background" : @{@"color" : @(0xFFFF0000)}}};
134
 	NSDictionary* dictFromJs = @{@"topBar": @{@"background" : @{@"color" : @(0xFFFF0000)}}};
135
 	UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
135
 	UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
136
-
136
+	
137
 	[self.uut mergeOptions:@"componentId" options:dictFromJs completion:^{
137
 	[self.uut mergeOptions:@"componentId" options:dictFromJs completion:^{
138
 		XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
138
 		XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
139
 		XCTAssertTrue([nav.navigationBar.barTintColor isEqual:expectedColor]);
139
 		XCTAssertTrue([nav.navigationBar.barTintColor isEqual:expectedColor]);
193
 - (void)testShowOverlay_invokeNavigationCommandEventWithLayout {
193
 - (void)testShowOverlay_invokeNavigationCommandEventWithLayout {
194
 	[self.uut setReadyToReceiveCommands:true];
194
 	[self.uut setReadyToReceiveCommands:true];
195
 	OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]);
195
 	OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]);
196
-	id mockedVC = [OCMockObject partialMockForObject:self.vc1];	
196
+	id mockedVC = [OCMockObject partialMockForObject:self.vc1];
197
 	OCMStub([self.controllerFactory createLayout:[OCMArg any]]).andReturn(mockedVC);
197
 	OCMStub([self.controllerFactory createLayout:[OCMArg any]]).andReturn(mockedVC);
198
 	
198
 	
199
 	NSDictionary* layout = @{};
199
 	NSDictionary* layout = @{};
216
 	[self.uut setReadyToReceiveCommands:true];
216
 	[self.uut setReadyToReceiveCommands:true];
217
 	NSString* componentId = @"componentId";
217
 	NSString* componentId = @"componentId";
218
 	UIViewController* returnedView = [UIViewController new];
218
 	UIViewController* returnedView = [UIViewController new];
219
-
219
+	
220
 	id classMock = OCMClassMock([RNNLayoutManager class]);
220
 	id classMock = OCMClassMock([RNNLayoutManager class]);
221
 	OCMStub(ClassMethod([classMock findComponentForId:componentId])).andReturn(returnedView);
221
 	OCMStub(ClassMethod([classMock findComponentForId:componentId])).andReturn(returnedView);
222
-
222
+	
223
 	[[self.overlayManager expect] dismissOverlay:returnedView];
223
 	[[self.overlayManager expect] dismissOverlay:returnedView];
224
 	[self.uut dismissOverlay:componentId commandId:@"" completion:^{} rejection:^(NSString *code, NSString *message, NSError *error) {}];
224
 	[self.uut dismissOverlay:componentId commandId:@"" completion:^{} rejection:^(NSString *code, NSString *message, NSError *error) {}];
225
 	[self.overlayManager verify];
225
 	[self.overlayManager verify];
289
 	XCTAssertTrue([_nvc.viewControllers isEqual:newViewControllers]);
289
 	XCTAssertTrue([_nvc.viewControllers isEqual:newViewControllers]);
290
 }
290
 }
291
 
291
 
292
+- (void)testSetStackRoot_callRenderTreeAndWaitOnce {
293
+	id vc1Mock = OCMPartialMock(_vc1);
294
+	id vc2Mock = OCMPartialMock(_vc2);
295
+	NSArray* newViewControllers = @[vc1Mock, vc2Mock];
296
+	id classMock = OCMClassMock([RNNLayoutManager class]);
297
+	OCMStub(ClassMethod([classMock findComponentForId:@"vc1"])).andReturn(_nvc);
298
+	OCMStub([self.controllerFactory createChildrenLayout:[OCMArg any]]).andReturn(newViewControllers);
299
+	[self.uut setReadyToReceiveCommands:true];
300
+	[self.uut setStackRoot:@"vc1" commandId:@"" children:nil completion:^{
301
+		
302
+	} rejection:^(NSString *code, NSString *message, NSError *error) {
303
+		
304
+	}];
305
+	
306
+	[[vc1Mock expect] renderTreeAndWait:NO perform:[OCMArg any]];
307
+	[[vc2Mock expect] renderTreeAndWait:NO perform:[OCMArg any]];
308
+}
309
+
310
+- (void)testSetStackRoot_waitForRender {
311
+	_vc2.options.animations.setStackRoot.waitForRender = [[Bool alloc] initWithBOOL:YES];
312
+	id vc1Mock = OCMPartialMock(_vc1);
313
+	id vc2Mock = OCMPartialMock(_vc2);
314
+	OCMStub([vc2Mock renderTreeAndWait:YES perform:[OCMArg any]]);
315
+	NSArray* newViewControllers = @[vc1Mock, vc2Mock];
316
+	id classMock = OCMClassMock([RNNLayoutManager class]);
317
+	OCMStub(ClassMethod([classMock findComponentForId:@"vc1"])).andReturn(_nvc);
318
+	OCMStub([self.controllerFactory createChildrenLayout:[OCMArg any]]).andReturn(newViewControllers);
319
+	[self.uut setReadyToReceiveCommands:true];
320
+	[self.uut setStackRoot:@"vc1" commandId:@"" children:nil completion:^{
321
+		
322
+	} rejection:^(NSString *code, NSString *message, NSError *error) {
323
+		
324
+	}];
325
+	
326
+	[[vc1Mock expect] renderTreeAndWait:NO perform:[OCMArg any]];
327
+	[[vc2Mock expect] renderTreeAndWait:YES perform:[OCMArg any]];
328
+}
329
+
292
 - (void)testSetRoot_waitForRenderTrue {
330
 - (void)testSetRoot_waitForRenderTrue {
293
 	[self.uut setReadyToReceiveCommands:true];
331
 	[self.uut setReadyToReceiveCommands:true];
294
 	self.vc1.options = [[RNNNavigationOptions alloc] initEmptyOptions];
332
 	self.vc1.options = [[RNNNavigationOptions alloc] initEmptyOptions];