Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Started tearing down the mock engine in tearDown in FlutterViewControllerTest #23037

Merged
merged 2 commits into from
Dec 11, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -67,68 +68,64 @@ - (void)dispatchPresses:(NSSet<UIPress*>*)presses;

@implementation FlutterViewControllerTest

- (void)setUp {
self.mockEngine = OCMClassMock([FlutterEngine class]);
}

- (void)tearDown {
// We stop mocking here to avoid retain cycles that stop
// FlutterViewControllers from deallocing.
[self.mockEngine stopMocking];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment about why we're doing this - especially since we're doing it for this mock and not others?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

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];

Expand All @@ -141,18 +138,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];

Expand All @@ -165,7 +159,6 @@ - (void)testItReportsPlatformBrightnessWhenViewWillAppear {
}]]);

// Clean up mocks
[engine stopMocking];
[settingsChannel stopMocking];
}

Expand All @@ -177,12 +170,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 =
Expand All @@ -205,7 +196,6 @@ - (void)testItReportsDarkPlatformBrightnessWhenTraitCollectionRequestsIt {

// Clean up mocks
[partialMockVC stopMocking];
[engine stopMocking];
[settingsChannel stopMocking];
[mockTraitCollection stopMocking];
}
Expand All @@ -228,12 +218,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];

Expand All @@ -246,7 +234,6 @@ - (void)testItReportsNormalPlatformContrastByDefault {
}]]);

// Clean up mocks
[engine stopMocking];
[settingsChannel stopMocking];
}

Expand All @@ -258,12 +245,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];

Expand All @@ -276,7 +261,6 @@ - (void)testItReportsPlatformContrastWhenViewWillAppear {
}]]);

// Clean up mocks
[engine stopMocking];
[settingsChannel stopMocking];
}

Expand All @@ -288,12 +272,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];
Expand All @@ -315,7 +297,6 @@ - (void)testItReportsHighContrastWhenTraitCollectionRequestsIt {

// Clean up mocks
[partialMockVC stopMocking];
[engine stopMocking];
[settingsChannel stopMocking];
[mockTraitCollection stopMocking];
}
Expand Down Expand Up @@ -470,16 +451,14 @@ - (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"]);
} else {
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]);
Expand All @@ -488,7 +467,6 @@ - (void)orientationTestWithOrientationUpdate:(UIInterfaceOrientationMask)mask

[realVC performOrientationUpdate:mask];
OCMVerifyAll(deviceMock);
[engine stopMocking];
[deviceMock stopMocking];
[mockApplication stopMocking];
}
Expand Down Expand Up @@ -544,17 +522,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)) {
Expand All @@ -564,12 +540,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];

Expand All @@ -594,7 +568,6 @@ - (void)testValidKeyUpEvent API_AVAILABLE(ios(13.4)) {
}]]);

// Clean up mocks
[engine stopMocking];
[keyEventChannel stopMocking];
}

Expand All @@ -605,12 +578,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];

Expand All @@ -635,7 +606,6 @@ - (void)testValidKeyDownEvent API_AVAILABLE(ios(13.4)) {
}]]);

// Clean up mocks
[engine stopMocking];
[keyEventChannel stopMocking];
}

Expand All @@ -646,12 +616,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];

Expand All @@ -674,7 +642,6 @@ - (void)testIgnoredKeyEvents API_AVAILABLE(ios(13.4)) {
OCMVerify(never(), [keyEventChannel sendMessage:[OCMArg any]]);

// Clean up mocks
[engine stopMocking];
[keyEventChannel stopMocking];
}

Expand Down