Flutter Engine
The Flutter Engine
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 170 of file FlutterViewControllerTest.mm.

Method Documentation

◆ fakeTraitCollectionWithContrast:

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

Definition at line 179 of file FlutterViewControllerTest.mm.

1609 :(UIAccessibilityContrast)contrast {
1610 id mockTraitCollection = OCMClassMock([UITraitCollection class]);
1611 OCMStub([mockTraitCollection accessibilityContrast]).andReturn(contrast);
1612 return mockTraitCollection;
1613}

◆ fakeTraitCollectionWithUserInterfaceStyle:

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

Definition at line 179 of file FlutterViewControllerTest.mm.

1239 :(UIUserInterfaceStyle)style {
1240 id mockTraitCollection = OCMClassMock([UITraitCollection class]);
1241 OCMStub([mockTraitCollection userInterfaceStyle]).andReturn(style);
1242 return mockTraitCollection;
1243}

◆ ios [1/5]

- ios
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1837 {
1838 if (@available(iOS 13.4, *)) {
1839 // noop
1840 } else {
1841 return;
1842 }
1843
1844 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1845 nibName:nil
1846 bundle:nil];
1847 XCTAssertNotNil(vc);
1848
1849 id mockPanGestureRecognizer = OCMClassMock([UIPanGestureRecognizer class]);
1850 XCTAssertNotNil(mockPanGestureRecognizer);
1851
1852 [vc discreteScrollEvent:mockPanGestureRecognizer];
1853
1854 [[[self.mockEngine verify] ignoringNonObjectArgs]
1855 dispatchPointerDataPacket:std::make_unique<flutter::PointerDataPacket>(0)];
1856}
void discreteScrollEvent:(ios(13.4) API_AVAILABLE)

◆ ios [2/5]

- ios
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1811 {
1812 if (@available(iOS 13.4, *)) {
1813 // noop
1814 } else {
1815 return;
1816 }
1817
1818 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1819 nibName:nil
1820 bundle:nil];
1821 XCTAssertNotNil(vc);
1822 UIView* view = vc.view;
1823 XCTAssertNotNil(view);
1824 NSArray* gestureRecognizers = view.gestureRecognizers;
1825 XCTAssertNotNil(gestureRecognizers);
1826
1827 BOOL found = NO;
1828 for (id gesture in gestureRecognizers) {
1829 if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
1830 found = YES;
1831 break;
1832 }
1833 }
1834 XCTAssertTrue(found);
1835}
int BOOL
Definition: windows_types.h:37

◆ ios [3/5]

