| Flutter macOS Embedder |

Classes | Typedefs | Functions | Variables
flutter::testing Namespace Reference

## Classes
class | FlutterEngineTest
class | MockFlutterEngineTest
class | FlutterMenuPluginTest
class | FlutterWindowControllerTest
class | FlutterWindowControllerRetainTest

## Typedefs
using | FlutterChannelKeyResponderTest = AutoreleasePoolTest
using | FlutterEmbedderExternalTextureTest = AutoreleasePoolTest
using | FlutterViewControllerTest = AutoreleasePoolTest
using | FlutterViewControllerMockEngineTest = MockFlutterEngineTest

## Functions
| TEST_F (AccessibilityBridgeMacWindowTest, SendsAccessibilityCreateNotificationFlutterViewWindow)
| TEST_F (AccessibilityBridgeMacWindowTest, NonZeroRootNodeId)
| TEST_F (AccessibilityBridgeMacTest, DoesNotSendAccessibilityCreateNotificationWhenHeadless)
| TEST_F (AccessibilityBridgeMacTest, DoesNotSendAccessibilityCreateNotificationWhenNoWindow)
| TEST (FlutterAppDelegateTest, DoesNotCallDelegatesWithoutHandler)
| TEST (FlutterAppDelegateTest, ReceivesOpenURLs)
| TEST (FlutterAppDelegateTest, OperURLsStopsAfterHandled)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToWillFinishLaunching)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToDidFinishLaunching)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToWillBecomeActive)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToDidBecomeActive)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToWillResignActive)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToDidResignActive)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToWillTerminate)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToWillHide)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToWillUnhide)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToDidHide)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToDidUnhide)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToDidChangeScreenParameters)
| TEST (FlutterAppLifecycleDelegateTest, RespondsToDidChangeOcclusionState)
| TEST (FlutterAppLifecycleDelegateTest, ReleasesDelegateOnDealloc)
| TEST_F (FlutterChannelKeyResponderTest, BasicKeyEvent)
| TEST_F (FlutterChannelKeyResponderTest, EmptyResponseIsTakenAsHandled)
| TEST_F (FlutterChannelKeyResponderTest, FollowsLayoutMap)
| TEST_F (FlutterEmbedderExternalTextureTest, TestTextureResolution)
| TEST_F (FlutterEmbedderExternalTextureTest, TestPopulateExternalTexture)
| TEST_F (FlutterEmbedderExternalTextureTest, TestPopulateExternalTextureYUVA)
| TEST_F (FlutterEmbedderExternalTextureTest, TestPopulateExternalTextureYUVA2)
| TEST_F (FlutterEmbedderExternalTextureTest, TestPopulateUnsupportedExternalTexture)
| TEST_F (FlutterEmbedderExternalTextureTest, TestTextureResolutionImpeller)
| TEST_F (FlutterEmbedderExternalTextureTest, TestPopulateExternalTextureImpeller)
| TEST_F (FlutterEmbedderExternalTextureTest, TestPopulateExternalTextureYUVAImpeller)
| TEST_F (FlutterEmbedderExternalTextureTest, TestPopulateExternalTextureYUVA2Impeller)
| TEST_F (FlutterEmbedderExternalTextureTest, TestPopulateUnsupportedExternalTextureImpeller)
| TEST (FlutterEmbedderKeyResponderUnittests, BasicKeyEvent)
| TEST (FlutterEmbedderKeyResponderUnittests, NonAsciiCharacters)
| TEST (FlutterEmbedderKeyResponderUnittests, MultipleCharacters)
| TEST (FlutterEmbedderKeyResponderUnittests, SynthesizeForDuplicateDownEvent)
| TEST (FlutterEmbedderKeyResponderUnittests, IgnoreDuplicateUpEvent)
| TEST (FlutterEmbedderKeyResponderUnittests, ConvertAbruptRepeatEventsToDown)
| TEST (FlutterEmbedderKeyResponderUnittests, ToggleModifiersDuringKeyTap)
| TEST (FlutterEmbedderKeyResponderUnittests, SpecialModiferFlags)
| TEST (FlutterEmbedderKeyResponderUnittests, IdentifyLeftAndRightModifiers)
| TEST (FlutterEmbedderKeyResponderUnittests, SynthesizeMissedModifierEvents)
| TEST (FlutterEmbedderKeyResponderUnittests, SynthesizeMissedModifierEventsInNormalEvents)
| TEST (FlutterEmbedderKeyResponderUnittests, ConvertCapsLockEvents)
| TEST (FlutterEmbedderKeyResponderUnittests, SynchronizeCapsLockStateOnCapsLock)
| TEST (FlutterEmbedderKeyResponderUnittests, SynchronizeCapsLockStateOnNormalKey)
| TEST_F (FlutterEngineTest, CanLaunch)
| TEST_F (FlutterEngineTest, HasNonNullExecutableName)
| TEST_F (FlutterEngineTest, Switches)
| TEST_F (FlutterEngineTest, MessengerSend)
| TEST_F (FlutterEngineTest, CanLogToStdout)
| TEST_F (FlutterEngineTest, DISABLED_BackgroundIsBlack)
| TEST_F (FlutterEngineTest, DISABLED_CanOverrideBackgroundColor)
| TEST_F (FlutterEngineTest, CanToggleAccessibility)
| TEST_F (FlutterEngineTest, CanToggleAccessibilityWhenHeadless)
| TEST_F (FlutterEngineTest, ProducesAccessibilityTreeWhenAddingViews)
| TEST_F (FlutterEngineTest, NativeCallbacks)
| TEST_F (FlutterEngineTest, Compositor)
| TEST_F (FlutterEngineTest, CompositorIgnoresUnknownView)
| TEST_F (FlutterEngineTest, DartEntrypointArguments)
| TEST_F (FlutterEngineTest, FlutterBinaryMessengerDoesNotRetainEngine)
| TEST_F (FlutterEngineTest, FlutterTextureRegistryDoesNotReturnEngine)
| TEST_F (FlutterEngineTest, PublishedValueNilForUnknownPlugin)
| TEST_F (FlutterEngineTest, PublishedValueNSNullIfNoPublishedValue)
| TEST_F (FlutterEngineTest, PublishedValueReturnsLastPublished)
| TEST_F (FlutterEngineTest, RegistrarForwardViewControllerLookUpToEngine)
| TEST_F (FlutterEngineTest, MessengerCleanupConnectionWorks)
| TEST_F (FlutterEngineTest, HasStringsWhenPasteboardEmpty)
| TEST_F (FlutterEngineTest, HasStringsWhenPasteboardFull)
| TEST_F (FlutterEngineTest, ResponseAfterEngineDied)
| TEST_F (FlutterEngineTest, ResponseFromBackgroundThread)
| TEST_F (FlutterEngineTest, CanGetEngineForId)
| TEST_F (FlutterEngineTest, ResizeSynchronizerNotBlockingRasterThreadAfterShutdown)
| TEST_F (FlutterEngineTest, ManageControllersIfInitiatedByController)
| TEST_F (FlutterEngineTest, ManageControllersIfInitiatedByEngine)
| TEST_F (FlutterEngineTest, RemovingViewDisposesCompositorResources)
| TEST_F (FlutterEngineTest, HandlesTerminationRequest)
| TEST_F (FlutterEngineTest, IgnoresTerminationRequestIfNotFlutterAppDelegate)
| TEST_F (FlutterEngineTest, HandleAccessibilityEvent)
| TEST_F (FlutterEngineTest, HandleLifecycleStates) API_AVAILABLE(macos(10.9))
| TEST_F (FlutterEngineTest, ForwardsPluginDelegateRegistration)
| TEST_F (FlutterEngineTest, UnregistersPluginsOnEngineDestruction)
| TEST_F (FlutterEngineTest, RunWithEntrypointUpdatesDisplayConfig)
| TEST_F (FlutterEngineTest, NotificationsUpdateDisplays)
| TEST_F (FlutterEngineTest, DisplaySizeIsInPhysicalPixel)
| TEST_F (FlutterEngineTest, ReportsHourFormat)
id | CreateMockFlutterEngine (NSString *pasteboardString)
| TEST (FlutterKeyboardManagerUnittests, SinglePrimaryResponder)
| TEST (FlutterKeyboardManagerUnittests, DoublePrimaryResponder)
| TEST (FlutterKeyboardManagerUnittests, SingleFinalResponder)
| TEST (FlutterKeyboardManagerUnittests, EmptyNextResponder)
| TEST (FlutterKeyboardManagerUnittests, GetPressedState)
| TEST (FlutterKeyboardManagerUnittests, KeyboardChannelGetPressedState)
| TEST (FlutterKeyboardManagerUnittests, RacingConditionBetweenKeyAndText)
| TEST (FlutterKeyboardManagerUnittests, CorrectLogicalKeyForLayouts)
| TEST (FlutterKeyboardManagerUnittests, ShouldNotHoldStrongReferenceToDelegate)
| TEST_F (FlutterMenuPluginTest, TestSetMenu)
| TEST (FlutterPlatformNodeDelegateMac, Basics)
| TEST (FlutterPlatformNodeDelegateMac, SelectableTextHasCorrectSemantics)
| TEST (FlutterPlatformNodeDelegateMac, SelectableTextWithoutSelectionReturnZeroRange)
| TEST (FlutterPlatformNodeDelegateMac, CanPerformAction)
| TEST (FlutterPlatformNodeDelegateMac, TextFieldUsesFlutterTextField)
| TEST (FlutterPlatformNodeDelegateMac, ChangingFlagsUpdatesNativeViewAccessible)
| TEST (FlutterPlatformViewController, TestCreatePlatformViewNoMatchingViewType)
| TEST (FlutterPlatformViewController, TestRegisterPlatformViewFactoryAndCreate)
| TEST (FlutterPlatformViewController, TestCreateAndDispose)
| TEST (FlutterPlatformViewController, TestReset)
| TEST (FlutterPlatformViewController, TestDisposeOnMissingViewId)
| TEST (FlutterPlatformViewController, TestAcceptGesture)
| TEST (FlutterPlatformViewController, TestAcceptGestureOnMissingViewId)
| TEST (FlutterPlatformViewController, TestRejectGesture)
| TEST (FlutterPlatformViewController, TestRejectGestureOnMissingViewId)
static FlutterSurfaceManager * | CreateSurfaceManager (TestView *testView)
static FlutterSurfacePresentInfo * | CreatePresentInfo (FlutterSurface *surface, CGPoint offset=CGPointZero, size_t index=0, const std::vector< FlutterRect > &paintRegion={})
| TEST (FlutterSurfaceManager, MetalTextureSizeMatchesSurfaceSize)
| TEST (FlutterSurfaceManager, TestSurfaceLookupFromTexture)
| TEST (FlutterSurfaceManager, BackBufferCacheDoesNotLeak)
| TEST (FlutterSurfaceManager, SurfacesAreRecycled)
| TEST (FlutterSurfaceManager, BackingStoreCacheSurfaceStuckInUse)
bool | operator== (const CGRect &lhs, const CGRect &rhs)
| TEST (FlutterSurfaceManager, LayerManagement)
| TEST (FlutterTextInputPluginTest, TestEmptyCompositionRange)
| TEST (FlutterTextInputPluginTest, TestSetMarkedTextWithSelectionChange)
| TEST (FlutterTextInputPluginTest, TestSetMarkedTextWithReplacementRange)
| TEST (FlutterTextInputPluginTest, TestComposingRegionRemovedByFramework)
| TEST (FlutterTextInputPluginTest, TestClearClientDuringComposing)
| TEST (FlutterTextInputPluginTest, TestAutocompleteDisabledWhenAutofillNotSet)
| TEST (FlutterTextInputPluginTest, TestAutocompleteEnabledWhenAutofillSet)
| TEST (FlutterTextInputPluginTest, TestAutocompleteEnabledWhenAutofillSetNoHint)
| TEST (FlutterTextInputPluginTest, TestAutocompleteDisabledWhenObscureTextSet)
| TEST (FlutterTextInputPluginTest, TestAutocompleteDisabledWhenPasswordAutofillSet)
| TEST (FlutterTextInputPluginTest, TestAutocompleteDisabledWhenAutofillGroupIncludesPassword)
| TEST (FlutterTextInputPluginTest, TestFirstRectForCharacterRange)
| TEST (FlutterTextInputPluginTest, TestFirstRectForCharacterRangeAtInfinity)
| TEST (FlutterTextInputPluginTest, TestFirstRectForCharacterRangeWithEsotericAffineTransform)
| TEST (FlutterTextInputPluginTest, TestSetEditingStateWithTextEditingDelta)
| TEST (FlutterTextInputPluginTest, TestOperationsThatTriggerDelta)
| TEST (FlutterTextInputPluginTest, TestComposingWithDelta)
| TEST (FlutterTextInputPluginTest, TestComposingWithDeltasWhenSelectionIsActive)
| TEST (FlutterTextInputPluginTest, TestLocalTextAndSelectionUpdateAfterDelta)
| TEST (FlutterTextInputPluginTest, TestPerformKeyEquivalent)
| TEST (FlutterTextInputPluginTest, HandleArrowKeyWhenImePopoverIsActive)
| TEST (FlutterTextInputPluginTest, UnhandledKeyEquivalent)
| TEST (FlutterTextInputPluginTest, TestSelectorsAreForwardedToFramework)
| TEST (FlutterTextInputPluginTest, TestSelectorsNotForwardedToFrameworkIfNoClient)
| TEST (FlutterTextInputPluginTest, TestInsertNewLine)
| TEST (FlutterTextInputPluginTest, TestSendActionDoNotInsertNewLine)
| TEST (FlutterTextInputPluginTest, TestAttributedSubstringOutOfRange)
| TEST (FlutterTextInputPluginTest, CanWorkWithFlutterTextField)
| TEST (FlutterTextInputPluginTest, CanNotBecomeResponderIfNoViewController)
| TEST (FlutterTextInputPluginTest, IsAddedAndRemovedFromViewHierarchy)
| TEST (FlutterTextInputPluginTest, FirstResponderIsCorrect)
| TEST (FlutterTextInputPluginTest, HasZeroSizeAndClipsToBounds)
| TEST (FlutterTextInputPluginTest, WorksWithoutViewId)
| TEST (FlutterTextInputPluginTest, InsertTextWithCollapsedSelectionInsideComposing)
| TEST (FlutterTextInputPluginTest, InsertTextHandlesNSAttributedString)
| TEST (FlutterTextInputPluginTest, InsertTextHandlesEmptyAttributedString)
| TEST (FlutterTextInputSemanticsObjectTest, DoesInitialize)
| TEST_F (FlutterViewControllerTest, HasViewThatHidesOtherViewsInAccessibility)
| TEST_F (FlutterViewControllerTest, FlutterViewAcceptsFirstMouse)
| TEST_F (FlutterViewControllerTest, ReparentsPluginWhenAccessibilityDisabled)
| TEST_F (FlutterViewControllerTest, CanSetMouseTrackingModeBeforeViewLoaded)
| TEST_F (FlutterViewControllerMockEngineTest, TestKeyEventsAreSentToFramework)
| TEST_F (FlutterViewControllerMockEngineTest, TestKeyEventsArePropagatedIfNotHandled)
| TEST_F (FlutterViewControllerMockEngineTest, TestKeyEventsAreNotPropagatedIfHandled)
| TEST_F (FlutterViewControllerMockEngineTest, TestCtrlTabKeyEventIsPropagated)
| TEST_F (FlutterViewControllerMockEngineTest, TestKeyEquivalentIsPassedToTextInputPlugin)
| TEST_F (FlutterViewControllerMockEngineTest, TestFlagsChangedEventsArePropagatedIfNotHandled)
| TEST_F (FlutterViewControllerMockEngineTest, TestKeyboardIsRestartedOnEngineRestart)
| TEST_F (FlutterViewControllerMockEngineTest, TestTrackpadGesturesAreSentToFramework)
| TEST_F (FlutterViewControllerMockEngineTest, TestmouseAndGestureEventsAreHandledSeparately)
| TEST_F (FlutterViewControllerMockEngineTest, TestMouseDownUpEventsSentToNextResponder)
| TEST_F (FlutterViewControllerMockEngineTest, TestModifierKeysAreSynthesizedOnMouseMove)
| TEST_F (FlutterViewControllerMockEngineTest, testViewWillAppearCalledMultipleTimes)
| TEST_F (FlutterViewControllerMockEngineTest, testFlutterViewIsConfigured)
| TEST_F (FlutterViewControllerTest, testLookupKeyAssets)
| TEST_F (FlutterViewControllerTest, testLookupKeyAssetsWithPackage)
| TEST_F (FlutterViewControllerTest, testViewControllerIsReleased)
id | CreateMockViewController ()
| TEST (FlutterViewEngineProviderUnittests, GetViewReturnsTheCorrectView)
| TEST_F (FlutterWindowControllerTest, CreateRegularWindow)
| TEST_F (FlutterWindowControllerRetainTest, WindowControllerDoesNotRetainEngine)
| TEST_F (FlutterWindowControllerTest, DestroyRegularWindow)
| TEST_F (FlutterWindowControllerTest, InternalFlutter_Window_GetHandle)
| TEST_F (FlutterWindowControllerTest, WindowStates)
| TEST (KeyMappingTest, HasExpectedValues)
FlutterSemanticsNode2 | CreateSemanticsNode (int32_t id, const char *label, const std::vector< int32_t > *children=nullptr)
| TEST (AccessibilityBridgeTest, BasicTest)
| TEST (AccessibilityBridgeTest, AccessibilityRootId)
| TEST (AccessibilityBridgeTest, AddOrder)
| TEST (AccessibilityBridgeTest, CanFireChildrenChangedCorrectly)
| TEST (AccessibilityBridgeTest, CanHandleSelectionChangeCorrectly)
| TEST (AccessibilityBridgeTest, DoesNotAssignEditableRootToSelectableText)
| TEST (AccessibilityBridgeTest, SwitchHasSwitchRole)
| TEST (AccessibilityBridgeTest, SliderHasSliderRole)
| TEST (AccessibilityBridgeTest, CanSetCheckboxChecked)
| TEST (AccessibilityBridgeTest, CanReparentNode)
| TEST (AccessibilityBridgeTest, CanReparentMultipleNodes)
| TEST (AccessibilityBridgeTest, CanReparentNodeWithChild)
| TEST (AccessibilityBridgeTest, AXTreeManagerTest)
| TEST (AccessibilityBridgeTest, LineBreakingObjectTest)
| TEST (FlutterPlatformNodeDelegateTest, NodeDelegateHasUniqueId)
| TEST (FlutterPlatformNodeDelegateTest, canPerfomActions)
| TEST (FlutterPlatformNodeDelegateTest, canGetAXNode)
| TEST (FlutterPlatformNodeDelegateTest, canCalculateBoundsCorrectly)
| TEST (FlutterPlatformNodeDelegateTest, canCalculateOffScreenBoundsCorrectly)
| TEST (FlutterPlatformNodeDelegateTest, canUseOwnerBridge)
| TEST (FlutterPlatformNodeDelegateTest, selfIsLowestPlatformAncestor)
| TEST (FlutterPlatformNodeDelegateTest, canGetFromNodeID)

## Variables
FlutterSemanticsFlags | kEmptyFlags = FlutterSemanticsFlags{}

## Typedef Documentation

## ◆ FlutterChannelKeyResponderTest

using flutter::testing::FlutterChannelKeyResponderTest = typedef AutoreleasePoolTest

Definition at line 73 of file FlutterChannelKeyResponderTest.mm.

## ◆ FlutterEmbedderExternalTextureTest

using flutter::testing::FlutterEmbedderExternalTextureTest = typedef AutoreleasePoolTest

Definition at line 94 of file FlutterEmbedderExternalTextureTest.mm.

## ◆ FlutterViewControllerMockEngineTest

using flutter::testing::FlutterViewControllerMockEngineTest = typedef MockFlutterEngineTest

Definition at line 185 of file FlutterViewControllerTest.mm.

## ◆ FlutterViewControllerTest

using flutter::testing::FlutterViewControllerTest = typedef AutoreleasePoolTest

Definition at line 184 of file FlutterViewControllerTest.mm.

## Function Documentation

## ◆ CreateMockFlutterEngine()

id flutter::testing::CreateMockFlutterEngine | ( | NSString * | pasteboardString | ) |

Definition at line 76 of file FlutterEngineTestUtils.mm.

76 {
77 NSString* fixtures = @(testing::GetFixturesPath());
78 FlutterDartProject* project = [[FlutterDartProject alloc]
79 initWithAssetsPath:fixtures
80 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
81 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
82 project:project
83 allowHeadlessExecution:true];
84
85 FakePasteboard* pasteboardMock = [[FakePasteboard alloc] init];
86 [pasteboardMock setString:pasteboardString forType:NSPasteboardTypeString];
87 engine.pasteboard = pasteboardMock;
88 id engineMock = OCMPartialMock(engine);
89 return engineMock;
90 }
FlutterDartProject
Definition: FlutterDartProject.mm:24
FakePasteboard
Definition: FlutterEngineTestUtils.mm:18
FlutterEngine
Definition: FlutterEngine.h:32

References FlutterPasteboard::setString:forType:.

Referenced by flutter::testing::MockFlutterEngineTest::SetUp(), TEST(), and TEST_F().

## ◆ CreateMockViewController()

id flutter::testing::CreateMockViewController | ( |  | ) |

Definition at line 9 of file FlutterViewControllerTestUtils.mm.

9 {
10 {
11 NSString* fixtures = @(testing::GetFixturesPath());
12 FlutterDartProject* project = [[FlutterDartProject alloc]
13 initWithAssetsPath:fixtures
14 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
15 FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:project];
16 id viewControllerMock = OCMPartialMock(viewController);
17 return viewControllerMock;
18 }
19 }
FlutterViewController
Definition: FlutterViewController.h:73

Referenced by TEST_F().

## ◆ CreatePresentInfo()

static FlutterSurfacePresentInfo* flutter::testing::CreatePresentInfo | ( | FlutterSurface * | surface,
|  | CGPoint | offset = `CGPointZero`,
|  | size_t | index = `0`,
|  | const std::vector< FlutterRect > & | paintRegion = `{}`
| ) |  |
| static

Definition at line 53 of file FlutterSurfaceManagerTest.mm.

57 {}) {
58 FlutterSurfacePresentInfo* res = [[FlutterSurfacePresentInfo alloc] init];
59 res.surface = surface;
60 res.offset = offset;
61 res.zIndex = index;
62 res.paintRegion = paintRegion;
63 return res;
64 }
FlutterSurfacePresentInfo
Definition: FlutterSurfaceManager.h:19
FlutterSurfacePresentInfo::surface
FlutterSurface * surface
Definition: FlutterSurfaceManager.h:20
FlutterSurfacePresentInfo::paintRegion
std::vector< FlutterRect > paintRegion
Definition: FlutterSurfaceManager.h:23
FlutterSurfacePresentInfo::offset
CGPoint offset
Definition: FlutterSurfaceManager.h:21
FlutterSurfacePresentInfo::zIndex
size_t zIndex
Definition: FlutterSurfaceManager.h:22

## ◆ CreateSemanticsNode()

FlutterSemanticsNode2 flutter::testing::CreateSemanticsNode | ( | int32_t | id,
|  | const char * | label,
|  | const std::vector< int32_t > * | children = `nullptr`
| ) |  |

Definition at line 20 of file accessibility_bridge_unittests.cc.

23 {
24 return {
25 .id = id,
26 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
27 .flags__deprecated__ = static_cast<FlutterSemanticsFlag>(0),
28 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
29 .actions = static_cast<FlutterSemanticsAction>(0),
30 .text_selection_base = -1,
31 .text_selection_extent = -1,
32 .label = label,
33 .hint = "",
34 .value = "",
35 .increased_value = "",
36 .decreased_value = "",
37 .child_count = children ? children->size() : 0,
38 .children_in_traversal_order = children ? children->data() : nullptr,
39 .custom_accessibility_actions_count = 0,
40 .tooltip = "",
41 .flags2 = &kEmptyFlags,
42 };
43 }
flutter::testing::kEmptyFlags
FlutterSemanticsFlags kEmptyFlags
Definition: accessibility_bridge_unittests.cc:18

References kEmptyFlags.

Referenced by TEST().

## ◆ CreateSurfaceManager()

static FlutterSurfaceManager* flutter::testing::CreateSurfaceManager | ( | TestView * | testView | ) |
| static

Definition at line 43 of file FlutterSurfaceManagerTest.mm.

43 {
44 id<MTLDevice> device = MTLCreateSystemDefaultDevice();
45 id<MTLCommandQueue> commandQueue = [device newCommandQueue];
46 CALayer* layer = reinterpret_cast<CALayer*>(testView.layer);
47 return [[FlutterSurfaceManager alloc] initWithDevice:device
48 commandQueue:commandQueue
49 layer:layer
50 delegate:testView];
51 }
FlutterSurfaceManager
Definition: FlutterSurfaceManager.h:47

Referenced by TEST().

## ◆ operator==()

bool flutter::testing::operator== | ( | const CGRect & | lhs,
|  | const CGRect & | rhs
| ) |  |
| inline

Definition at line 200 of file FlutterSurfaceManagerTest.mm.

200 {
201 return CGRectEqualToRect(lhs, rhs);
202 }

## ◆ TEST() [1/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | AccessibilityRootId |
| ) |  |

Definition at line 79 of file accessibility_bridge_unittests.cc.

79 {
80 std::shared_ptr<TestAccessibilityBridge> bridge =
81 std::make_shared<TestAccessibilityBridge>();
82
83 std::vector<int32_t> children{456, 789};
84 FlutterSemanticsNode2 root = CreateSemanticsNode(123, "root", &children);
85 FlutterSemanticsNode2 child1 = CreateSemanticsNode(456, "child 1");
86 FlutterSemanticsNode2 child2 = CreateSemanticsNode(789, "child 2");
87
88 bridge->AddFlutterSemanticsNodeUpdate(root);
89 bridge->AddFlutterSemanticsNodeUpdate(child1);
90 bridge->AddFlutterSemanticsNodeUpdate(child2);
91 bridge->CommitUpdates();
92
93 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(123).lock();
94 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(456).lock();
95 auto child2_node = bridge->GetFlutterPlatformNodeDelegateFromID(789).lock();
96 auto fake_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
97
98 EXPECT_EQ(bridge->GetRootAsAXNode()->id(), 123);
99 EXPECT_EQ(bridge->RootDelegate()->GetName(), "root");
100
101 EXPECT_EQ(root_node->GetChildCount(), 2);
102 EXPECT_EQ(root_node->GetData().child_ids[0], 456);
103 EXPECT_EQ(root_node->GetData().child_ids[1], 789);
104 EXPECT_EQ(root_node->GetName(), "root");
105
106 EXPECT_EQ(child1_node->GetChildCount(), 0);
107 EXPECT_EQ(child1_node->GetName(), "child 1");
108
109 EXPECT_EQ(child2_node->GetChildCount(), 0);
110 EXPECT_EQ(child2_node->GetName(), "child 2");
111
112 ASSERT_FALSE(fake_delegate);
113 }
flutter::testing::CreateSemanticsNode
FlutterSemanticsNode2 CreateSemanticsNode(int32_t id, const char *label, const std::vector< int32_t > *children=nullptr)
Definition: accessibility_bridge_unittests.cc:20

References CreateSemanticsNode().

## ◆ TEST() [2/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | AddOrder |
| ) |  |

Definition at line 116 of file accessibility_bridge_unittests.cc.

116 {
117 std::shared_ptr<TestAccessibilityBridge> bridge =
118 std::make_shared<TestAccessibilityBridge>();
119
120 std::vector<int32_t> root_children{34, 56};
121 std::vector<int32_t> child2_children{78};
122 std::vector<int32_t> child3_children{90};
123 FlutterSemanticsNode2 root = CreateSemanticsNode(12, "root", &root_children);
124 FlutterSemanticsNode2 child1 = CreateSemanticsNode(34, "child 1");
125 FlutterSemanticsNode2 child2 =
126 CreateSemanticsNode(56, "child 2", &child2_children);
127 FlutterSemanticsNode2 child3 =
128 CreateSemanticsNode(78, "child 3", &child3_children);
129 FlutterSemanticsNode2 child4 = CreateSemanticsNode(90, "child 4");
130
131 bridge->AddFlutterSemanticsNodeUpdate(child3);
132 bridge->AddFlutterSemanticsNodeUpdate(child2);
133 bridge->AddFlutterSemanticsNodeUpdate(root);
134 bridge->AddFlutterSemanticsNodeUpdate(child1);
135 bridge->AddFlutterSemanticsNodeUpdate(child4);
136 bridge->CommitUpdates();
137
138 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(12).lock();
139 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(34).lock();
140 auto child2_node = bridge->GetFlutterPlatformNodeDelegateFromID(56).lock();
141 auto child3_node = bridge->GetFlutterPlatformNodeDelegateFromID(78).lock();
142 auto child4_node = bridge->GetFlutterPlatformNodeDelegateFromID(90).lock();
143
144 EXPECT_EQ(bridge->GetRootAsAXNode()->id(), 12);
145 EXPECT_EQ(bridge->RootDelegate()->GetName(), "root");
146
147 EXPECT_EQ(root_node->GetChildCount(), 2);
148 EXPECT_EQ(root_node->GetData().child_ids[0], 34);
149 EXPECT_EQ(root_node->GetData().child_ids[1], 56);
150 EXPECT_EQ(root_node->GetName(), "root");
151
152 EXPECT_EQ(child1_node->GetChildCount(), 0);
153 EXPECT_EQ(child1_node->GetName(), "child 1");
154
155 EXPECT_EQ(child2_node->GetChildCount(), 1);
156 EXPECT_EQ(child2_node->GetData().child_ids[0], 78);
157 EXPECT_EQ(child2_node->GetName(), "child 2");
158
159 EXPECT_EQ(child3_node->GetChildCount(), 1);
160 EXPECT_EQ(child3_node->GetData().child_ids[0], 90);
161 EXPECT_EQ(child3_node->GetName(), "child 3");
162
163 EXPECT_EQ(child4_node->GetChildCount(), 0);
164 EXPECT_EQ(child4_node->GetName(), "child 4");
165 }

References CreateSemanticsNode().

## ◆ TEST() [3/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | AXTreeManagerTest |
| ) |  |

Definition at line 566 of file accessibility_bridge_unittests.cc.

566 {
567 std::shared_ptr<TestAccessibilityBridge> bridge =
568 std::make_shared<TestAccessibilityBridge>();
569
570 ui::AXTreeID tree_id = bridge->GetTreeID();
571 ui::AXTreeManager* manager =
572 ui::AXTreeManagerMap::GetInstance().GetManager(tree_id);
573 ASSERT_EQ(manager, static_cast<ui::AXTreeManager*>(bridge.get()));
574 }

## ◆ TEST() [4/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | BasicTest |
| ) |  |

Definition at line 45 of file accessibility_bridge_unittests.cc.

45 {
46 std::shared_ptr<TestAccessibilityBridge> bridge =
47 std::make_shared<TestAccessibilityBridge>();
48
49 std::vector<int32_t> children{1, 2};
50 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root", &children);
51 root.identifier = "identifier";
52 FlutterSemanticsNode2 child1 = CreateSemanticsNode(1, "child 1");
53 FlutterSemanticsNode2 child2 = CreateSemanticsNode(2, "child 2");
54
55 bridge->AddFlutterSemanticsNodeUpdate(root);
56 bridge->AddFlutterSemanticsNodeUpdate(child1);
57 bridge->AddFlutterSemanticsNodeUpdate(child2);
58 bridge->CommitUpdates();
59
60 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
61 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
62 auto child2_node = bridge->GetFlutterPlatformNodeDelegateFromID(2).lock();
63 EXPECT_EQ(root_node->GetChildCount(), 2);
64 EXPECT_EQ(root_node->GetData().child_ids[0], 1);
65 EXPECT_EQ(root_node->GetData().child_ids[1], 2);
66 EXPECT_EQ(root_node->GetName(), "root");
67 EXPECT_EQ(root_node->GetAuthorUniqueId(), u"identifier");
68
69 EXPECT_EQ(child1_node->GetChildCount(), 0);
70 EXPECT_EQ(child1_node->GetName(), "child 1");
71
72 EXPECT_EQ(child2_node->GetChildCount(), 0);
73 EXPECT_EQ(child2_node->GetName(), "child 2");
74 }

References CreateSemanticsNode().

## ◆ TEST() [5/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | CanFireChildrenChangedCorrectly |
| ) |  |

Definition at line 167 of file accessibility_bridge_unittests.cc.

167 {
168 std::shared_ptr<TestAccessibilityBridge> bridge =
169 std::make_shared<TestAccessibilityBridge>();
170
171 std::vector<int32_t> children{1};
172 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root", &children);
173 FlutterSemanticsNode2 child1 = CreateSemanticsNode(1, "child 1");
174
175 bridge->AddFlutterSemanticsNodeUpdate(root);
176 bridge->AddFlutterSemanticsNodeUpdate(child1);
177
178 bridge->CommitUpdates();
179
180 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
181 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
182 EXPECT_EQ(root_node->GetChildCount(), 1);
183 EXPECT_EQ(root_node->GetData().child_ids[0], 1);
184 EXPECT_EQ(root_node->GetName(), "root");
185
186 EXPECT_EQ(child1_node->GetChildCount(), 0);
187 EXPECT_EQ(child1_node->GetName(), "child 1");
188 bridge->accessibility_events.clear();
189
190 // Add a child to root.
191 root.child_count = 2;
192 int32_t new_children[] = {1, 2};
193 root.children_in_traversal_order = new_children;
194
195 FlutterSemanticsNode2 child2 = CreateSemanticsNode(2, "child 2");
196
197 bridge->AddFlutterSemanticsNodeUpdate(root);
198 bridge->AddFlutterSemanticsNodeUpdate(child2);
199 bridge->CommitUpdates();
200
201 root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
202
203 EXPECT_EQ(root_node->GetChildCount(), 2);
204 EXPECT_EQ(root_node->GetData().child_ids[0], 1);
205 EXPECT_EQ(root_node->GetData().child_ids[1], 2);
206 EXPECT_EQ(bridge->accessibility_events.size(), size_t{2});
207 std::set<ui::AXEventGenerator::Event> actual_event{
208 bridge->accessibility_events.begin(), bridge->accessibility_events.end()};
209 EXPECT_THAT(actual_event,
210 Contains(ui::AXEventGenerator::Event::CHILDREN_CHANGED));
211 EXPECT_THAT(actual_event,
212 Contains(ui::AXEventGenerator::Event::SUBTREE_CREATED));
213 }

References CreateSemanticsNode().

## ◆ TEST() [6/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | CanHandleSelectionChangeCorrectly |
| ) |  |

Definition at line 215 of file accessibility_bridge_unittests.cc.

215 {
216 std::shared_ptr<TestAccessibilityBridge> bridge =
217 std::make_shared<TestAccessibilityBridge>();
218 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root");
219 auto flags = FlutterSemanticsFlags{
220 .is_focused = FlutterTristate::kFlutterTristateTrue,
221 .is_text_field = true,
222 };
223 root.flags2 = &flags;
224
225 bridge->AddFlutterSemanticsNodeUpdate(root);
226 bridge->CommitUpdates();
227
228 const ui::AXTreeData& tree = bridge->GetAXTreeData();
229 EXPECT_EQ(tree.sel_anchor_object_id, ui::AXNode::kInvalidAXID);
230 bridge->accessibility_events.clear();
231
232 // Update the selection.
233 root.text_selection_base = 0;
234 root.text_selection_extent = 5;
235 bridge->AddFlutterSemanticsNodeUpdate(root);
236
237 bridge->CommitUpdates();
238
239 EXPECT_EQ(tree.sel_anchor_object_id, 0);
240 EXPECT_EQ(tree.sel_anchor_offset, 0);
241 EXPECT_EQ(tree.sel_focus_object_id, 0);
242 EXPECT_EQ(tree.sel_focus_offset, 5);
243 ASSERT_EQ(bridge->accessibility_events.size(), size_t{2});
244 EXPECT_EQ(bridge->accessibility_events[0],
245 ui::AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED);
246 EXPECT_EQ(bridge->accessibility_events[1],
247 ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED);
248 }

References CreateSemanticsNode().

## ◆ TEST() [7/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | CanReparentMultipleNodes |
| ) |  |

Definition at line 392 of file accessibility_bridge_unittests.cc.

392 {
393 std::shared_ptr<TestAccessibilityBridge> bridge =
394 std::make_shared<TestAccessibilityBridge>();
395
396 int32_t root_id = 0;
397 int32_t intermediary1_id = 1;
398 int32_t intermediary2_id = 2;
399 int32_t leaf1_id = 3;
400 int32_t leaf2_id = 4;
401 int32_t leaf3_id = 5;
402
403 std::vector<int32_t> root_children{intermediary1_id, intermediary2_id};
404 std::vector<int32_t> intermediary1_children{leaf1_id};
405 std::vector<int32_t> intermediary2_children{leaf2_id, leaf3_id};
406 FlutterSemanticsNode2 root =
407 CreateSemanticsNode(root_id, "root", &root_children);
408 FlutterSemanticsNode2 intermediary1 = CreateSemanticsNode(
409 intermediary1_id, "intermediary 1", &intermediary1_children);
410 FlutterSemanticsNode2 intermediary2 = CreateSemanticsNode(
411 intermediary2_id, "intermediary 2", &intermediary2_children);
412 FlutterSemanticsNode2 leaf1 = CreateSemanticsNode(leaf1_id, "leaf 1");
413 FlutterSemanticsNode2 leaf2 = CreateSemanticsNode(leaf2_id, "leaf 2");
414 FlutterSemanticsNode2 leaf3 = CreateSemanticsNode(leaf3_id, "leaf 3");
415
416 bridge->AddFlutterSemanticsNodeUpdate(root);
417 bridge->AddFlutterSemanticsNodeUpdate(intermediary1);
418 bridge->AddFlutterSemanticsNodeUpdate(intermediary2);
419 bridge->AddFlutterSemanticsNodeUpdate(leaf1);
420 bridge->AddFlutterSemanticsNodeUpdate(leaf2);
421 bridge->AddFlutterSemanticsNodeUpdate(leaf3);
422 bridge->CommitUpdates();
423 bridge->accessibility_events.clear();
424
425 // Swap intermediary 1's and intermediary2's children.
426 int32_t new_intermediary1_children[] = {leaf2_id, leaf3_id};
427 intermediary1.child_count = 2;
428 intermediary1.children_in_traversal_order = new_intermediary1_children;
429
430 int32_t new_intermediary2_children[] = {leaf1_id};
431 intermediary2.child_count = 1;
432 intermediary2.children_in_traversal_order = new_intermediary2_children;
433
434 bridge->AddFlutterSemanticsNodeUpdate(intermediary1);
435 bridge->AddFlutterSemanticsNodeUpdate(intermediary2);
436 bridge->AddFlutterSemanticsNodeUpdate(leaf1);
437 bridge->AddFlutterSemanticsNodeUpdate(leaf2);
438 bridge->AddFlutterSemanticsNodeUpdate(leaf3);
439 bridge->CommitUpdates();
440
441 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(root_id).lock();
442 auto intermediary1_node =
443 bridge->GetFlutterPlatformNodeDelegateFromID(intermediary1_id).lock();
444 auto intermediary2_node =
445 bridge->GetFlutterPlatformNodeDelegateFromID(intermediary2_id).lock();
446 auto leaf1_node =
447 bridge->GetFlutterPlatformNodeDelegateFromID(leaf1_id).lock();
448 auto leaf2_node =
449 bridge->GetFlutterPlatformNodeDelegateFromID(leaf2_id).lock();
450 auto leaf3_node =
451 bridge->GetFlutterPlatformNodeDelegateFromID(leaf3_id).lock();
452
453 EXPECT_EQ(root_node->GetChildCount(), 2);
454 EXPECT_EQ(root_node->GetData().child_ids[0], intermediary1_id);
455 EXPECT_EQ(root_node->GetData().child_ids[1], intermediary2_id);
456 EXPECT_EQ(root_node->GetName(), "root");
457
458 EXPECT_EQ(intermediary1_node->GetChildCount(), 2);
459 EXPECT_EQ(intermediary1_node->GetData().child_ids[0], leaf2_id);
460 EXPECT_EQ(intermediary1_node->GetData().child_ids[1], leaf3_id);
461 EXPECT_EQ(intermediary1_node->GetName(), "intermediary 1");
462
463 EXPECT_EQ(intermediary2_node->GetChildCount(), 1);
464 EXPECT_EQ(intermediary2_node->GetData().child_ids[0], leaf1_id);
465 EXPECT_EQ(intermediary2_node->GetName(), "intermediary 2");
466
467 EXPECT_EQ(leaf1_node->GetChildCount(), 0);
468 EXPECT_EQ(leaf1_node->GetName(), "leaf 1");
469
470 EXPECT_EQ(leaf2_node->GetChildCount(), 0);
471 EXPECT_EQ(leaf2_node->GetName(), "leaf 2");
472
473 EXPECT_EQ(leaf3_node->GetChildCount(), 0);
474 EXPECT_EQ(leaf3_node->GetName(), "leaf 3");
475
476 // Intermediary 1 and intermediary 2 have new children.
477 // Leaf 1, 2, and 3 are all moved.
478 ASSERT_EQ(bridge->accessibility_events.size(), size_t{5});
479 EXPECT_THAT(bridge->accessibility_events,
480 Contains(ui::AXEventGenerator::Event::CHILDREN_CHANGED).Times(2));
481 EXPECT_THAT(bridge->accessibility_events,
482 Contains(ui::AXEventGenerator::Event::SUBTREE_CREATED).Times(3));
483 }

References CreateSemanticsNode().

## ◆ TEST() [8/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | CanReparentNode |
| ) |  |

Definition at line 329 of file accessibility_bridge_unittests.cc.

329 {
330 std::shared_ptr<TestAccessibilityBridge> bridge =
331 std::make_shared<TestAccessibilityBridge>();
332
333 std::vector<int32_t> root_children{1};
334 std::vector<int32_t> child1_children{2};
335 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root", &root_children);
336 FlutterSemanticsNode2 child1 =
337 CreateSemanticsNode(1, "child 1", &child1_children);
338 FlutterSemanticsNode2 child2 = CreateSemanticsNode(2, "child 2");
339
340 bridge->AddFlutterSemanticsNodeUpdate(root);
341 bridge->AddFlutterSemanticsNodeUpdate(child1);
342 bridge->AddFlutterSemanticsNodeUpdate(child2);
343 bridge->CommitUpdates();
344 bridge->accessibility_events.clear();
345
346 // Reparent child2 from child1 to the root.
347 child1.child_count = 0;
348 child1.children_in_traversal_order = nullptr;
349
350 int32_t new_root_children[] = {1, 2};
351 root.child_count = 2;
352 root.children_in_traversal_order = new_root_children;
353
354 bridge->AddFlutterSemanticsNodeUpdate(root);
355 bridge->AddFlutterSemanticsNodeUpdate(child1);
356 bridge->AddFlutterSemanticsNodeUpdate(child2);
357 bridge->CommitUpdates();
358
359 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
360 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
361 auto child2_node = bridge->GetFlutterPlatformNodeDelegateFromID(2).lock();
362
363 EXPECT_EQ(root_node->GetChildCount(), 2);
364 EXPECT_EQ(root_node->GetData().child_ids[0], 1);
365 EXPECT_EQ(root_node->GetData().child_ids[1], 2);
366 EXPECT_EQ(root_node->GetName(), "root");
367
368 EXPECT_EQ(child1_node->GetChildCount(), 0);
369 EXPECT_EQ(child1_node->GetName(), "child 1");
370
371 EXPECT_EQ(child2_node->GetChildCount(), 0);
372 EXPECT_EQ(child2_node->GetName(), "child 2");
373
374 ASSERT_EQ(bridge->accessibility_events.size(), size_t{5});
375
376 // Child2 is moved from child1 to root.
377 EXPECT_THAT(bridge->accessibility_events,
378 Contains(ui::AXEventGenerator::Event::CHILDREN_CHANGED).Times(2));
379 EXPECT_THAT(bridge->accessibility_events,
380 Contains(ui::AXEventGenerator::Event::SUBTREE_CREATED).Times(1));
381
382 // Child1 is no longer a parent. It loses its group role and disables its
383 // 'clip children' attribute.
384 EXPECT_THAT(
385 bridge->accessibility_events,
386 Contains(ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED).Times(1));
387 EXPECT_THAT(bridge->accessibility_events,
388 Contains(ui::AXEventGenerator::Event::ROLE_CHANGED).Times(1));
389 }

References CreateSemanticsNode().

## ◆ TEST() [9/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | CanReparentNodeWithChild |
| ) |  |

Definition at line 486 of file accessibility_bridge_unittests.cc.

486 {
487 std::shared_ptr<TestAccessibilityBridge> bridge =
488 std::make_shared<TestAccessibilityBridge>();
489
490 int32_t root_id = 0;
491 int32_t intermediary1_id = 1;
492 int32_t intermediary2_id = 2;
493 int32_t leaf1_id = 3;
494
495 std::vector<int32_t> root_children{intermediary1_id, intermediary2_id};
496 std::vector<int32_t> intermediary1_children{leaf1_id};
497 FlutterSemanticsNode2 root =
498 CreateSemanticsNode(root_id, "root", &root_children);
499 FlutterSemanticsNode2 intermediary1 = CreateSemanticsNode(
500 intermediary1_id, "intermediary 1", &intermediary1_children);
501 FlutterSemanticsNode2 intermediary2 =
502 CreateSemanticsNode(intermediary2_id, "intermediary 2");
503 FlutterSemanticsNode2 leaf1 = CreateSemanticsNode(leaf1_id, "leaf 1");
504
505 bridge->AddFlutterSemanticsNodeUpdate(root);
506 bridge->AddFlutterSemanticsNodeUpdate(intermediary1);
507 bridge->AddFlutterSemanticsNodeUpdate(intermediary2);
508 bridge->AddFlutterSemanticsNodeUpdate(leaf1);
509 bridge->CommitUpdates();
510 bridge->accessibility_events.clear();
511
512 // Move intermediary1 from root to intermediary 2.
513 int32_t new_root_children[] = {intermediary2_id};
514 root.child_count = 1;
515 root.children_in_traversal_order = new_root_children;
516
517 int32_t new_intermediary2_children[] = {intermediary1_id};
518 intermediary2.child_count = 1;
519 intermediary2.children_in_traversal_order = new_intermediary2_children;
520
521 bridge->AddFlutterSemanticsNodeUpdate(root);
522 bridge->AddFlutterSemanticsNodeUpdate(intermediary1);
523 bridge->AddFlutterSemanticsNodeUpdate(intermediary2);
524 bridge->AddFlutterSemanticsNodeUpdate(leaf1);
525 bridge->CommitUpdates();
526
527 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(root_id).lock();
528 auto intermediary1_node =
529 bridge->GetFlutterPlatformNodeDelegateFromID(intermediary1_id).lock();
530 auto intermediary2_node =
531 bridge->GetFlutterPlatformNodeDelegateFromID(intermediary2_id).lock();
532 auto leaf1_node =
533 bridge->GetFlutterPlatformNodeDelegateFromID(leaf1_id).lock();
534
535 EXPECT_EQ(root_node->GetChildCount(), 1);
536 EXPECT_EQ(root_node->GetData().child_ids[0], intermediary2_id);
537 EXPECT_EQ(root_node->GetName(), "root");
538
539 EXPECT_EQ(intermediary2_node->GetChildCount(), 1);
540 EXPECT_EQ(intermediary2_node->GetData().child_ids[0], intermediary1_id);
541 EXPECT_EQ(intermediary2_node->GetName(), "intermediary 2");
542
543 EXPECT_EQ(intermediary1_node->GetChildCount(), 1);
544 EXPECT_EQ(intermediary1_node->GetData().child_ids[0], leaf1_id);
545 EXPECT_EQ(intermediary1_node->GetName(), "intermediary 1");
546
547 EXPECT_EQ(leaf1_node->GetChildCount(), 0);
548 EXPECT_EQ(leaf1_node->GetName(), "leaf 1");
549
550 ASSERT_EQ(bridge->accessibility_events.size(), size_t{5});
551
552 EXPECT_THAT(bridge->accessibility_events,
553 Contains(ui::AXEventGenerator::Event::CHILDREN_CHANGED).Times(2));
554 EXPECT_THAT(bridge->accessibility_events,
555 Contains(ui::AXEventGenerator::Event::SUBTREE_CREATED).Times(1));
556
557 // Intermediary 2 becomes a parent node. It updates to group role and enables
558 // its 'clip children' attribute.
559 EXPECT_THAT(
560 bridge->accessibility_events,
561 Contains(ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED).Times(1));
562 EXPECT_THAT(bridge->accessibility_events,
563 Contains(ui::AXEventGenerator::Event::ROLE_CHANGED).Times(1));
564 }

References CreateSemanticsNode().

## ◆ TEST() [10/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | CanSetCheckboxChecked |
| ) |  |

Definition at line 310 of file accessibility_bridge_unittests.cc.

310 {
311 std::shared_ptr<TestAccessibilityBridge> bridge =
312 std::make_shared<TestAccessibilityBridge>();
313 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root");
314 auto flags = FlutterSemanticsFlags{
315 .is_checked = FlutterCheckState::kFlutterCheckStateTrue,
316 };
317
318 root.flags2 = &flags;
319 bridge->AddFlutterSemanticsNodeUpdate(root);
320 bridge->CommitUpdates();
321
322 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
323 EXPECT_EQ(root_node->GetData().role, ax::mojom::Role::kCheckBox);
324 EXPECT_EQ(root_node->GetData().GetCheckedState(),
325 ax::mojom::CheckedState::kTrue);
326 }

References CreateSemanticsNode().

## ◆ TEST() [11/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | DoesNotAssignEditableRootToSelectableText |
| ) |  |

Definition at line 250 of file accessibility_bridge_unittests.cc.

250 {
251 std::shared_ptr<TestAccessibilityBridge> bridge =
252 std::make_shared<TestAccessibilityBridge>();
253 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root");
254 auto flags = FlutterSemanticsFlags{
255 .is_text_field = true,
256 .is_read_only = true,
257 };
258 root.flags2 = &flags;
259
260 bridge->AddFlutterSemanticsNodeUpdate(root);
261 bridge->CommitUpdates();
262
263 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
264
265 EXPECT_FALSE(root_node->GetData().GetBoolAttribute(
266 ax::mojom::BoolAttribute::kEditableRoot));
267 }

References CreateSemanticsNode().

## ◆ TEST() [12/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | LineBreakingObjectTest |
| ) |  |

Definition at line 576 of file accessibility_bridge_unittests.cc.

576 {
577 std::shared_ptr<TestAccessibilityBridge> bridge =
578 std::make_shared<TestAccessibilityBridge>();
579
580 const int32_t root_id = 0;
581
582 FlutterSemanticsNode2 root = CreateSemanticsNode(root_id, "root", {});
583
584 bridge->AddFlutterSemanticsNodeUpdate(root);
585 bridge->CommitUpdates();
586
587 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(root_id).lock();
588 auto root_data = root_node->GetData();
589 EXPECT_TRUE(root_data.HasBoolAttribute(
590 ax::mojom::BoolAttribute::kIsLineBreakingObject));
591 EXPECT_TRUE(root_data.GetBoolAttribute(
592 ax::mojom::BoolAttribute::kIsLineBreakingObject));
593 }

References CreateSemanticsNode().

## ◆ TEST() [13/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | SliderHasSliderRole |
| ) |  |

Definition at line 286 of file accessibility_bridge_unittests.cc.

286 {
287 std::shared_ptr<TestAccessibilityBridge> bridge =
288 std::make_shared<TestAccessibilityBridge>();
289 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root");
290 auto flags = FlutterSemanticsFlags{
291 .is_enabled = FlutterTristate::kFlutterTristateTrue,
292 .is_focused = FlutterTristate::kFlutterTristateFalse,
293 .is_slider = true,
294 };
295
296 root.flags2 = &flags;
297
298 bridge->AddFlutterSemanticsNodeUpdate(root);
299 bridge->CommitUpdates();
300
301 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
302 EXPECT_EQ(root_node->GetData().role, ax::mojom::Role::kSlider);
303 }

References CreateSemanticsNode().

## ◆ TEST() [14/122]

flutter::testing::TEST | ( | AccessibilityBridgeTest | ,
|  | SwitchHasSwitchRole |
| ) |  |

Definition at line 269 of file accessibility_bridge_unittests.cc.

269 {
270 std::shared_ptr<TestAccessibilityBridge> bridge =
271 std::make_shared<TestAccessibilityBridge>();
272 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root");
273 auto flags = FlutterSemanticsFlags{
274 .is_enabled = FlutterTristate::kFlutterTristateTrue,
275 .is_toggled = FlutterTristate::kFlutterTristateFalse,
276 };
277
278 root.flags2 = &flags;
279 bridge->AddFlutterSemanticsNodeUpdate(root);
280 bridge->CommitUpdates();
281
282 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
283 EXPECT_EQ(root_node->GetData().role, ax::mojom::Role::kSwitch);
284 }

References CreateSemanticsNode().

## ◆ TEST() [15/122]

flutter::testing::TEST | ( | FlutterAppDelegateTest | ,
|  | DoesNotCallDelegatesWithoutHandler |
| ) |  |

Definition at line 32 of file FlutterAppDelegateTest.mm.

32 {
33 FlutterAppDelegate* appDelegate = [[FlutterAppDelegate alloc] init];
34 AppDelegateNoopFlutterAppLifecycleDelegate* noopDelegate =
35 [[AppDelegateNoopFlutterAppLifecycleDelegate alloc] init];
36 [appDelegate addApplicationLifecycleDelegate:noopDelegate];
37
38 [appDelegate application:NSApplication.sharedApplication openURLs:@[]];
39 // No EXPECT, since the test is that the call doesn't throw due to calling without checking that
40 // the method is implemented.
41 }
AppDelegateNoopFlutterAppLifecycleDelegate
Definition: FlutterAppDelegateTest.mm:10
FlutterAppDelegate
Definition: FlutterAppDelegate.h:54
-[FlutterAppLifecycleProvider-p addApplicationLifecycleDelegate:]
void addApplicationLifecycleDelegate:(nonnull NSObject< FlutterAppLifecycleDelegate > *delegate)

References <FlutterAppLifecycleProvider>::addApplicationLifecycleDelegate:.

## ◆ TEST() [16/122]

flutter::testing::TEST | ( | FlutterAppDelegateTest | ,
|  | OperURLsStopsAfterHandled |
| ) |  |

Definition at line 57 of file FlutterAppDelegateTest.mm.

57 {
58 FlutterAppDelegate* appDelegate = [[FlutterAppDelegate alloc] init];
59 AppDelegateTestFlutterAppLifecycleDelegate* firstDelegate =
60 [[AppDelegateTestFlutterAppLifecycleDelegate alloc] init];
61 AppDelegateTestFlutterAppLifecycleDelegate* secondDelegate =
62 [[AppDelegateTestFlutterAppLifecycleDelegate alloc] init];
63 [appDelegate addApplicationLifecycleDelegate:firstDelegate];
64 [appDelegate addApplicationLifecycleDelegate:secondDelegate];
65
66 NSURL* URL = [NSURL URLWithString:@"https://flutter.dev"];
67 EXPECT_NE(URL, nil);
68 NSArray<NSURL*>* URLs = @[ URL ];
69 [appDelegate application:NSApplication.sharedApplication openURLs:URLs];
70
71 EXPECT_EQ([firstDelegate receivedURLs], URLs);
72 EXPECT_EQ([secondDelegate receivedURLs], nil);
73 }
AppDelegateTestFlutterAppLifecycleDelegate
Definition: FlutterAppDelegateTest.mm:17

References <FlutterAppLifecycleProvider>::addApplicationLifecycleDelegate:, and AppDelegateNoopFlutterAppLifecycleDelegate::receivedURLs.

## ◆ TEST() [17/122]

flutter::testing::TEST | ( | FlutterAppDelegateTest | ,
|  | ReceivesOpenURLs |
| ) |  |

Definition at line 43 of file FlutterAppDelegateTest.mm.

43 {
44 FlutterAppDelegate* appDelegate = [[FlutterAppDelegate alloc] init];
45 AppDelegateTestFlutterAppLifecycleDelegate* delegate =
46 [[AppDelegateTestFlutterAppLifecycleDelegate alloc] init];
47 [appDelegate addApplicationLifecycleDelegate:delegate];
48
49 NSURL* URL = [NSURL URLWithString:@"https://flutter.dev"];
50 EXPECT_NE(URL, nil);
51 NSArray<NSURL*>* URLs = @[ URL ];
52 [appDelegate application:NSApplication.sharedApplication openURLs:URLs];
53
54 EXPECT_EQ([delegate receivedURLs], URLs);
55 }

References <FlutterAppLifecycleProvider>::addApplicationLifecycleDelegate:, and AppDelegateNoopFlutterAppLifecycleDelegate::receivedURLs.

## ◆ TEST() [18/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | ReleasesDelegateOnDealloc |
| ) |  |

Definition at line 223 of file FlutterAppLifecycleDelegateTest.mm.

223 {
224 __weak FlutterAppLifecycleRegistrar* weakRegistrar;
225 __weak TestFlutterAppLifecycleDelegate* weakDelegate;
226 @autoreleasepool {
227 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
228 weakRegistrar = registrar;
229 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
230 weakDelegate = delegate;
231 [registrar addDelegate:delegate];
232 }
233 EXPECT_EQ(weakRegistrar, nil);
234 EXPECT_EQ(weakDelegate, nil);
235 }
FlutterAppLifecycleRegistrar
Definition: FlutterAppLifecycleDelegate.h:126
-[FlutterAppLifecycleRegistrar addDelegate:]
void addDelegate:(NSObject< FlutterAppLifecycleDelegate > *delegate)
Definition: FlutterAppLifecycleDelegate.mm:58
TestFlutterAppLifecycleDelegate
Definition: FlutterAppLifecycleDelegateTest.mm:10

References FlutterAppLifecycleRegistrar::addDelegate:.

## ◆ TEST() [19/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToDidBecomeActive |
| ) |  |

Definition at line 109 of file FlutterAppLifecycleDelegateTest.mm.

109 {
110 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
111 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
112 [registrar addDelegate:delegate];
113
114 NSNotification* didBecomeActive =
115 [NSNotification notificationWithName:NSApplicationDidBecomeActiveNotification object:nil];
116 [registrar handleDidBecomeActive:didBecomeActive];
117 EXPECT_EQ([delegate lastNotification], didBecomeActive);
118 }
-[FlutterAppLifecycleDelegate-p handleDidBecomeActive:]
void handleDidBecomeActive:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleDidBecomeActive:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [20/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToDidChangeOcclusionState |
| ) |  |

Definition at line 209 of file FlutterAppLifecycleDelegateTest.mm.

209 {
210 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
211 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
212 [registrar addDelegate:delegate];
213
214 NSNotification* didChangeOcclusionState =
215 [NSNotification notificationWithName:NSApplicationDidChangeOcclusionStateNotification
216 object:nil];
217 if ([registrar respondsToSelector:@selector(handleDidChangeOcclusionState:)]) {
218 [registrar handleDidChangeOcclusionState:didChangeOcclusionState];
219 EXPECT_EQ([delegate lastNotification], didChangeOcclusionState);
220 }
221 }
-[FlutterAppLifecycleDelegate-p handleDidChangeOcclusionState:]
void handleDidChangeOcclusionState:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleDidChangeOcclusionState:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [21/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToDidChangeScreenParameters |
| ) |  |

Definition at line 197 of file FlutterAppLifecycleDelegateTest.mm.

197 {
198 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
199 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
200 [registrar addDelegate:delegate];
201
202 NSNotification* didChangeScreenParameters =
203 [NSNotification notificationWithName:NSApplicationDidChangeScreenParametersNotification
204 object:nil];
205 [registrar handleDidChangeScreenParameters:didChangeScreenParameters];
206 EXPECT_EQ([delegate lastNotification], didChangeScreenParameters);
207 }
-[FlutterAppLifecycleDelegate-p handleDidChangeScreenParameters:]
void handleDidChangeScreenParameters:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleDidChangeScreenParameters:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [22/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToDidFinishLaunching |
| ) |  |

Definition at line 87 of file FlutterAppLifecycleDelegateTest.mm.

87 {
88 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
89 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
90 [registrar addDelegate:delegate];
91
92 NSNotification* didFinishLaunching =
93 [NSNotification notificationWithName:NSApplicationDidFinishLaunchingNotification object:nil];
94 [registrar handleDidFinishLaunching:didFinishLaunching];
95 EXPECT_EQ([delegate lastNotification], didFinishLaunching);
96 }
-[FlutterAppLifecycleDelegate-p handleDidFinishLaunching:]
void handleDidFinishLaunching:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleDidFinishLaunching:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [23/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToDidHide |
| ) |  |

Definition at line 175 of file FlutterAppLifecycleDelegateTest.mm.

175 {
176 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
177 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
178 [registrar addDelegate:delegate];
179
180 NSNotification* didHide = [NSNotification notificationWithName:NSApplicationDidHideNotification
181 object:nil];
182 [registrar handleDidHide:didHide];
183 EXPECT_EQ([delegate lastNotification], didHide);
184 }
-[FlutterAppLifecycleDelegate-p handleDidHide:]
void handleDidHide:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleDidHide:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [24/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToDidResignActive |
| ) |  |

Definition at line 131 of file FlutterAppLifecycleDelegateTest.mm.

131 {
132 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
133 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
134 [registrar addDelegate:delegate];
135
136 NSNotification* didResignActive =
137 [NSNotification notificationWithName:NSApplicationDidResignActiveNotification object:nil];
138 [registrar handleDidResignActive:didResignActive];
139 EXPECT_EQ([delegate lastNotification], didResignActive);
140 }
-[FlutterAppLifecycleDelegate-p handleDidResignActive:]
void handleDidResignActive:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleDidResignActive:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [25/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToDidUnhide |
| ) |  |

Definition at line 186 of file FlutterAppLifecycleDelegateTest.mm.

186 {
187 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
188 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
189 [registrar addDelegate:delegate];
190
191 NSNotification* didUnhide =
192 [NSNotification notificationWithName:NSApplicationDidUnhideNotification object:nil];
193 [registrar handleDidUnhide:didUnhide];
194 EXPECT_EQ([delegate lastNotification], didUnhide);
195 }
-[FlutterAppLifecycleDelegate-p handleDidUnhide:]
void handleDidUnhide:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleDidUnhide:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [26/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToWillBecomeActive |
| ) |  |

Definition at line 98 of file FlutterAppLifecycleDelegateTest.mm.

98 {
99 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
100 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
101 [registrar addDelegate:delegate];
102
103 NSNotification* willBecomeActive =
104 [NSNotification notificationWithName:NSApplicationWillBecomeActiveNotification object:nil];
105 [registrar handleWillBecomeActive:willBecomeActive];
106 EXPECT_EQ([delegate lastNotification], willBecomeActive);
107 }
-[FlutterAppLifecycleDelegate-p handleWillBecomeActive:]
void handleWillBecomeActive:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleWillBecomeActive:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [27/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToWillFinishLaunching |
| ) |  |

Definition at line 76 of file FlutterAppLifecycleDelegateTest.mm.

76 {
77 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
78 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
79 [registrar addDelegate:delegate];
80
81 NSNotification* willFinishLaunching =
82 [NSNotification notificationWithName:NSApplicationWillFinishLaunchingNotification object:nil];
83 [registrar handleWillFinishLaunching:willFinishLaunching];
84 EXPECT_EQ([delegate lastNotification], willFinishLaunching);
85 }
-[FlutterAppLifecycleDelegate-p handleWillFinishLaunching:]
void handleWillFinishLaunching:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleWillFinishLaunching:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [28/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToWillHide |
| ) |  |

Definition at line 153 of file FlutterAppLifecycleDelegateTest.mm.

153 {
154 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
155 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
156 [registrar addDelegate:delegate];
157
158 NSNotification* willHide = [NSNotification notificationWithName:NSApplicationWillHideNotification
159 object:nil];
160 [registrar handleWillHide:willHide];
161 EXPECT_EQ([delegate lastNotification], willHide);
162 }
-[FlutterAppLifecycleDelegate-p handleWillHide:]
void handleWillHide:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleWillHide:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [29/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToWillResignActive |
| ) |  |

Definition at line 120 of file FlutterAppLifecycleDelegateTest.mm.

120 {
121 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
122 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
123 [registrar addDelegate:delegate];
124
125 NSNotification* willResignActive =
126 [NSNotification notificationWithName:NSApplicationWillResignActiveNotification object:nil];
127 [registrar handleWillResignActive:willResignActive];
128 EXPECT_EQ([delegate lastNotification], willResignActive);
129 }
-[FlutterAppLifecycleDelegate-p handleWillResignActive:]
void handleWillResignActive:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleWillResignActive:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [30/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToWillTerminate |
| ) |  |

Definition at line 142 of file FlutterAppLifecycleDelegateTest.mm.

142 {
143 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
144 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
145 [registrar addDelegate:delegate];
146
147 NSNotification* applicationWillTerminate =
148 [NSNotification notificationWithName:NSApplicationWillTerminateNotification object:nil];
149 [registrar handleWillTerminate:applicationWillTerminate];
150 EXPECT_EQ([delegate lastNotification], applicationWillTerminate);
151 }
-[FlutterAppLifecycleDelegate-p handleWillTerminate:]
void handleWillTerminate:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleWillTerminate:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [31/122]

flutter::testing::TEST | ( | FlutterAppLifecycleDelegateTest | ,
|  | RespondsToWillUnhide |
| ) |  |

Definition at line 164 of file FlutterAppLifecycleDelegateTest.mm.

164 {
165 FlutterAppLifecycleRegistrar* registrar = [[FlutterAppLifecycleRegistrar alloc] init];
166 TestFlutterAppLifecycleDelegate* delegate = [[TestFlutterAppLifecycleDelegate alloc] init];
167 [registrar addDelegate:delegate];
168
169 NSNotification* willUnhide =
170 [NSNotification notificationWithName:NSApplicationWillUnhideNotification object:nil];
171 [registrar handleWillUnhide:willUnhide];
172 EXPECT_EQ([delegate lastNotification], willUnhide);
173 }
-[FlutterAppLifecycleDelegate-p handleWillUnhide:]
void handleWillUnhide:(NSNotification *notification)

References FlutterAppLifecycleRegistrar::addDelegate:, <FlutterAppLifecycleDelegate>::handleWillUnhide:, and TestFlutterAppLifecycleDelegate::lastNotification.

## ◆ TEST() [32/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | BasicKeyEvent |
| ) |  |

Definition at line 118 of file FlutterEmbedderKeyResponderTest.mm.

118 {
119 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
120 __block BOOL last_handled = TRUE;
121 FlutterKeyEvent* event;
122
123 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
124 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
125 void* _Nullable user_data) {
126 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
127 callback:callback
128 userData:user_data]];
129 }];
130
131 last_handled = FALSE;
132 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 123.0f, 0x100, @"a", @"a", FALSE, 0)
133 callback:^(BOOL handled) {
134 last_handled = handled;
135 }];
136
137 EXPECT_EQ([events count], 1u);
138 event = [events lastObject].data;
139 ASSERT_NE(event, nullptr);
140 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
141 EXPECT_EQ(event->timestamp, 123000000.0f);
142 EXPECT_EQ(event->physical, kPhysicalKeyA);
143 EXPECT_EQ(event->logical, kLogicalKeyA);
144 EXPECT_STREQ(event->character, "a");
145 EXPECT_EQ(event->synthesized, false);
146
147 EXPECT_EQ(last_handled, FALSE);
148 EXPECT_TRUE([[events lastObject] hasCallback]);
149 [[events lastObject] respond:TRUE];
150 EXPECT_EQ(last_handled, TRUE);
151
152 [events removeAllObjects];
153
154 last_handled = FALSE;
155 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", TRUE, kKeyCodeKeyA)
156 callback:^(BOOL handled) {
157 last_handled = handled;
158 }];
159
160 EXPECT_EQ([events count], 1u);
161 event = [events lastObject].data;
162 ASSERT_NE(event, nullptr);
163 EXPECT_EQ(event->type, kFlutterKeyEventTypeRepeat);
164 EXPECT_EQ(event->physical, kPhysicalKeyA);
165 EXPECT_EQ(event->logical, kLogicalKeyA);
166 EXPECT_STREQ(event->character, "a");
167 EXPECT_EQ(event->synthesized, false);
168
169 EXPECT_EQ(last_handled, FALSE);
170 EXPECT_TRUE([[events lastObject] hasCallback]);
171 [[events lastObject] respond:TRUE];
172 EXPECT_EQ(last_handled, TRUE);
173
174 [events removeAllObjects];
175
176 last_handled = TRUE;
177 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 124.0f, 0x100, @"a", @"a", FALSE, kKeyCodeKeyA)
178 callback:^(BOOL handled) {
179 last_handled = handled;
180 }];
181
182 EXPECT_EQ([events count], 1u);
183 event = [events lastObject].data;
184 ASSERT_NE(event, nullptr);
185 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
186 EXPECT_EQ(event->timestamp, 124000000.0f);
187 EXPECT_EQ(event->physical, kPhysicalKeyA);
188 EXPECT_EQ(event->logical, kLogicalKeyA);
189 EXPECT_EQ(event->character, nullptr);
190 EXPECT_EQ(event->synthesized, false);
191
192 EXPECT_EQ(last_handled, TRUE);
193 EXPECT_TRUE([[events lastObject] hasCallback]);
194 [[events lastObject] respond:FALSE]; // Check if responding FALSE works
195 EXPECT_EQ(last_handled, FALSE);
196
197 [events removeAllObjects];
198 }
FlutterEmbedderKeyResponder
Definition: FlutterEmbedderKeyResponder.h:23
TestKeyEvent
Definition: FlutterEmbedderKeyResponderTest.mm:14
-[FlutterKeyPrimaryResponder-p handleEvent:callback:]
void handleEvent:callback:(nonnull NSEvent *event,[callback] nonnull FlutterAsyncKeyCallback callback)

References <FlutterKeyPrimaryResponder>::handleEvent:callback:, and TestKeyEvent::hasCallback.

## ◆ TEST() [33/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | ConvertAbruptRepeatEventsToDown |
| ) |  |

Definition at line 410 of file FlutterEmbedderKeyResponderTest.mm.

410 {
411 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
412 __block BOOL last_handled = TRUE;
413 FlutterKeyEvent* event;
414
415 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
416 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
417 void* _Nullable user_data) {
418 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
419 callback:callback
420 userData:user_data]];
421 }];
422
423 last_handled = TRUE;
424 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", TRUE, kKeyCodeKeyA)
425 callback:^(BOOL handled) {
426 last_handled = handled;
427 }];
428
429 EXPECT_EQ([events count], 1u);
430 event = [events lastObject].data;
431 ASSERT_NE(event, nullptr);
432 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
433 EXPECT_EQ(event->physical, kPhysicalKeyA);
434 EXPECT_EQ(event->logical, kLogicalKeyA);
435 EXPECT_STREQ(event->character, "a");
436 EXPECT_EQ(event->synthesized, false);
437 EXPECT_EQ(last_handled, TRUE);
438 [[events lastObject] respond:FALSE];
439 EXPECT_EQ(last_handled, FALSE);
440
441 [events removeAllObjects];
442 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [34/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | ConvertCapsLockEvents |
| ) |  |

Definition at line 1100 of file FlutterEmbedderKeyResponderTest.mm.

1100 {
1101 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
1102 __block BOOL last_handled = TRUE;
1103 id keyEventCallback = ^(BOOL handled) {
1104 last_handled = handled;
1105 };
1106 FlutterKeyEvent* event;
1107
1108 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
1109 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
1110 void* _Nullable user_data) {
1111 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
1112 callback:callback
1113 userData:user_data]];
1114 }];
1115
1116 // In: CapsLock down
1117 // Out: CapsLock down & *CapsLock Up
1118 last_handled = FALSE;
1119 [responder
1120 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x10100, @"", @"", FALSE, kKeyCodeCapsLock)
1121 callback:keyEventCallback];
1122
1123 EXPECT_EQ([events count], 2u);
1124
1125 event = [events firstObject].data;
1126 ASSERT_NE(event, nullptr);
1127 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1128 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1129 EXPECT_EQ(event->logical, kLogicalCapsLock);
1130 EXPECT_STREQ(event->character, nullptr);
1131 EXPECT_EQ(event->synthesized, false);
1132 EXPECT_TRUE([[events firstObject] hasCallback]);
1133
1134 event = [events lastObject].data;
1135 ASSERT_NE(event, nullptr);
1136 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1137 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1138 EXPECT_EQ(event->logical, kLogicalCapsLock);
1139 EXPECT_STREQ(event->character, nullptr);
1140 EXPECT_EQ(event->synthesized, true);
1141 EXPECT_FALSE([[events lastObject] hasCallback]);
1142
1143 EXPECT_EQ(last_handled, FALSE);
1144 [[events firstObject] respond:TRUE];
1145 EXPECT_EQ(last_handled, TRUE);
1146
1147 [events removeAllObjects];
1148
1149 // In: CapsLock up
1150 // Out: CapsLock down & *CapsLock Up
1151 last_handled = FALSE;
1152 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeCapsLock)
1153 callback:keyEventCallback];
1154
1155 EXPECT_EQ([events count], 2u);
1156
1157 event = [events firstObject].data;
1158 ASSERT_NE(event, nullptr);
1159 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1160 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1161 EXPECT_EQ(event->logical, kLogicalCapsLock);
1162 EXPECT_STREQ(event->character, nullptr);
1163 EXPECT_EQ(event->synthesized, false);
1164 EXPECT_TRUE([[events firstObject] hasCallback]);
1165
1166 event = [events lastObject].data;
1167 ASSERT_NE(event, nullptr);
1168 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1169 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1170 EXPECT_EQ(event->logical, kLogicalCapsLock);
1171 EXPECT_STREQ(event->character, nullptr);
1172 EXPECT_EQ(event->synthesized, true);
1173 EXPECT_FALSE([[events lastObject] hasCallback]);
1174
1175 EXPECT_EQ(last_handled, FALSE);
1176 [[events firstObject] respond:TRUE];
1177 EXPECT_EQ(last_handled, TRUE);
1178
1179 [events removeAllObjects];
1180 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:, and TestKeyEvent::hasCallback.

## ◆ TEST() [35/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | IdentifyLeftAndRightModifiers |
| ) |  |

Definition at line 720 of file FlutterEmbedderKeyResponderTest.mm.

720 {
721 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
722 FlutterKeyEvent* event;
723
724 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
725 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
726 void* _Nullable user_data) {
727 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
728 callback:callback
729 userData:user_data]];
730 }];
731
732 [responder
733 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
734 callback:^(BOOL handled){
735 }];
736
737 EXPECT_EQ([events count], 1u);
738 event = [events lastObject].data;
739 ASSERT_NE(event, nullptr);
740 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
741 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
742 EXPECT_EQ(event->logical, kLogicalShiftLeft);
743 EXPECT_STREQ(event->character, nullptr);
744 EXPECT_EQ(event->synthesized, false);
745 [[events lastObject] respond:TRUE];
746
747 [events removeAllObjects];
748
749 [responder
750 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20106, @"", @"", FALSE, kKeyCodeShiftRight)
751 callback:^(BOOL handled){
752 }];
753
754 EXPECT_EQ([events count], 1u);
755 event = [events lastObject].data;
756 ASSERT_NE(event, nullptr);
757 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
758 EXPECT_EQ(event->physical, kPhysicalShiftRight);
759 EXPECT_EQ(event->logical, kLogicalShiftRight);
760 EXPECT_STREQ(event->character, nullptr);
761 EXPECT_EQ(event->synthesized, false);
762 [[events lastObject] respond:TRUE];
763
764 [events removeAllObjects];
765
766 [responder
767 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20104, @"", @"", FALSE, kKeyCodeShiftLeft)
768 callback:^(BOOL handled){
769 }];
770
771 EXPECT_EQ([events count], 1u);
772 event = [events lastObject].data;
773 ASSERT_NE(event, nullptr);
774 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
775 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
776 EXPECT_EQ(event->logical, kLogicalShiftLeft);
777 EXPECT_STREQ(event->character, nullptr);
778 EXPECT_EQ(event->synthesized, false);
779 [[events lastObject] respond:TRUE];
780
781 [events removeAllObjects];
782
783 [responder
784 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftRight)
785 callback:^(BOOL handled){
786 }];
787
788 EXPECT_EQ([events count], 1u);
789 event = [events lastObject].data;
790 ASSERT_NE(event, nullptr);
791 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
792 EXPECT_EQ(event->physical, kPhysicalShiftRight);
793 EXPECT_EQ(event->logical, kLogicalShiftRight);
794 EXPECT_STREQ(event->character, nullptr);
795 EXPECT_EQ(event->synthesized, false);
796 [[events lastObject] respond:TRUE];
797
798 [events removeAllObjects];
799 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [36/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | IgnoreDuplicateUpEvent |
| ) |  |

Definition at line 379 of file FlutterEmbedderKeyResponderTest.mm.

379 {
380 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
381 FlutterKeyEvent* event;
382 __block BOOL last_handled = TRUE;
383
384 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
385 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
386 void* _Nullable user_data) {
387 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
388 callback:callback
389 userData:user_data]];
390 }];
391
392 last_handled = FALSE;
393 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0x100, @"a", @"a", FALSE, kKeyCodeKeyA)
394 callback:^(BOOL handled) {
395 last_handled = handled;
396 }];
397
398 EXPECT_EQ([events count], 1u);
399 EXPECT_EQ(last_handled, TRUE);
400 event = [events lastObject].data;
401 ASSERT_NE(event, nullptr);
402 EXPECT_EQ(event->physical, 0ull);
403 EXPECT_EQ(event->logical, 0ull);
404 EXPECT_FALSE([[events lastObject] hasCallback]);
405 EXPECT_EQ(last_handled, TRUE);
406
407 [events removeAllObjects];
408 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:, and TestKeyEvent::hasCallback.

## ◆ TEST() [37/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | MultipleCharacters |
| ) |  |

Definition at line 274 of file FlutterEmbedderKeyResponderTest.mm.

274 {
275 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
276 FlutterKeyEvent* event;
277
278 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
279 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
280 void* _Nullable user_data) {
281 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
282 callback:callback
283 userData:user_data]];
284 }];
285
286 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0, @"Ã n", @"Ã n", FALSE, kKeyCodeKeyA)
287 callback:^(BOOL handled){
288 }];
289
290 EXPECT_EQ([events count], 1u);
291 event = [events lastObject].data;
292 ASSERT_NE(event, nullptr);
293 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
294 EXPECT_EQ(event->physical, kPhysicalKeyA);
295 EXPECT_EQ(event->logical, 0x1400000000ull);
296 EXPECT_STREQ(event->character, "Ã n");
297 EXPECT_EQ(event->synthesized, false);
298
299 [events removeAllObjects];
300
301 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0, @"a", @"a", FALSE, kKeyCodeKeyA)
302 callback:^(BOOL handled){
303 }];
304
305 EXPECT_EQ([events count], 1u);
306 event = [events lastObject].data;
307 ASSERT_NE(event, nullptr);
308 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
309 EXPECT_EQ(event->physical, kPhysicalKeyA);
310 EXPECT_EQ(event->logical, 0x1400000000ull);
311 EXPECT_STREQ(event->character, nullptr);
312 EXPECT_EQ(event->synthesized, false);
313
314 [events removeAllObjects];
315 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [38/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | NonAsciiCharacters |
| ) |  |

Definition at line 200 of file FlutterEmbedderKeyResponderTest.mm.

200 {
201 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
202 FlutterKeyEvent* event;
203
204 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
205 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
206 void* _Nullable user_data) {
207 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
208 callback:callback
209 userData:user_data]];
210 }];
211
212 [responder
213 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x80140, @"", @"", FALSE, kKeyCodeAltRight)
214 callback:^(BOOL handled){
215 }];
216
217 EXPECT_EQ([events count], 1u);
218 event = [events lastObject].data;
219 ASSERT_NE(event, nullptr);
220 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
221 EXPECT_EQ(event->physical, kPhysicalAltRight);
222 EXPECT_EQ(event->logical, kLogicalAltRight);
223 EXPECT_STREQ(event->character, nullptr);
224 EXPECT_EQ(event->synthesized, false);
225
226 [events removeAllObjects];
227
228 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x80140, @"âˆ‘", @"w", FALSE, kKeyCodeKeyW)
229 callback:^(BOOL handled){
230 }];
231
232 EXPECT_EQ([events count], 1u);
233 event = [events lastObject].data;
234 ASSERT_NE(event, nullptr);
235 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
236 EXPECT_EQ(event->physical, kPhysicalKeyW);
237 EXPECT_EQ(event->logical, kLogicalKeyW);
238 EXPECT_STREQ(event->character, "âˆ‘");
239 EXPECT_EQ(event->synthesized, false);
240
241 [events removeAllObjects];
242
243 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeAltRight)
244 callback:^(BOOL handled){
245 }];
246
247 EXPECT_EQ([events count], 1u);
248 event = [events lastObject].data;
249 ASSERT_NE(event, nullptr);
250 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
251 EXPECT_EQ(event->physical, kPhysicalAltRight);
252 EXPECT_EQ(event->logical, kLogicalAltRight);
253 EXPECT_STREQ(event->character, nullptr);
254 EXPECT_EQ(event->synthesized, false);
255
256 [events removeAllObjects];
257
258 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0x100, @"w", @"w", FALSE, kKeyCodeKeyW)
259 callback:^(BOOL handled){
260 }];
261
262 EXPECT_EQ([events count], 1u);
263 event = [events lastObject].data;
264 ASSERT_NE(event, nullptr);
265 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
266 EXPECT_EQ(event->physical, kPhysicalKeyW);
267 EXPECT_EQ(event->logical, kLogicalKeyW);
268 EXPECT_STREQ(event->character, nullptr);
269 EXPECT_EQ(event->synthesized, false);
270
271 [events removeAllObjects];
272 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [39/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | SpecialModiferFlags |
| ) |  |

Definition at line 564 of file FlutterEmbedderKeyResponderTest.mm.

564 {
565 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
566 FlutterKeyEvent* event;
567
568 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
569 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
570 void* _Nullable user_data) {
571 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
572 callback:callback
573 userData:user_data]];
574 }];
575
576 // Keydown: Numpad1, F1, KeyA, ShiftLeft
577 // Then KeyUp: Numpad1, F1, KeyA, ShiftLeft
578
579 // Numpad 1
580 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x200100, @"1", @"1", FALSE, kKeyCodeNumpad1)
581 callback:^(BOOL handled){
582 }];
583
584 EXPECT_EQ([events count], 1u);
585 event = [events lastObject].data;
586 ASSERT_NE(event, nullptr);
587 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
588 EXPECT_EQ(event->physical, kPhysicalNumpad1);
589 EXPECT_EQ(event->logical, kLogicalNumpad1);
590 EXPECT_STREQ(event->character, "1");
591 EXPECT_EQ(event->synthesized, false);
592 [[events lastObject] respond:TRUE];
593
594 [events removeAllObjects];
595
596 // F1
597 [responder
598 handleEvent:keyEvent(NSEventTypeKeyDown, 0x800100, @"\uf704", @"\uf704", FALSE, kKeyCodeF1)
599 callback:^(BOOL handled){
600 }];
601
602 EXPECT_EQ([events count], 1u);
603 event = [events lastObject].data;
604 ASSERT_NE(event, nullptr);
605 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
606 EXPECT_EQ(event->physical, kPhysicalF1);
607 EXPECT_EQ(event->logical, kLogicalF1);
608 EXPECT_STREQ(event->character, nullptr);
609 EXPECT_EQ(event->synthesized, false);
610 [[events lastObject] respond:TRUE];
611
612 [events removeAllObjects];
613
614 // KeyA
615 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", FALSE, kKeyCodeKeyA)
616 callback:^(BOOL handled){
617 }];
618
619 EXPECT_EQ([events count], 1u);
620 event = [events lastObject].data;
621 ASSERT_NE(event, nullptr);
622 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
623 EXPECT_EQ(event->physical, kPhysicalKeyA);
624 EXPECT_EQ(event->logical, kLogicalKeyA);
625 EXPECT_STREQ(event->character, "a");
626 EXPECT_EQ(event->synthesized, false);
627 [[events lastObject] respond:TRUE];
628
629 [events removeAllObjects];
630
631 // ShiftLeft
632 [responder
633 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
634 callback:^(BOOL handled){
635 }];
636
637 EXPECT_EQ([events count], 1u);
638 event = [events lastObject].data;
639 ASSERT_NE(event, nullptr);
640 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
641 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
642 EXPECT_EQ(event->logical, kLogicalShiftLeft);
643 EXPECT_STREQ(event->character, nullptr);
644 EXPECT_EQ(event->synthesized, false);
645 [[events lastObject] respond:TRUE];
646
647 [events removeAllObjects];
648
649 // Numpad 1
650 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0x220102, @"1", @"1", FALSE, kKeyCodeNumpad1)
651 callback:^(BOOL handled){
652 }];
653
654 EXPECT_EQ([events count], 1u);
655 event = [events lastObject].data;
656 ASSERT_NE(event, nullptr);
657 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
658 EXPECT_EQ(event->physical, kPhysicalNumpad1);
659 EXPECT_EQ(event->logical, kLogicalNumpad1);
660 EXPECT_STREQ(event->character, nullptr);
661 EXPECT_EQ(event->synthesized, false);
662 [[events lastObject] respond:TRUE];
663
664 [events removeAllObjects];
665
666 // F1
667 [responder
668 handleEvent:keyEvent(NSEventTypeKeyUp, 0x820102, @"\uF704", @"\uF704", FALSE, kKeyCodeF1)
669 callback:^(BOOL handled){
670 }];
671
672 EXPECT_EQ([events count], 1u);
673 event = [events lastObject].data;
674 ASSERT_NE(event, nullptr);
675 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
676 EXPECT_EQ(event->physical, kPhysicalF1);
677 EXPECT_EQ(event->logical, kLogicalF1);
678 EXPECT_STREQ(event->character, nullptr);
679 EXPECT_EQ(event->synthesized, false);
680 [[events lastObject] respond:TRUE];
681
682 [events removeAllObjects];
683
684 // KeyA
685 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0x20102, @"a", @"a", FALSE, kKeyCodeKeyA)
686 callback:^(BOOL handled){
687 }];
688
689 EXPECT_EQ([events count], 1u);
690 event = [events lastObject].data;
691 ASSERT_NE(event, nullptr);
692 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
693 EXPECT_EQ(event->physical, kPhysicalKeyA);
694 EXPECT_EQ(event->logical, kLogicalKeyA);
695 EXPECT_STREQ(event->character, nullptr);
696 EXPECT_EQ(event->synthesized, false);
697 [[events lastObject] respond:TRUE];
698
699 [events removeAllObjects];
700
701 // ShiftLeft
702 [responder
703 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftLeft)
704 callback:^(BOOL handled){
705 }];
706
707 EXPECT_EQ([events count], 1u);
708 event = [events lastObject].data;
709 ASSERT_NE(event, nullptr);
710 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
711 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
712 EXPECT_EQ(event->logical, kLogicalShiftLeft);
713 EXPECT_STREQ(event->character, nullptr);
714 EXPECT_EQ(event->synthesized, false);
715 [[events lastObject] respond:TRUE];
716
717 [events removeAllObjects];
718 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [40/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | SynchronizeCapsLockStateOnCapsLock |
| ) |  |

Definition at line 1183 of file FlutterEmbedderKeyResponderTest.mm.

1183 {
1184 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
1185 FlutterKeyEvent* event;
1186 __block BOOL last_handled = TRUE;
1187 id keyEventCallback = ^(BOOL handled) {
1188 last_handled = handled;
1189 };
1190
1191 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
1192 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
1193 void* _Nullable user_data) {
1194 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
1195 callback:callback
1196 userData:user_data]];
1197 }];
1198
1199 // In: CapsLock down
1200 // Out: (empty)
1201 last_handled = FALSE;
1202 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeCapsLock)
1203 callback:keyEventCallback];
1204
1205 EXPECT_EQ([events count], 1u);
1206 EXPECT_EQ(last_handled, TRUE);
1207 event = [events lastObject].data;
1208 ASSERT_NE(event, nullptr);
1209 EXPECT_EQ(event->physical, 0ull);
1210 EXPECT_EQ(event->logical, 0ull);
1211 EXPECT_FALSE([[events lastObject] hasCallback]);
1212 EXPECT_EQ(last_handled, TRUE);
1213
1214 [events removeAllObjects];
1215 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:, and TestKeyEvent::hasCallback.

## ◆ TEST() [41/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | SynchronizeCapsLockStateOnNormalKey |
| ) |  |

Definition at line 1218 of file FlutterEmbedderKeyResponderTest.mm.

1218 {
1219 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
1220 __block BOOL last_handled = TRUE;
1221 id keyEventCallback = ^(BOOL handled) {
1222 last_handled = handled;
1223 };
1224 FlutterKeyEvent* event;
1225
1226 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
1227 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
1228 void* _Nullable user_data) {
1229 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
1230 callback:callback
1231 userData:user_data]];
1232 }];
1233
1234 last_handled = FALSE;
1235 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x10100, @"A", @"a", FALSE, kKeyCodeKeyA)
1236 callback:keyEventCallback];
1237
1238 EXPECT_EQ([events count], 3u);
1239
1240 event = events[0].data;
1241 ASSERT_NE(event, nullptr);
1242 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1243 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1244 EXPECT_EQ(event->logical, kLogicalCapsLock);
1245 EXPECT_STREQ(event->character, nullptr);
1246 EXPECT_EQ(event->synthesized, true);
1247 EXPECT_FALSE([events[0] hasCallback]);
1248
1249 event = events[1].data;
1250 ASSERT_NE(event, nullptr);
1251 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1252 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1253 EXPECT_EQ(event->logical, kLogicalCapsLock);
1254 EXPECT_STREQ(event->character, nullptr);
1255 EXPECT_EQ(event->synthesized, true);
1256 EXPECT_FALSE([events[1] hasCallback]);
1257
1258 event = events[2].data;
1259 ASSERT_NE(event, nullptr);
1260 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1261 EXPECT_EQ(event->physical, kPhysicalKeyA);
1262 EXPECT_EQ(event->logical, kLogicalKeyA);
1263 EXPECT_STREQ(event->character, "A");
1264 EXPECT_EQ(event->synthesized, false);
1265 EXPECT_TRUE([events[2] hasCallback]);
1266
1267 EXPECT_EQ(last_handled, FALSE);
1268 [[events lastObject] respond:TRUE];
1269 EXPECT_EQ(last_handled, TRUE);
1270
1271 [events removeAllObjects];
1272 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:, and TestKeyEvent::hasCallback.

## ◆ TEST() [42/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | SynthesizeForDuplicateDownEvent |
| ) |  |

Definition at line 317 of file FlutterEmbedderKeyResponderTest.mm.

317 {
318 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
319 __block BOOL last_handled = TRUE;
320 FlutterKeyEvent* event;
321
322 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
323 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
324 void* _Nullable user_data) {
325 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
326 callback:callback
327 userData:user_data]];
328 }];
329
330 last_handled = TRUE;
331 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", FALSE, kKeyCodeKeyA)
332 callback:^(BOOL handled) {
333 last_handled = handled;
334 }];
335
336 EXPECT_EQ([events count], 1u);
337 event = [events lastObject].data;
338 ASSERT_NE(event, nullptr);
339 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
340 EXPECT_EQ(event->physical, kPhysicalKeyA);
341 EXPECT_EQ(event->logical, kLogicalKeyA);
342 EXPECT_STREQ(event->character, "a");
343 EXPECT_EQ(event->synthesized, false);
344 EXPECT_EQ(last_handled, TRUE);
345 [[events lastObject] respond:FALSE];
346 EXPECT_EQ(last_handled, FALSE);
347
348 [events removeAllObjects];
349
350 last_handled = TRUE;
351 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"Ã ", @"Ã ", FALSE, kKeyCodeKeyA)
352 callback:^(BOOL handled) {
353 last_handled = handled;
354 }];
355
356 EXPECT_EQ([events count], 2u);
357
358 event = [events firstObject].data;
359 ASSERT_NE(event, nullptr);
360 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
361 EXPECT_EQ(event->physical, kPhysicalKeyA);
362 EXPECT_EQ(event->logical, kLogicalKeyA);
363 EXPECT_STREQ(event->character, NULL);
364 EXPECT_EQ(event->synthesized, true);
365
366 event = [events lastObject].data;
367 ASSERT_NE(event, nullptr);
368 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
369 EXPECT_EQ(event->physical, kPhysicalKeyA);
370 EXPECT_EQ(event->logical, 0xE0ull /* Ã */);
371 EXPECT_STREQ(event->character, "Ã ");
372 EXPECT_EQ(event->synthesized, false);
373 [[events lastObject] respond:FALSE];
374 EXPECT_EQ(last_handled, FALSE);
375
376 [events removeAllObjects];
377 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [43/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | SynthesizeMissedModifierEvents |
| ) |  |

Definition at line 806 of file FlutterEmbedderKeyResponderTest.mm.

806 {
807 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
808 __block BOOL last_handled = TRUE;
809 id keyEventCallback = ^(BOOL handled) {
810 last_handled = handled;
811 };
812 FlutterKeyEvent* event;
813
814 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
815 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
816 void* _Nullable user_data) {
817 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
818 callback:callback
819 userData:user_data]];
820 }];
821
822 // Case 1:
823 // In: L down, (L up), L down, L up
824 // Out: L down, L up
825 last_handled = FALSE;
826 [responder
827 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
828 callback:keyEventCallback];
829
830 EXPECT_EQ([events count], 1u);
831 event = [events lastObject].data;
832 ASSERT_NE(event, nullptr);
833 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
834 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
835 EXPECT_EQ(event->logical, kLogicalShiftLeft);
836 EXPECT_STREQ(event->character, nullptr);
837 EXPECT_EQ(event->synthesized, false);
838
839 EXPECT_EQ(last_handled, FALSE);
840 EXPECT_TRUE([[events lastObject] hasCallback]);
841 [[events lastObject] respond:TRUE];
842 EXPECT_EQ(last_handled, TRUE);
843
844 [events removeAllObjects];
845
846 last_handled = FALSE;
847 [responder
848 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
849 callback:keyEventCallback];
850
851 EXPECT_EQ([events count], 1u);
852 event = [events lastObject].data;
853 ASSERT_NE(event, nullptr);
854 EXPECT_EQ(event->physical, 0u);
855 EXPECT_EQ(event->logical, 0u);
856 EXPECT_FALSE([[events lastObject] hasCallback]);
857 EXPECT_EQ(last_handled, TRUE);
858 [events removeAllObjects];
859
860 last_handled = FALSE;
861 [responder
862 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftLeft)
863 callback:keyEventCallback];
864
865 EXPECT_EQ([events count], 1u);
866 event = [events lastObject].data;
867 ASSERT_NE(event, nullptr);
868 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
869 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
870 EXPECT_EQ(event->logical, kLogicalShiftLeft);
871 EXPECT_STREQ(event->character, nullptr);
872 EXPECT_EQ(event->synthesized, false);
873
874 EXPECT_EQ(last_handled, FALSE);
875 EXPECT_TRUE([[events lastObject] hasCallback]);
876 [[events lastObject] respond:TRUE];
877 EXPECT_EQ(last_handled, TRUE);
878
879 [events removeAllObjects];
880
881 // Case 2:
882 // In: (L down), L up
883 // Out:
884
885 last_handled = FALSE;
886 [responder
887 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftLeft)
888 callback:keyEventCallback];
889
890 EXPECT_EQ([events count], 1u);
891 event = [events lastObject].data;
892 ASSERT_NE(event, nullptr);
893 EXPECT_EQ(event->physical, 0u);
894 EXPECT_EQ(event->logical, 0u);
895 EXPECT_FALSE([[events lastObject] hasCallback]);
896 EXPECT_EQ(last_handled, TRUE);
897 [events removeAllObjects];
898
899 // Case 3:
900 // In: L down, (L up), (R down), R up
901 // Out: L down, *L up
902
903 last_handled = FALSE;
904 [responder
905 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
906 callback:keyEventCallback];
907
908 EXPECT_EQ([events count], 1u);
909 event = [events lastObject].data;
910 ASSERT_NE(event, nullptr);
911 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
912 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
913 EXPECT_EQ(event->logical, kLogicalShiftLeft);
914 EXPECT_STREQ(event->character, nullptr);
915 EXPECT_EQ(event->synthesized, false);
916
917 EXPECT_EQ(last_handled, FALSE);
918 EXPECT_TRUE([[events lastObject] hasCallback]);
919 [[events lastObject] respond:TRUE];
920 EXPECT_EQ(last_handled, TRUE);
921
922 [events removeAllObjects];
923
924 last_handled = FALSE;
925 [responder
926 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftRight)
927 callback:keyEventCallback];
928
929 EXPECT_EQ([events count], 1u);
930 event = [events lastObject].data;
931 ASSERT_NE(event, nullptr);
932 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
933 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
934 EXPECT_EQ(event->logical, kLogicalShiftLeft);
935 EXPECT_STREQ(event->character, nullptr);
936 EXPECT_EQ(event->synthesized, true);
937
938 // The primary event is automatically replied with TRUE, unrelated to the received event.
939 EXPECT_EQ(last_handled, TRUE);
940 EXPECT_FALSE([[events lastObject] hasCallback]);
941
942 [events removeAllObjects];
943
944 // Case 4:
945 // In: L down, R down, (L up), R up
946 // Out: L down, R down *L up & R up
947
948 last_handled = FALSE;
949 [responder
950 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
951 callback:keyEventCallback];
952
953 EXPECT_EQ([events count], 1u);
954 event = [events lastObject].data;
955 ASSERT_NE(event, nullptr);
956 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
957 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
958 EXPECT_EQ(event->logical, kLogicalShiftLeft);
959 EXPECT_STREQ(event->character, nullptr);
960 EXPECT_EQ(event->synthesized, false);
961
962 EXPECT_EQ(last_handled, FALSE);
963 EXPECT_TRUE([[events lastObject] hasCallback]);
964 [[events lastObject] respond:TRUE];
965 EXPECT_EQ(last_handled, TRUE);
966
967 [events removeAllObjects];
968
969 last_handled = FALSE;
970 [responder
971 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20106, @"", @"", FALSE, kKeyCodeShiftRight)
972 callback:keyEventCallback];
973
974 EXPECT_EQ([events count], 1u);
975 event = [events lastObject].data;
976 ASSERT_NE(event, nullptr);
977 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
978 EXPECT_EQ(event->physical, kPhysicalShiftRight);
979 EXPECT_EQ(event->logical, kLogicalShiftRight);
980 EXPECT_STREQ(event->character, nullptr);
981 EXPECT_EQ(event->synthesized, false);
982
983 EXPECT_EQ(last_handled, FALSE);
984 EXPECT_TRUE([[events lastObject] hasCallback]);
985 [[events lastObject] respond:TRUE];
986 EXPECT_EQ(last_handled, TRUE);
987
988 [events removeAllObjects];
989
990 last_handled = FALSE;
991 [responder
992 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftRight)
993 callback:keyEventCallback];
994
995 EXPECT_EQ([events count], 2u);
996 event = [events firstObject].data;
997 ASSERT_NE(event, nullptr);
998 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
999 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
1000 EXPECT_EQ(event->logical, kLogicalShiftLeft);
1001 EXPECT_STREQ(event->character, nullptr);
1002 EXPECT_EQ(event->synthesized, true);
1003
1004 EXPECT_FALSE([[events firstObject] hasCallback]);
1005
1006 event = [events lastObject].data;
1007 ASSERT_NE(event, nullptr);
1008 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1009 EXPECT_EQ(event->physical, kPhysicalShiftRight);
1010 EXPECT_EQ(event->logical, kLogicalShiftRight);
1011 EXPECT_STREQ(event->character, nullptr);
1012 EXPECT_EQ(event->synthesized, false);
1013
1014 EXPECT_EQ(last_handled, FALSE);
1015 EXPECT_TRUE([[events lastObject] hasCallback]);
1016 [[events lastObject] respond:TRUE];
1017 EXPECT_EQ(last_handled, TRUE);
1018
1019 [events removeAllObjects];
1020 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:, and TestKeyEvent::hasCallback.

## ◆ TEST() [44/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | SynthesizeMissedModifierEventsInNormalEvents |
| ) |  |

Definition at line 1022 of file FlutterEmbedderKeyResponderTest.mm.

1022 {
1023 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
1024 __block BOOL last_handled = TRUE;
1025 id keyEventCallback = ^(BOOL handled) {
1026 last_handled = handled;
1027 };
1028 FlutterKeyEvent* event;
1029
1030 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
1031 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
1032 void* _Nullable user_data) {
1033 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
1034 callback:callback
1035 userData:user_data]];
1036 }];
1037
1038 // In: (LShift down), A down, (LShift up), A up
1039 // Out: *LS down & A down, *LS up & A up
1040
1041 last_handled = FALSE;
1042 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x20102, @"A", @"A", FALSE, kKeyCodeKeyA)
1043 callback:keyEventCallback];
1044
1045 EXPECT_EQ([events count], 2u);
1046 event = [events firstObject].data;
1047 ASSERT_NE(event, nullptr);
1048 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1049 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
1050 EXPECT_EQ(event->logical, kLogicalShiftLeft);
1051 EXPECT_STREQ(event->character, nullptr);
1052 EXPECT_EQ(event->synthesized, true);
1053 EXPECT_FALSE([[events firstObject] hasCallback]);
1054
1055 event = [events lastObject].data;
1056 ASSERT_NE(event, nullptr);
1057 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1058 EXPECT_EQ(event->physical, kPhysicalKeyA);
1059 EXPECT_EQ(event->logical, kLogicalKeyA);
1060 EXPECT_STREQ(event->character, "A");
1061 EXPECT_EQ(event->synthesized, false);
1062 EXPECT_TRUE([[events lastObject] hasCallback]);
1063
1064 EXPECT_EQ(last_handled, FALSE);
1065 [[events lastObject] respond:TRUE];
1066 EXPECT_EQ(last_handled, TRUE);
1067
1068 [events removeAllObjects];
1069
1070 last_handled = FALSE;
1071 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0x100, @"a", @"a", FALSE, kKeyCodeKeyA)
1072 callback:keyEventCallback];
1073
1074 EXPECT_EQ([events count], 2u);
1075 event = [events firstObject].data;
1076 ASSERT_NE(event, nullptr);
1077 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1078 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
1079 EXPECT_EQ(event->logical, kLogicalShiftLeft);
1080 EXPECT_STREQ(event->character, nullptr);
1081 EXPECT_EQ(event->synthesized, true);
1082 EXPECT_FALSE([[events firstObject] hasCallback]);
1083
1084 event = [events lastObject].data;
1085 ASSERT_NE(event, nullptr);
1086 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1087 EXPECT_EQ(event->physical, kPhysicalKeyA);
1088 EXPECT_EQ(event->logical, kLogicalKeyA);
1089 EXPECT_STREQ(event->character, nullptr);
1090 EXPECT_EQ(event->synthesized, false);
1091 EXPECT_TRUE([[events lastObject] hasCallback]);
1092
1093 EXPECT_EQ(last_handled, FALSE);
1094 [[events lastObject] respond:TRUE];
1095 EXPECT_EQ(last_handled, TRUE);
1096
1097 [events removeAllObjects];
1098 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:, and TestKeyEvent::hasCallback.

## ◆ TEST() [45/122]

flutter::testing::TEST | ( | FlutterEmbedderKeyResponderUnittests | ,
|  | ToggleModifiersDuringKeyTap |
| ) |  |

Definition at line 448 of file FlutterEmbedderKeyResponderTest.mm.

448 {
449 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
450 FlutterKeyEvent* event;
451
452 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
453 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
454 void* _Nullable user_data) {
455 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
456 callback:callback
457 userData:user_data]];
458 }];
459
460 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 123.0f, 0x20104, @"", @"", FALSE,
461 kKeyCodeShiftRight)
462 callback:^(BOOL handled){
463 }];
464
465 EXPECT_EQ([events count], 1u);
466 event = [events lastObject].data;
467 ASSERT_NE(event, nullptr);
468 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
469 EXPECT_EQ(event->timestamp, 123000000.0f);
470 EXPECT_EQ(event->physical, kPhysicalShiftRight);
471 EXPECT_EQ(event->logical, kLogicalShiftRight);
472 EXPECT_STREQ(event->character, nullptr);
473 EXPECT_EQ(event->synthesized, false);
474 [[events lastObject] respond:TRUE];
475
476 [events removeAllObjects];
477
478 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x20104, @"A", @"A", FALSE, kKeyCodeKeyA)
479 callback:^(BOOL handled){
480 }];
481
482 EXPECT_EQ([events count], 1u);
483 event = [events lastObject].data;
484 ASSERT_NE(event, nullptr);
485 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
486 EXPECT_EQ(event->physical, kPhysicalKeyA);
487 EXPECT_EQ(event->logical, kLogicalKeyA);
488 EXPECT_STREQ(event->character, "A");
489 EXPECT_EQ(event->synthesized, false);
490 [[events lastObject] respond:TRUE];
491
492 [events removeAllObjects];
493
494 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x20104, @"A", @"A", TRUE, kKeyCodeKeyA)
495 callback:^(BOOL handled){
496 }];
497
498 EXPECT_EQ([events count], 1u);
499 event = [events lastObject].data;
500 ASSERT_NE(event, nullptr);
501 EXPECT_EQ(event->type, kFlutterKeyEventTypeRepeat);
502 EXPECT_EQ(event->physical, kPhysicalKeyA);
503 EXPECT_EQ(event->logical, kLogicalKeyA);
504 EXPECT_STREQ(event->character, "A");
505 EXPECT_EQ(event->synthesized, false);
506 [[events lastObject] respond:TRUE];
507
508 [events removeAllObjects];
509
510 [responder
511 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftRight)
512 callback:^(BOOL handled){
513 }];
514
515 EXPECT_EQ([events count], 1u);
516 event = [events lastObject].data;
517 ASSERT_NE(event, nullptr);
518 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
519 EXPECT_EQ(event->physical, kPhysicalShiftRight);
520 EXPECT_EQ(event->logical, kLogicalShiftRight);
521 EXPECT_STREQ(event->character, nullptr);
522 EXPECT_EQ(event->synthesized, false);
523 [[events lastObject] respond:TRUE];
524
525 [events removeAllObjects];
526
527 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", TRUE, kKeyCodeKeyA)
528 callback:^(BOOL handled){
529 }];
530
531 EXPECT_EQ([events count], 1u);
532 event = [events lastObject].data;
533 ASSERT_NE(event, nullptr);
534 EXPECT_EQ(event->type, kFlutterKeyEventTypeRepeat);
535 EXPECT_EQ(event->physical, kPhysicalKeyA);
536 EXPECT_EQ(event->logical, kLogicalKeyA);
537 EXPECT_STREQ(event->character, "a");
538 EXPECT_EQ(event->synthesized, false);
539
540 [events removeAllObjects];
541
542 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0x100, @"a", @"a", FALSE, kKeyCodeKeyA)
543 callback:^(BOOL handled){
544 }];
545
546 EXPECT_EQ([events count], 1u);
547 event = [events lastObject].data;
548 ASSERT_NE(event, nullptr);
549 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
550 EXPECT_EQ(event->physical, kPhysicalKeyA);
551 EXPECT_EQ(event->logical, kLogicalKeyA);
552 EXPECT_STREQ(event->character, nullptr);
553 EXPECT_EQ(event->synthesized, false);
554 [[events lastObject] respond:TRUE];
555
556 [events removeAllObjects];
557 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [46/122]

flutter::testing::TEST | ( | FlutterKeyboardManagerUnittests | ,
|  | CorrectLogicalKeyForLayouts |
| ) |  |

Definition at line 469 of file FlutterKeyboardManagerTest.mm.

469 {
470 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] correctLogicalKeyForLayouts]);
471 }
FlutterKeyboardManagerUnittestsObjC
Definition: FlutterKeyboardManagerTest.mm:428

## ◆ TEST() [47/122]

flutter::testing::TEST | ( | FlutterKeyboardManagerUnittests | ,
|  | DoublePrimaryResponder |
| ) |  |

Definition at line 445 of file FlutterKeyboardManagerTest.mm.

445 {
446 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] doublePrimaryResponder]);
447 }

## ◆ TEST() [48/122]

flutter::testing::TEST | ( | FlutterKeyboardManagerUnittests | ,
|  | EmptyNextResponder |
| ) |  |

Definition at line 453 of file FlutterKeyboardManagerTest.mm.

453 {
454 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] emptyNextResponder]);
455 }

## ◆ TEST() [49/122]

flutter::testing::TEST | ( | FlutterKeyboardManagerUnittests | ,
|  | GetPressedState |
| ) |  |

Definition at line 457 of file FlutterKeyboardManagerTest.mm.

457 {
458 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] getPressedState]);
459 }

## ◆ TEST() [50/122]

flutter::testing::TEST | ( | FlutterKeyboardManagerUnittests | ,
|  | KeyboardChannelGetPressedState |
| ) |  |

Definition at line 461 of file FlutterKeyboardManagerTest.mm.

461 {
462 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] keyboardChannelGetPressedState]);
463 }

## ◆ TEST() [51/122]

flutter::testing::TEST | ( | FlutterKeyboardManagerUnittests | ,
|  | RacingConditionBetweenKeyAndText |
| ) |  |

Definition at line 465 of file FlutterKeyboardManagerTest.mm.

465 {
466 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] racingConditionBetweenKeyAndText]);
467 }

## ◆ TEST() [52/122]

flutter::testing::TEST | ( | FlutterKeyboardManagerUnittests | ,
|  | ShouldNotHoldStrongReferenceToDelegate |
| ) |  |

Definition at line 473 of file FlutterKeyboardManagerTest.mm.

473 {
474 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] shouldNotHoldStrongReferenceToDelegate]);
475 }

## ◆ TEST() [53/122]

flutter::testing::TEST | ( | FlutterKeyboardManagerUnittests | ,
|  | SingleFinalResponder |
| ) |  |

Definition at line 449 of file FlutterKeyboardManagerTest.mm.

449 {
450 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] textInputPlugin]);
451 }

## ◆ TEST() [54/122]

flutter::testing::TEST | ( | FlutterKeyboardManagerUnittests | ,
|  | SinglePrimaryResponder |
| ) |  |

Definition at line 441 of file FlutterKeyboardManagerTest.mm.

441 {
442 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] singlePrimaryResponder]);
443 }

## ◆ TEST() [55/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateMac | ,
|  | Basics |
| ) |  |

Definition at line 32 of file FlutterPlatformNodeDelegateMacTest.mm.

32 {
33 FlutterViewController* viewController = CreateTestViewController();
34 FlutterEngine* engine = viewController.engine;
35 engine.semanticsEnabled = YES;
36 auto bridge = viewController.accessibilityBridge.lock();
37 // Initialize ax node data.
38 FlutterSemanticsNode2 root;
39 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
40 root.id = 0;
41 root.flags2 = &flags;
42 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
43 root.actions = static_cast<FlutterSemanticsAction>(0);
44 root.text_selection_base = -1;
45 root.text_selection_extent = -1;
46 root.label = "accessibility";
47 root.hint = "";
48 root.value = "";
49 root.increased_value = "";
50 root.decreased_value = "";
51 root.tooltip = "";
52 root.child_count = 0;
53 root.custom_accessibility_actions_count = 0;
54 root.identifier = "";
55 bridge->AddFlutterSemanticsNodeUpdate(root);
56
57 bridge->CommitUpdates();
58
59 auto root_platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
60 // Verify the accessibility attribute matches.
61 NSAccessibilityElement* native_accessibility =
62 root_platform_node_delegate->GetNativeViewAccessible();
63 std::string value = [native_accessibility.accessibilityValue UTF8String];
64 EXPECT_TRUE(value == "accessibility");
65 EXPECT_EQ(native_accessibility.accessibilityRole, NSAccessibilityStaticTextRole);
66 EXPECT_EQ([native_accessibility.accessibilityChildren count], 0u);
67 [engine shutDownEngine];
68 }
FlutterViewController::engine
FlutterEngine * engine
Definition: FlutterViewController.h:78

References FlutterViewController::engine.

## ◆ TEST() [56/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateMac | ,
|  | CanPerformAction |
| ) |  |

Definition at line 153 of file FlutterPlatformNodeDelegateMacTest.mm.

153 {
154 FlutterViewController* viewController = CreateTestViewController();
155 FlutterEngine* engine = viewController.engine;
156
157 // Attach the view to a NSWindow.
158 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
159 styleMask:NSBorderlessWindowMask
160 backing:NSBackingStoreBuffered
161 defer:NO];
162 window.contentView = viewController.view;
163
164 engine.semanticsEnabled = YES;
165 auto bridge = viewController.accessibilityBridge.lock();
166 // Initialize ax node data.
167 FlutterSemanticsNode2 root;
168 FlutterSemanticsFlags flags = FlutterSemanticsFlags{};
169 root.flags2 = &flags;
170 root.id = 0;
171 root.label = "root";
172 root.hint = "";
173 root.value = "";
174 root.increased_value = "";
175 root.decreased_value = "";
176 root.tooltip = "";
177 root.child_count = 1;
178 int32_t children[] = {1};
179 root.children_in_traversal_order = children;
180 root.custom_accessibility_actions_count = 0;
181 root.identifier = "";
182 bridge->AddFlutterSemanticsNodeUpdate(root);
183
184 FlutterSemanticsNode2 child1;
185 FlutterSemanticsFlags child_flags = FlutterSemanticsFlags{};
186 child1.flags2 = &child_flags;
187 child1.id = 1;
188 child1.label = "child 1";
189 child1.hint = "";
190 child1.value = "";
191 child1.increased_value = "";
192 child1.decreased_value = "";
193 child1.tooltip = "";
194 child1.child_count = 0;
195 child1.custom_accessibility_actions_count = 0;
196 child1.identifier = "";
197 bridge->AddFlutterSemanticsNodeUpdate(child1);
198
199 bridge->CommitUpdates();
200
201 auto root_platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
202
203 // Set up embedder API mock.
204 FlutterSemanticsAction called_action;
205 uint64_t called_id;
206
207 engine.embedderAPI.DispatchSemanticsAction = MOCK_ENGINE_PROC(
208 DispatchSemanticsAction,
209 ([&called_id, &called_action](auto engine, uint64_t id, FlutterSemanticsAction action,
210 const uint8_t* data, size_t data_length) {
211 called_id = id;
212 called_action = action;
213 return kSuccess;
214 }));
215
216 // Performs an AXAction.
217 ui::AXActionData action_data;
218 action_data.action = ax::mojom::Action::kDoDefault;
219 root_platform_node_delegate->AccessibilityPerformAction(action_data);
220
221 EXPECT_EQ(called_action, FlutterSemanticsAction::kFlutterSemanticsActionTap);
222 EXPECT_EQ(called_id, 1u);
223
224 [engine setViewController:nil];
225 [engine shutDownEngine];
226 }

References FlutterViewController::engine.

## ◆ TEST() [57/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateMac | ,
|  | ChangingFlagsUpdatesNativeViewAccessible |
| ) |  |

Definition at line 315 of file FlutterPlatformNodeDelegateMacTest.mm.

315 {
316 FlutterViewController* viewController = CreateTestViewController();
317 FlutterEngine* engine = viewController.engine;
318 [viewController loadView];
319
320 // Creates a NSWindow so that the native text field can become first responder.
321 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
322 styleMask:NSBorderlessWindowMask
323 backing:NSBackingStoreBuffered
324 defer:NO];
325 window.contentView = viewController.view;
326 engine.semanticsEnabled = YES;
327
328 auto bridge = viewController.accessibilityBridge.lock();
329 // Initialize ax node data.
330 FlutterSemanticsNode2 root;
331 root.id = 0;
332 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
333 root.flags2 = &flags;
334 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
335 root.actions = static_cast<FlutterSemanticsAction>(0);
336 root.label = "root";
337 root.hint = "";
338 root.value = "";
339 root.increased_value = "";
340 root.decreased_value = "";
341 root.tooltip = "";
342 root.child_count = 1;
343 int32_t children[] = {1};
344 root.children_in_traversal_order = children;
345 root.custom_accessibility_actions_count = 0;
346 root.identifier = "";
347 root.rect = {0, 0, 100, 100}; // LTRB
348 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
349 bridge->AddFlutterSemanticsNodeUpdate(root);
350
351 double rectSize = 50;
352 double transformFactor = 0.5;
353
354 FlutterSemanticsNode2 child1;
355 FlutterSemanticsFlags child_flags = FlutterSemanticsFlags{0};
356 child1.flags2 = &child_flags;
357 child1.id = 1;
358 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
359 child1.actions = static_cast<FlutterSemanticsAction>(0);
360 child1.label = "";
361 child1.hint = "";
362 child1.value = "textfield";
363 child1.increased_value = "";
364 child1.decreased_value = "";
365 child1.tooltip = "";
366 child1.text_selection_base = -1;
367 child1.text_selection_extent = -1;
368 child1.child_count = 0;
369 child1.custom_accessibility_actions_count = 0;
370 child1.identifier = "";
371 child1.rect = {0, 0, rectSize, rectSize}; // LTRB
372 child1.transform = {transformFactor, 0, 0, 0, transformFactor, 0, 0, 0, 1};
373 bridge->AddFlutterSemanticsNodeUpdate(child1);
374
375 bridge->CommitUpdates();
376
377 auto child_platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
378 // Verify the accessibility attribute matches.
379 id native_accessibility = child_platform_node_delegate->GetNativeViewAccessible();
380 EXPECT_TRUE([[native_accessibility className] isEqualToString:@"AXPlatformNodeCocoa"]);
381
382 // Converting child to text field should produce `FlutterTextField` native view accessible.
383
384 FlutterSemanticsFlags child_flags_updated_1 = FlutterSemanticsFlags{.is_text_field = true};
385 child1.flags2 = &child_flags_updated_1;
386 bridge->AddFlutterSemanticsNodeUpdate(child1);
387 bridge->CommitUpdates();
388
389 native_accessibility = child_platform_node_delegate->GetNativeViewAccessible();
390 EXPECT_TRUE([native_accessibility isKindOfClass:[FlutterTextField class]]);
391
392 FlutterSemanticsFlags child_flags_updated_2 = FlutterSemanticsFlags{.is_text_field = false};
393 child1.flags2 = &child_flags_updated_2;
394 bridge->AddFlutterSemanticsNodeUpdate(child1);
395 bridge->CommitUpdates();
396
397 native_accessibility = child_platform_node_delegate->GetNativeViewAccessible();
398 EXPECT_TRUE([[native_accessibility className] isEqualToString:@"AXPlatformNodeCocoa"]);
399 }
FlutterTextField
Definition: FlutterTextInputSemanticsObject.h:82

References FlutterViewController::engine.

## ◆ TEST() [58/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateMac | ,
|  | SelectableTextHasCorrectSemantics |
| ) |  |

Definition at line 70 of file FlutterPlatformNodeDelegateMacTest.mm.

70 {
71 FlutterViewController* viewController = CreateTestViewController();
72 FlutterEngine* engine = viewController.engine;
73 engine.semanticsEnabled = YES;
74 auto bridge = viewController.accessibilityBridge.lock();
75 // Initialize ax node data.
76 FlutterSemanticsNode2 root;
77 FlutterSemanticsFlags flags = FlutterSemanticsFlags{.is_text_field = true, .is_read_only = true};
78 root.id = 0;
79 root.flags2 = &flags;
80 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
81 root.actions = static_cast<FlutterSemanticsAction>(0);
82 root.text_selection_base = 1;
83 root.text_selection_extent = 3;
84 root.label = "";
85 root.hint = "";
86 // Selectable text store its text in value
87 root.value = "selectable text";
88 root.increased_value = "";
89 root.decreased_value = "";
90 root.tooltip = "";
91 root.child_count = 0;
92 root.custom_accessibility_actions_count = 0;
93 root.identifier = "";
94 bridge->AddFlutterSemanticsNodeUpdate(root);
95
96 bridge->CommitUpdates();
97
98 auto root_platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
99 // Verify the accessibility attribute matches.
100 NSAccessibilityElement* native_accessibility =
101 root_platform_node_delegate->GetNativeViewAccessible();
102 std::string value = [native_accessibility.accessibilityValue UTF8String];
103 EXPECT_EQ(value, "selectable text");
104 EXPECT_EQ(native_accessibility.accessibilityRole, NSAccessibilityStaticTextRole);
105 EXPECT_EQ([native_accessibility.accessibilityChildren count], 0u);
106 NSRange selection = native_accessibility.accessibilitySelectedTextRange;
107 EXPECT_EQ(selection.location, 1u);
108 EXPECT_EQ(selection.length, 2u);
109 std::string selected_text = [native_accessibility.accessibilitySelectedText UTF8String];
110 EXPECT_EQ(selected_text, "el");
111 }

References FlutterViewController::engine.

## ◆ TEST() [59/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateMac | ,
|  | SelectableTextWithoutSelectionReturnZeroRange |
| ) |  |

Definition at line 113 of file FlutterPlatformNodeDelegateMacTest.mm.

113 {
114 FlutterViewController* viewController = CreateTestViewController();
115 FlutterEngine* engine = viewController.engine;
116 engine.semanticsEnabled = YES;
117 auto bridge = viewController.accessibilityBridge.lock();
118 // Initialize ax node data.
119 FlutterSemanticsNode2 root;
120 FlutterSemanticsFlags flags = FlutterSemanticsFlags{.is_text_field = true, .is_read_only = true};
121 root.id = 0;
122 root.flags2 = &flags;
123 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
124 root.actions = static_cast<FlutterSemanticsAction>(0);
125 root.text_selection_base = -1;
126 root.text_selection_extent = -1;
127 root.label = "";
128 root.hint = "";
129 // Selectable text store its text in value
130 root.value = "selectable text";
131 root.increased_value = "";
132 root.decreased_value = "";
133 root.tooltip = "";
134 root.child_count = 0;
135 root.custom_accessibility_actions_count = 0;
136 root.identifier = "";
137 bridge->AddFlutterSemanticsNodeUpdate(root);
138
139 bridge->CommitUpdates();
140
141 auto root_platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
142 // Verify the accessibility attribute matches.
143 NSAccessibilityElement* native_accessibility =
144 root_platform_node_delegate->GetNativeViewAccessible();
145 NSRange selection = native_accessibility.accessibilitySelectedTextRange;
146 EXPECT_TRUE(selection.location == NSNotFound);
147 EXPECT_EQ(selection.length, 0u);
148 }

References FlutterViewController::engine.

## ◆ TEST() [60/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateMac | ,
|  | TextFieldUsesFlutterTextField |
| ) |  |

Definition at line 230 of file FlutterPlatformNodeDelegateMacTest.mm.

230 {
231 FlutterViewController* viewController = CreateTestViewController();
232 FlutterEngine* engine = viewController.engine;
233 [viewController loadView];
234
235 // Unit test localization is unnecessary.
236 // NOLINTNEXTLINE(clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker)
237 engine.textInputPlugin.string = @"textfield";
238 // Creates a NSWindow so that the native text field can become first responder.
239 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
240 styleMask:NSBorderlessWindowMask
241 backing:NSBackingStoreBuffered
242 defer:NO];
243 window.contentView = viewController.view;
244 engine.semanticsEnabled = YES;
245
246 auto bridge = viewController.accessibilityBridge.lock();
247 // Initialize ax node data.
248 FlutterSemanticsNode2 root;
249 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
250 FlutterSemanticsFlags child_flags = FlutterSemanticsFlags{.is_text_field = true};
251 root.id = 0;
252 root.flags2 = &flags;
253 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
254 root.actions = static_cast<FlutterSemanticsAction>(0);
255 root.label = "root";
256 root.hint = "";
257 root.value = "";
258 root.increased_value = "";
259 root.decreased_value = "";
260 root.tooltip = "";
261 root.child_count = 1;
262 int32_t children[] = {1};
263 root.children_in_traversal_order = children;
264 root.custom_accessibility_actions_count = 0;
265 root.identifier = "";
266 root.rect = {0, 0, 100, 100}; // LTRB
267 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
268 bridge->AddFlutterSemanticsNodeUpdate(root);
269
270 double rectSize = 50;
271 double transformFactor = 0.5;
272
273 FlutterSemanticsNode2 child1;
274 child1.id = 1;
275 child1.flags2 = &child_flags;
276 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
277 child1.actions = static_cast<FlutterSemanticsAction>(0);
278 child1.label = "";
279 child1.hint = "";
280 child1.value = "textfield";
281 child1.increased_value = "";
282 child1.decreased_value = "";
283 child1.tooltip = "";
284 child1.text_selection_base = -1;
285 child1.text_selection_extent = -1;
286 child1.child_count = 0;
287 child1.custom_accessibility_actions_count = 0;
288 child1.identifier = "";
289 child1.rect = {0, 0, rectSize, rectSize}; // LTRB
290 child1.transform = {transformFactor, 0, 0, 0, transformFactor, 0, 0, 0, 1};
291 bridge->AddFlutterSemanticsNodeUpdate(child1);
292
293 bridge->CommitUpdates();
294
295 auto child_platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
296 // Verify the accessibility attribute matches.
297 id native_accessibility = child_platform_node_delegate->GetNativeViewAccessible();
298 EXPECT_EQ([native_accessibility isKindOfClass:[FlutterTextField class]], YES);
299 FlutterTextField* native_text_field = (FlutterTextField*)native_accessibility;
300
301 NSView* view = viewController.flutterView;
302 CGRect scaledBounds = [view convertRectToBacking:view.bounds];
303 CGSize scaledSize = scaledBounds.size;
304 double pixelRatio = view.bounds.size.width == 0 ? 1 : scaledSize.width / view.bounds.size.width;
305
306 double expectedFrameSize = rectSize * transformFactor / pixelRatio;
307 EXPECT_EQ(NSEqualRects(native_text_field.frame, NSMakeRect(0, 600 - expectedFrameSize,
308 expectedFrameSize, expectedFrameSize)),
309 YES);
310
311 [native_text_field startEditing];
312 EXPECT_EQ([native_text_field.stringValue isEqualToString:@"textfield"], YES);
313 }

References FlutterViewController::engine.

## ◆ TEST() [61/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateTest | ,
|  | canCalculateBoundsCorrectly |
| ) |  |

Definition at line 121 of file flutter_platform_node_delegate_unittests.cc.

121 {
122 std::shared_ptr<TestAccessibilityBridge> bridge =
123 std::make_shared<TestAccessibilityBridge>();
124 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
125 FlutterSemanticsNode2 root;
126 root.id = 0;
127 root.label = "root";
128 root.hint = "";
129 root.value = "";
130 root.increased_value = "";
131 root.decreased_value = "";
132 root.tooltip = "";
133 root.child_count = 1;
134 root.flags2 = &flags;
135 int32_t children[] = {1};
136 root.children_in_traversal_order = children;
137 root.custom_accessibility_actions_count = 0;
138 root.identifier = "";
139 root.rect = {0, 0, 100, 100}; // LTRB
140 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
141 bridge->AddFlutterSemanticsNodeUpdate(root);
142
143 FlutterSemanticsNode2 child1;
144 child1.id = 1;
145 child1.label = "child 1";
146 child1.hint = "";
147 child1.value = "";
148 child1.increased_value = "";
149 child1.decreased_value = "";
150 child1.tooltip = "";
151 child1.child_count = 0;
152 child1.flags2 = &flags;
153 child1.custom_accessibility_actions_count = 0;
154 child1.identifier = "";
155 child1.rect = {0, 0, 50, 50}; // LTRB
156 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
157 bridge->AddFlutterSemanticsNodeUpdate(child1);
158
159 bridge->CommitUpdates();
160 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
161 ui::AXOffscreenResult result;
162 gfx::Rect bounds =
163 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
164 ui::AXClippingBehavior::kClipped, &result);
165 EXPECT_EQ(bounds.x(), 0);
166 EXPECT_EQ(bounds.y(), 0);
167 EXPECT_EQ(bounds.width(), 25);
168 EXPECT_EQ(bounds.height(), 25);
169 EXPECT_EQ(result, ui::AXOffscreenResult::kOnscreen);
170 }

## ◆ TEST() [62/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateTest | ,
|  | canCalculateOffScreenBoundsCorrectly |
| ) |  |

Definition at line 172 of file flutter_platform_node_delegate_unittests.cc.

172 {
173 std::shared_ptr<TestAccessibilityBridge> bridge =
174 std::make_shared<TestAccessibilityBridge>();
175 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
176 FlutterSemanticsNode2 root;
177 root.id = 0;
178 root.label = "root";
179 root.hint = "";
180 root.value = "";
181 root.increased_value = "";
182 root.decreased_value = "";
183 root.tooltip = "";
184 root.child_count = 1;
185 root.flags2 = &flags;
186 int32_t children[] = {1};
187 root.children_in_traversal_order = children;
188 root.custom_accessibility_actions_count = 0;
189 root.identifier = "";
190 root.rect = {0, 0, 100, 100}; // LTRB
191 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
192 bridge->AddFlutterSemanticsNodeUpdate(root);
193
194 FlutterSemanticsNode2 child1;
195 child1.id = 1;
196 child1.label = "child 1";
197 child1.hint = "";
198 child1.value = "";
199 child1.increased_value = "";
200 child1.decreased_value = "";
201 child1.tooltip = "";
202 child1.child_count = 0;
203 child1.flags2 = &flags;
204 child1.custom_accessibility_actions_count = 0;
205 child1.identifier = "";
206 child1.rect = {90, 90, 100, 100}; // LTRB
207 child1.transform = {2, 0, 0, 0, 2, 0, 0, 0, 1};
208 bridge->AddFlutterSemanticsNodeUpdate(child1);
209
210 bridge->CommitUpdates();
211 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
212 ui::AXOffscreenResult result;
213 gfx::Rect bounds =
214 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
215 ui::AXClippingBehavior::kUnclipped, &result);
216 EXPECT_EQ(bounds.x(), 180);
217 EXPECT_EQ(bounds.y(), 180);
218 EXPECT_EQ(bounds.width(), 20);
219 EXPECT_EQ(bounds.height(), 20);
220 EXPECT_EQ(result, ui::AXOffscreenResult::kOffscreen);
221 }

## ◆ TEST() [63/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateTest | ,
|  | canGetAXNode |
| ) |  |

Definition at line 91 of file flutter_platform_node_delegate_unittests.cc.

91 {
92 // Set up a flutter accessibility node.
93 std::shared_ptr<TestAccessibilityBridge> bridge =
94 std::make_shared<TestAccessibilityBridge>();
95 FlutterSemanticsNode2 root;
96 root.id = 0;
97 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
98 flags.is_text_field = true;
99 root.flags2 = &flags;
100 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
101 root.actions = static_cast<FlutterSemanticsAction>(0);
102 root.text_selection_base = -1;
103 root.text_selection_extent = -1;
104 root.label = "root";
105 root.hint = "";
106 root.value = "";
107 root.increased_value = "";
108 root.decreased_value = "";
109 root.tooltip = "";
110 root.child_count = 0;
111 root.custom_accessibility_actions_count = 0;
112 root.identifier = "";
113 bridge->AddFlutterSemanticsNodeUpdate(root);
114
115 bridge->CommitUpdates();
116
117 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
118 EXPECT_EQ(accessibility->GetData().id, 0);
119 }

## ◆ TEST() [64/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateTest | ,
|  | canGetFromNodeID |
| ) |  |

Definition at line 300 of file flutter_platform_node_delegate_unittests.cc.

300 {
301 std::shared_ptr<TestAccessibilityBridge> bridge =
302 std::make_shared<TestAccessibilityBridge>();
303 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
304 FlutterSemanticsNode2 root;
305 root.id = 0;
306 root.label = "root";
307 root.hint = "";
308 root.value = "";
309 root.increased_value = "";
310 root.decreased_value = "";
311 root.tooltip = "";
312 root.child_count = 1;
313 root.flags2 = &flags;
314 int32_t children[] = {1};
315 root.children_in_traversal_order = children;
316 root.custom_accessibility_actions_count = 0;
317 root.identifier = "";
318 bridge->AddFlutterSemanticsNodeUpdate(root);
319
320 FlutterSemanticsNode2 child1;
321 child1.id = 1;
322 child1.label = "child 1";
323 child1.hint = "";
324 child1.value = "";
325 child1.increased_value = "";
326 child1.decreased_value = "";
327 child1.tooltip = "";
328 child1.child_count = 0;
329 child1.flags2 = &flags;
330 child1.custom_accessibility_actions_count = 0;
331 child1.identifier = "";
332 bridge->AddFlutterSemanticsNodeUpdate(child1);
333
334 bridge->CommitUpdates();
335 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
336 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
337 auto node_by_id = root_node->GetFromNodeID(1);
338 EXPECT_EQ(child1_node->GetPlatformNode(), node_by_id);
339 }

## ◆ TEST() [65/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateTest | ,
|  | canPerfomActions |
| ) |  |

Definition at line 43 of file flutter_platform_node_delegate_unittests.cc.

43 {
44 std::shared_ptr<TestAccessibilityBridge> bridge =
45 std::make_shared<TestAccessibilityBridge>();
46 FlutterSemanticsNode2 root;
47 root.id = 0;
48 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
49 flags.is_text_field = true;
50 root.flags2 = &flags;
51 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
52 root.actions = static_cast<FlutterSemanticsAction>(0);
53 root.text_selection_base = -1;
54 root.text_selection_extent = -1;
55 root.label = "root";
56 root.hint = "";
57 root.value = "";
58 root.increased_value = "";
59 root.decreased_value = "";
60 root.tooltip = "";
61 root.child_count = 0;
62 root.custom_accessibility_actions_count = 0;
63 root.identifier = "";
64 bridge->AddFlutterSemanticsNodeUpdate(root);
65
66 bridge->CommitUpdates();
67
68 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
69 // Performs an AXAction.
70 ui::AXActionData action_data;
71 action_data.action = ax::mojom::Action::kDoDefault;
72 accessibility->AccessibilityPerformAction(action_data);
73 EXPECT_EQ(bridge->performed_actions.size(), size_t{1});
74 EXPECT_EQ(bridge->performed_actions[0],
75 FlutterSemanticsAction::kFlutterSemanticsActionTap);
76
77 action_data.action = ax::mojom::Action::kFocus;
78 accessibility->AccessibilityPerformAction(action_data);
79 EXPECT_EQ(bridge->performed_actions.size(), size_t{2});
80 EXPECT_EQ(
81 bridge->performed_actions[1],
82 FlutterSemanticsAction::kFlutterSemanticsActionDidGainAccessibilityFocus);
83
84 action_data.action = ax::mojom::Action::kScrollToMakeVisible;
85 accessibility->AccessibilityPerformAction(action_data);
86 EXPECT_EQ(bridge->performed_actions.size(), size_t{3});
87 EXPECT_EQ(bridge->performed_actions[2],
88 FlutterSemanticsAction::kFlutterSemanticsActionShowOnScreen);
89 }

## ◆ TEST() [66/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateTest | ,
|  | canUseOwnerBridge |
| ) |  |

Definition at line 223 of file flutter_platform_node_delegate_unittests.cc.

223 {
224 std::shared_ptr<TestAccessibilityBridge> bridge =
225 std::make_shared<TestAccessibilityBridge>();
226 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
227 FlutterSemanticsNode2 root{sizeof(FlutterSemanticsNode2), 0};
228 root.label = "root";
229 root.hint = "";
230 root.value = "";
231 root.increased_value = "";
232 root.decreased_value = "";
233 root.tooltip = "";
234 root.heading_level = 0;
235 root.child_count = 1;
236 root.flags2 = &flags;
237 int32_t children[] = {1};
238 root.children_in_traversal_order = children;
239 root.custom_accessibility_actions_count = 0;
240 root.identifier = "";
241 root.rect = {0, 0, 100, 100}; // LTRB
242 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
243 bridge->AddFlutterSemanticsNodeUpdate(root);
244
245 FlutterSemanticsNode2 child1{sizeof(FlutterSemanticsNode2), 1};
246 child1.label = "child 1";
247 child1.hint = "";
248 child1.value = "";
249 child1.increased_value = "";
250 child1.decreased_value = "";
251 child1.tooltip = "";
252 child1.heading_level = 0;
253 child1.child_count = 0;
254 child1.flags2 = &flags;
255 child1.custom_accessibility_actions_count = 0;
256 child1.identifier = "";
257 child1.rect = {0, 0, 50, 50}; // LTRB
258 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
259 bridge->AddFlutterSemanticsNodeUpdate(child1);
260
261 bridge->CommitUpdates();
262 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
263 auto owner_bridge = child1_node->GetOwnerBridge().lock();
264
265 bool result = false;
266 gfx::RectF bounds = owner_bridge->RelativeToGlobalBounds(
267 child1_node->GetAXNode(), result, true);
268 EXPECT_EQ(bounds.x(), 0);
269 EXPECT_EQ(bounds.y(), 0);
270 EXPECT_EQ(bounds.width(), 25);
271 EXPECT_EQ(bounds.height(), 25);
272 EXPECT_EQ(result, false);
273 }

## ◆ TEST() [67/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateTest | ,
|  | NodeDelegateHasUniqueId |
| ) |  |

Definition at line 15 of file flutter_platform_node_delegate_unittests.cc.

15 {
16 std::shared_ptr<TestAccessibilityBridge> bridge =
17 std::make_shared<TestAccessibilityBridge>();
18
19 // Add node 0: root.
20 FlutterSemanticsNode2 node0{sizeof(FlutterSemanticsNode2), 0};
21 std::vector<int32_t> node0_children{1};
22 FlutterSemanticsFlags emptyFlags = FlutterSemanticsFlags{};
23 node0.child_count = node0_children.size();
24 node0.children_in_traversal_order = node0_children.data();
25 node0.children_in_hit_test_order = node0_children.data();
26 node0.flags2 = &emptyFlags;
27
28 // Add node 1: text child of node 0.
29 FlutterSemanticsNode2 node1{sizeof(FlutterSemanticsNode2), 1};
30 node1.label = "prefecture";
31 node1.value = "Kyoto";
32 node1.flags2 = &emptyFlags;
33
34 bridge->AddFlutterSemanticsNodeUpdate(node0);
35 bridge->AddFlutterSemanticsNodeUpdate(node1);
36 bridge->CommitUpdates();
37
38 auto node0_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
39 auto node1_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
40 EXPECT_TRUE(node0_delegate->GetUniqueId() != node1_delegate->GetUniqueId());
41 }

## ◆ TEST() [68/122]

flutter::testing::TEST | ( | FlutterPlatformNodeDelegateTest | ,
|  | selfIsLowestPlatformAncestor |
| ) |  |

Definition at line 275 of file flutter_platform_node_delegate_unittests.cc.

275 {
276 std::shared_ptr<TestAccessibilityBridge> bridge =
277 std::make_shared<TestAccessibilityBridge>();
278 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
279 FlutterSemanticsNode2 root;
280 root.id = 0;
281 root.label = "root";
282 root.hint = "";
283 root.value = "";
284 root.increased_value = "";
285 root.decreased_value = "";
286 root.tooltip = "";
287 root.child_count = 0;
288 root.flags2 = &flags;
289 root.children_in_traversal_order = nullptr;
290 root.custom_accessibility_actions_count = 0;
291 root.identifier = "";
292 bridge->AddFlutterSemanticsNodeUpdate(root);
293
294 bridge->CommitUpdates();
295 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
296 auto lowest_platform_ancestor = root_node->GetLowestPlatformAncestor();
297 EXPECT_EQ(root_node->GetNativeViewAccessible(), lowest_platform_ancestor);
298 }

## ◆ TEST() [69/122]

flutter::testing::TEST | ( | FlutterPlatformViewController | ,
|  | TestAcceptGesture |
| ) |  |

Definition at line 218 of file FlutterPlatformViewControllerTest.mm.

218 {
219 FlutterPlatformViewController* platformViewController =
220 [[FlutterPlatformViewController alloc] init];
221 [platformViewController registerViewFactory:[TestFlutterPlatformViewFactory alloc]
222 withId:@"MockPlatformView"];
223
224 // Create the PlatformView.
225 const NSNumber* viewId = [NSNumber numberWithLongLong:2];
226 FlutterMethodCall* methodCallOnCreate = [FlutterMethodCall
227 methodCallWithMethodName:@"create"
228 arguments:@{@"id" : viewId, @"viewType" : @"MockPlatformView"}];
229 __block bool created = false;
230 FlutterResult resultOnCreate = ^(id result) {
231 // If a platform view is successfully created, the result is nil.
232 if (result == nil) {
233 created = true;
234 }
235 };
236 [platformViewController handleMethodCall:methodCallOnCreate result:resultOnCreate];
237
238 // Call acceptGesture.
239 FlutterMethodCall* methodCallAcceptGesture =
240 [FlutterMethodCall methodCallWithMethodName:@"acceptGesture" arguments:@{@"id" : viewId}];
241 __block bool acceptGestureCalled = false;
242 FlutterResult resultAcceptGesture = ^(id result) {
243 // If a acceptGesture is successful, the result is nil.
244 if (result == nil) {
245 acceptGestureCalled = true;
246 }
247 };
248 [platformViewController handleMethodCall:methodCallAcceptGesture result:resultAcceptGesture];
249
250 EXPECT_TRUE(created);
251 EXPECT_TRUE(acceptGestureCalled);
252 }
FlutterResult
void(^ FlutterResult)(id _Nullable result)
Definition: FlutterChannels.h:194
FlutterMethodCall
Definition: FlutterCodecs.h:221
FlutterPlatformViewController
Definition: FlutterPlatformViewController.h:18
TestFlutterPlatformViewFactory
Definition: TestFlutterPlatformView.h:19

## ◆ TEST() [70/122]

flutter::testing::TEST | ( | FlutterPlatformViewController | ,
|  | TestAcceptGestureOnMissingViewId |
| ) |  |

Definition at line 254 of file FlutterPlatformViewControllerTest.mm.

254 {
255 FlutterPlatformViewController* platformViewController =
256 [[FlutterPlatformViewController alloc] init];
257 [platformViewController registerViewFactory:[TestFlutterPlatformViewFactory alloc]
258 withId:@"MockPlatformView"];
259
260 // Call rejectGesture.
261 FlutterMethodCall* methodCallAcceptGesture =
262 [FlutterMethodCall methodCallWithMethodName:@"acceptGesture" arguments:@{
263 @"id" : @20
264 }];
265 __block bool errored = false;
266 FlutterResult result = ^(id result) {
267 if ([result isKindOfClass:[FlutterError class]]) {
268 errored = true;
269 }
270 };
271 [platformViewController handleMethodCall:methodCallAcceptGesture result:result];
272
273 EXPECT_TRUE(errored);
274 }
FlutterError
Definition: FlutterCodecs.h:247

## ◆ TEST() [71/122]

flutter::testing::TEST | ( | FlutterPlatformViewController | ,
|  | TestCreateAndDispose |
| ) |  |

Definition at line 101 of file FlutterPlatformViewControllerTest.mm.

101 {
102 // Use id so we can access handleMethodCall method.
103 id platformViewController = [[FlutterPlatformViewController alloc] init];
104
105 TestFlutterPlatformViewFactory* factory = [TestFlutterPlatformViewFactory alloc];
106
107 [platformViewController registerViewFactory:factory withId:@"MockPlatformView"];
108
109 FlutterMethodCall* methodCallOnCreate =
110 [FlutterMethodCall methodCallWithMethodName:@"create"
111 arguments:@{
112 @"id" : @2,
113 @"viewType" : @"MockPlatformView"
114 }];
115
116 __block bool created = false;
117 FlutterResult resultOnCreate = ^(id result) {
118 // If a platform view is successfully created, the result is nil.
119 if (result == nil) {
120 created = true;
121 }
122 };
123
124 [platformViewController handleMethodCall:methodCallOnCreate result:resultOnCreate];
125
126 FlutterMethodCall* methodCallOnDispose =
127 [FlutterMethodCall methodCallWithMethodName:@"dispose"
128 arguments:[NSNumber numberWithLongLong:2]];
129
130 __block bool disposed = false;
131 FlutterResult resultOnDispose = ^(id result) {
132 // If a platform view is successfully created, the result is nil.
133 if (result == nil) {
134 disposed = true;
135 }
136 };
137
138 [platformViewController handleMethodCall:methodCallOnDispose result:resultOnDispose];
139
140 EXPECT_TRUE(created);
141 EXPECT_TRUE(disposed);
142 }

## ◆ TEST() [72/122]

flutter::testing::TEST | ( | FlutterPlatformViewController | ,
|  | TestCreatePlatformViewNoMatchingViewType |
| ) |  |

Definition at line 14 of file FlutterPlatformViewControllerTest.mm.

14 {
15 // Use id so we can access handleMethodCall method.
16 id platformViewController = [[FlutterPlatformViewController alloc] init];
17
18 FlutterMethodCall* methodCall =
19 [FlutterMethodCall methodCallWithMethodName:@"create"
20 arguments:@{
21 @"id" : @2,
22 @"viewType" : @"FlutterPlatformViewMock"
23 }];
24
25 __block bool errored = false;
26 FlutterResult result = ^(id result) {
27 if ([result isKindOfClass:[FlutterError class]]) {
28 errored = true;
29 }
30 };
31
32 [platformViewController handleMethodCall:methodCall result:result];
33
34 // We expect the call to error since no factories are registered.
35 EXPECT_TRUE(errored);
36 }

## ◆ TEST() [73/122]

flutter::testing::TEST | ( | FlutterPlatformViewController | ,
|  | TestDisposeOnMissingViewId |
| ) |  |

Definition at line 198 of file FlutterPlatformViewControllerTest.mm.

198 {
199 // Use id so we can access handleMethodCall method.
200 id platformViewController = [[FlutterPlatformViewController alloc] init];
201
202 FlutterMethodCall* methodCall =
203 [FlutterMethodCall methodCallWithMethodName:@"dispose"
204 arguments:[NSNumber numberWithLongLong:20]];
205
206 __block bool errored = false;
207 FlutterResult result = ^(id result) {
208 if ([result isKindOfClass:[FlutterError class]]) {
209 errored = true;
210 }
211 };
212
213 [platformViewController handleMethodCall:methodCall result:result];
214
215 EXPECT_TRUE(errored);
216 }

## ◆ TEST() [74/122]

flutter::testing::TEST | ( | FlutterPlatformViewController | ,
|  | TestRegisterPlatformViewFactoryAndCreate |
| ) |  |

Definition at line 38 of file FlutterPlatformViewControllerTest.mm.

38 {
39 // Use id so we can access handleMethodCall method.
40 id platformViewController = [[FlutterPlatformViewController alloc] init];
41
42 TestFlutterPlatformViewFactory* factory = [TestFlutterPlatformViewFactory alloc];
43
44 [platformViewController registerViewFactory:factory withId:@"MockPlatformView"];
45
46 NSDictionary* creationArgs = @{
47 @"album" : @"ã‚¹ã‚³ãƒƒãƒˆã�¨ãƒªãƒ�ãƒ¼ã‚¹",
48 @"releaseYear" : @2013,
49 @"artists" : @[ @"Scott Murphy", @"Rivers Cuomo" ],
50 @"playlist" : @[ @"ã�Šã�‹ã�—ã�„ã‚„ã�¤", @"ã�»ã�©ã�‘ã�¦ã�„ã�Ÿã‚“ã� " ],
51 };
52 NSObject<FlutterMessageCodec>* codec = [factory createArgsCodec];
53 FlutterStandardTypedData* creationArgsData =
54 [FlutterStandardTypedData typedDataWithBytes:[codec encode:creationArgs]];
55
56 FlutterMethodCall* methodCall =
57 [FlutterMethodCall methodCallWithMethodName:@"create"
58 arguments:@{
59 @"id" : @2,
60 @"viewType" : @"MockPlatformView",
61 @"params" : creationArgsData,
62 }];
63
64 __block bool success = false;
65 FlutterResult result = ^(id result) {
66 // If a platform view is successfully created, the result is nil.
67 if (result == nil) {
68 success = true;
69 }
70 };
71 [platformViewController handleMethodCall:methodCall result:result];
72 EXPECT_TRUE(success);
73
74 // Verify PlatformView parameters are decoded correctly.
75 TestFlutterPlatformView* view =
76 (TestFlutterPlatformView*)[platformViewController platformViewWithID:2];
77 ASSERT_TRUE(view != nil);
78 ASSERT_TRUE(view.args != nil);
79
80 // Verify string type.
81 NSString* album = [view.args objectForKey:@"album"];
82 EXPECT_TRUE([album isEqualToString:@"ã‚¹ã‚³ãƒƒãƒˆã�¨ãƒªãƒ�ãƒ¼ã‚¹"]);
83
84 // Verify int type.
85 NSNumber* releaseYear = [view.args objectForKey:@"releaseYear"];
86 EXPECT_EQ(releaseYear.intValue, 2013);
87
88 // Verify list/array types.
89 NSArray* artists = [view.args objectForKey:@"artists"];
90 ASSERT_TRUE(artists != nil);
91 ASSERT_EQ(artists.count, 2ul);
92 EXPECT_TRUE([artists[0] isEqualToString:@"Scott Murphy"]);
93 EXPECT_TRUE([artists[1] isEqualToString:@"Rivers Cuomo"]);
94
95 NSArray* playlist = [view.args objectForKey:@"playlist"];
96 ASSERT_EQ(playlist.count, 2ul);
97 EXPECT_TRUE([playlist[0] isEqualToString:@"ã�Šã�‹ã�—ã�„ã‚„ã�¤"]);
98 EXPECT_TRUE([playlist[1] isEqualToString:@"ã�»ã�©ã�‘ã�¦ã�„ã�Ÿã‚“ã� "]);
99 }
FlutterStandardTypedData
Definition: FlutterCodecs.h:301
TestFlutterPlatformView
Definition: TestFlutterPlatformView.h:13
TestFlutterPlatformView::args
id args
Arguments passed via the params value in the create method call.
Definition: TestFlutterPlatformView.h:15

References TestFlutterPlatformView::args.

## ◆ TEST() [75/122]

flutter::testing::TEST | ( | FlutterPlatformViewController | ,
|  | TestRejectGesture |
| ) |  |

Definition at line 276 of file FlutterPlatformViewControllerTest.mm.

276 {
277 FlutterPlatformViewController* platformViewController =
278 [[FlutterPlatformViewController alloc] init];
279 [platformViewController registerViewFactory:[TestFlutterPlatformViewFactory alloc]
280 withId:@"MockPlatformView"];
281
282 // Create the PlatformView.
283 const NSNumber* viewId = [NSNumber numberWithLongLong:2];
284 FlutterMethodCall* methodCallOnCreate = [FlutterMethodCall
285 methodCallWithMethodName:@"create"
286 arguments:@{@"id" : viewId, @"viewType" : @"MockPlatformView"}];
287 __block bool created = false;
288 FlutterResult resultOnCreate = ^(id result) {
289 // If a platform view is successfully created, the result is nil.
290 if (result == nil) {
291 created = true;
292 }
293 };
294 [platformViewController handleMethodCall:methodCallOnCreate result:resultOnCreate];
295
296 // Call rejectGesture.
297 FlutterMethodCall* methodCallRejectGesture =
298 [FlutterMethodCall methodCallWithMethodName:@"rejectGesture" arguments:@{@"id" : viewId}];
299 __block bool rejectGestureCalled = false;
300 FlutterResult resultRejectGesture = ^(id result) {
301 // If a rejectGesture is successful, the result is nil.
302 if (result == nil) {
303 rejectGestureCalled = true;
304 }
305 };
306 [platformViewController handleMethodCall:methodCallRejectGesture result:resultRejectGesture];
307
308 EXPECT_TRUE(created);
309 EXPECT_TRUE(rejectGestureCalled);
310 }

## ◆ TEST() [76/122]

flutter::testing::TEST | ( | FlutterPlatformViewController | ,
|  | TestRejectGestureOnMissingViewId |
| ) |  |

Definition at line 312 of file FlutterPlatformViewControllerTest.mm.

312 {
313 FlutterPlatformViewController* platformViewController =
314 [[FlutterPlatformViewController alloc] init];
315 [platformViewController registerViewFactory:[TestFlutterPlatformViewFactory alloc]
316 withId:@"MockPlatformView"];
317
318 // Call rejectGesture.
319 FlutterMethodCall* methodCallRejectGesture =
320 [FlutterMethodCall methodCallWithMethodName:@"rejectGesture" arguments:@{
321 @"id" : @20
322 }];
323 __block bool errored = false;
324 FlutterResult result = ^(id result) {
325 if ([result isKindOfClass:[FlutterError class]]) {
326 errored = true;
327 }
328 };
329 [platformViewController handleMethodCall:methodCallRejectGesture result:result];
330
331 EXPECT_TRUE(errored);
332 }

## ◆ TEST() [77/122]

flutter::testing::TEST | ( | FlutterPlatformViewController | ,
|  | TestReset |
| ) |  |

Definition at line 144 of file FlutterPlatformViewControllerTest.mm.

144 {
145 // Use id so we can access handleMethodCall method.
146 id platformViewController = [[FlutterPlatformViewController alloc] init];
147 TestFlutterPlatformViewFactory* factory = [TestFlutterPlatformViewFactory alloc];
148
149 [platformViewController registerViewFactory:factory withId:@"MockPlatformView"];
150
151 __block bool created = false;
152 FlutterResult resultOnCreate = ^(id result) {
153 // If a platform view is successfully created, the result is nil.
154 if (result == nil) {
155 created = true;
156 } else {
157 created = false;
158 }
159 };
160
161 // Create 2 views.
162 FlutterMethodCall* methodCallOnCreate0 =
163 [FlutterMethodCall methodCallWithMethodName:@"create"
164 arguments:@{
165 @"id" : @0,
166 @"viewType" : @"MockPlatformView"
167 }];
168
169 [platformViewController handleMethodCall:methodCallOnCreate0 result:resultOnCreate];
170 EXPECT_TRUE(created);
171
172 FlutterMethodCall* methodCallOnCreate1 =
173 [FlutterMethodCall methodCallWithMethodName:@"create"
174 arguments:@{
175 @"id" : @1,
176 @"viewType" : @"MockPlatformView"
177 }];
178 [platformViewController handleMethodCall:methodCallOnCreate1 result:resultOnCreate];
179 EXPECT_TRUE(created);
180
181 TestFlutterPlatformView* view = nil;
182
183 // Before the reset, the views exist.
184 view = (TestFlutterPlatformView*)[platformViewController platformViewWithID:0];
185 EXPECT_TRUE(view != nil);
186 view = (TestFlutterPlatformView*)[platformViewController platformViewWithID:1];
187 EXPECT_TRUE(view != nil);
188
189 // After a reset, the views should no longer exist.
190 [platformViewController reset];
191
192 view = (TestFlutterPlatformView*)[platformViewController platformViewWithID:0];
193 EXPECT_TRUE(view == nil);
194 view = (TestFlutterPlatformView*)[platformViewController platformViewWithID:1];
195 EXPECT_TRUE(view == nil);
196 }

## ◆ TEST() [78/122]

flutter::testing::TEST | ( | FlutterSurfaceManager | ,
|  | BackBufferCacheDoesNotLeak |
| ) |  |

Definition at line 98 of file FlutterSurfaceManagerTest.mm.

98 {
99 TestView* testView = [[TestView alloc] init];
100 FlutterSurfaceManager* surfaceManager = CreateSurfaceManager(testView);
101 EXPECT_EQ(surfaceManager.backBufferCache.count, 0ul);
102
103 auto surface1 = [surfaceManager surfaceForSize:CGSizeMake(100, 100)];
104 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface1) ] atTime:0 notify:nil];
105
106 EXPECT_EQ(surfaceManager.backBufferCache.count, 0ul);
107
108 auto surface2 = [surfaceManager surfaceForSize:CGSizeMake(110, 110)];
109 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface2) ] atTime:0 notify:nil];
110
111 EXPECT_EQ(surfaceManager.backBufferCache.count, 1ul);
112
113 auto surface3 = [surfaceManager surfaceForSize:CGSizeMake(120, 120)];
114 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface3) ] atTime:0 notify:nil];
115
116 // Cache should be cleaned during present and only contain the last visible
117 // surface(s).
118 EXPECT_EQ(surfaceManager.backBufferCache.count, 1ul);
119 auto surfaceFromCache = [surfaceManager surfaceForSize:CGSizeMake(110, 110)];
120 EXPECT_EQ(surfaceFromCache, surface2);
121
122 // Submit empty surfaces until the one in cache gets to age >= kSurfaceEvictionAge, in which case
123 // it should be removed.
124
125 for (int i = 0; i < 30 /* kSurfaceEvictionAge */; ++i) {
126 [surfaceManager presentSurfaces:@[] atTime:0 notify:nil];
127 EXPECT_EQ(surfaceManager.backBufferCache.count, 1ul);
128 }
129
130 [surfaceManager presentSurfaces:@[] atTime:0 notify:nil];
131 EXPECT_EQ(surfaceManager.backBufferCache.count, 0ul);
132 }
-[FlutterBackBufferCache count]
NSUInteger count()
Definition: FlutterSurfaceManager.mm:346
-[FlutterSurfaceManager surfaceForSize:]
nonnull FlutterSurface * surfaceForSize:(CGSize size)
Definition: FlutterSurfaceManager.mm:133
FlutterSurfaceManager::backBufferCache
FlutterBackBufferCache * backBufferCache
Definition: FlutterSurfaceManager.h:107
-[FlutterSurfaceManager presentSurfaces:atTime:notify:]
void presentSurfaces:atTime:notify:(nonnull NSArray< FlutterSurfacePresentInfo * > *surfaces,[atTime] CFTimeInterval presentationTime,[notify] nullable dispatch_block_t notify)
TestView
Definition: FlutterSurfaceManagerTest.mm:14
flutter::testing::CreateSurfaceManager
static FlutterSurfaceManager * CreateSurfaceManager(TestView *testView)
Definition: FlutterSurfaceManagerTest.mm:43

References FlutterSurfaceManager::backBufferCache, FlutterBackBufferCache::count, CreateSurfaceManager(), FlutterSurfaceManager::presentSurfaces:atTime:notify:, and FlutterSurfaceManager::surfaceForSize:.

## ◆ TEST() [79/122]

flutter::testing::TEST | ( | FlutterSurfaceManager | ,
|  | BackingStoreCacheSurfaceStuckInUse |
| ) |  |

Definition at line 173 of file FlutterSurfaceManagerTest.mm.

173 {
174 TestView* testView = [[TestView alloc] init];
175 FlutterSurfaceManager* surfaceManager = CreateSurfaceManager(testView);
176
177 auto surface1 = [surfaceManager surfaceForSize:CGSizeMake(100, 100)];
178
179 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface1) ] atTime:0 notify:nil];
180 // Pretend that compositor is holding on to the surface. The surface will be kept
181 // in cache until the age of kSurfaceEvictionAge is reached, and then evicted.
182 surface1.isInUseOverride = YES;
183
184 auto surface2 = [surfaceManager surfaceForSize:CGSizeMake(100, 100)];
185 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface2) ] atTime:0 notify:nil];
186 EXPECT_EQ(surfaceManager.backBufferCache.count, 1ul);
187
188 for (int i = 0; i < 30 /* kSurfaceEvictionAge */ - 1; ++i) {
189 auto surface3 = [surfaceManager surfaceForSize:CGSizeMake(100, 100)];
190 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface3) ] atTime:0 notify:nil];
191 EXPECT_EQ(surfaceManager.backBufferCache.count, 2ul);
192 }
193
194 auto surface4 = [surfaceManager surfaceForSize:CGSizeMake(100, 100)];
195 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface4) ] atTime:0 notify:nil];
196 // Surface in use should bet old enough at this point to be evicted.
197 EXPECT_EQ(surfaceManager.backBufferCache.count, 1ul);
198 }

References FlutterSurfaceManager::backBufferCache, FlutterBackBufferCache::count, CreateSurfaceManager(), FlutterSurfaceManager::presentSurfaces:atTime:notify:, and FlutterSurfaceManager::surfaceForSize:.

## ◆ TEST() [80/122]

flutter::testing::TEST | ( | FlutterSurfaceManager | ,
|  | LayerManagement |
| ) |  |

Definition at line 204 of file FlutterSurfaceManagerTest.mm.

204 {
205 TestView* testView = [[TestView alloc] init];
206 FlutterSurfaceManager* surfaceManager = CreateSurfaceManager(testView);
207
208 EXPECT_EQ(testView.layer.sublayers.count, 0ul);
209
210 auto surface1_1 = [surfaceManager surfaceForSize:CGSizeMake(50, 30)];
211 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface1_1, CGPointMake(20, 10)) ]
212 atTime:0
213 notify:nil];
214
215 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
216 EXPECT_TRUE(CGSizeEqualToSize(testView.presentedFrameSize, CGSizeMake(70, 40)));
217
218 auto surface2_1 = [surfaceManager surfaceForSize:CGSizeMake(50, 30)];
219 auto surface2_2 = [surfaceManager surfaceForSize:CGSizeMake(20, 20)];
220 [surfaceManager presentSurfaces:@[
221 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
222 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
223 {
224 FlutterRect{0, 0, 20, 20},
225 FlutterRect{40, 0, 60, 20},
226 })
227 ]
228 atTime:0
229 notify:nil];
230
231 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
232 EXPECT_EQ(testView.layer.sublayers[0].zPosition, 1.0);
233 EXPECT_EQ(testView.layer.sublayers[1].zPosition, 2.0);
234 CALayer* firstOverlaySublayer;
235 {
236 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
237 EXPECT_EQ(sublayers.count, 2ul);
238 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 0, 10, 10)));
239 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].frame, CGRectMake(20, 0, 10, 10)));
240 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].contentsRect, CGRectMake(0, 0, 1, 1)));
241 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].contentsRect, CGRectMake(2, 0, 1, 1)));
242 EXPECT_EQ(sublayers[0].contents, sublayers[1].contents);
243 firstOverlaySublayer = sublayers[0];
244 }
245 EXPECT_TRUE(CGSizeEqualToSize(testView.presentedFrameSize, CGSizeMake(70, 70)));
246
247 // Check second overlay sublayer is removed while first is reused and updated
248 [surfaceManager presentSurfaces:@[
249 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
250 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
251 {
252 FlutterRect{0, 10, 20, 20},
253 })
254 ]
255 atTime:0
256 notify:nil];
257 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
258 {
259 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
260 EXPECT_EQ(sublayers.count, 1ul);
261 EXPECT_EQ(sublayers[0], firstOverlaySublayer);
262 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 5, 10, 5)));
263 }
264
265 // Check that second overlay sublayer is added back while first is reused and updated
266 [surfaceManager presentSurfaces:@[
267 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
268 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
269 {
270 FlutterRect{0, 0, 20, 20},
271 FlutterRect{40, 0, 60, 20},
272 })
273 ]
274 atTime:0
275 notify:nil];
276
277 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
278 {
279 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
280 EXPECT_EQ(sublayers.count, 2ul);
281 EXPECT_EQ(sublayers[0], firstOverlaySublayer);
282 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 0, 10, 10)));
283 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].frame, CGRectMake(20, 0, 10, 10)));
284 EXPECT_EQ(sublayers[0].contents, sublayers[1].contents);
285 }
286
287 auto surface3_1 = [surfaceManager surfaceForSize:CGSizeMake(50, 30)];
288 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface3_1, CGPointMake(20, 10)) ]
289 atTime:0
290 notify:nil];
291
292 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
293 EXPECT_TRUE(CGSizeEqualToSize(testView.presentedFrameSize, CGSizeMake(70, 40)));
294
295 // Check removal of all surfaces.
296 [surfaceManager presentSurfaces:@[] atTime:0 notify:nil];
297 EXPECT_EQ(testView.layer.sublayers.count, 0ul);
298 EXPECT_TRUE(CGSizeEqualToSize(testView.presentedFrameSize, CGSizeMake(0, 0)));
299 }
TestView::presentedFrameSize
CGSize presentedFrameSize
Definition: FlutterSurfaceManagerTest.mm:16

References CreateSurfaceManager(), TestView::presentedFrameSize, FlutterSurfaceManager::presentSurfaces:atTime:notify:, and FlutterSurfaceManager::surfaceForSize:.

## ◆ TEST() [81/122]

flutter::testing::TEST | ( | FlutterSurfaceManager | ,
|  | MetalTextureSizeMatchesSurfaceSize |
| ) |  |

Definition at line 66 of file FlutterSurfaceManagerTest.mm.

66 {
67 TestView* testView = [[TestView alloc] init];
68 FlutterSurfaceManager* surfaceManager = CreateSurfaceManager(testView);
69
70 // Get back buffer, lookup should work for borrowed surfaces util present.
71 auto surface = [surfaceManager surfaceForSize:CGSizeMake(100, 50)];
72 auto texture = surface.asFlutterMetalTexture;
73 id<MTLTexture> metalTexture = (__bridge id)texture.texture;
74 EXPECT_EQ(metalTexture.width, 100ul);
75 EXPECT_EQ(metalTexture.height, 50ul);
76 texture.destruction_callback(texture.user_data);
77 }

References FlutterSurface::asFlutterMetalTexture, CreateSurfaceManager(), and FlutterSurfaceManager::surfaceForSize:.

## ◆ TEST() [82/122]

flutter::testing::TEST | ( | FlutterSurfaceManager | ,
|  | SurfacesAreRecycled |
| ) |  |

Definition at line 134 of file FlutterSurfaceManagerTest.mm.

134 {
135 TestView* testView = [[TestView alloc] init];
136 FlutterSurfaceManager* surfaceManager = CreateSurfaceManager(testView);
137
138 EXPECT_EQ(surfaceManager.frontSurfaces.count, 0ul);
139
140 // Get first surface and present it.
141
142 auto surface1 = [surfaceManager surfaceForSize:CGSizeMake(100, 100)];
143 EXPECT_TRUE(CGSizeEqualToSize(surface1.size, CGSizeMake(100, 100)));
144
145 EXPECT_EQ(surfaceManager.backBufferCache.count, 0ul);
146 EXPECT_EQ(surfaceManager.frontSurfaces.count, 0ul);
147
148 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface1) ] atTime:0 notify:nil];
149
150 EXPECT_EQ(surfaceManager.backBufferCache.count, 0ul);
151 EXPECT_EQ(surfaceManager.frontSurfaces.count, 1ul);
152 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
153
154 // Get second surface and present it.
155
156 auto surface2 = [surfaceManager surfaceForSize:CGSizeMake(100, 100)];
157 EXPECT_TRUE(CGSizeEqualToSize(surface2.size, CGSizeMake(100, 100)));
158
159 EXPECT_EQ(surfaceManager.backBufferCache.count, 0ul);
160
161 [surfaceManager presentSurfaces:@[ CreatePresentInfo(surface2) ] atTime:0 notify:nil];
162
163 // Check that current front surface returns to cache.
164 EXPECT_EQ(surfaceManager.backBufferCache.count, 1ul);
165 EXPECT_EQ(surfaceManager.frontSurfaces.count, 1ul);
166 EXPECT_EQ(testView.layer.sublayers.count, 1ull);
167
168 // Check that surface is properly reused.
169 auto surface3 = [surfaceManager surfaceForSize:CGSizeMake(100, 100)];
170 EXPECT_EQ(surface3, surface1);
171 }
FlutterSurfaceManager::frontSurfaces
NSArray< FlutterSurface * > * frontSurfaces
Definition: FlutterSurfaceManager.h:108

References FlutterSurfaceManager::backBufferCache, FlutterBackBufferCache::count, CreateSurfaceManager(), FlutterSurfaceManager::frontSurfaces, FlutterSurfaceManager::presentSurfaces:atTime:notify:, and FlutterSurfaceManager::surfaceForSize:.

## ◆ TEST() [83/122]

flutter::testing::TEST | ( | FlutterSurfaceManager | ,
|  | TestSurfaceLookupFromTexture |
| ) |  |

Definition at line 79 of file FlutterSurfaceManagerTest.mm.

79 {
80 TestView* testView = [[TestView alloc] init];
81 FlutterSurfaceManager* surfaceManager = CreateSurfaceManager(testView);
82
83 // Get back buffer, lookup should work for borrowed surfaces util present.
84 auto surface = [surfaceManager surfaceForSize:CGSizeMake(100, 50)];
85
86 // SurfaceManager should keep texture alive while borrowed.
87 auto texture = surface.asFlutterMetalTexture;
88 texture.destruction_callback(texture.user_data);
89
90 FlutterMetalTexture dummyTexture{.texture_id = 1, .texture = nullptr, .user_data = nullptr};
91 auto surface1 = [FlutterSurface fromFlutterMetalTexture:&dummyTexture];
92 EXPECT_EQ(surface1, nil);
93
94 auto surface2 = [FlutterSurface fromFlutterMetalTexture:&texture];
95 EXPECT_EQ(surface2, surface);
96 }
FlutterSurface
Definition: FlutterSurface.h:17
+[FlutterSurface fromFlutterMetalTexture:]
nullable FlutterSurface * fromFlutterMetalTexture:(nonnull const FlutterMetalTexture *texture)

References FlutterSurface::asFlutterMetalTexture, CreateSurfaceManager(), FlutterSurface::fromFlutterMetalTexture:, and FlutterSurfaceManager::surfaceForSize:.

## ◆ TEST() [84/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | CanNotBecomeResponderIfNoViewController |
| ) |  |

Definition at line 2314 of file FlutterTextInputPluginTest.mm.

2314 {
2315 FlutterEngine* engine = CreateTestEngine();
2316 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2317 nibName:nil
2318 bundle:nil];
2319 [viewController loadView];
2320 // Creates a NSWindow so that the native text field can become first responder.
2321 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
2322 styleMask:NSBorderlessWindowMask
2323 backing:NSBackingStoreBuffered
2324 defer:NO];
2325 window.contentView = viewController.view;
2326
2327 engine.semanticsEnabled = YES;
2328
2329 auto bridge = viewController.accessibilityBridge.lock();
2330 FlutterPlatformNodeDelegateMac delegate(bridge, viewController);
2331 ui::AXTree tree;
2332 ui::AXNode ax_node(&tree, nullptr, 0, 0);
2333 ui::AXNodeData node_data;
2334 node_data.SetValue("initial text");
2335 ax_node.SetData(node_data);
2336 delegate.Init(viewController.accessibilityBridge, &ax_node);
2337 FlutterTextPlatformNode text_platform_node(&delegate, viewController);
2338
2339 FlutterTextField* textField = text_platform_node.GetNativeViewAccessible();
2340 EXPECT_EQ([textField becomeFirstResponder], YES);
2341 // Removes view controller.
2342 [engine setViewController:nil];
2343 FlutterTextPlatformNode text_platform_node_no_controller(&delegate, nil);
2344 textField = text_platform_node_no_controller.GetNativeViewAccessible();
2345 EXPECT_EQ([textField becomeFirstResponder], NO);
2346 }

References flutter::FlutterTextPlatformNode::GetNativeViewAccessible(), and flutter::FlutterPlatformNodeDelegateMac::Init().

## ◆ TEST() [85/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | CanWorkWithFlutterTextField |
| ) |  |

Definition at line 2248 of file FlutterTextInputPluginTest.mm.

2248 {
2249 FlutterEngine* engine = CreateTestEngine();
2250 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2251 nibName:nil
2252 bundle:nil];
2253 [viewController loadView];
2254 // Create a NSWindow so that the native text field can become first responder.
2255 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
2256 styleMask:NSBorderlessWindowMask
2257 backing:NSBackingStoreBuffered
2258 defer:NO];
2259 window.contentView = viewController.view;
2260
2261 engine.semanticsEnabled = YES;
2262
2263 auto bridge = viewController.accessibilityBridge.lock();
2264 FlutterPlatformNodeDelegateMac delegate(bridge, viewController);
2265 ui::AXTree tree;
2266 ui::AXNode ax_node(&tree, nullptr, 0, 0);
2267 ui::AXNodeData node_data;
2268 node_data.SetValue("initial text");
2269 ax_node.SetData(node_data);
2270 delegate.Init(viewController.accessibilityBridge, &ax_node);
2271 {
2272 FlutterTextPlatformNode text_platform_node(&delegate, viewController);
2273
2274 FlutterTextFieldMock* mockTextField =
2275 [[FlutterTextFieldMock alloc] initWithPlatformNode:&text_platform_node
2276 fieldEditor:engine.textInputPlugin];
2277 [viewController.view addSubview:mockTextField];
2278 [mockTextField startEditing];
2279
2280 NSDictionary* setClientConfig = @{
2281 @"viewId" : @(flutter::kFlutterImplicitViewId),
2282 @"inputAction" : @"action",
2283 @"inputType" : @{@"name" : @"inputName"},
2284 };
2285 FlutterMethodCall* methodCall =
2286 [FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
2287 arguments:@[ @(1), setClientConfig ]];
2288 FlutterResult result = ^(id result) {
2289 };
2290 [engine.textInputPlugin handleMethodCall:methodCall result:result];
2291
2292 NSDictionary* arguments = @{
2293 @"text" : @"new text",
2294 @"selectionBase" : @(1),
2295 @"selectionExtent" : @(2),
2296 @"composingBase" : @(-1),
2297 @"composingExtent" : @(-1),
2298 };
2299 methodCall = [FlutterMethodCall methodCallWithMethodName:@"TextInput.setEditingState"
2300 arguments:arguments];
2301 [engine.textInputPlugin handleMethodCall:methodCall result:result];
2302 EXPECT_EQ([mockTextField.lastUpdatedString isEqualToString:@"new text"], YES);
2303 EXPECT_EQ(NSEqualRanges(mockTextField.lastUpdatedSelection, NSMakeRange(1, 1)), YES);
2304
2305 // This blocks the FlutterTextFieldMock, which is held onto by the main event
2306 // loop, from crashing.
2307 [mockTextField setPlatformNode:nil];
2308 }
2309
2310 // This verifies that clearing the platform node works.
2311 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
2312 }
+[FlutterMethodCall methodCallWithMethodName:arguments:]
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
-[FlutterTextField startEditing]
void startEditing()
Definition: FlutterTextInputSemanticsObject.mm:112
FlutterTextFieldMock
Definition: FlutterTextInputPluginTest.mm:25
FlutterTextFieldMock::lastUpdatedSelection
NSRange lastUpdatedSelection
Definition: FlutterTextInputPluginTest.mm:27
FlutterTextFieldMock::lastUpdatedString
NSString * lastUpdatedString
Definition: FlutterTextInputPluginTest.mm:26

References flutter::FlutterPlatformNodeDelegateMac::Init(), FlutterTextFieldMock::lastUpdatedSelection, FlutterTextFieldMock::lastUpdatedString, FlutterMethodCall::methodCallWithMethodName:arguments:, and FlutterTextField::startEditing.

## ◆ TEST() [86/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | FirstResponderIsCorrect |
| ) |  |

Definition at line 2390 of file FlutterTextInputPluginTest.mm.

2390 {
2391 FlutterEngine* engine = CreateTestEngine();
2392 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2393 nibName:nil
2394 bundle:nil];
2395 [viewController loadView];
2396
2397 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
2398 styleMask:NSBorderlessWindowMask
2399 backing:NSBackingStoreBuffered
2400 defer:NO];
2401 window.contentView = viewController.view;
2402
2403 ASSERT_TRUE(viewController.flutterView.acceptsFirstResponder);
2404
2405 [window makeFirstResponder:viewController.flutterView];
2406
2407 NSDictionary* setClientConfig = @{
2408 @"viewId" : @(flutter::kFlutterImplicitViewId),
2409 };
2410 [engine.textInputPlugin
2411 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
2412 arguments:@[ @(1), setClientConfig ]]
2413 result:^(id){
2414 }];
2415
2416 [engine.textInputPlugin
2417 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.show" arguments:@[]]
2418 result:^(id){
2419 }];
2420
2421 ASSERT_TRUE(window.firstResponder == engine.textInputPlugin);
2422
2423 ASSERT_FALSE(viewController.flutterView.acceptsFirstResponder);
2424
2425 [engine.textInputPlugin
2426 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.hide" arguments:@[]]
2427 result:^(id){
2428 }];
2429
2430 ASSERT_TRUE(viewController.flutterView.acceptsFirstResponder);
2431 ASSERT_TRUE(window.firstResponder == viewController.flutterView);
2432 }

References FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST() [87/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | HandleArrowKeyWhenImePopoverIsActive |
| ) |  |

Definition at line 2172 of file FlutterTextInputPluginTest.mm.

2172 {
2173 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] handleArrowKeyWhenImePopoverIsActive]);
2174 }
FlutterInputPluginTestObjc
Definition: FlutterTextInputPluginTest.mm:56

## ◆ TEST() [88/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | HasZeroSizeAndClipsToBounds |
| ) |  |

Definition at line 2434 of file FlutterTextInputPluginTest.mm.

2434 {
2435 id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
2436 id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
2437 OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
2438 [engineMock binaryMessenger])
2439 .andReturn(binaryMessengerMock);
2440
2441 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
2442 nibName:@""
2443 bundle:nil];
2444
2445 FlutterTextInputPluginTestDelegate* delegate =
2446 [[FlutterTextInputPluginTestDelegate alloc] initWithBinaryMessenger:binaryMessengerMock
2447 viewController:viewController];
2448
2449 FlutterTextInputPlugin* plugin = [[FlutterTextInputPlugin alloc] initWithDelegate:delegate];
2450
2451 ASSERT_TRUE(NSIsEmptyRect(plugin.frame));
2452 ASSERT_TRUE(plugin.clipsToBounds);
2453 }
FlutterTextInputPlugin
Definition: FlutterTextInputPlugin.h:42
FlutterTextInputPluginTestDelegate
Definition: FlutterTextInputPluginTest.mm:60
flutter::testing::CreateMockFlutterEngine
id CreateMockFlutterEngine(NSString *pasteboardString)
Definition: FlutterEngineTestUtils.mm:76
FlutterBinaryMessenger-p
Definition: FlutterBinaryMessenger.h:49

References CreateMockFlutterEngine().

## ◆ TEST() [89/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | InsertTextHandlesEmptyAttributedString |
| ) |  |

Definition at line 2526 of file FlutterTextInputPluginTest.mm.

2526 {
2527 id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
2528 id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
2529 OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
2530 [engineMock binaryMessenger])
2531 .andReturn(binaryMessengerMock);
2532
2533 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
2534 nibName:@""
2535 bundle:nil];
2536
2537 FlutterTextInputPluginTestDelegate* delegate =
2538 [[FlutterTextInputPluginTestDelegate alloc] initWithBinaryMessenger:binaryMessengerMock
2539 viewController:viewController];
2540
2541 FlutterTextInputPlugin* plugin = [[FlutterTextInputPlugin alloc] initWithDelegate:delegate];
2542
2543 NSDictionary* setClientConfig = @{
2544 @"viewId" : @(kViewId),
2545 @"inputAction" : @"action",
2546 @"inputType" : @{@"name" : @"inputName"},
2547 };
2548 [plugin handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
2549 arguments:@[ @(1), setClientConfig ]]
2550 result:^(id){
2551 }];
2552
2553 // Test with empty NSAttributedString
2554 NSAttributedString* emptyAttributedString = [[NSAttributedString alloc] initWithString:@""];
2555 [plugin insertText:emptyAttributedString replacementRange:NSMakeRange(NSNotFound, 0)];
2556
2557 NSDictionary* editingState = [plugin editingState];
2558 EXPECT_STREQ([editingState[@"text"] UTF8String], "");
2559 EXPECT_EQ([editingState[@"selectionBase"] intValue], 0);
2560 EXPECT_EQ([editingState[@"selectionExtent"] intValue], 0);
2561 }
kViewId
static const FlutterViewIdentifier kViewId
Definition: FlutterTextInputPluginTest.mm:70
-[FlutterTextInputPlugin handleMethodCall:result:]
void handleMethodCall:result:(FlutterMethodCall *call,[result] FlutterResult result)
-[FlutterTextInputPlugin editingState]
NSDictionary * editingState()

References CreateMockFlutterEngine(), FlutterTextInputPlugin::editingState, FlutterTextInputPlugin::handleMethodCall:result:, kViewId, and FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST() [90/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | InsertTextHandlesNSAttributedString |
| ) |  |

Definition at line 2488 of file FlutterTextInputPluginTest.mm.

2488 {
2489 id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
2490 id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
2491 OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
2492 [engineMock binaryMessenger])
2493 .andReturn(binaryMessengerMock);
2494
2495 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
2496 nibName:@""
2497 bundle:nil];
2498
2499 FlutterTextInputPluginTestDelegate* delegate =
2500 [[FlutterTextInputPluginTestDelegate alloc] initWithBinaryMessenger:binaryMessengerMock
2501 viewController:viewController];
2502
2503 FlutterTextInputPlugin* plugin = [[FlutterTextInputPlugin alloc] initWithDelegate:delegate];
2504
2505 NSDictionary* setClientConfig = @{
2506 @"viewId" : @(kViewId),
2507 @"inputAction" : @"action",
2508 @"inputType" : @{@"name" : @"inputName"},
2509 };
2510 [plugin handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
2511 arguments:@[ @(1), setClientConfig ]]
2512 result:^(id){
2513 }];
2514
2515 // Test with NSAttributedString
2516 NSAttributedString* attributedString =
2517 [[NSAttributedString alloc] initWithString:@"attributed text"];
2518 [plugin insertText:attributedString replacementRange:NSMakeRange(NSNotFound, 0)];
2519
2520 NSDictionary* editingState = [plugin editingState];
2521 EXPECT_STREQ([editingState[@"text"] UTF8String], "attributed text");
2522 EXPECT_EQ([editingState[@"selectionBase"] intValue], 15);
2523 EXPECT_EQ([editingState[@"selectionExtent"] intValue], 15);
2524 }

References CreateMockFlutterEngine(), FlutterTextInputPlugin::editingState, FlutterTextInputPlugin::handleMethodCall:result:, kViewId, and FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST() [91/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | InsertTextWithCollapsedSelectionInsideComposing |
| ) |  |

Definition at line 2483 of file FlutterTextInputPluginTest.mm.

2483 {
2484 ASSERT_TRUE(
2485 [[FlutterInputPluginTestObjc alloc] testInsertTextWithCollapsedSelectionInsideComposing]);
2486 }

## ◆ TEST() [92/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | IsAddedAndRemovedFromViewHierarchy |
| ) |  |

Definition at line 2348 of file FlutterTextInputPluginTest.mm.

2348 {
2349 FlutterEngine* engine = CreateTestEngine();
2350 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2351 nibName:nil
2352 bundle:nil];
2353 [viewController loadView];
2354
2355 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
2356 styleMask:NSBorderlessWindowMask
2357 backing:NSBackingStoreBuffered
2358 defer:NO];
2359 window.contentView = viewController.view;
2360
2361 ASSERT_EQ(engine.textInputPlugin.superview, nil);
2362 ASSERT_FALSE(window.firstResponder == engine.textInputPlugin);
2363
2364 NSDictionary* setClientConfig = @{
2365 @"viewId" : @(flutter::kFlutterImplicitViewId),
2366 };
2367 [engine.textInputPlugin
2368 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
2369 arguments:@[ @(1), setClientConfig ]]
2370 result:^(id){
2371 }];
2372
2373 [engine.textInputPlugin
2374 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.show" arguments:@[]]
2375 result:^(id){
2376 }];
2377
2378 ASSERT_EQ(engine.textInputPlugin.superview, viewController.view);
2379 ASSERT_TRUE(window.firstResponder == engine.textInputPlugin);
2380
2381 [engine.textInputPlugin
2382 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.hide" arguments:@[]]
2383 result:^(id){
2384 }];
2385
2386 ASSERT_EQ(engine.textInputPlugin.superview, nil);
2387 ASSERT_FALSE(window.firstResponder == engine.textInputPlugin);
2388 }

References FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST() [93/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestAttributedSubstringOutOfRange |
| ) |  |

Definition at line 2196 of file FlutterTextInputPluginTest.mm.

2196 {
2197 id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
2198 id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
2199 OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
2200 [engineMock binaryMessenger])
2201 .andReturn(binaryMessengerMock);
2202
2203 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
2204 nibName:@""
2205 bundle:nil];
2206
2207 FlutterTextInputPluginTestDelegate* delegate =
2208 [[FlutterTextInputPluginTestDelegate alloc] initWithBinaryMessenger:binaryMessengerMock
2209 viewController:viewController];
2210
2211 FlutterTextInputPlugin* plugin = [[FlutterTextInputPlugin alloc] initWithDelegate:delegate];
2212
2213 NSDictionary* setClientConfig = @{
2214 @"viewId" : @(kViewId),
2215 @"inputAction" : @"action",
2216 @"enableDeltaModel" : @"true",
2217 @"inputType" : @{@"name" : @"inputName"},
2218 };
2219 [plugin handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
2220 arguments:@[ @(1), setClientConfig ]]
2221 result:^(id){
2222 }];
2223
2224 FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"TextInput.setEditingState"
2225 arguments:@{
2226 @"text" : @"Text",
2227 @"selectionBase" : @(0),
2228 @"selectionExtent" : @(0),
2229 @"composingBase" : @(-1),
2230 @"composingExtent" : @(-1),
2231 }];
2232
2233 [plugin handleMethodCall:call
2234 result:^(id){
2235 }];
2236
2237 NSRange out;
2238 NSAttributedString* text = [plugin attributedSubstringForProposedRange:NSMakeRange(1, 10)
2239 actualRange:&out];
2240 EXPECT_TRUE([text.string isEqualToString:@"ext"]);
2241 EXPECT_EQ(out.location, 1u);
2242 EXPECT_EQ(out.length, 3u);
2243
2244 text = [plugin attributedSubstringForProposedRange:NSMakeRange(4, 10) actualRange:&out];
2245 EXPECT_EQ(text, nil);
2246 }

References CreateMockFlutterEngine(), FlutterTextInputPlugin::handleMethodCall:result:, kViewId, and FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST() [94/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestAutocompleteDisabledWhenAutofillGroupIncludesPassword |
| ) |  |

Definition at line 2130 of file FlutterTextInputPluginTest.mm.

2130 {
2131 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc]
2132 testAutocompleteDisabledWhenAutofillGroupIncludesPassword]);
2133 }

## ◆ TEST() [95/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestAutocompleteDisabledWhenAutofillNotSet |
| ) |  |

Definition at line 2110 of file FlutterTextInputPluginTest.mm.

2110 {
2111 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testAutocompleteDisabledWhenAutofillNotSet]);
2112 }

## ◆ TEST() [96/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestAutocompleteDisabledWhenObscureTextSet |
| ) |  |

Definition at line 2122 of file FlutterTextInputPluginTest.mm.

2122 {
2123 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testAutocompleteDisabledWhenObscureTextSet]);
2124 }

## ◆ TEST() [97/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestAutocompleteDisabledWhenPasswordAutofillSet |
| ) |  |

Definition at line 2126 of file FlutterTextInputPluginTest.mm.

2126 {
2127 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testAutocompleteDisabledWhenPasswordAutofillSet]);
2128 }

## ◆ TEST() [98/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestAutocompleteEnabledWhenAutofillSet |
| ) |  |

Definition at line 2114 of file FlutterTextInputPluginTest.mm.

2114 {
2115 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testAutocompleteEnabledWhenAutofillSet]);
2116 }

## ◆ TEST() [99/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestAutocompleteEnabledWhenAutofillSetNoHint |
| ) |  |

Definition at line 2118 of file FlutterTextInputPluginTest.mm.

2118 {
2119 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testAutocompleteEnabledWhenAutofillSetNoHint]);
2120 }

## ◆ TEST() [100/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestClearClientDuringComposing |
| ) |  |

Definition at line 2106 of file FlutterTextInputPluginTest.mm.

2106 {
2107 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testClearClientDuringComposing]);
2108 }

## ◆ TEST() [101/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestComposingRegionRemovedByFramework |
| ) |  |

Definition at line 2102 of file FlutterTextInputPluginTest.mm.

2102 {
2103 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testComposingRegionRemovedByFramework]);
2104 }

## ◆ TEST() [102/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestComposingWithDelta |
| ) |  |

Definition at line 2156 of file FlutterTextInputPluginTest.mm.

2156 {
2157 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testComposingWithDelta]);
2158 }

## ◆ TEST() [103/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestComposingWithDeltasWhenSelectionIsActive |
| ) |  |

Definition at line 2160 of file FlutterTextInputPluginTest.mm.

2160 {
2161 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testComposingWithDeltasWhenSelectionIsActive]);
2162 }

## ◆ TEST() [104/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestEmptyCompositionRange |
| ) |  |

Definition at line 2090 of file FlutterTextInputPluginTest.mm.

2090 {
2091 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testEmptyCompositionRange]);
2092 }

## ◆ TEST() [105/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestFirstRectForCharacterRange |
| ) |  |

Definition at line 2135 of file FlutterTextInputPluginTest.mm.

2135 {
2136 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testFirstRectForCharacterRange]);
2137 }

## ◆ TEST() [106/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestFirstRectForCharacterRangeAtInfinity |
| ) |  |

Definition at line 2139 of file FlutterTextInputPluginTest.mm.

2139 {
2140 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testFirstRectForCharacterRangeAtInfinity]);
2141 }

## ◆ TEST() [107/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestFirstRectForCharacterRangeWithEsotericAffineTransform |
| ) |  |

Definition at line 2143 of file FlutterTextInputPluginTest.mm.

2143 {
2144 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc]
2145 testFirstRectForCharacterRangeWithEsotericAffineTransform]);
2146 }

## ◆ TEST() [108/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestInsertNewLine |
| ) |  |

Definition at line 2188 of file FlutterTextInputPluginTest.mm.

2188 {
2189 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testInsertNewLine]);
2190 }

## ◆ TEST() [109/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestLocalTextAndSelectionUpdateAfterDelta |
| ) |  |

Definition at line 2164 of file FlutterTextInputPluginTest.mm.

2164 {
2165 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testLocalTextAndSelectionUpdateAfterDelta]);
2166 }

## ◆ TEST() [110/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestOperationsThatTriggerDelta |
| ) |  |

Definition at line 2152 of file FlutterTextInputPluginTest.mm.

2152 {
2153 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testOperationsThatTriggerDelta]);
2154 }

## ◆ TEST() [111/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestPerformKeyEquivalent |
| ) |  |

Definition at line 2168 of file FlutterTextInputPluginTest.mm.

2168 {
2169 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testPerformKeyEquivalent]);
2170 }

## ◆ TEST() [112/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestSelectorsAreForwardedToFramework |
| ) |  |

Definition at line 2180 of file FlutterTextInputPluginTest.mm.

2180 {
2181 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSelectorsAreForwardedToFramework]);
2182 }

## ◆ TEST() [113/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestSelectorsNotForwardedToFrameworkIfNoClient |
| ) |  |

Definition at line 2184 of file FlutterTextInputPluginTest.mm.

2184 {
2185 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSelectorsNotForwardedToFrameworkIfNoClient]);
2186 }

## ◆ TEST() [114/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestSendActionDoNotInsertNewLine |
| ) |  |

Definition at line 2192 of file FlutterTextInputPluginTest.mm.

2192 {
2193 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSendActionDoNotInsertNewLine]);
2194 }

## ◆ TEST() [115/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestSetEditingStateWithTextEditingDelta |
| ) |  |

Definition at line 2148 of file FlutterTextInputPluginTest.mm.

2148 {
2149 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSetEditingStateWithTextEditingDelta]);
2150 }

## ◆ TEST() [116/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestSetMarkedTextWithReplacementRange |
| ) |  |

Definition at line 2098 of file FlutterTextInputPluginTest.mm.

2098 {
2099 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSetMarkedTextWithReplacementRange]);
2100 }

## ◆ TEST() [117/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | TestSetMarkedTextWithSelectionChange |
| ) |  |

Definition at line 2094 of file FlutterTextInputPluginTest.mm.

2094 {
2095 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSetMarkedTextWithSelectionChange]);
2096 }

## ◆ TEST() [118/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | UnhandledKeyEquivalent |
| ) |  |

Definition at line 2176 of file FlutterTextInputPluginTest.mm.

2176 {
2177 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] unhandledKeyEquivalent]);
2178 }

## ◆ TEST() [119/122]

flutter::testing::TEST | ( | FlutterTextInputPluginTest | ,
|  | WorksWithoutViewId |
| ) |  |

Definition at line 2455 of file FlutterTextInputPluginTest.mm.

2455 {
2456 id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
2457 id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
2458 OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
2459 [engineMock binaryMessenger])
2460 .andReturn(binaryMessengerMock);
2461
2462 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
2463 nibName:@""
2464 bundle:nil];
2465
2466 FlutterTextInputPluginTestDelegate* delegate =
2467 [[FlutterTextInputPluginTestDelegate alloc] initWithBinaryMessenger:binaryMessengerMock
2468 implicitViewController:viewController];
2469
2470 FlutterTextInputPlugin* plugin = [[FlutterTextInputPlugin alloc] initWithDelegate:delegate];
2471
2472 NSDictionary* setClientConfig = @{
2473 // omit viewId
2474 };
2475 [plugin handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
2476 arguments:@[ @(1), setClientConfig ]]
2477 result:^(id){
2478 }];
2479
2480 ASSERT_TRUE(plugin.currentViewController == viewController);
2481 }
FlutterTextInputPlugin::currentViewController
FlutterViewController * currentViewController
Definition: FlutterTextInputPlugin.h:54

References CreateMockFlutterEngine(), FlutterTextInputPlugin::currentViewController, FlutterTextInputPlugin::handleMethodCall:result:, and FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST() [120/122]

flutter::testing::TEST | ( | FlutterTextInputSemanticsObjectTest | ,
|  | DoesInitialize |
| ) |  |

Definition at line 27 of file FlutterTextInputSemanticsObjectTest.mm.

27 {
28 FlutterEngine* engine = CreateTestEngine();
29 {
30 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
31 nibName:nil
32 bundle:nil];
33 [viewController loadView];
34 // Create a NSWindow so that the native text field can become first responder.
35 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
36 styleMask:NSBorderlessWindowMask
37 backing:NSBackingStoreBuffered
38 defer:NO];
39 window.contentView = viewController.view;
40
41 engine.semanticsEnabled = YES;
42
43 auto bridge = viewController.accessibilityBridge.lock();
44 FlutterPlatformNodeDelegateMac delegate(bridge, viewController);
45 ui::AXTree tree;
46 ui::AXNode ax_node(&tree, nullptr, 0, 0);
47 ui::AXNodeData node_data;
48 node_data.SetValue("initial text");
49 ax_node.SetData(node_data);
50 delegate.Init(viewController.accessibilityBridge, &ax_node);
51 // Verify that a FlutterTextField is attached to the view.
52 FlutterTextPlatformNode text_platform_node(&delegate, viewController);
53 id native_accessibility = text_platform_node.GetNativeViewAccessible();
54 EXPECT_TRUE([native_accessibility isKindOfClass:[FlutterTextField class]]);
55 auto subviews = [viewController.view subviews];
56 EXPECT_EQ([subviews count], 2u);
57 EXPECT_TRUE([subviews[0] isKindOfClass:[FlutterTextField class]]);
58 FlutterTextField* nativeTextField = subviews[0];
59 EXPECT_EQ(text_platform_node.GetNativeViewAccessible(), nativeTextField);
60 }
61
62 [engine shutDownEngine];
63 engine = nil;
64 // Pump the event loop to make sure no stray nodes cause crashes after the
65 // engine has been destroyed.
66 // From issue: https://github.com/flutter/flutter/issues/115599
67 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
68 }

References flutter::FlutterTextPlatformNode::GetNativeViewAccessible(), and flutter::FlutterPlatformNodeDelegateMac::Init().

## ◆ TEST() [121/122]

flutter::testing::TEST | ( | FlutterViewEngineProviderUnittests | ,
|  | GetViewReturnsTheCorrectView |
| ) |  |

Definition at line 19 of file FlutterViewEngineProviderTest.mm.

19 {
20 FlutterViewEngineProvider* viewProvider;
21 id mockEngine = CreateMockFlutterEngine(@"");
22 __block id mockFlutterViewController;
23 OCMStub([mockEngine viewControllerForIdentifier:0])
24 .ignoringNonObjectArgs()
25 .andDo(^(NSInvocation* invocation) {
26 FlutterViewIdentifier viewIdentifier;
27 [invocation getArgument:&viewIdentifier atIndex:2];
28 if (viewIdentifier == kFlutterImplicitViewId) {
29 if (mockFlutterViewController != nil) {
30 [invocation setReturnValue:&mockFlutterViewController];
31 }
32 }
33 });
34 viewProvider = [[FlutterViewEngineProvider alloc] initWithEngine:mockEngine];
35
36 // When the view controller is not set, the returned view is nil.
37 EXPECT_EQ([viewProvider viewForIdentifier:0], nil);
38
39 // When the view controller is set, the returned view is the controller's view.
40 mockFlutterViewController = OCMStrictClassMock([FlutterViewController class]);
41 id mockView = OCMStrictClassMock([FlutterView class]);
42 OCMStub([mockFlutterViewController flutterView]).andReturn(mockView);
43 EXPECT_EQ([viewProvider viewForIdentifier:0], mockView);
44 }
FlutterViewIdentifier
int64_t FlutterViewIdentifier
Definition: FlutterViewController.h:21
FlutterViewEngineProvider
Definition: FlutterViewEngineProvider.h:18
FlutterView
Definition: FlutterView.h:36

References CreateMockFlutterEngine().

## ◆ TEST() [122/122]

flutter::testing::TEST | ( | KeyMappingTest | ,
|  | HasExpectedValues |
| ) |  |

Definition at line 20 of file KeyCodeMapTest.mm.

20 {
21 // Has Space
22 EXPECT_NE(std::find(kLayoutGoals.begin(), kLayoutGoals.end(), LayoutGoal{0x31, 0x20, false}),
23 kLayoutGoals.end());
24 // Has Digit0
25 EXPECT_NE(std::find(kLayoutGoals.begin(), kLayoutGoals.end(), LayoutGoal{0x1d, 0x30, true}),
26 kLayoutGoals.end());
27 // Has KeyA
28 EXPECT_NE(std::find(kLayoutGoals.begin(), kLayoutGoals.end(), LayoutGoal{0x00, 0x61, true}),
29 kLayoutGoals.end());
30 // Has Equal
31 EXPECT_NE(std::find(kLayoutGoals.begin(), kLayoutGoals.end(), LayoutGoal{0x18, 0x3d, false}),
32 kLayoutGoals.end());
33 // Has IntlBackslash
34 EXPECT_NE(
35 std::find(kLayoutGoals.begin(), kLayoutGoals.end(), LayoutGoal{0x0a, 0x200000020, false}),
36 kLayoutGoals.end());
37 }
flutter::kLayoutGoals
const std::vector< LayoutGoal > kLayoutGoals
Definition: KeyCodeMap.g.mm:248

References flutter::kLayoutGoals.

## ◆ TEST_F() [1/83]

flutter::testing::TEST_F | ( | AccessibilityBridgeMacTest | ,
|  | DoesNotSendAccessibilityCreateNotificationWhenHeadless |
| ) |  |

Definition at line 221 of file AccessibilityBridgeMacTest.mm.

221 {
222 FlutterViewController* viewController = CreateTestViewController();
223 FlutterEngine* engine = viewController.engine;
224
225 // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy
226 // can query semantics information from.
227 engine.semanticsEnabled = YES;
228 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
229 viewController.accessibilityBridge.lock());
230 FlutterSemanticsNode2 root;
231 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
232 root.id = 0;
233 root.flags2 = &flags;
234 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
235 root.actions = static_cast<FlutterSemanticsAction>(0);
236 root.text_selection_base = -1;
237 root.text_selection_extent = -1;
238 root.label = "root";
239 root.hint = "";
240 root.value = "";
241 root.increased_value = "";
242 root.decreased_value = "";
243 root.tooltip = "";
244 root.child_count = 0;
245 root.custom_accessibility_actions_count = 0;
246 root.identifier = "";
247 bridge->AddFlutterSemanticsNodeUpdate(root);
248
249 bridge->CommitUpdates();
250 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
251
252 // Creates a targeted event.
253 ui::AXTree tree;
254 ui::AXNode ax_node(&tree, nullptr, 0, 0);
255 ui::AXNodeData node_data;
256 node_data.id = 0;
257 ax_node.SetData(node_data);
258 std::vector<ui::AXEventIntent> intent;
259 ui::AXEventGenerator::EventParams event_params(ui::AXEventGenerator::Event::CHILDREN_CHANGED,
260 ax::mojom::EventFrom::kNone, intent);
261 ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params);
262
263 bridge->OnAccessibilityEvent(targeted_event);
264
265 // Does not send any notification if the engine is headless.
266 EXPECT_EQ(bridge->actual_notifications.size(), 0u);
267 [engine shutDownEngine];
268 }
-[FlutterEngine shutDownEngine]
void shutDownEngine()
Definition: FlutterEngine.mm:1323

References FlutterViewController::engine, and FlutterEngine::shutDownEngine.

## ◆ TEST_F() [2/83]

flutter::testing::TEST_F | ( | AccessibilityBridgeMacTest | ,
|  | DoesNotSendAccessibilityCreateNotificationWhenNoWindow |
| ) |  |

Definition at line 270 of file AccessibilityBridgeMacTest.mm.

270 {
271 FlutterViewController* viewController = CreateTestViewController();
272 FlutterEngine* engine = viewController.engine;
273
274 // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy
275 // can query semantics information from.
276 engine.semanticsEnabled = YES;
277 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
278 viewController.accessibilityBridge.lock());
279 FlutterSemanticsNode2 root;
280 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
281 root.id = 0;
282 root.flags2 = &flags;
283 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
284 root.actions = static_cast<FlutterSemanticsAction>(0);
285 root.text_selection_base = -1;
286 root.text_selection_extent = -1;
287 root.label = "root";
288 root.hint = "";
289 root.value = "";
290 root.increased_value = "";
291 root.decreased_value = "";
292 root.tooltip = "";
293 root.child_count = 0;
294 root.custom_accessibility_actions_count = 0;
295 root.identifier = "";
296 bridge->AddFlutterSemanticsNodeUpdate(root);
297
298 bridge->CommitUpdates();
299 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
300
301 // Creates a targeted event.
302 ui::AXTree tree;
303 ui::AXNode ax_node(&tree, nullptr, 0, 0);
304 ui::AXNodeData node_data;
305 node_data.id = 0;
306 ax_node.SetData(node_data);
307 std::vector<ui::AXEventIntent> intent;
308 ui::AXEventGenerator::EventParams event_params(ui::AXEventGenerator::Event::CHILDREN_CHANGED,
309 ax::mojom::EventFrom::kNone, intent);
310 ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params);
311
312 bridge->OnAccessibilityEvent(targeted_event);
313
314 // Does not send any notification if the flutter view is not attached to a NSWindow.
315 EXPECT_EQ(bridge->actual_notifications.size(), 0u);
316 [engine shutDownEngine];
317 }

References FlutterViewController::engine, and FlutterEngine::shutDownEngine.

## ◆ TEST_F() [3/83]

flutter::testing::TEST_F | ( | AccessibilityBridgeMacWindowTest | ,
|  | NonZeroRootNodeId |
| ) |  |

Definition at line 150 of file AccessibilityBridgeMacTest.mm.

150 {
151 FlutterViewController* viewController = CreateTestViewController();
152 FlutterEngine* engine = viewController.engine;
153 NSWindow* expectedTarget = GetWindow();
154 expectedTarget.contentView = viewController.view;
155
156 // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy
157 // can query semantics information from.
158 engine.semanticsEnabled = YES;
159 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
160 viewController.accessibilityBridge.lock());
161
162 FlutterSemanticsNode2 node1;
163 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
164 std::vector<int32_t> node1_children{2};
165 node1.id = 1;
166 node1.flags2 = &flags;
167 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
168 node1.actions = static_cast<FlutterSemanticsAction>(0);
169 node1.text_selection_base = -1;
170 node1.text_selection_extent = -1;
171 node1.label = "node1";
172 node1.hint = "";
173 node1.value = "";
174 node1.increased_value = "";
175 node1.decreased_value = "";
176 node1.tooltip = "";
177 node1.child_count = node1_children.size();
178 node1.children_in_traversal_order = node1_children.data();
179 node1.children_in_hit_test_order = node1_children.data();
180 node1.custom_accessibility_actions_count = 0;
181 node1.identifier = "";
182
183 FlutterSemanticsNode2 node2;
184 node2.id = 2;
185 node2.flags2 = &flags;
186 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
187 node2.actions = static_cast<FlutterSemanticsAction>(0);
188 node2.text_selection_base = -1;
189 node2.text_selection_extent = -1;
190 node2.label = "node2";
191 node2.hint = "";
192 node2.value = "";
193 node2.increased_value = "";
194 node2.decreased_value = "";
195 node2.tooltip = "";
196 node2.child_count = 0;
197 node2.custom_accessibility_actions_count = 0;
198 node2.identifier = "";
199
200 bridge->AddFlutterSemanticsNodeUpdate(node1);
201 bridge->AddFlutterSemanticsNodeUpdate(node2);
202 bridge->CommitUpdates();
203
204 // Look up the root node delegate.
205 auto root_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
206 ASSERT_TRUE(root_delegate);
207 ASSERT_EQ(root_delegate->GetChildCount(), 1);
208
209 // Look up the child node delegate.
210 auto child_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(2).lock();
211 ASSERT_TRUE(child_delegate);
212 ASSERT_EQ(child_delegate->GetChildCount(), 0);
213
214 // Ensure a node with ID 0 does not exist.
215 auto invalid_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
216 ASSERT_FALSE(invalid_delegate);
217
218 [engine shutDownEngine];
219 }

References FlutterViewController::engine, and FlutterEngine::shutDownEngine.

## ◆ TEST_F() [4/83]

flutter::testing::TEST_F | ( | AccessibilityBridgeMacWindowTest | ,
|  | SendsAccessibilityCreateNotificationFlutterViewWindow |
| ) |  |

Definition at line 90 of file AccessibilityBridgeMacTest.mm.

90 {
91 FlutterViewController* viewController = CreateTestViewController();
92 FlutterEngine* engine = viewController.engine;
93 NSWindow* expectedTarget = GetWindow();
94 expectedTarget.contentView = viewController.view;
95
96 // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy
97 // can query semantics information from.
98 engine.semanticsEnabled = YES;
99 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
100 viewController.accessibilityBridge.lock());
101 FlutterSemanticsNode2 root;
102 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
103 root.id = 0;
104 root.flags2 = &flags;
105 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
106 root.actions = static_cast<FlutterSemanticsAction>(0);
107 root.text_selection_base = -1;
108 root.text_selection_extent = -1;
109 root.label = "root";
110 root.hint = "";
111 root.value = "";
112 root.increased_value = "";
113 root.decreased_value = "";
114 root.tooltip = "";
115 root.child_count = 0;
116 root.custom_accessibility_actions_count = 0;
117 root.identifier = "";
118 bridge->AddFlutterSemanticsNodeUpdate(root);
119
120 bridge->CommitUpdates();
121 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
122
123 // Creates a targeted event.
124 ui::AXTree tree;
125 ui::AXNode ax_node(&tree, nullptr, 0, 0);
126 ui::AXNodeData node_data;
127 node_data.id = 0;
128 ax_node.SetData(node_data);
129 std::vector<ui::AXEventIntent> intent;
130 ui::AXEventGenerator::EventParams event_params(ui::AXEventGenerator::Event::CHILDREN_CHANGED,
131 ax::mojom::EventFrom::kNone, intent);
132 ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params);
133
134 bridge->OnAccessibilityEvent(targeted_event);
135
136 ASSERT_EQ(bridge->actual_notifications.size(), 1u);
137 auto target = bridge->actual_notifications.find([NSAccessibilityCreatedNotification UTF8String]);
138 ASSERT_NE(target, bridge->actual_notifications.end());
139 EXPECT_EQ(target->second, expectedTarget);
140 [engine shutDownEngine];
141 }

References FlutterViewController::engine, and FlutterEngine::shutDownEngine.

## ◆ TEST_F() [5/83]

flutter::testing::TEST_F | ( | FlutterChannelKeyResponderTest | ,
|  | BasicKeyEvent |
| ) |  |

Definition at line 75 of file FlutterChannelKeyResponderTest.mm.

75 {
76 __block NSMutableArray<NSNumber*>* responses = [[NSMutableArray<NSNumber*> alloc] init];
77 FakeMessageChannel* channel = [[FakeMessageChannel alloc] init];
78 FlutterChannelKeyResponder* responder =
79 [[FlutterChannelKeyResponder alloc] initWithChannel:channel];
80
81 // Initial empty modifiers.
82 //
83 // This can happen when user opens window while modifier key is pressed and then releases the
84 // modifier. No events should be sent, but the callback should still be called.
85 // Regression test for https://github.com/flutter/flutter/issues/87339.
86 channel.nextResponse = @{@"handled" : @YES};
87 [responder handleEvent:CreateKeyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", NO, 60)
88 callback:^(BOOL handled) {
89 [responses addObject:@(handled)];
90 }];
91
92 EXPECT_EQ([channel.messages count], 0u);
93 ASSERT_EQ([responses count], 1u);
94 EXPECT_EQ([responses[0] boolValue], YES);
95 [responses removeAllObjects];
96
97 // Key down
98 channel.nextResponse = @{@"handled" : @YES};
99 [responder handleEvent:CreateKeyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", NO, 0)
100 callback:^(BOOL handled) {
101 [responses addObject:@(handled)];
102 }];
103
104 ASSERT_EQ([channel.messages count], 1u);
105 EXPECT_STREQ([[channel.messages lastObject][@"keymap"] UTF8String], "macos");
106 EXPECT_STREQ([[channel.messages lastObject][@"type"] UTF8String], "keydown");
107 EXPECT_EQ([[channel.messages lastObject][@"keyCode"] intValue], 0);
108 EXPECT_EQ([[channel.messages lastObject][@"modifiers"] intValue], 0x0);
109 EXPECT_STREQ([[channel.messages lastObject][@"characters"] UTF8String], "a");
110 EXPECT_STREQ([[channel.messages lastObject][@"charactersIgnoringModifiers"] UTF8String], "a");
111
112 ASSERT_EQ([responses count], 1u);
113 EXPECT_EQ([[responses lastObject] boolValue], YES);
114
115 [channel.messages removeAllObjects];
116 [responses removeAllObjects];
117
118 // Key up
119 channel.nextResponse = @{@"handled" : @NO};
120 [responder handleEvent:CreateKeyEvent(NSEventTypeKeyUp, 0x100, @"a", @"a", NO, 0)
121 callback:^(BOOL handled) {
122 [responses addObject:@(handled)];
123 }];
124
125 ASSERT_EQ([channel.messages count], 1u);
126 EXPECT_STREQ([[channel.messages lastObject][@"keymap"] UTF8String], "macos");
127 EXPECT_STREQ([[channel.messages lastObject][@"type"] UTF8String], "keyup");
128 EXPECT_EQ([[channel.messages lastObject][@"keyCode"] intValue], 0);
129 EXPECT_EQ([[channel.messages lastObject][@"modifiers"] intValue], 0);
130 EXPECT_STREQ([[channel.messages lastObject][@"characters"] UTF8String], "a");
131 EXPECT_STREQ([[channel.messages lastObject][@"charactersIgnoringModifiers"] UTF8String], "a");
132
133 ASSERT_EQ([responses count], 1u);
134 EXPECT_EQ([[responses lastObject] boolValue], NO);
135
136 [channel.messages removeAllObjects];
137 [responses removeAllObjects];
138
139 // LShift down
140 channel.nextResponse = @{@"handled" : @YES};
141 [responder handleEvent:CreateKeyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", NO, 56)
142 callback:^(BOOL handled) {
143 [responses addObject:@(handled)];
144 }];
145
146 ASSERT_EQ([channel.messages count], 1u);
147 EXPECT_STREQ([[channel.messages lastObject][@"keymap"] UTF8String], "macos");
148 EXPECT_STREQ([[channel.messages lastObject][@"type"] UTF8String], "keydown");
149 EXPECT_EQ([[channel.messages lastObject][@"keyCode"] intValue], 56);
150 EXPECT_EQ([[channel.messages lastObject][@"modifiers"] intValue], 0x20002);
151
152 ASSERT_EQ([responses count], 1u);
153 EXPECT_EQ([[responses lastObject] boolValue], YES);
154
155 [channel.messages removeAllObjects];
156 [responses removeAllObjects];
157
158 // RShift down
159 channel.nextResponse = @{@"handled" : @NO};
160 [responder handleEvent:CreateKeyEvent(NSEventTypeFlagsChanged, 0x20006, @"", @"", NO, 60)
161 callback:^(BOOL handled) {
162 [responses addObject:@(handled)];
163 }];
164
165 ASSERT_EQ([channel.messages count], 1u);
166 EXPECT_STREQ([[channel.messages lastObject][@"keymap"] UTF8String], "macos");
167 EXPECT_STREQ([[channel.messages lastObject][@"type"] UTF8String], "keydown");
168 EXPECT_EQ([[channel.messages lastObject][@"keyCode"] intValue], 60);
169 EXPECT_EQ([[channel.messages lastObject][@"modifiers"] intValue], 0x20006);
170
171 ASSERT_EQ([responses count], 1u);
172 EXPECT_EQ([[responses lastObject] boolValue], NO);
173
174 [channel.messages removeAllObjects];
175 [responses removeAllObjects];
176
177 // LShift up
178 channel.nextResponse = @{@"handled" : @NO};
179 [responder handleEvent:CreateKeyEvent(NSEventTypeFlagsChanged, 0x20104, @"", @"", NO, 56)
180 callback:^(BOOL handled) {
181 [responses addObject:@(handled)];
182 }];
183
184 ASSERT_EQ([channel.messages count], 1u);
185 EXPECT_STREQ([[channel.messages lastObject][@"keymap"] UTF8String], "macos");
186 EXPECT_STREQ([[channel.messages lastObject][@"type"] UTF8String], "keyup");
187 EXPECT_EQ([[channel.messages lastObject][@"keyCode"] intValue], 56);
188 EXPECT_EQ([[channel.messages lastObject][@"modifiers"] intValue], 0x20004);
189
190 ASSERT_EQ([responses count], 1u);
191 EXPECT_EQ([[responses lastObject] boolValue], NO);
192
193 [channel.messages removeAllObjects];
194 [responses removeAllObjects];
195
196 // RShift up
197 channel.nextResponse = @{@"handled" : @NO};
198 [responder handleEvent:CreateKeyEvent(NSEventTypeFlagsChanged, 0, @"", @"", NO, 60)
199 callback:^(BOOL handled) {
200 [responses addObject:@(handled)];
201 }];
202
203 ASSERT_EQ([channel.messages count], 1u);
204 EXPECT_STREQ([[channel.messages lastObject][@"keymap"] UTF8String], "macos");
205 EXPECT_STREQ([[channel.messages lastObject][@"type"] UTF8String], "keyup");
206 EXPECT_EQ([[channel.messages lastObject][@"keyCode"] intValue], 60);
207 EXPECT_EQ([[channel.messages lastObject][@"modifiers"] intValue], 0);
208
209 ASSERT_EQ([responses count], 1u);
210 EXPECT_EQ([[responses lastObject] boolValue], NO);
211
212 [channel.messages removeAllObjects];
213 [responses removeAllObjects];
214
215 // RShift up again, should be ignored and not produce a keydown event, but the
216 // callback should be called.
217 channel.nextResponse = @{@"handled" : @NO};
218 [responder handleEvent:CreateKeyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", NO, 60)
219 callback:^(BOOL handled) {
220 [responses addObject:@(handled)];
221 }];
222
223 EXPECT_EQ([channel.messages count], 0u);
224 ASSERT_EQ([responses count], 1u);
225 EXPECT_EQ([responses[0] boolValue], YES);
226 }
FakeMessageChannel
Definition: FlutterChannelKeyResponderTest.mm:20
FakeMessageChannel::messages
NSMutableArray< id > * messages
Definition: FlutterChannelKeyResponderTest.mm:20
FakeMessageChannel::nextResponse
NSDictionary * nextResponse
Definition: FlutterChannelKeyResponderTest.mm:21
FlutterChannelKeyResponder
Definition: FlutterChannelKeyResponder.h:20

References <FlutterKeyPrimaryResponder>::handleEvent:callback:, FakeMessageChannel::messages, and FakeMessageChannel::nextResponse.

## ◆ TEST_F() [6/83]

flutter::testing::TEST_F | ( | FlutterChannelKeyResponderTest | ,
|  | EmptyResponseIsTakenAsHandled |
| ) |  |

Definition at line 228 of file FlutterChannelKeyResponderTest.mm.

228 {
229 __block NSMutableArray<NSNumber*>* responses = [[NSMutableArray<NSNumber*> alloc] init];
230 FakeMessageChannel* channel = [[FakeMessageChannel alloc] init];
231 FlutterChannelKeyResponder* responder =
232 [[FlutterChannelKeyResponder alloc] initWithChannel:channel];
233
234 channel.nextResponse = nil;
235 [responder handleEvent:CreateKeyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", NO, 0)
236 callback:^(BOOL handled) {
237 [responses addObject:@(handled)];
238 }];
239
240 ASSERT_EQ([channel.messages count], 1u);
241 EXPECT_STREQ([[channel.messages lastObject][@"keymap"] UTF8String], "macos");
242 EXPECT_STREQ([[channel.messages lastObject][@"type"] UTF8String], "keydown");
243 EXPECT_EQ([[channel.messages lastObject][@"keyCode"] intValue], 0);
244 EXPECT_EQ([[channel.messages lastObject][@"modifiers"] intValue], 0);
245 EXPECT_STREQ([[channel.messages lastObject][@"characters"] UTF8String], "a");
246 EXPECT_STREQ([[channel.messages lastObject][@"charactersIgnoringModifiers"] UTF8String], "a");
247
248 ASSERT_EQ([responses count], 1u);
249 EXPECT_EQ([[responses lastObject] boolValue], YES);
250 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:, FakeMessageChannel::messages, and FakeMessageChannel::nextResponse.

## ◆ TEST_F() [7/83]

flutter::testing::TEST_F | ( | FlutterChannelKeyResponderTest | ,
|  | FollowsLayoutMap |
| ) |  |

Definition at line 252 of file FlutterChannelKeyResponderTest.mm.

252 {
253 __block NSMutableArray<NSNumber*>* responses = [[NSMutableArray<NSNumber*> alloc] init];
254 FakeMessageChannel* channel = [[FakeMessageChannel alloc] init];
255 FlutterChannelKeyResponder* responder =
256 [[FlutterChannelKeyResponder alloc] initWithChannel:channel];
257
258 NSMutableDictionary<NSNumber*, NSNumber*>* layoutMap =
259 [NSMutableDictionary<NSNumber*, NSNumber*> dictionary];
260 responder.layoutMap = layoutMap;
261 // French layout
262 layoutMap[@(kVK_ANSI_A)] = @(kLogicalKeyQ);
263
264 channel.nextResponse = @{@"handled" : @YES};
265 [responder handleEvent:CreateKeyEvent(NSEventTypeKeyDown, kVK_ANSI_A, @"q", @"q", NO, 0)
266 callback:^(BOOL handled) {
267 [responses addObject:@(handled)];
268 }];
269
270 ASSERT_EQ([channel.messages count], 1u);
271 EXPECT_STREQ([[channel.messages lastObject][@"keymap"] UTF8String], "macos");
272 EXPECT_STREQ([[channel.messages lastObject][@"type"] UTF8String], "keydown");
273 EXPECT_EQ([[channel.messages lastObject][@"keyCode"] intValue], 0);
274 EXPECT_EQ([[channel.messages lastObject][@"modifiers"] intValue], 0x0);
275 EXPECT_STREQ([[channel.messages lastObject][@"characters"] UTF8String], "q");
276 EXPECT_STREQ([[channel.messages lastObject][@"charactersIgnoringModifiers"] UTF8String], "q");
277 EXPECT_EQ([channel.messages lastObject][@"specifiedLogicalKey"], @(kLogicalKeyQ));
278
279 ASSERT_EQ([responses count], 1u);
280 EXPECT_EQ([[responses lastObject] boolValue], YES);
281
282 [channel.messages removeAllObjects];
283 [responses removeAllObjects];
284 }
FlutterKeyPrimaryResponder-p::layoutMap
NSMutableDictionary< NSNumber *, NSNumber * > * layoutMap
Definition: FlutterKeyPrimaryResponder.h:46

References <FlutterKeyPrimaryResponder>::handleEvent:callback:, <FlutterKeyPrimaryResponder>::layoutMap, FakeMessageChannel::messages, and FakeMessageChannel::nextResponse.

## ◆ TEST_F() [8/83]

flutter::testing::TEST_F | ( | FlutterEmbedderExternalTextureTest | ,
|  | TestPopulateExternalTexture |
| ) |  |

Definition at line 154 of file FlutterEmbedderExternalTextureTest.mm.

154 {
155 // Constants.
156 const size_t width = 100;
157 const size_t height = 100;
158 const int64_t texture_id = 1;
159
160 // Set up the surface.
161 FlutterDarwinContextMetalSkia* darwinContextMetal =
162 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
163 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
164 GrDirectContext* grContext = darwinContextMetal.mainContext.get();
165 sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));
166
167 // Create a texture.
168 TestExternalTexture* testExternalTexture =
169 [[TestExternalTexture alloc] initWidth:width
170 height:height
171 pixelFormatType:kCVPixelFormatType_32BGRA];
172 FlutterExternalTexture* textureHolder =
173 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
174 darwinMetalContext:darwinContextMetal];
175
176 // Callback to resolve the texture.
177 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
178 size_t h) {
179 EXPECT_TRUE(w == width);
180 EXPECT_TRUE(h == height);
181
182 auto texture = std::make_unique<FlutterMetalExternalTexture>();
183 [textureHolder populateTexture:texture.get()];
184
185 EXPECT_TRUE(texture->num_textures == 1);
186 EXPECT_TRUE(texture->textures != nullptr);
187 EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kRGBA);
188 return texture;
189 };
190
191 // Render the texture.
192 std::unique_ptr<flutter::Texture> texture =
193 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
194 DlRect bounds = DlRect::MakeWH(info.width(), info.height());
195 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
196 DlSkCanvasAdapter canvas(gpuSurface->getCanvas());
197 flutter::Texture::PaintContext context{
198 .canvas = &canvas,
199 .gr_context = grContext,
200 };
201 texture->Paint(context, bounds, /*freeze=*/false, sampling);
202
203 gpuSurface->makeImageSnapshot();
204 }
FlutterExternalTexture
Definition: FlutterExternalTexture.h:19
-[FlutterExternalTexture populateTexture:]
BOOL populateTexture:(nonnull FlutterMetalExternalTexture *metalTexture)
TestExternalTexture
Definition: FlutterEmbedderExternalTextureTest.mm:48
texture_id
int64_t texture_id
Definition: texture_registrar_unittests.cc:24

References FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST_F() [9/83]

flutter::testing::TEST_F | ( | FlutterEmbedderExternalTextureTest | ,
|  | TestPopulateExternalTextureImpeller |
| ) |  |

Definition at line 413 of file FlutterEmbedderExternalTextureTest.mm.

413 {
414 // Constants.
415 const size_t width = 100;
416 const size_t height = 100;
417 const int64_t texture_id = 1;
418
419 // Set up the surface.
420 FlutterDarwinContextMetalSkia* darwinContextMetal =
421 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
422 impeller::AiksContext aiks_context(CreateImpellerContext(), nullptr);
423 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
424
425 // Create a texture.
426 TestExternalTexture* testExternalTexture =
427 [[TestExternalTexture alloc] initWidth:width
428 height:height
429 pixelFormatType:kCVPixelFormatType_32BGRA];
430 FlutterExternalTexture* textureHolder =
431 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
432 darwinMetalContext:darwinContextMetal];
433
434 // Callback to resolve the texture.
435 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
436 size_t h) {
437 EXPECT_TRUE(w == width);
438 EXPECT_TRUE(h == height);
439
440 auto texture = std::make_unique<FlutterMetalExternalTexture>();
441 [textureHolder populateTexture:texture.get()];
442
443 EXPECT_TRUE(texture->num_textures == 1);
444 EXPECT_TRUE(texture->textures != nullptr);
445 EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kRGBA);
446 return texture;
447 };
448
449 // Render the texture.
450 std::unique_ptr<flutter::Texture> texture =
451 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
452 DlRect bounds = DlRect::MakeWH(info.width(), info.height());
453 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
454
455 DisplayListBuilder builder;
456 flutter::Texture::PaintContext context{
457 .canvas = &builder,
458 .gr_context = nullptr,
459 .aiks_context = &aiks_context,
460 };
461 texture->Paint(context, bounds, /*freeze=*/false, sampling);
462 }
CreateImpellerContext
static std::shared_ptr< impeller::ContextMTL > CreateImpellerContext()
Definition: FlutterEmbedderExternalTextureTest.mm:34

References CreateImpellerContext(), FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST_F() [10/83]

flutter::testing::TEST_F | ( | FlutterEmbedderExternalTextureTest | ,
|  | TestPopulateExternalTextureYUVA |
| ) |  |

Definition at line 206 of file FlutterEmbedderExternalTextureTest.mm.

206 {
207 // Constants.
208 const size_t width = 100;
209 const size_t height = 100;
210 const int64_t texture_id = 1;
211
212 // Set up the surface.
213 FlutterDarwinContextMetalSkia* darwinContextMetal =
214 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
215 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
216 GrDirectContext* grContext = darwinContextMetal.mainContext.get();
217 sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));
218
219 // Create a texture.
220 TestExternalTexture* testExternalTexture =
221 [[TestExternalTexture alloc] initWidth:width
222 height:height
223 pixelFormatType:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange];
224 FlutterExternalTexture* textureHolder =
225 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
226 darwinMetalContext:darwinContextMetal];
227
228 // Callback to resolve the texture.
229 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
230 size_t h) {
231 EXPECT_TRUE(w == width);
232 EXPECT_TRUE(h == height);
233
234 auto texture = std::make_unique<FlutterMetalExternalTexture>();
235 [textureHolder populateTexture:texture.get()];
236
237 EXPECT_TRUE(texture->num_textures == 2);
238 EXPECT_TRUE(texture->textures != nullptr);
239 EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kYUVA);
240 EXPECT_TRUE(texture->yuv_color_space ==
241 FlutterMetalExternalTextureYUVColorSpace::kBT601LimitedRange);
242 return texture;
243 };
244
245 // Render the texture.
246 std::unique_ptr<flutter::Texture> texture =
247 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
248 DlRect bounds = DlRect::MakeWH(info.width(), info.height());
249 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
250 DlSkCanvasAdapter canvas(gpuSurface->getCanvas());
251 flutter::Texture::PaintContext context{
252 .canvas = &canvas,
253 .gr_context = grContext,
254 };
255 texture->Paint(context, bounds, /*freeze=*/false, sampling);
256
257 gpuSurface->makeImageSnapshot();
258 }

References FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST_F() [11/83]

flutter::testing::TEST_F | ( | FlutterEmbedderExternalTextureTest | ,
|  | TestPopulateExternalTextureYUVA2 |
| ) |  |

Definition at line 260 of file FlutterEmbedderExternalTextureTest.mm.

260 {
261 // Constants.
262 const size_t width = 100;
263 const size_t height = 100;
264 const int64_t texture_id = 1;
265
266 // Set up the surface.
267 FlutterDarwinContextMetalSkia* darwinContextMetal =
268 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
269 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
270 GrDirectContext* grContext = darwinContextMetal.mainContext.get();
271 sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));
272
273 // Create a texture.
274 TestExternalTexture* testExternalTexture =
275 [[TestExternalTexture alloc] initWidth:width
276 height:height
277 pixelFormatType:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange];
278 FlutterExternalTexture* textureHolder =
279 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
280 darwinMetalContext:darwinContextMetal];
281
282 // Callback to resolve the texture.
283 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
284 size_t h) {
285 EXPECT_TRUE(w == width);
286 EXPECT_TRUE(h == height);
287
288 auto texture = std::make_unique<FlutterMetalExternalTexture>();
289 [textureHolder populateTexture:texture.get()];
290
291 EXPECT_TRUE(texture->num_textures == 2);
292 EXPECT_TRUE(texture->textures != nullptr);
293 EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kYUVA);
294 EXPECT_TRUE(texture->yuv_color_space ==
295 FlutterMetalExternalTextureYUVColorSpace::kBT601FullRange);
296 return texture;
297 };
298
299 // Render the texture.
300 std::unique_ptr<flutter::Texture> texture =
301 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
302 DlRect bounds = DlRect::MakeWH(info.width(), info.height());
303 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
304 DlSkCanvasAdapter canvas(gpuSurface->getCanvas());
305 flutter::Texture::PaintContext context{
306 .canvas = &canvas,
307 .gr_context = grContext,
308 };
309 texture->Paint(context, bounds, /*freeze=*/false, sampling);
310
311 gpuSurface->makeImageSnapshot();
312 }

References FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST_F() [12/83]

flutter::testing::TEST_F | ( | FlutterEmbedderExternalTextureTest | ,
|  | TestPopulateExternalTextureYUVA2Impeller |
| ) |  |

Definition at line 514 of file FlutterEmbedderExternalTextureTest.mm.

514 {
515 // Constants.
516 const size_t width = 100;
517 const size_t height = 100;
518 const int64_t texture_id = 1;
519
520 // Set up the surface.
521 FlutterDarwinContextMetalSkia* darwinContextMetal =
522 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
523 impeller::AiksContext aiks_context(CreateImpellerContext(), nullptr);
524 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
525
526 // Create a texture.
527 TestExternalTexture* testExternalTexture =
528 [[TestExternalTexture alloc] initWidth:width
529 height:height
530 pixelFormatType:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange];
531 FlutterExternalTexture* textureHolder =
532 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
533 darwinMetalContext:darwinContextMetal];
534
535 // Callback to resolve the texture.
536 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
537 size_t h) {
538 EXPECT_TRUE(w == width);
539 EXPECT_TRUE(h == height);
540
541 auto texture = std::make_unique<FlutterMetalExternalTexture>();
542 [textureHolder populateTexture:texture.get()];
543
544 EXPECT_TRUE(texture->num_textures == 2);
545 EXPECT_TRUE(texture->textures != nullptr);
546 EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kYUVA);
547 EXPECT_TRUE(texture->yuv_color_space ==
548 FlutterMetalExternalTextureYUVColorSpace::kBT601FullRange);
549 return texture;
550 };
551
552 // Render the texture.
553 std::unique_ptr<flutter::Texture> texture =
554 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
555 DlRect bounds = DlRect::MakeWH(info.width(), info.height());
556 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
557
558 DisplayListBuilder builder;
559 flutter::Texture::PaintContext context{
560 .canvas = &builder, .gr_context = nullptr, .aiks_context = &aiks_context};
561 texture->Paint(context, bounds, /*freeze=*/false, sampling);
562 }

References CreateImpellerContext(), FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST_F() [13/83]

flutter::testing::TEST_F | ( | FlutterEmbedderExternalTextureTest | ,
|  | TestPopulateExternalTextureYUVAImpeller |
| ) |  |

Definition at line 464 of file FlutterEmbedderExternalTextureTest.mm.

464 {
465 // Constants.
466 const size_t width = 100;
467 const size_t height = 100;
468 const int64_t texture_id = 1;
469
470 // Set up the surface.
471 FlutterDarwinContextMetalSkia* darwinContextMetal =
472 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
473 impeller::AiksContext aiks_context(CreateImpellerContext(), nullptr);
474 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
475
476 // Create a texture.
477 TestExternalTexture* testExternalTexture =
478 [[TestExternalTexture alloc] initWidth:width
479 height:height
480 pixelFormatType:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange];
481 FlutterExternalTexture* textureHolder =
482 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
483 darwinMetalContext:darwinContextMetal];
484
485 // Callback to resolve the texture.
486 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
487 size_t h) {
488 EXPECT_TRUE(w == width);
489 EXPECT_TRUE(h == height);
490
491 auto texture = std::make_unique<FlutterMetalExternalTexture>();
492 [textureHolder populateTexture:texture.get()];
493
494 EXPECT_TRUE(texture->num_textures == 2);
495 EXPECT_TRUE(texture->textures != nullptr);
496 EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kYUVA);
497 EXPECT_TRUE(texture->yuv_color_space ==
498 FlutterMetalExternalTextureYUVColorSpace::kBT601LimitedRange);
499 return texture;
500 };
501
502 // Render the texture.
503 std::unique_ptr<flutter::Texture> texture =
504 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
505 DlRect bounds = DlRect::MakeWH(info.width(), info.height());
506 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
507
508 DisplayListBuilder builder;
509 flutter::Texture::PaintContext context{
510 .canvas = &builder, .gr_context = nullptr, .aiks_context = &aiks_context};
511 texture->Paint(context, bounds, /*freeze=*/false, sampling);
512 }

References CreateImpellerContext(), FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST_F() [14/83]

flutter::testing::TEST_F | ( | FlutterEmbedderExternalTextureTest | ,
|  | TestPopulateUnsupportedExternalTexture |
| ) |  |

Definition at line 314 of file FlutterEmbedderExternalTextureTest.mm.

314 {
315 // Constants.
316 const size_t width = 100;
317 const size_t height = 100;
318 const int64_t texture_id = 1;
319
320 // Set up the surface.
321 FlutterDarwinContextMetalSkia* darwinContextMetal =
322 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
323 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
324 GrDirectContext* grContext = darwinContextMetal.mainContext.get();
325 sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));
326
327 // Create a texture.
328 TestExternalTexture* testExternalTexture =
329 [[TestExternalTexture alloc] initWidth:width
330 height:height
331 pixelFormatType:kCVPixelFormatType_420YpCbCr8PlanarFullRange];
332 FlutterExternalTexture* textureHolder =
333 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
334 darwinMetalContext:darwinContextMetal];
335
336 // Callback to resolve the texture.
337 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
338 size_t h) {
339 EXPECT_TRUE(w == width);
340 EXPECT_TRUE(h == height);
341
342 auto texture = std::make_unique<FlutterMetalExternalTexture>();
343 EXPECT_FALSE([textureHolder populateTexture:texture.get()]);
344 return nullptr;
345 };
346
347 // Render the texture.
348 std::unique_ptr<flutter::Texture> texture =
349 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
350 DlRect bounds = DlRect::MakeWH(info.width(), info.height());
351 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
352 DlSkCanvasAdapter canvas(gpuSurface->getCanvas());
353 flutter::Texture::PaintContext context{
354 .canvas = &canvas,
355 .gr_context = grContext,
356 };
357 texture->Paint(context, bounds, /*freeze=*/false, sampling);
358 }

References texture_id.

## ◆ TEST_F() [15/83]

flutter::testing::TEST_F | ( | FlutterEmbedderExternalTextureTest | ,
|  | TestPopulateUnsupportedExternalTextureImpeller |
| ) |  |

Definition at line 564 of file FlutterEmbedderExternalTextureTest.mm.

564 {
565 // Constants.
566 const size_t width = 100;
567 const size_t height = 100;
568 const int64_t texture_id = 1;
569
570 // Set up the surface.
571 FlutterDarwinContextMetalSkia* darwinContextMetal =
572 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
573 impeller::AiksContext aiks_context(CreateImpellerContext(), nullptr);
574 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
575
576 // Create a texture.
577 TestExternalTexture* testExternalTexture =
578 [[TestExternalTexture alloc] initWidth:width
579 height:height
580 pixelFormatType:kCVPixelFormatType_420YpCbCr8PlanarFullRange];
581 FlutterExternalTexture* textureHolder =
582 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
583 darwinMetalContext:darwinContextMetal];
584
585 // Callback to resolve the texture.
586 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
587 size_t h) {
588 EXPECT_TRUE(w == width);
589 EXPECT_TRUE(h == height);
590
591 auto texture = std::make_unique<FlutterMetalExternalTexture>();
592 EXPECT_FALSE([textureHolder populateTexture:texture.get()]);
593 return nullptr;
594 };
595
596 // Render the texture.
597 std::unique_ptr<flutter::Texture> texture =
598 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
599 DlRect bounds = DlRect::MakeWH(info.width(), info.height());
600 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
601
602 DisplayListBuilder builder;
603 flutter::Texture::PaintContext context{
604 .canvas = &builder, .gr_context = nullptr, .aiks_context = &aiks_context};
605 texture->Paint(context, bounds, /*freeze=*/false, sampling);
606 }

References CreateImpellerContext(), and texture_id.

## ◆ TEST_F() [16/83]

flutter::testing::TEST_F | ( | FlutterEmbedderExternalTextureTest | ,
|  | TestTextureResolution |
| ) |  |

Definition at line 96 of file FlutterEmbedderExternalTextureTest.mm.

96 {
97 // Constants.
98 const size_t width = 100;
99 const size_t height = 100;
100 const int64_t texture_id = 1;
101
102 // Set up the surface.
103 FlutterDarwinContextMetalSkia* darwinContextMetal =
104 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
105 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
106 GrDirectContext* grContext = darwinContextMetal.mainContext.get();
107 sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));
108
109 // Create a texture.
110 MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init];
111 textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm;
112 textureDescriptor.width = width;
113 textureDescriptor.height = height;
114 textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
115 id<MTLTexture> mtlTexture =
116 [darwinContextMetal.device newTextureWithDescriptor:textureDescriptor];
117 std::vector<FlutterMetalTextureHandle> textures = {
118 (__bridge FlutterMetalTextureHandle)mtlTexture,
119 };
120
121 // Callback to resolve the texture.
122 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
123 size_t h) {
124 EXPECT_TRUE(w == width);
125 EXPECT_TRUE(h == height);
126
127 auto texture = std::make_unique<FlutterMetalExternalTexture>();
128 texture->struct_size = sizeof(FlutterMetalExternalTexture);
129 texture->num_textures = 1;
130 texture->height = h;
131 texture->width = w;
132 texture->pixel_format = FlutterMetalExternalTexturePixelFormat::kRGBA;
133 texture->textures = textures.data();
134 return texture;
135 };
136
137 // Render the texture.
138 std::unique_ptr<flutter::Texture> texture =
139 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
140 DlRect bounds = DlRect::MakeWH(info.width(), info.height());
141 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
142 DlSkCanvasAdapter canvas(gpuSurface->getCanvas());
143 flutter::Texture::PaintContext context{
144 .canvas = &canvas,
145 .gr_context = grContext,
146 };
147 texture->Paint(context, bounds, /*freeze=*/false, sampling);
148
149 ASSERT_TRUE(mtlTexture != nil);
150
151 gpuSurface->makeImageSnapshot();
152 }

References texture_id.

## ◆ TEST_F() [17/83]

flutter::testing::TEST_F | ( | FlutterEmbedderExternalTextureTest | ,
|  | TestTextureResolutionImpeller |
| ) |  |

Definition at line 360 of file FlutterEmbedderExternalTextureTest.mm.

360 {
361 // Constants.
362 const size_t width = 100;
363 const size_t height = 100;
364 const int64_t texture_id = 1;
365
366 // Set up the surface.
367 auto device = ::MTLCreateSystemDefaultDevice();
368 impeller::AiksContext aiks_context(CreateImpellerContext(), nullptr);
369
370 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
371
372 // Create a texture.
373 MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init];
374 textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm;
375 textureDescriptor.width = width;
376 textureDescriptor.height = height;
377 textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
378 id<MTLTexture> mtlTexture = [device newTextureWithDescriptor:textureDescriptor];
379 std::vector<FlutterMetalTextureHandle> textures = {
380 (__bridge FlutterMetalTextureHandle)mtlTexture,
381 };
382
383 // Callback to resolve the texture.
384 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
385 size_t h) {
386 EXPECT_TRUE(w == width);
387 EXPECT_TRUE(h == height);
388
389 auto texture = std::make_unique<FlutterMetalExternalTexture>();
390 texture->struct_size = sizeof(FlutterMetalExternalTexture);
391 texture->num_textures = 1;
392 texture->height = h;
393 texture->width = w;
394 texture->pixel_format = FlutterMetalExternalTexturePixelFormat::kRGBA;
395 texture->textures = textures.data();
396 return texture;
397 };
398
399 // Render the texture.
400 std::unique_ptr<flutter::Texture> texture =
401 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
402 DlRect bounds = DlRect::MakeWH(info.width(), info.height());
403 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
404
405 DisplayListBuilder builder;
406 flutter::Texture::PaintContext context{
407 .canvas = &builder, .gr_context = nullptr, .aiks_context = &aiks_context};
408 texture->Paint(context, bounds, /*freeze=*/false, sampling);
409
410 ASSERT_TRUE(mtlTexture != nil);
411 }

References CreateImpellerContext(), and texture_id.

## ◆ TEST_F() [18/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | CanGetEngineForId |
| ) |  |

Definition at line 905 of file FlutterEngineTest.mm.

905 {
906 FlutterEngine* engine = GetFlutterEngine();
907
908 BOOL signaled = NO;
909 std::optional<int64_t> engineId;
910 AddNativeCallback("NotifyEngineId", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
911 const auto argument = Dart_GetNativeArgument(args, 0);
912 if (!Dart_IsNull(argument)) {
913 const auto id = tonic::DartConverter<int64_t>::FromDart(argument);
914 engineId = id;
915 }
916 signaled = YES;
917 }));
918
919 EXPECT_TRUE([engine runWithEntrypoint:@"testEngineId"]);
920 while (!signaled) {
921 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
922 }
923
924 EXPECT_TRUE(engineId.has_value());
925 if (!engineId.has_value()) {
926 return;
927 }
928 EXPECT_EQ(engine, [FlutterEngine engineForIdentifier:*engineId]);
929 ShutDownEngine();
930 }

## ◆ TEST_F() [19/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | CanLaunch |
| ) |  |

Definition at line 142 of file FlutterEngineTest.mm.

142 {
143 FlutterEngine* engine = GetFlutterEngine();
144 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
145 ASSERT_TRUE(engine.running);
146 }

## ◆ TEST_F() [20/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | CanLogToStdout |
| ) |  |

Definition at line 207 of file FlutterEngineTest.mm.

207 {
208 // Block until completion of print statement.
209 BOOL signaled = NO;
210 AddNativeCallback("SignalNativeTest",
211 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { signaled = YES; }));
212
213 // Replace stdout stream buffer with our own.
214 FlutterStringOutputWriter* writer = [[FlutterStringOutputWriter alloc] init];
215 writer.expectedOutput = @"Hello logging";
216 FlutterLogger.outputWriter = writer;
217
218 // Launch the test entrypoint.
219 FlutterEngine* engine = GetFlutterEngine();
220 EXPECT_TRUE([engine runWithEntrypoint:@"canLogToStdout"]);
221 ASSERT_TRUE(engine.running);
222
223 while (!signaled) {
224 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
225 }
226
227 // Verify hello world was written to stdout.
228 EXPECT_TRUE(writer.gotExpectedOutput);
229 }

## ◆ TEST_F() [21/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | CanToggleAccessibility |
| ) |  |

Definition at line 294 of file FlutterEngineTest.mm.

294 {
295 FlutterEngine* engine = GetFlutterEngine();
296 // Capture the update callbacks before the embedder API initializes.
297 auto original_init = engine.embedderAPI.Initialize;
298 std::function<void(const FlutterSemanticsUpdate2*, void*)> update_semantics_callback;
299 engine.embedderAPI.Initialize = MOCK_ENGINE_PROC(
300 Initialize, ([&update_semantics_callback, &original_init](
301 size_t version, const FlutterRendererConfig* config,
302 const FlutterProjectArgs* args, void* user_data, auto engine_out) {
303 update_semantics_callback = args->update_semantics_callback2;
304 return original_init(version, config, args, user_data, engine_out);
305 }));
306 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
307 // Set up view controller.
308 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
309 nibName:nil
310 bundle:nil];
311 [viewController loadView];
312 // Enable the semantics.
313 bool enabled_called = false;
314 engine.embedderAPI.UpdateSemanticsEnabled =
315 MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&enabled_called](auto engine, bool enabled) {
316 enabled_called = enabled;
317 return kSuccess;
318 }));
319 engine.semanticsEnabled = YES;
320 EXPECT_TRUE(enabled_called);
321 // Send flutter semantics updates.
322 FlutterSemanticsNode2 root;
323 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
324 FlutterSemanticsFlags child_flags = FlutterSemanticsFlags{0};
325 root.id = 0;
326 root.flags2 = &flags;
327 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
328 root.actions = static_cast<FlutterSemanticsAction>(0);
329 root.text_selection_base = -1;
330 root.text_selection_extent = -1;
331 root.label = "root";
332 root.hint = "";
333 root.value = "";
334 root.increased_value = "";
335 root.decreased_value = "";
336 root.tooltip = "";
337 root.child_count = 1;
338 int32_t children[] = {1};
339 root.children_in_traversal_order = children;
340 root.custom_accessibility_actions_count = 0;
341 root.identifier = "";
342
343 FlutterSemanticsNode2 child1;
344 child1.id = 1;
345 child1.flags2 = &child_flags;
346 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
347 child1.actions = static_cast<FlutterSemanticsAction>(0);
348 child1.text_selection_base = -1;
349 child1.text_selection_extent = -1;
350 child1.label = "child 1";
351 child1.hint = "";
352 child1.value = "";
353 child1.increased_value = "";
354 child1.decreased_value = "";
355 child1.tooltip = "";
356 child1.child_count = 0;
357 child1.custom_accessibility_actions_count = 0;
358 child1.identifier = "";
359
360 FlutterSemanticsUpdate2 update;
361 update.node_count = 2;
362 FlutterSemanticsNode2* nodes[] = {&root, &child1};
363 update.nodes = nodes;
364 update.custom_action_count = 0;
365 update_semantics_callback(&update, (__bridge void*)engine);
366
367 // Verify the accessibility tree is attached to the flutter view.
368 EXPECT_EQ([engine.viewController.flutterView.accessibilityChildren count], 1u);
369 NSAccessibilityElement* native_root = engine.viewController.flutterView.accessibilityChildren[0];
370 std::string root_label = [native_root.accessibilityLabel UTF8String];
371 EXPECT_TRUE(root_label == "root");
372 EXPECT_EQ(native_root.accessibilityRole, NSAccessibilityGroupRole);
373 EXPECT_EQ([native_root.accessibilityChildren count], 1u);
374 NSAccessibilityElement* native_child1 = native_root.accessibilityChildren[0];
375 std::string child1_value = [native_child1.accessibilityValue UTF8String];
376 EXPECT_TRUE(child1_value == "child 1");
377 EXPECT_EQ(native_child1.accessibilityRole, NSAccessibilityStaticTextRole);
378 EXPECT_EQ([native_child1.accessibilityChildren count], 0u);
379 // Disable the semantics.
380 bool semanticsEnabled = true;
381 engine.embedderAPI.UpdateSemanticsEnabled =
382 MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&semanticsEnabled](auto engine, bool enabled) {
383 semanticsEnabled = enabled;
384 return kSuccess;
385 }));
386 engine.semanticsEnabled = NO;
387 EXPECT_FALSE(semanticsEnabled);
388 // Verify the accessibility tree is removed from the view.
389 EXPECT_EQ([engine.viewController.flutterView.accessibilityChildren count], 0u);
390
391 [engine setViewController:nil];
392 }
FlutterEngine::viewController
FlutterViewController * viewController
Definition: FlutterEngine.h:87
user_data
void * user_data
Definition: texture_registrar_unittests.cc:27

References user_data, and FlutterEngine::viewController.

## ◆ TEST_F() [22/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | CanToggleAccessibilityWhenHeadless |
| ) |  |

Definition at line 394 of file FlutterEngineTest.mm.

394 {
395 FlutterEngine* engine = GetFlutterEngine();
396 // Capture the update callbacks before the embedder API initializes.
397 auto original_init = engine.embedderAPI.Initialize;
398 std::function<void(const FlutterSemanticsUpdate2*, void*)> update_semantics_callback;
399 engine.embedderAPI.Initialize = MOCK_ENGINE_PROC(
400 Initialize, ([&update_semantics_callback, &original_init](
401 size_t version, const FlutterRendererConfig* config,
402 const FlutterProjectArgs* args, void* user_data, auto engine_out) {
403 update_semantics_callback = args->update_semantics_callback2;
404 return original_init(version, config, args, user_data, engine_out);
405 }));
406 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
407
408 // Enable the semantics without attaching a view controller.
409 bool enabled_called = false;
410 engine.embedderAPI.UpdateSemanticsEnabled =
411 MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&enabled_called](auto engine, bool enabled) {
412 enabled_called = enabled;
413 return kSuccess;
414 }));
415 engine.semanticsEnabled = YES;
416 EXPECT_TRUE(enabled_called);
417 // Send flutter semantics updates.
418 FlutterSemanticsNode2 root;
419 FlutterSemanticsFlags flags = FlutterSemanticsFlags{0};
420 FlutterSemanticsFlags child_flags = FlutterSemanticsFlags{0};
421 root.id = 0;
422 root.flags2 = &flags;
423 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
424 root.actions = static_cast<FlutterSemanticsAction>(0);
425 root.text_selection_base = -1;
426 root.text_selection_extent = -1;
427 root.label = "root";
428 root.hint = "";
429 root.value = "";
430 root.increased_value = "";
431 root.decreased_value = "";
432 root.tooltip = "";
433 root.child_count = 1;
434 int32_t children[] = {1};
435 root.children_in_traversal_order = children;
436 root.custom_accessibility_actions_count = 0;
437
438 FlutterSemanticsNode2 child1;
439 child1.id = 1;
440 child1.flags2 = &child_flags;
441 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
442 child1.actions = static_cast<FlutterSemanticsAction>(0);
443 child1.text_selection_base = -1;
444 child1.text_selection_extent = -1;
445 child1.label = "child 1";
446 child1.hint = "";
447 child1.value = "";
448 child1.increased_value = "";
449 child1.decreased_value = "";
450 child1.tooltip = "";
451 child1.child_count = 0;
452 child1.custom_accessibility_actions_count = 0;
453
454 FlutterSemanticsUpdate2 update;
455 update.node_count = 2;
456 FlutterSemanticsNode2* nodes[] = {&root, &child1};
457 update.nodes = nodes;
458 update.custom_action_count = 0;
459 // This call updates semantics for the implicit view, which does not exist,
460 // and therefore this call is invalid. But the engine should not crash.
461 update_semantics_callback(&update, (__bridge void*)engine);
462
463 // No crashes.
464 EXPECT_EQ(engine.viewController, nil);
465
466 // Disable the semantics.
467 bool semanticsEnabled = true;
468 engine.embedderAPI.UpdateSemanticsEnabled =
469 MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&semanticsEnabled](auto engine, bool enabled) {
470 semanticsEnabled = enabled;
471 return kSuccess;
472 }));
473 engine.semanticsEnabled = NO;
474 EXPECT_FALSE(semanticsEnabled);
475 // Still no crashes
476 EXPECT_EQ(engine.viewController, nil);
477 }

References user_data, and FlutterEngine::viewController.

## ◆ TEST_F() [23/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | Compositor |
| ) |  |

Definition at line 519 of file FlutterEngineTest.mm.

519 {
520 NSString* fixtures = @(flutter::testing::GetFixturesPath());
521 FlutterDartProject* project = [[FlutterDartProject alloc]
522 initWithAssetsPath:fixtures
523 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
524 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:project];
525
526 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
527 nibName:nil
528 bundle:nil];
529 [viewController loadView];
530 [viewController viewDidLoad];
531 viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);
532
533 EXPECT_TRUE([engine runWithEntrypoint:@"canCompositePlatformViews"]);
534
535 [engine.platformViewController registerViewFactory:[[TestPlatformViewFactory alloc] init]
536 withId:@"factory_id"];
537 [engine.platformViewController
538 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create"
539 arguments:@{
540 @"id" : @(42),
541 @"viewType" : @"factory_id",
542 }]
543 result:^(id result){
544 }];
545
546 // Wait up to 1 second for Flutter to emit a frame.
547 CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
548 CALayer* rootLayer = viewController.flutterView.layer;
549 while (rootLayer.sublayers.count == 0) {
550 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
551 if (CFAbsoluteTimeGetCurrent() - start > 1) {
552 break;
553 }
554 }
555
556 // There are two layers with Flutter contents and one view
557 EXPECT_EQ(rootLayer.sublayers.count, 2u);
558 EXPECT_EQ(viewController.flutterView.subviews.count, 1u);
559
560 // TODO(gw280): add support for screenshot tests in this test harness
561
562 [engine shutDownEngine];
563 }
TestPlatformViewFactory
Definition: FlutterEngineTest.mm:48

References FlutterMethodCall::methodCallWithMethodName:arguments:, and FlutterEngine::shutDownEngine.

## ◆ TEST_F() [24/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | CompositorIgnoresUnknownView |
| ) |  |

Definition at line 565 of file FlutterEngineTest.mm.

565 {
566 FlutterEngine* engine = GetFlutterEngine();
567 auto original_init = engine.embedderAPI.Initialize;
568 ::FlutterCompositor compositor;
569 engine.embedderAPI.Initialize = MOCK_ENGINE_PROC(
570 Initialize, ([&compositor, &original_init](
571 size_t version, const FlutterRendererConfig* config,
572 const FlutterProjectArgs* args, void* user_data, auto engine_out) {
573 compositor = *args->compositor;
574 return original_init(version, config, args, user_data, engine_out);
575 }));
576
577 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
578 nibName:nil
579 bundle:nil];
580 [viewController loadView];
581
582 EXPECT_TRUE([engine runWithEntrypoint:@"empty"]);
583
584 FlutterBackingStoreConfig config = {
585 .struct_size = sizeof(FlutterBackingStoreConfig),
586 .size = FlutterSize{10, 10},
587 };
588 FlutterBackingStore backing_store = {};
589 EXPECT_NE(compositor.create_backing_store_callback, nullptr);
590 EXPECT_TRUE(
591 compositor.create_backing_store_callback(&config, &backing_store, compositor.user_data));
592
593 FlutterLayer layer{
594 .type = kFlutterLayerContentTypeBackingStore,
595 .backing_store = &backing_store,
596 };
597 std::vector<FlutterLayer*> layers = {&layer};
598
599 FlutterPresentViewInfo info = {
600 .struct_size = sizeof(FlutterPresentViewInfo),
601 .view_id = 123,
602 .layers = const_cast<const FlutterLayer**>(layers.data()),
603 .layers_count = 1,
604 .user_data = compositor.user_data,
605 };
606 EXPECT_NE(compositor.present_view_callback, nullptr);
607 EXPECT_FALSE(compositor.present_view_callback(&info));
608 EXPECT_TRUE(compositor.collect_backing_store_callback(&backing_store, compositor.user_data));
609
610 (void)viewController;
611 [engine shutDownEngine];
612 }

References FlutterEngine::shutDownEngine, and user_data.

## ◆ TEST_F() [25/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | DartEntrypointArguments |
| ) |  |

Definition at line 614 of file FlutterEngineTest.mm.

614 {
615 NSString* fixtures = @(flutter::testing::GetFixturesPath());
616 FlutterDartProject* project = [[FlutterDartProject alloc]
617 initWithAssetsPath:fixtures
618 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
619
620 project.dartEntrypointArguments = @[ @"arg1", @"arg2" ];
621 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:project];
622
623 bool called = false;
624 auto original_init = engine.embedderAPI.Initialize;
625 engine.embedderAPI.Initialize = MOCK_ENGINE_PROC(
626 Initialize, ([&called, &original_init](size_t version, const FlutterRendererConfig* config,
627 const FlutterProjectArgs* args, void* user_data,
628 FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
629 called = true;
630 EXPECT_EQ(args->dart_entrypoint_argc, 2);
631 NSString* arg1 = [[NSString alloc] initWithCString:args->dart_entrypoint_argv[0]
632 encoding:NSUTF8StringEncoding];
633 NSString* arg2 = [[NSString alloc] initWithCString:args->dart_entrypoint_argv[1]
634 encoding:NSUTF8StringEncoding];
635
636 EXPECT_TRUE([arg1 isEqualToString:@"arg1"]);
637 EXPECT_TRUE([arg2 isEqualToString:@"arg2"]);
638
639 return original_init(version, config, args, user_data, engine_out);
640 }));
641
642 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
643 EXPECT_TRUE(called);
644 [engine shutDownEngine];
645 }

References FlutterEngine::shutDownEngine, and user_data.

## ◆ TEST_F() [26/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | DISABLED_BackgroundIsBlack |
| ) |  |

Definition at line 231 of file FlutterEngineTest.mm.

231 {
232 FlutterEngine* engine = GetFlutterEngine();
233
234 // Latch to ensure the entire layer tree has been generated and presented.
235 BOOL signaled = NO;
236 AddNativeCallback("SignalNativeTest", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
237 CALayer* rootLayer = engine.viewController.flutterView.layer;
238 EXPECT_TRUE(rootLayer.backgroundColor != nil);
239 if (rootLayer.backgroundColor != nil) {
240 NSColor* actualBackgroundColor =
241 [NSColor colorWithCGColor:rootLayer.backgroundColor];
242 EXPECT_EQ(actualBackgroundColor, [NSColor blackColor]);
243 }
244 signaled = YES;
245 }));
246
247 // Launch the test entrypoint.
248 EXPECT_TRUE([engine runWithEntrypoint:@"backgroundTest"]);
249 ASSERT_TRUE(engine.running);
250
251 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
252 nibName:nil
253 bundle:nil];
254 [viewController loadView];
255 viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);
256
257 while (!signaled) {
258 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
259 }
260 }

References FlutterEngine::viewController.

## ◆ TEST_F() [27/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | DISABLED_CanOverrideBackgroundColor |
| ) |  |

Definition at line 262 of file FlutterEngineTest.mm.

262 {
263 FlutterEngine* engine = GetFlutterEngine();
264
265 // Latch to ensure the entire layer tree has been generated and presented.
266 BOOL signaled = NO;
267 AddNativeCallback("SignalNativeTest", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
268 CALayer* rootLayer = engine.viewController.flutterView.layer;
269 EXPECT_TRUE(rootLayer.backgroundColor != nil);
270 if (rootLayer.backgroundColor != nil) {
271 NSColor* actualBackgroundColor =
272 [NSColor colorWithCGColor:rootLayer.backgroundColor];
273 EXPECT_EQ(actualBackgroundColor, [NSColor whiteColor]);
274 }
275 signaled = YES;
276 }));
277
278 // Launch the test entrypoint.
279 EXPECT_TRUE([engine runWithEntrypoint:@"backgroundTest"]);
280 ASSERT_TRUE(engine.running);
281
282 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
283 nibName:nil
284 bundle:nil];
285 [viewController loadView];
286 viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);
287 viewController.flutterView.backgroundColor = [NSColor whiteColor];
288
289 while (!signaled) {
290 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
291 }
292 }
FlutterViewController::backgroundColor
NSColor * backgroundColor
Definition: FlutterViewController.h:210

References FlutterViewController::backgroundColor, and FlutterEngine::viewController.

## ◆ TEST_F() [28/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | DisplaySizeIsInPhysicalPixel |
| ) |  |

Definition at line 1317 of file FlutterEngineTest.mm.

1317 {
1318 NSString* fixtures = @(testing::GetFixturesPath());
1319 FlutterDartProject* project = [[FlutterDartProject alloc]
1320 initWithAssetsPath:fixtures
1321 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
1322 project.rootIsolateCreateCallback = FlutterEngineTest::IsolateCreateCallback;
1323 MockableFlutterEngine* engine = [[MockableFlutterEngine alloc] initWithName:@"foobar"
1324 project:project
1325 allowHeadlessExecution:true];
1326 BOOL updated = NO;
1327 auto original_update_displays = engine.embedderAPI.NotifyDisplayUpdate;
1328 engine.embedderAPI.NotifyDisplayUpdate = MOCK_ENGINE_PROC(
1329 NotifyDisplayUpdate, ([&updated, &original_update_displays](
1330 auto engine, auto update_type, auto* displays, auto display_count) {
1331 EXPECT_EQ(display_count, 1UL);
1332 EXPECT_EQ(displays->display_id, 10UL);
1333 EXPECT_EQ(displays->width, 60UL);
1334 EXPECT_EQ(displays->height, 80UL);
1335 EXPECT_EQ(displays->device_pixel_ratio, 2UL);
1336 updated = YES;
1337 return original_update_displays(engine, update_type, displays, display_count);
1338 }));
1339 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
1340 EXPECT_TRUE(updated);
1341 [engine shutDownEngine];
1342 engine = nil;
1343 }
MockableFlutterEngine
Definition: FlutterEngineTest.mm:124

References FlutterEngine::shutDownEngine.

## ◆ TEST_F() [29/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | FlutterBinaryMessengerDoesNotRetainEngine |
| ) |  |

Definition at line 653 of file FlutterEngineTest.mm.

653 {
654 __weak FlutterEngine* weakEngine;
655 id<FlutterBinaryMessenger> binaryMessenger = nil;
656 @autoreleasepool {
657 // Create a test engine.
658 NSString* fixtures = @(flutter::testing::GetFixturesPath());
659 FlutterDartProject* project = [[FlutterDartProject alloc]
660 initWithAssetsPath:fixtures
661 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
662 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
663 project:project
664 allowHeadlessExecution:YES];
665 weakEngine = engine;
666 binaryMessenger = engine.binaryMessenger;
667 }
668
669 // Once the engine has been deallocated, verify the weak engine pointer is nil, and thus not
670 // retained by the relay.
671 EXPECT_NE(binaryMessenger, nil);
672 EXPECT_EQ(weakEngine, nil);
673 }
FlutterEngine::binaryMessenger
id< FlutterBinaryMessenger > binaryMessenger
Definition: FlutterEngine.h:92

References FlutterEngine::binaryMessenger.

## ◆ TEST_F() [30/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | FlutterTextureRegistryDoesNotReturnEngine |
| ) |  |

Definition at line 677 of file FlutterEngineTest.mm.

677 {
678 __weak FlutterEngine* weakEngine;
679 id<FlutterTextureRegistry> textureRegistry;
680 @autoreleasepool {
681 // Create a test engine.
682 NSString* fixtures = @(flutter::testing::GetFixturesPath());
683 FlutterDartProject* project = [[FlutterDartProject alloc]
684 initWithAssetsPath:fixtures
685 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
686 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
687 project:project
688 allowHeadlessExecution:YES];
689 id<FlutterPluginRegistrar> registrar = [engine registrarForPlugin:@"MyPlugin"];
690 textureRegistry = registrar.textures;
691 }
692
693 // Once the engine has been deallocated, verify the weak engine pointer is nil, and thus not
694 // retained via the texture registry.
695 EXPECT_NE(textureRegistry, nil);
696 EXPECT_EQ(weakEngine, nil);
697 }

## ◆ TEST_F() [31/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | ForwardsPluginDelegateRegistration |
| ) |  |

Definition at line 1230 of file FlutterEngineTest.mm.

1230 {
1231 id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
1232 FakeLifecycleProvider* fakeAppDelegate = [[FakeLifecycleProvider alloc] init];
1233 [NSApplication sharedApplication].delegate = fakeAppDelegate;
1234
1235 FakeAppDelegatePlugin* plugin = [[FakeAppDelegatePlugin alloc] init];
1236 FlutterEngine* engine = CreateMockFlutterEngine(nil);
1237
1238 [[engine registrarForPlugin:@"TestPlugin"] addApplicationDelegate:plugin];
1239
1240 EXPECT_TRUE([fakeAppDelegate hasDelegate:plugin]);
1241
1242 [NSApplication sharedApplication].delegate = previousDelegate;
1243 }
FakeAppDelegatePlugin
Definition: FlutterEngineTest.mm:113
FakeLifecycleProvider
Definition: FlutterEngineTest.mm:71

References CreateMockFlutterEngine().

## ◆ TEST_F() [32/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | HandleAccessibilityEvent |
| ) |  |

Definition at line 1136 of file FlutterEngineTest.mm.

1136 {
1137 __block BOOL announced = NO;
1138 id engineMock = CreateMockFlutterEngine(nil);
1139
1140 OCMStub([engineMock announceAccessibilityMessage:[OCMArg any]
1141 withPriority:NSAccessibilityPriorityMedium])
1142 .andDo((^(NSInvocation* invocation) {
1143 announced = TRUE;
1144 [invocation retainArguments];
1145 NSString* message;
1146 [invocation getArgument:&message atIndex:2];
1147 EXPECT_EQ(message, @"error message");
1148 }));
1149
1150 NSDictionary<NSString*, id>* annotatedEvent =
1151 @{@"type" : @"announce",
1152 @"data" : @{@"message" : @"error message"}};
1153
1154 [engineMock handleAccessibilityEvent:annotatedEvent];
1155
1156 EXPECT_TRUE(announced);
1157 }

References CreateMockFlutterEngine().

## ◆ TEST_F() [33/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | HandleLifecycleStates |
| ) |  |

Definition at line 1159 of file FlutterEngineTest.mm.

1159 {
1160 __block flutter::AppLifecycleState sentState;
1161 id engineMock = CreateMockFlutterEngine(nil);
1162
1163 // Have to enumerate all the values because OCMStub can't capture
1164 // non-Objective-C object arguments.
1165 OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kDetached])
1166 .andDo((^(NSInvocation* invocation) {
1167 sentState = flutter::AppLifecycleState::kDetached;
1168 }));
1169 OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kResumed])
1170 .andDo((^(NSInvocation* invocation) {
1171 sentState = flutter::AppLifecycleState::kResumed;
1172 }));
1173 OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kInactive])
1174 .andDo((^(NSInvocation* invocation) {
1175 sentState = flutter::AppLifecycleState::kInactive;
1176 }));
1177 OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kHidden])
1178 .andDo((^(NSInvocation* invocation) {
1179 sentState = flutter::AppLifecycleState::kHidden;
1180 }));
1181 OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kPaused])
1182 .andDo((^(NSInvocation* invocation) {
1183 sentState = flutter::AppLifecycleState::kPaused;
1184 }));
1185
1186 __block NSApplicationOcclusionState visibility = NSApplicationOcclusionStateVisible;
1187 id mockApplication = OCMPartialMock([NSApplication sharedApplication]);
1188 OCMStub((NSApplicationOcclusionState)[mockApplication occlusionState])
1189 .andDo(^(NSInvocation* invocation) {
1190 [invocation setReturnValue:&visibility];
1191 });
1192
1193 NSNotification* willBecomeActive =
1194 [[NSNotification alloc] initWithName:NSApplicationWillBecomeActiveNotification
1195 object:nil
1196 userInfo:nil];
1197 NSNotification* willResignActive =
1198 [[NSNotification alloc] initWithName:NSApplicationWillResignActiveNotification
1199 object:nil
1200 userInfo:nil];
1201
1202 NSNotification* didChangeOcclusionState;
1203 didChangeOcclusionState =
1204 [[NSNotification alloc] initWithName:NSApplicationDidChangeOcclusionStateNotification
1205 object:nil
1206 userInfo:nil];
1207
1208 [engineMock handleDidChangeOcclusionState:didChangeOcclusionState];
1209 EXPECT_EQ(sentState, flutter::AppLifecycleState::kInactive);
1210
1211 [engineMock handleWillBecomeActive:willBecomeActive];
1212 EXPECT_EQ(sentState, flutter::AppLifecycleState::kResumed);
1213
1214 [engineMock handleWillResignActive:willResignActive];
1215 EXPECT_EQ(sentState, flutter::AppLifecycleState::kInactive);
1216
1217 visibility = 0;
1218 [engineMock handleDidChangeOcclusionState:didChangeOcclusionState];
1219 EXPECT_EQ(sentState, flutter::AppLifecycleState::kHidden);
1220
1221 [engineMock handleWillBecomeActive:willBecomeActive];
1222 EXPECT_EQ(sentState, flutter::AppLifecycleState::kHidden);
1223
1224 [engineMock handleWillResignActive:willResignActive];
1225 EXPECT_EQ(sentState, flutter::AppLifecycleState::kHidden);
1226
1227 [mockApplication stopMocking];
1228 }
flutter::AppLifecycleState
AppLifecycleState
Definition: app_lifecycle_state.h:32
flutter::AppLifecycleState::kPaused
@ kPaused
flutter::AppLifecycleState::kDetached
@ kDetached
flutter::AppLifecycleState::kHidden
@ kHidden
flutter::AppLifecycleState::kResumed
@ kResumed
flutter::AppLifecycleState::kInactive
@ kInactive

References CreateMockFlutterEngine(), flutter::kDetached, flutter::kHidden, flutter::kInactive, flutter::kPaused, and flutter::kResumed.

## ◆ TEST_F() [34/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | HandlesTerminationRequest |
| ) |  |

Definition at line 1042 of file FlutterEngineTest.mm.

1042 {
1043 id engineMock = CreateMockFlutterEngine(nil);
1044 __block NSString* nextResponse = @"exit";
1045 __block BOOL triedToTerminate = NO;
1046 FlutterEngineTerminationHandler* terminationHandler =
1047 [[FlutterEngineTerminationHandler alloc] initWithEngine:engineMock
1048 terminator:^(id sender) {
1049 triedToTerminate = TRUE;
1050 // Don't actually terminate, of course.
1051 }];
1052 OCMStub([engineMock terminationHandler]).andReturn(terminationHandler);
1053 id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
1054 OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
1055 [engineMock binaryMessenger])
1056 .andReturn(binaryMessengerMock);
1057 OCMStub([engineMock sendOnChannel:@"flutter/platform"
1058 message:[OCMArg any]
1059 binaryReply:[OCMArg any]])
1060 .andDo((^(NSInvocation* invocation) {
1061 [invocation retainArguments];
1062 FlutterBinaryReply callback;
1063 NSData* returnedMessage;
1064 [invocation getArgument:&callback atIndex:4];
1065 if ([nextResponse isEqualToString:@"error"]) {
1066 FlutterError* errorResponse = [FlutterError errorWithCode:@"Error"
1067 message:@"Failed"
1068 details:@"Details"];
1069 returnedMessage =
1070 [[FlutterJSONMethodCodec sharedInstance] encodeErrorEnvelope:errorResponse];
1071 } else {
1072 NSDictionary* responseDict = @{@"response" : nextResponse};
1073 returnedMessage =
1074 [[FlutterJSONMethodCodec sharedInstance] encodeSuccessEnvelope:responseDict];
1075 }
1076 callback(returnedMessage);
1077 }));
1078 __block NSString* calledAfterTerminate = @"";
1079 FlutterResult appExitResult = ^(id result) {
1080 NSDictionary* resultDict = result;
1081 calledAfterTerminate = resultDict[@"response"];
1082 };
1083 FlutterMethodCall* methodExitApplication =
1084 [FlutterMethodCall methodCallWithMethodName:@"System.exitApplication"
1085 arguments:@{@"type" : @"cancelable"}];
1086
1087 // Always terminate when the binding isn't ready (which is the default).
1088 triedToTerminate = NO;
1089 calledAfterTerminate = @"";
1090 nextResponse = @"cancel";
1091 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
1092 EXPECT_STREQ([calledAfterTerminate UTF8String], "");
1093 EXPECT_TRUE(triedToTerminate);
1094
1095 // Once the binding is ready, handle the request.
1096 terminationHandler.acceptingRequests = YES;
1097 triedToTerminate = NO;
1098 calledAfterTerminate = @"";
1099 nextResponse = @"exit";
1100 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
1101 EXPECT_STREQ([calledAfterTerminate UTF8String], "exit");
1102 EXPECT_TRUE(triedToTerminate);
1103
1104 triedToTerminate = NO;
1105 calledAfterTerminate = @"";
1106 nextResponse = @"cancel";
1107 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
1108 EXPECT_STREQ([calledAfterTerminate UTF8String], "cancel");
1109 EXPECT_FALSE(triedToTerminate);
1110
1111 // Check that it doesn't crash on error.
1112 triedToTerminate = NO;
1113 calledAfterTerminate = @"";
1114 nextResponse = @"error";
1115 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
1116 EXPECT_STREQ([calledAfterTerminate UTF8String], "");
1117 EXPECT_TRUE(triedToTerminate);
1118 }
FlutterBinaryReply
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterBinaryReply)(NSData *_Nullable reply)
FlutterEngineTerminationHandler
Definition: FlutterEngine.mm:194
FlutterEngineTerminationHandler::acceptingRequests
BOOL acceptingRequests
Definition: FlutterEngine_Internal.h:63
+[FlutterError errorWithCode:message:details:]
instancetype errorWithCode:message:details:(NSString *code,[message] NSString *_Nullable message,[details] id _Nullable details)
FlutterJSONMethodCodec
Definition: FlutterCodecs.h:455

References FlutterEngineTerminationHandler::acceptingRequests, CreateMockFlutterEngine(), FlutterError::errorWithCode:message:details:, FlutterBinaryReply, and FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST_F() [35/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | HasNonNullExecutableName |
| ) |  |

Definition at line 148 of file FlutterEngineTest.mm.

148 {
149 FlutterEngine* engine = GetFlutterEngine();
150 std::string executable_name = [[engine executableName] UTF8String];
151 ASSERT_FALSE(executable_name.empty());
152
153 // Block until notified by the Dart test of the value of Platform.executable.
154 BOOL signaled = NO;
155 AddNativeCallback("NotifyStringValue", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
156 const auto dart_string = tonic::DartConverter<std::string>::FromDart(
157 Dart_GetNativeArgument(args, 0));
158 EXPECT_EQ(executable_name, dart_string);
159 signaled = YES;
160 }));
161
162 // Launch the test entrypoint.
163 EXPECT_TRUE([engine runWithEntrypoint:@"executableNameNotNull"]);
164
165 while (!signaled) {
166 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
167 }
168 }

## ◆ TEST_F() [36/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | HasStringsWhenPasteboardEmpty |
| ) |  |

Definition at line 827 of file FlutterEngineTest.mm.

827 {
828 id engineMock = CreateMockFlutterEngine(nil);
829
830 // Call hasStrings and expect it to be false.
831 __block bool calledAfterClear = false;
832 __block bool valueAfterClear;
833 FlutterResult resultAfterClear = ^(id result) {
834 calledAfterClear = true;
835 NSNumber* valueNumber = [result valueForKey:@"value"];
836 valueAfterClear = [valueNumber boolValue];
837 };
838 FlutterMethodCall* methodCallAfterClear =
839 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.hasStrings" arguments:nil];
840 [engineMock handleMethodCall:methodCallAfterClear result:resultAfterClear];
841 EXPECT_TRUE(calledAfterClear);
842 EXPECT_FALSE(valueAfterClear);
843 }

References CreateMockFlutterEngine(), and FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST_F() [37/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | HasStringsWhenPasteboardFull |
| ) |  |

Definition at line 845 of file FlutterEngineTest.mm.

845 {
846 id engineMock = CreateMockFlutterEngine(@"some string");
847
848 // Call hasStrings and expect it to be true.
849 __block bool called = false;
850 __block bool value;
851 FlutterResult result = ^(id result) {
852 called = true;
853 NSNumber* valueNumber = [result valueForKey:@"value"];
854 value = [valueNumber boolValue];
855 };
856 FlutterMethodCall* methodCall =
857 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.hasStrings" arguments:nil];
858 [engineMock handleMethodCall:methodCall result:result];
859 EXPECT_TRUE(called);
860 EXPECT_TRUE(value);
861 }

References CreateMockFlutterEngine(), and FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST_F() [38/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | IgnoresTerminationRequestIfNotFlutterAppDelegate |
| ) |  |

Definition at line 1120 of file FlutterEngineTest.mm.

1120 {
1121 id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
1122 id<NSApplicationDelegate> plainDelegate = [[PlainAppDelegate alloc] init];
1123 [NSApplication sharedApplication].delegate = plainDelegate;
1124
1125 // Creating the engine shouldn't fail here, even though the delegate isn't a
1126 // FlutterAppDelegate.
1127 CreateMockFlutterEngine(nil);
1128
1129 // Asking to terminate the app should cancel.
1130 EXPECT_EQ([[[NSApplication sharedApplication] delegate] applicationShouldTerminate:NSApp],
1131 NSTerminateCancel);
1132
1133 [NSApplication sharedApplication].delegate = previousDelegate;
1134 }
PlainAppDelegate
Definition: FlutterEngineTest.mm:59

References CreateMockFlutterEngine().

## ◆ TEST_F() [39/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | ManageControllersIfInitiatedByController |
| ) |  |

Definition at line 946 of file FlutterEngineTest.mm.

946 {
947 NSString* fixtures = @(flutter::testing::GetFixturesPath());
948 FlutterDartProject* project = [[FlutterDartProject alloc]
949 initWithAssetsPath:fixtures
950 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
951
952 FlutterEngine* engine;
953 FlutterViewController* viewController1;
954
955 @autoreleasepool {
956 // Create FVC1.
957 viewController1 = [[FlutterViewController alloc] initWithProject:project];
958 EXPECT_EQ(viewController1.viewIdentifier, 0ll);
959
960 engine = viewController1.engine;
961 engine.viewController = nil;
962
963 // Create FVC2 based on the same engine.
964 FlutterViewController* viewController2 = [[FlutterViewController alloc] initWithEngine:engine
965 nibName:nil
966 bundle:nil];
967 EXPECT_EQ(engine.viewController, viewController2);
968 }
969 // FVC2 is deallocated but FVC1 is retained.
970
971 EXPECT_EQ(engine.viewController, nil);
972
973 engine.viewController = viewController1;
974 EXPECT_EQ(engine.viewController, viewController1);
975 EXPECT_EQ(viewController1.viewIdentifier, 0ll);
976 }
FlutterViewController::viewIdentifier
FlutterViewIdentifier viewIdentifier
Definition: FlutterViewController.h:130

References FlutterViewController::engine, FlutterEngine::viewController, and FlutterViewController::viewIdentifier.

## ◆ TEST_F() [40/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | ManageControllersIfInitiatedByEngine |
| ) |  |

Definition at line 978 of file FlutterEngineTest.mm.

978 {
979 // Don't create the engine with `CreateMockFlutterEngine`, because it adds
980 // additional references to FlutterViewControllers, which is crucial to this
981 // test case.
982 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"io.flutter"
983 project:nil
984 allowHeadlessExecution:NO];
985 FlutterViewController* viewController1;
986
987 @autoreleasepool {
988 viewController1 = [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
989 EXPECT_EQ(viewController1.viewIdentifier, 0ll);
990 EXPECT_EQ(engine.viewController, viewController1);
991
992 engine.viewController = nil;
993
994 FlutterViewController* viewController2 = [[FlutterViewController alloc] initWithEngine:engine
995 nibName:nil
996 bundle:nil];
997 EXPECT_EQ(viewController2.viewIdentifier, 0ll);
998 EXPECT_EQ(engine.viewController, viewController2);
999 }
1000 // FVC2 is deallocated but FVC1 is retained.
1001
1002 EXPECT_EQ(engine.viewController, nil);
1003
1004 engine.viewController = viewController1;
1005 EXPECT_EQ(engine.viewController, viewController1);
1006 EXPECT_EQ(viewController1.viewIdentifier, 0ll);
1007 }

References FlutterEngine::viewController, and FlutterViewController::viewIdentifier.

## ◆ TEST_F() [41/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | MessengerCleanupConnectionWorks |
| ) |  |

Definition at line 770 of file FlutterEngineTest.mm.

770 {
771 FlutterEngine* engine = GetFlutterEngine();
772 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
773
774 NSString* channel = @"_test_";
775 NSData* channel_data = [channel dataUsingEncoding:NSUTF8StringEncoding];
776
777 // Mock SendPlatformMessage so that if a message is sent to
778 // "test/send_message", act as if the framework has sent an empty message to
779 // the channel marked by the `sendOnChannel:message:` call's message.
780 engine.embedderAPI.SendPlatformMessage = MOCK_ENGINE_PROC(
781 SendPlatformMessage, ([](auto engine_, auto message_) {
782 if (strcmp(message_->channel, "test/send_message") == 0) {
783 // The simplest message that is acceptable to a method channel.
784 std::string message = R"|({"method": "a"})|";
785 std::string channel(reinterpret_cast<const char*>(message_->message),
786 message_->message_size);
787 reinterpret_cast<EmbedderEngine*>(engine_)
788 ->GetShell()
789 .GetPlatformView()
790 ->HandlePlatformMessage(std::make_unique<PlatformMessage>(
791 channel.c_str(), fml::MallocMapping::Copy(message.c_str(), message.length()),
792 fml::RefPtr<PlatformMessageResponse>()));
793 }
794 return kSuccess;
795 }));
796
797 __block int record = 0;
798
799 FlutterMethodChannel* channel1 =
800 [FlutterMethodChannel methodChannelWithName:channel
801 binaryMessenger:engine.binaryMessenger
802 codec:[FlutterJSONMethodCodec sharedInstance]];
803 [channel1 setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
804 record += 1;
805 }];
806
807 [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
808 EXPECT_EQ(record, 1);
809
810 FlutterMethodChannel* channel2 =
811 [FlutterMethodChannel methodChannelWithName:channel
812 binaryMessenger:engine.binaryMessenger
813 codec:[FlutterJSONMethodCodec sharedInstance]];
814 [channel2 setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
815 record += 10;
816 }];
817
818 [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
819 EXPECT_EQ(record, 11);
820
821 [channel1 setMethodCallHandler:nil];
822
823 [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
824 EXPECT_EQ(record, 21);
825 }
FlutterMethodChannel
Definition: FlutterChannels.h:221
-[FlutterMethodChannel setMethodCallHandler:]
void setMethodCallHandler:(FlutterMethodCallHandler _Nullable handler)
+[FlutterMethodChannel methodChannelWithName:binaryMessenger:codec:]
instancetype methodChannelWithName:binaryMessenger:codec:(NSString *name,[binaryMessenger] NSObject< FlutterBinaryMessenger > *messenger,[codec] NSObject< FlutterMethodCodec > *codec)

References FlutterMethodChannel::methodChannelWithName:binaryMessenger:codec:, and FlutterMethodChannel::setMethodCallHandler:.

## ◆ TEST_F() [42/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | MessengerSend |
| ) |  |

Definition at line 188 of file FlutterEngineTest.mm.

188 {
189 FlutterEngine* engine = GetFlutterEngine();
190 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
191
192 NSData* test_message = [@"a message" dataUsingEncoding:NSUTF8StringEncoding];
193 bool called = false;
194
195 engine.embedderAPI.SendPlatformMessage = MOCK_ENGINE_PROC(
196 SendPlatformMessage, ([&called, test_message](auto engine, auto message) {
197 called = true;
198 EXPECT_STREQ(message->channel, "test");
199 EXPECT_EQ(memcmp(message->message, test_message.bytes, message->message_size), 0);
200 return kSuccess;
201 }));
202
203 [engine.binaryMessenger sendOnChannel:@"test" message:test_message];
204 EXPECT_TRUE(called);
205 }

## ◆ TEST_F() [43/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | NativeCallbacks |
| ) |  |

Definition at line 504 of file FlutterEngineTest.mm.

504 {
505 BOOL latch_called = NO;
506 AddNativeCallback("SignalNativeTest",
507 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { latch_called = YES; }));
508
509 FlutterEngine* engine = GetFlutterEngine();
510 EXPECT_TRUE([engine runWithEntrypoint:@"nativeCallback"]);
511 ASSERT_TRUE(engine.running);
512
513 while (!latch_called) {
514 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
515 }
516 ASSERT_TRUE(latch_called);
517 }

## ◆ TEST_F() [44/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | NotificationsUpdateDisplays |
| ) |  |

Definition at line 1287 of file FlutterEngineTest.mm.

1287 {
1288 BOOL updated = NO;
1289 FlutterEngine* engine = GetFlutterEngine();
1290 auto original_set_viewport_metrics = engine.embedderAPI.SendWindowMetricsEvent;
1291 engine.embedderAPI.SendWindowMetricsEvent = MOCK_ENGINE_PROC(
1292 SendWindowMetricsEvent,
1293 ([&updated, &original_set_viewport_metrics](auto engine, auto* window_metrics) {
1294 updated = YES;
1295 return original_set_viewport_metrics(engine, window_metrics);
1296 }));
1297
1298 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
1299
1300 updated = NO;
1301 [[NSNotificationCenter defaultCenter] postNotificationName:NSWindowDidChangeScreenNotification
1302 object:nil];
1303 // No VC.
1304 EXPECT_FALSE(updated);
1305
1306 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
1307 nibName:nil
1308 bundle:nil];
1309 [viewController loadView];
1310 viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);
1311
1312 [[NSNotificationCenter defaultCenter] postNotificationName:NSWindowDidChangeScreenNotification
1313 object:nil];
1314 EXPECT_TRUE(updated);
1315 }

## ◆ TEST_F() [45/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | ProducesAccessibilityTreeWhenAddingViews |
| ) |  |

Definition at line 479 of file FlutterEngineTest.mm.

479 {
480 FlutterEngine* engine = GetFlutterEngine();
481 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
482
483 // Enable the semantics without attaching a view controller.
484 bool enabled_called = false;
485 engine.embedderAPI.UpdateSemanticsEnabled =
486 MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&enabled_called](auto engine, bool enabled) {
487 enabled_called = enabled;
488 return kSuccess;
489 }));
490 engine.semanticsEnabled = YES;
491 EXPECT_TRUE(enabled_called);
492
493 EXPECT_EQ(engine.viewController, nil);
494
495 // Assign the view controller after enabling semantics
496 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
497 nibName:nil
498 bundle:nil];
499 engine.viewController = viewController;
500
501 EXPECT_NE(viewController.accessibilityBridge.lock(), nullptr);
502 }

References FlutterEngine::viewController.

## ◆ TEST_F() [46/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | PublishedValueNilForUnknownPlugin |
| ) |  |

Definition at line 699 of file FlutterEngineTest.mm.

699 {
700 NSString* fixtures = @(flutter::testing::GetFixturesPath());
701 FlutterDartProject* project = [[FlutterDartProject alloc]
702 initWithAssetsPath:fixtures
703 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
704 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
705 project:project
706 allowHeadlessExecution:YES];
707
708 EXPECT_EQ([engine valuePublishedByPlugin:@"NoSuchPlugin"], nil);
709 }

## ◆ TEST_F() [47/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | PublishedValueNSNullIfNoPublishedValue |
| ) |  |

Definition at line 711 of file FlutterEngineTest.mm.

711 {
712 NSString* fixtures = @(flutter::testing::GetFixturesPath());
713 FlutterDartProject* project = [[FlutterDartProject alloc]
714 initWithAssetsPath:fixtures
715 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
716 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
717 project:project
718 allowHeadlessExecution:YES];
719 NSString* pluginName = @"MyPlugin";
720 // Request the registarar to register the plugin as existing.
721 [engine registrarForPlugin:pluginName];
722
723 // The documented behavior is that a plugin that exists but hasn't published
724 // anything returns NSNull, rather than nil, as on iOS.
725 EXPECT_EQ([engine valuePublishedByPlugin:pluginName], [NSNull null]);
726 }

## ◆ TEST_F() [48/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | PublishedValueReturnsLastPublished |
| ) |  |

Definition at line 728 of file FlutterEngineTest.mm.

728 {
729 NSString* fixtures = @(flutter::testing::GetFixturesPath());
730 FlutterDartProject* project = [[FlutterDartProject alloc]
731 initWithAssetsPath:fixtures
732 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
733 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
734 project:project
735 allowHeadlessExecution:YES];
736 NSString* pluginName = @"MyPlugin";
737 id<FlutterPluginRegistrar> registrar = [engine registrarForPlugin:pluginName];
738
739 NSString* firstValue = @"A published value";
740 NSArray* secondValue = @[ @"A different published value" ];
741
742 [registrar publish:firstValue];
743 EXPECT_EQ([engine valuePublishedByPlugin:pluginName], firstValue);
744
745 [registrar publish:secondValue];
746 EXPECT_EQ([engine valuePublishedByPlugin:pluginName], secondValue);
747 }

## ◆ TEST_F() [49/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | RegistrarForwardViewControllerLookUpToEngine |
| ) |  |

Definition at line 749 of file FlutterEngineTest.mm.

749 {
750 NSString* fixtures = @(flutter::testing::GetFixturesPath());
751 FlutterDartProject* project = [[FlutterDartProject alloc]
752 initWithAssetsPath:fixtures
753 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
754 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:project];
755
756 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
757 nibName:nil
758 bundle:nil];
759 id<FlutterPluginRegistrar> registrar = [engine registrarForPlugin:@"MyPlugin"];
760
761 EXPECT_EQ([registrar viewController], viewController);
762 }

## ◆ TEST_F() [50/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | RemovingViewDisposesCompositorResources |
| ) |  |

Definition at line 1009 of file FlutterEngineTest.mm.

1009 {
1010 NSString* fixtures = @(flutter::testing::GetFixturesPath());
1011 FlutterDartProject* project = [[FlutterDartProject alloc]
1012 initWithAssetsPath:fixtures
1013 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
1014 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:project];
1015
1016 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
1017 nibName:nil
1018 bundle:nil];
1019 [viewController loadView];
1020 [viewController viewDidLoad];
1021 viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);
1022
1023 EXPECT_TRUE([engine runWithEntrypoint:@"drawIntoAllViews"]);
1024 // Wait up to 1 second for Flutter to emit a frame.
1025 CFTimeInterval start = CACurrentMediaTime();
1026 while (engine.macOSCompositor->DebugNumViews() == 0) {
1027 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, YES);
1028 if (CACurrentMediaTime() - start > 1) {
1029 break;
1030 }
1031 }
1032
1033 EXPECT_EQ(engine.macOSCompositor->DebugNumViews(), 1u);
1034
1035 engine.viewController = nil;
1036 EXPECT_EQ(engine.macOSCompositor->DebugNumViews(), 0u);
1037
1038 [engine shutDownEngine];
1039 engine = nil;
1040 }

References FlutterEngine::shutDownEngine, and FlutterEngine::viewController.

## ◆ TEST_F() [51/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | ReportsHourFormat |
| ) |  |

Definition at line 1345 of file FlutterEngineTest.mm.

1345 {
1346 __block BOOL expectedValue;
1347
1348 // Set up mocks.
1349 id channelMock = OCMClassMock([FlutterBasicMessageChannel class]);
1350 OCMStub([channelMock messageChannelWithName:@"flutter/settings"
1351 binaryMessenger:[OCMArg any]
1352 codec:[OCMArg any]])
1353 .andReturn(channelMock);
1354 OCMStub([channelMock sendMessage:[OCMArg any]]).andDo((^(NSInvocation* invocation) {
1355 __weak id message;
1356 [invocation getArgument:&message atIndex:2];
1357 EXPECT_EQ(message[@"alwaysUse24HourFormat"], @(expectedValue));
1358 }));
1359
1360 id mockHourFormat = OCMClassMock([FlutterHourFormat class]);
1361 OCMStub([mockHourFormat isAlwaysUse24HourFormat]).andDo((^(NSInvocation* invocation) {
1362 [invocation setReturnValue:&expectedValue];
1363 }));
1364
1365 id engineMock = CreateMockFlutterEngine(nil);
1366
1367 // Verify the YES case.
1368 expectedValue = YES;
1369 EXPECT_TRUE([engineMock runWithEntrypoint:@"main"]);
1370 [engineMock shutDownEngine];
1371
1372 // Verify the NO case.
1373 expectedValue = NO;
1374 EXPECT_TRUE([engineMock runWithEntrypoint:@"main"]);
1375 [engineMock shutDownEngine];
1376
1377 // Clean up mocks.
1378 [mockHourFormat stopMocking];
1379 [engineMock stopMocking];
1380 [channelMock stopMocking];
1381 }
FlutterBasicMessageChannel
Definition: FlutterChannels.h:38
FlutterHourFormat
Definition: FlutterHourFormat.h:11

References CreateMockFlutterEngine().

## ◆ TEST_F() [52/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | ResizeSynchronizerNotBlockingRasterThreadAfterShutdown |
| ) |  |

Definition at line 932 of file FlutterEngineTest.mm.

932 {
933 FlutterResizeSynchronizer* threadSynchronizer = [[FlutterResizeSynchronizer alloc] init];
934 [threadSynchronizer shutDown];
935
936 std::thread rasterThread([&threadSynchronizer] {
937 [threadSynchronizer performCommitForSize:CGSizeMake(100, 100)
938 afterDelay:0
939 notify:^{
940 }];
941 });
942
943 rasterThread.join();
944 }

## ◆ TEST_F() [53/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | ResponseAfterEngineDied |
| ) |  |

Definition at line 863 of file FlutterEngineTest.mm.

863 {
864 FlutterEngine* engine = GetFlutterEngine();
865 FlutterBasicMessageChannel* channel = [[FlutterBasicMessageChannel alloc]
866 initWithName:@"foo"
867 binaryMessenger:engine.binaryMessenger
868 codec:[FlutterStandardMessageCodec sharedInstance]];
869 __block BOOL didCallCallback = NO;
870 [channel setMessageHandler:^(id message, FlutterReply callback) {
871 ShutDownEngine();
872 callback(nil);
873 didCallCallback = YES;
874 }];
875 EXPECT_TRUE([engine runWithEntrypoint:@"sendFooMessage"]);
876 engine = nil;
877
878 while (!didCallCallback) {
879 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
880 }
881 }
-[FlutterBasicMessageChannel setMessageHandler:]
void setMessageHandler:(FlutterMessageHandler _Nullable handler)
FlutterStandardMessageCodec
Definition: FlutterCodecs.h:209
+[FlutterMessageCodec-p sharedInstance]
instancetype sharedInstance()

References FlutterBasicMessageChannel::setMessageHandler:, and <FlutterMessageCodec>::sharedInstance.

## ◆ TEST_F() [54/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | ResponseFromBackgroundThread |
| ) |  |

Definition at line 883 of file FlutterEngineTest.mm.

883 {
884 FlutterEngine* engine = GetFlutterEngine();
885 FlutterBasicMessageChannel* channel = [[FlutterBasicMessageChannel alloc]
886 initWithName:@"foo"
887 binaryMessenger:engine.binaryMessenger
888 codec:[FlutterStandardMessageCodec sharedInstance]];
889 __block BOOL didCallCallback = NO;
890 [channel setMessageHandler:^(id message, FlutterReply callback) {
891 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
892 callback(nil);
893 dispatch_async(dispatch_get_main_queue(), ^{
894 didCallCallback = YES;
895 });
896 });
897 }];
898 EXPECT_TRUE([engine runWithEntrypoint:@"sendFooMessage"]);
899
900 while (!didCallCallback) {
901 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
902 }
903 }

References FlutterBasicMessageChannel::setMessageHandler:, and <FlutterMessageCodec>::sharedInstance.

## ◆ TEST_F() [55/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | RunWithEntrypointUpdatesDisplayConfig |
| ) |  |

Definition at line 1266 of file FlutterEngineTest.mm.

1266 {
1267 BOOL updated = NO;
1268 FlutterEngine* engine = GetFlutterEngine();
1269 auto original_update_displays = engine.embedderAPI.NotifyDisplayUpdate;
1270 engine.embedderAPI.NotifyDisplayUpdate = MOCK_ENGINE_PROC(
1271 NotifyDisplayUpdate, ([&updated, &original_update_displays](
1272 auto engine, auto update_type, auto* displays, auto display_count) {
1273 updated = YES;
1274 return original_update_displays(engine, update_type, displays, display_count);
1275 }));
1276
1277 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
1278 EXPECT_TRUE(updated);
1279
1280 updated = NO;
1281 [[NSNotificationCenter defaultCenter]
1282 postNotificationName:NSApplicationDidChangeScreenParametersNotification
1283 object:nil];
1284 EXPECT_TRUE(updated);
1285 }

## ◆ TEST_F() [56/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | Switches |
| ) |  |

Definition at line 171 of file FlutterEngineTest.mm.

171 {
172 setenv("FLUTTER_ENGINE_SWITCHES", "2", 1);
173 setenv("FLUTTER_ENGINE_SWITCH_1", "abc", 1);
174 setenv("FLUTTER_ENGINE_SWITCH_2", "foo=\"bar, baz\"", 1);
175
176 FlutterEngine* engine = GetFlutterEngine();
177 std::vector<std::string> switches = engine.switches;
178 ASSERT_EQ(switches.size(), 2UL);
179 EXPECT_EQ(switches[0], "--abc");
180 EXPECT_EQ(switches[1], "--foo=\"bar, baz\"");
181
182 unsetenv("FLUTTER_ENGINE_SWITCHES");
183 unsetenv("FLUTTER_ENGINE_SWITCH_1");
184 unsetenv("FLUTTER_ENGINE_SWITCH_2");
185 }

## ◆ TEST_F() [57/83]

flutter::testing::TEST_F | ( | FlutterEngineTest | ,
|  | UnregistersPluginsOnEngineDestruction |
| ) |  |

Definition at line 1245 of file FlutterEngineTest.mm.

1245 {
1246 id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
1247 FakeLifecycleProvider* fakeAppDelegate = [[FakeLifecycleProvider alloc] init];
1248 [NSApplication sharedApplication].delegate = fakeAppDelegate;
1249
1250 FakeAppDelegatePlugin* plugin = [[FakeAppDelegatePlugin alloc] init];
1251
1252 @autoreleasepool {
1253 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
1254
1255 [[engine registrarForPlugin:@"TestPlugin"] addApplicationDelegate:plugin];
1256 EXPECT_TRUE([fakeAppDelegate hasDelegate:plugin]);
1257 }
1258
1259 // When the engine is released, it should unregister any plugins it had
1260 // registered on its behalf.
1261 EXPECT_FALSE([fakeAppDelegate hasDelegate:plugin]);
1262
1263 [NSApplication sharedApplication].delegate = previousDelegate;
1264 }

## ◆ TEST_F() [58/83]

flutter::testing::TEST_F | ( | FlutterMenuPluginTest | ,
|  | TestSetMenu |
| ) |  |

Definition at line 90 of file FlutterMenuPluginTest.mm.

90 {
91 // Build a simulation of the default main menu.
92 NSMenu* mainMenu = [[NSMenu alloc] init];
93 NSMenuItem* appNameMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"APP_NAME", nil)
94 action:nil
95 keyEquivalent:@""];
96 NSMenu* submenu =
97 [[NSMenu alloc] initWithTitle:NSLocalizedString(@"Prexisting APP_NAME menu", nil)];
98 [submenu addItem:[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"About APP_NAME", nil)
99 action:nil
100 keyEquivalent:@""]];
101 appNameMenu.submenu = submenu;
102 [mainMenu addItem:appNameMenu];
103 [NSApp setMainMenu:mainMenu];
104
105 FakePluginRegistrar* registrar = [[FakePluginRegistrar alloc] init];
106 [FlutterMenuPlugin registerWithRegistrar:registrar];
107 FlutterMenuPlugin* plugin = [registrar plugin];
108
109 NSDictionary* testMenus = @{
110 @"0" : @[
111 @{
112 @"id" : [NSNumber numberWithInt:1],
113 @"label" : @"APP_NAME",
114 @"enabled" : @(YES),
115 @"children" : @[
116 @{
117 @"id" : [NSNumber numberWithInt:3],
118 @"platformProvidedMenu" : @(static_cast<int>(flutter::PlatformProvidedMenu::kQuit)),
119 @"enabled" : @(YES),
120 },
121 @{
122 @"id" : [NSNumber numberWithInt:2],
123 @"label" : @"APP_NAME Info",
124 @"enabled" : @(YES),
125 @"shortcutTrigger" : [NSNumber numberWithUnsignedLongLong:0x61],
126 @"shortcutModifiers" : [NSNumber numberWithUnsignedInt:0],
127 },
128 ],
129 },
130 @{
131 @"id" : [NSNumber numberWithInt:4],
132 @"label" : @"Help for APP_NAME",
133 @"enabled" : @(YES),
134 @"children" : @[
135 @{
136 @"id" : [NSNumber numberWithInt:5],
137 @"label" : @"Help me!",
138 @"enabled" : @(YES),
139 },
140 @{
141 @"id" : [NSNumber numberWithInt:6],
142 @"label" : @"",
143 @"enabled" : @(NO),
144 @"isDivider" : @(YES),
145 },
146 @{
147 @"id" : [NSNumber numberWithInt:7],
148 @"label" : @"Search help",
149 @"enabled" : @(NO),
150 },
151 ],
152 },
153 ],
154 };
155
156 __block id available = @NO;
157 [plugin handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"Menu.isPluginAvailable"
158 arguments:nil]
159 result:^(id _Nullable result) {
160 available = result;
161 }];
162
163 EXPECT_TRUE(available);
164
165 [plugin handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"Menu.setMenus"
166 arguments:testMenus]
167 result:^(id _Nullable result){
168 }];
169
170 EXPECT_EQ([NSApp.mainMenu numberOfItems], 2);
171 NSMenuItem* firstMenu = [NSApp.mainMenu itemAtIndex:0];
172 EXPECT_TRUE([[firstMenu title] isEqualToString:@"flutter_desktop_darwin_unittests"]);
173 EXPECT_EQ([firstMenu tag], 1);
174 EXPECT_TRUE([firstMenu isEnabled]);
175 EXPECT_FALSE([firstMenu isHidden]);
176 EXPECT_TRUE([[firstMenu keyEquivalent] isEqualToString:@"\0"]);
177
178 EXPECT_EQ([[firstMenu submenu] numberOfItems], 1);
179 NSMenuItem* firstItem = [[firstMenu submenu] itemAtIndex:0];
180 EXPECT_TRUE([[firstItem title] isEqualToString:@"flutter_desktop_darwin_unittests Info"]);
181 EXPECT_TRUE([[firstItem keyEquivalent] isEqualToString:@"a"]);
182 EXPECT_TRUE([firstItem isEnabled]);
183 EXPECT_FALSE([firstItem isHidden]);
184 EXPECT_TRUE(
185 [NSStringFromSelector([firstItem action]) isEqualToString:@"flutterMenuItemSelected:"]);
186 EXPECT_EQ([firstItem tag], 2);
187
188 NSMenuItem* secondMenu = [NSApp.mainMenu itemAtIndex:1];
189 EXPECT_TRUE([[secondMenu title] isEqualToString:@"Help for flutter_desktop_darwin_unittests"]);
190 EXPECT_EQ([secondMenu tag], 4);
191 EXPECT_TRUE([secondMenu isEnabled]);
192 EXPECT_FALSE([secondMenu isHidden]);
193
194 EXPECT_EQ([[secondMenu submenu] numberOfItems], 3);
195 NSMenuItem* secondMenuFirst = [[secondMenu submenu] itemAtIndex:0];
196 EXPECT_TRUE([[secondMenuFirst title] isEqualToString:@"Help me!"]);
197 EXPECT_TRUE([secondMenuFirst isEnabled]);
198 EXPECT_FALSE([secondMenuFirst isHidden]);
199 EXPECT_TRUE(
200 [NSStringFromSelector([secondMenuFirst action]) isEqualToString:@"flutterMenuItemSelected:"]);
201 EXPECT_EQ([secondMenuFirst tag], 5);
202
203 NSMenuItem* secondMenuDivider = [[secondMenu submenu] itemAtIndex:1];
204 EXPECT_TRUE([[secondMenuDivider title] isEqualToString:@""]);
205 EXPECT_TRUE([[secondMenuDivider keyEquivalent] isEqualToString:@""]);
206 EXPECT_FALSE([secondMenuDivider isEnabled]);
207 EXPECT_FALSE([secondMenuDivider isHidden]);
208 EXPECT_EQ([secondMenuDivider action], nil);
209 EXPECT_EQ([secondMenuDivider tag], 0);
210
211 NSMenuItem* secondMenuLast = [[secondMenu submenu] itemAtIndex:2];
212 EXPECT_TRUE([[secondMenuLast title] isEqualToString:@"Search help"]);
213 EXPECT_FALSE([secondMenuLast isEnabled]);
214 EXPECT_FALSE([secondMenuLast isHidden]);
215 EXPECT_TRUE(
216 [NSStringFromSelector([secondMenuLast action]) isEqualToString:@"flutterMenuItemSelected:"]);
217 EXPECT_EQ([secondMenuLast tag], 7);
218 }
FakePluginRegistrar
Definition: FlutterMenuPluginTest.mm:22
FakePluginRegistrar::plugin
id< FlutterPlugin > plugin
Definition: FlutterMenuPluginTest.mm:23
-[FlutterPlugin-p handleMethodCall:result:]
void handleMethodCall:result:(FlutterMethodCall *call,[result] FlutterResult result)

References <FlutterPlugin>::handleMethodCall:result:, FlutterMethodCall::methodCallWithMethodName:arguments:, FakePluginRegistrar::plugin, and FlutterMenuPlugin::registerWithRegistrar:.

## ◆ TEST_F() [59/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestCtrlTabKeyEventIsPropagated |
| ) |  |

Definition at line 278 of file FlutterViewControllerTest.mm.

278 {
279 id mockEngine = GetMockEngine();
280 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testCtrlTabKeyEventIsPropagated:mockEngine]);
281 }
FlutterViewControllerTestObjC
Definition: FlutterViewControllerTest.mm:101

## ◆ TEST_F() [60/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestFlagsChangedEventsArePropagatedIfNotHandled |
| ) |  |

Definition at line 289 of file FlutterViewControllerTest.mm.

289 {
290 id mockEngine = GetMockEngine();
291 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc]
292 testFlagsChangedEventsArePropagatedIfNotHandled:mockEngine]);
293 }

## ◆ TEST_F() [61/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | testFlutterViewIsConfigured |
| ) |  |

Definition at line 331 of file FlutterViewControllerTest.mm.

331 {
332 id mockEngine = GetMockEngine();
333 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testFlutterViewIsConfigured:mockEngine]);
334 }

## ◆ TEST_F() [62/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestKeyboardIsRestartedOnEngineRestart |
| ) |  |

Definition at line 295 of file FlutterViewControllerTest.mm.

295 {
296 id mockEngine = GetMockEngine();
297 ASSERT_TRUE(
298 [[FlutterViewControllerTestObjC alloc] testKeyboardIsRestartedOnEngineRestart:mockEngine]);
299 }

## ◆ TEST_F() [63/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestKeyEquivalentIsPassedToTextInputPlugin |
| ) |  |

Definition at line 283 of file FlutterViewControllerTest.mm.

283 {
284 id mockEngine = GetMockEngine();
285 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc]
286 testKeyEquivalentIsPassedToTextInputPlugin:mockEngine]);
287 }

## ◆ TEST_F() [64/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestKeyEventsAreNotPropagatedIfHandled |
| ) |  |

Definition at line 272 of file FlutterViewControllerTest.mm.

272 {
273 id mockEngine = GetMockEngine();
274 ASSERT_TRUE(
275 [[FlutterViewControllerTestObjC alloc] testKeyEventsAreNotPropagatedIfHandled:mockEngine]);
276 }

## ◆ TEST_F() [65/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestKeyEventsArePropagatedIfNotHandled |
| ) |  |

Definition at line 266 of file FlutterViewControllerTest.mm.

266 {
267 id mockEngine = GetMockEngine();
268 ASSERT_TRUE(
269 [[FlutterViewControllerTestObjC alloc] testKeyEventsArePropagatedIfNotHandled:mockEngine]);
270 }

## ◆ TEST_F() [66/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestKeyEventsAreSentToFramework |
| ) |  |

Definition at line 261 of file FlutterViewControllerTest.mm.

261 {
262 id mockEngine = GetMockEngine();
263 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEventsAreSentToFramework:mockEngine]);
264 }

## ◆ TEST_F() [67/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestModifierKeysAreSynthesizedOnMouseMove |
| ) |  |

Definition at line 319 of file FlutterViewControllerTest.mm.

319 {
320 id mockEngine = GetMockEngine();
321 ASSERT_TRUE(
322 [[FlutterViewControllerTestObjC alloc] testModifierKeysAreSynthesizedOnMouseMove:mockEngine]);
323 }

## ◆ TEST_F() [68/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestmouseAndGestureEventsAreHandledSeparately |
| ) |  |

Definition at line 307 of file FlutterViewControllerTest.mm.

307 {
308 id mockEngine = GetMockEngine();
309 ASSERT_TRUE(
310 [[FlutterViewControllerTestObjC alloc] mouseAndGestureEventsAreHandledSeparately:mockEngine]);
311 }

## ◆ TEST_F() [69/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestMouseDownUpEventsSentToNextResponder |
| ) |  |

Definition at line 313 of file FlutterViewControllerTest.mm.

313 {
314 id mockEngine = GetMockEngine();
315 ASSERT_TRUE(
316 [[FlutterViewControllerTestObjC alloc] testMouseDownUpEventsSentToNextResponder:mockEngine]);
317 }

## ◆ TEST_F() [70/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | TestTrackpadGesturesAreSentToFramework |
| ) |  |

Definition at line 301 of file FlutterViewControllerTest.mm.

301 {
302 id mockEngine = GetMockEngine();
303 ASSERT_TRUE(
304 [[FlutterViewControllerTestObjC alloc] testTrackpadGesturesAreSentToFramework:mockEngine]);
305 }

## ◆ TEST_F() [71/83]

flutter::testing::TEST_F | ( | FlutterViewControllerMockEngineTest | ,
|  | testViewWillAppearCalledMultipleTimes |
| ) |  |

Definition at line 325 of file FlutterViewControllerTest.mm.

325 {
326 id mockEngine = GetMockEngine();
327 ASSERT_TRUE(
328 [[FlutterViewControllerTestObjC alloc] testViewWillAppearCalledMultipleTimes:mockEngine]);
329 }

## ◆ TEST_F() [72/83]

flutter::testing::TEST_F | ( | FlutterViewControllerTest | ,
|  | CanSetMouseTrackingModeBeforeViewLoaded |
| ) |  |

Definition at line 251 of file FlutterViewControllerTest.mm.

251 {
252 NSString* fixtures = @(testing::GetFixturesPath());
253 FlutterDartProject* project = [[FlutterDartProject alloc]
254 initWithAssetsPath:fixtures
255 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
256 FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:project];
257 viewController.mouseTrackingMode = kFlutterMouseTrackingModeInActiveApp;
258 ASSERT_EQ(viewController.mouseTrackingMode, kFlutterMouseTrackingModeInActiveApp);
259 }
FlutterViewController::mouseTrackingMode
FlutterMouseTrackingMode mouseTrackingMode
Definition: FlutterViewController.h:84

References FlutterViewController::mouseTrackingMode.

## ◆ TEST_F() [73/83]

flutter::testing::TEST_F | ( | FlutterViewControllerTest | ,
|  | FlutterViewAcceptsFirstMouse |
| ) |  |

Definition at line 208 of file FlutterViewControllerTest.mm.

208 {
209 FlutterViewController* viewControllerMock = CreateMockViewController();
210 [viewControllerMock loadView];
211 EXPECT_EQ([viewControllerMock.flutterView acceptsFirstMouse:nil], YES);
212 }
flutter::testing::CreateMockViewController
id CreateMockViewController()
Definition: FlutterViewControllerTestUtils.mm:9

References CreateMockViewController().

## ◆ TEST_F() [74/83]

flutter::testing::TEST_F | ( | FlutterViewControllerTest | ,
|  | HasViewThatHidesOtherViewsInAccessibility |
| ) |  |

Definition at line 187 of file FlutterViewControllerTest.mm.

187 {
188 FlutterViewController* viewControllerMock = CreateMockViewController();
189
190 [viewControllerMock loadView];
191 auto subViews = [viewControllerMock.view subviews];
192
193 EXPECT_EQ([subViews count], 1u);
194 EXPECT_EQ(subViews[0], viewControllerMock.flutterView);
195
196 NSTextField* textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 1, 1)];
197 [viewControllerMock.view addSubview:textField];
198
199 subViews = [viewControllerMock.view subviews];
200 EXPECT_EQ([subViews count], 2u);
201
202 auto accessibilityChildren = viewControllerMock.view.accessibilityChildren;
203 // The accessibilityChildren should only contains the FlutterView.
204 EXPECT_EQ([accessibilityChildren count], 1u);
205 EXPECT_EQ(accessibilityChildren[0], viewControllerMock.flutterView);
206 }

References CreateMockViewController().

## ◆ TEST_F() [75/83]

flutter::testing::TEST_F | ( | FlutterViewControllerTest | ,
|  | ReparentsPluginWhenAccessibilityDisabled |
| ) |  |

Definition at line 214 of file FlutterViewControllerTest.mm.

214 {
215 FlutterEngine* engine = CreateTestEngine();
216 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
217 nibName:nil
218 bundle:nil];
219 [viewController loadView];
220 // Creates a NSWindow so that sub view can be first responder.
221 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
222 styleMask:NSBorderlessWindowMask
223 backing:NSBackingStoreBuffered
224 defer:NO];
225 window.contentView = viewController.view;
226 NSView* dummyView = [[NSView alloc] initWithFrame:CGRectZero];
227 [viewController.view addSubview:dummyView];
228
229 NSDictionary* setClientConfig = @{
230 @"viewId" : @(flutter::kFlutterImplicitViewId),
231 };
232 FlutterMethodCall* methodCall =
233 [FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
234 arguments:@[ @(1), setClientConfig ]];
235 FlutterResult result = ^(id result) {
236 };
237 [engine.textInputPlugin handleMethodCall:methodCall result:result];
238
239 // Attaches FlutterTextInputPlugin to the view;
240 [dummyView addSubview:engine.textInputPlugin];
241 // Makes sure the textInputPlugin can be the first responder.
242
243 EXPECT_TRUE([window makeFirstResponder:engine.textInputPlugin]);
244 EXPECT_EQ([window firstResponder], engine.textInputPlugin);
245 EXPECT_FALSE(engine.textInputPlugin.superview == viewController.view);
246 [viewController onAccessibilityStatusChanged:NO];
247 // FlutterView becomes child of view controller
248 EXPECT_TRUE(viewController.engine.textInputPlugin.superview == viewController.view);
249 }
-[FlutterViewController onAccessibilityStatusChanged:]
void onAccessibilityStatusChanged:(BOOL enabled)

References FlutterViewController::engine, FlutterMethodCall::methodCallWithMethodName:arguments:, and FlutterViewController::onAccessibilityStatusChanged:.

## ◆ TEST_F() [76/83]

flutter::testing::TEST_F | ( | FlutterViewControllerTest | ,
|  | testLookupKeyAssets |
| ) |  |

Definition at line 336 of file FlutterViewControllerTest.mm.

336 {
337 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testLookupKeyAssets]);
338 }

## ◆ TEST_F() [77/83]

flutter::testing::TEST_F | ( | FlutterViewControllerTest | ,
|  | testLookupKeyAssetsWithPackage |
| ) |  |

Definition at line 340 of file FlutterViewControllerTest.mm.

340 {
341 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testLookupKeyAssetsWithPackage]);
342 }

## ◆ TEST_F() [78/83]

flutter::testing::TEST_F | ( | FlutterViewControllerTest | ,
|  | testViewControllerIsReleased |
| ) |  |

Definition at line 344 of file FlutterViewControllerTest.mm.

344 {
345 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testViewControllerIsReleased]);
346 }

## ◆ TEST_F() [79/83]

flutter::testing::TEST_F | ( | FlutterWindowControllerRetainTest | ,
|  | WindowControllerDoesNotRetainEngine |
| ) |  |

Definition at line 82 of file FlutterWindowControllerTest.mm.

82 {
83 FlutterWindowCreationRequest request{
84 .has_size = true,
85 .size = {.width = 800, .height = 600},
86 .on_close = [] {},
87 .notify_listeners = [] {},
88 };
89
90 __weak FlutterEngine* weakEngine = nil;
91 @autoreleasepool {
92 NSString* fixtures = @(flutter::testing::GetFixturesPath());
93 NSLog(@"Fixtures path: %@", fixtures);
94 FlutterDartProject* project = [[FlutterDartProject alloc]
95 initWithAssetsPath:fixtures
96 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
97
98 static std::optional<flutter::Isolate> isolate;
99 isolate = std::nullopt;
100
101 project.rootIsolateCreateCallback = [](void*) { isolate = flutter::Isolate::Current(); };
102 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
103 project:project
104 allowHeadlessExecution:YES];
105 weakEngine = engine;
106 [engine runWithEntrypoint:@"testWindowControllerRetainCycle"];
107
108 int64_t engineId = reinterpret_cast<int64_t>(engine);
109
110 {
111 FML_DCHECK(isolate.has_value());
112 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
113 IsolateScope isolateScope(*isolate);
114 int64_t handle = InternalFlutter_WindowController_CreateRegularWindow(engineId, &request);
115 EXPECT_EQ(handle, 1);
116 }
117
118 [engine.windowController closeAllWindows];
119 [engine shutDownEngine];
120 }
121 EXPECT_EQ(weakEngine, nil);
122 }
InternalFlutter_WindowController_CreateRegularWindow
FLUTTER_DARWIN_EXPORT int64_t InternalFlutter_WindowController_CreateRegularWindow(int64_t engine_id, const FlutterWindowCreationRequest *request)
Definition: FlutterWindowController.mm:205
flutter::Isolate::Current
static Isolate Current()
Definition: isolate_scope.cc:9
FlutterWindowCreationRequest
Definition: FlutterWindowController.h:39
FlutterWindowCreationRequest::has_size
bool has_size
Definition: FlutterWindowController.h:40

References flutter::Isolate::Current(), FlutterWindowCreationRequest::has_size, and InternalFlutter_WindowController_CreateRegularWindow().

## ◆ TEST_F() [80/83]

flutter::testing::TEST_F | ( | FlutterWindowControllerTest | ,
|  | CreateRegularWindow |
| ) |  |

Definition at line 58 of file FlutterWindowControllerTest.mm.

58 {
59 FlutterWindowCreationRequest request{
60 .has_size = true,
61 .size = {.width = 800, .height = 600},
62 .on_close = [] {},
63 .notify_listeners = [] {},
64 };
65
66 FlutterEngine* engine = GetFlutterEngine();
67 int64_t engineId = reinterpret_cast<int64_t>(engine);
68
69 {
70 IsolateScope isolate_scope(isolate());
71 int64_t handle = InternalFlutter_WindowController_CreateRegularWindow(engineId, &request);
72 EXPECT_EQ(handle, 1);
73
74 FlutterViewController* viewController = [engine viewControllerForIdentifier:handle];
75 EXPECT_NE(viewController, nil);
76 CGSize size = viewController.view.frame.size;
77 EXPECT_EQ(size.width, 800);
78 EXPECT_EQ(size.height, 600);
79 }
80 }

References FlutterWindowCreationRequest::has_size, and InternalFlutter_WindowController_CreateRegularWindow().

## ◆ TEST_F() [81/83]

flutter::testing::TEST_F | ( | FlutterWindowControllerTest | ,
|  | DestroyRegularWindow |
| ) |  |

Definition at line 124 of file FlutterWindowControllerTest.mm.

124 {
125 FlutterWindowCreationRequest request{
126 .has_size = true,
127 .size = {.width = 800, .height = 600},
128 .on_close = [] {},
129 .notify_listeners = [] {},
130 };
131
132 FlutterEngine* engine = GetFlutterEngine();
133 int64_t engine_id = reinterpret_cast<int64_t>(engine);
134
135 IsolateScope isolate_scope(isolate());
136 int64_t handle = InternalFlutter_WindowController_CreateRegularWindow(engine_id, &request);
137 FlutterViewController* viewController = [engine viewControllerForIdentifier:handle];
138
139 InternalFlutter_Window_Destroy(engine_id, (__bridge void*)viewController.view.window);
140 viewController = [engine viewControllerForIdentifier:handle];
141 EXPECT_EQ(viewController, nil);
142 }
InternalFlutter_Window_Destroy
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_Destroy(int64_t engine_id, void *window)
Definition: FlutterWindowController.mm:213

References FlutterWindowCreationRequest::has_size, InternalFlutter_Window_Destroy(), and InternalFlutter_WindowController_CreateRegularWindow().

## ◆ TEST_F() [82/83]

flutter::testing::TEST_F | ( | FlutterWindowControllerTest | ,
|  | InternalFlutter_Window_GetHandle |
| ) |  |

Definition at line 144 of file FlutterWindowControllerTest.mm.

144 {
145 FlutterWindowCreationRequest request{
146 .has_size = true,
147 .size = {.width = 800, .height = 600},
148 .on_close = [] {},
149 .notify_listeners = [] {},
150 };
151
152 FlutterEngine* engine = GetFlutterEngine();
153 int64_t engine_id = reinterpret_cast<int64_t>(engine);
154
155 IsolateScope isolate_scope(isolate());
156 int64_t handle = InternalFlutter_WindowController_CreateRegularWindow(engine_id, &request);
157 FlutterViewController* viewController = [engine viewControllerForIdentifier:handle];
158
159 void* window_handle = InternalFlutter_Window_GetHandle(engine_id, handle);
160 EXPECT_EQ(window_handle, (__bridge void*)viewController.view.window);
161 }
InternalFlutter_Window_GetHandle
FLUTTER_DARWIN_EXPORT void * InternalFlutter_Window_GetHandle(int64_t engine_id, FlutterViewIdentifier view_id)
Definition: FlutterWindowController.mm:219

References FlutterWindowCreationRequest::has_size, InternalFlutter_Window_GetHandle(), and InternalFlutter_WindowController_CreateRegularWindow().

## ◆ TEST_F() [83/83]

flutter::testing::TEST_F | ( | FlutterWindowControllerTest | ,
|  | WindowStates |
| ) |  |

Definition at line 163 of file FlutterWindowControllerTest.mm.

163 {
164 FlutterWindowCreationRequest request{
165 .has_size = true,
166 .size = {.width = 800, .height = 600},
167 .on_close = [] {},
168 .notify_listeners = [] {},
169 };
170
171 FlutterEngine* engine = GetFlutterEngine();
172 int64_t engine_id = reinterpret_cast<int64_t>(engine);
173
174 IsolateScope isolate_scope(isolate());
175 int64_t handle = InternalFlutter_WindowController_CreateRegularWindow(engine_id, &request);
176
177 FlutterViewController* viewController = [engine viewControllerForIdentifier:handle];
178 NSWindow* window = viewController.view.window;
179 void* windowHandle = (__bridge void*)window;
180
181 EXPECT_EQ(window.zoomed, NO);
182 EXPECT_EQ(window.miniaturized, NO);
183 EXPECT_EQ(window.styleMask & NSWindowStyleMaskFullScreen, 0u);
184
185 InternalFlutter_Window_SetMaximized(windowHandle, true);
186 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, false);
187 EXPECT_EQ(window.zoomed, YES);
188
189 InternalFlutter_Window_SetMaximized(windowHandle, false);
190 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, false);
191 EXPECT_EQ(window.zoomed, NO);
192
193 // FullScreen toggle does not seem to work when the application is not run from a bundle.
194
195 InternalFlutter_Window_Minimize(windowHandle);
196 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, false);
197 EXPECT_EQ(window.miniaturized, YES);
198 }
InternalFlutter_Window_SetMaximized
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_SetMaximized(void *window, bool maximized)
Definition: FlutterWindowController.mm:251
InternalFlutter_Window_Minimize
FLUTTER_DARWIN_EXPORT void InternalFlutter_Window_Minimize(void *window)
Definition: FlutterWindowController.mm:265

References FlutterWindowCreationRequest::has_size, InternalFlutter_Window_Minimize(), InternalFlutter_Window_SetMaximized(), and InternalFlutter_WindowController_CreateRegularWindow().

## Variable Documentation

## ◆ kEmptyFlags

FlutterSemanticsFlags flutter::testing::kEmptyFlags = FlutterSemanticsFlags{}

Definition at line 18 of file accessibility_bridge_unittests.cc.

Referenced by CreateSemanticsNode().