| Flutter macOS Embedder |

Classes | Typedefs | Functions
flutter::testing Namespace Reference

## Classes
class | FlutterEngineTest
class | FlutterMenuPluginTest
class | MockFlutterEngineTest

## 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_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 (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, DartEntrypointArguments)
| TEST_F (FlutterEngineTest, FlutterBinaryMessengerDoesNotRetainEngine)
| TEST_F (FlutterEngineTest, FlutterTextureRegistryDoesNotReturnEngine)
| TEST_F (FlutterEngineTest, PublishedValueNilForUnknownPlugin)
| TEST_F (FlutterEngineTest, PublishedValueNSNullIfNoPublishedValue)
| TEST_F (FlutterEngineTest, PublishedValueReturnsLastPublished)
| TEST_F (FlutterEngineTest, MessengerCleanupConnectionWorks)
| TEST_F (FlutterEngineTest, HasStringsWhenPasteboardEmpty)
| TEST_F (FlutterEngineTest, HasStringsWhenPasteboardFull)
| TEST_F (FlutterEngineTest, ResponseAfterEngineDied)
| TEST_F (FlutterEngineTest, ResponseFromBackgroundThread)
| TEST_F (FlutterEngineTest, ThreadSynchronizerNotBlockingRasterThreadAfterShutdown)
| TEST_F (FlutterEngineTest, ManageControllersIfInitiatedByController)
| TEST_F (FlutterEngineTest, ManageControllersIfInitiatedByEngine)
| 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)
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, ShouldNotHoldStrongReferenceToViewDelegate)
| TEST_F (FlutterMenuPluginTest, TestSetMenu)
| TEST (FlutterPlatformNodeDelegateMac, Basics)
| TEST (FlutterPlatformNodeDelegateMac, SelectableTextHasCorrectSemantics)
| TEST (FlutterPlatformNodeDelegateMac, SelectableTextWithoutSelectionReturnZeroRange)
| TEST (FlutterPlatformNodeDelegateMac, CanPerformAction)
| TEST (FlutterPlatformNodeDelegateMac, TextFieldUsesFlutterTextField)
| TEST (FlutterPlatformViewController, TestCreatePlatformViewNoMatchingViewType)
| TEST (FlutterPlatformViewController, TestRegisterPlatformViewFactoryAndCreate)
| TEST (FlutterPlatformViewController, TestCreateAndDispose)
| TEST (FlutterPlatformViewController, TestDisposeOnMissingViewId)
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)
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, TestInsertNewLine)
| TEST (FlutterTextInputPluginTest, TestSendActionDoNotInsertNewLine)
| TEST (FlutterTextInputPluginTest, CanWorkWithFlutterTextField)
| TEST (FlutterTextInputPluginTest, CanNotBecomeResponderIfNoViewController)
| TEST (FlutterTextInputPluginTest, IsAddedAndRemovedFromViewHierarchy)
| TEST (FlutterTextInputPluginTest, FirstResponderIsCorrect)
| TEST (FlutterTextInputPluginTest, HasZeroSizeAndClipsToBounds)
| 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, 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 (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)

## 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 71 of file FlutterEmbedderExternalTextureTest.mm.

## ◆ FlutterViewControllerMockEngineTest

using flutter::testing::FlutterViewControllerMockEngineTest = typedef MockFlutterEngineTest

Definition at line 179 of file FlutterViewControllerTest.mm.

## ◆ FlutterViewControllerTest

using flutter::testing::FlutterViewControllerTest = typedef AutoreleasePoolTest

Definition at line 178 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 }

References FlutterPasteboard::setString:forType:.

Referenced by flutter::testing::MockFlutterEngineTest::SetUp(), TEST(), TEST_F(), FlutterInputPluginTestObjc::testClearClientDuringComposing, FlutterInputPluginTestObjc::testEmptyCompositionRange, and FlutterViewControllerTestObjC::testViewControllerIsReleased.

## ◆ 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 }

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 51 of file FlutterSurfaceManagerTest.mm.

55 {}) {
56 FlutterSurfacePresentInfo* res = [[FlutterSurfacePresentInfo alloc] init];
57 res.surface = surface;
58 res.offset = offset;
59 res.zIndex = index;
60 res.paintRegion = paintRegion;
61 return res;
62 }

## ◆ CreateSemanticsNode()

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

Definition at line 18 of file accessibility_bridge_unittests.cc.

21 {
22 return {
23 .id = id,
24 .flags = static_cast<FlutterSemanticsFlag>(0),
25 .actions = static_cast<FlutterSemanticsAction>(0),
26 .text_selection_base = -1,
27 .text_selection_extent = -1,
28 .label = label,
29 .hint = "",
30 .value = "",
31 .increased_value = "",
32 .decreased_value = "",
33 .child_count = children ? children->size() : 0,
34 .children_in_traversal_order = children ? children->data() : nullptr,
35 .custom_accessibility_actions_count = 0,
36 .tooltip = "",
37 };
38 }

Referenced by TEST().

## ◆ CreateSurfaceManager()

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

Definition at line 41 of file FlutterSurfaceManagerTest.mm.

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

Referenced by TEST().

## ◆ operator==()

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

Definition at line 166 of file FlutterSurfaceManagerTest.mm.

166 {
167 return CGRectEqualToRect(lhs, rhs);
168 }

## ◆ TEST() [1/108]

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

Definition at line 72 of file accessibility_bridge_unittests.cc.

72 {
73 std::shared_ptr<TestAccessibilityBridge> bridge =
74 std::make_shared<TestAccessibilityBridge>();
75
76 std::vector<int32_t> children{456, 789};
77 FlutterSemanticsNode2 root = CreateSemanticsNode(123, "root", &children);
78 FlutterSemanticsNode2 child1 = CreateSemanticsNode(456, "child 1");
79 FlutterSemanticsNode2 child2 = CreateSemanticsNode(789, "child 2");
80
81 bridge->AddFlutterSemanticsNodeUpdate(root);
82 bridge->AddFlutterSemanticsNodeUpdate(child1);
83 bridge->AddFlutterSemanticsNodeUpdate(child2);
84 bridge->CommitUpdates();
85
86 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(123).lock();
87 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(456).lock();
88 auto child2_node = bridge->GetFlutterPlatformNodeDelegateFromID(789).lock();
89 auto fake_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
90
91 EXPECT_EQ(bridge->GetRootAsAXNode()->id(), 123);
92 EXPECT_EQ(bridge->RootDelegate()->GetName(), "root");
93
94 EXPECT_EQ(root_node->GetChildCount(), 2);
95 EXPECT_EQ(root_node->GetData().child_ids[0], 456);
96 EXPECT_EQ(root_node->GetData().child_ids[1], 789);
97 EXPECT_EQ(root_node->GetName(), "root");
98
99 EXPECT_EQ(child1_node->GetChildCount(), 0);
100 EXPECT_EQ(child1_node->GetName(), "child 1");
101
102 EXPECT_EQ(child2_node->GetChildCount(), 0);
103 EXPECT_EQ(child2_node->GetName(), "child 2");
104
105 ASSERT_FALSE(fake_delegate);
106 }

References CreateSemanticsNode().

## ◆ TEST() [2/108]

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

Definition at line 109 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

## ◆ TEST() [3/108]

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

Definition at line 546 of file accessibility_bridge_unittests.cc.

546 {
547 std::shared_ptr<TestAccessibilityBridge> bridge =
548 std::make_shared<TestAccessibilityBridge>();
549
550 ui::AXTreeID tree_id = bridge->GetTreeID();
551 ui::AXTreeManager* manager =
552 ui::AXTreeManagerMap::GetInstance().GetManager(tree_id);
553 ASSERT_EQ(manager, static_cast<ui::AXTreeManager*>(bridge.get()));
554 }

## ◆ TEST() [4/108]

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

Definition at line 40 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

## ◆ TEST() [5/108]

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

Definition at line 160 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

## ◆ TEST() [6/108]

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

Definition at line 208 of file accessibility_bridge_unittests.cc.

208 {
209 std::shared_ptr<TestAccessibilityBridge> bridge =
210 std::make_shared<TestAccessibilityBridge>();
211 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root");
212 root.flags = static_cast<FlutterSemanticsFlag>(
213 FlutterSemanticsFlag::kFlutterSemanticsFlagIsTextField |
214 FlutterSemanticsFlag::kFlutterSemanticsFlagIsFocused);
215 bridge->AddFlutterSemanticsNodeUpdate(root);
216 bridge->CommitUpdates();
217
218 const ui::AXTreeData& tree = bridge->GetAXTreeData();
219 EXPECT_EQ(tree.sel_anchor_object_id, ui::AXNode::kInvalidAXID);
220 bridge->accessibility_events.clear();
221
222 // Update the selection.
223 root.text_selection_base = 0;
224 root.text_selection_extent = 5;
225 bridge->AddFlutterSemanticsNodeUpdate(root);
226
227 bridge->CommitUpdates();
228
229 EXPECT_EQ(tree.sel_anchor_object_id, 0);
230 EXPECT_EQ(tree.sel_anchor_offset, 0);
231 EXPECT_EQ(tree.sel_focus_object_id, 0);
232 EXPECT_EQ(tree.sel_focus_offset, 5);
233 ASSERT_EQ(bridge->accessibility_events.size(), size_t{2});
234 EXPECT_EQ(bridge->accessibility_events[0],
235 ui::AXEventGenerator::Event::DOCUMENT_SELECTION_CHANGED);
236 EXPECT_EQ(bridge->accessibility_events[1],
237 ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED);
238 }

References CreateSemanticsNode().

## ◆ TEST() [7/108]

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

Definition at line 372 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

## ◆ TEST() [8/108]

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

Definition at line 309 of file accessibility_bridge_unittests.cc.

309 {
310 std::shared_ptr<TestAccessibilityBridge> bridge =
311 std::make_shared<TestAccessibilityBridge>();
312
313 std::vector<int32_t> root_children{1};
314 std::vector<int32_t> child1_children{2};
315 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root", &root_children);
316 FlutterSemanticsNode2 child1 =
317 CreateSemanticsNode(1, "child 1", &child1_children);
318 FlutterSemanticsNode2 child2 = CreateSemanticsNode(2, "child 2");
319
320 bridge->AddFlutterSemanticsNodeUpdate(root);
321 bridge->AddFlutterSemanticsNodeUpdate(child1);
322 bridge->AddFlutterSemanticsNodeUpdate(child2);
323 bridge->CommitUpdates();
324 bridge->accessibility_events.clear();
325
326 // Reparent child2 from child1 to the root.
327 child1.child_count = 0;
328 child1.children_in_traversal_order = nullptr;
329
330 int32_t new_root_children[] = {1, 2};
331 root.child_count = 2;
332 root.children_in_traversal_order = new_root_children;
333
334 bridge->AddFlutterSemanticsNodeUpdate(root);
335 bridge->AddFlutterSemanticsNodeUpdate(child1);
336 bridge->AddFlutterSemanticsNodeUpdate(child2);
337 bridge->CommitUpdates();
338
339 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
340 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
341 auto child2_node = bridge->GetFlutterPlatformNodeDelegateFromID(2).lock();
342
343 EXPECT_EQ(root_node->GetChildCount(), 2);
344 EXPECT_EQ(root_node->GetData().child_ids[0], 1);
345 EXPECT_EQ(root_node->GetData().child_ids[1], 2);
346 EXPECT_EQ(root_node->GetName(), "root");
347
348 EXPECT_EQ(child1_node->GetChildCount(), 0);
349 EXPECT_EQ(child1_node->GetName(), "child 1");
350
351 EXPECT_EQ(child2_node->GetChildCount(), 0);
352 EXPECT_EQ(child2_node->GetName(), "child 2");
353
354 ASSERT_EQ(bridge->accessibility_events.size(), size_t{5});
355
356 // Child2 is moved from child1 to root.
357 EXPECT_THAT(bridge->accessibility_events,
358 Contains(ui::AXEventGenerator::Event::CHILDREN_CHANGED).Times(2));
359 EXPECT_THAT(bridge->accessibility_events,
360 Contains(ui::AXEventGenerator::Event::SUBTREE_CREATED).Times(1));
361
362 // Child1 is no longer a parent. It loses its group role and disables its
363 // 'clip children' attribute.
364 EXPECT_THAT(
365 bridge->accessibility_events,
366 Contains(ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED).Times(1));
367 EXPECT_THAT(bridge->accessibility_events,
368 Contains(ui::AXEventGenerator::Event::ROLE_CHANGED).Times(1));
369 }

References CreateSemanticsNode().

## ◆ TEST() [9/108]

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

Definition at line 466 of file accessibility_bridge_unittests.cc.

466 {
467 std::shared_ptr<TestAccessibilityBridge> bridge =
468 std::make_shared<TestAccessibilityBridge>();
469
470 int32_t root_id = 0;
471 int32_t intermediary1_id = 1;
472 int32_t intermediary2_id = 2;
473 int32_t leaf1_id = 3;
474
475 std::vector<int32_t> root_children{intermediary1_id, intermediary2_id};
476 std::vector<int32_t> intermediary1_children{leaf1_id};
477 FlutterSemanticsNode2 root =
478 CreateSemanticsNode(root_id, "root", &root_children);
479 FlutterSemanticsNode2 intermediary1 = CreateSemanticsNode(
480 intermediary1_id, "intermediary 1", &intermediary1_children);
481 FlutterSemanticsNode2 intermediary2 =
482 CreateSemanticsNode(intermediary2_id, "intermediary 2");
483 FlutterSemanticsNode2 leaf1 = CreateSemanticsNode(leaf1_id, "leaf 1");
484
485 bridge->AddFlutterSemanticsNodeUpdate(root);
486 bridge->AddFlutterSemanticsNodeUpdate(intermediary1);
487 bridge->AddFlutterSemanticsNodeUpdate(intermediary2);
488 bridge->AddFlutterSemanticsNodeUpdate(leaf1);
489 bridge->CommitUpdates();
490 bridge->accessibility_events.clear();
491
492 // Move intermediary1 from root to intermediary 2.
493 int32_t new_root_children[] = {intermediary2_id};
494 root.child_count = 1;
495 root.children_in_traversal_order = new_root_children;
496
497 int32_t new_intermediary2_children[] = {intermediary1_id};
498 intermediary2.child_count = 1;
499 intermediary2.children_in_traversal_order = new_intermediary2_children;
500
501 bridge->AddFlutterSemanticsNodeUpdate(root);
502 bridge->AddFlutterSemanticsNodeUpdate(intermediary1);
503 bridge->AddFlutterSemanticsNodeUpdate(intermediary2);
504 bridge->AddFlutterSemanticsNodeUpdate(leaf1);
505 bridge->CommitUpdates();
506
507 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(root_id).lock();
508 auto intermediary1_node =
509 bridge->GetFlutterPlatformNodeDelegateFromID(intermediary1_id).lock();
510 auto intermediary2_node =
511 bridge->GetFlutterPlatformNodeDelegateFromID(intermediary2_id).lock();
512 auto leaf1_node =
513 bridge->GetFlutterPlatformNodeDelegateFromID(leaf1_id).lock();
514
515 EXPECT_EQ(root_node->GetChildCount(), 1);
516 EXPECT_EQ(root_node->GetData().child_ids[0], intermediary2_id);
517 EXPECT_EQ(root_node->GetName(), "root");
518
519 EXPECT_EQ(intermediary2_node->GetChildCount(), 1);
520 EXPECT_EQ(intermediary2_node->GetData().child_ids[0], intermediary1_id);
521 EXPECT_EQ(intermediary2_node->GetName(), "intermediary 2");
522
523 EXPECT_EQ(intermediary1_node->GetChildCount(), 1);
524 EXPECT_EQ(intermediary1_node->GetData().child_ids[0], leaf1_id);
525 EXPECT_EQ(intermediary1_node->GetName(), "intermediary 1");
526
527 EXPECT_EQ(leaf1_node->GetChildCount(), 0);
528 EXPECT_EQ(leaf1_node->GetName(), "leaf 1");
529
530 ASSERT_EQ(bridge->accessibility_events.size(), size_t{5});
531
532 EXPECT_THAT(bridge->accessibility_events,
533 Contains(ui::AXEventGenerator::Event::CHILDREN_CHANGED).Times(2));
534 EXPECT_THAT(bridge->accessibility_events,
535 Contains(ui::AXEventGenerator::Event::SUBTREE_CREATED).Times(1));
536
537 // Intermediary 2 becomes a parent node. It updates to group role and enables
538 // its 'clip children' attribute.
539 EXPECT_THAT(
540 bridge->accessibility_events,
541 Contains(ui::AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED).Times(1));
542 EXPECT_THAT(bridge->accessibility_events,
543 Contains(ui::AXEventGenerator::Event::ROLE_CHANGED).Times(1));
544 }