- ios
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1773 {
1774 if (@available(iOS 13.4, *)) {
1775 // noop
1776 } else {
1777 return;
1778 }
1779 id keyEventChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1780 OCMStub([keyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
1781 .andCall(self, @selector(sendMessage:reply:));
1782 OCMStub([self.mockTextInputPlugin handlePress:[OCMArg any]]).andReturn(YES);
1783 OCMStub([self.mockEngine keyEventChannel]).andReturn(keyEventChannel);
1784
1785 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1786 nibName:nil
1787 bundle:nil];
1788
1789 // Allocate the keyboard manager in the view controller by adding the internal
1790 // plugins.
1791 [vc addInternalPlugins];
1792
1793 [vc handlePressEvent:keyEventWithPhase(UIPressPhaseStationary, UIKeyboardHIDUsageKeyboardA,
1794 UIKeyModifierShift, 123.0)
1795 nextAction:^(){
1796 }];
1797 [vc handlePressEvent:keyEventWithPhase(UIPressPhaseCancelled, UIKeyboardHIDUsageKeyboardA,
1798 UIKeyModifierShift, 123.0)
1799 nextAction:^(){
1800 }];
1801 [vc handlePressEvent:keyEventWithPhase(UIPressPhaseChanged, UIKeyboardHIDUsageKeyboardA,
1802 UIKeyModifierShift, 123.0)
1803 nextAction:^(){
1804 }];
1805
1806 XCTAssert(self.messageSent == nil);
1807 OCMVerify(never(), [keyEventChannel sendMessage:[OCMArg any]]);
1809}
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 179 of file FlutterViewControllerTest.mm.

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

◆ ios [5/5]

- ios
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ orientationTestWithOrientationUpdate:currentOrientation:didChangeOrientation:resultingOrientation:

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

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ sendMessage:reply:

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

Definition at line 179 of file FlutterViewControllerTest.mm.

1688 :(id _Nullable)message reply:(FlutterReply _Nullable)callback {
1689 NSMutableDictionary* replyMessage = [@{
1690 @"handled" : @YES,
1691 } mutableCopy];
1692 // Response is async, so we have to post it to the run loop instead of calling
1693 // it directly.
1694 self.messageSent = message;
1695 CFRunLoopPerformBlock(CFRunLoopGetCurrent(), fml::MessageLoopDarwin::kMessageLoopCFRunLoopMode,
1696 ^() {
1697 callback(replyMessage);
1698 });
1699}
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 179 of file FlutterViewControllerTest.mm.

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

◆ setUpMockScreen

- (id) setUpMockScreen
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ setUpMockView:screen:viewFrame:convertedFrame:

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

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ tearDown

- (void) tearDown
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testAccessibilityPerformEscapePopsRoute

- (void) testAccessibilityPerformEscapePopsRoute
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1378 {
1379 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
1380 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
1381 id mockNavigationChannel = OCMClassMock([FlutterMethodChannel class]);
1382 OCMStub([mockEngine navigationChannel]).andReturn(mockNavigationChannel);
1383
1384 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
1385 nibName:nil
1386 bundle:nil];
1387 XCTAssertTrue([viewController accessibilityPerformEscape]);
1388
1389 OCMVerify([mockNavigationChannel invokeMethod:@"popRoute" arguments:nil]);
1390
1391 [mockNavigationChannel stopMocking];
1392}
BOOL createShell:libraryURI:initialRoute:(NSString *entrypoint, [libraryURI] NSString *libraryURI, [initialRoute] NSString *initialRoute)
FlutterViewController * viewController
static bool init()

◆ testAppWillTerminateViewDidDestroyTheEngine

- (void) testAppWillTerminateViewDidDestroyTheEngine
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testBinaryMessenger

- (void) testBinaryMessenger
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testCalculateKeyboardAttachMode

- (void) testCalculateKeyboardAttachMode
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testCalculateKeyboardInset

- (void) testCalculateKeyboardInset
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testCalculateMultitaskingAdjustment

- (void) testCalculateMultitaskingAdjustment
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testCreateTouchRateCorrectionVSyncClientWillCreateVsyncClientWhenRefreshRateIsLargerThan60HZ

- (void) testCreateTouchRateCorrectionVSyncClientWillCreateVsyncClientWhenRefreshRateIsLargerThan60HZ
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

2089 {
2090 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
2091 double maxFrameRate = 120;
2092 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
2093 FlutterEngine* engine = [[FlutterEngine alloc] init];
2094 [engine runWithEntrypoint:nil];
2095 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2096 nibName:nil
2097 bundle:nil];
2100}
FlutterEngine engine
Definition: main.cc:68
BOOL runWithEntrypoint:(nullable NSString *entrypoint)
VSyncClient * touchRateCorrectionVSyncClient

◆ testCreateTouchRateCorrectionVSyncClientWillNotCreateNewVSyncClientWhenClientAlreadyExists

- (void) testCreateTouchRateCorrectionVSyncClientWillNotCreateNewVSyncClientWhenClientAlreadyExists
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

2102 {
2103 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
2104 double maxFrameRate = 120;
2105 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
2106
2107 FlutterEngine* engine = [[FlutterEngine alloc] init];
2108 [engine runWithEntrypoint:nil];
2109 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2110 nibName:nil
2111 bundle:nil];
2114 XCTAssertNotNil(clientBefore);
2115
2118 XCTAssertNotNil(clientAfter);
2119
2120 XCTAssertTrue(clientBefore == clientAfter);
2121}

◆ testCreateTouchRateCorrectionVSyncClientWillNotCreateVsyncClientWhenRefreshRateIs60HZ

