Reland: Started waiting for the notifications locally before asserting side-effects (flutter/engine#25257)

This commit is contained in:
gaaclarke 2021-03-29 13:48:58 -07:00 committed by GitHub
parent eff2763bd5
commit 2cd1c0280c
5 changed files with 71 additions and 21 deletions

View File

@ -87,17 +87,24 @@ class MockDelegate : public PlatformView::Delegate {
OCMVerify([mockEngine notifyLowMemory]);
OCMReject([mockEngine notifyLowMemory]);
XCTNSNotificationExpectation* memoryExpectation = [[XCTNSNotificationExpectation alloc]
initWithName:UIApplicationDidReceiveMemoryWarningNotification];
[[NSNotificationCenter defaultCenter]
postNotificationName:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
[self waitForExpectations:@[ memoryExpectation ] timeout:5.0];
OCMVerify([mockEngine notifyLowMemory]);
OCMReject([mockEngine notifyLowMemory]);
XCTNSNotificationExpectation* backgroundExpectation = [[XCTNSNotificationExpectation alloc]
initWithName:UIApplicationDidEnterBackgroundNotification];
[[NSNotificationCenter defaultCenter]
postNotificationName:UIApplicationDidEnterBackgroundNotification
object:nil];
[self waitForExpectations:@[ backgroundExpectation ] timeout:5.0];
OCMVerify([mockEngine notifyLowMemory]);
[mockEngine stopMocking];
}
@end

View File

@ -11,7 +11,6 @@
FLUTTER_ASSERT_ARC
@interface FlutterPluginAppLifeCycleDelegateTest : XCTestCase
@end
@implementation FlutterPluginAppLifeCycleDelegateTest
@ -22,51 +21,71 @@ FLUTTER_ASSERT_ARC
}
- (void)testDidEnterBackground {
XCTNSNotificationExpectation* expectation = [[XCTNSNotificationExpectation alloc]
initWithName:UIApplicationDidEnterBackgroundNotification];
FlutterPluginAppLifeCycleDelegate* delegate = [[FlutterPluginAppLifeCycleDelegate alloc] init];
id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
[delegate addDelegate:plugin];
[[NSNotificationCenter defaultCenter]
postNotificationName:UIApplicationDidEnterBackgroundNotification
object:nil];
[self waitForExpectations:@[ expectation ] timeout:5.0];
OCMVerify([plugin applicationDidEnterBackground:[UIApplication sharedApplication]]);
}
- (void)testWillEnterForeground {
XCTNSNotificationExpectation* expectation = [[XCTNSNotificationExpectation alloc]
initWithName:UIApplicationWillEnterForegroundNotification];
FlutterPluginAppLifeCycleDelegate* delegate = [[FlutterPluginAppLifeCycleDelegate alloc] init];
id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
[delegate addDelegate:plugin];
[[NSNotificationCenter defaultCenter]
postNotificationName:UIApplicationWillEnterForegroundNotification
object:nil];
[self waitForExpectations:@[ expectation ] timeout:5.0];
OCMVerify([plugin applicationWillEnterForeground:[UIApplication sharedApplication]]);
}
- (void)skip_testWillResignActive {
- (void)testWillResignActive {
XCTNSNotificationExpectation* expectation =
[[XCTNSNotificationExpectation alloc] initWithName:UIApplicationWillResignActiveNotification];
FlutterPluginAppLifeCycleDelegate* delegate = [[FlutterPluginAppLifeCycleDelegate alloc] init];
id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
[delegate addDelegate:plugin];
[[NSNotificationCenter defaultCenter]
postNotificationName:UIApplicationWillResignActiveNotification
object:nil];
[self waitForExpectations:@[ expectation ] timeout:5.0];
OCMVerify([plugin applicationWillResignActive:[UIApplication sharedApplication]]);
}
- (void)skip_testDidBecomeActive {
- (void)testDidBecomeActive {
XCTNSNotificationExpectation* expectation =
[[XCTNSNotificationExpectation alloc] initWithName:UIApplicationDidBecomeActiveNotification];
FlutterPluginAppLifeCycleDelegate* delegate = [[FlutterPluginAppLifeCycleDelegate alloc] init];
id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
[delegate addDelegate:plugin];
[[NSNotificationCenter defaultCenter]
postNotificationName:UIApplicationDidBecomeActiveNotification
object:nil];
[self waitForExpectations:@[ expectation ] timeout:5.0];
OCMVerify([plugin applicationDidBecomeActive:[UIApplication sharedApplication]]);
}
- (void)testWillTerminate {
XCTNSNotificationExpectation* expectation =
[[XCTNSNotificationExpectation alloc] initWithName:UIApplicationWillTerminateNotification];
FlutterPluginAppLifeCycleDelegate* delegate = [[FlutterPluginAppLifeCycleDelegate alloc] init];
id plugin = OCMProtocolMock(@protocol(FlutterPlugin));
[delegate addDelegate:plugin];
[[NSNotificationCenter defaultCenter] postNotificationName:UIApplicationWillTerminateNotification
object:nil];
[self waitForExpectations:@[ expectation ] timeout:5.0];
OCMVerify([plugin applicationWillTerminate:[UIApplication sharedApplication]]);
}

View File

@ -885,9 +885,8 @@ FLUTTER_ASSERT_ARC
- (void)testFlutterTextInputPluginRetainsFlutterTextInputView {
FlutterTextInputPlugin* myInputPlugin;
id myEngine = OCMClassMock([FlutterEngine class]);
myInputPlugin = [[FlutterTextInputPlugin alloc] init];
myInputPlugin.textInputDelegate = myEngine;
myInputPlugin.textInputDelegate = engine;
__weak UIView* activeView;
@autoreleasepool {
FlutterMethodCall* setClientCall = [FlutterMethodCall

View File

@ -16,6 +16,22 @@ namespace flutter {
class PointerDataPacket {};
}
/// Sometimes we have to use a custom mock to avoid retain cycles in ocmock.
@interface FlutterEnginePartialMock : FlutterEngine
@property(nonatomic, strong) FlutterBasicMessageChannel* lifecycleChannel;
@property(nonatomic, weak) FlutterViewController* viewController;
@property(nonatomic, assign) BOOL didCallNotifyLowMemory;
@end
@implementation FlutterEnginePartialMock
@synthesize viewController;
@synthesize lifecycleChannel;
- (void)notifyLowMemory {
_didCallNotifyLowMemory = YES;
}
@end
@interface FlutterEngine ()
- (BOOL)createShell:(NSString*)entrypoint
libraryURI:(NSString*)libraryURI
@ -87,14 +103,15 @@ typedef enum UIAccessibilityContrast : NSInteger {
- (void)testViewDidDisappearDoesntPauseEngineWhenNotTheViewController {
id lifecycleChannel = OCMClassMock([FlutterBasicMessageChannel class]);
OCMStub([self.mockEngine lifecycleChannel]).andReturn(lifecycleChannel);
FlutterEnginePartialMock* mockEngine = [[FlutterEnginePartialMock alloc] init];
mockEngine.lifecycleChannel = 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([self.mockEngine viewController]).andReturn(viewControllerB);
mockEngine.viewController = viewControllerB;
[viewControllerA viewDidDisappear:NO];
OCMReject([lifecycleChannel sendMessage:@"AppLifecycleState.paused"]);
OCMReject([viewControllerMock surfaceUpdated:[OCMArg any]]);
@ -102,15 +119,21 @@ typedef enum UIAccessibilityContrast : NSInteger {
- (void)testViewDidDisappearDoesPauseEngineWhenIsTheViewController {
id lifecycleChannel = OCMClassMock([FlutterBasicMessageChannel class]);
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([self.mockEngine viewController]).andReturn(viewController);
[viewController viewDidDisappear:NO];
OCMVerify([lifecycleChannel sendMessage:@"AppLifecycleState.paused"]);
OCMVerify([viewControllerMock surfaceUpdated:NO]);
FlutterEnginePartialMock* mockEngine = [[FlutterEnginePartialMock alloc] init];
mockEngine.lifecycleChannel = lifecycleChannel;
__weak FlutterViewController* weakViewController;
@autoreleasepool {
FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
nibName:nil
bundle:nil];
weakViewController = viewController;
id viewControllerMock = OCMPartialMock(viewController);
OCMStub([viewControllerMock surfaceUpdated:NO]);
[viewController viewDidDisappear:NO];
OCMVerify([lifecycleChannel sendMessage:@"AppLifecycleState.paused"]);
OCMVerify([viewControllerMock surfaceUpdated:NO]);
}
XCTAssertNil(weakViewController);
}
- (void)testBinaryMessenger {
@ -528,15 +551,16 @@ typedef enum UIAccessibilityContrast : NSInteger {
}
- (void)testNotifyLowMemory {
FlutterViewController* viewController =
[[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil];
OCMStub([self.mockEngine viewController]).andReturn(viewController);
FlutterEnginePartialMock* mockEngine = [[FlutterEnginePartialMock alloc] init];
FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
nibName:nil
bundle:nil];
id viewControllerMock = OCMPartialMock(viewController);
OCMStub([viewControllerMock surfaceUpdated:NO]);
[viewController beginAppearanceTransition:NO animated:NO];
[viewController endAppearanceTransition];
OCMVerify([self.mockEngine notifyLowMemory]);
XCTAssertTrue(mockEngine.didCallNotifyLowMemory);
[viewControllerMock stopMocking];
}
- (void)testValidKeyUpEvent API_AVAILABLE(ios(13.4)) {

View File

@ -970,5 +970,6 @@ fml::RefPtr<fml::TaskRunner> CreateNewThread(std::string name) {
});
latch.Wait();
OCMVerify([messenger cleanupConnection:connection]);
[engine stopMocking];
}
@end