References CreateSemanticsNode().

## ◆ TEST() [10/108]

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

Definition at line 292 of file accessibility_bridge_unittests.cc.

292 {
293 std::shared_ptr<TestAccessibilityBridge> bridge =
294 std::make_shared<TestAccessibilityBridge>();
295 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root");
296 root.flags = static_cast<FlutterSemanticsFlag>(
297 FlutterSemanticsFlag::kFlutterSemanticsFlagHasCheckedState |
298 FlutterSemanticsFlag::kFlutterSemanticsFlagIsChecked);
299 bridge->AddFlutterSemanticsNodeUpdate(root);
300 bridge->CommitUpdates();
301
302 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
303 EXPECT_EQ(root_node->GetData().role, ax::mojom::Role::kCheckBox);
304 EXPECT_EQ(root_node->GetData().GetCheckedState(),
305 ax::mojom::CheckedState::kTrue);
306 }

References CreateSemanticsNode().

## ◆ TEST() [11/108]

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

Definition at line 240 of file accessibility_bridge_unittests.cc.

240 {
241 std::shared_ptr<TestAccessibilityBridge> bridge =
242 std::make_shared<TestAccessibilityBridge>();
243 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root");
244 root.flags = static_cast<FlutterSemanticsFlag>(
245 FlutterSemanticsFlag::kFlutterSemanticsFlagIsTextField |
246 FlutterSemanticsFlag::kFlutterSemanticsFlagIsReadOnly);
247 bridge->AddFlutterSemanticsNodeUpdate(root);
248 bridge->CommitUpdates();
249
250 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
251
252 EXPECT_FALSE(root_node->GetData().GetBoolAttribute(
253 ax::mojom::BoolAttribute::kEditableRoot));
254 }

References CreateSemanticsNode().

## ◆ TEST() [12/108]

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

Definition at line 556 of file accessibility_bridge_unittests.cc.

556 {
557 std::shared_ptr<TestAccessibilityBridge> bridge =
558 std::make_shared<TestAccessibilityBridge>();
559
560 const int32_t root_id = 0;
561
562 FlutterSemanticsNode2 root = CreateSemanticsNode(root_id, "root", {});
563
564 bridge->AddFlutterSemanticsNodeUpdate(root);
565 bridge->CommitUpdates();
566
567 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(root_id).lock();
568 auto root_data = root_node->GetData();
569 EXPECT_TRUE(root_data.HasBoolAttribute(
570 ax::mojom::BoolAttribute::kIsLineBreakingObject));
571 EXPECT_TRUE(root_data.GetBoolAttribute(
572 ax::mojom::BoolAttribute::kIsLineBreakingObject));
573 }

References CreateSemanticsNode().

## ◆ TEST() [13/108]

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

Definition at line 271 of file accessibility_bridge_unittests.cc.

271 {
272 std::shared_ptr<TestAccessibilityBridge> bridge =
273 std::make_shared<TestAccessibilityBridge>();
274 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root");
275 root.flags = static_cast<FlutterSemanticsFlag>(
276 FlutterSemanticsFlag::kFlutterSemanticsFlagIsSlider |
277 FlutterSemanticsFlag::kFlutterSemanticsFlagHasEnabledState |
278 FlutterSemanticsFlag::kFlutterSemanticsFlagIsEnabled |
279 FlutterSemanticsFlag::kFlutterSemanticsFlagIsFocusable);
280 bridge->AddFlutterSemanticsNodeUpdate(root);
281 bridge->CommitUpdates();
282
283 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
284 EXPECT_EQ(root_node->GetData().role, ax::mojom::Role::kSlider);
285 }

References CreateSemanticsNode().

## ◆ TEST() [14/108]

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

Definition at line 256 of file accessibility_bridge_unittests.cc.

256 {
257 std::shared_ptr<TestAccessibilityBridge> bridge =
258 std::make_shared<TestAccessibilityBridge>();
259 FlutterSemanticsNode2 root = CreateSemanticsNode(0, "root");
260 root.flags = static_cast<FlutterSemanticsFlag>(
261 FlutterSemanticsFlag::kFlutterSemanticsFlagHasToggledState |
262 FlutterSemanticsFlag::kFlutterSemanticsFlagHasEnabledState |
263 FlutterSemanticsFlag::kFlutterSemanticsFlagIsEnabled);
264 bridge->AddFlutterSemanticsNodeUpdate(root);
265 bridge->CommitUpdates();
266
267 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
268 EXPECT_EQ(root_node->GetData().role, ax::mojom::Role::kSwitch);
269 }

References CreateSemanticsNode().

## ◆ TEST() [15/108]

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 }

References <FlutterAppLifecycleProvider>::addApplicationLifecycleDelegate:.

## ◆ TEST() [16/108]

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 }

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

## ◆ TEST() [17/108]

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/108]

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 }

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

## ◆ TEST() [19/108]

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 }

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

## ◆ TEST() [20/108]

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 }

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

## ◆ TEST() [21/108]

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 }

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

## ◆ TEST() [22/108]

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 }

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

## ◆ TEST() [23/108]

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 }

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

## ◆ TEST() [24/108]

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 }

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

## ◆ TEST() [25/108]

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 }

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

## ◆ TEST() [26/108]

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 }

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

## ◆ TEST() [27/108]

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 }

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

## ◆ TEST() [28/108]

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 }

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

## ◆ TEST() [29/108]

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 }

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

## ◆ TEST() [30/108]

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 }

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

## ◆ TEST() [31/108]

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 }

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

## ◆ TEST() [32/108]

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() [33/108]

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() [34/108]

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() [35/108]

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() [36/108]

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() [37/108]

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() [38/108]

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() [39/108]

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() [40/108]

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() [41/108]

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() [42/108]

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() [43/108]

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() [44/108]

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() [45/108]

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

Definition at line 462 of file FlutterKeyboardManagerTest.mm.

462 {
463 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] correctLogicalKeyForLayouts]);
464 }

## ◆ TEST() [46/108]

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

Definition at line 438 of file FlutterKeyboardManagerTest.mm.

438 {
439 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] doublePrimaryResponder]);
440 }

## ◆ TEST() [47/108]

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

Definition at line 446 of file FlutterKeyboardManagerTest.mm.

446 {
447 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] emptyNextResponder]);
448 }

## ◆ TEST() [48/108]

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

Definition at line 450 of file FlutterKeyboardManagerTest.mm.

450 {
451 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] getPressedState]);
452 }

## ◆ TEST() [49/108]

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

Definition at line 454 of file FlutterKeyboardManagerTest.mm.

454 {
455 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] keyboardChannelGetPressedState]);
456 }

## ◆ TEST() [50/108]

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

Definition at line 458 of file FlutterKeyboardManagerTest.mm.

458 {
459 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] racingConditionBetweenKeyAndText]);
460 }

## ◆ TEST() [51/108]

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

Definition at line 466 of file FlutterKeyboardManagerTest.mm.

466 {
467 ASSERT_TRUE(
468 [[FlutterKeyboardManagerUnittestsObjC alloc] shouldNotHoldStrongReferenceToViewDelegate]);
469 }

## ◆ TEST() [52/108]

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

Definition at line 442 of file FlutterKeyboardManagerTest.mm.

442 {
443 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] textInputPlugin]);
444 }

## ◆ TEST() [53/108]

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

Definition at line 434 of file FlutterKeyboardManagerTest.mm.

434 {
435 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] singlePrimaryResponder]);
436 }

## ◆ TEST() [54/108]

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 root.id = 0;
40 root.flags = static_cast<FlutterSemanticsFlag>(0);
41 ;
42 root.actions = static_cast<FlutterSemanticsAction>(0);
43 root.text_selection_base = -1;
44 root.text_selection_extent = -1;
45 root.label = "accessibility";
46 root.hint = "";
47 root.value = "";
48 root.increased_value = "";
49 root.decreased_value = "";
50 root.tooltip = "";
51 root.child_count = 0;
52 root.custom_accessibility_actions_count = 0;
53 bridge->AddFlutterSemanticsNodeUpdate(root);
54
55 bridge->CommitUpdates();
56
57 auto root_platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
58 // Verify the accessibility attribute matches.
59 NSAccessibilityElement* native_accessibility =
60 root_platform_node_delegate->GetNativeViewAccessible();
61 std::string value = [native_accessibility.accessibilityValue UTF8String];
62 EXPECT_TRUE(value == "accessibility");
63 EXPECT_EQ(native_accessibility.accessibilityRole, NSAccessibilityStaticTextRole);
64 EXPECT_EQ([native_accessibility.accessibilityChildren count], 0u);
65 [engine shutDownEngine];
66 }

References FlutterViewController::engine.

## ◆ TEST() [55/108]

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

Definition at line 149 of file FlutterPlatformNodeDelegateMacTest.mm.

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

References FlutterViewController::engine.

## ◆ TEST() [56/108]

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

Definition at line 68 of file FlutterPlatformNodeDelegateMacTest.mm.

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

References FlutterViewController::engine.

## ◆ TEST() [57/108]

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

Definition at line 110 of file FlutterPlatformNodeDelegateMacTest.mm.

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

References FlutterViewController::engine.

## ◆ TEST() [58/108]

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

Definition at line 220 of file FlutterPlatformNodeDelegateMacTest.mm.

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

References FlutterViewController::engine.

## ◆ TEST() [59/108]

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

Definition at line 110 of file flutter_platform_node_delegate_unittests.cc.

110 {
111 std::shared_ptr<TestAccessibilityBridge> bridge =
112 std::make_shared<TestAccessibilityBridge>();
113 FlutterSemanticsNode2 root;
114 root.id = 0;
115 root.label = "root";
116 root.hint = "";
117 root.value = "";
118 root.increased_value = "";
119 root.decreased_value = "";
120 root.tooltip = "";
121 root.child_count = 1;
122 int32_t children[] = {1};
123 root.children_in_traversal_order = children;
124 root.custom_accessibility_actions_count = 0;
125 root.rect = {0, 0, 100, 100}; // LTRB
126 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
127 bridge->AddFlutterSemanticsNodeUpdate(root);
128
129 FlutterSemanticsNode2 child1;
130 child1.id = 1;
131 child1.label = "child 1";
132 child1.hint = "";
133 child1.value = "";
134 child1.increased_value = "";
135 child1.decreased_value = "";
136 child1.tooltip = "";
137 child1.child_count = 0;
138 child1.custom_accessibility_actions_count = 0;
139 child1.rect = {0, 0, 50, 50}; // LTRB
140 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
141 bridge->AddFlutterSemanticsNodeUpdate(child1);
142
143 bridge->CommitUpdates();
144 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
145 ui::AXOffscreenResult result;
146 gfx::Rect bounds =
147 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
148 ui::AXClippingBehavior::kClipped, &result);
149 EXPECT_EQ(bounds.x(), 0);
150 EXPECT_EQ(bounds.y(), 0);
151 EXPECT_EQ(bounds.width(), 25);
152 EXPECT_EQ(bounds.height(), 25);
153 EXPECT_EQ(result, ui::AXOffscreenResult::kOnscreen);
154 }

## ◆ TEST() [60/108]

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

Definition at line 156 of file flutter_platform_node_delegate_unittests.cc.

156 {
157 std::shared_ptr<TestAccessibilityBridge> bridge =
158 std::make_shared<TestAccessibilityBridge>();
159 FlutterSemanticsNode2 root;
160 root.id = 0;
161 root.label = "root";
162 root.hint = "";
163 root.value = "";
164 root.increased_value = "";
165 root.decreased_value = "";
166 root.tooltip = "";
167 root.child_count = 1;
168 int32_t children[] = {1};
169 root.children_in_traversal_order = children;
170 root.custom_accessibility_actions_count = 0;
171 root.rect = {0, 0, 100, 100}; // LTRB
172 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
173 bridge->AddFlutterSemanticsNodeUpdate(root);
174
175 FlutterSemanticsNode2 child1;
176 child1.id = 1;
177 child1.label = "child 1";
178 child1.hint = "";
179 child1.value = "";
180 child1.increased_value = "";
181 child1.decreased_value = "";
182 child1.tooltip = "";
183 child1.child_count = 0;
184 child1.custom_accessibility_actions_count = 0;
185 child1.rect = {90, 90, 100, 100}; // LTRB
186 child1.transform = {2, 0, 0, 0, 2, 0, 0, 0, 1};
187 bridge->AddFlutterSemanticsNodeUpdate(child1);
188
189 bridge->CommitUpdates();
190 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
191 ui::AXOffscreenResult result;
192 gfx::Rect bounds =
193 child1_node->GetBoundsRect(ui::AXCoordinateSystem::kScreenDIPs,
194 ui::AXClippingBehavior::kUnclipped, &result);
195 EXPECT_EQ(bounds.x(), 180);
196 EXPECT_EQ(bounds.y(), 180);
197 EXPECT_EQ(bounds.width(), 20);
198 EXPECT_EQ(bounds.height(), 20);
199 EXPECT_EQ(result, ui::AXOffscreenResult::kOffscreen);
200 }

## ◆ TEST() [61/108]

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

Definition at line 84 of file flutter_platform_node_delegate_unittests.cc.

84 {
85 // Set up a flutter accessibility node.
86 std::shared_ptr<TestAccessibilityBridge> bridge =
87 std::make_shared<TestAccessibilityBridge>();
88 FlutterSemanticsNode2 root;
89 root.id = 0;
90 root.flags = FlutterSemanticsFlag::kFlutterSemanticsFlagIsTextField;
91 root.actions = static_cast<FlutterSemanticsAction>(0);
92 root.text_selection_base = -1;
93 root.text_selection_extent = -1;
94 root.label = "root";
95 root.hint = "";
96 root.value = "";
97 root.increased_value = "";
98 root.decreased_value = "";
99 root.tooltip = "";
100 root.child_count = 0;
101 root.custom_accessibility_actions_count = 0;
102 bridge->AddFlutterSemanticsNodeUpdate(root);
103
104 bridge->CommitUpdates();
105
106 auto accessibility = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
107 EXPECT_EQ(accessibility->GetData().id, 0);
108 }

## ◆ TEST() [62/108]

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

Definition at line 271 of file flutter_platform_node_delegate_unittests.cc.