- (void) testCreateTouchRateCorrectionVSyncClientWillNotCreateVsyncClientWhenRefreshRateIs60HZ
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

2123 {
2124 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
2125 double maxFrameRate = 60;
2126 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
2127 FlutterEngine* engine = [[FlutterEngine alloc] init];
2128 [engine runWithEntrypoint:nil];
2129 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2130 nibName:nil
2131 bundle:nil];
2134}

◆ testDoesntLoadViewInInit

- (void) testDoesntLoadViewInInit
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1651 {
1652 FlutterDartProject* project = [[FlutterDartProject alloc] init];
1653 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
1654 [engine createShell:@"" libraryURI:@"" initialRoute:nil];
1655 FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine
1656 nibName:nil
1657 bundle:nil];
1658 XCTAssertFalse([realVC isViewLoaded], @"shouldn't have loaded since it hasn't been shown");
1659 engine.viewController = nil;
1660}
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}
UIWindow * window
Definition: AppDelegate.h:12
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 179 of file FlutterViewControllerTest.mm.

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

◆ testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewWillAppear

- (void) testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewWillAppear
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewWillDisappear

- (void) testEngineConfigSyncMethodWillExecuteWhenViewControllerInEngineIsCurrentViewControllerInViewWillDisappear
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewDidAppear

- (void) testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewDidAppear
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewWillAppear

- (void) testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewWillAppear
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewWillDisappear

- (void) testEngineConfigSyncMethodWillNotExecuteWhenViewControllerInEngineIsNotCurrentViewControllerInViewWillDisappear
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testEnsureBottomInsetIsZeroWhenKeyboardDismissed

- (void) testEnsureBottomInsetIsZeroWhenKeyboardDismissed
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testEnsureViewportMetricsWillInvokeAndDisplayLinkWillInvalidateInViewDidDisappear

- (void) testEnsureViewportMetricsWillInvokeAndDisplayLinkWillInvalidateInViewDidDisappear
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testFakeEventTimeStamp

- (void) testFakeEventTimeStamp
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1858 {
1859 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1860 nibName:nil
1861 bundle:nil];
1862 XCTAssertNotNil(vc);
1863
1865 int64_t current_micros = [[NSProcessInfo processInfo] systemUptime] * 1000 * 1000;
1866 int64_t interval_micros = current_micros - pointer_data.time_stamp;
1867 const int64_t tolerance_millis = 2;
1868 XCTAssertTrue(interval_micros / 1000 < tolerance_millis,
1869 @"PointerData.time_stamp should be equal to NSProcessInfo.systemUptime");
1870}
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 179 of file FlutterViewControllerTest.mm.

2195 {
2196 FlutterEngine* engine = [[FlutterEngine alloc] init];
2197 [engine runWithEntrypoint:nil];
2198 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2199 nibName:nil
2200 bundle:nil];
2202 [viewController startKeyBoardAnimation:0.25];
2204}
void startKeyBoardAnimation:(NSTimeInterval duration)
VSyncClient * keyboardAnimationVSyncClient

◆ testHandleKeyboardNotification

- (void) testHandleKeyboardNotification
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testHideOverlay

- (void) testHideOverlay
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1662 {
1663 FlutterDartProject* project = [[FlutterDartProject alloc] init];
1664 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"foobar" project:project];
1665 [engine createShell:@"" libraryURI:@"" initialRoute:nil];
1666 FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine
1667 nibName:nil
1668 bundle:nil];
1669 XCTAssertFalse(realVC.prefersHomeIndicatorAutoHidden, @"");
1670 [[NSNotificationCenter defaultCenter] postNotificationName:FlutterViewControllerHideHomeIndicator
1671 object:nil];
1672 XCTAssertTrue(realVC.prefersHomeIndicatorAutoHidden, @"");
1673 engine.viewController = nil;
1674}

◆ testInternalPluginsInvokeInViewDidLoad

- (void) testInternalPluginsInvokeInViewDidLoad
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testInternalPluginsWeakPtrNotCrash

- (void) testInternalPluginsWeakPtrNotCrash
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testItReportsAccessibilityOnOffSwitchLabelsFlagNotSet

