Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Instance Methods | Properties | List of all members
FlutterViewControllerTest Class Reference
Inheritance diagram for FlutterViewControllerTest:

Instance Methods

(void) - sendMessage:reply:
 
(void) - setUp [implementation]
 
(void) - tearDown [implementation]
 
(id- setUpMockScreen [implementation]
 
(id- setUpMockView:screen:viewFrame:convertedFrame: [implementation]
 
(void) - testViewDidLoadWillInvokeCreateTouchRateCorrectionVSyncClient [implementation]
 
(void) - testStartKeyboardAnimationWillInvokeSetupKeyboardSpringAnimationIfNeeded [implementation]
 
(void) - testSetupKeyboardSpringAnimationIfNeeded [implementation]
 
(void) - testKeyboardAnimationIsShowingAndCompounding [implementation]
 
(void) - testShouldIgnoreKeyboardNotification [implementation]
 
(void) - testKeyboardAnimationWillNotCrashWhenEngineDestroyed [implementation]
 
(void) - testKeyboardAnimationWillWaitUIThreadVsync [implementation]
 
(void) - testCalculateKeyboardAttachMode [implementation]
 
(void) - testCalculateMultitaskingAdjustment [implementation]
 
(void) - testCalculateKeyboardInset [implementation]
 
(void) - testHandleKeyboardNotification [implementation]
 
(void) - testEnsureBottomInsetIsZeroWhenKeyboardDismissed [implementation]
 
(void) - testEnsureViewportMetricsWillInvokeAndDisplayLinkWillInvalidateInViewDidDisappear [implementation]
 
(void) - testViewDidDisappearDoesntPauseEngineWhenNotTheViewController [implementation]
 
(void) - testAppWillTerminateViewDidDestroyTheEngine [implementation]
 
(void) - testViewDidDisappearDoesPauseEngineWhenIsTheViewController [implementation]
 
(void) - testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewWillAppear [implementation]
 
(void) - testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewWillAppear [implementation]
 
(void) - testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewDidAppear [implementation]
 
(void) - testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewDidAppear [implementation]
 
(void) - testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewWillDisappear [implementation]
 
(void) - testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewWillDisappear [implementation]
 
(void) - testUpdateViewportMetricsIfNeeded_DoesntInvokeEngineWhenNotTheViewController [implementation]
 
(void) - testUpdateViewportMetricsIfNeeded_DoesInvokeEngineWhenIsTheViewController [implementation]
 
(void) - testUpdateViewportMetricsIfNeeded_DoesNotInvokeEngineWhenShouldBeIgnoredDuringRotation [implementation]
 
(void) - testViewWillTransitionToSize_DoesDelayEngineCallIfNonZeroDuration [implementation]
 
(void) - testViewWillTransitionToSize_DoesNotDelayEngineCallIfZeroDuration [implementation]
 
(void) - testViewDidLoadDoesntInvokeEngineWhenNotTheViewController [implementation]
 
(void) - testViewDidLoadDoesInvokeEngineWhenIsTheViewController [implementation]
 
(void) - testViewDidLoadDoesntInvokeEngineAttachViewWhenEngineNeedsLaunch [implementation]
 
(void) - testSplashScreenViewRemoveNotCrash [implementation]
 
(void) - testInternalPluginsWeakPtrNotCrash [implementation]
 
(void) - testInternalPluginsInvokeInViewDidLoad [implementation]
 
(void) - testBinaryMessenger [implementation]
 
(void) - testViewControllerIsReleased [implementation]
 
(void) - testItReportsLightPlatformBrightnessByDefault [implementation]
 
(void) - testItReportsPlatformBrightnessWhenViewWillAppear [implementation]
 
(void) - testItReportsDarkPlatformBrightnessWhenTraitCollectionRequestsIt [implementation]
 
(UITraitCollection *) - fakeTraitCollectionWithUserInterfaceStyle: [implementation]
 
(void) - testItReportsNormalPlatformContrastByDefault [implementation]
 
(void) - testItReportsPlatformContrastWhenViewWillAppear [implementation]
 
(void) - testItReportsHighContrastWhenTraitCollectionRequestsIt [implementation]
 
(void) - testItReportsAccessibilityOnOffSwitchLabelsFlagNotSet [implementation]
 
(void) - testItReportsAccessibilityOnOffSwitchLabelsFlagSet [implementation]
 
(void) - testAccessibilityPerformEscapePopsRoute [implementation]
 
(void) - testPerformOrientationUpdateForcesOrientationChange [implementation]
 
(void) - testPerformOrientationUpdateDoesNotForceOrientationChange [implementation]
 
(void) - orientationTestWithOrientationUpdate:currentOrientation:didChangeOrientation:resultingOrientation: [implementation]
 
(UITraitCollection *) - fakeTraitCollectionWithContrast: [implementation]
 
(void) - testWillDeallocNotification [implementation]
 
(void) - testReleasesKeyboardManagerOnDealloc [implementation]
 
(void) - testDoesntLoadViewInInit [implementation]
 
(void) - testHideOverlay [implementation]
 
(void) - testNotifyLowMemory [implementation]
 
() - ios [implementation]
 
() - ios [implementation]
 
() - ios [implementation]
 
() - ios [implementation]
 
() - ios [implementation]
 
(void) - testFakeEventTimeStamp [implementation]
 
(void) - testSplashScreenViewCanSetNil [implementation]
 
(void) - testLifeCycleNotificationBecameActive [implementation]
 
(void) - testLifeCycleNotificationWillResignActive [implementation]
 
(void) - testLifeCycleNotificationWillTerminate [implementation]
 
(void) - testLifeCycleNotificationDidEnterBackground [implementation]
 
(void) - testLifeCycleNotificationWillEnterForeground [implementation]
 
(void) - testLifeCycleNotificationCancelledInvalidResumed [implementation]
 
(void) - testSetupKeyboardAnimationVsyncClientWillCreateNewVsyncClientForFlutterViewController [implementation]
 
(void) - testCreateTouchRateCorrectionVSyncClientWillCreateVsyncClientWhenRefreshRateIsLargerThan60HZ [implementation]
 
(void) - testCreateTouchRateCorrectionVSyncClientWillNotCreateNewVSyncClientWhenClientAlreadyExists [implementation]
 
(void) - testCreateTouchRateCorrectionVSyncClientWillNotCreateVsyncClientWhenRefreshRateIs60HZ [implementation]
 
(void) - testTriggerTouchRateCorrectionVSyncClientCorrectly [implementation]
 
(void) - testFlutterViewControllerStartKeyboardAnimationWillCreateVsyncClientCorrectly [implementation]
 
(void) - testSetupKeyboardAnimationVsyncClientWillNotCreateNewVsyncClientWhenKeyboardAnimationCallbackIsNil [implementation]
 
(void) - testSupportsShowingSystemContextMenuForIOS16AndAbove [implementation]
 
(void) - testFirstFrameCallback [implementation]
 
(void) - testDrawLayer [implementation]
 

Properties

id mockEngine
 
id mockTextInputPlugin
 
id messageSent
 
FlutterViewControllerflutterViewController
 

Detailed Description

Definition at line 169 of file FlutterViewControllerTest.mm.

Method Documentation

◆ fakeTraitCollectionWithContrast:

- (UITraitCollection *) fakeTraitCollectionWithContrast: (UIAccessibilityContrast)  contrast
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1599 :(UIAccessibilityContrast)contrast {
1600 id mockTraitCollection = OCMClassMock([UITraitCollection class]);
1601 OCMStub([mockTraitCollection accessibilityContrast]).andReturn(contrast);
1602 return mockTraitCollection;
1603}

◆ fakeTraitCollectionWithUserInterfaceStyle:

- (UITraitCollection *) fakeTraitCollectionWithUserInterfaceStyle: (UIUserInterfaceStyle)  style
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1229 :(UIUserInterfaceStyle)style {
1230 id mockTraitCollection = OCMClassMock([UITraitCollection class]);
1231 OCMStub([mockTraitCollection userInterfaceStyle]).andReturn(style);
1232 return mockTraitCollection;
1233}

◆ ios [1/5]

- ios
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1827 {
1828 if (@available(iOS 13.4, *)) {
1829 // noop
1830 } else {
1831 return;
1832 }
1833
1834 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1835 nibName:nil
1836 bundle:nil];
1837 XCTAssertNotNil(vc);
1838
1839 id mockPanGestureRecognizer = OCMClassMock([UIPanGestureRecognizer class]);
1840 XCTAssertNotNil(mockPanGestureRecognizer);
1841
1842 [vc discreteScrollEvent:mockPanGestureRecognizer];
1843
1844 [[[self.mockEngine verify] ignoringNonObjectArgs]
1845 dispatchPointerDataPacket:std::make_unique<flutter::PointerDataPacket>(0)];
1846}
void discreteScrollEvent:(ios(13.4) API_AVAILABLE)

◆ ios [2/5]

- ios
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1801 {
1802 if (@available(iOS 13.4, *)) {
1803 // noop
1804 } else {
1805 return;
1806 }
1807
1808 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1809 nibName:nil
1810 bundle:nil];
1811 XCTAssertNotNil(vc);
1812 UIView* view = vc.view;
1813 XCTAssertNotNil(view);
1814 NSArray* gestureRecognizers = view.gestureRecognizers;
1815 XCTAssertNotNil(gestureRecognizers);
1816
1817 BOOL found = NO;
1818 for (id gesture in gestureRecognizers) {
1819 if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
1820 found = YES;
1821 break;
1822 }
1823 }
1824 XCTAssertTrue(found);
1825}
int BOOL

◆ ios [3/5]

