From 72be4b927dc6e0cccb25e4e9f0bf0559981e1d88 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 11 Dec 2020 11:46:00 -0800 Subject: [PATCH 1/2] Started tearing down the mock engine in tearDown in FlutterViewControllerTest. --- .../Source/FlutterViewControllerTest.mm | 137 +++++++----------- 1 file changed, 51 insertions(+), 86 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index 06007d72c4d9f..678c765019bf3 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -43,6 +43,7 @@ - (void)setViewController:(FlutterViewController*)viewController { @end @interface FlutterViewControllerTest : XCTestCase +@property(nonatomic, strong) id mockEngine; @end // The following conditional compilation defines an API 13 concept on earlier API targets so that @@ -67,68 +68,62 @@ - (void)dispatchPresses:(NSSet*)presses; @implementation FlutterViewControllerTest +- (void)setUp { + self.mockEngine = OCMClassMock([FlutterEngine class]); +} + +- (void)tearDown { + [self.mockEngine stopMocking]; + self.mockEngine = nil; +} + - (void)testViewDidDisappearDoesntPauseEngineWhenNotTheViewController { - id engine = OCMClassMock([FlutterEngine class]); id lifecycleChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine lifecycleChannel]).andReturn(lifecycleChannel); - FlutterViewController* viewControllerA = [[FlutterViewController alloc] initWithEngine:engine - nibName:nil - bundle:nil]; - FlutterViewController* viewControllerB = [[FlutterViewController alloc] initWithEngine:engine - nibName:nil - bundle:nil]; + OCMStub([self.mockEngine lifecycleChannel]).andReturn(lifecycleChannel); + FlutterViewController* viewControllerA = + [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; + FlutterViewController* viewControllerB = + [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; id viewControllerMock = OCMPartialMock(viewControllerA); OCMStub([viewControllerMock surfaceUpdated:NO]); - OCMStub([engine viewController]).andReturn(viewControllerB); + OCMStub([self.mockEngine viewController]).andReturn(viewControllerB); [viewControllerA viewDidDisappear:NO]; OCMReject([lifecycleChannel sendMessage:@"AppLifecycleState.paused"]); OCMReject([viewControllerMock surfaceUpdated:[OCMArg any]]); } - (void)testViewDidDisappearDoesPauseEngineWhenIsTheViewController { - id engine = OCMClassMock([FlutterEngine class]); id lifecycleChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine lifecycleChannel]).andReturn(lifecycleChannel); - FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine - nibName:nil - bundle:nil]; + OCMStub([self.mockEngine lifecycleChannel]).andReturn(lifecycleChannel); + FlutterViewController* viewController = + [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; id viewControllerMock = OCMPartialMock(viewController); OCMStub([viewControllerMock surfaceUpdated:NO]); - OCMStub([engine viewController]).andReturn(viewController); + OCMStub([self.mockEngine viewController]).andReturn(viewController); [viewController viewDidDisappear:NO]; OCMVerify([lifecycleChannel sendMessage:@"AppLifecycleState.paused"]); OCMVerify([viewControllerMock surfaceUpdated:NO]); } - (void)testBinaryMessenger { - __weak FlutterViewController* weakVC; - @autoreleasepool { - id engine = OCMClassMock([FlutterEngine class]); - FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine - nibName:nil - bundle:nil]; - XCTAssertNotNil(vc); - weakVC = vc; - id messenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); - OCMStub([engine binaryMessenger]).andReturn(messenger); - XCTAssertEqual(vc.binaryMessenger, messenger); - OCMVerify([engine binaryMessenger]); - // This had to be added to make sure the view controller is deleted. - [engine stopMocking]; - } - XCTAssertNil(weakVC); + FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine + nibName:nil + bundle:nil]; + XCTAssertNotNil(vc); + id messenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); + OCMStub([self.mockEngine binaryMessenger]).andReturn(messenger); + XCTAssertEqual(vc.binaryMessenger, messenger); + OCMVerify([self.mockEngine binaryMessenger]); } #pragma mark - Platform Brightness - (void)testItReportsLightPlatformBrightnessByDefault { // Setup test. - id engine = OCMClassMock([FlutterEngine class]); - id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine settingsChannel]).andReturn(settingsChannel); + OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel); - FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine + FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; @@ -141,18 +136,15 @@ - (void)testItReportsLightPlatformBrightnessByDefault { }]]); // Clean up mocks - [engine stopMocking]; [settingsChannel stopMocking]; } - (void)testItReportsPlatformBrightnessWhenViewWillAppear { // Setup test. - id engine = OCMClassMock([FlutterEngine class]); - id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine settingsChannel]).andReturn(settingsChannel); + OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel); - FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine + FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; @@ -165,7 +157,6 @@ - (void)testItReportsPlatformBrightnessWhenViewWillAppear { }]]); // Clean up mocks - [engine stopMocking]; [settingsChannel stopMocking]; } @@ -177,12 +168,10 @@ - (void)testItReportsDarkPlatformBrightnessWhenTraitCollectionRequestsIt { } // Setup test. - id engine = OCMClassMock([FlutterEngine class]); - id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine settingsChannel]).andReturn(settingsChannel); + OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel); - FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine + FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; id mockTraitCollection = @@ -205,7 +194,6 @@ - (void)testItReportsDarkPlatformBrightnessWhenTraitCollectionRequestsIt { // Clean up mocks [partialMockVC stopMocking]; - [engine stopMocking]; [settingsChannel stopMocking]; [mockTraitCollection stopMocking]; } @@ -228,12 +216,10 @@ - (void)testItReportsNormalPlatformContrastByDefault { } // Setup test. - id engine = OCMClassMock([FlutterEngine class]); - id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine settingsChannel]).andReturn(settingsChannel); + OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel); - FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine + FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; @@ -246,7 +232,6 @@ - (void)testItReportsNormalPlatformContrastByDefault { }]]); // Clean up mocks - [engine stopMocking]; [settingsChannel stopMocking]; } @@ -258,12 +243,10 @@ - (void)testItReportsPlatformContrastWhenViewWillAppear { } // Setup test. - id engine = OCMClassMock([FlutterEngine class]); - id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine settingsChannel]).andReturn(settingsChannel); + OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel); - FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine + FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; @@ -276,7 +259,6 @@ - (void)testItReportsPlatformContrastWhenViewWillAppear { }]]); // Clean up mocks - [engine stopMocking]; [settingsChannel stopMocking]; } @@ -288,12 +270,10 @@ - (void)testItReportsHighContrastWhenTraitCollectionRequestsIt { } // Setup test. - id engine = OCMClassMock([FlutterEngine class]); - id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine settingsChannel]).andReturn(settingsChannel); + OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel); - FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine + FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; id mockTraitCollection = [self fakeTraitCollectionWithContrast:UIAccessibilityContrastHigh]; @@ -315,7 +295,6 @@ - (void)testItReportsHighContrastWhenTraitCollectionRequestsIt { // Clean up mocks [partialMockVC stopMocking]; - [engine stopMocking]; [settingsChannel stopMocking]; [mockTraitCollection stopMocking]; } @@ -470,8 +449,6 @@ - (void)orientationTestWithOrientationUpdate:(UIInterfaceOrientationMask)mask currentOrientation:(UIInterfaceOrientation)currentOrientation didChangeOrientation:(BOOL)didChange resultingOrientation:(UIInterfaceOrientation)resultingOrientation { - id engine = OCMClassMock([FlutterEngine class]); - id deviceMock = OCMPartialMock([UIDevice currentDevice]); if (!didChange) { OCMReject([deviceMock setValue:[OCMArg any] forKey:@"orientation"]); @@ -479,7 +456,7 @@ - (void)orientationTestWithOrientationUpdate:(UIInterfaceOrientationMask)mask OCMExpect([deviceMock setValue:@(resultingOrientation) forKey:@"orientation"]); } - FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine + FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; id mockApplication = OCMClassMock([UIApplication class]); @@ -488,7 +465,6 @@ - (void)orientationTestWithOrientationUpdate:(UIInterfaceOrientationMask)mask [realVC performOrientationUpdate:mask]; OCMVerifyAll(deviceMock); - [engine stopMocking]; [deviceMock stopMocking]; [mockApplication stopMocking]; } @@ -544,17 +520,15 @@ - (void)testHideOverlay { } - (void)testNotifyLowMemory { - id engine = OCMClassMock([FlutterEngine class]); - FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine - nibName:nil - bundle:nil]; - OCMStub([engine viewController]).andReturn(viewController); + FlutterViewController* viewController = + [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; + OCMStub([self.mockEngine viewController]).andReturn(viewController); id viewControllerMock = OCMPartialMock(viewController); OCMStub([viewControllerMock surfaceUpdated:NO]); [viewController beginAppearanceTransition:NO animated:NO]; [viewController endAppearanceTransition]; - OCMVerify([engine notifyLowMemory]); + OCMVerify([self.mockEngine notifyLowMemory]); } - (void)testValidKeyUpEvent API_AVAILABLE(ios(13.4)) { @@ -564,12 +538,10 @@ - (void)testValidKeyUpEvent API_AVAILABLE(ios(13.4)) { return; } - id engine = OCMClassMock([FlutterEngine class]); - id keyEventChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine keyEventChannel]).andReturn(keyEventChannel); + OCMStub([self.mockEngine keyEventChannel]).andReturn(keyEventChannel); - FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine + FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; @@ -594,7 +566,6 @@ - (void)testValidKeyUpEvent API_AVAILABLE(ios(13.4)) { }]]); // Clean up mocks - [engine stopMocking]; [keyEventChannel stopMocking]; } @@ -605,12 +576,10 @@ - (void)testValidKeyDownEvent API_AVAILABLE(ios(13.4)) { return; } - id engine = OCMClassMock([FlutterEngine class]); - id keyEventChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine keyEventChannel]).andReturn(keyEventChannel); + OCMStub([self.mockEngine keyEventChannel]).andReturn(keyEventChannel); - FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine + FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; @@ -635,7 +604,6 @@ - (void)testValidKeyDownEvent API_AVAILABLE(ios(13.4)) { }]]); // Clean up mocks - [engine stopMocking]; [keyEventChannel stopMocking]; } @@ -646,12 +614,10 @@ - (void)testIgnoredKeyEvents API_AVAILABLE(ios(13.4)) { return; } - id engine = OCMClassMock([FlutterEngine class]); - id keyEventChannel = OCMClassMock([FlutterBasicMessageChannel class]); - OCMStub([engine keyEventChannel]).andReturn(keyEventChannel); + OCMStub([self.mockEngine keyEventChannel]).andReturn(keyEventChannel); - FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:engine + FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil]; @@ -674,7 +640,6 @@ - (void)testIgnoredKeyEvents API_AVAILABLE(ios(13.4)) { OCMVerify(never(), [keyEventChannel sendMessage:[OCMArg any]]); // Clean up mocks - [engine stopMocking]; [keyEventChannel stopMocking]; } From 07d80ff500bf0499662ed8ccd362194004a9700f Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 11 Dec 2020 14:06:47 -0800 Subject: [PATCH 2/2] added comment --- .../darwin/ios/framework/Source/FlutterViewControllerTest.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm index 678c765019bf3..48a1c1ee2cbd1 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewControllerTest.mm @@ -73,6 +73,8 @@ - (void)setUp { } - (void)tearDown { + // We stop mocking here to avoid retain cycles that stop + // FlutterViewControllers from deallocing. [self.mockEngine stopMocking]; self.mockEngine = nil; }