- (void) testItReportsAccessibilityOnOffSwitchLabelsFlagNotSet
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1338 {
1339 if (@available(iOS 13, *)) {
1340 // noop
1341 } else {
1342 return;
1343 }
1344
1345 // Setup test.
1347 [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil];
1348 id partialMockViewController = OCMPartialMock(viewController);
1349 OCMStub([partialMockViewController accessibilityIsOnOffSwitchLabelsEnabled]).andReturn(NO);
1350
1351 // Exercise behavior under test.
1352 int32_t flags = [partialMockViewController accessibilityFlags];
1353
1354 // Verify behavior.
1356}
FlutterSemanticsFlag flags

◆ testItReportsAccessibilityOnOffSwitchLabelsFlagSet

- (void) testItReportsAccessibilityOnOffSwitchLabelsFlagSet
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1358 {
1359 if (@available(iOS 13, *)) {
1360 // noop
1361 } else {
1362 return;
1363 }
1364
1365 // Setup test.
1367 [[FlutterViewController alloc] initWithEngine:self.mockEngine nibName:nil bundle:nil];
1368 id partialMockViewController = OCMPartialMock(viewController);
1369 OCMStub([partialMockViewController accessibilityIsOnOffSwitchLabelsEnabled]).andReturn(YES);
1370
1371 // Exercise behavior under test.
1372 int32_t flags = [partialMockViewController accessibilityFlags];
1373
1374 // Verify behavior.
1376}

◆ testItReportsDarkPlatformBrightnessWhenTraitCollectionRequestsIt

- (void) testItReportsDarkPlatformBrightnessWhenTraitCollectionRequestsIt
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testItReportsHighContrastWhenTraitCollectionRequestsIt

- (void) testItReportsHighContrastWhenTraitCollectionRequestsIt
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testItReportsLightPlatformBrightnessByDefault

- (void) testItReportsLightPlatformBrightnessByDefault
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1158 {
1159 // Setup test.
1160 id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1161 OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel);
1162
1163 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1164 nibName:nil
1165 bundle:nil];
1166
1167 // Exercise behavior under test.
1168 [vc traitCollectionDidChange:nil];
1169
1170 // Verify behavior.
1171 OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
1172 return [message[@"platformBrightness"] isEqualToString:@"light"];
1173 }]]);
1174
1175 // Clean up mocks
1176 [settingsChannel stopMocking];
1177}
void traitCollectionDidChange:(UITraitCollection *previousTraitCollection)

◆ testItReportsNormalPlatformContrastByDefault

- (void) testItReportsNormalPlatformContrastByDefault
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1247 {
1248 if (@available(iOS 13, *)) {
1249 // noop
1250 } else {
1251 return;
1252 }
1253
1254 // Setup test.
1255 id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1256 OCMStub([self.mockEngine settingsChannel]).andReturn(settingsChannel);
1257
1258 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:self.mockEngine
1259 nibName:nil
1260 bundle:nil];
1261
1262 // Exercise behavior under test.
1263 [vc traitCollectionDidChange:nil];
1264
1265 // Verify behavior.
1266 OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
1267 return [message[@"platformContrast"] isEqualToString:@"normal"];
1268 }]]);
1269
1270 // Clean up mocks
1271 [settingsChannel stopMocking];
1272}

◆ testItReportsPlatformBrightnessWhenViewWillAppear

- (void) testItReportsPlatformBrightnessWhenViewWillAppear
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1179 {
1180 // Setup test.
1181 id settingsChannel = OCMClassMock([FlutterBasicMessageChannel class]);
1182 FlutterEngine* mockEngine = OCMPartialMock([[FlutterEngine alloc] init]);
1183 [mockEngine createShell:@"" libraryURI:@"" initialRoute:nil];
1184 OCMStub([mockEngine settingsChannel]).andReturn(settingsChannel);
1185 FlutterViewController* vc = [[FlutterViewController alloc] initWithEngine:mockEngine
1186 nibName:nil
1187 bundle:nil];
1188
1189 // Exercise behavior under test.
1190 [vc viewWillAppear:false];
1191
1192 // Verify behavior.
1193 OCMVerify([settingsChannel sendMessage:[OCMArg checkWithBlock:^BOOL(id message) {
1194 return [message[@"platformBrightness"] isEqualToString:@"light"];
1195 }]]);
1196
1197 // Clean up mocks
1198 [settingsChannel stopMocking];
1199}