- ios
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1763 {
1764 if (@available(iOS 13.4, *)) {
1765 // noop
1766 } else {
1767 return;
1768 }
1769 id keyEventChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1770 OCMStub([keyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
1771 .andCall(self, @selector(sendMessage:reply:));
1772 OCMStub([self.mockTextInputPlugin handlePress:[OCMArg any]]).andReturn(YES);
1773 OCMStub([self.mockEngine keyEventChannel]).andReturn(keyEventChannel);
1774
1775 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1776 nibName:nil
1777 bundle:nil];
1778
1779 // Allocate the keyboard manager in the view controller by adding the internal
1780 // plugins.
1781 [vc addInternalPlugins];
1782
1783 [vc handlePressEvent:keyEventWithPhase(UIPressPhaseStationary, UIKeyboardHIDUsageKeyboardA,
1784 UIKeyModifierShift, 123.0)
1785 nextAction:^(){
1786 }];
1787 [vc handlePressEvent:keyEventWithPhase(UIPressPhaseCancelled, UIKeyboardHIDUsageKeyboardA,
1788 UIKeyModifierShift, 123.0)
1789 nextAction:^(){
1790 }];
1791 [vc handlePressEvent:keyEventWithPhase(UIPressPhaseChanged, UIKeyboardHIDUsageKeyboardA,
1792 UIKeyModifierShift, 123.0)
1793 nextAction:^(){
1794 }];
1795
1796 XCTAssert(self.messageSent == nil);
1797 OCMVerify(never(), [keyEventChannel sendMessage:[OCMArg any]]);
1799}
void handlePressEvent:nextAction:(FlutterUIPressProxy *press, [nextAction] ios(13.4) API_AVAILABLE)
SIT bool any(const Vec< 1, T > &x)
Definition SkVx.h:530

◆ ios [4/5]

- ios
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1691 {
1692 if (@available(iOS 13.4, *)) {
1693 // noop
1694 } else {
1695 return;
1696 }
1699 OCMStub([mockEngine.keyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
1700 .andCall(self, @selector(sendMessage:reply:));
1701 OCMStub([self.mockTextInputPlugin handlePress:[OCMArg any]]).andReturn(YES);
1702 mockEngine.textInputPlugin = self.mockTextInputPlugin;
1703
1704 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:mockEngine
1705 nibName:nil
1706 bundle:nil];
1707
1708 // Allocate the keyboard manager in the view controller by adding the internal
1709 // plugins.
1710 [vc addInternalPlugins];
1711
1712 [vc handlePressEvent:keyUpEvent(UIKeyboardHIDUsageKeyboardA, UIKeyModifierShift, 123.0)
1713 nextAction:^(){
1714 }];
1715
1716 XCTAssert(self.messageSent != nil);
1717 XCTAssert([self.messageSent[@"keymap"] isEqualToString:@"ios"]);
1718 XCTAssert([self.messageSent[@"type"] isEqualToString:@"keyup"]);
1719 XCTAssert([self.messageSent[@"keyCode"] isEqualToNumber:[NSNumber numberWithInt:4]]);
1720 XCTAssert([self.messageSent[@"modifiers"] isEqualToNumber:[NSNumber numberWithInt:0]]);
1721 XCTAssert([self.messageSent[@"characters"] isEqualToString:@""]);
1722 XCTAssert([self.messageSent[@"charactersIgnoringModifiers"] isEqualToString:@""]);
1724}
FlutterBasicMessageChannel * keyEventChannel

◆ ios [5/5]

- ios
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1726 {
1727 if (@available(iOS 13.4, *)) {
1728 // noop
1729 } else {
1730 return;
1731 }
1732
1735 OCMStub([mockEngine.keyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
1736 .andCall(self, @selector(sendMessage:reply:));
1737 OCMStub([self.mockTextInputPlugin handlePress:[OCMArg any]]).andReturn(YES);
1738 mockEngine.textInputPlugin = self.mockTextInputPlugin;
1739
1740 __strong FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:mockEngine
1741 nibName:nil
1742 bundle:nil];
1743 // Allocate the keyboard manager in the view controller by adding the internal
1744 // plugins.
1745 [vc addInternalPlugins];
1746
1747 [vc handlePressEvent:keyDownEvent(UIKeyboardHIDUsageKeyboardA, UIKeyModifierShift, 123.0f, "A",
1748 "a")
1749 nextAction:^(){
1750 }];
1751
1752 XCTAssert(self.messageSent != nil);
1753 XCTAssert([self.messageSent[@"keymap"] isEqualToString:@"ios"]);
1754 XCTAssert([self.messageSent[@"type"] isEqualToString:@"keydown"]);
1755 XCTAssert([self.messageSent[@"keyCode"] isEqualToNumber:[NSNumber numberWithInt:4]]);
1756 XCTAssert([self.messageSent[@"modifiers"] isEqualToNumber:[NSNumber numberWithInt:0]]);
1757 XCTAssert([self.messageSent[@"characters"] isEqualToString:@"A"]);
1758 XCTAssert([self.messageSent[@"charactersIgnoringModifiers"] isEqualToString:@"a"]);
1759 [vc deregisterNotifications];
1760 vc = nil;
1761}

◆ orientationTestWithOrientationUpdate:currentOrientation:didChangeOrientation:resultingOrientation:

- (void) orientationTestWithOrientationUpdate: (UIInterfaceOrientationMask)  mask
currentOrientation: (UIInterfaceOrientation)  currentOrientation
didChangeOrientation: (BOOL didChange
resultingOrientation: (UIInterfaceOrientation)  resultingOrientation 
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1530 :(UIInterfaceOrientationMask)mask
1531 currentOrientation:(UIInterfaceOrientation)currentOrientation
1532 didChangeOrientation:(BOOL)didChange
1533 resultingOrientation:(UIInterfaceOrientation)resultingOrientation {
1534 id mockApplication = OCMClassMock([UIApplication class]);
1535 id mockWindowScene;
1536 id deviceMock;
1537 id mockVC;
1538 __block __weak id weakPreferences;
1539 @autoreleasepool {
1540 FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1541 nibName:nil
1542 bundle:nil];
1543
1544 if (@available(iOS 16.0, *)) {
1545 mockWindowScene = OCMClassMock([UIWindowScene class]);
1546 mockVC = OCMPartialMock(realVC);
1547 OCMStub([mockVC flutterWindowSceneIfViewLoaded]).andReturn(mockWindowScene);
1548 if (realVC.supportedInterfaceOrientations == mask) {
1549 OCMReject([mockWindowScene requestGeometryUpdateWithPreferences:[OCMArg any]
1550 errorHandler:[OCMArg any]]);
1551 } else {
1552 // iOS 16 will decide whether to rotate based on the new preference, so always set it
1553 // when it changes.
1554 OCMExpect([mockWindowScene
1555 requestGeometryUpdateWithPreferences:[OCMArg checkWithBlock:^BOOL(
1556 UIWindowSceneGeometryPreferencesIOS*
1557 preferences) {
1558 weakPreferences = preferences;
1559 return preferences.interfaceOrientations == mask;
1560 }]
1561 errorHandler:[OCMArg any]]);
1562 }
1563 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
1564 OCMStub([mockApplication connectedScenes]).andReturn([NSSet setWithObject:mockWindowScene]);
1565 } else {
1566 deviceMock = OCMPartialMock([UIDevice currentDevice]);
1567 if (!didChange) {
1568 OCMReject([deviceMock setValue:[OCMArg any] forKey:@"orientation"]);
1569 } else {
1570 OCMExpect([deviceMock setValue:@(resultingOrientation) forKey:@"orientation"]);
1571 }
1572 if (@available(iOS 13.0, *)) {
1573 mockWindowScene = OCMClassMock([UIWindowScene class]);
1574 mockVC = OCMPartialMock(realVC);
1575 OCMStub([mockVC flutterWindowSceneIfViewLoaded]).andReturn(mockWindowScene);
1576 OCMStub(((UIWindowScene*)mockWindowScene).interfaceOrientation)
1577 .andReturn(currentOrientation);
1578 } else {
1579 OCMStub([mockApplication sharedApplication]).andReturn(mockApplication);
1580 OCMStub([mockApplication statusBarOrientation]).andReturn(currentOrientation);
1581 }
1582 }
1583
1584 [realVC performOrientationUpdate:mask];
1585 if (@available(iOS 16.0, *)) {
1586 OCMVerifyAll(mockWindowScene);
1587 } else {
1588 OCMVerifyAll(deviceMock);
1589 }
1590 }
1591 [mockWindowScene stopMocking];
1592 [deviceMock stopMocking];
1593 [mockApplication stopMocking];
1594 XCTAssertNil(weakPreferences);
1595}
void performOrientationUpdate:(UIInterfaceOrientationMask new_preferences)
const uintptr_t id

◆ sendMessage:reply:

- (void) sendMessage: (id _Nullable)  message
reply: (FlutterReply _Nullable)  callback 

Definition at line 178 of file FlutterViewControllerTest.mm.

1678 :(id _Nullable)message reply:(FlutterReply _Nullable)callback {
1679 NSMutableDictionary* replyMessage = [@{
1680 @"handled" : @YES,
1681 } mutableCopy];
1682 // Response is async, so we have to post it to the run loop instead of calling
1683 // it directly.
1684 self.messageSent = message;
1685 CFRunLoopPerformBlock(CFRunLoopGetCurrent(), fml::MessageLoopDarwin::kMessageLoopCFRunLoopMode,
1686 ^() {
1687 callback(replyMessage);
1688 });
1689}
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterReply)(id _Nullable reply)
static CFStringRef kMessageLoopCFRunLoopMode
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Win32Message message

◆ setUp

- (void) setUp
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

190 {
191 self.mockEngine = OCMClassMock([FlutterEngine class]);
192 self.mockTextInputPlugin = OCMClassMock([FlutterTextInputPlugin class]);
193 OCMStub([self.mockEngine textInputPlugin]).andReturn(self.mockTextInputPlugin);
194 self.messageSent = nil;
195}
FlutterTextInputPlugin * textInputPlugin

◆ setUpMockScreen

- (id) setUpMockScreen
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

206 {
207 UIScreen* mockScreen = OCMClassMock([UIScreen class]);
208 // iPhone 14 pixels
209 CGRect screenBounds = CGRectMake(0, 0, 1170, 2532);
210 OCMStub([mockScreen bounds]).andReturn(screenBounds);
211 CGFloat screenScale = 1;
212 OCMStub([mockScreen scale]).andReturn(screenScale);
213
214 return mockScreen;
215}
const Scalar scale

◆ setUpMockView:screen:viewFrame:convertedFrame:

- (id) setUpMockView: (FlutterViewController*)  viewControllerMock
screen: (UIScreen*)  screen
viewFrame: (CGRect)  viewFrame
convertedFrame: (CGRect)  convertedFrame 
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

217 :(FlutterViewController*)viewControllerMock
218 screen:(UIScreen*)screen
219 viewFrame:(CGRect)viewFrame
220 convertedFrame:(CGRect)convertedFrame {
221 OCMStub([viewControllerMock flutterScreenIfViewLoaded]).andReturn(screen);
222 id mockView = OCMClassMock([UIView class]);
223 OCMStub([mockView frame]).andReturn(viewFrame);
224 OCMStub([mockView convertRect:viewFrame toCoordinateSpace:[OCMArg any]])
225 .andReturn(convertedFrame);
226 OCMStub([viewControllerMock viewIfLoaded]).andReturn(mockView);
227
228 return mockView;
229}
double frame
Definition examples.cpp:31

◆ tearDown

- (void) tearDown
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

197 {
198 // We stop mocking here to avoid retain cycles that stop
199 // FlutterViewControllers from deallocing.
200 [self.mockEngine stopMocking];
201 self.mockEngine = nil;
202 self.mockTextInputPlugin = nil;
203 self.messageSent = nil;
204}

◆ testAccessibilityPerformEscapePopsRoute

- (void) testAccessibilityPerformEscapePopsRoute
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1368 {
1369 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
1370 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
1371 id mockNavigationChannel = OCMClassMock([FlutterMethodChannel class]);
1372 OCMStub([mockEngine navigationChannel]).andReturn(mockNavigationChannel);
1373
1374 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
1375 nibName:nil
1376 bundle:nil];
1377 XCTAssertTrue([viewController accessibilityPerformEscape]);
1378
1379 OCMVerify([mockNavigationChannel invokeMethod:@"popRoute" arguments:nil]);
1380
1381 [mockNavigationChannel stopMocking];
1382}
BOOL createShell:libraryURI:initialRoute:(NSString *entrypoint, [libraryURI] NSString *libraryURI, [initialRoute] NSString *initialRoute)
FlutterViewController * viewController

◆ testAppWillTerminateViewDidDestroyTheEngine

- (void) testAppWillTerminateViewDidDestroyTheEngine
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

810 {
811 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
812 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
813 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
814 nibName:nil
815 bundle:nil];
816 id viewControllerMock = OCMPartialMock(viewController);
817 OCMStub([viewControllerMock goToApplicationLifecycle:@"AppLifecycleState.detached"]);
818 OCMStub([mockEngine destroyContext]);
819 [viewController applicationWillTerminate:nil];
820 OCMVerify([viewControllerMock goToApplicationLifecycle:@"AppLifecycleState.detached"]);
821 OCMVerify([mockEngine destroyContext]);
822}
void applicationWillTerminate:(NSNotification *notification)

◆ testBinaryMessenger

- (void) testBinaryMessenger
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1125 {
1126 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1127 nibName:nil
1128 bundle:nil];
1129 XCTAssertNotNil(vc);
1130 id messenger = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
1131 OCMStub([self.mockEngine binaryMessenger]).andReturn(messenger);
1132 XCTAssertEqual(vc.binaryMessenger, messenger);
1133 OCMVerify([self.mockEngine binaryMessenger]);
1134}
NSObject< FlutterBinaryMessenger > * binaryMessenger

◆ testCalculateKeyboardAttachMode

- (void) testCalculateKeyboardAttachMode
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