271 {
272 std::shared_ptr<TestAccessibilityBridge> bridge =
273 std::make_shared<TestAccessibilityBridge>();
274 FlutterSemanticsNode2 root;
275 root.id = 0;
276 root.label = "root";
277 root.hint = "";
278 root.value = "";
279 root.increased_value = "";
280 root.decreased_value = "";
281 root.tooltip = "";
282 root.child_count = 1;
283 int32_t children[] = {1};
284 root.children_in_traversal_order = children;
285 root.custom_accessibility_actions_count = 0;
286 bridge->AddFlutterSemanticsNodeUpdate(root);
287
288 FlutterSemanticsNode2 child1;
289 child1.id = 1;
290 child1.label = "child 1";
291 child1.hint = "";
292 child1.value = "";
293 child1.increased_value = "";
294 child1.decreased_value = "";
295 child1.tooltip = "";
296 child1.child_count = 0;
297 child1.custom_accessibility_actions_count = 0;
298 bridge->AddFlutterSemanticsNodeUpdate(child1);
299
300 bridge->CommitUpdates();
301 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
302 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
303 auto node_by_id = root_node->GetFromNodeID(1);
304 EXPECT_EQ(child1_node->GetPlatformNode(), node_by_id);
305 }

## ◆ TEST() [63/108]

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

Definition at line 40 of file flutter_platform_node_delegate_unittests.cc.

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

## ◆ TEST() [64/108]

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

Definition at line 202 of file flutter_platform_node_delegate_unittests.cc.

202 {
203 std::shared_ptr<TestAccessibilityBridge> bridge =
204 std::make_shared<TestAccessibilityBridge>();
205 FlutterSemanticsNode2 root;
206 root.id = 0;
207 root.label = "root";
208 root.hint = "";
209 root.value = "";
210 root.increased_value = "";
211 root.decreased_value = "";
212 root.tooltip = "";
213 root.child_count = 1;
214 int32_t children[] = {1};
215 root.children_in_traversal_order = children;
216 root.custom_accessibility_actions_count = 0;
217 root.rect = {0, 0, 100, 100}; // LTRB
218 root.transform = {1, 0, 0, 0, 1, 0, 0, 0, 1};
219 bridge->AddFlutterSemanticsNodeUpdate(root);
220
221 FlutterSemanticsNode2 child1;
222 child1.id = 1;
223 child1.label = "child 1";
224 child1.hint = "";
225 child1.value = "";
226 child1.increased_value = "";
227 child1.decreased_value = "";
228 child1.tooltip = "";
229 child1.child_count = 0;
230 child1.custom_accessibility_actions_count = 0;
231 child1.rect = {0, 0, 50, 50}; // LTRB
232 child1.transform = {0.5, 0, 0, 0, 0.5, 0, 0, 0, 1};
233 bridge->AddFlutterSemanticsNodeUpdate(child1);
234
235 bridge->CommitUpdates();
236 auto child1_node = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
237 auto owner_bridge = child1_node->GetOwnerBridge().lock();
238
239 bool result;
240 gfx::RectF bounds = owner_bridge->RelativeToGlobalBounds(
241 child1_node->GetAXNode(), result, true);
242 EXPECT_EQ(bounds.x(), 0);
243 EXPECT_EQ(bounds.y(), 0);
244 EXPECT_EQ(bounds.width(), 25);
245 EXPECT_EQ(bounds.height(), 25);
246 EXPECT_EQ(result, false);
247 }

## ◆ TEST() [65/108]

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 node0.child_count = node0_children.size();
23 node0.children_in_traversal_order = node0_children.data();
24 node0.children_in_hit_test_order = node0_children.data();
25
26 // Add node 1: text child of node 0.
27 FlutterSemanticsNode2 node1{sizeof(FlutterSemanticsNode2), 1};
28 node1.label = "prefecture";
29 node1.value = "Kyoto";
30
31 bridge->AddFlutterSemanticsNodeUpdate(node0);
32 bridge->AddFlutterSemanticsNodeUpdate(node1);
33 bridge->CommitUpdates();
34
35 auto node0_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
36 auto node1_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
37 EXPECT_TRUE(node0_delegate->GetUniqueId() != node1_delegate->GetUniqueId());
38 }

## ◆ TEST() [66/108]

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

Definition at line 249 of file flutter_platform_node_delegate_unittests.cc.

249 {
250 std::shared_ptr<TestAccessibilityBridge> bridge =
251 std::make_shared<TestAccessibilityBridge>();
252 FlutterSemanticsNode2 root;
253 root.id = 0;
254 root.label = "root";
255 root.hint = "";
256 root.value = "";
257 root.increased_value = "";
258 root.decreased_value = "";
259 root.tooltip = "";
260 root.child_count = 0;
261 root.children_in_traversal_order = nullptr;
262 root.custom_accessibility_actions_count = 0;
263 bridge->AddFlutterSemanticsNodeUpdate(root);
264
265 bridge->CommitUpdates();
266 auto root_node = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
267 auto lowest_platform_ancestor = root_node->GetLowestPlatformAncestor();
268 EXPECT_EQ(root_node->GetNativeViewAccessible(), lowest_platform_ancestor);
269 }

## ◆ TEST() [67/108]

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() [68/108]

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() [69/108]

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

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
148 FlutterMethodCall* methodCall =
149 [FlutterMethodCall methodCallWithMethodName:@"dispose"
150 arguments:[NSNumber numberWithLongLong:20]];
151
152 __block bool errored = false;
153 FlutterResult result = ^(id result) {
154 if ([result isKindOfClass:[FlutterError class]]) {
155 errored = true;
156 }
157 };
158
159 [platformViewController handleMethodCall:methodCall result:result];
160
161 EXPECT_TRUE(errored);
162 }

## ◆ TEST() [70/108]

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 }

References TestFlutterPlatformView::args.

## ◆ TEST() [71/108]

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

Definition at line 96 of file FlutterSurfaceManagerTest.mm.

96 {
97 TestView* testView = [[TestView alloc] init];
98 FlutterSurfaceManager* surfaceManager = CreateSurfaceManager(testView);
99 EXPECT_EQ(surfaceManager.backBufferCache.count, 0ul);
100
101 auto surface1 = [surfaceManager surfaceForSize:CGSizeMake(100, 100)];
102 [surfaceManager present:@[ CreatePresentInfo(surface1) ] notify:nil];
103
104 EXPECT_EQ(surfaceManager.backBufferCache.count, 0ul);
105
106 auto surface2 = [surfaceManager surfaceForSize:CGSizeMake(110, 110)];
107 [surfaceManager present:@[ CreatePresentInfo(surface2) ] notify:nil];
108
109 EXPECT_EQ(surfaceManager.backBufferCache.count, 1ul);
110
111 auto surface3 = [surfaceManager surfaceForSize:CGSizeMake(120, 120)];
112 [surfaceManager present:@[ CreatePresentInfo(surface3) ] notify:nil];
113
114 // Cache should be cleaned during present and only contain the last visible
115 // surface(s).
116 EXPECT_EQ(surfaceManager.backBufferCache.count, 1ul);
117 auto surfaceFromCache = [surfaceManager surfaceForSize:CGSizeMake(110, 110)];
118 EXPECT_EQ(surfaceFromCache, surface2);
119
120 [surfaceManager present:@[] notify:nil];
121 EXPECT_EQ(surfaceManager.backBufferCache.count, 1ul);
122
123 [surfaceManager present:@[] notify:nil];
124 EXPECT_EQ(surfaceManager.backBufferCache.count, 0ul);
125 }

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

## ◆ TEST() [72/108]

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

Definition at line 170 of file FlutterSurfaceManagerTest.mm.

170 {
171 TestView* testView = [[TestView alloc] init];
172 FlutterSurfaceManager* surfaceManager = CreateSurfaceManager(testView);
173
174 EXPECT_EQ(testView.layer.sublayers.count, 0ul);
175
176 auto surface1_1 = [surfaceManager surfaceForSize:CGSizeMake(50, 30)];
177 [surfaceManager present:@[ CreatePresentInfo(surface1_1, CGPointMake(20, 10)) ] notify:nil];
178
179 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
180 EXPECT_TRUE(CGSizeEqualToSize(testView.presentedFrameSize, CGSizeMake(70, 40)));
181
182 auto surface2_1 = [surfaceManager surfaceForSize:CGSizeMake(50, 30)];
183 auto surface2_2 = [surfaceManager surfaceForSize:CGSizeMake(20, 20)];
184 [surfaceManager present:@[
185 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
186 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
187 {
188 FlutterRect{0, 0, 20, 20},
189 FlutterRect{40, 0, 60, 20},
190 })
191 ]
192 notify:nil];
193
194 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
195 EXPECT_EQ(testView.layer.sublayers[0].zPosition, 1.0);
196 EXPECT_EQ(testView.layer.sublayers[1].zPosition, 2.0);
197 CALayer* firstOverlaySublayer;
198 {
199 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
200 EXPECT_EQ(sublayers.count, 2ul);
201 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 0, 10, 10)));
202 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].frame, CGRectMake(20, 0, 10, 10)));
203 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].contentsRect, CGRectMake(0, 0, 1, 1)));
204 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].contentsRect, CGRectMake(2, 0, 1, 1)));
205 EXPECT_EQ(sublayers[0].contents, sublayers[1].contents);
206 firstOverlaySublayer = sublayers[0];
207 }
208 EXPECT_TRUE(CGSizeEqualToSize(testView.presentedFrameSize, CGSizeMake(70, 70)));
209
210 // Check second overlay sublayer is removed while first is reused and updated
211 [surfaceManager present:@[
212 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
213 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
214 {
215 FlutterRect{0, 10, 20, 20},
216 })
217 ]
218 notify:nil];
219 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
220 {
221 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
222 EXPECT_EQ(sublayers.count, 1ul);
223 EXPECT_EQ(sublayers[0], firstOverlaySublayer);
224 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 5, 10, 5)));
225 }
226
227 // Check that second overlay sublayer is added back while first is reused and updated
228 [surfaceManager present:@[
229 CreatePresentInfo(surface2_1, CGPointMake(20, 10), 1),
230 CreatePresentInfo(surface2_2, CGPointMake(40, 50), 2,
231 {
232 FlutterRect{0, 0, 20, 20},
233 FlutterRect{40, 0, 60, 20},
234 })
235 ]
236 notify:nil];
237
238 EXPECT_EQ(testView.layer.sublayers.count, 2ul);
239 {
240 NSArray<CALayer*>* sublayers = testView.layer.sublayers[1].sublayers;
241 EXPECT_EQ(sublayers.count, 2ul);
242 EXPECT_EQ(sublayers[0], firstOverlaySublayer);
243 EXPECT_TRUE(CGRectEqualToRect(sublayers[0].frame, CGRectMake(0, 0, 10, 10)));
244 EXPECT_TRUE(CGRectEqualToRect(sublayers[1].frame, CGRectMake(20, 0, 10, 10)));
245 EXPECT_EQ(sublayers[0].contents, sublayers[1].contents);
246 }
247
248 auto surface3_1 = [surfaceManager surfaceForSize:CGSizeMake(50, 30)];
249 [surfaceManager present:@[ CreatePresentInfo(surface3_1, CGPointMake(20, 10)) ] notify:nil];
250
251 EXPECT_EQ(testView.layer.sublayers.count, 1ul);
252 EXPECT_TRUE(CGSizeEqualToSize(testView.presentedFrameSize, CGSizeMake(70, 40)));
253
254 // Check removal of all surfaces.
255 [surfaceManager present:@[] notify:nil];
256 EXPECT_EQ(testView.layer.sublayers.count, 0ul);
257 EXPECT_TRUE(CGSizeEqualToSize(testView.presentedFrameSize, CGSizeMake(0, 0)));
258 }

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

## ◆ TEST() [73/108]

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

Definition at line 64 of file FlutterSurfaceManagerTest.mm.

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

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

## ◆ TEST() [74/108]

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

Definition at line 127 of file FlutterSurfaceManagerTest.mm.

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

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

## ◆ TEST() [75/108]

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

Definition at line 77 of file FlutterSurfaceManagerTest.mm.

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

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

## ◆ TEST() [76/108]

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

Definition at line 1986 of file FlutterTextInputPluginTest.mm.

1986 {
1987 FlutterEngine* engine = CreateTestEngine();
1988 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
1989 nibName:nil
1990 bundle:nil];
1991 [viewController loadView];
1992 // Creates a NSWindow so that the native text field can become first responder.
1993 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
1994 styleMask:NSBorderlessWindowMask
1995 backing:NSBackingStoreBuffered
1996 defer:NO];
1997 window.contentView = viewController.view;
1998
1999 engine.semanticsEnabled = YES;
2000
2001 auto bridge = viewController.accessibilityBridge.lock();
2002 FlutterPlatformNodeDelegateMac delegate(bridge, viewController);
2003 ui::AXTree tree;
2004 ui::AXNode ax_node(&tree, nullptr, 0, 0);
2005 ui::AXNodeData node_data;
2006 node_data.SetValue("initial text");
2007 ax_node.SetData(node_data);
2008 delegate.Init(viewController.accessibilityBridge, &ax_node);
2009 FlutterTextPlatformNode text_platform_node(&delegate, viewController);
2010
2011 FlutterTextField* textField = text_platform_node.GetNativeViewAccessible();
2012 EXPECT_EQ([textField becomeFirstResponder], YES);
2013 // Removes view controller.
2014 [engine setViewController:nil];
2015 FlutterTextPlatformNode text_platform_node_no_controller(&delegate, nil);
2016 textField = text_platform_node_no_controller.GetNativeViewAccessible();
2017 EXPECT_EQ([textField becomeFirstResponder], NO);
2018 }

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

## ◆ TEST() [77/108]

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

Definition at line 1921 of file FlutterTextInputPluginTest.mm.

1921 {
1922 FlutterEngine* engine = CreateTestEngine();
1923 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
1924 nibName:nil
1925 bundle:nil];
1926 [viewController loadView];
1927 // Create a NSWindow so that the native text field can become first responder.
1928 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
1929 styleMask:NSBorderlessWindowMask
1930 backing:NSBackingStoreBuffered
1931 defer:NO];
1932 window.contentView = viewController.view;
1933
1934 engine.semanticsEnabled = YES;
1935
1936 auto bridge = viewController.accessibilityBridge.lock();
1937 FlutterPlatformNodeDelegateMac delegate(bridge, viewController);
1938 ui::AXTree tree;
1939 ui::AXNode ax_node(&tree, nullptr, 0, 0);
1940 ui::AXNodeData node_data;
1941 node_data.SetValue("initial text");
1942 ax_node.SetData(node_data);
1943 delegate.Init(viewController.accessibilityBridge, &ax_node);
1944 {
1945 FlutterTextPlatformNode text_platform_node(&delegate, viewController);
1946
1947 FlutterTextFieldMock* mockTextField =
1948 [[FlutterTextFieldMock alloc] initWithPlatformNode:&text_platform_node
1949 fieldEditor:viewController.textInputPlugin];
1950 [viewController.view addSubview:mockTextField];
1951 [mockTextField startEditing];
1952
1953 NSDictionary* setClientConfig = @{
1954 @"inputAction" : @"action",
1955 @"inputType" : @{@"name" : @"inputName"},
1956 };
1957 FlutterMethodCall* methodCall =
1958 [FlutterMethodCall methodCallWithMethodName:@"TextInput.setClient"
1959 arguments:@[ @(1), setClientConfig ]];
1960 FlutterResult result = ^(id result) {
1961 };
1962 [viewController.textInputPlugin handleMethodCall:methodCall result:result];
1963
1964 NSDictionary* arguments = @{
1965 @"text" : @"new text",
1966 @"selectionBase" : @(1),
1967 @"selectionExtent" : @(2),
1968 @"composingBase" : @(-1),
1969 @"composingExtent" : @(-1),
1970 };
1971 methodCall = [FlutterMethodCall methodCallWithMethodName:@"TextInput.setEditingState"
1972 arguments:arguments];
1973 [viewController.textInputPlugin handleMethodCall:methodCall result:result];
1974 EXPECT_EQ([mockTextField.lastUpdatedString isEqualToString:@"new text"], YES);
1975 EXPECT_EQ(NSEqualRanges(mockTextField.lastUpdatedSelection, NSMakeRange(1, 1)), YES);
1976
1977 // This blocks the FlutterTextFieldMock, which is held onto by the main event
1978 // loop, from crashing.
1979 [mockTextField setPlatformNode:nil];
1980 }
1981
1982 // This verifies that clearing the platform node works.
1983 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
1984 }

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

