5 #import <Foundation/Foundation.h>
6 #import <OCMock/OCMock.h>
7 #import <XCTest/XCTest.h>
9 #import <objc/runtime.h>
11 #import "flutter/common/settings.h"
12 #include "flutter/fml/synchronization/sync_switch.h"
15 #import "flutter/shell/platform/darwin/common/test_utils_swift/test_utils_swift.h"
16 #import "flutter/shell/platform/darwin/ios/InternalFlutterSwift/InternalFlutterSwift.h"
36 + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
41 @property(nonatomic) BOOL ensureSemanticsEnabledCalled;
47 _ensureSemanticsEnabledCalled = YES;
61 @property(nonatomic, assign) BOOL failOnDealloc;
67 XCTFail(
"FakeBinaryMessageRelay should not be deallocated");
89 - (void)testShellGetters {
95 XCTAssertNil(
engine.platformTaskRunner);
96 XCTAssertNil(
engine.uiTaskRunner);
97 XCTAssertNil(
engine.rasterTaskRunner);
100 - (void)testTaskRunnerPropertyStability {
107 XCTAssertNotNil(
engine.platformTaskRunner);
108 XCTAssertEqual(
engine.platformTaskRunner,
engine.platformTaskRunner);
109 XCTAssertNotNil(
engine.uiTaskRunner);
110 XCTAssertEqual(
engine.uiTaskRunner,
engine.uiTaskRunner);
111 XCTAssertNotNil(
engine.rasterTaskRunner);
112 XCTAssertEqual(
engine.rasterTaskRunner,
engine.rasterTaskRunner);
115 - (void)testInfoPlist {
117 NSURL* flutterFrameworkURL =
118 [NSBundle.mainBundle.privateFrameworksURL URLByAppendingPathComponent:@"Flutter.framework"];
119 NSBundle* flutterBundle = [NSBundle bundleWithURL:flutterFrameworkURL];
120 XCTAssertEqualObjects(flutterBundle.bundleIdentifier,
@"io.flutter.flutter");
122 NSDictionary<NSString*, id>* infoDictionary = flutterBundle.infoDictionary;
125 NSError* regexError = NULL;
126 NSRegularExpression* osVersionRegex =
127 [NSRegularExpression regularExpressionWithPattern:@"((0|[1-9]\\d*)\\.)*(0|[1-9]\\d*)"
128 options:NSRegularExpressionCaseInsensitive
130 XCTAssertNil(regexError);
133 NSString* testString =
@"9";
134 NSUInteger versionMatches =
135 [osVersionRegex numberOfMatchesInString:testString
136 options:NSMatchingAnchored
137 range:NSMakeRange(0, testString.length)];
138 XCTAssertEqual(versionMatches, 1UL);
140 versionMatches = [osVersionRegex numberOfMatchesInString:testString
141 options:NSMatchingAnchored
142 range:NSMakeRange(0, testString.length)];
143 XCTAssertEqual(versionMatches, 1UL);
144 testString =
@"9.0.1";
145 versionMatches = [osVersionRegex numberOfMatchesInString:testString
146 options:NSMatchingAnchored
147 range:NSMakeRange(0, testString.length)];
148 XCTAssertEqual(versionMatches, 1UL);
149 testString =
@".0.1";
150 versionMatches = [osVersionRegex numberOfMatchesInString:testString
151 options:NSMatchingAnchored
152 range:NSMakeRange(0, testString.length)];
153 XCTAssertEqual(versionMatches, 0UL);
156 NSString* minimumOSVersion = infoDictionary[@"MinimumOSVersion"];
157 versionMatches = [osVersionRegex numberOfMatchesInString:minimumOSVersion
158 options:NSMatchingAnchored
159 range:NSMakeRange(0, minimumOSVersion.length)];
160 XCTAssertEqual(versionMatches, 1UL);
163 XCTAssertEqual(((NSString*)infoDictionary[
@"FlutterEngine"]).length, 40UL);
168 XCTAssertTrue(((NSString*)infoDictionary[
@"ClangVersion"]).length > 15UL);
171 - (void)testDeallocated {
177 XCTAssertNotNil(weakEngine);
179 XCTAssertNil(weakEngine);
182 - (void)testSendMessageBeforeRun {
186 XCTAssertThrows([
engine.binaryMessenger
188 message:[
@"bar" dataUsingEncoding:NSUTF8StringEncoding]
192 - (void)testSetMessageHandlerBeforeRun {
196 XCTAssertThrows([
engine.binaryMessenger
197 setMessageHandlerOnChannel:
@"foo"
203 - (void)testNilSetMessageHandlerBeforeRun {
207 XCTAssertNoThrow([
engine.binaryMessenger setMessageHandlerOnChannel:
@"foo"
208 binaryMessageHandler:nil]);
211 - (void)testNotifyPluginOfDealloc {
213 OCMStub([plugin detachFromEngineForRegistrar:[OCMArg any]]);
218 [registrar publish:plugin];
220 OCMVerify([plugin detachFromEngineForRegistrar:[OCMArg any]]);
223 - (void)testGetViewControllerFromRegistrar {
226 id mockEngine = OCMPartialMock(
engine);
227 NSObject<FlutterPluginRegistrar>* registrar = [mockEngine registrarForPlugin:@"plugin"];
234 - (void)testSetBinaryMessengerToSameBinaryMessenger {
248 - (void)testRunningInitialRouteSendsNavigationMessage {
261 NSData* encodedSetInitialRouteMethod =
263 OCMVerify([mockBinaryMessenger sendOnChannel:
@"flutter/navigation"
264 message:encodedSetInitialRouteMethod]);
267 - (void)testInitialRouteSettingsSendsNavigationMessage {
271 settings.route =
"test";
281 NSData* encodedSetInitialRouteMethod =
283 OCMVerify([mockBinaryMessenger sendOnChannel:
@"flutter/navigation"
284 message:encodedSetInitialRouteMethod]);
287 - (void)testPlatformViewsControllerRenderingMetalBackend {
295 - (void)testWaitForFirstFrameTimeout {
298 XCTestExpectation* timeoutFirstFrame = [
self expectationWithDescription:@"timeoutFirstFrame"];
301 if (timeoutFirstFrame) {
302 [timeoutFirstFrame fulfill];
305 [
self waitForExpectations:@[ timeoutFirstFrame ]];
315 XCTAssertNotNil(spawn);
318 - (void)testEngineId {
321 int64_t id1 =
engine.engineIdentifier;
322 XCTAssertTrue(id1 != 0);
327 int64_t id2 = spawn.engineIdentifier;
329 XCTAssertEqual([
FlutterEngine engineForIdentifier:id2], spawn);
332 - (void)testSetHandlerAfterRun {
334 XCTestExpectation* gotMessage = [
self expectationWithDescription:@"gotMessage"];
335 dispatch_async(dispatch_get_main_queue(), ^{
337 fml::AutoResetWaitableEvent latch;
339 flutter::Shell& shell =
engine.shell;
340 fml::TaskRunner::RunNowOrPostTask(
341 engine.shell.GetTaskRunners().GetUITaskRunner(), [&latch, &shell] {
342 flutter::Engine::Delegate& delegate = shell;
343 auto message = std::make_unique<flutter::PlatformMessage>(
"foo", nullptr);
344 delegate.OnEngineHandlePlatformMessage(std::move(message));
348 [registrar.messenger setMessageHandlerOnChannel:@"foo"
349 binaryMessageHandler:^(NSData* message, FlutterBinaryReply reply) {
350 [gotMessage fulfill];
353 [
self waitForExpectations:@[ gotMessage ]];
356 - (void)testThreadPrioritySetCorrectly {
357 XCTestExpectation* prioritiesSet = [
self expectationWithDescription:@"prioritiesSet"];
358 prioritiesSet.expectedFulfillmentCount = 2;
360 IMP mockSetThreadPriority =
361 imp_implementationWithBlock(^(NSThread* thread,
double threadPriority) {
362 if ([thread.name hasSuffix:
@".raster"]) {
363 XCTAssertEqual(threadPriority, 1.0);
364 [prioritiesSet fulfill];
365 }
else if ([thread.name hasSuffix:
@".io"]) {
366 XCTAssertEqual(threadPriority, 0.5);
367 [prioritiesSet fulfill];
370 Method method = class_getInstanceMethod([NSThread
class],
@selector(setThreadPriority:));
371 IMP originalSetThreadPriority = method_getImplementation(method);
372 method_setImplementation(method, mockSetThreadPriority);
376 [
self waitForExpectations:@[ prioritiesSet ]];
378 method_setImplementation(method, originalSetThreadPriority);
381 - (void)testCanEnableDisableEmbedderAPIThroughInfoPlist {
385 settings.enable_software_rendering =
true;
388 XCTAssertFalse(
engine.enableEmbedderAPI);
392 id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
393 OCMStub([mockMainBundle objectForInfoDictionaryKey:
@"FLTEnableIOSEmbedderAPI"])
396 settings.enable_software_rendering =
true;
399 XCTAssertTrue(
engine.enableEmbedderAPI);
403 - (void)testFlutterTextInputViewDidResignFirstResponderWillCallTextInputClientConnectionClosed {
408 [engine flutterTextInputView:nil didResignFirstResponderWithTextInputClient:1];
413 OCMVerify([mockBinaryMessenger sendOnChannel:
@"flutter/textinput" message:encodedMethodCall]);
416 - (void)testFlutterEngineUpdatesDisplays {
418 id mockEngine = OCMPartialMock(
engine);
421 OCMVerify(times(1), [mockEngine updateDisplays]);
422 engine.viewController = nil;
423 OCMVerify(times(2), [mockEngine updateDisplays]);
426 - (void)testLifeCycleNotificationDidEnterBackgroundForApplication {
430 NSNotification* sceneNotification =
431 [NSNotification notificationWithName:UISceneDidEnterBackgroundNotification
434 NSNotification* applicationNotification =
435 [NSNotification notificationWithName:UIApplicationDidEnterBackgroundNotification
438 id mockEngine = OCMPartialMock(
engine);
439 [NSNotificationCenter.defaultCenter postNotification:sceneNotification];
440 [NSNotificationCenter.defaultCenter postNotification:applicationNotification];
441 OCMVerify(times(1), [mockEngine applicationDidEnterBackground:[OCMArg any]]);
442 XCTAssertTrue(
engine.isGpuDisabled);
443 BOOL gpuDisabled = NO;
444 [engine
shell].GetIsGpuDisabledSyncSwitch()->Execute(
445 fml::SyncSwitch::Handlers().SetIfTrue([&] { gpuDisabled = YES; }).SetIfFalse([&] {
448 XCTAssertTrue(gpuDisabled);
451 - (void)testLifeCycleNotificationDidEnterBackgroundForScene {
452 id mockBundle = OCMPartialMock([NSBundle mainBundle]);
453 OCMStub([mockBundle objectForInfoDictionaryKey:
@"NSExtension"]).andReturn(@{
454 @"NSExtensionPointIdentifier" :
@"com.apple.share-services"
459 NSNotification* sceneNotification =
460 [NSNotification notificationWithName:UISceneDidEnterBackgroundNotification
463 NSNotification* applicationNotification =
464 [NSNotification notificationWithName:UIApplicationDidEnterBackgroundNotification
467 id mockEngine = OCMPartialMock(
engine);
468 [NSNotificationCenter.defaultCenter postNotification:sceneNotification];
469 [NSNotificationCenter.defaultCenter postNotification:applicationNotification];
470 OCMVerify(times(1), [mockEngine sceneDidEnterBackground:[OCMArg any]]);
471 XCTAssertTrue(
engine.isGpuDisabled);
472 BOOL gpuDisabled = NO;
473 [engine
shell].GetIsGpuDisabledSyncSwitch()->Execute(
474 fml::SyncSwitch::Handlers().SetIfTrue([&] { gpuDisabled = YES; }).SetIfFalse([&] {
477 XCTAssertTrue(gpuDisabled);
478 [mockBundle stopMocking];
481 - (void)testLifeCycleNotificationWillEnterForegroundForApplication {
485 NSNotification* sceneNotification =
486 [NSNotification notificationWithName:UISceneWillEnterForegroundNotification
489 NSNotification* applicationNotification =
490 [NSNotification notificationWithName:UIApplicationWillEnterForegroundNotification
493 id mockEngine = OCMPartialMock(
engine);
494 [NSNotificationCenter.defaultCenter postNotification:sceneNotification];
495 [NSNotificationCenter.defaultCenter postNotification:applicationNotification];
496 OCMVerify(times(1), [mockEngine applicationWillEnterForeground:[OCMArg any]]);
497 XCTAssertFalse(
engine.isGpuDisabled);
498 BOOL gpuDisabled = YES;
499 [engine
shell].GetIsGpuDisabledSyncSwitch()->Execute(
500 fml::SyncSwitch::Handlers().SetIfTrue([&] { gpuDisabled = YES; }).SetIfFalse([&] {
503 XCTAssertFalse(gpuDisabled);
506 - (void)testLifeCycleNotificationWillEnterForegroundForScene {
507 id mockBundle = OCMPartialMock([NSBundle mainBundle]);
508 OCMStub([mockBundle objectForInfoDictionaryKey:
@"NSExtension"]).andReturn(@{
509 @"NSExtensionPointIdentifier" :
@"com.apple.share-services"
514 NSNotification* sceneNotification =
515 [NSNotification notificationWithName:UISceneWillEnterForegroundNotification
518 NSNotification* applicationNotification =
519 [NSNotification notificationWithName:UIApplicationWillEnterForegroundNotification
522 id mockEngine = OCMPartialMock(
engine);
523 [NSNotificationCenter.defaultCenter postNotification:sceneNotification];
524 [NSNotificationCenter.defaultCenter postNotification:applicationNotification];
525 OCMVerify(times(1), [mockEngine sceneWillEnterForeground:[OCMArg any]]);
526 XCTAssertFalse(
engine.isGpuDisabled);
527 BOOL gpuDisabled = YES;
528 [engine
shell].GetIsGpuDisabledSyncSwitch()->Execute(
529 fml::SyncSwitch::Handlers().SetIfTrue([&] { gpuDisabled = YES; }).SetIfFalse([&] {
532 XCTAssertFalse(gpuDisabled);
533 [mockBundle stopMocking];
536 - (void)testLifeCycleNotificationSceneWillConnect {
540 id mockScene = OCMClassMock([UIWindowScene
class]);
543 OCMStub([mockScene delegate]).andReturn(mockLifecycleProvider);
544 OCMStub([mockLifecycleProvider sceneLifeCycleDelegate]).andReturn(mockLifecycleDelegate);
546 NSNotification* sceneNotification =
547 [NSNotification notificationWithName:UISceneWillConnectNotification
551 [NSNotificationCenter.defaultCenter postNotification:sceneNotification];
552 OCMVerify(times(1), [mockLifecycleDelegate
engine:
engine
553 receivedConnectNotificationFor:mockScene]);
556 - (void)testSpawnsShareGpuContext {
563 XCTAssertNotNil(spawn);
564 XCTAssertTrue(
engine.platformView !=
nullptr);
566 std::shared_ptr<flutter::IOSContext> engine_context =
engine.platformView->GetIosContext();
568 XCTAssertEqual(engine_context, spawn_context);
571 - (void)testEnableSemanticsWhenFlutterViewAccessibilityDidCall {
573 engine.ensureSemanticsEnabledCalled = NO;
574 [engine flutterViewAccessibilityDidCall];
575 XCTAssertTrue(
engine.ensureSemanticsEnabledCalled);
578 - (void)testCanMergePlatformAndUIThread {
579 #if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
585 XCTAssertEqual(
engine.shell.GetTaskRunners().GetUITaskRunner(),
586 engine.shell.GetTaskRunners().GetPlatformTaskRunner());
590 - (void)testCanUnMergePlatformAndUIThread {
591 #if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
593 settings.merged_platform_ui_thread = flutter::Settings::MergedPlatformUIThread::kDisabled;
598 XCTAssertNotEqual(
engine.shell.GetTaskRunners().GetUITaskRunner(),
599 engine.shell.GetTaskRunners().GetPlatformTaskRunner());
603 - (void)testAddSceneDelegateToRegistrar {
606 id mockEngine = OCMPartialMock(
engine);
607 NSObject<FlutterPluginRegistrar>* registrar = [mockEngine registrarForPlugin:@"plugin"];
609 [registrar addSceneDelegate:mockPlugin];
611 OCMVerify(times(1), [mockEngine addSceneLifeCycleDelegate:[OCMArg any]]);
614 - (void)testNotifyAppDelegateOfEngineInitialization {
618 id mockApplication = OCMClassMock([UIApplication
class]);
619 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
621 OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
623 [engine performImplicitEngineCallback];
624 OCMVerify(times(1), [mockAppDelegate didInitializeImplicitFlutterEngine:[OCMArg any]]);
627 - (void)testRegistrarForPlugin {
635 OCMStub([mockEngine
viewController]).andReturn(mockViewController);
636 OCMStub([mockEngine binaryMessenger]).andReturn(mockBinaryMessenger);
637 OCMStub([mockEngine textureRegistry]).andReturn(mockTextureRegistry);
638 OCMStub([mockEngine platformViewsController]).andReturn(mockPlatformViewController);
640 NSString* pluginKey =
@"plugin";
641 NSString* assetKey =
@"asset";
642 NSString* factoryKey =
@"platform_view_factory";
644 NSObject<FlutterPluginRegistrar>* registrar = [mockEngine
registrarForPlugin:pluginKey];
646 XCTAssertTrue([registrar respondsToSelector:
@selector(messenger)]);
647 XCTAssertTrue([registrar respondsToSelector:
@selector(textures)]);
648 XCTAssertTrue([registrar respondsToSelector:
@selector(registerViewFactory:withId:)]);
649 XCTAssertTrue([registrar
650 respondsToSelector:
@selector(registerViewFactory:withId:gestureRecognizersBlockingPolicy:)]);
651 XCTAssertTrue([registrar respondsToSelector:
@selector(
viewController)]);
652 XCTAssertTrue([registrar respondsToSelector:
@selector(publish:)]);
653 XCTAssertTrue([registrar respondsToSelector:
@selector(valuePublishedByPlugin:)]);
654 XCTAssertTrue([registrar respondsToSelector:
@selector(addMethodCallDelegate:channel:)]);
655 XCTAssertTrue([registrar respondsToSelector:
@selector(addApplicationDelegate:)]);
656 XCTAssertTrue([registrar respondsToSelector:
@selector(lookupKeyForAsset:)]);
657 XCTAssertTrue([registrar respondsToSelector:
@selector(lookupKeyForAsset:fromPackage:)]);
660 XCTAssertEqual(registrar.messenger, mockBinaryMessenger);
661 XCTAssertEqual(registrar.textures, mockTextureRegistry);
662 XCTAssertEqual(registrar.viewController, mockViewController);
667 [registrar registerViewFactory:mockPlatformViewFactory withId:factoryKey];
668 [registrar registerViewFactory:mockPlatformViewFactory
670 gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager];
671 OCMVerify(times(2), [mockPlatformViewController registerViewFactory:mockPlatformViewFactory
673 gestureRecognizersBlockingPolicy:
678 [registrar publish:plugin];
682 id published = [registrar valuePublishedByPlugin:pluginKey];
683 XCTAssertEqual(plugin, published);
686 [registrar lookupKeyForAsset:assetKey];
687 OCMVerify(times(1), [mockEngine lookupKeyForAsset:assetKey]);
688 [registrar lookupKeyForAsset:assetKey fromPackage:pluginKey];
689 OCMVerify(times(1), [mockEngine lookupKeyForAsset:assetKey fromPackage:pluginKey]);
692 - (void)testRegistrarForApplication {
700 OCMStub([mockEngine
viewController]).andReturn(mockViewController);
701 OCMStub([mockEngine binaryMessenger]).andReturn(mockBinaryMessenger);
702 OCMStub([mockEngine textureRegistry]).andReturn(mockTextureRegistry);
703 OCMStub([mockEngine platformViewsController]).andReturn(mockPlatformViewController);
705 NSString* pluginKey =
@"plugin";
706 NSString* factoryKey =
@"platform_view_factory";
708 NSObject<FlutterApplicationRegistrar>* registrar = [mockEngine registrarForApplication:pluginKey];
710 XCTAssertTrue([registrar respondsToSelector:
@selector(messenger)]);
711 XCTAssertTrue([registrar respondsToSelector:
@selector(textures)]);
712 XCTAssertTrue([registrar respondsToSelector:
@selector(registerViewFactory:withId:)]);
713 XCTAssertTrue([registrar
714 respondsToSelector:
@selector(registerViewFactory:withId:gestureRecognizersBlockingPolicy:)]);
715 XCTAssertFalse([registrar respondsToSelector:
@selector(
viewController)]);
716 XCTAssertFalse([registrar respondsToSelector:
@selector(publish:)]);
717 XCTAssertFalse([registrar respondsToSelector:
@selector(valuePublishedByPlugin:)]);
718 XCTAssertFalse([registrar respondsToSelector:
@selector(addMethodCallDelegate:channel:)]);
719 XCTAssertFalse([registrar respondsToSelector:
@selector(addApplicationDelegate:)]);
720 XCTAssertFalse([registrar respondsToSelector:
@selector(lookupKeyForAsset:)]);
721 XCTAssertFalse([registrar respondsToSelector:
@selector(lookupKeyForAsset:fromPackage:)]);
724 XCTAssertEqual(registrar.messenger, mockBinaryMessenger);
725 XCTAssertEqual(registrar.textures, mockTextureRegistry);
730 [registrar registerViewFactory:mockPlatformViewFactory withId:factoryKey];
731 [registrar registerViewFactory:mockPlatformViewFactory
733 gestureRecognizersBlockingPolicy:FlutterPlatformViewGestureRecognizersBlockingPolicyEager];
734 OCMVerify(times(2), [mockPlatformViewController registerViewFactory:mockPlatformViewFactory
736 gestureRecognizersBlockingPolicy:
740 - (void)testSendDeepLinkToFrameworkTimesOut {
743 id mockEngine = OCMPartialMock(
engine);
744 id mockEngineFirstFrameCallback = [OCMArg invokeBlockWithArgs:@YES, nil];
745 OCMStub([mockEngine waitForFirstFrame:3.0 callback:mockEngineFirstFrameCallback]);
747 NSURL* url = [NSURL URLWithString:@"example.com"];
749 [mockEngine sendDeepLinkToFramework:url
750 completionHandler:^(BOOL success) {
751 XCTAssertFalse(success);
755 - (void)testSendDeepLinkToFrameworkUsingNavigationChannel {
756 NSString* urlString =
@"example.com";
757 NSURL* url = [NSURL URLWithString:urlString];
760 id mockEngine = OCMPartialMock(
engine);
761 id mockEngineFirstFrameCallback = [OCMArg invokeBlockWithArgs:@NO, nil];
762 OCMStub([mockEngine waitForFirstFrame:3.0 callback:mockEngineFirstFrameCallback]);
764 OCMStub([mockEngine navigationChannel]).andReturn(mockNavigationChannel);
765 id mockNavigationChannelCallback = [OCMArg invokeBlockWithArgs:@1, nil];
766 OCMStub([mockNavigationChannel invokeMethod:
@"pushRouteInformation"
767 arguments:@{
@"location" : urlString}
768 result:mockNavigationChannelCallback]);
770 [mockEngine sendDeepLinkToFramework:url
771 completionHandler:^(BOOL success) {
772 XCTAssertTrue(success);
776 - (void)testSendDeepLinkToFrameworkUsingNavigationChannelFails {
777 NSString* urlString =
@"example.com";
778 NSURL* url = [NSURL URLWithString:urlString];
781 id mockEngine = OCMPartialMock(
engine);
782 id mockEngineFirstFrameCallback = [OCMArg invokeBlockWithArgs:@NO, nil];
783 OCMStub([mockEngine waitForFirstFrame:3.0 callback:mockEngineFirstFrameCallback]);
785 OCMStub([mockEngine navigationChannel]).andReturn(mockNavigationChannel);
786 id mockNavigationChannelCallback = [OCMArg invokeBlockWithArgs:@0, nil];
787 OCMStub([mockNavigationChannel invokeMethod:
@"pushRouteInformation"
788 arguments:@{
@"location" : urlString}
789 result:mockNavigationChannelCallback]);
791 [mockEngine sendDeepLinkToFramework:url
792 completionHandler:^(BOOL success) {
793 XCTAssertFalse(success);
797 #pragma mark - Scene Lifecycle Warning Tests
799 - (void)testAddApplicationDelegateLogsWarningWhenPluginDoesNotConformToSceneDelegate {
800 FlutterStringOutputWriter* writer = [[FlutterStringOutputWriter alloc] init];
801 writer.expectedOutput =
@"uses deprecated application lifecycle events";
802 FlutterLogger.outputWriter = writer;
811 id mockApplication = OCMClassMock([UIApplication
class]);
812 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
813 OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
815 [registrar addApplicationDelegate:mockPlugin];
817 XCTAssertTrue(writer.gotExpectedOutput,
818 @"Expected warning about plugin not adopting scenes was not logged");
821 - (void)testAddApplicationDelegateDoesNotLogWarningWhenPluginConformsToSceneDelegate {
822 FlutterStringOutputWriter* writer = [[FlutterStringOutputWriter alloc] init];
823 FlutterLogger.outputWriter = writer;
826 id<FlutterPluginRegistrar> registrar = [engine
registrarForPlugin:@"TestPluginWithSceneEvents"];
831 id mockApplication = OCMClassMock([UIApplication
class]);
832 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
833 OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
835 [registrar addApplicationDelegate:mockPlugin];
837 XCTAssertFalse(writer.didLog,
@"No warning should be logged for scene-conforming plugin");
840 - (void)testAddApplicationDelegateDoesNotLogWarningWhenPluginDoesNotUseLifecycleEvents {
841 FlutterStringOutputWriter* writer = [[FlutterStringOutputWriter alloc] init];
842 FlutterLogger.outputWriter = writer;
853 id mockApplication = OCMClassMock([UIApplication
class]);
854 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
855 OCMStub([mockApplication delegate]).andReturn(mockAppDelegate);
857 [registrar addApplicationDelegate:plugin];
859 XCTAssertFalse(writer.didLog,
860 @"No warning should be logged for a plugin that doesn't use lifecycle events");
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterBinaryReply)(NSData *_Nullable reply)
flutter::Settings FLTDefaultSettingsForBundle(NSBundle *bundle, NSProcessInfo *processInfoOrNil)
@ FlutterPlatformViewGestureRecognizersBlockingPolicyEager
FlutterViewController * viewController
flutter::PlatformViewIOS * platformView()
FlutterEngine * spawnWithEntrypoint:libraryURI:initialRoute:entrypointArgs:(/*nullable */NSString *entrypoint,[libraryURI]/*nullable */NSString *libraryURI,[initialRoute]/*nullable */NSString *initialRoute,[entrypointArgs]/*nullable */NSArray< NSString * > *entrypointArgs)
void setBinaryMessenger:(FlutterBinaryMessengerRelay *binaryMessenger)
flutter::IOSRenderingAPI platformViewsRenderingAPI()
BOOL runWithEntrypoint:initialRoute:(nullable NSString *entrypoint,[initialRoute] nullable NSString *initialRoute)
NSMutableDictionary * pluginPublications
void ensureSemanticsEnabled()
void waitForFirstFrame:callback:(NSTimeInterval timeout,[callback] void(^ callback)(BOOL didTimeout))
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
nullable NSObject< FlutterPluginRegistrar > * registrarForPlugin:(NSString *pluginKey)