535 {
536 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
537 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
538 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
539 nibName:nil
540 bundle:nil];
541
542 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
543 UIScreen* screen = [self setUpMockScreen];
544 CGRect viewFrame = screen.bounds;
545 [self setUpMockView:viewControllerMock
546 screen:screen
547 viewFrame:viewFrame
548 convertedFrame:viewFrame];
549
550 CGFloat screenWidth = screen.bounds.size.width;
551 CGFloat screenHeight = screen.bounds.size.height;
552
553 // hide notification
554 CGRect keyboardFrame = CGRectZero;
555 NSNotification* notification =
556 [NSNotification notificationWithName:UIKeyboardWillHideNotification
557 object:nil
558 userInfo:@{
559 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
560 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
561 @"UIKeyboardIsLocalUserInfoKey" : @(YES)
562 }];
563 FlutterKeyboardMode keyboardMode = [viewControllerMock calculateKeyboardAttachMode:notification];
564 XCTAssertTrue(keyboardMode == FlutterKeyboardModeHidden);
565
566 // all zeros
567 keyboardFrame = CGRectZero;
568 notification = [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
569 object:nil
570 userInfo:@{
571 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
572 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
573 @"UIKeyboardIsLocalUserInfoKey" : @(YES)
574 }];
575 keyboardMode = [viewControllerMock calculateKeyboardAttachMode:notification];
576 XCTAssertTrue(keyboardMode == FlutterKeyboardModeFloating);
577
578 // 0 height
579 keyboardFrame = CGRectMake(0, 0, screenWidth, 0);
580 notification = [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
581 object:nil
582 userInfo:@{
583 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
584 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
585 @"UIKeyboardIsLocalUserInfoKey" : @(YES)
586 }];
587 keyboardMode = [viewControllerMock calculateKeyboardAttachMode:notification];
588 XCTAssertTrue(keyboardMode == FlutterKeyboardModeHidden);
589
590 // floating
591 keyboardFrame = CGRectMake(0, 0, 320, 320);
592 notification = [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
593 object:nil
594 userInfo:@{
595 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
596 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
597 @"UIKeyboardIsLocalUserInfoKey" : @(YES)
598 }];
599 keyboardMode = [viewControllerMock calculateKeyboardAttachMode:notification];
600 XCTAssertTrue(keyboardMode == FlutterKeyboardModeFloating);
601
602 // undocked
603 keyboardFrame = CGRectMake(0, 0, screenWidth, 320);
604 notification = [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
605 object:nil
606 userInfo:@{
607 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
608 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
609 @"UIKeyboardIsLocalUserInfoKey" : @(YES)
610 }];
611 keyboardMode = [viewControllerMock calculateKeyboardAttachMode:notification];
612 XCTAssertTrue(keyboardMode == FlutterKeyboardModeFloating);
613
614 // docked
615 keyboardFrame = CGRectMake(0, screenHeight - 320, screenWidth, 320);
616 notification = [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
617 object:nil
618 userInfo:@{
619 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
620 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
621 @"UIKeyboardIsLocalUserInfoKey" : @(YES)
622 }];
623 keyboardMode = [viewControllerMock calculateKeyboardAttachMode:notification];
624 XCTAssertTrue(keyboardMode == FlutterKeyboardModeDocked);
625
626 // docked - rounded values
627 CGFloat longDecimalHeight = 320.666666666666666;
628 keyboardFrame = CGRectMake(0, screenHeight - longDecimalHeight, screenWidth, longDecimalHeight);
629 notification = [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
630 object:nil
631 userInfo:@{
632 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
633 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
634 @"UIKeyboardIsLocalUserInfoKey" : @(YES)
635 }];
636 keyboardMode = [viewControllerMock calculateKeyboardAttachMode:notification];
637 XCTAssertTrue(keyboardMode == FlutterKeyboardModeDocked);
638
639 // hidden - rounded values
640 keyboardFrame = CGRectMake(0, screenHeight - .0000001, screenWidth, longDecimalHeight);
641 notification = [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
642 object:nil
643 userInfo:@{
644 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
645 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
646 @"UIKeyboardIsLocalUserInfoKey" : @(YES)
647 }];
648 keyboardMode = [viewControllerMock calculateKeyboardAttachMode:notification];
649 XCTAssertTrue(keyboardMode == FlutterKeyboardModeHidden);
650
651 // hidden
652 keyboardFrame = CGRectMake(0, screenHeight, screenWidth, 320);
653 notification = [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
654 object:nil
655 userInfo:@{
656 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
657 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
658 @"UIKeyboardIsLocalUserInfoKey" : @(YES)
659 }];
660 keyboardMode = [viewControllerMock calculateKeyboardAttachMode:notification];
661 XCTAssertTrue(keyboardMode == FlutterKeyboardModeHidden);
662}
FlutterKeyboardMode calculateKeyboardAttachMode:(NSNotification *notification)

◆ testCalculateKeyboardInset

- (void) testCalculateKeyboardInset
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

694 {
695 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
696 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
697 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
698 nibName:nil
699 bundle:nil];
700 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
701 UIScreen* screen = [self setUpMockScreen];
702 OCMStub([viewControllerMock flutterScreenIfViewLoaded]).andReturn(screen);
703
704 CGFloat screenWidth = screen.bounds.size.width;
705 CGFloat screenHeight = screen.bounds.size.height;
706 CGRect viewOrigFrame = CGRectMake(0, 0, 320, screenHeight - 40);
707 CGRect convertedViewFrame = CGRectMake(20, 20, 320, screenHeight - 40);
708 CGRect keyboardFrame = CGRectMake(20, screenHeight - 320, screenWidth, 300);
709
710 [self setUpMockView:viewControllerMock
711 screen:screen
712 viewFrame:viewOrigFrame
713 convertedFrame:convertedViewFrame];
714
715 CGFloat inset = [viewControllerMock calculateKeyboardInset:keyboardFrame
716 keyboardMode:FlutterKeyboardModeDocked];
717 XCTAssertTrue(inset == 300 * screen.scale);
718}
CGFloat calculateKeyboardInset:keyboardMode:(CGRect keyboardFrame, [keyboardMode] NSInteger keyboardMode)
static SkRect inset(const SkRect &r)

◆ testCalculateMultitaskingAdjustment

- (void) testCalculateMultitaskingAdjustment
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

664 {
665 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
666 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
667 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
668 nibName:nil
669 bundle:nil];
670 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
671
672 UIScreen* screen = [self setUpMockScreen];
673 CGFloat screenWidth = screen.bounds.size.width;
674 CGFloat screenHeight = screen.bounds.size.height;
675 CGRect screenRect = screen.bounds;
676 CGRect viewOrigFrame = CGRectMake(0, 0, 320, screenHeight - 40);
677 CGRect convertedViewFrame = CGRectMake(20, 20, 320, screenHeight - 40);
678 CGRect keyboardFrame = CGRectMake(20, screenHeight - 320, screenWidth, 300);
679 id mockView = [self setUpMockView:viewControllerMock
680 screen:screen
681 viewFrame:viewOrigFrame
682 convertedFrame:convertedViewFrame];
683 id mockTraitCollection = OCMClassMock([UITraitCollection class]);
684 OCMStub([mockTraitCollection userInterfaceIdiom]).andReturn(UIUserInterfaceIdiomPad);
685 OCMStub([mockTraitCollection horizontalSizeClass]).andReturn(UIUserInterfaceSizeClassCompact);
686 OCMStub([mockTraitCollection verticalSizeClass]).andReturn(UIUserInterfaceSizeClassRegular);
687 OCMStub([mockView traitCollection]).andReturn(mockTraitCollection);
688
689 CGFloat adjustment = [viewControllerMock calculateMultitaskingAdjustment:screenRect
690 keyboardFrame:keyboardFrame];
691 XCTAssertTrue(adjustment == 20);
692}
CGFloat calculateMultitaskingAdjustment:keyboardFrame:(CGRect screenRect, [keyboardFrame] CGRect keyboardFrame)

◆ testCreateTouchRateCorrectionVSyncClientWillCreateVsyncClientWhenRefreshRateIsLargerThan60HZ

- (void) testCreateTouchRateCorrectionVSyncClientWillCreateVsyncClientWhenRefreshRateIsLargerThan60HZ
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

2079 {
2080 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
2081 double maxFrameRate = 120;
2082 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
2083 FlutterEngine* engine = [[FlutterEngine alloc] init];
2084 [engine runWithEntrypoint:nil];
2085 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2086 nibName:nil
2087 bundle:nil];
2090}
FlutterEngine engine
Definition main.cc:68
BOOL runWithEntrypoint:(nullable NSString *entrypoint)
VSyncClient * touchRateCorrectionVSyncClient

◆ testCreateTouchRateCorrectionVSyncClientWillNotCreateNewVSyncClientWhenClientAlreadyExists

- (void) testCreateTouchRateCorrectionVSyncClientWillNotCreateNewVSyncClientWhenClientAlreadyExists
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

2092 {
2093 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
2094 double maxFrameRate = 120;
2095 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
2096
2097 FlutterEngine* engine = [[FlutterEngine alloc] init];
2098 [engine runWithEntrypoint:nil];
2099 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2100 nibName:nil
2101 bundle:nil];
2104 XCTAssertNotNil(clientBefore);
2105
2108 XCTAssertNotNil(clientAfter);
2109
2110 XCTAssertTrue(clientBefore == clientAfter);
2111}

◆ testCreateTouchRateCorrectionVSyncClientWillNotCreateVsyncClientWhenRefreshRateIs60HZ

- (void) testCreateTouchRateCorrectionVSyncClientWillNotCreateVsyncClientWhenRefreshRateIs60HZ
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

2113 {
2114 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
2115 double maxFrameRate = 60;
2116 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
2117 FlutterEngine* engine = [[FlutterEngine alloc] init];
2118 [engine runWithEntrypoint:nil];
2119 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2120 nibName:nil
2121 bundle:nil];
2124}

◆ testDoesntLoadViewInInit

- (void) testDoesntLoadViewInInit
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1641 {
1642 FlutterDartProject* project = [[FlutterDartProject alloc] init];
1643 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
1644 [engine createShell:@"" libraryURI:@"" initialRoute:nil];
1645 FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine
1646 nibName:nil
1647 bundle:nil];
1648 XCTAssertFalse([realVC isViewLoaded], @"shouldn't have loaded since it hasn't been shown");
1649 engine.viewController = nil;
1650}
FlutterViewController * viewController

◆ testDrawLayer

- (void) testDrawLayer
implementation

Definition at line 13 of file FlutterViewControllerTest.m.

63 {
64 XCTestExpectation* firstFrameRendered = [self expectationWithDescription:@"firstFrameRendered"];
65 XCTestExpectation* imageRendered = [self expectationWithDescription:@"imageRendered"];
66
67 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
68 [engine runWithEntrypoint:nil];
69 [engine.binaryMessenger
70 setMessageHandlerOnChannel:@"waiting_for_status"
71 binaryMessageHandler:^(NSData* _Nullable message, FlutterBinaryReply _Nonnull reply) {
73 methodChannelWithName:@"driver"
74 binaryMessenger:engine.binaryMessenger
76 [channel invokeMethod:@"set_scenario" arguments:@{@"name" : @"solid_blue"}];
77 }];
78
79 self.flutterViewController = [[FlutterViewController alloc] initWithEngine:engine
80 nibName:nil
81 bundle:nil];
82
83 XCTAssertFalse(self.flutterViewController.isDisplayingFlutterUI);
84
85 [self.flutterViewController setFlutterViewDidRenderCallback:^{
86 [firstFrameRendered fulfill];
87 }];
88
89 AppDelegate* appDelegate = (AppDelegate*)UIApplication.sharedApplication.delegate;
90 UIViewController* rootVC = appDelegate.window.rootViewController;
91 [rootVC presentViewController:self.flutterViewController animated:NO completion:nil];
92
93 CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
94
95 __block dispatch_block_t callback;
96 callback = ^{
97 size_t width = 300u;
98 CGContextRef context =
99 CGBitmapContextCreate(nil, width, width, 8, 4 * width, color_space,
100 kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
101 [appDelegate.window.layer renderInContext:context];
102 uint32_t* image_data = (uint32_t*)CGBitmapContextGetData(context);
103 if (image_data[20] == 0xFF0000FF) {
104 [imageRendered fulfill];
105 return;
106 }
107
108 CGContextRelease(context);
109
110 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC), dispatch_get_main_queue(),
111 callback);
112 };
113 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC), dispatch_get_main_queue(),
114 callback);
115
116 [self waitForExpectationsWithTimeout:30.0 handler:nil];
117
118 CGColorSpaceRelease(color_space);
119}
FlutterBinaryMessengerConnection setMessageHandlerOnChannel:binaryMessageHandler:(NSString *channel, [binaryMessageHandler] FlutterBinaryMessageHandler handler)
instancetype sharedInstance()
instancetype methodChannelWithName:binaryMessenger:codec:(NSString *name,[binaryMessenger] NSObject< FlutterBinaryMessenger > *messenger,[codec] NSObject< FlutterMethodCodec > *codec)
FlutterViewController * flutterViewController
int32_t width
#define NSEC_PER_SEC
Definition timerfd.cc:35

◆ testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewDidAppear

- (void) testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewDidAppear
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

872 {
873 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
874 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
875 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
876 nibName:nil
877 bundle:nil];
878 [viewController viewDidAppear:YES];
879 OCMVerify([viewController onUserSettingsChanged:nil]);
880}
void viewDidAppear:(BOOL animated)

◆ testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewWillAppear

- (void) testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewWillAppear
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

844 {
845 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
846 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
847 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
848 nibName:nil
849 bundle:nil];
850 [viewController viewWillAppear:YES];
851 OCMVerify([viewController onUserSettingsChanged:nil]);
852}
void viewWillAppear:(BOOL animated)

◆ testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewWillDisappear

- (void) testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewWillDisappear
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

900 {
901 id lifecycleChannel = OCMClassMock([FlutterBasicMessageChannel class]);
903 mockEngine.lifecycleChannel = lifecycleChannel;
904 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
905 nibName:nil
906 bundle:nil];
907 mockEngine.viewController = viewController;
908 [viewController viewWillDisappear:NO];
909 OCMVerify([lifecycleChannel sendMessage:@"AppLifecycleState.inactive"]);
910}
FlutterBasicMessageChannel * lifecycleChannel
void viewWillDisappear:(BOOL animated)

◆ testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewDidAppear

- (void) testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewDidAppear
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

883 {
884 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
885 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
886 FlutterViewController* viewControllerA = [[FlutterViewController alloc] initWithEngine:mockEngine
887 nibName:nil
888 bundle:nil];
889 mockEngine.viewController = nil;
890 FlutterViewController* viewControllerB = [[FlutterViewController alloc] initWithEngine:mockEngine
891 nibName:nil
892 bundle:nil];
893 mockEngine.viewController = nil;
894 mockEngine.viewController = viewControllerB;
895 [viewControllerA viewDidAppear:YES];
896 OCMVerify(never(), [viewControllerA onUserSettingsChanged:nil]);
897}

◆ testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewWillAppear

- (void) testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewWillAppear
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