## ◆ TEST() [78/108]

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

Definition at line 2053 of file FlutterTextInputPluginTest.mm.

2053 {
2054 FlutterEngine* engine = CreateTestEngine();
2055 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2056 nibName:nil
2057 bundle:nil];
2058 [viewController loadView];
2059
2060 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
2061 styleMask:NSBorderlessWindowMask
2062 backing:NSBackingStoreBuffered
2063 defer:NO];
2064 window.contentView = viewController.view;
2065
2066 ASSERT_TRUE(viewController.flutterView.acceptsFirstResponder);
2067
2068 [window makeFirstResponder:viewController.flutterView];
2069
2070 [viewController.textInputPlugin
2071 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.show" arguments:@[]]
2072 result:^(id){
2073 }];
2074
2075 ASSERT_TRUE(window.firstResponder == viewController.textInputPlugin);
2076
2077 ASSERT_FALSE(viewController.flutterView.acceptsFirstResponder);
2078
2079 [viewController.textInputPlugin
2080 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.hide" arguments:@[]]
2081 result:^(id){
2082 }];
2083
2084 ASSERT_TRUE(viewController.flutterView.acceptsFirstResponder);
2085 ASSERT_TRUE(window.firstResponder == viewController.flutterView);
2086 }

References FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST() [79/108]

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

Definition at line 1901 of file FlutterTextInputPluginTest.mm.

1901 {
1902 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] handleArrowKeyWhenImePopoverIsActive]);
1903 }

## ◆ TEST() [80/108]

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

Definition at line 2088 of file FlutterTextInputPluginTest.mm.

2088 {
2089 id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
2090 id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
2091 OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
2092 [engineMock binaryMessenger])
2093 .andReturn(binaryMessengerMock);
2094
2095 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
2096 nibName:@""
2097 bundle:nil];
2098
2099 FlutterTextInputPlugin* plugin =
2100 [[FlutterTextInputPlugin alloc] initWithViewController:viewController];
2101
2102 ASSERT_TRUE(NSIsEmptyRect(plugin.frame));
2103 ASSERT_TRUE(plugin.clipsToBounds);
2104 }

References CreateMockFlutterEngine().

## ◆ TEST() [81/108]

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

Definition at line 2020 of file FlutterTextInputPluginTest.mm.

2020 {
2021 FlutterEngine* engine = CreateTestEngine();
2022 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
2023 nibName:nil
2024 bundle:nil];
2025 [viewController loadView];
2026
2027 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
2028 styleMask:NSBorderlessWindowMask
2029 backing:NSBackingStoreBuffered
2030 defer:NO];
2031 window.contentView = viewController.view;
2032
2033 ASSERT_EQ(viewController.textInputPlugin.superview, nil);
2034 ASSERT_FALSE(window.firstResponder == viewController.textInputPlugin);
2035
2036 [viewController.textInputPlugin
2037 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.show" arguments:@[]]
2038 result:^(id){
2039 }];
2040
2041 ASSERT_EQ(viewController.textInputPlugin.superview, viewController.view);
2042 ASSERT_TRUE(window.firstResponder == viewController.textInputPlugin);
2043
2044 [viewController.textInputPlugin
2045 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"TextInput.hide" arguments:@[]]
2046 result:^(id){
2047 }];
2048
2049 ASSERT_EQ(viewController.textInputPlugin.superview, nil);
2050 ASSERT_FALSE(window.firstResponder == viewController.textInputPlugin);
2051 }

References FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST() [82/108]

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

Definition at line 1859 of file FlutterTextInputPluginTest.mm.

1859 {
1860 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc]
1861 testAutocompleteDisabledWhenAutofillGroupIncludesPassword]);
1862 }

## ◆ TEST() [83/108]

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

Definition at line 1839 of file FlutterTextInputPluginTest.mm.

1839 {
1840 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testAutocompleteDisabledWhenAutofillNotSet]);
1841 }

## ◆ TEST() [84/108]

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

Definition at line 1851 of file FlutterTextInputPluginTest.mm.

1851 {
1852 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testAutocompleteDisabledWhenObscureTextSet]);
1853 }

## ◆ TEST() [85/108]

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

Definition at line 1855 of file FlutterTextInputPluginTest.mm.

1855 {
1856 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testAutocompleteDisabledWhenPasswordAutofillSet]);
1857 }

## ◆ TEST() [86/108]

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

Definition at line 1843 of file FlutterTextInputPluginTest.mm.

1843 {
1844 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testAutocompleteEnabledWhenAutofillSet]);
1845 }

## ◆ TEST() [87/108]

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

Definition at line 1847 of file FlutterTextInputPluginTest.mm.

1847 {
1848 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testAutocompleteEnabledWhenAutofillSetNoHint]);
1849 }

## ◆ TEST() [88/108]

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

Definition at line 1835 of file FlutterTextInputPluginTest.mm.

1835 {
1836 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testClearClientDuringComposing]);
1837 }

## ◆ TEST() [89/108]

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

Definition at line 1831 of file FlutterTextInputPluginTest.mm.

1831 {
1832 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testComposingRegionRemovedByFramework]);
1833 }

## ◆ TEST() [90/108]

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

Definition at line 1885 of file FlutterTextInputPluginTest.mm.

1885 {
1886 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testComposingWithDelta]);
1887 }

## ◆ TEST() [91/108]

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

Definition at line 1889 of file FlutterTextInputPluginTest.mm.

1889 {
1890 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testComposingWithDeltasWhenSelectionIsActive]);
1891 }

## ◆ TEST() [92/108]

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

Definition at line 1819 of file FlutterTextInputPluginTest.mm.

1819 {
1820 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testEmptyCompositionRange]);
1821 }

## ◆ TEST() [93/108]

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

Definition at line 1864 of file FlutterTextInputPluginTest.mm.

1864 {
1865 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testFirstRectForCharacterRange]);
1866 }

## ◆ TEST() [94/108]

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

Definition at line 1868 of file FlutterTextInputPluginTest.mm.

1868 {
1869 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testFirstRectForCharacterRangeAtInfinity]);
1870 }

## ◆ TEST() [95/108]

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

Definition at line 1872 of file FlutterTextInputPluginTest.mm.

1872 {
1873 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc]
1874 testFirstRectForCharacterRangeWithEsotericAffineTransform]);
1875 }

## ◆ TEST() [96/108]

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

Definition at line 1913 of file FlutterTextInputPluginTest.mm.

1913 {
1914 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testInsertNewLine]);
1915 }

## ◆ TEST() [97/108]

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

Definition at line 1893 of file FlutterTextInputPluginTest.mm.

1893 {
1894 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testLocalTextAndSelectionUpdateAfterDelta]);
1895 }

## ◆ TEST() [98/108]

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

Definition at line 1881 of file FlutterTextInputPluginTest.mm.

1881 {
1882 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testOperationsThatTriggerDelta]);
1883 }

## ◆ TEST() [99/108]

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

Definition at line 1897 of file FlutterTextInputPluginTest.mm.

1897 {
1898 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testPerformKeyEquivalent]);
1899 }

## ◆ TEST() [100/108]

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

Definition at line 1909 of file FlutterTextInputPluginTest.mm.

1909 {
1910 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSelectorsAreForwardedToFramework]);
1911 }

## ◆ TEST() [101/108]

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

Definition at line 1917 of file FlutterTextInputPluginTest.mm.

1917 {
1918 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSendActionDoNotInsertNewLine]);
1919 }

## ◆ TEST() [102/108]

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

Definition at line 1877 of file FlutterTextInputPluginTest.mm.

1877 {
1878 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSetEditingStateWithTextEditingDelta]);
1879 }

## ◆ TEST() [103/108]

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

Definition at line 1827 of file FlutterTextInputPluginTest.mm.

1827 {
1828 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSetMarkedTextWithReplacementRange]);
1829 }

## ◆ TEST() [104/108]

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

Definition at line 1823 of file FlutterTextInputPluginTest.mm.

1823 {
1824 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] testSetMarkedTextWithSelectionChange]);
1825 }

## ◆ TEST() [105/108]

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

Definition at line 1905 of file FlutterTextInputPluginTest.mm.

1905 {
1906 ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] unhandledKeyEquivalent]);
1907 }

## ◆ TEST() [106/108]

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() [107/108]

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

Definition at line 21 of file FlutterViewEngineProviderTest.mm.

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

References CreateMockFlutterEngine(), and kFlutterImplicitViewId.

## ◆ TEST() [108/108]

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 }

References flutter::kLayoutGoals.

## ◆ TEST_F() [1/63]

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

Definition at line 213 of file AccessibilityBridgeMacTest.mm.

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

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

## ◆ TEST_F() [2/63]

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

Definition at line 259 of file AccessibilityBridgeMacTest.mm.

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

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

## ◆ TEST_F() [3/63]

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

Definition at line 147 of file AccessibilityBridgeMacTest.mm.

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

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

## ◆ TEST_F() [4/63]

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 root.id = 0;
103 root.flags = static_cast<FlutterSemanticsFlag>(0);
104 root.actions = static_cast<FlutterSemanticsAction>(0);
105 root.text_selection_base = -1;
106 root.text_selection_extent = -1;
107 root.label = "root";
108 root.hint = "";
109 root.value = "";
110 root.increased_value = "";
111 root.decreased_value = "";
112 root.tooltip = "";
113 root.child_count = 0;
114 root.custom_accessibility_actions_count = 0;
115 bridge->AddFlutterSemanticsNodeUpdate(root);
116
117 bridge->CommitUpdates();
118 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
119
120 // Creates a targeted event.
121 ui::AXTree tree;
122 ui::AXNode ax_node(&tree, nullptr, 0, 0);
123 ui::AXNodeData node_data;
124 node_data.id = 0;
125 ax_node.SetData(node_data);
126 std::vector<ui::AXEventIntent> intent;
127 ui::AXEventGenerator::EventParams event_params(ui::AXEventGenerator::Event::CHILDREN_CHANGED,
128 ax::mojom::EventFrom::kNone, intent);
129 ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params);
130
131 bridge->OnAccessibilityEvent(targeted_event);
132
133 ASSERT_EQ(bridge->actual_notifications.size(), 1u);
134 auto target = bridge->actual_notifications.find([NSAccessibilityCreatedNotification UTF8String]);
135 ASSERT_NE(target, bridge->actual_notifications.end());
136 EXPECT_EQ(target->second, expectedTarget);
137 [engine shutDownEngine];
138 }

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

## ◆ TEST_F() [5/63]

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 }

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

## ◆ TEST_F() [6/63]

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/63]

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 }

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

## ◆ TEST_F() [8/63]

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

Definition at line 131 of file FlutterEmbedderExternalTextureTest.mm.

131 {
132 // Constants.
133 const size_t width = 100;
134 const size_t height = 100;
135 const int64_t texture_id = 1;
136
137 // Set up the surface.
138 FlutterDarwinContextMetalSkia* darwinContextMetal =
139 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
140 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
141 GrDirectContext* grContext = darwinContextMetal.mainContext.get();
142 sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));
143
144 // Create a texture.
145 TestExternalTexture* testExternalTexture =
146 [[TestExternalTexture alloc] initWidth:width
147 height:height
148 pixelFormatType:kCVPixelFormatType_32BGRA];
149 FlutterExternalTexture* textureHolder =
150 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
151 darwinMetalContext:darwinContextMetal];
152
153 // Callback to resolve the texture.
154 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
155 size_t h) {
156 EXPECT_TRUE(w == width);
157 EXPECT_TRUE(h == height);
158
159 auto texture = std::make_unique<FlutterMetalExternalTexture>();
160 [textureHolder populateTexture:texture.get()];
161
162 EXPECT_TRUE(texture->num_textures == 1);
163 EXPECT_TRUE(texture->textures != nullptr);
164 EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kRGBA);
165 return texture;
166 };
167
168 // Render the texture.
169 std::unique_ptr<flutter::Texture> texture =
170 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
171 SkRect bounds = SkRect::MakeWH(info.width(), info.height());
172 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
173 DlSkCanvasAdapter canvas(gpuSurface->getCanvas());
174 flutter::Texture::PaintContext context{
175 .canvas = &canvas,
176 .gr_context = grContext,
177 };
178 texture->Paint(context, bounds, /*freeze=*/false, sampling);
179
180 gpuSurface->makeImageSnapshot();
181 }

References FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST_F() [9/63]

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

Definition at line 183 of file FlutterEmbedderExternalTextureTest.mm.

183 {
184 // Constants.
185 const size_t width = 100;
186 const size_t height = 100;
187 const int64_t texture_id = 1;
188
189 // Set up the surface.
190 FlutterDarwinContextMetalSkia* darwinContextMetal =
191 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
192 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
193 GrDirectContext* grContext = darwinContextMetal.mainContext.get();
194 sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));
195
196 // Create a texture.
197 TestExternalTexture* testExternalTexture =
198 [[TestExternalTexture alloc] initWidth:width
199 height:height
200 pixelFormatType:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange];
201 FlutterExternalTexture* textureHolder =
202 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
203 darwinMetalContext:darwinContextMetal];
204
205 // Callback to resolve the texture.
206 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
207 size_t h) {
208 EXPECT_TRUE(w == width);
209 EXPECT_TRUE(h == height);
210
211 auto texture = std::make_unique<FlutterMetalExternalTexture>();
212 [textureHolder populateTexture:texture.get()];
213
214 EXPECT_TRUE(texture->num_textures == 2);
215 EXPECT_TRUE(texture->textures != nullptr);
216 EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kYUVA);
217 EXPECT_TRUE(texture->yuv_color_space ==
218 FlutterMetalExternalTextureYUVColorSpace::kBT601LimitedRange);
219 return texture;
220 };
221
222 // Render the texture.
223 std::unique_ptr<flutter::Texture> texture =
224 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
225 SkRect bounds = SkRect::MakeWH(info.width(), info.height());
226 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
227 DlSkCanvasAdapter canvas(gpuSurface->getCanvas());
228 flutter::Texture::PaintContext context{
229 .canvas = &canvas,
230 .gr_context = grContext,
231 };
232 texture->Paint(context, bounds, /*freeze=*/false, sampling);
233
234 gpuSurface->makeImageSnapshot();
235 }

References FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST_F() [10/63]

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

Definition at line 237 of file FlutterEmbedderExternalTextureTest.mm.