◆ testItReportsPlatformContrastWhenViewWillAppear

- (void) testItReportsPlatformContrastWhenViewWillAppear
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testKeyboardAnimationIsShowingAndCompounding

- (void) testKeyboardAnimationIsShowingAndCompounding
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testKeyboardAnimationWillNotCrashWhenEngineDestroyed

- (void) testKeyboardAnimationWillNotCrashWhenEngineDestroyed
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testKeyboardAnimationWillWaitUIThreadVsync

- (void) testKeyboardAnimationWillWaitUIThreadVsync
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testLifeCycleNotificationBecameActive

- (void) testLifeCycleNotificationBecameActive
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testLifeCycleNotificationCancelledInvalidResumed

- (void) testLifeCycleNotificationCancelledInvalidResumed
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testLifeCycleNotificationDidEnterBackground

- (void) testLifeCycleNotificationDidEnterBackground
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1973 {
1974 FlutterEngine* engine = [[FlutterEngine alloc] init];
1975 [engine runWithEntrypoint:nil];
1977 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
1978 NSNotification* sceneNotification =
1979 [NSNotification notificationWithName:UISceneDidEnterBackgroundNotification
1980 object:nil
1981 userInfo:nil];
1982 NSNotification* applicationNotification =
1983 [NSNotification notificationWithName:UIApplicationDidEnterBackgroundNotification
1984 object:nil
1985 userInfo:nil];
1986 id mockVC = OCMPartialMock(flutterViewController);
1987 [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
1988 [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
1989#if APPLICATION_EXTENSION_API_ONLY
1990 OCMVerify([mockVC sceneDidEnterBackground:[OCMArg any]]);
1991 OCMReject([mockVC applicationDidEnterBackground:[OCMArg any]]);
1992#else
1993 OCMReject([mockVC sceneDidEnterBackground:[OCMArg any]]);
1994 OCMVerify([mockVC applicationDidEnterBackground:[OCMArg any]]);
1995#endif
1997 OCMVerify([mockVC surfaceUpdated:NO]);
1998 OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.paused"]);
1999 [flutterViewController deregisterNotifications];
2000}

◆ testLifeCycleNotificationWillEnterForeground

- (void) testLifeCycleNotificationWillEnterForeground
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

2002 {
2003 FlutterEngine* engine = [[FlutterEngine alloc] init];
2004 [engine runWithEntrypoint:nil];
2006 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
2007 NSNotification* sceneNotification =
2008 [NSNotification notificationWithName:UISceneWillEnterForegroundNotification
2009 object:nil
2010 userInfo:nil];
2011 NSNotification* applicationNotification =
2012 [NSNotification notificationWithName:UIApplicationWillEnterForegroundNotification
2013 object:nil
2014 userInfo:nil];
2015 id mockVC = OCMPartialMock(flutterViewController);
2016 [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
2017 [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
2018#if APPLICATION_EXTENSION_API_ONLY
2019 OCMVerify([mockVC sceneWillEnterForeground:[OCMArg any]]);
2020 OCMReject([mockVC applicationWillEnterForeground:[OCMArg any]]);
2021#else
2022 OCMReject([mockVC sceneWillEnterForeground:[OCMArg any]]);
2023 OCMVerify([mockVC applicationWillEnterForeground:[OCMArg any]]);
2024#endif
2025 OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.inactive"]);
2026 [flutterViewController deregisterNotifications];
2027}

◆ testLifeCycleNotificationWillResignActive

- (void) testLifeCycleNotificationWillResignActive
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1916 {
1917 FlutterEngine* engine = [[FlutterEngine alloc] init];
1918 [engine runWithEntrypoint:nil];
1920 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
1921 NSNotification* sceneNotification =
1922 [NSNotification notificationWithName:UISceneWillDeactivateNotification
1923 object:nil
1924 userInfo:nil];
1925 NSNotification* applicationNotification =
1926 [NSNotification notificationWithName:UIApplicationWillResignActiveNotification
1927 object:nil
1928 userInfo:nil];
1929 id mockVC = OCMPartialMock(flutterViewController);
1930 [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
1931 [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
1932#if APPLICATION_EXTENSION_API_ONLY
1933 OCMVerify([mockVC sceneWillResignActive:[OCMArg any]]);
1934 OCMReject([mockVC applicationWillResignActive:[OCMArg any]]);
1935#else
1936 OCMReject([mockVC sceneWillResignActive:[OCMArg any]]);
1937 OCMVerify([mockVC applicationWillResignActive:[OCMArg any]]);
1938#endif
1939 OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.inactive"]);
1940 [flutterViewController deregisterNotifications];
1941}

◆ testLifeCycleNotificationWillTerminate

- (void) testLifeCycleNotificationWillTerminate
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1943 {
1944 FlutterEngine* engine = [[FlutterEngine alloc] init];
1945 [engine runWithEntrypoint:nil];
1947 [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
1948 NSNotification* sceneNotification =
1949 [NSNotification notificationWithName:UISceneDidDisconnectNotification
1950 object:nil
1951 userInfo:nil];
1952 NSNotification* applicationNotification =
1953 [NSNotification notificationWithName:UIApplicationWillTerminateNotification
1954 object:nil
1955 userInfo:nil];
1956 id mockVC = OCMPartialMock(flutterViewController);
1957 id mockEngine = OCMPartialMock(engine);
1958 OCMStub([mockVC engine]).andReturn(mockEngine);
1959 [[NSNotificationCenter defaultCenter] postNotification:sceneNotification];
1960 [[NSNotificationCenter defaultCenter] postNotification:applicationNotification];
1961#if APPLICATION_EXTENSION_API_ONLY
1962 OCMVerify([mockVC sceneWillDisconnect:[OCMArg any]]);
1963 OCMReject([mockVC applicationWillTerminate:[OCMArg any]]);
1964#else
1965 OCMReject([mockVC sceneWillDisconnect:[OCMArg any]]);
1966 OCMVerify([mockVC applicationWillTerminate:[OCMArg any]]);
1967#endif
1968 OCMVerify([mockVC goToApplicationLifecycle:@"AppLifecycleState.detached"]);
1969 OCMVerify([mockEngine destroyContext]);
1970 [flutterViewController deregisterNotifications];
1971}

◆ testNotifyLowMemory

- (void) testNotifyLowMemory
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1676 {
1678 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:mockEngine
1679 nibName:nil
1680 bundle:nil];
1681 id viewControllerMock = OCMPartialMock(viewController);
1682 OCMStub([viewControllerMock surfaceUpdated:NO]);
1683 [viewController beginAppearanceTransition:NO animated:NO];
1684 [viewController endAppearanceTransition];
1685 XCTAssertTrue(mockEngine.didCallNotifyLowMemory);
1686}

◆ testPerformOrientationUpdateDoesNotForceOrientationChange

- (void) testPerformOrientationUpdateDoesNotForceOrientationChange
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testPerformOrientationUpdateForcesOrientationChange

- (void) testPerformOrientationUpdateForcesOrientationChange
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testReleasesKeyboardManagerOnDealloc

- (void) testReleasesKeyboardManagerOnDealloc
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1636 {
1637 __weak FlutterKeyboardManager* weakKeyboardManager = nil;
1638 @autoreleasepool {
1640
1641 [viewController addInternalPlugins];
1642 weakKeyboardManager = viewController.keyboardManager;
1643 XCTAssertNotNil(weakKeyboardManager);
1644 [viewController deregisterNotifications];
1645 viewController = nil;
1646 }
1647 // View controller has released the keyboard manager.
1648 XCTAssertNil(weakKeyboardManager);
1649}

◆ testSetupKeyboardAnimationVsyncClientWillCreateNewVsyncClientForFlutterViewController

- (void) testSetupKeyboardAnimationVsyncClientWillCreateNewVsyncClientForFlutterViewController
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

2061 {
2062 id bundleMock = OCMPartialMock([NSBundle mainBundle]);
2063 OCMStub([bundleMock objectForInfoDictionaryKey:@"CADisableMinimumFrameDurationOnPhone"])
2064 .andReturn(@YES);
2065 id mockDisplayLinkManager = [OCMockObject mockForClass:[DisplayLinkManager class]];
2066 double maxFrameRate = 120;
2067 [[[mockDisplayLinkManager stub] andReturnValue:@(maxFrameRate)] displayRefreshRate];
2068 FlutterEngine* engine = [[FlutterEngine alloc] init];
2069 [engine runWithEntrypoint:nil];
2070 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2071 nibName:nil
2072 bundle:nil];
2074 };
2075 [viewController setUpKeyboardAnimationVsyncClient:callback];
2077 CADisplayLink* link = [viewController.keyboardAnimationVSyncClient getDisplayLink];
2078 XCTAssertNotNil(link);
2079 if (@available(iOS 15.0, *)) {
2080 XCTAssertEqual(link.preferredFrameRateRange.maximum, maxFrameRate);
2081 XCTAssertEqual(link.preferredFrameRateRange.preferred, maxFrameRate);
2082 XCTAssertEqual(link.preferredFrameRateRange.minimum, maxFrameRate / 2);
2083 } else {
2084 XCTAssertEqual(link.preferredFramesPerSecond, maxFrameRate);
2085 }
2086}
def link(from_root, to_root)
Definition: dart_pkg.py:44

◆ testSetupKeyboardAnimationVsyncClientWillNotCreateNewVsyncClientWhenKeyboardAnimationCallbackIsNil

- (void) testSetupKeyboardAnimationVsyncClientWillNotCreateNewVsyncClientWhenKeyboardAnimationCallbackIsNil
implementation

Definition at line 179 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 [viewController setUpKeyboardAnimationVsyncClient:nil];
2215}

◆ testSetupKeyboardSpringAnimationIfNeeded

- (void) testSetupKeyboardSpringAnimationIfNeeded
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testShouldIgnoreKeyboardNotification

- (void) testShouldIgnoreKeyboardNotification
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testSplashScreenViewCanSetNil

- (void) testSplashScreenViewCanSetNil
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1872 {
1874 [[FlutterViewController alloc] initWithProject:nil nibName:nil bundle:nil];
1875 [flutterViewController setSplashScreenView:nil];
1876}
void setSplashScreenView:(UIView *view)

◆ testSplashScreenViewRemoveNotCrash

- (void) testSplashScreenViewRemoveNotCrash
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testStartKeyboardAnimationWillInvokeSetupKeyboardSpringAnimationIfNeeded

- (void) testStartKeyboardAnimationWillInvokeSetupKeyboardSpringAnimationIfNeeded
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testSupportsShowingSystemContextMenuForIOS16AndAbove

- (void) testSupportsShowingSystemContextMenuForIOS16AndAbove
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

2217 {
2218 FlutterEngine* engine = [[FlutterEngine alloc] init];
2219 [engine runWithEntrypoint:nil];
2220 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2221 nibName:nil
2222 bundle:nil];
2223 BOOL supportsShowingSystemContextMenu = [viewController supportsShowingSystemContextMenu];
2224 if (@available(iOS 16.0, *)) {
2225 XCTAssertTrue(supportsShowingSystemContextMenu);
2226 } else {
2227 XCTAssertFalse(supportsShowingSystemContextMenu);
2228 }
2229}

◆ testTriggerTouchRateCorrectionVSyncClientCorrectly

- (void) testTriggerTouchRateCorrectionVSyncClientCorrectly
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testUpdateViewportMetricsIfNeeded_DoesInvokeEngineWhenIsTheViewController

- (void) testUpdateViewportMetricsIfNeeded_DoesInvokeEngineWhenIsTheViewController
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testUpdateViewportMetricsIfNeeded_DoesNotInvokeEngineWhenShouldBeIgnoredDuringRotation

- (void) testUpdateViewportMetricsIfNeeded_DoesNotInvokeEngineWhenShouldBeIgnoredDuringRotation
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testUpdateViewportMetricsIfNeeded_DoesntInvokeEngineWhenNotTheViewController

- (void) testUpdateViewportMetricsIfNeeded_DoesntInvokeEngineWhenNotTheViewController
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testViewControllerIsReleased

- (void) testViewControllerIsReleased
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1137 {
1138 __weak FlutterViewController* weakViewController;
1139 __weak UIView* weakView;
1140 @autoreleasepool {
1141 FlutterEngine* engine = [[FlutterEngine alloc] init];
1142
1143 [engine runWithEntrypoint:nil];
1144 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
1145 nibName:nil
1146 bundle:nil];
1147 weakViewController = viewController;
1148 [viewController viewDidLoad];
1149 weakView = viewController.view;
1150 XCTAssertTrue([viewController.view isKindOfClass:[FlutterView class]]);
1151 }
1152 XCTAssertNil(weakViewController);
1153 XCTAssertNil(weakView);
1154}

◆ testViewDidDisappearDoesntPauseEngineWhenNotTheViewController

- (void) testViewDidDisappearDoesntPauseEngineWhenNotTheViewController
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testViewDidDisappearDoesPauseEngineWhenIsTheViewController

- (void) testViewDidDisappearDoesPauseEngineWhenIsTheViewController
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testViewDidLoadDoesInvokeEngineWhenIsTheViewController

- (void) testViewDidLoadDoesInvokeEngineWhenIsTheViewController
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testViewDidLoadDoesntInvokeEngineAttachViewWhenEngineNeedsLaunch

- (void) testViewDidLoadDoesntInvokeEngineAttachViewWhenEngineNeedsLaunch
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testViewDidLoadDoesntInvokeEngineWhenNotTheViewController

- (void) testViewDidLoadDoesntInvokeEngineWhenNotTheViewController
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testViewDidLoadWillInvokeCreateTouchRateCorrectionVSyncClient

- (void) testViewDidLoadWillInvokeCreateTouchRateCorrectionVSyncClient
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testViewWillTransitionToSize_DoesDelayEngineCallIfNonZeroDuration

- (void) testViewWillTransitionToSize_DoesDelayEngineCallIfNonZeroDuration
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testViewWillTransitionToSize_DoesNotDelayEngineCallIfZeroDuration

- (void) testViewWillTransitionToSize_DoesNotDelayEngineCallIfZeroDuration
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

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

◆ testWillDeallocNotification

- (void) testWillDeallocNotification
implementation

Definition at line 179 of file FlutterViewControllerTest.mm.

1615 {
1616 XCTestExpectation* expectation =
1617 [[XCTestExpectation alloc] initWithDescription:@"notification called"];
1618 id engine = [[MockEngine alloc] init];
1619 @autoreleasepool {
1620 // NOLINTNEXTLINE(clang-analyzer-deadcode.DeadStores)
1621 FlutterViewController* realVC = [[FlutterViewController alloc] initWithEngine:engine
1622 nibName:nil
1623 bundle:nil];
1624 [[NSNotificationCenter defaultCenter] addObserverForName:FlutterViewControllerWillDealloc
1625 object:nil
1626 queue:[NSOperationQueue mainQueue]
1627 usingBlock:^(NSNotification* _Nonnull note) {
1628 [expectation fulfill];
1629 }];
1630 XCTAssertNotNil(realVC);
1631 realVC = nil;
1632 }
1633 [self waitForExpectations:@[ expectation ] timeout:1.0];
1634}

Property Documentation

◆ flutterViewController

- (FlutterViewController*) flutterViewController
readwritenonatomicstrong

Definition at line 13 of file FlutterViewControllerTest.m.

◆ messageSent

- (id) messageSent
readwritenonatomicstrong

Definition at line 173 of file FlutterViewControllerTest.mm.

◆ mockEngine

- (id) mockEngine
readwritenonatomicstrong

Definition at line 171 of file FlutterViewControllerTest.mm.

◆ mockTextInputPlugin

- (id) mockTextInputPlugin
readwritenonatomicstrong

Definition at line 172 of file FlutterViewControllerTest.mm.


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