855 {
856 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
857 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
858 FlutterViewController* viewControllerA = [[FlutterViewController alloc] initWithEngine:mockEngine
859 nibName:nil
860 bundle:nil];
861 mockEngine.viewController = nil;
862 FlutterViewController* viewControllerB = [[FlutterViewController alloc] initWithEngine:mockEngine
863 nibName:nil
864 bundle:nil];
865 mockEngine.viewController = nil;
866 mockEngine.viewController = viewControllerB;
867 [viewControllerA viewWillAppear:YES];
868 OCMVerify(never(), [viewControllerA onUserSettingsChanged:nil]);
869}

◆ testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewWillDisappear

- (void) testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewWillDisappear
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

913 {
914 id lifecycleChannel = OCMClassMock([FlutterBasicMessageChannel class]);
916 mockEngine.lifecycleChannel = lifecycleChannel;
917 FlutterViewController* viewControllerA = [[FlutterViewController alloc] initWithEngine:mockEngine
918 nibName:nil
919 bundle:nil];
920 FlutterViewController* viewControllerB = [[FlutterViewController alloc] initWithEngine:mockEngine
921 nibName:nil
922 bundle:nil];
923 mockEngine.viewController = viewControllerB;
924 [viewControllerA viewDidDisappear:NO];
925 OCMReject([lifecycleChannel sendMessage:@"AppLifecycleState.inactive"]);
926}
void viewDidDisappear:(BOOL animated)

◆ testEnsureBottomInsetIsZeroWhenKeyboardDismissed

- (void) testEnsureBottomInsetIsZeroWhenKeyboardDismissed
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

758 {
759 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
760 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
761 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
762 nibName:nil
763 bundle:nil];
764
765 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
766 CGRect keyboardFrame = CGRectZero;
767 BOOL isLocal = YES;
768 NSNotification* fakeNotification =
769 [NSNotification notificationWithName:UIKeyboardWillHideNotification
770 object:nil
771 userInfo:@{
772 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
773 @"UIKeyboardAnimationDurationUserInfoKey" : @(0.25),
774 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
775 }];
776
777 viewControllerMock.targetViewInsetBottom = 10;
778 [viewControllerMock handleKeyboardNotification:fakeNotification];
779 XCTAssertTrue(viewControllerMock.targetViewInsetBottom == 0);
780}
void handleKeyboardNotification:(NSNotification *notification)

◆ testEnsureViewportMetricsWillInvokeAndDisplayLinkWillInvalidateInViewDidDisappear

- (void) testEnsureViewportMetricsWillInvokeAndDisplayLinkWillInvalidateInViewDidDisappear
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

782 {
783 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
784 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
785 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
786 nibName:nil
787 bundle:nil];
788 id viewControllerMock = OCMPartialMock(viewController);
789 [viewControllerMock viewDidDisappear:YES];
790 OCMVerify([viewControllerMock ensureViewportMetricsIsCorrect]);
791 OCMVerify([viewControllerMock invalidateKeyboardAnimationVSyncClient]);
792}

◆ testFakeEventTimeStamp

- (void) testFakeEventTimeStamp
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1848 {
1849 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1850 nibName:nil
1851 bundle:nil];
1852 XCTAssertNotNil(vc);
1853
1855 int64_t current_micros = [[NSProcessInfo processInfo] systemUptime] * 1000 * 1000;
1856 int64_t interval_micros = current_micros - pointer_data.time_stamp;
1857 const int64_t tolerance_millis = 2;
1858 XCTAssertTrue(interval_micros / 1000 < tolerance_millis,
1859 @"PointerData.time_stamp should be equal to NSProcessInfo.systemUptime");
1860}
flutter::PointerData generatePointerDataForFake()

◆ testFirstFrameCallback

- (void) testFirstFrameCallback
implementation

Definition at line 13 of file FlutterViewControllerTest.m.

35 {
36 XCTestExpectation* firstFrameRendered = [self expectationWithDescription:@"firstFrameRendered"];
37
38 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
39 [engine runWithEntrypoint:nil];
40 self.flutterViewController = [[FlutterViewController alloc] initWithEngine:engine
41 nibName:nil
42 bundle:nil];
43
44 XCTAssertFalse(self.flutterViewController.isDisplayingFlutterUI);
45
46 XCTestExpectation* displayingFlutterUIExpectation =
47 [self keyValueObservingExpectationForObject:self.flutterViewController
48 keyPath:@"displayingFlutterUI"
49 expectedValue:@YES];
50 displayingFlutterUIExpectation.assertForOverFulfill = YES;
51
52 [self.flutterViewController setFlutterViewDidRenderCallback:^{
53 [firstFrameRendered fulfill];
54 }];
55
56 AppDelegate* appDelegate = (AppDelegate*)UIApplication.sharedApplication.delegate;
57 UIViewController* rootVC = appDelegate.window.rootViewController;
58 [rootVC presentViewController:self.flutterViewController animated:NO completion:nil];
59
60 [self waitForExpectationsWithTimeout:30.0 handler:nil];
61}

◆ testFlutterViewControllerStartKeyboardAnimationWillCreateVsyncClientCorrectly

- (void) testFlutterViewControllerStartKeyboardAnimationWillCreateVsyncClientCorrectly
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

2185 {
2186 FlutterEngine* engine = [[FlutterEngine alloc] init];
2187 [engine runWithEntrypoint:nil];
2188 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2189 nibName:nil
2190 bundle:nil];
2192 [viewController startKeyBoardAnimation:0.25];
2194}
void startKeyBoardAnimation:(NSTimeInterval duration)
VSyncClient * keyboardAnimationVSyncClient

◆ testHandleKeyboardNotification

- (void) testHandleKeyboardNotification
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

720 {
721 FlutterEngine* engine = [[FlutterEngine alloc] init];
722 [engine runWithEntrypoint:nil];
723 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
724 nibName:nil
725 bundle:nil];
726 // keyboard is empty
727 UIScreen* screen = [self setUpMockScreen];
728 CGFloat screenWidth = screen.bounds.size.width;
729 CGFloat screenHeight = screen.bounds.size.height;
730 CGRect keyboardFrame = CGRectMake(0, screenHeight - 320, screenWidth, 320);
731 CGRect viewFrame = screen.bounds;
732 BOOL isLocal = YES;
733 NSNotification* notification =
734 [NSNotification notificationWithName:UIKeyboardWillShowNotification
735 object:nil
736 userInfo:@{
737 @"UIKeyboardFrameEndUserInfoKey" : @(keyboardFrame),
738 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
739 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
740 }];
741 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
742 [self setUpMockView:viewControllerMock
743 screen:screen
744 viewFrame:viewFrame
745 convertedFrame:viewFrame];
746 viewControllerMock.targetViewInsetBottom = 0;
747 XCTestExpectation* expectation = [self expectationWithDescription:@"update viewport"];
748 OCMStub([viewControllerMock updateViewportMetricsIfNeeded]).andDo(^(NSInvocation* invocation) {
749 [expectation fulfill];
750 });
751
752 [viewControllerMock handleKeyboardNotification:notification];
753 XCTAssertTrue(viewControllerMock.targetViewInsetBottom == 320 * screen.scale);
754 OCMVerify([viewControllerMock startKeyBoardAnimation:0.25]);
755 [self waitForExpectationsWithTimeout:5.0 handler:nil];
756}

◆ testHideOverlay

- (void) testHideOverlay
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1652 {
1653 FlutterDartProject* project = [[FlutterDartProject alloc] init];
1654 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
1655 [engine createShell:@"" libraryURI:@"" initialRoute:nil];
1656 FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine
1657 nibName:nil
1658 bundle:nil];
1659 XCTAssertFalse(realVC.prefersHomeIndicatorAutoHidden, @"");
1660 [[NSNotificationCenter defaultCenter] postNotificationName:FlutterViewControllerHideHomeIndicator
1661 object:nil];
1662 XCTAssertTrue(realVC.prefersHomeIndicatorAutoHidden, @"");
1663 engine.viewController = nil;
1664}

◆ testInternalPluginsInvokeInViewDidLoad

- (void) testInternalPluginsInvokeInViewDidLoad
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1110 {
1111 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
1112 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
1113 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
1114 nibName:nil
1115 bundle:nil];
1116 UIView* view = viewController.view;
1117 // The implementation in viewDidLoad requires the viewControllers.viewLoaded is true.
1118 // Accessing the view to make sure the view loads in the memory,
1119 // which makes viewControllers.viewLoaded true.
1120 XCTAssertNotNil(view);
1121 [viewController viewDidLoad];
1122 OCMVerify([viewController addInternalPlugins]);
1123}

◆ testInternalPluginsWeakPtrNotCrash

- (void) testInternalPluginsWeakPtrNotCrash
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1091 {
1092 FlutterSendKeyEvent sendEvent;
1093 @autoreleasepool {
1094 FlutterViewController* vc = [[FlutterViewController alloc] initWithProject:nil
1095 nibName:nil
1096 bundle:nil];
1097 [vc addInternalPlugins];
1098 FlutterKeyboardManager* keyboardManager = vc.keyboardManager;
1100 [(NSArray<id<FlutterKeyPrimaryResponder>>*)keyboardManager.primaryResponders firstObject];
1101 sendEvent = [keyPrimaryResponder sendEvent];
1102 }
1103
1104 if (sendEvent) {
1105 sendEvent({}, nil, nil);
1106 }
1107}
NSMutableArray< id< FlutterKeyPrimaryResponder > > * primaryResponders
FlutterKeyboardManager * keyboardManager
void(^ FlutterSendKeyEvent)(const FlutterKeyEvent &, _Nullable FlutterKeyEventCallback, void *_Nullable)

◆ testItReportsAccessibilityOnOffSwitchLabelsFlagNotSet

- (void) testItReportsAccessibilityOnOffSwitchLabelsFlagNotSet
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1328 {
1329 if (@available(iOS 13, *)) {
1330 // noop
1331 } else {
1332 return;
1333 }
1334
1335 // Setup test.
1337 [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil];
1338 id partialMockViewController = OCMPartialMock(viewController);
1339 OCMStub([partialMockViewController accessibilityIsOnOffSwitchLabelsEnabled]).andReturn(NO);
1340
1341 // Exercise behavior under test.
1342 int32_t flags = [partialMockViewController accessibilityFlags];
1343
1344 // Verify behavior.
1346}
FlutterSemanticsFlag flags

◆ testItReportsAccessibilityOnOffSwitchLabelsFlagSet

- (void) testItReportsAccessibilityOnOffSwitchLabelsFlagSet
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1348 {
1349 if (@available(iOS 13, *)) {
1350 // noop
1351 } else {
1352 return;
1353 }
1354
1355 // Setup test.
1357 [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil];
1358 id partialMockViewController = OCMPartialMock(viewController);
1359 OCMStub([partialMockViewController accessibilityIsOnOffSwitchLabelsEnabled]).andReturn(YES);
1360
1361 // Exercise behavior under test.
1362 int32_t flags = [partialMockViewController accessibilityFlags];
1363
1364 // Verify behavior.
1366}

◆ testItReportsDarkPlatformBrightnessWhenTraitCollectionRequestsIt

- (void) testItReportsDarkPlatformBrightnessWhenTraitCollectionRequestsIt
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1191 {
1192 if (@available(iOS 13, *)) {
1193 // noop
1194 } else {
1195 return;
1196 }
1197
1198 // Setup test.
1199 id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1200 OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel);
1201 id mockTraitCollection =
1202 [self fakeTraitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark];
1203
1204 // We partially mock the real FlutterViewController to act as the OS and report
1205 // the UITraitCollection of our choice. Mocking the object under test is not
1206 // desirable, but given that the OS does not offer a DI approach to providing
1207 // our own UITraitCollection, this seems to be the least bad option.
1208 id partialMockVC = OCMPartialMock([[FlutterViewController alloc] initWithEngine:self.mockEngine
1209 nibName:nil
1210 bundle:nil]);
1211 OCMStub([partialMockVC traitCollection]).andReturn(mockTraitCollection);
1212
1213 // Exercise behavior under test.
1214 [partialMockVC traitCollectionDidChange:nil];
1215
1216 // Verify behavior.
1217 OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
1218 return [message[@"platformBrightness"] isEqualToString:@"dark"];
1219 }]]);
1220
1221 // Clean up mocks
1222 [partialMockVC stopMocking];
1223 [settingsChannel stopMocking];
1224 [mockTraitCollection stopMocking];
1225}

◆ testItReportsHighContrastWhenTraitCollectionRequestsIt