237 {
238 // Constants.
239 const size_t width = 100;
240 const size_t height = 100;
241 const int64_t texture_id = 1;
242
243 // Set up the surface.
244 FlutterDarwinContextMetalSkia* darwinContextMetal =
245 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
246 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
247 GrDirectContext* grContext = darwinContextMetal.mainContext.get();
248 sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));
249
250 // Create a texture.
251 TestExternalTexture* testExternalTexture =
252 [[TestExternalTexture alloc] initWidth:width
253 height:height
254 pixelFormatType:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange];
255 FlutterExternalTexture* textureHolder =
256 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
257 darwinMetalContext:darwinContextMetal];
258
259 // Callback to resolve the texture.
260 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
261 size_t h) {
262 EXPECT_TRUE(w == width);
263 EXPECT_TRUE(h == height);
264
265 auto texture = std::make_unique<FlutterMetalExternalTexture>();
266 [textureHolder populateTexture:texture.get()];
267
268 EXPECT_TRUE(texture->num_textures == 2);
269 EXPECT_TRUE(texture->textures != nullptr);
270 EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kYUVA);
271 EXPECT_TRUE(texture->yuv_color_space ==
272 FlutterMetalExternalTextureYUVColorSpace::kBT601FullRange);
273 return texture;
274 };
275
276 // Render the texture.
277 std::unique_ptr<flutter::Texture> texture =
278 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
279 SkRect bounds = SkRect::MakeWH(info.width(), info.height());
280 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
281 DlSkCanvasAdapter canvas(gpuSurface->getCanvas());
282 flutter::Texture::PaintContext context{
283 .canvas = &canvas,
284 .gr_context = grContext,
285 };
286 texture->Paint(context, bounds, /*freeze=*/false, sampling);
287
288 gpuSurface->makeImageSnapshot();
289 }

References FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST_F() [11/63]

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

Definition at line 73 of file FlutterEmbedderExternalTextureTest.mm.

73 {
74 // Constants.
75 const size_t width = 100;
76 const size_t height = 100;
77 const int64_t texture_id = 1;
78
79 // Set up the surface.
80 FlutterDarwinContextMetalSkia* darwinContextMetal =
81 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
82 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
83 GrDirectContext* grContext = darwinContextMetal.mainContext.get();
84 sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));
85
86 // Create a texture.
87 MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init];
88 textureDescriptor.pixelFormat = MTLPixelFormatBGRA8Unorm;
89 textureDescriptor.width = width;
90 textureDescriptor.height = height;
91 textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
92 id<MTLTexture> mtlTexture =
93 [darwinContextMetal.device newTextureWithDescriptor:textureDescriptor];
94 std::vector<FlutterMetalTextureHandle> textures = {
95 (__bridge FlutterMetalTextureHandle)mtlTexture,
96 };
97
98 // Callback to resolve the texture.
99 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
100 size_t h) {
101 EXPECT_TRUE(w == width);
102 EXPECT_TRUE(h == height);
103
104 auto texture = std::make_unique<FlutterMetalExternalTexture>();
105 texture->struct_size = sizeof(FlutterMetalExternalTexture);
106 texture->num_textures = 1;
107 texture->height = h;
108 texture->width = w;
109 texture->pixel_format = FlutterMetalExternalTexturePixelFormat::kRGBA;
110 texture->textures = textures.data();
111 return texture;
112 };
113
114 // Render the texture.
115 std::unique_ptr<flutter::Texture> texture =
116 std::make_unique<EmbedderExternalTextureMetal>(texture_id, callback);
117 SkRect bounds = SkRect::MakeWH(info.width(), info.height());
118 DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
119 DlSkCanvasAdapter canvas(gpuSurface->getCanvas());
120 flutter::Texture::PaintContext context{
121 .canvas = &canvas,
122 .gr_context = grContext,
123 };
124 texture->Paint(context, bounds, /*freeze=*/false, sampling);
125
126 ASSERT_TRUE(mtlTexture != nil);
127
128 gpuSurface->makeImageSnapshot();
129 }

References texture_id.

## ◆ TEST_F() [12/63]

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

Definition at line 123 of file FlutterEngineTest.mm.

123 {
124 FlutterEngine* engine = GetFlutterEngine();
125 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
126 ASSERT_TRUE(engine.running);
127 }

## ◆ TEST_F() [13/63]

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

Definition at line 186 of file FlutterEngineTest.mm.

186 {
187 // Block until completion of print statement.
188 fml::AutoResetWaitableEvent latch;
189 AddNativeCallback("SignalNativeTest",
190 CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { latch.Signal(); }));
191
192 // Replace stdout stream buffer with our own.
193 StreamCapture stdout_capture(&std::cout);
194
195 // Launch the test entrypoint.
196 FlutterEngine* engine = GetFlutterEngine();
197 EXPECT_TRUE([engine runWithEntrypoint:@"canLogToStdout"]);
198 ASSERT_TRUE(engine.running);
199
200 latch.Wait();
201
202 stdout_capture.Stop();
203
204 // Verify hello world was written to stdout.
205 EXPECT_TRUE(stdout_capture.GetOutput().find("Hello logging") != std::string::npos);
206 }

## ◆ TEST_F() [14/63]

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

Definition at line 269 of file FlutterEngineTest.mm.

269 {
270 FlutterEngine* engine = GetFlutterEngine();
271 // Capture the update callbacks before the embedder API initializes.
272 auto original_init = engine.embedderAPI.Initialize;
273 std::function<void(const FlutterSemanticsUpdate2*, void*)> update_semantics_callback;
274 engine.embedderAPI.Initialize = MOCK_ENGINE_PROC(
275 Initialize, ([&update_semantics_callback, &original_init](
276 size_t version, const FlutterRendererConfig* config,
277 const FlutterProjectArgs* args, void* user_data, auto engine_out) {
278 update_semantics_callback = args->update_semantics_callback2;
279 return original_init(version, config, args, user_data, engine_out);
280 }));
281 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
282 // Set up view controller.
283 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
284 nibName:nil
285 bundle:nil];
286 [viewController loadView];
287 // Enable the semantics.
288 bool enabled_called = false;
289 engine.embedderAPI.UpdateSemanticsEnabled =
290 MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&enabled_called](auto engine, bool enabled) {
291 enabled_called = enabled;
292 return kSuccess;
293 }));
294 engine.semanticsEnabled = YES;
295 EXPECT_TRUE(enabled_called);
296 // Send flutter semantics updates.
297 FlutterSemanticsNode2 root;
298 root.id = 0;
299 root.flags = static_cast<FlutterSemanticsFlag>(0);
300 root.actions = static_cast<FlutterSemanticsAction>(0);
301 root.text_selection_base = -1;
302 root.text_selection_extent = -1;
303 root.label = "root";
304 root.hint = "";
305 root.value = "";
306 root.increased_value = "";
307 root.decreased_value = "";
308 root.tooltip = "";
309 root.child_count = 1;
310 int32_t children[] = {1};
311 root.children_in_traversal_order = children;
312 root.custom_accessibility_actions_count = 0;
313
314 FlutterSemanticsNode2 child1;
315 child1.id = 1;
316 child1.flags = static_cast<FlutterSemanticsFlag>(0);
317 child1.actions = static_cast<FlutterSemanticsAction>(0);
318 child1.text_selection_base = -1;
319 child1.text_selection_extent = -1;
320 child1.label = "child 1";
321 child1.hint = "";
322 child1.value = "";
323 child1.increased_value = "";
324 child1.decreased_value = "";
325 child1.tooltip = "";
326 child1.child_count = 0;
327 child1.custom_accessibility_actions_count = 0;
328
329 FlutterSemanticsUpdate2 update;
330 update.node_count = 2;
331 FlutterSemanticsNode2* nodes[] = {&root, &child1};
332 update.nodes = nodes;
333 update.custom_action_count = 0;
334 update_semantics_callback(&update, (__bridge void*)engine);
335
336 // Verify the accessibility tree is attached to the flutter view.
337 EXPECT_EQ([engine.viewController.flutterView.accessibilityChildren count], 1u);
338 NSAccessibilityElement* native_root = engine.viewController.flutterView.accessibilityChildren[0];
339 std::string root_label = [native_root.accessibilityLabel UTF8String];
340 EXPECT_TRUE(root_label == "root");
341 EXPECT_EQ(native_root.accessibilityRole, NSAccessibilityGroupRole);
342 EXPECT_EQ([native_root.accessibilityChildren count], 1u);
343 NSAccessibilityElement* native_child1 = native_root.accessibilityChildren[0];
344 std::string child1_value = [native_child1.accessibilityValue UTF8String];
345 EXPECT_TRUE(child1_value == "child 1");
346 EXPECT_EQ(native_child1.accessibilityRole, NSAccessibilityStaticTextRole);
347 EXPECT_EQ([native_child1.accessibilityChildren count], 0u);
348 // Disable the semantics.
349 bool semanticsEnabled = true;
350 engine.embedderAPI.UpdateSemanticsEnabled =
351 MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&semanticsEnabled](auto engine, bool enabled) {
352 semanticsEnabled = enabled;
353 return kSuccess;
354 }));
355 engine.semanticsEnabled = NO;
356 EXPECT_FALSE(semanticsEnabled);
357 // Verify the accessibility tree is removed from the view.
358 EXPECT_EQ([engine.viewController.flutterView.accessibilityChildren count], 0u);
359
360 [engine setViewController:nil];
361 }

References user_data.

## ◆ TEST_F() [15/63]

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

Definition at line 363 of file FlutterEngineTest.mm.

363 {
364 FlutterEngine* engine = GetFlutterEngine();
365 // Capture the update callbacks before the embedder API initializes.
366 auto original_init = engine.embedderAPI.Initialize;
367 std::function<void(const FlutterSemanticsUpdate2*, void*)> update_semantics_callback;
368 engine.embedderAPI.Initialize = MOCK_ENGINE_PROC(
369 Initialize, ([&update_semantics_callback, &original_init](
370 size_t version, const FlutterRendererConfig* config,
371 const FlutterProjectArgs* args, void* user_data, auto engine_out) {
372 update_semantics_callback = args->update_semantics_callback2;
373 return original_init(version, config, args, user_data, engine_out);
374 }));
375 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
376
377 // Enable the semantics without attaching a view controller.
378 bool enabled_called = false;
379 engine.embedderAPI.UpdateSemanticsEnabled =
380 MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&enabled_called](auto engine, bool enabled) {
381 enabled_called = enabled;
382 return kSuccess;
383 }));
384 engine.semanticsEnabled = YES;
385 EXPECT_TRUE(enabled_called);
386 // Send flutter semantics updates.
387 FlutterSemanticsNode2 root;
388 root.id = 0;
389 root.flags = static_cast<FlutterSemanticsFlag>(0);
390 root.actions = static_cast<FlutterSemanticsAction>(0);
391 root.text_selection_base = -1;
392 root.text_selection_extent = -1;
393 root.label = "root";
394 root.hint = "";
395 root.value = "";
396 root.increased_value = "";
397 root.decreased_value = "";
398 root.tooltip = "";
399 root.child_count = 1;
400 int32_t children[] = {1};
401 root.children_in_traversal_order = children;
402 root.custom_accessibility_actions_count = 0;
403
404 FlutterSemanticsNode2 child1;
405 child1.id = 1;
406 child1.flags = static_cast<FlutterSemanticsFlag>(0);
407 child1.actions = static_cast<FlutterSemanticsAction>(0);
408 child1.text_selection_base = -1;
409 child1.text_selection_extent = -1;
410 child1.label = "child 1";
411 child1.hint = "";
412 child1.value = "";
413 child1.increased_value = "";
414 child1.decreased_value = "";
415 child1.tooltip = "";
416 child1.child_count = 0;
417 child1.custom_accessibility_actions_count = 0;
418
419 FlutterSemanticsUpdate2 update;
420 update.node_count = 2;
421 FlutterSemanticsNode2* nodes[] = {&root, &child1};
422 update.nodes = nodes;
423 update.custom_action_count = 0;
424 // This call updates semantics for the implicit view, which does not exist,
425 // and therefore this call is invalid. But the engine should not crash.
426 update_semantics_callback(&update, (__bridge void*)engine);
427
428 // No crashes.
429 EXPECT_EQ(engine.viewController, nil);
430
431 // Disable the semantics.
432 bool semanticsEnabled = true;
433 engine.embedderAPI.UpdateSemanticsEnabled =
434 MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&semanticsEnabled](auto engine, bool enabled) {
435 semanticsEnabled = enabled;
436 return kSuccess;
437 }));
438 engine.semanticsEnabled = NO;
439 EXPECT_FALSE(semanticsEnabled);
440 // Still no crashes
441 EXPECT_EQ(engine.viewController, nil);
442 }

References user_data.

## ◆ TEST_F() [16/63]

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

Definition at line 485 of file FlutterEngineTest.mm.

485 {
486 NSString* fixtures = @(flutter::testing::GetFixturesPath());
487 FlutterDartProject* project = [[FlutterDartProject alloc]
488 initWithAssetsPath:fixtures
489 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
490 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:project];
491
492 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
493 nibName:nil
494 bundle:nil];
495 [viewController loadView];
496 viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);
497
498 EXPECT_TRUE([engine runWithEntrypoint:@"canCompositePlatformViews"]);
499
500 [engine.platformViewController registerViewFactory:[[TestPlatformViewFactory alloc] init]
501 withId:@"factory_id"];
502 [engine.platformViewController
503 handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"create"
504 arguments:@{
505 @"id" : @(42),
506 @"viewType" : @"factory_id",
507 }]
508 result:^(id result){
509 }];
510
511 [engine.testThreadSynchronizer blockUntilFrameAvailable];
512
513 CALayer* rootLayer = viewController.flutterView.layer;
514
515 // There are two layers with Flutter contents and one view
516 EXPECT_EQ(rootLayer.sublayers.count, 2u);
517 EXPECT_EQ(viewController.flutterView.subviews.count, 1u);
518
519 // TODO(gw280): add support for screenshot tests in this test harness
520
521 [engine shutDownEngine];
522 } // namespace flutter::testing

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

## ◆ TEST_F() [17/63]

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

Definition at line 524 of file FlutterEngineTest.mm.

524 {
525 NSString* fixtures = @(flutter::testing::GetFixturesPath());
526 FlutterDartProject* project = [[FlutterDartProject alloc]
527 initWithAssetsPath:fixtures
528 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
529
530 project.dartEntrypointArguments = @[ @"arg1", @"arg2" ];
531 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:project];
532
533 bool called = false;
534 auto original_init = engine.embedderAPI.Initialize;
535 engine.embedderAPI.Initialize = MOCK_ENGINE_PROC(
536 Initialize, ([&called, &original_init](size_t version, const FlutterRendererConfig* config,
537 const FlutterProjectArgs* args, void* user_data,
538 FLUTTER_API_SYMBOL(FlutterEngine) * engine_out) {
539 called = true;
540 EXPECT_EQ(args->dart_entrypoint_argc, 2);
541 NSString* arg1 = [[NSString alloc] initWithCString:args->dart_entrypoint_argv[0]
542 encoding:NSUTF8StringEncoding];
543 NSString* arg2 = [[NSString alloc] initWithCString:args->dart_entrypoint_argv[1]
544 encoding:NSUTF8StringEncoding];
545
546 EXPECT_TRUE([arg1 isEqualToString:@"arg1"]);
547 EXPECT_TRUE([arg2 isEqualToString:@"arg2"]);
548
549 return original_init(version, config, args, user_data, engine_out);
550 }));
551
552 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
553 EXPECT_TRUE(called);
554 }

References user_data.

## ◆ TEST_F() [18/63]

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

Definition at line 209 of file FlutterEngineTest.mm.

209 {
210 FlutterEngine* engine = GetFlutterEngine();
211
212 // Latch to ensure the entire layer tree has been generated and presented.
213 fml::AutoResetWaitableEvent latch;
214 AddNativeCallback("SignalNativeTest", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
215 CALayer* rootLayer = engine.viewController.flutterView.layer;
216 EXPECT_TRUE(rootLayer.backgroundColor != nil);
217 if (rootLayer.backgroundColor != nil) {
218 NSColor* actualBackgroundColor =
219 [NSColor colorWithCGColor:rootLayer.backgroundColor];
220 EXPECT_EQ(actualBackgroundColor, [NSColor blackColor]);
221 }
222 latch.Signal();
223 }));
224
225 // Launch the test entrypoint.
226 EXPECT_TRUE([engine runWithEntrypoint:@"backgroundTest"]);
227 ASSERT_TRUE(engine.running);
228
229 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
230 nibName:nil
231 bundle:nil];
232 [viewController loadView];
233 viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);
234
235 latch.Wait();
236 }