- (void) testItReportsHighContrastWhenTraitCollectionRequestsIt
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1292 {
1293 if (@available(iOS 13, *)) {
1294 // noop
1295 } else {
1296 return;
1297 }
1298
1299 // Setup test.
1300 id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1301 OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel);
1302
1303 id mockTraitCollection = [self fakeTraitCollectionWithContrast:UIAccessibilityContrastHigh];
1304
1305 // We partially mock the real FlutterViewController to act as the OS and report
1306 // the UITraitCollection of our choice. Mocking the object under test is not
1307 // desirable, but given that the OS does not offer a DI approach to providing
1308 // our own UITraitCollection, this seems to be the least bad option.
1309 id partialMockVC = OCMPartialMock([[FlutterViewController alloc] initWithEngine:self.mockEngine
1310 nibName:nil
1311 bundle:nil]);
1312 OCMStub([partialMockVC traitCollection]).andReturn(mockTraitCollection);
1313
1314 // Exercise behavior under test.
1315 [partialMockVC traitCollectionDidChange:mockTraitCollection];
1316
1317 // Verify behavior.
1318 OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
1319 return [message[@"platformContrast"] isEqualToString:@"high"];
1320 }]]);
1321
1322 // Clean up mocks
1323 [partialMockVC stopMocking];
1324 [settingsChannel stopMocking];
1325 [mockTraitCollection stopMocking];
1326}

◆ testItReportsLightPlatformBrightnessByDefault

- (void) testItReportsLightPlatformBrightnessByDefault
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1148 {
1149 // Setup test.
1150 id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1151 OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel);
1152
1153 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1154 nibName:nil
1155 bundle:nil];
1156
1157 // Exercise behavior under test.
1158 [vc traitCollectionDidChange:nil];
1159
1160 // Verify behavior.
1161 OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
1162 return [message[@"platformBrightness"] isEqualToString:@"light"];
1163 }]]);
1164
1165 // Clean up mocks
1166 [settingsChannel stopMocking];
1167}
void traitCollectionDidChange:(UITraitCollection *previousTraitCollection)

◆ testItReportsNormalPlatformContrastByDefault

- (void) testItReportsNormalPlatformContrastByDefault
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1237 {
1238 if (@available(iOS 13, *)) {
1239 // noop
1240 } else {
1241 return;
1242 }
1243
1244 // Setup test.
1245 id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1246 OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel);
1247
1248 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1249 nibName:nil
1250 bundle:nil];
1251
1252 // Exercise behavior under test.
1253 [vc traitCollectionDidChange:nil];
1254
1255 // Verify behavior.
1256 OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
1257 return [message[@"platformContrast"] isEqualToString:@"normal"];
1258 }]]);
1259
1260 // Clean up mocks
1261 [settingsChannel stopMocking];
1262}

◆ testItReportsPlatformBrightnessWhenViewWillAppear

- (void) testItReportsPlatformBrightnessWhenViewWillAppear
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1169 {
1170 // Setup test.
1171 id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1172 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
1173 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
1174 OCMStub([mockEngine settingsChannel]).andReturn(settingsChannel);
1175 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:mockEngine
1176 nibName:nil
1177 bundle:nil];
1178
1179 // Exercise behavior under test.
1180 [vc viewWillAppear:false];
1181
1182 // Verify behavior.
1183 OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
1184 return [message[@"platformBrightness"] isEqualToString:@"light"];
1185 }]]);
1186
1187 // Clean up mocks
1188 [settingsChannel stopMocking];
1189}

◆ testItReportsPlatformContrastWhenViewWillAppear

- (void) testItReportsPlatformContrastWhenViewWillAppear
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1264 {
1265 if (@available(iOS 13, *)) {
1266 // noop
1267 } else {
1268 return;
1269 }
1270 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
1271 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
1272
1273 // Setup test.
1274 id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1275 OCMStub([mockEngine settingsChannel]).andReturn(settingsChannel);
1276 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:mockEngine
1277 nibName:nil
1278 bundle:nil];
1279
1280 // Exercise behavior under test.
1281 [vc viewWillAppear:false];
1282
1283 // Verify behavior.
1284 OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
1285 return [message[@"platformContrast"] isEqualToString:@"normal"];
1286 }]]);
1287
1288 // Clean up mocks
1289 [settingsChannel stopMocking];
1290}

◆ testKeyboardAnimationIsShowingAndCompounding

- (void) testKeyboardAnimationIsShowingAndCompounding
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

302 {
303 FlutterEngine* engine = [[FlutterEngine alloc] init];
304 [engine runWithEntrypoint:nil];
305 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
306 nibName:nil
307 bundle:nil];
308 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
309 UIScreen* screen = [self setUpMockScreen];
310 CGRect viewFrame = screen.bounds;
311 [self setUpMockView:viewControllerMock
312 screen:screen
313 viewFrame:viewFrame
314 convertedFrame:viewFrame];
315
316 BOOL isLocal = YES;
317 CGFloat screenHeight = screen.bounds.size.height;
318 CGFloat screenWidth = screen.bounds.size.height;
319
320 // Start show keyboard animation.
321 CGRect initialShowKeyboardBeginFrame = CGRectMake(0, screenHeight, screenWidth, 250);
322 CGRect initialShowKeyboardEndFrame = CGRectMake(0, screenHeight - 250, screenWidth, 500);
323 NSNotification* fakeNotification = [NSNotification
324 notificationWithName:UIKeyboardWillChangeFrameNotification
325 object:nil
326 userInfo:@{
327 @"UIKeyboardFrameBeginUserInfoKey" : @(initialShowKeyboardBeginFrame),
328 @"UIKeyboardFrameEndUserInfoKey" : @(initialShowKeyboardEndFrame),
329 @"UIKeyboardAnimationDurationUserInfoKey" : @(0.25),
330 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
331 }];
332 viewControllerMock.targetViewInsetBottom = 0;
333 [viewControllerMock handleKeyboardNotification:fakeNotification];
334 BOOL isShowingAnimation1 = viewControllerMock.keyboardAnimationIsShowing;
335 XCTAssertTrue(isShowingAnimation1);
336
337 // Start compounding show keyboard animation.
338 CGRect compoundingShowKeyboardBeginFrame = CGRectMake(0, screenHeight - 250, screenWidth, 250);
339 CGRect compoundingShowKeyboardEndFrame = CGRectMake(0, screenHeight - 500, screenWidth, 500);
340 fakeNotification = [NSNotification
341 notificationWithName:UIKeyboardWillChangeFrameNotification
342 object:nil
343 userInfo:@{
344 @"UIKeyboardFrameBeginUserInfoKey" : @(compoundingShowKeyboardBeginFrame),
345 @"UIKeyboardFrameEndUserInfoKey" : @(compoundingShowKeyboardEndFrame),
346 @"UIKeyboardAnimationDurationUserInfoKey" : @(0.25),
347 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
348 }];
349
350 [viewControllerMock handleKeyboardNotification:fakeNotification];
351 BOOL isShowingAnimation2 = viewControllerMock.keyboardAnimationIsShowing;
352 XCTAssertTrue(isShowingAnimation2);
353 XCTAssertTrue(isShowingAnimation1 == isShowingAnimation2);
354
355 // Start hide keyboard animation.
356 CGRect initialHideKeyboardBeginFrame = CGRectMake(0, screenHeight - 500, screenWidth, 250);
357 CGRect initialHideKeyboardEndFrame = CGRectMake(0, screenHeight - 250, screenWidth, 500);
358 fakeNotification = [NSNotification
359 notificationWithName:UIKeyboardWillChangeFrameNotification
360 object:nil
361 userInfo:@{
362 @"UIKeyboardFrameBeginUserInfoKey" : @(initialHideKeyboardBeginFrame),
363 @"UIKeyboardFrameEndUserInfoKey" : @(initialHideKeyboardEndFrame),
364 @"UIKeyboardAnimationDurationUserInfoKey" : @(0.25),
365 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
366 }];
367
368 [viewControllerMock handleKeyboardNotification:fakeNotification];
369 BOOL isShowingAnimation3 = viewControllerMock.keyboardAnimationIsShowing;
370 XCTAssertFalse(isShowingAnimation3);
371 XCTAssertTrue(isShowingAnimation2 != isShowingAnimation3);
372
373 // Start compounding hide keyboard animation.
374 CGRect compoundingHideKeyboardBeginFrame = CGRectMake(0, screenHeight - 250, screenWidth, 250);
375 CGRect compoundingHideKeyboardEndFrame = CGRectMake(0, screenHeight, screenWidth, 500);
376 fakeNotification = [NSNotification
377 notificationWithName:UIKeyboardWillChangeFrameNotification
378 object:nil
379 userInfo:@{
380 @"UIKeyboardFrameBeginUserInfoKey" : @(compoundingHideKeyboardBeginFrame),
381 @"UIKeyboardFrameEndUserInfoKey" : @(compoundingHideKeyboardEndFrame),
382 @"UIKeyboardAnimationDurationUserInfoKey" : @(0.25),
383 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
384 }];
385
386 [viewControllerMock handleKeyboardNotification:fakeNotification];
387 BOOL isShowingAnimation4 = viewControllerMock.keyboardAnimationIsShowing;
388 XCTAssertFalse(isShowingAnimation4);
389 XCTAssertTrue(isShowingAnimation3 == isShowingAnimation4);
390}

◆ testKeyboardAnimationWillNotCrashWhenEngineDestroyed

- (void) testKeyboardAnimationWillNotCrashWhenEngineDestroyed
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

496 {
497 FlutterEngine* engine = [[FlutterEngine alloc] init];
498 [engine runWithEntrypoint:nil];
499 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
500 nibName:nil
501 bundle:nil];
502 [viewController setUpKeyboardAnimationVsyncClient:^(fml::TimePoint){
503 }];
504 [engine destroyContext];
505}
void setUpKeyboardAnimationVsyncClient:(FlutterKeyboardAnimationCallback keyboardAnimationCallback)

◆ testKeyboardAnimationWillWaitUIThreadVsync

- (void) testKeyboardAnimationWillWaitUIThreadVsync
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

507 {
508 // We need to make sure the new viewport metrics get sent after the
509 // begin frame event has processed. And this test is to expect that the callback
510 // will sync with UI thread. So just simulate a lot of works on UI thread and
511 // test the keyboard animation callback will execute until UI task completed.
512 // Related issue: https://github.com/flutter/flutter/issues/120555.
513
514 FlutterEngine* engine = [[FlutterEngine alloc] init];
515 [engine runWithEntrypoint:nil];
516 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
517 nibName:nil
518 bundle:nil];
519 // Post a task to UI thread to block the thread.
520 const int delayTime = 1;
521 [engine uiTaskRunner]->PostTask([] { sleep(delayTime); });
522 XCTestExpectation* expectation = [self expectationWithDescription:@"keyboard animation callback"];
523
524 __block CFTimeInterval fulfillTime;
526 fulfillTime = CACurrentMediaTime();
527 [expectation fulfill];
528 };
529 CFTimeInterval startTime = CACurrentMediaTime();
530 [viewController setUpKeyboardAnimationVsyncClient:callback];
531 [self waitForExpectationsWithTimeout:5.0 handler:nil];
532 XCTAssertTrue(fulfillTime - startTime > delayTime);
533}
fml::RefPtr< fml::TaskRunner > uiTaskRunner()
void(^ FlutterKeyboardAnimationCallback)(fml::TimePoint)

◆ testLifeCycleNotificationBecameActive

- (void) testLifeCycleNotificationBecameActive
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1868 {
1869 FlutterEngine* engine = [[FlutterEngine alloc] init];
1870 [engine runWithEntrypoint:nil];
1872 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
1873 UIWindow* window = [[UIWindow alloc] init];
1874 [window addSubview:flutterViewController.view];
1875 flutterViewController.view.bounds = CGRectMake(0, 0, 100, 100);
1876 [flutterViewController viewDidLayoutSubviews];
1877 NSNotification* sceneNotification =
1878 [NSNotification notificationWithName:UISceneDidActivateNotification object:nil userInfo:nil];
1879 NSNotification* applicationNotification =
1880 [NSNotification notificationWithName:UIApplicationDidBecomeActiveNotification
1881 object:nil
1882 userInfo:nil];
1883 id mockVC = OCMPartialMock(flutterViewController);
1884 [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
1885 [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
1886#if APPLICATION_EXTENSION_API_ONLY
1887 OCMVerify([mockVC sceneBecameActive:[OCMArg any]]);
1888 OCMReject([mockVC applicationBecameActive:[OCMArg any]]);
1889#else
1890 OCMReject([mockVC sceneBecameActive:[OCMArg any]]);
1891 OCMVerify([mockVC applicationBecameActive:[OCMArg any]]);
1892#endif
1894 OCMVerify([mockVC surfaceUpdated:YES]);
1895 XCTestExpectation* timeoutApplicationLifeCycle =
1896 [self expectationWithDescription:@"timeoutApplicationLifeCycle"];
1897 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)),
1898 dispatch_get_main_queue(), ^{
1899 [timeoutApplicationLifeCycle fulfill];
1900 OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.resumed"]);
1901 [flutterViewController deregisterNotifications];
1902 });
1903 [self waitForExpectationsWithTimeout:5.0 handler:nil];
1904}
GLFWwindow * window
Definition main.cc:45

◆ testLifeCycleNotificationCancelledInvalidResumed

- (void) testLifeCycleNotificationCancelledInvalidResumed
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