References FlutterEngine::viewController.

## ◆ TEST_F() [19/63]

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

Definition at line 239 of file FlutterEngineTest.mm.

239 {
240 FlutterEngine* engine = GetFlutterEngine();
241
242 // Latch to ensure the entire layer tree has been generated and presented.
243 fml::AutoResetWaitableEvent latch;
244 AddNativeCallback("SignalNativeTest", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
245 CALayer* rootLayer = engine.viewController.flutterView.layer;
246 EXPECT_TRUE(rootLayer.backgroundColor != nil);
247 if (rootLayer.backgroundColor != nil) {
248 NSColor* actualBackgroundColor =
249 [NSColor colorWithCGColor:rootLayer.backgroundColor];
250 EXPECT_EQ(actualBackgroundColor, [NSColor whiteColor]);
251 }
252 latch.Signal();
253 }));
254
255 // Launch the test entrypoint.
256 EXPECT_TRUE([engine runWithEntrypoint:@"backgroundTest"]);
257 ASSERT_TRUE(engine.running);
258
259 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
260 nibName:nil
261 bundle:nil];
262 [viewController loadView];
263 viewController.flutterView.frame = CGRectMake(0, 0, 800, 600);
264 viewController.flutterView.backgroundColor = [NSColor whiteColor];
265
266 latch.Wait();
267 }

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

## ◆ TEST_F() [20/63]

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

Definition at line 562 of file FlutterEngineTest.mm.

562 {
563 __weak FlutterEngine* weakEngine;
564 id<FlutterBinaryMessenger> binaryMessenger = nil;
565 @autoreleasepool {
566 // Create a test engine.
567 NSString* fixtures = @(flutter::testing::GetFixturesPath());
568 FlutterDartProject* project = [[FlutterDartProject alloc]
569 initWithAssetsPath:fixtures
570 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
571 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
572 project:project
573 allowHeadlessExecution:YES];
574 weakEngine = engine;
575 binaryMessenger = engine.binaryMessenger;
576 }
577
578 // Once the engine has been deallocated, verify the weak engine pointer is nil, and thus not
579 // retained by the relay.
580 EXPECT_NE(binaryMessenger, nil);
581 EXPECT_EQ(weakEngine, nil);
582 }

References FlutterEngine::binaryMessenger.

## ◆ TEST_F() [21/63]

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

Definition at line 586 of file FlutterEngineTest.mm.

586 {
587 __weak FlutterEngine* weakEngine;
588 id<FlutterTextureRegistry> textureRegistry;
589 @autoreleasepool {
590 // Create a test engine.
591 NSString* fixtures = @(flutter::testing::GetFixturesPath());
592 FlutterDartProject* project = [[FlutterDartProject alloc]
593 initWithAssetsPath:fixtures
594 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
595 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
596 project:project
597 allowHeadlessExecution:YES];
598 id<FlutterPluginRegistrar> registrar = [engine registrarForPlugin:@"MyPlugin"];
599 textureRegistry = registrar.textures;
600 }
601
602 // Once the engine has been deallocated, verify the weak engine pointer is nil, and thus not
603 // retained via the texture registry.
604 EXPECT_NE(textureRegistry, nil);
605 EXPECT_EQ(weakEngine, nil);
606 }

## ◆ TEST_F() [22/63]

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

Definition at line 1064 of file FlutterEngineTest.mm.

1064 {
1065 id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
1066 FakeLifecycleProvider* fakeAppDelegate = [[FakeLifecycleProvider alloc] init];
1067 [NSApplication sharedApplication].delegate = fakeAppDelegate;
1068
1069 FakeAppDelegatePlugin* plugin = [[FakeAppDelegatePlugin alloc] init];
1070 FlutterEngine* engine = CreateMockFlutterEngine(nil);
1071
1072 [[engine registrarForPlugin:@"TestPlugin"] addApplicationDelegate:plugin];
1073
1074 EXPECT_TRUE([fakeAppDelegate hasDelegate:plugin]);
1075
1076 [NSApplication sharedApplication].delegate = previousDelegate;
1077 }

References CreateMockFlutterEngine().

## ◆ TEST_F() [23/63]

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

Definition at line 970 of file FlutterEngineTest.mm.

970 {
971 __block BOOL announced = NO;
972 id engineMock = CreateMockFlutterEngine(nil);
973
974 OCMStub([engineMock announceAccessibilityMessage:[OCMArg any]
975 withPriority:NSAccessibilityPriorityMedium])
976 .andDo((^(NSInvocation* invocation) {
977 announced = TRUE;
978 [invocation retainArguments];
979 NSString* message;
980 [invocation getArgument:&message atIndex:2];
981 EXPECT_EQ(message, @"error message");
982 }));
983
984 NSDictionary<NSString*, id>* annotatedEvent =
985 @{@"type" : @"announce",
986 @"data" : @{@"message" : @"error message"}};
987
988 [engineMock handleAccessibilityEvent:annotatedEvent];
989
990 EXPECT_TRUE(announced);
991 }

References CreateMockFlutterEngine().

## ◆ TEST_F() [24/63]

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

Definition at line 993 of file FlutterEngineTest.mm.

993 {
994 __block flutter::AppLifecycleState sentState;
995 id engineMock = CreateMockFlutterEngine(nil);
996
997 // Have to enumerate all the values because OCMStub can't capture
998 // non-Objective-C object arguments.
999 OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kDetached])
1000 .andDo((^(NSInvocation* invocation) {
1001 sentState = flutter::AppLifecycleState::kDetached;
1002 }));
1003 OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kResumed])
1004 .andDo((^(NSInvocation* invocation) {
1005 sentState = flutter::AppLifecycleState::kResumed;
1006 }));
1007 OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kInactive])
1008 .andDo((^(NSInvocation* invocation) {
1009 sentState = flutter::AppLifecycleState::kInactive;
1010 }));
1011 OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kHidden])
1012 .andDo((^(NSInvocation* invocation) {
1013 sentState = flutter::AppLifecycleState::kHidden;
1014 }));
1015 OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kPaused])
1016 .andDo((^(NSInvocation* invocation) {
1017 sentState = flutter::AppLifecycleState::kPaused;
1018 }));
1019
1020 __block NSApplicationOcclusionState visibility = NSApplicationOcclusionStateVisible;
1021 id mockApplication = OCMPartialMock([NSApplication sharedApplication]);
1022 OCMStub((NSApplicationOcclusionState)[mockApplication occlusionState])
1023 .andDo(^(NSInvocation* invocation) {
1024 [invocation setReturnValue:&visibility];
1025 });
1026
1027 NSNotification* willBecomeActive =
1028 [[NSNotification alloc] initWithName:NSApplicationWillBecomeActiveNotification
1029 object:nil
1030 userInfo:nil];
1031 NSNotification* willResignActive =
1032 [[NSNotification alloc] initWithName:NSApplicationWillResignActiveNotification
1033 object:nil
1034 userInfo:nil];
1035
1036 NSNotification* didChangeOcclusionState;
1037 didChangeOcclusionState =
1038 [[NSNotification alloc] initWithName:NSApplicationDidChangeOcclusionStateNotification
1039 object:nil
1040 userInfo:nil];
1041
1042 [engineMock handleDidChangeOcclusionState:didChangeOcclusionState];
1043 EXPECT_EQ(sentState, flutter::AppLifecycleState::kInactive);
1044
1045 [engineMock handleWillBecomeActive:willBecomeActive];
1046 EXPECT_EQ(sentState, flutter::AppLifecycleState::kResumed);
1047
1048 [engineMock handleWillResignActive:willResignActive];
1049 EXPECT_EQ(sentState, flutter::AppLifecycleState::kInactive);
1050
1051 visibility = 0;
1052 [engineMock handleDidChangeOcclusionState:didChangeOcclusionState];
1053 EXPECT_EQ(sentState, flutter::AppLifecycleState::kHidden);
1054
1055 [engineMock handleWillBecomeActive:willBecomeActive];
1056 EXPECT_EQ(sentState, flutter::AppLifecycleState::kHidden);
1057
1058 [engineMock handleWillResignActive:willResignActive];
1059 EXPECT_EQ(sentState, flutter::AppLifecycleState::kHidden);
1060
1061 [mockApplication stopMocking];
1062 }

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

## ◆ TEST_F() [25/63]

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

Definition at line 876 of file FlutterEngineTest.mm.

876 {
877 id engineMock = CreateMockFlutterEngine(nil);
878 __block NSString* nextResponse = @"exit";
879 __block BOOL triedToTerminate = NO;
880 FlutterEngineTerminationHandler* terminationHandler =
881 [[FlutterEngineTerminationHandler alloc] initWithEngine:engineMock
882 terminator:^(id sender) {
883 triedToTerminate = TRUE;
884 // Don't actually terminate, of course.
885 }];
886 OCMStub([engineMock terminationHandler]).andReturn(terminationHandler);
887 id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
888 OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
889 [engineMock binaryMessenger])
890 .andReturn(binaryMessengerMock);
891 OCMStub([engineMock sendOnChannel:@"flutter/platform"
892 message:[OCMArg any]
893 binaryReply:[OCMArg any]])
894 .andDo((^(NSInvocation* invocation) {
895 [invocation retainArguments];
896 FlutterBinaryReply callback;
897 NSData* returnedMessage;
898 [invocation getArgument:&callback atIndex:4];
899 if ([nextResponse isEqualToString:@"error"]) {
900 FlutterError* errorResponse = [FlutterError errorWithCode:@"Error"
901 message:@"Failed"
902 details:@"Details"];
903 returnedMessage =
904 [[FlutterJSONMethodCodec sharedInstance] encodeErrorEnvelope:errorResponse];
905 } else {
906 NSDictionary* responseDict = @{@"response" : nextResponse};
907 returnedMessage =
908 [[FlutterJSONMethodCodec sharedInstance] encodeSuccessEnvelope:responseDict];
909 }
910 callback(returnedMessage);
911 }));
912 __block NSString* calledAfterTerminate = @"";
913 FlutterResult appExitResult = ^(id result) {
914 NSDictionary* resultDict = result;
915 calledAfterTerminate = resultDict[@"response"];
916 };
917 FlutterMethodCall* methodExitApplication =
918 [FlutterMethodCall methodCallWithMethodName:@"System.exitApplication"
919 arguments:@{@"type" : @"cancelable"}];
920
921 // Always terminate when the binding isn't ready (which is the default).
922 triedToTerminate = NO;
923 calledAfterTerminate = @"";
924 nextResponse = @"cancel";
925 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
926 EXPECT_STREQ([calledAfterTerminate UTF8String], "");
927 EXPECT_TRUE(triedToTerminate);
928
929 // Once the binding is ready, handle the request.
930 terminationHandler.acceptingRequests = YES;
931 triedToTerminate = NO;
932 calledAfterTerminate = @"";
933 nextResponse = @"exit";
934 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
935 EXPECT_STREQ([calledAfterTerminate UTF8String], "exit");
936 EXPECT_TRUE(triedToTerminate);
937
938 triedToTerminate = NO;
939 calledAfterTerminate = @"";
940 nextResponse = @"cancel";
941 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
942 EXPECT_STREQ([calledAfterTerminate UTF8String], "cancel");
943 EXPECT_FALSE(triedToTerminate);
944
945 // Check that it doesn't crash on error.
946 triedToTerminate = NO;
947 calledAfterTerminate = @"";
948 nextResponse = @"error";
949 [engineMock handleMethodCall:methodExitApplication result:appExitResult];
950 EXPECT_STREQ([calledAfterTerminate UTF8String], "");
951 EXPECT_TRUE(triedToTerminate);
952 }

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

## ◆ TEST_F() [26/63]

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

Definition at line 129 of file FlutterEngineTest.mm.

129 {
130 FlutterEngine* engine = GetFlutterEngine();
131 std::string executable_name = [[engine executableName] UTF8String];
132 ASSERT_FALSE(executable_name.empty());
133
134 // Block until notified by the Dart test of the value of Platform.executable.
135 fml::AutoResetWaitableEvent latch;
136 AddNativeCallback("NotifyStringValue", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
137 const auto dart_string = tonic::DartConverter<std::string>::FromDart(
138 Dart_GetNativeArgument(args, 0));
139 EXPECT_EQ(executable_name, dart_string);
140 latch.Signal();
141 }));
142
143 // Launch the test entrypoint.
144 EXPECT_TRUE([engine runWithEntrypoint:@"executableNameNotNull"]);
145
146 latch.Wait();
147 }

## ◆ TEST_F() [27/63]

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

Definition at line 721 of file FlutterEngineTest.mm.

721 {
722 id engineMock = CreateMockFlutterEngine(nil);
723
724 // Call hasStrings and expect it to be false.
725 __block bool calledAfterClear = false;
726 __block bool valueAfterClear;
727 FlutterResult resultAfterClear = ^(id result) {
728 calledAfterClear = true;
729 NSNumber* valueNumber = [result valueForKey:@"value"];
730 valueAfterClear = [valueNumber boolValue];
731 };
732 FlutterMethodCall* methodCallAfterClear =
733 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.hasStrings" arguments:nil];
734 [engineMock handleMethodCall:methodCallAfterClear result:resultAfterClear];
735 EXPECT_TRUE(calledAfterClear);
736 EXPECT_FALSE(valueAfterClear);
737 }

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

## ◆ TEST_F() [28/63]

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

Definition at line 739 of file FlutterEngineTest.mm.

739 {
740 id engineMock = CreateMockFlutterEngine(@"some string");
741
742 // Call hasStrings and expect it to be true.
743 __block bool called = false;
744 __block bool value;
745 FlutterResult result = ^(id result) {
746 called = true;
747 NSNumber* valueNumber = [result valueForKey:@"value"];
748 value = [valueNumber boolValue];
749 };
750 FlutterMethodCall* methodCall =
751 [FlutterMethodCall methodCallWithMethodName:@"Clipboard.hasStrings" arguments:nil];
752 [engineMock handleMethodCall:methodCall result:result];
753 EXPECT_TRUE(called);
754 EXPECT_TRUE(value);
755 }

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

## ◆ TEST_F() [29/63]

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

Definition at line 954 of file FlutterEngineTest.mm.

954 {
955 id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
956 id<NSApplicationDelegate> plainDelegate = [[PlainAppDelegate alloc] init];
957 [NSApplication sharedApplication].delegate = plainDelegate;
958
959 // Creating the engine shouldn't fail here, even though the delegate isn't a
960 // FlutterAppDelegate.
961 CreateMockFlutterEngine(nil);
962
963 // Asking to terminate the app should cancel.
964 EXPECT_EQ([[[NSApplication sharedApplication] delegate] applicationShouldTerminate:NSApp],
965 NSTerminateCancel);
966
967 [NSApplication sharedApplication].delegate = previousDelegate;
968 }

References CreateMockFlutterEngine().

## ◆ TEST_F() [30/63]

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

Definition at line 813 of file FlutterEngineTest.mm.