2019 {
2020 FlutterEngine* engine = [[FlutterEngine alloc] init];
2021 [engine runWithEntrypoint:nil];
2023 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
2024 NSNotification* applicationDidBecomeActiveNotification =
2025 [NSNotification notificationWithName:UIApplicationDidBecomeActiveNotification
2026 object:nil
2027 userInfo:nil];
2028 NSNotification* applicationWillResignActiveNotification =
2029 [NSNotification notificationWithName:UIApplicationWillResignActiveNotification
2030 object:nil
2031 userInfo:nil];
2032 id mockVC = OCMPartialMock(flutterViewController);
2033 [[NSNotificationCenter defaultCenter] postNotification:applicationDidBecomeActiveNotification];
2034 [[NSNotificationCenter defaultCenter] postNotification:applicationWillResignActiveNotification];
2035#if APPLICATION_EXTENSION_API_ONLY
2036#else
2037 OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.inactive"]);
2038#endif
2039
2040 XCTestExpectation* timeoutApplicationLifeCycle =
2041 [self expectationWithDescription:@"timeoutApplicationLifeCycle"];
2042 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)),
2043 dispatch_get_main_queue(), ^{
2044 OCMReject([mockVC goToApplicationLifecycle:@"AppLifecycleState.resumed"]);
2045 [timeoutApplicationLifeCycle fulfill];
2046 [flutterViewController deregisterNotifications];
2047 });
2048 [self waitForExpectationsWithTimeout:5.0 handler:nil];
2049}

◆ testLifeCycleNotificationDidEnterBackground

- (void) testLifeCycleNotificationDidEnterBackground
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1963 {
1964 FlutterEngine* engine = [[FlutterEngine alloc] init];
1965 [engine runWithEntrypoint:nil];
1967 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
1968 NSNotification* sceneNotification =
1969 [NSNotification notificationWithName:UISceneDidEnterBackgroundNotification
1970 object:nil
1971 userInfo:nil];
1972 NSNotification* applicationNotification =
1973 [NSNotification notificationWithName:UIApplicationDidEnterBackgroundNotification
1974 object:nil
1975 userInfo:nil];
1976 id mockVC = OCMPartialMock(flutterViewController);
1977 [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
1978 [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
1979#if APPLICATION_EXTENSION_API_ONLY
1980 OCMVerify([mockVC sceneDidEnterBackground:[OCMArg any]]);
1981 OCMReject([mockVC applicationDidEnterBackground:[OCMArg any]]);
1982#else
1983 OCMReject([mockVC sceneDidEnterBackground:[OCMArg any]]);
1984 OCMVerify([mockVC applicationDidEnterBackground:[OCMArg any]]);
1985#endif
1987 OCMVerify([mockVC surfaceUpdated:NO]);
1988 OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.paused"]);
1989 [flutterViewController deregisterNotifications];
1990}

◆ testLifeCycleNotificationWillEnterForeground

- (void) testLifeCycleNotificationWillEnterForeground
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1992 {
1993 FlutterEngine* engine = [[FlutterEngine alloc] init];
1994 [engine runWithEntrypoint:nil];
1996 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
1997 NSNotification* sceneNotification =
1998 [NSNotification notificationWithName:UISceneWillEnterForegroundNotification
1999 object:nil
2000 userInfo:nil];
2001 NSNotification* applicationNotification =
2002 [NSNotification notificationWithName:UIApplicationWillEnterForegroundNotification
2003 object:nil
2004 userInfo:nil];
2005 id mockVC = OCMPartialMock(flutterViewController);
2006 [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
2007 [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
2008#if APPLICATION_EXTENSION_API_ONLY
2009 OCMVerify([mockVC sceneWillEnterForeground:[OCMArg any]]);
2010 OCMReject([mockVC applicationWillEnterForeground:[OCMArg any]]);
2011#else
2012 OCMReject([mockVC sceneWillEnterForeground:[OCMArg any]]);
2013 OCMVerify([mockVC applicationWillEnterForeground:[OCMArg any]]);
2014#endif
2015 OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.inactive"]);
2016 [flutterViewController deregisterNotifications];
2017}

◆ testLifeCycleNotificationWillResignActive

- (void) testLifeCycleNotificationWillResignActive
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1906 {
1907 FlutterEngine* engine = [[FlutterEngine alloc] init];
1908 [engine runWithEntrypoint:nil];
1910 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
1911 NSNotification* sceneNotification =
1912 [NSNotification notificationWithName:UISceneWillDeactivateNotification
1913 object:nil
1914 userInfo:nil];
1915 NSNotification* applicationNotification =
1916 [NSNotification notificationWithName:UIApplicationWillResignActiveNotification
1917 object:nil
1918 userInfo:nil];
1919 id mockVC = OCMPartialMock(flutterViewController);
1920 [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
1921 [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
1922#if APPLICATION_EXTENSION_API_ONLY
1923 OCMVerify([mockVC sceneWillResignActive:[OCMArg any]]);
1924 OCMReject([mockVC applicationWillResignActive:[OCMArg any]]);
1925#else
1926 OCMReject([mockVC sceneWillResignActive:[OCMArg any]]);
1927 OCMVerify([mockVC applicationWillResignActive:[OCMArg any]]);
1928#endif
1929 OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.inactive"]);
1930 [flutterViewController deregisterNotifications];
1931}

◆ testLifeCycleNotificationWillTerminate

- (void) testLifeCycleNotificationWillTerminate
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1933 {
1934 FlutterEngine* engine = [[FlutterEngine alloc] init];
1935 [engine runWithEntrypoint:nil];
1937 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
1938 NSNotification* sceneNotification =
1939 [NSNotification notificationWithName:UISceneDidDisconnectNotification
1940 object:nil
1941 userInfo:nil];
1942 NSNotification* applicationNotification =
1943 [NSNotification notificationWithName:UIApplicationWillTerminateNotification
1944 object:nil
1945 userInfo:nil];
1946 id mockVC = OCMPartialMock(flutterViewController);
1947 id mockEngine = OCMPartialMock(engine);
1948 OCMStub([mockVC engine]).andReturn(mockEngine);
1949 [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
1950 [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
1951#if APPLICATION_EXTENSION_API_ONLY
1952 OCMVerify([mockVC sceneWillDisconnect:[OCMArg any]]);
1953 OCMReject([mockVC applicationWillTerminate:[OCMArg any]]);
1954#else
1955 OCMReject([mockVC sceneWillDisconnect:[OCMArg any]]);
1956 OCMVerify([mockVC applicationWillTerminate:[OCMArg any]]);
1957#endif
1958 OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.detached"]);
1959 OCMVerify([mockEngine destroyContext]);
1960 [flutterViewController deregisterNotifications];
1961}

◆ testNotifyLowMemory

- (void) testNotifyLowMemory
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1666 {
1668 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
1669 nibName:nil
1670 bundle:nil];
1671 id viewControllerMock = OCMPartialMock(viewController);
1672 OCMStub([viewControllerMock surfaceUpdated:NO]);
1673 [viewController beginAppearanceTransition:NO animated:NO];
1674 [viewController endAppearanceTransition];
1675 XCTAssertTrue(mockEngine.didCallNotifyLowMemory);
1676}

◆ testPerformOrientationUpdateDoesNotForceOrientationChange

- (void) testPerformOrientationUpdateDoesNotForceOrientationChange
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1461 {
1462 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskAll
1463 currentOrientation:UIInterfaceOrientationPortrait
1464 didChangeOrientation:NO
1465 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1466
1467 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskAll
1468 currentOrientation:UIInterfaceOrientationPortraitUpsideDown
1469 didChangeOrientation:NO
1470 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1471
1472 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskAll
1473 currentOrientation:UIInterfaceOrientationLandscapeLeft
1474 didChangeOrientation:NO
1475 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1476
1477 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskAll
1478 currentOrientation:UIInterfaceOrientationLandscapeRight
1479 didChangeOrientation:NO
1480 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1481
1482 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskAllButUpsideDown
1483 currentOrientation:UIInterfaceOrientationPortrait
1484 didChangeOrientation:NO
1485 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1486
1487 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskAllButUpsideDown
1488 currentOrientation:UIInterfaceOrientationLandscapeLeft
1489 didChangeOrientation:NO
1490 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1491
1492 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskAllButUpsideDown
1493 currentOrientation:UIInterfaceOrientationLandscapeRight
1494 didChangeOrientation:NO
1495 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1496
1497 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskPortrait
1498 currentOrientation:UIInterfaceOrientationPortrait
1499 didChangeOrientation:NO
1500 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1501
1502 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskPortraitUpsideDown
1503 currentOrientation:UIInterfaceOrientationPortraitUpsideDown
1504 didChangeOrientation:NO
1505 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1506
1507 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscape
1508 currentOrientation:UIInterfaceOrientationLandscapeLeft
1509 didChangeOrientation:NO
1510 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1511
1512 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscape
1513 currentOrientation:UIInterfaceOrientationLandscapeRight
1514 didChangeOrientation:NO
1515 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1516
1517 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscapeLeft
1518 currentOrientation:UIInterfaceOrientationLandscapeLeft
1519 didChangeOrientation:NO
1520 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1521
1522 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscapeRight
1523 currentOrientation:UIInterfaceOrientationLandscapeRight
1524 didChangeOrientation:NO
1525 resultingOrientation:static_cast<UIInterfaceOrientation>(0)];
1526}

◆ testPerformOrientationUpdateForcesOrientationChange

- (void) testPerformOrientationUpdateForcesOrientationChange
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1384 {
1385 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskPortrait
1386 currentOrientation:UIInterfaceOrientationLandscapeLeft
1387 didChangeOrientation:YES
1388 resultingOrientation:UIInterfaceOrientationPortrait];
1389
1390 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskPortrait
1391 currentOrientation:UIInterfaceOrientationLandscapeRight
1392 didChangeOrientation:YES
1393 resultingOrientation:UIInterfaceOrientationPortrait];
1394
1395 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskPortrait
1396 currentOrientation:UIInterfaceOrientationPortraitUpsideDown
1397 didChangeOrientation:YES
1398 resultingOrientation:UIInterfaceOrientationPortrait];
1399
1400 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskPortraitUpsideDown
1401 currentOrientation:UIInterfaceOrientationLandscapeLeft
1402 didChangeOrientation:YES
1403 resultingOrientation:UIInterfaceOrientationPortraitUpsideDown];
1404
1405 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskPortraitUpsideDown
1406 currentOrientation:UIInterfaceOrientationLandscapeRight
1407 didChangeOrientation:YES
1408 resultingOrientation:UIInterfaceOrientationPortraitUpsideDown];
1409
1410 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskPortraitUpsideDown
1411 currentOrientation:UIInterfaceOrientationPortrait
1412 didChangeOrientation:YES
1413 resultingOrientation:UIInterfaceOrientationPortraitUpsideDown];
1414
1415 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscape
1416 currentOrientation:UIInterfaceOrientationPortrait
1417 didChangeOrientation:YES
1418 resultingOrientation:UIInterfaceOrientationLandscapeLeft];
1419
1420 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscape
1421 currentOrientation:UIInterfaceOrientationPortraitUpsideDown
1422 didChangeOrientation:YES
1423 resultingOrientation:UIInterfaceOrientationLandscapeLeft];
1424
1425 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscapeLeft
1426 currentOrientation:UIInterfaceOrientationPortrait
1427 didChangeOrientation:YES
1428 resultingOrientation:UIInterfaceOrientationLandscapeLeft];
1429
1430 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscapeLeft
1431 currentOrientation:UIInterfaceOrientationLandscapeRight
1432 didChangeOrientation:YES
1433 resultingOrientation:UIInterfaceOrientationLandscapeLeft];
1434
1435 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscapeLeft
1436 currentOrientation:UIInterfaceOrientationPortraitUpsideDown
1437 didChangeOrientation:YES
1438 resultingOrientation:UIInterfaceOrientationLandscapeLeft];
1439
1440 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscapeRight
1441 currentOrientation:UIInterfaceOrientationPortrait
1442 didChangeOrientation:YES
1443 resultingOrientation:UIInterfaceOrientationLandscapeRight];
1444
1445 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscapeRight
1446 currentOrientation:UIInterfaceOrientationLandscapeLeft
1447 didChangeOrientation:YES
1448 resultingOrientation:UIInterfaceOrientationLandscapeRight];
1449
1450 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskLandscapeRight
1451 currentOrientation:UIInterfaceOrientationPortraitUpsideDown
1452 didChangeOrientation:YES
1453 resultingOrientation:UIInterfaceOrientationLandscapeRight];
1454
1455 [self orientationTestWithOrientationUpdate:UIInterfaceOrientationMaskAllButUpsideDown
1456 currentOrientation:UIInterfaceOrientationPortraitUpsideDown
1457 didChangeOrientation:YES
1458 resultingOrientation:UIInterfaceOrientationPortrait];
1459}

◆ testReleasesKeyboardManagerOnDealloc