813 {
814 NSString* fixtures = @(flutter::testing::GetFixturesPath());
815 FlutterDartProject* project = [[FlutterDartProject alloc]
816 initWithAssetsPath:fixtures
817 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
818
819 FlutterEngine* engine;
820 FlutterViewController* viewController1;
821
822 @autoreleasepool {
823 // Create FVC1.
824 viewController1 = [[FlutterViewController alloc] initWithProject:project];
825 EXPECT_EQ(viewController1.viewId, 0ll);
826
827 engine = viewController1.engine;
828 engine.viewController = nil;
829
830 // Create FVC2 based on the same engine.
831 FlutterViewController* viewController2 = [[FlutterViewController alloc] initWithEngine:engine
832 nibName:nil
833 bundle:nil];
834 EXPECT_EQ(engine.viewController, viewController2);
835 }
836 // FVC2 is deallocated but FVC1 is retained.
837
838 EXPECT_EQ(engine.viewController, nil);
839
840 engine.viewController = viewController1;
841 EXPECT_EQ(engine.viewController, viewController1);
842 EXPECT_EQ(viewController1.viewId, 0ll);
843 }

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

## ◆ TEST_F() [31/63]

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

Definition at line 845 of file FlutterEngineTest.mm.

845 {
846 // Don't create the engine with `CreateMockFlutterEngine`, because it adds
847 // additional references to FlutterViewControllers, which is crucial to this
848 // test case.
849 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"io.flutter"
850 project:nil
851 allowHeadlessExecution:NO];
852 FlutterViewController* viewController1;
853
854 @autoreleasepool {
855 viewController1 = [[FlutterViewController alloc] initWithEngine:engine nibName:nil bundle:nil];
856 EXPECT_EQ(viewController1.viewId, 0ll);
857 EXPECT_EQ(engine.viewController, viewController1);
858
859 engine.viewController = nil;
860
861 FlutterViewController* viewController2 = [[FlutterViewController alloc] initWithEngine:engine
862 nibName:nil
863 bundle:nil];
864 EXPECT_EQ(viewController2.viewId, 0ll);
865 EXPECT_EQ(engine.viewController, viewController2);
866 }
867 // FVC2 is deallocated but FVC1 is retained.
868
869 EXPECT_EQ(engine.viewController, nil);
870
871 engine.viewController = viewController1;
872 EXPECT_EQ(engine.viewController, viewController1);
873 EXPECT_EQ(viewController1.viewId, 0ll);
874 }

References FlutterEngine::viewController.

## ◆ TEST_F() [32/63]

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

Definition at line 664 of file FlutterEngineTest.mm.

664 {
665 FlutterEngine* engine = GetFlutterEngine();
666 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
667
668 NSString* channel = @"_test_";
669 NSData* channel_data = [channel dataUsingEncoding:NSUTF8StringEncoding];
670
671 // Mock SendPlatformMessage so that if a message is sent to
672 // "test/send_message", act as if the framework has sent an empty message to
673 // the channel marked by the `sendOnChannel:message:` call's message.
674 engine.embedderAPI.SendPlatformMessage = MOCK_ENGINE_PROC(
675 SendPlatformMessage, ([](auto engine_, auto message_) {
676 if (strcmp(message_->channel, "test/send_message") == 0) {
677 // The simplest message that is acceptable to a method channel.
678 std::string message = R"|({"method": "a"})|";
679 std::string channel(reinterpret_cast<const char*>(message_->message),
680 message_->message_size);
681 reinterpret_cast<EmbedderEngine*>(engine_)
682 ->GetShell()
683 .GetPlatformView()
684 ->HandlePlatformMessage(std::make_unique<PlatformMessage>(
685 channel.c_str(), fml::MallocMapping::Copy(message.c_str(), message.length()),
686 fml::RefPtr<PlatformMessageResponse>()));
687 }
688 return kSuccess;
689 }));
690
691 __block int record = 0;
692
693 FlutterMethodChannel* channel1 =
694 [FlutterMethodChannel methodChannelWithName:channel
695 binaryMessenger:engine.binaryMessenger
696 codec:[FlutterJSONMethodCodec sharedInstance]];
697 [channel1 setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
698 record += 1;
699 }];
700
701 [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
702 EXPECT_EQ(record, 1);
703
704 FlutterMethodChannel* channel2 =
705 [FlutterMethodChannel methodChannelWithName:channel
706 binaryMessenger:engine.binaryMessenger
707 codec:[FlutterJSONMethodCodec sharedInstance]];
708 [channel2 setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
709 record += 10;
710 }];
711
712 [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
713 EXPECT_EQ(record, 11);
714
715 [channel1 setMethodCallHandler:nil];
716
717 [engine.binaryMessenger sendOnChannel:@"test/send_message" message:channel_data];
718 EXPECT_EQ(record, 21);
719 }

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

## ◆ TEST_F() [33/63]

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

Definition at line 167 of file FlutterEngineTest.mm.

167 {
168 FlutterEngine* engine = GetFlutterEngine();
169 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
170
171 NSData* test_message = [@"a message" dataUsingEncoding:NSUTF8StringEncoding];
172 bool called = false;
173
174 engine.embedderAPI.SendPlatformMessage = MOCK_ENGINE_PROC(
175 SendPlatformMessage, ([&called, test_message](auto engine, auto message) {
176 called = true;
177 EXPECT_STREQ(message->channel, "test");
178 EXPECT_EQ(memcmp(message->message, test_message.bytes, message->message_size), 0);
179 return kSuccess;
180 }));
181
182 [engine.binaryMessenger sendOnChannel:@"test" message:test_message];
183 EXPECT_TRUE(called);
184 }

## ◆ TEST_F() [34/63]

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

Definition at line 469 of file FlutterEngineTest.mm.

469 {
470 fml::AutoResetWaitableEvent latch;
471 bool latch_called = false;
472 AddNativeCallback("SignalNativeTest", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
473 latch_called = true;
474 latch.Signal();
475 }));
476
477 FlutterEngine* engine = GetFlutterEngine();
478 EXPECT_TRUE([engine runWithEntrypoint:@"nativeCallback"]);
479 ASSERT_TRUE(engine.running);
480
481 latch.Wait();
482 ASSERT_TRUE(latch_called);
483 }

## ◆ TEST_F() [35/63]

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

Definition at line 444 of file FlutterEngineTest.mm.

444 {
445 FlutterEngine* engine = GetFlutterEngine();
446 EXPECT_TRUE([engine runWithEntrypoint:@"main"]);
447
448 // Enable the semantics without attaching a view controller.
449 bool enabled_called = false;
450 engine.embedderAPI.UpdateSemanticsEnabled =
451 MOCK_ENGINE_PROC(UpdateSemanticsEnabled, ([&enabled_called](auto engine, bool enabled) {
452 enabled_called = enabled;
453 return kSuccess;
454 }));
455 engine.semanticsEnabled = YES;
456 EXPECT_TRUE(enabled_called);
457
458 EXPECT_EQ(engine.viewController, nil);
459
460 // Assign the view controller after enabling semantics
461 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
462 nibName:nil
463 bundle:nil];
464 engine.viewController = viewController;
465
466 EXPECT_NE(viewController.accessibilityBridge.lock(), nullptr);
467 }

References FlutterEngine::viewController.

## ◆ TEST_F() [36/63]

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

Definition at line 608 of file FlutterEngineTest.mm.

608 {
609 NSString* fixtures = @(flutter::testing::GetFixturesPath());
610 FlutterDartProject* project = [[FlutterDartProject alloc]
611 initWithAssetsPath:fixtures
612 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
613 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
614 project:project
615 allowHeadlessExecution:YES];
616
617 EXPECT_EQ([engine valuePublishedByPlugin:@"NoSuchPlugin"], nil);
618 }

## ◆ TEST_F() [37/63]

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

Definition at line 620 of file FlutterEngineTest.mm.

620 {
621 NSString* fixtures = @(flutter::testing::GetFixturesPath());
622 FlutterDartProject* project = [[FlutterDartProject alloc]
623 initWithAssetsPath:fixtures
624 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
625 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
626 project:project
627 allowHeadlessExecution:YES];
628 NSString* pluginName = @"MyPlugin";
629 // Request the registarar to register the plugin as existing.
630 [engine registrarForPlugin:pluginName];
631
632 // The documented behavior is that a plugin that exists but hasn't published
633 // anything returns NSNull, rather than nil, as on iOS.
634 EXPECT_EQ([engine valuePublishedByPlugin:pluginName], [NSNull null]);
635 }

## ◆ TEST_F() [38/63]

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

Definition at line 637 of file FlutterEngineTest.mm.

637 {
638 NSString* fixtures = @(flutter::testing::GetFixturesPath());
639 FlutterDartProject* project = [[FlutterDartProject alloc]
640 initWithAssetsPath:fixtures
641 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
642 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
643 project:project
644 allowHeadlessExecution:YES];
645 NSString* pluginName = @"MyPlugin";
646 id<FlutterPluginRegistrar> registrar = [engine registrarForPlugin:pluginName];
647
648 NSString* firstValue = @"A published value";
649 NSArray* secondValue = @[ @"A different published value" ];
650
651 [registrar publish:firstValue];
652 EXPECT_EQ([engine valuePublishedByPlugin:pluginName], firstValue);
653
654 [registrar publish:secondValue];
655 EXPECT_EQ([engine valuePublishedByPlugin:pluginName], secondValue);
656 }

## ◆ TEST_F() [39/63]

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

Definition at line 757 of file FlutterEngineTest.mm.

757 {
758 FlutterEngine* engine = GetFlutterEngine();
759 FlutterBasicMessageChannel* channel = [[FlutterBasicMessageChannel alloc]
760 initWithName:@"foo"
761 binaryMessenger:engine.binaryMessenger
762 codec:[FlutterStandardMessageCodec sharedInstance]];
763 __block BOOL didCallCallback = NO;
764 [channel setMessageHandler:^(id message, FlutterReply callback) {
765 ShutDownEngine();
766 callback(nil);
767 didCallCallback = YES;
768 }];
769 EXPECT_TRUE([engine runWithEntrypoint:@"sendFooMessage"]);
770 engine = nil;
771
772 while (!didCallCallback) {
773 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
774 }
775 }

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

## ◆ TEST_F() [40/63]

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

Definition at line 777 of file FlutterEngineTest.mm.

777 {
778 FlutterEngine* engine = GetFlutterEngine();
779 FlutterBasicMessageChannel* channel = [[FlutterBasicMessageChannel alloc]
780 initWithName:@"foo"
781 binaryMessenger:engine.binaryMessenger
782 codec:[FlutterStandardMessageCodec sharedInstance]];
783 __block BOOL didCallCallback = NO;
784 [channel setMessageHandler:^(id message, FlutterReply callback) {
785 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
786 callback(nil);
787 dispatch_async(dispatch_get_main_queue(), ^{
788 didCallCallback = YES;
789 });
790 });
791 }];
792 EXPECT_TRUE([engine runWithEntrypoint:@"sendFooMessage"]);
793
794 while (!didCallCallback) {
795 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
796 }
797 }

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

## ◆ TEST_F() [41/63]

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

Definition at line 150 of file FlutterEngineTest.mm.

150 {
151 setenv("FLUTTER_ENGINE_SWITCHES", "2", 1);
152 setenv("FLUTTER_ENGINE_SWITCH_1", "abc", 1);
153 setenv("FLUTTER_ENGINE_SWITCH_2", "foo=\"bar, baz\"", 1);
154
155 FlutterEngine* engine = GetFlutterEngine();
156 std::vector<std::string> switches = engine.switches;
157 ASSERT_EQ(switches.size(), 2UL);
158 EXPECT_EQ(switches[0], "--abc");
159 EXPECT_EQ(switches[1], "--foo=\"bar, baz\"");
160
161 unsetenv("FLUTTER_ENGINE_SWITCHES");
162 unsetenv("FLUTTER_ENGINE_SWITCH_1");
163 unsetenv("FLUTTER_ENGINE_SWITCH_2");
164 }

## ◆ TEST_F() [42/63]

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

Definition at line 799 of file FlutterEngineTest.mm.

799 {
800 FlutterThreadSynchronizer* threadSynchronizer = [[FlutterThreadSynchronizer alloc] init];
801 [threadSynchronizer shutdown];
802
803 std::thread rasterThread([&threadSynchronizer] {
804 [threadSynchronizer performCommitForView:kImplicitViewId
805 size:CGSizeMake(100, 100)
806 notify:^{
807 }];
808 });
809
810 rasterThread.join();
811 }

References FlutterThreadSynchronizer::performCommitForView:size:notify:, and FlutterThreadSynchronizer::shutdown.

## ◆ TEST_F() [43/63]

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

Definition at line 1079 of file FlutterEngineTest.mm.

1079 {
1080 id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
1081 FakeLifecycleProvider* fakeAppDelegate = [[FakeLifecycleProvider alloc] init];
1082 [NSApplication sharedApplication].delegate = fakeAppDelegate;
1083
1084 FakeAppDelegatePlugin* plugin = [[FakeAppDelegatePlugin alloc] init];
1085
1086 @autoreleasepool {
1087 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
1088
1089 [[engine registrarForPlugin:@"TestPlugin"] addApplicationDelegate:plugin];
1090 EXPECT_TRUE([fakeAppDelegate hasDelegate:plugin]);
1091 }
1092
1093 // When the engine is released, it should unregister any plugins it had
1094 // registered on its behalf.
1095 EXPECT_FALSE([fakeAppDelegate hasDelegate:plugin]);
1096
1097 [NSApplication sharedApplication].delegate = previousDelegate;
1098 }

## ◆ TEST_F() [44/63]

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

Definition at line 84 of file FlutterMenuPluginTest.mm.

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

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

## ◆ TEST_F() [45/63]

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

Definition at line 261 of file FlutterViewControllerTest.mm.

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

## ◆ TEST_F() [46/63]

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

Definition at line 272 of file FlutterViewControllerTest.mm.

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

## ◆ TEST_F() [47/63]

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

Definition at line 308 of file FlutterViewControllerTest.mm.

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

## ◆ TEST_F() [48/63]

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

Definition at line 278 of file FlutterViewControllerTest.mm.

278 {
279 id mockEngine = GetMockEngine();
280 ASSERT_TRUE(
281 [[FlutterViewControllerTestObjC alloc] testKeyboardIsRestartedOnEngineRestart:mockEngine]);
282 }

## ◆ TEST_F() [49/63]

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

Definition at line 266 of file FlutterViewControllerTest.mm.

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

## ◆ TEST_F() [50/63]

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

Definition at line 255 of file FlutterViewControllerTest.mm.

255 {
256 id mockEngine = GetMockEngine();
257 ASSERT_TRUE(
258 [[FlutterViewControllerTestObjC alloc] testKeyEventsAreNotPropagatedIfHandled:mockEngine]);
259 }

## ◆ TEST_F() [51/63]

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

Definition at line 249 of file FlutterViewControllerTest.mm.

249 {
250 id mockEngine = GetMockEngine();
251 ASSERT_TRUE(
252 [[FlutterViewControllerTestObjC alloc] testKeyEventsArePropagatedIfNotHandled:mockEngine]);
253 }

## ◆ TEST_F() [52/63]

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

Definition at line 244 of file FlutterViewControllerTest.mm.

244 {
245 id mockEngine = GetMockEngine();
246 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEventsAreSentToFramework:mockEngine]);
247 }

## ◆ TEST_F() [53/63]

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

Definition at line 296 of file FlutterViewControllerTest.mm.

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

## ◆ TEST_F() [54/63]

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

Definition at line 290 of file FlutterViewControllerTest.mm.

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

## ◆ TEST_F() [55/63]

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

Definition at line 284 of file FlutterViewControllerTest.mm.

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

## ◆ TEST_F() [56/63]

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

Definition at line 302 of file FlutterViewControllerTest.mm.

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

## ◆ TEST_F() [57/63]

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

Definition at line 234 of file FlutterViewControllerTest.mm.