- (void) testReleasesKeyboardManagerOnDealloc
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1626 {
1627 __weak FlutterKeyboardManager* weakKeyboardManager = nil;
1628 @autoreleasepool {
1630
1631 [viewController addInternalPlugins];
1632 weakKeyboardManager = viewController.keyboardManager;
1633 XCTAssertNotNil(weakKeyboardManager);
1634 [viewController deregisterNotifications];
1635 viewController = nil;
1636 }
1637 // View controller has released the keyboard manager.
1638 XCTAssertNil(weakKeyboardManager);
1639}

◆ testSetupKeyboardAnimationVsyncClientWillCreateNewVsyncClientForFlutterViewController

- (void) testSetupKeyboardAnimationVsyncClientWillCreateNewVsyncClientForFlutterViewController
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

2051 {
2052 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
2053 OCMStub([bundleMock objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"])
2054 .andReturn(@YES);
2055 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
2056 double maxFrameRate = 120;
2057 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
2058 FlutterEngine* engine = [[FlutterEngine alloc] init];
2059 [engine runWithEntrypoint:nil];
2060 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2061 nibName:nil
2062 bundle:nil];
2064 };
2065 [viewController setUpKeyboardAnimationVsyncClient:callback];
2067 CADisplayLink* link = [viewController.keyboardAnimationVSyncClient getDisplayLink];
2068 XCTAssertNotNil(link);
2069 if (@available(iOS 15.0, *)) {
2070 XCTAssertEqual(link.preferredFrameRateRange.maximum, maxFrameRate);
2071 XCTAssertEqual(link.preferredFrameRateRange.preferred, maxFrameRate);
2072 XCTAssertEqual(link.preferredFrameRateRange.minimum, maxFrameRate / 2);
2073 } else {
2074 XCTAssertEqual(link.preferredFramesPerSecond, maxFrameRate);
2075 }
2076}
link(from_root, to_root)
Definition dart_pkg.py:44

◆ testSetupKeyboardAnimationVsyncClientWillNotCreateNewVsyncClientWhenKeyboardAnimationCallbackIsNil

- (void) testSetupKeyboardAnimationVsyncClientWillNotCreateNewVsyncClientWhenKeyboardAnimationCallbackIsNil
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

2197 {
2198 FlutterEngine* engine = [[FlutterEngine alloc] init];
2199 [engine runWithEntrypoint:nil];
2200 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2201 nibName:nil
2202 bundle:nil];
2203 [viewController setUpKeyboardAnimationVsyncClient:nil];
2205}

◆ testSetupKeyboardSpringAnimationIfNeeded

- (void) testSetupKeyboardSpringAnimationIfNeeded
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

259 {
260 FlutterEngine* engine = [[FlutterEngine alloc] init];
261 [engine runWithEntrypoint:nil];
262 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
263 nibName:nil
264 bundle:nil];
265 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
266 UIScreen* screen = [self setUpMockScreen];
267 CGRect viewFrame = screen.bounds;
268 [self setUpMockView:viewControllerMock
269 screen:screen
270 viewFrame:viewFrame
271 convertedFrame:viewFrame];
272
273 // Null check.
274 [viewControllerMock setUpKeyboardSpringAnimationIfNeeded:nil];
275 SpringAnimation* keyboardSpringAnimation = [viewControllerMock keyboardSpringAnimation];
276 XCTAssertTrue(keyboardSpringAnimation == nil);
277
278 // CAAnimation that is not a CASpringAnimation.
279 CABasicAnimation* nonSpringAnimation = [CABasicAnimation animation];
280 nonSpringAnimation.duration = 1.0;
281 nonSpringAnimation.fromValue = [NSNumber numberWithFloat:0.0];
282 nonSpringAnimation.toValue = [NSNumber numberWithFloat:1.0];
283 nonSpringAnimation.keyPath = @"position";
284 [viewControllerMock setUpKeyboardSpringAnimationIfNeeded:nonSpringAnimation];
285 keyboardSpringAnimation = [viewControllerMock keyboardSpringAnimation];
286
287 XCTAssertTrue(keyboardSpringAnimation == nil);
288
289 // CASpringAnimation.
290 CASpringAnimation* springAnimation = [CASpringAnimation animation];
291 springAnimation.mass = 1.0;
292 springAnimation.stiffness = 100.0;
293 springAnimation.damping = 10.0;
294 springAnimation.keyPath = @"position";
295 springAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
296 springAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(100, 100)];
297 [viewControllerMock setUpKeyboardSpringAnimationIfNeeded:springAnimation];
298 keyboardSpringAnimation = [viewControllerMock keyboardSpringAnimation];
299 XCTAssertTrue(keyboardSpringAnimation != nil);
300}
SpringAnimation * keyboardSpringAnimation()
void setUpKeyboardSpringAnimationIfNeeded:(CAAnimation *keyboardAnimation)

◆ testShouldIgnoreKeyboardNotification

- (void) testShouldIgnoreKeyboardNotification
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

392 {
393 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
394 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
395 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
396 nibName:nil
397 bundle:nil];
398 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
399 UIScreen* screen = [self setUpMockScreen];
400 CGRect viewFrame = screen.bounds;
401 [self setUpMockView:viewControllerMock
402 screen:screen
403 viewFrame:viewFrame
404 convertedFrame:viewFrame];
405
406 CGFloat screenWidth = screen.bounds.size.width;
407 CGFloat screenHeight = screen.bounds.size.height;
408 CGRect emptyKeyboard = CGRectZero;
409 CGRect zeroHeightKeyboard = CGRectMake(0, 0, screenWidth, 0);
410 CGRect validKeyboardEndFrame = CGRectMake(0, screenHeight - 320, screenWidth, 320);
411 BOOL isLocal = NO;
412
413 // Hide notification, valid keyboard
414 NSNotification* notification =
415 [NSNotification notificationWithName:UIKeyboardWillHideNotification
416 object:nil
417 userInfo:@{
418 @"UIKeyboardFrameEndUserInfoKey" : @(validKeyboardEndFrame),
419 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
420 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
421 }];
422
423 BOOL shouldIgnore = [viewControllerMock shouldIgnoreKeyboardNotification:notification];
424 XCTAssertTrue(shouldIgnore == NO);
425
426 // All zero keyboard
427 isLocal = YES;
428 notification = [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
429 object:nil
430 userInfo:@{
431 @"UIKeyboardFrameEndUserInfoKey" : @(emptyKeyboard),
432 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
433 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
434 }];
435 shouldIgnore = [viewControllerMock shouldIgnoreKeyboardNotification:notification];
436 XCTAssertTrue(shouldIgnore == YES);
437
438 // Zero height keyboard
439 isLocal = NO;
440 notification =
441 [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
442 object:nil
443 userInfo:@{
444 @"UIKeyboardFrameEndUserInfoKey" : @(zeroHeightKeyboard),
445 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
446 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
447 }];
448 shouldIgnore = [viewControllerMock shouldIgnoreKeyboardNotification:notification];
449 XCTAssertTrue(shouldIgnore == NO);
450
451 // Valid keyboard, triggered from another app
452 isLocal = NO;
453 notification =
454 [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
455 object:nil
456 userInfo:@{
457 @"UIKeyboardFrameEndUserInfoKey" : @(validKeyboardEndFrame),
458 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
459 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
460 }];
461 shouldIgnore = [viewControllerMock shouldIgnoreKeyboardNotification:notification];
462 XCTAssertTrue(shouldIgnore == YES);
463
464 // Valid keyboard
465 isLocal = YES;
466 notification =
467 [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
468 object:nil
469 userInfo:@{
470 @"UIKeyboardFrameEndUserInfoKey" : @(validKeyboardEndFrame),
471 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
472 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
473 }];
474 shouldIgnore = [viewControllerMock shouldIgnoreKeyboardNotification:notification];
475 XCTAssertTrue(shouldIgnore == NO);
476
477 if (@available(iOS 13.0, *)) {
478 // noop
479 } else {
480 // Valid keyboard, keyboard is in background
481 OCMStub([viewControllerMock isKeyboardInOrTransitioningFromBackground]).andReturn(YES);
482
483 isLocal = YES;
484 notification =
485 [NSNotification notificationWithName:UIKeyboardWillChangeFrameNotification
486 object:nil
487 userInfo:@{
488 @"UIKeyboardFrameEndUserInfoKey" : @(validKeyboardEndFrame),
489 @"UIKeyboardAnimationDurationUserInfoKey" : @0.25,
490 @"UIKeyboardIsLocalUserInfoKey" : @(isLocal)
491 }];
492 shouldIgnore = [viewControllerMock shouldIgnoreKeyboardNotification:notification];
493 XCTAssertTrue(shouldIgnore == YES);
494 }
495}
BOOL shouldIgnoreKeyboardNotification:(NSNotification *notification)

◆ testSplashScreenViewCanSetNil

- (void) testSplashScreenViewCanSetNil
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1862 {
1864 [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil];
1865 [flutterViewController setSplashScreenView:nil];
1866}
void setSplashScreenView:(UIView *view)

◆ testSplashScreenViewRemoveNotCrash

- (void) testSplashScreenViewRemoveNotCrash
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1082 {
1083 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"engine" project:nil];
1084 [engine runWithEntrypoint:nil];
1086 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
1087 [flutterViewController setSplashScreenView:[[UIView alloc] init]];
1088 [flutterViewController setSplashScreenView:nil];
1089}

◆ testStartKeyboardAnimationWillInvokeSetupKeyboardSpringAnimationIfNeeded

- (void) testStartKeyboardAnimationWillInvokeSetupKeyboardSpringAnimationIfNeeded
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

243 {
244 FlutterEngine* engine = [[FlutterEngine alloc] init];
245 [engine runWithEntrypoint:nil];
246 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
247 nibName:nil
248 bundle:nil];
249 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
250 viewControllerMock.targetViewInsetBottom = 100;
251 [viewControllerMock startKeyBoardAnimation:0.25];
252
253 CAAnimation* keyboardAnimation =
254 [[viewControllerMock keyboardAnimationView].layer animationForKey:@"position"];
255
256 OCMVerify([viewControllerMock setUpKeyboardSpringAnimationIfNeeded:keyboardAnimation]);
257}

◆ testSupportsShowingSystemContextMenuForIOS16AndAbove

- (void) testSupportsShowingSystemContextMenuForIOS16AndAbove
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

2207 {
2208 FlutterEngine* engine = [[FlutterEngine alloc] init];
2209 [engine runWithEntrypoint:nil];
2210 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2211 nibName:nil
2212 bundle:nil];
2213 BOOL supportsShowingSystemContextMenu = [viewController supportsShowingSystemContextMenu];
2214 if (@available(iOS 16.0, *)) {
2215 XCTAssertTrue(supportsShowingSystemContextMenu);
2216 } else {
2217 XCTAssertFalse(supportsShowingSystemContextMenu);
2218 }
2219}

◆ testTriggerTouchRateCorrectionVSyncClientCorrectly

- (void) testTriggerTouchRateCorrectionVSyncClientCorrectly
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

2126 {
2127 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
2128 double maxFrameRate = 120;
2129 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
2130 FlutterEngine* engine = [[FlutterEngine alloc] init];
2131 [engine runWithEntrypoint:nil];
2132 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2133 nibName:nil
2134 bundle:nil];
2135 [viewController loadView];
2136 [viewController viewDidLoad];
2137
2139 CADisplayLink* link = [client getDisplayLink];
2140
2141 UITouch* fakeTouchBegan = [[UITouch alloc] init];
2142 fakeTouchBegan.phase = UITouchPhaseBegan;
2143
2144 UITouch* fakeTouchMove = [[UITouch alloc] init];
2145 fakeTouchMove.phase = UITouchPhaseMoved;
2146
2147 UITouch* fakeTouchEnd = [[UITouch alloc] init];
2148 fakeTouchEnd.phase = UITouchPhaseEnded;
2149
2150 UITouch* fakeTouchCancelled = [[UITouch alloc] init];
2151 fakeTouchCancelled.phase = UITouchPhaseCancelled;
2152
2153 [viewController
2154 triggerTouchRateCorrectionIfNeeded:[[NSSet alloc] initWithObjects:fakeTouchBegan, nil]];
2155 XCTAssertFalse(link.isPaused);
2156
2157 [viewController
2158 triggerTouchRateCorrectionIfNeeded:[[NSSet alloc] initWithObjects:fakeTouchEnd, nil]];
2159 XCTAssertTrue(link.isPaused);
2160
2161 [viewController
2162 triggerTouchRateCorrectionIfNeeded:[[NSSet alloc] initWithObjects:fakeTouchMove, nil]];
2163 XCTAssertFalse(link.isPaused);
2164
2165 [viewController
2166 triggerTouchRateCorrectionIfNeeded:[[NSSet alloc] initWithObjects:fakeTouchCancelled, nil]];
2167 XCTAssertTrue(link.isPaused);
2168
2169 [viewController
2171 initWithObjects:fakeTouchBegan, fakeTouchEnd, nil]];
2172 XCTAssertFalse(link.isPaused);
2173
2174 [viewController
2175 triggerTouchRateCorrectionIfNeeded:[[NSSet alloc] initWithObjects:fakeTouchEnd,
2176 fakeTouchCancelled, nil]];
2177 XCTAssertTrue(link.isPaused);
2178
2179 [viewController
2181 initWithObjects:fakeTouchMove, fakeTouchEnd, nil]];
2182 XCTAssertFalse(link.isPaused);
2183}
void triggerTouchRateCorrectionIfNeeded:(NSSet *touches)
CADisplayLink * getDisplayLink()