234 {
235 NSString* fixtures = @(testing::GetFixturesPath());
236 FlutterDartProject* project = [[FlutterDartProject alloc]
237 initWithAssetsPath:fixtures
238 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
239 FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:project];
240 viewController.mouseTrackingMode = kFlutterMouseTrackingModeInActiveApp;
241 ASSERT_EQ(viewController.mouseTrackingMode, kFlutterMouseTrackingModeInActiveApp);
242 }

References FlutterViewController::mouseTrackingMode.

## ◆ TEST_F() [58/63]

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

Definition at line 202 of file FlutterViewControllerTest.mm.

202 {
203 FlutterViewController* viewControllerMock = CreateMockViewController();
204 [viewControllerMock loadView];
205 EXPECT_EQ([viewControllerMock.flutterView acceptsFirstMouse:nil], YES);
206 }

References CreateMockViewController().

## ◆ TEST_F() [59/63]

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

Definition at line 181 of file FlutterViewControllerTest.mm.

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

References CreateMockViewController().

## ◆ TEST_F() [60/63]

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

Definition at line 208 of file FlutterViewControllerTest.mm.

208 {
209 FlutterEngine* engine = CreateTestEngine();
210 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
211 nibName:nil
212 bundle:nil];
213 [viewController loadView];
214 [engine setViewController:viewController];
215 // Creates a NSWindow so that sub view can be first responder.
216 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
217 styleMask:NSBorderlessWindowMask
218 backing:NSBackingStoreBuffered
219 defer:NO];
220 window.contentView = viewController.view;
221 NSView* dummyView = [[NSView alloc] initWithFrame:CGRectZero];
222 [viewController.view addSubview:dummyView];
223 // Attaches FlutterTextInputPlugin to the view;
224 [dummyView addSubview:viewController.textInputPlugin];
225 // Makes sure the textInputPlugin can be the first responder.
226 EXPECT_TRUE([window makeFirstResponder:viewController.textInputPlugin]);
227 EXPECT_EQ([window firstResponder], viewController.textInputPlugin);
228 EXPECT_FALSE(viewController.textInputPlugin.superview == viewController.view);
229 [viewController onAccessibilityStatusChanged:NO];
230 // FlutterView becomes child of view controller
231 EXPECT_TRUE(viewController.textInputPlugin.superview == viewController.view);
232 }

References FlutterViewController::onAccessibilityStatusChanged:.

## ◆ TEST_F() [61/63]

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

Definition at line 313 of file FlutterViewControllerTest.mm.

313 {
314 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testLookupKeyAssets]);
315 }

## ◆ TEST_F() [62/63]

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

Definition at line 317 of file FlutterViewControllerTest.mm.

317 {
318 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testLookupKeyAssetsWithPackage]);
319 }

## ◆ TEST_F() [63/63]

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

Definition at line 321 of file FlutterViewControllerTest.mm.

321 {
322 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testViewControllerIsReleased]);
323 }
flutter::testing::CreateSemanticsNode
FlutterSemanticsNode2 CreateSemanticsNode(int32_t id, const char *label, const std::vector< int32_t > *children=nullptr)
Definition: accessibility_bridge_unittests.cc:18
TestView
Definition: FlutterSurfaceManagerTest.mm:14
+[FlutterSurface fromFlutterMetalTexture:]
nullable FlutterSurface * fromFlutterMetalTexture:(nonnull const FlutterMetalTexture *texture)
FlutterViewControllerTestObjC
Definition: FlutterViewControllerTest.mm:95
flutter::AppLifecycleState::kHidden
@ kHidden
FlutterEngine
Definition: FlutterEngine.h:30
-[FlutterAppLifecycleDelegate-p handleDidHide:]
void handleDidHide:(NSNotification *notification)
-[FlutterAppLifecycleDelegate-p handleWillResignActive:]
void handleWillResignActive:(NSNotification *notification)
FlutterTextFieldMock::lastUpdatedString
NSString * lastUpdatedString
Definition: FlutterTextInputPluginTest.mm:23
+[FlutterMethodCall methodCallWithMethodName:arguments:]
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
FlutterBasicMessageChannel
Definition: FlutterChannels.h:37
-[FlutterAppLifecycleDelegate-p handleDidChangeOcclusionState:]
void handleDidChangeOcclusionState:(NSNotification *notification)
FlutterAppLifecycleRegistrar
Definition: FlutterAppLifecycleDelegate.h:126
-[FlutterAppLifecycleRegistrar addDelegate:]
void addDelegate:(NSObject< FlutterAppLifecycleDelegate > *delegate)
Definition: FlutterAppLifecycleDelegate.mm:76
FlutterViewController
Definition: FlutterViewController.h:62
FlutterMethodChannel
Definition: FlutterChannels.h:220
-[FlutterAppLifecycleDelegate-p handleWillHide:]
void handleWillHide:(NSNotification *notification)
-[FlutterThreadSynchronizer performCommitForView:size:notify:]
void performCommitForView:size:notify:(int64_t viewId,[size] CGSize size,[notify] nonnull dispatch_block_t notify)
Definition: FlutterThreadSynchronizer.mm:137
flutter::testing::CreateMockFlutterEngine
id CreateMockFlutterEngine(NSString *pasteboardString)
Definition: FlutterEngineTestUtils.mm:76
-[FlutterViewController onAccessibilityStatusChanged:]
void onAccessibilityStatusChanged:(BOOL enabled)
TestKeyEvent
Definition: FlutterEmbedderKeyResponderTest.mm:13
flutter::testing::CreateMockViewController
id CreateMockViewController()
Definition: FlutterViewControllerTestUtils.mm:9
FlutterPlatformViewController
Definition: FlutterPlatformViewController.h:14
user_data
void * user_data
Definition: texture_registrar_unittests.cc:27
-[FlutterKeyPrimaryResponder-p handleEvent:callback:]
void handleEvent:callback:(nonnull NSEvent *event,[callback] nonnull FlutterAsyncKeyCallback callback)
-[FlutterBackBufferCache count]
NSUInteger count()
Definition: FlutterSurfaceManager.mm:277
FlutterSurfaceManager
Definition: FlutterSurfaceManager.h:41
FlutterError
Definition: FlutterCodecs.h:246
flutter::kLayoutGoals
const std::vector< LayoutGoal > kLayoutGoals
Definition: KeyCodeMap.g.mm:248
FlutterTextFieldMock
Definition: FlutterTextInputPluginTest.mm:21
FlutterEngine::viewController
FlutterViewController * viewController
Definition: FlutterEngine.h:86
TestFlutterPlatformViewFactory
Definition: TestFlutterPlatformView.h:16
TestPlatformViewFactory
Definition: FlutterEngineTest.mm:47
FakeLifecycleProvider
Definition: FlutterEngineTest.mm:69
FakeMessageChannel
Definition: FlutterChannelKeyResponderTest.mm:19
FakePluginRegistrar::plugin
id< FlutterPlugin > plugin
Definition: FlutterMenuPluginTest.mm:23
-[FlutterAppLifecycleProvider-p addApplicationLifecycleDelegate:]
void addApplicationLifecycleDelegate:(nonnull NSObject< FlutterAppLifecycleDelegate > *delegate)
FakeAppDelegatePlugin
Definition: FlutterEngineTest.mm:111
FlutterViewController::engine
FlutterEngine * engine
Definition: FlutterViewController.h:67
TestFlutterPlatformView
Definition: TestFlutterPlatformView.h:9
+[FlutterError errorWithCode:message:details:]
instancetype errorWithCode:message:details:(NSString *code,[message] NSString *_Nullable message,[details] id _Nullable details)
FakeMessageChannel::messages
NSMutableArray< id > * messages
Definition: FlutterChannelKeyResponderTest.mm:20
FlutterExternalTexture
Definition: FlutterExternalTexture.h:15
FlutterTextFieldMock::lastUpdatedSelection
NSRange lastUpdatedSelection
Definition: FlutterTextInputPluginTest.mm:24
FlutterEngine::binaryMessenger
id< FlutterBinaryMessenger > binaryMessenger
Definition: FlutterEngine.h:91
FlutterViewEngineProvider
Definition: FlutterViewEngineProvider.h:15
kFlutterImplicitViewId
constexpr FlutterViewId kFlutterImplicitViewId
Definition: FlutterView.h:23
TestFlutterPlatformView::args
id args
Arguments passed via the params value in the create method call.
Definition: TestFlutterPlatformView.h:12
-[FlutterAppLifecycleDelegate-p handleDidUnhide:]
void handleDidUnhide:(NSNotification *notification)
-[FlutterAppLifecycleDelegate-p handleWillTerminate:]
void handleWillTerminate:(NSNotification *notification)
flutter::AppLifecycleState::kInactive
@ kInactive
FlutterSurface
Definition: FlutterSurface.h:13
-[FlutterMethodChannel setMethodCallHandler:]
void setMethodCallHandler:(FlutterMethodCallHandler _Nullable handler)
-[FlutterAppLifecycleDelegate-p handleDidChangeScreenParameters:]
void handleDidChangeScreenParameters:(NSNotification *notification)
FlutterStandardMessageCodec
Definition: FlutterCodecs.h:209
FlutterMethodCall
Definition: FlutterCodecs.h:220
FlutterViewController::backgroundColor
NSColor * backgroundColor
Definition: FlutterViewController.h:188
TestExternalTexture
Definition: FlutterEmbedderExternalTextureTest.mm:25
FlutterThreadSynchronizer
Definition: FlutterThreadSynchronizer.h:13
FakePasteboard
Definition: FlutterEngineTestUtils.mm:17
AppDelegateNoopFlutterAppLifecycleDelegate
Definition: FlutterAppDelegateTest.mm:10
FlutterSurfacePresentInfo::surface
FlutterSurface * surface
Definition: FlutterSurfaceManager.h:17
AppDelegateTestFlutterAppLifecycleDelegate
Definition: FlutterAppDelegateTest.mm:17
PlainAppDelegate
Definition: FlutterEngineTest.mm:57
FlutterAppDelegate
Definition: FlutterAppDelegate.h:54
FlutterSurfaceManager::frontSurfaces
NSArray< FlutterSurface * > * frontSurfaces
Definition: FlutterSurfaceManager.h:102
-[FlutterTextField startEditing]
void startEditing()
Definition: FlutterTextInputSemanticsObject.mm:112
FlutterTextInputPlugin
Definition: FlutterTextInputPlugin.h:24
-[FlutterAppLifecycleDelegate-p handleDidFinishLaunching:]
void handleDidFinishLaunching:(NSNotification *notification)
FlutterResult
void(^ FlutterResult)(id _Nullable result)
Definition: FlutterChannels.h:194
FlutterSurfacePresentInfo::offset
CGPoint offset
Definition: FlutterSurfaceManager.h:18
FlutterKeyPrimaryResponder-p::layoutMap
NSMutableDictionary< NSNumber *, NSNumber * > * layoutMap
Definition: FlutterKeyPrimaryResponder.h:43
FlutterSurfaceManager::backBufferCache
FlutterBackBufferCache * backBufferCache
Definition: FlutterSurfaceManager.h:101
-[FlutterPlugin-p handleMethodCall:result:]
void handleMethodCall:result:(FlutterMethodCall *call,[result] FlutterResult result)
FlutterChannelKeyResponder
Definition: FlutterChannelKeyResponder.h:17
+[FlutterMethodChannel methodChannelWithName:binaryMessenger:codec:]
instancetype methodChannelWithName:binaryMessenger:codec:(NSString *name,[binaryMessenger] NSObject< FlutterBinaryMessenger > *messenger,[codec] NSObject< FlutterMethodCodec > *codec)
FlutterSurfacePresentInfo
Definition: FlutterSurfaceManager.h:15
FakeMessageChannel::nextResponse
NSDictionary * nextResponse
Definition: FlutterChannelKeyResponderTest.mm:21
FlutterSurfacePresentInfo::zIndex
size_t zIndex
Definition: FlutterSurfaceManager.h:19
-[FlutterSurfaceManager surfaceForSize:]
nonnull FlutterSurface * surfaceForSize:(CGSize size)
Definition: FlutterSurfaceManager.mm:131
-[FlutterAppLifecycleDelegate-p handleWillFinishLaunching:]
void handleWillFinishLaunching:(NSNotification *notification)
FlutterStandardTypedData
Definition: FlutterCodecs.h:300
TestView::presentedFrameSize
CGSize presentedFrameSize
Definition: FlutterSurfaceManagerTest.mm:16
flutter::AppLifecycleState::kResumed
@ kResumed
FlutterView
Definition: FlutterView.h:45
flutter::AppLifecycleState::kDetached
@ kDetached
flutter::testing::CreateSurfaceManager
static FlutterSurfaceManager * CreateSurfaceManager(TestView *testView)
Definition: FlutterSurfaceManagerTest.mm:41
-[FlutterAppLifecycleDelegate-p handleWillBecomeActive:]
void handleWillBecomeActive:(NSNotification *notification)
FlutterJSONMethodCodec
Definition: FlutterCodecs.h:455
-[FlutterBasicMessageChannel setMessageHandler:]
void setMessageHandler:(FlutterMessageHandler _Nullable handler)
-[FlutterSurfaceManager present:notify:]
void present:notify:(nonnull NSArray< FlutterSurfacePresentInfo * > *surfaces,[notify] nullable dispatch_block_t notify)
FlutterSurfacePresentInfo::paintRegion
std::vector< FlutterRect > paintRegion
Definition: FlutterSurfaceManager.h:20
-[FlutterAppLifecycleDelegate-p handleDidBecomeActive:]
void handleDidBecomeActive:(NSNotification *notification)
flutter::AppLifecycleState
AppLifecycleState
Definition: app_lifecycle_state.h:32
FakePluginRegistrar
Definition: FlutterMenuPluginTest.mm:22
-[FlutterEngine shutDownEngine]
void shutDownEngine()
Definition: FlutterEngine.mm:1035
FlutterDartProject
Definition: FlutterDartProject.mm:24
FlutterKeyboardManagerUnittestsObjC
Definition: FlutterKeyboardManagerTest.mm:420
FlutterEngineTerminationHandler::acceptingRequests
BOOL acceptingRequests
Definition: FlutterEngine_Internal.h:58
FlutterBinaryMessenger-p
Definition: FlutterBinaryMessenger.h:49
texture_id
int64_t texture_id
Definition: texture_registrar_unittests.cc:24
FlutterTextField
Definition: FlutterTextInputSemanticsObject.h:78
-[FlutterAppLifecycleDelegate-p handleWillUnhide:]
void handleWillUnhide:(NSNotification *notification)
FlutterEmbedderKeyResponder
Definition: FlutterEmbedderKeyResponder.h:20
FlutterEngineTerminationHandler
Definition: FlutterEngine.mm:180
-[FlutterThreadSynchronizer shutdown]
void shutdown()
Definition: FlutterThreadSynchronizer.mm:179
-[FlutterExternalTexture populateTexture:]
BOOL populateTexture:(nonnull FlutterMetalExternalTexture *metalTexture)
FlutterViewId
int64_t FlutterViewId
Definition: FlutterView.h:12
FlutterBinaryReply
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterBinaryReply)(NSData *_Nullable reply)
FlutterViewController::mouseTrackingMode
FlutterMouseTrackingMode mouseTrackingMode
Definition: FlutterViewController.h:73
+[FlutterMessageCodec-p sharedInstance]
instancetype sharedInstance()
FlutterInputPluginTestObjc
Definition: FlutterTextInputPluginTest.mm:52
-[FlutterAppLifecycleDelegate-p handleDidResignActive:]
void handleDidResignActive:(NSNotification *notification)
flutter::AppLifecycleState::kPaused
@ kPaused
TestFlutterAppLifecycleDelegate
Definition: FlutterAppLifecycleDelegateTest.mm:10