◆ testUpdateViewportMetricsIfNeeded_DoesInvokeEngineWhenIsTheViewController

- (void) testUpdateViewportMetricsIfNeeded_DoesInvokeEngineWhenIsTheViewController
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

944 {
945 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
946 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
947 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
948 nibName:nil
949 bundle:nil];
950 mockEngine.viewController = viewController;
951 flutter::ViewportMetrics viewportMetrics;
952 OCMExpect([mockEngine updateViewportMetrics:viewportMetrics]).ignoringNonObjectArgs();
953 [viewController updateViewportMetricsIfNeeded];
954 OCMVerifyAll(mockEngine);
955}

◆ testUpdateViewportMetricsIfNeeded_DoesNotInvokeEngineWhenShouldBeIgnoredDuringRotation

- (void) testUpdateViewportMetricsIfNeeded_DoesNotInvokeEngineWhenShouldBeIgnoredDuringRotation
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

957 {
958 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
959 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
960 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
961 nibName:nil
962 bundle:nil];
963 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
964 UIScreen* screen = [self setUpMockScreen];
965 OCMStub([viewControllerMock flutterScreenIfViewLoaded]).andReturn(screen);
966 mockEngine.viewController = viewController;
967
968 id mockCoordinator = OCMProtocolMock(@protocol(UIViewControllerTransitionCoordinator));
969 OCMStub([mockCoordinator transitionDuration]).andReturn(0.5);
970
971 // Mimic the device rotation.
972 [viewController viewWillTransitionToSize:CGSizeZero withTransitionCoordinator:mockCoordinator];
973 // Should not trigger the engine call when during rotation.
974 [viewController updateViewportMetricsIfNeeded];
975
976 OCMVerify(never(), [mockEngine updateViewportMetrics:flutter::ViewportMetrics()]);
977}
void viewWillTransitionToSize:withTransitionCoordinator:(CGSize size, [withTransitionCoordinator] id< UIViewControllerTransitionCoordinator > coordinator)

◆ testUpdateViewportMetricsIfNeeded_DoesntInvokeEngineWhenNotTheViewController

- (void) testUpdateViewportMetricsIfNeeded_DoesntInvokeEngineWhenNotTheViewController
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

928 {
929 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
930 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
931 FlutterViewController* viewControllerA = [[FlutterViewController alloc] initWithEngine:mockEngine
932 nibName:nil
933 bundle:nil];
934 mockEngine.viewController = nil;
935 FlutterViewController* viewControllerB = [[FlutterViewController alloc] initWithEngine:mockEngine
936 nibName:nil
937 bundle:nil];
938 mockEngine.viewController = viewControllerB;
939 [viewControllerA updateViewportMetricsIfNeeded];
940 flutter::ViewportMetrics viewportMetrics;
941 OCMVerify(never(), [mockEngine updateViewportMetrics:viewportMetrics]);
942}

◆ testViewControllerIsReleased

- (void) testViewControllerIsReleased
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1136 {
1137 __weak FlutterViewController* weakViewController;
1138 @autoreleasepool {
1140 weakViewController = viewController;
1141 [viewController viewDidLoad];
1142 }
1143 XCTAssertNil(weakViewController);
1144}

◆ testViewDidDisappearDoesntPauseEngineWhenNotTheViewController

- (void) testViewDidDisappearDoesntPauseEngineWhenNotTheViewController
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

794 {
795 id lifecycleChannel = OCMClassMock([FlutterBasicMessageChannel class]);
797 mockEngine.lifecycleChannel = lifecycleChannel;
798 FlutterViewController* viewControllerA =
799 [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil];
800 FlutterViewController* viewControllerB =
801 [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil];
802 id viewControllerMock = OCMPartialMock(viewControllerA);
803 OCMStub([viewControllerMock surfaceUpdated:NO]);
804 mockEngine.viewController = viewControllerB;
805 [viewControllerA viewDidDisappear:NO];
806 OCMReject([lifecycleChannel sendMessage:@"AppLifecycleState.paused"]);
807 OCMReject([viewControllerMock surfaceUpdated:[OCMArg any]]);
808}

◆ testViewDidDisappearDoesPauseEngineWhenIsTheViewController

- (void) testViewDidDisappearDoesPauseEngineWhenIsTheViewController
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

824 {
825 id lifecycleChannel = OCMClassMock([FlutterBasicMessageChannel class]);
827 mockEngine.lifecycleChannel = lifecycleChannel;
828 __weak FlutterViewController* weakViewController;
829 @autoreleasepool {
830 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
831 nibName:nil
832 bundle:nil];
833 weakViewController = viewController;
834 id viewControllerMock = OCMPartialMock(viewController);
835 OCMStub([viewControllerMock surfaceUpdated:NO]);
836 [viewController viewDidDisappear:NO];
837 OCMVerify([lifecycleChannel sendMessage:@"AppLifecycleState.paused"]);
838 OCMVerify([viewControllerMock surfaceUpdated:NO]);
839 }
840 XCTAssertNil(weakViewController);
841}

◆ testViewDidLoadDoesInvokeEngineWhenIsTheViewController

- (void) testViewDidLoadDoesInvokeEngineWhenIsTheViewController
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1054 {
1055 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
1056 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
1057 mockEngine.viewController = nil;
1058 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
1059 nibName:nil
1060 bundle:nil];
1061 mockEngine.viewController = viewController;
1062 UIView* view = viewController.view;
1063 XCTAssertNotNil(view);
1064 OCMVerify(times(1), [mockEngine attachView]);
1065}
static SkISize times(const SkISize &size, float factor)

◆ testViewDidLoadDoesntInvokeEngineAttachViewWhenEngineNeedsLaunch

- (void) testViewDidLoadDoesntInvokeEngineAttachViewWhenEngineNeedsLaunch
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1067 {
1068 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
1069 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
1070 mockEngine.viewController = nil;
1071 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
1072 nibName:nil
1073 bundle:nil];
1074 // sharedSetupWithProject sets the engine needs to be launched.
1075 [viewController sharedSetupWithProject:nil initialRoute:nil];
1076 mockEngine.viewController = viewController;
1077 UIView* view = viewController.view;
1078 XCTAssertNotNil(view);
1079 OCMVerify(never(), [mockEngine attachView]);
1080}
void sharedSetupWithProject:initialRoute:(nullable FlutterDartProject *project, [initialRoute] nullable NSString *initialRoute)

◆ testViewDidLoadDoesntInvokeEngineWhenNotTheViewController

- (void) testViewDidLoadDoesntInvokeEngineWhenNotTheViewController
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1038 {
1039 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
1040 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
1041 FlutterViewController* viewControllerA = [[FlutterViewController alloc] initWithEngine:mockEngine
1042 nibName:nil
1043 bundle:nil];
1044 mockEngine.viewController = nil;
1045 FlutterViewController* viewControllerB = [[FlutterViewController alloc] initWithEngine:mockEngine
1046 nibName:nil
1047 bundle:nil];
1048 mockEngine.viewController = viewControllerB;
1049 UIView* view = viewControllerA.view;
1050 XCTAssertNotNil(view);
1051 OCMVerify(never(), [mockEngine attachView]);
1052}

◆ testViewDidLoadWillInvokeCreateTouchRateCorrectionVSyncClient

- (void) testViewDidLoadWillInvokeCreateTouchRateCorrectionVSyncClient
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

231 {
232 FlutterEngine* engine = [[FlutterEngine alloc] init];
233 [engine runWithEntrypoint:nil];
234 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
235 nibName:nil
236 bundle:nil];
237 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
238 [viewControllerMock loadView];
239 [viewControllerMock viewDidLoad];
240 OCMVerify([viewControllerMock createTouchRateCorrectionVSyncClientIfNeeded]);
241}

◆ testViewWillTransitionToSize_DoesDelayEngineCallIfNonZeroDuration

- (void) testViewWillTransitionToSize_DoesDelayEngineCallIfNonZeroDuration
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

979 {
980 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
981 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
982 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
983 nibName:nil
984 bundle:nil];
985 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
986 UIScreen* screen = [self setUpMockScreen];
987 OCMStub([viewControllerMock flutterScreenIfViewLoaded]).andReturn(screen);
988 mockEngine.viewController = viewController;
989
990 // Mimic the device rotation with non-zero transition duration.
991 NSTimeInterval transitionDuration = 0.5;
992 id mockCoordinator = OCMProtocolMock(@protocol(UIViewControllerTransitionCoordinator));
993 OCMStub([mockCoordinator transitionDuration]).andReturn(transitionDuration);
994
995 flutter::ViewportMetrics viewportMetrics;
996 OCMExpect([mockEngine updateViewportMetrics:viewportMetrics]).ignoringNonObjectArgs();
997
998 [viewController viewWillTransitionToSize:CGSizeZero withTransitionCoordinator:mockCoordinator];
999 // Should not immediately call the engine (this request should be ignored).
1000 [viewController updateViewportMetricsIfNeeded];
1001 OCMVerify(never(), [mockEngine updateViewportMetrics:flutter::ViewportMetrics()]);
1002
1003 // Should delay the engine call for half of the transition duration.
1004 // Wait for additional transitionDuration to allow updateViewportMetrics calls if any.
1005 XCTWaiterResult result = [XCTWaiter
1006 waitForExpectations:@[ [self expectationWithDescription:@"Waiting for rotation duration"] ]
1007 timeout:transitionDuration];
1008 XCTAssertEqual(result, XCTWaiterResultTimedOut);
1009
1010 OCMVerifyAll(mockEngine);
1011}
GAsyncResult * result

◆ testViewWillTransitionToSize_DoesNotDelayEngineCallIfZeroDuration

- (void) testViewWillTransitionToSize_DoesNotDelayEngineCallIfZeroDuration
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1013 {
1014 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
1015 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
1016 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
1017 nibName:nil
1018 bundle:nil];
1019 FlutterViewController* viewControllerMock = OCMPartialMock(viewController);
1020 UIScreen* screen = [self setUpMockScreen];
1021 OCMStub([viewControllerMock flutterScreenIfViewLoaded]).andReturn(screen);
1022 mockEngine.viewController = viewController;
1023
1024 // Mimic the device rotation with zero transition duration.
1025 id mockCoordinator = OCMProtocolMock(@protocol(UIViewControllerTransitionCoordinator));
1026 OCMStub([mockCoordinator transitionDuration]).andReturn(0);
1027
1028 flutter::ViewportMetrics viewportMetrics;
1029 OCMExpect([mockEngine updateViewportMetrics:viewportMetrics]).ignoringNonObjectArgs();
1030
1031 // Should immediately trigger the engine call, without delay.
1032 [viewController viewWillTransitionToSize:CGSizeZero withTransitionCoordinator:mockCoordinator];
1033 [viewController updateViewportMetricsIfNeeded];
1034
1035 OCMVerifyAll(mockEngine);
1036}

◆ testWillDeallocNotification

- (void) testWillDeallocNotification
implementation

Definition at line 178 of file FlutterViewControllerTest.mm.

1605 {
1606 XCTestExpectation* expectation =
1607 [[XCTestExpectation alloc] initWithDescription:@"notification called"];
1608 id engine = [[MockEngine alloc] init];
1609 @autoreleasepool {
1610 // NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores)
1611 FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine
1612 nibName:nil
1613 bundle:nil];
1614 [[NSNotificationCenter defaultCenter] addObserverForName:FlutterViewControllerWillDealloc
1615 object:nil
1616 queue:[NSOperationQueue mainQueue]
1617 usingBlock:^(NSNotification* _Nonnull note) {
1618 [expectation fulfill];
1619 }];
1620 XCTAssertNotNil(realVC);
1621 realVC = nil;
1622 }
1623 [self waitForExpectations:@[ expectation ] timeout:1.0];
1624}

Property Documentation

◆ flutterViewController

- (FlutterViewController*) flutterViewController
readwritenonatomicstrong

Definition at line 13 of file FlutterViewControllerTest.m.

◆ messageSent

- (id) messageSent
readwritenonatomicstrong

Definition at line 172 of file FlutterViewControllerTest.mm.

◆ mockEngine

- (id) mockEngine
readwritenonatomicstrong

Definition at line 170 of file FlutterViewControllerTest.mm.

◆ mockTextInputPlugin

- (id) mockTextInputPlugin
readwritenonatomicstrong

Definition at line 171 of file FlutterViewControllerTest.mm.


The documentation for this class was generated from the following files: