| Flutter macOS Embedder |

Classes | Functions
flutter::testing Namespace Reference

## Classes
class | FlutterEngineTest

## Functions
| TEST (AccessibilityBridgeMacTest, SendsAccessibilityCreateNotificationToWindowOfFlutterView)
| TEST (AccessibilityBridgeMacTest, NonZeroRootNodeId)
| TEST (AccessibilityBridgeMacTest, DoesNotSendAccessibilityCreateNotificationWhenHeadless)
| TEST (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 (FlutterChannelKeyResponderUnittests, BasicKeyEvent)
| TEST (FlutterChannelKeyResponderUnittests, EmptyResponseIsTakenAsHandled)
| TEST (FlutterChannelKeyResponderUnittests, FollowsLayoutMap)
| TEST (FlutterCompositorTest, TestCreate)
| TEST (FlutterCompositorTest, TestPresent)
| TEST (FlutterEmbedderExternalTextureUnittests, TestTextureResolution)
| TEST (FlutterEmbedderExternalTextureUnittests, TestPopulateExternalTexture)
| TEST (FlutterEmbedderExternalTextureUnittests, TestPopulateExternalTextureYUVA)
| TEST (FlutterEmbedderExternalTextureUnittests, 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 (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, HasZeroSizeAndClipsToBounds)
| TEST (FlutterTextInputSemanticsObjectTest, DoesInitialize)
| TEST (FlutterViewController, HasViewThatHidesOtherViewsInAccessibility)
| TEST (FlutterViewController, FlutterViewAcceptsFirstMouse)
| TEST (FlutterViewController, ReparentsPluginWhenAccessibilityDisabled)
| TEST (FlutterViewController, CanSetMouseTrackingModeBeforeViewLoaded)
| TEST (FlutterViewControllerTest, TestKeyEventsAreSentToFramework)
| TEST (FlutterViewControllerTest, TestKeyEventsArePropagatedIfNotHandled)
| TEST (FlutterViewControllerTest, TestKeyEventsAreNotPropagatedIfHandled)
| TEST (FlutterViewControllerTest, TestCtrlTabKeyEventIsPropagated)
| TEST (FlutterViewControllerTest, TestKeyEquivalentIsPassedToTextInputPlugin)
| TEST (FlutterViewControllerTest, TestFlagsChangedEventsArePropagatedIfNotHandled)
| TEST (FlutterViewControllerTest, TestKeyboardIsRestartedOnEngineRestart)
| TEST (FlutterViewControllerTest, TestTrackpadGesturesAreSentToFramework)
| TEST (FlutterViewControllerTest, TestMouseDownUpEventsSentToNextResponder)
| TEST (FlutterViewControllerTest, TestModifierKeysAreSynthesizedOnMouseMove)
| TEST (FlutterViewControllerTest, testViewWillAppearCalledMultipleTimes)
| TEST (FlutterViewControllerTest, testFlutterViewIsConfigured)
| TEST (FlutterViewControllerTest, testLookupKeyAssets)
| TEST (FlutterViewControllerTest, testLookupKeyAssetsWithPackage)
| TEST (FlutterViewControllerTest, testViewControllerIsReleased)
id | CreateMockViewController ()
| TEST (FlutterViewEngineProviderUnittests, GetViewReturnsTheCorrectView)
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, ToggleHasToggleButtonRole)
| 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)

## Function Documentation

## ◆ CreateMockFlutterEngine()

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

Definition at line 47 of file FlutterEngineTestUtils.mm.

47 {
48 {
49 NSString* fixtures = @(testing::GetFixturesPath());
50 FlutterDartProject* project = [[FlutterDartProject alloc]
51 initWithAssetsPath:fixtures
52 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
53 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test"
54 project:project
55 allowHeadlessExecution:true];
56
57 // Mock pasteboard so that this test will work in environments without a
58 // real pasteboard.
59 id pasteboardMock = OCMClassMock([NSPasteboard class]);
60 OCMExpect([pasteboardMock stringForType:[OCMArg any]]).andDo(^(NSInvocation* invocation) {
61 NSString* returnValue = pasteboardString.length > 0 ? pasteboardString : nil;
62 [invocation setReturnValue:&returnValue];
63 });
64 id engineMock = OCMPartialMock(engine);
65 OCMStub([engineMock pasteboard]).andReturn(pasteboardMock);
66 return engineMock;
67 }
68 }

Referenced by TEST(), TEST_F(), FlutterInputPluginTestObjc::testClearClientDuringComposing, FlutterViewControllerTestObjC::testCtrlTabKeyEventIsPropagated, FlutterInputPluginTestObjc::testEmptyCompositionRange, FlutterViewControllerTestObjC::testFlagsChangedEventsArePropagatedIfNotHandled, FlutterViewControllerTestObjC::testFlutterViewIsConfigured, FlutterViewControllerTestObjC::testKeyboardIsRestartedOnEngineRestart, FlutterViewControllerTestObjC::testKeyEquivalentIsPassedToTextInputPlugin, FlutterViewControllerTestObjC::testKeyEventsAreNotPropagatedIfHandled, FlutterViewControllerTestObjC::testKeyEventsArePropagatedIfNotHandled, FlutterViewControllerTestObjC::testKeyEventsAreSentToFramework, FlutterViewControllerTestObjC::testModifierKeysAreSynthesizedOnMouseMove, FlutterViewControllerTestObjC::testMouseDownUpEventsSentToNextResponder, FlutterViewControllerTestObjC::testTrackpadGesturesAreSentToFramework, FlutterViewControllerTestObjC::testViewControllerIsReleased, and FlutterViewControllerTestObjC::testViewWillAppearCalledMultipleTimes.

## ◆ 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().

## ◆ CreatePresentInfo()

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

Definition at line 52 of file FlutterSurfaceManagerTest.mm.

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

## ◆ 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 42 of file FlutterSurfaceManagerTest.mm.

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

Referenced by TEST().

## ◆ operator==()

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

Definition at line 167 of file FlutterSurfaceManagerTest.mm.

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

## ◆ TEST() [1/138]

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

Definition at line 192 of file AccessibilityBridgeMacTest.mm.

192 {
193 FlutterViewController* viewController = CreateTestViewController();
194 FlutterEngine* engine = viewController.engine;
195 [viewController loadView];
196 // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy
197 // can query semantics information from.
198 engine.semanticsEnabled = YES;
199 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
200 viewController.accessibilityBridge.lock());
201 FlutterSemanticsNode2 root;
202 root.id = 0;
203 root.flags = static_cast<FlutterSemanticsFlag>(0);
204 root.actions = static_cast<FlutterSemanticsAction>(0);
205 root.text_selection_base = -1;
206 root.text_selection_extent = -1;
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 = 0;
214 root.custom_accessibility_actions_count = 0;
215 bridge->AddFlutterSemanticsNodeUpdate(root);
216
217 bridge->CommitUpdates();
218 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
219
220 // Creates a targeted event.
221 ui::AXTree tree;
222 ui::AXNode ax_node(&tree, nullptr, 0, 0);
223 ui::AXNodeData node_data;
224 node_data.id = 0;
225 ax_node.SetData(node_data);
226 std::vector<ui::AXEventIntent> intent;
227 ui::AXEventGenerator::EventParams event_params(ui::AXEventGenerator::Event::CHILDREN_CHANGED,
228 ax::mojom::EventFrom::kNone, intent);
229 ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params);
230
231 bridge->OnAccessibilityEvent(targeted_event);
232
233 // Does not send any notification if the engine is headless.
234 EXPECT_EQ(bridge->actual_notifications.size(), 0u);
235 [engine shutDownEngine];
236 }

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

## ◆ TEST() [2/138]

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

Definition at line 238 of file AccessibilityBridgeMacTest.mm.

238 {
239 FlutterViewController* viewController = CreateTestViewController();
240 FlutterEngine* engine = viewController.engine;
241 [viewController loadView];
242
243 // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy
244 // can query semantics information from.
245 engine.semanticsEnabled = YES;
246 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
247 viewController.accessibilityBridge.lock());
248 FlutterSemanticsNode2 root;
249 root.id = 0;
250 root.flags = static_cast<FlutterSemanticsFlag>(0);
251 root.actions = static_cast<FlutterSemanticsAction>(0);
252 root.text_selection_base = -1;
253 root.text_selection_extent = -1;
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.custom_accessibility_actions_count = 0;
262 bridge->AddFlutterSemanticsNodeUpdate(root);
263
264 bridge->CommitUpdates();
265 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
266
267 // Creates a targeted event.
268 ui::AXTree tree;
269 ui::AXNode ax_node(&tree, nullptr, 0, 0);
270 ui::AXNodeData node_data;
271 node_data.id = 0;
272 ax_node.SetData(node_data);
273 std::vector<ui::AXEventIntent> intent;
274 ui::AXEventGenerator::EventParams event_params(ui::AXEventGenerator::Event::CHILDREN_CHANGED,
275 ax::mojom::EventFrom::kNone, intent);
276 ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params);
277
278 bridge->OnAccessibilityEvent(targeted_event);
279
280 // Does not send any notification if the flutter view is not attached to a NSWindow.
281 EXPECT_EQ(bridge->actual_notifications.size(), 0u);
282 [engine shutDownEngine];
283 }

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

## ◆ TEST() [3/138]

flutter::testing::TEST | ( | AccessibilityBridgeMacTest | ,
|  | NonZeroRootNodeId |
| ) |  |

Definition at line 122 of file AccessibilityBridgeMacTest.mm.

122 {
123 FlutterViewController* viewController = CreateTestViewController();
124 FlutterEngine* engine = viewController.engine;
125 [viewController loadView];
126
127 NSWindow* expectedTarget = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
128 styleMask:NSBorderlessWindowMask
129 backing:NSBackingStoreBuffered
130 defer:NO];
131 expectedTarget.contentView = viewController.view;
132 // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy
133 // can query semantics information from.
134 engine.semanticsEnabled = YES;
135 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
136 viewController.accessibilityBridge.lock());
137
138 FlutterSemanticsNode2 node1;
139 std::vector<int32_t> node1_children{2};
140 node1.id = 1;
141 node1.flags = static_cast<FlutterSemanticsFlag>(0);
142 node1.actions = static_cast<FlutterSemanticsAction>(0);
143 node1.text_selection_base = -1;
144 node1.text_selection_extent = -1;
145 node1.label = "node1";
146 node1.hint = "";
147 node1.value = "";
148 node1.increased_value = "";
149 node1.decreased_value = "";
150 node1.tooltip = "";
151 node1.child_count = node1_children.size();
152 node1.children_in_traversal_order = node1_children.data();
153 node1.children_in_hit_test_order = node1_children.data();
154 node1.custom_accessibility_actions_count = 0;
155
156 FlutterSemanticsNode2 node2;
157 node2.id = 2;
158 node2.flags = static_cast<FlutterSemanticsFlag>(0);
159 node2.actions = static_cast<FlutterSemanticsAction>(0);
160 node2.text_selection_base = -1;
161 node2.text_selection_extent = -1;
162 node2.label = "node2";
163 node2.hint = "";
164 node2.value = "";
165 node2.increased_value = "";
166 node2.decreased_value = "";
167 node2.tooltip = "";
168 node2.child_count = 0;
169 node2.custom_accessibility_actions_count = 0;
170
171 bridge->AddFlutterSemanticsNodeUpdate(node1);
172 bridge->AddFlutterSemanticsNodeUpdate(node2);
173 bridge->CommitUpdates();
174
175 // Look up the root node delegate.
176 auto root_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(1).lock();
177 ASSERT_TRUE(root_delegate);
178 ASSERT_EQ(root_delegate->GetChildCount(), 1);
179
180 // Look up the child node delegate.
181 auto child_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(2).lock();
182 ASSERT_TRUE(child_delegate);
183 ASSERT_EQ(child_delegate->GetChildCount(), 0);
184
185 // Ensure a node with ID 0 does not exist.
186 auto invalid_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
187 ASSERT_FALSE(invalid_delegate);
188
189 [engine shutDownEngine];
190 }

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

## ◆ TEST() [4/138]

flutter::testing::TEST | ( | AccessibilityBridgeMacTest | ,
|  | SendsAccessibilityCreateNotificationToWindowOfFlutterView |
| ) |  |

Definition at line 61 of file AccessibilityBridgeMacTest.mm.

61 {
62 FlutterViewController* viewController = CreateTestViewController();
63 FlutterEngine* engine = viewController.engine;
64 [viewController loadView];
65
66 NSWindow* expectedTarget = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
67 styleMask:NSBorderlessWindowMask
68 backing:NSBackingStoreBuffered
69 defer:NO];
70 expectedTarget.contentView = viewController.view;
71 // Setting up bridge so that the AccessibilityBridgeMacDelegateSpy
72 // can query semantics information from.
73 engine.semanticsEnabled = YES;
74 auto bridge = std::static_pointer_cast<AccessibilityBridgeMacSpy>(
75 viewController.accessibilityBridge.lock());
76 FlutterSemanticsNode2 root;
77 root.id = 0;
78 root.flags = static_cast<FlutterSemanticsFlag>(0);
79 root.actions = static_cast<FlutterSemanticsAction>(0);
80 root.text_selection_base = -1;
81 root.text_selection_extent = -1;
82 root.label = "root";
83 root.hint = "";
84 root.value = "";
85 root.increased_value = "";
86 root.decreased_value = "";
87 root.tooltip = "";
88 root.child_count = 0;
89 root.custom_accessibility_actions_count = 0;
90 bridge->AddFlutterSemanticsNodeUpdate(root);
91
92 bridge->CommitUpdates();
93 auto platform_node_delegate = bridge->GetFlutterPlatformNodeDelegateFromID(0).lock();
94
95 // Creates a targeted event.
96 ui::AXTree tree;
97 ui::AXNode ax_node(&tree, nullptr, 0, 0);
98 ui::AXNodeData node_data;
99 node_data.id = 0;
100 ax_node.SetData(node_data);
101 std::vector<ui::AXEventIntent> intent;
102 ui::AXEventGenerator::EventParams event_params(ui::AXEventGenerator::Event::CHILDREN_CHANGED,
103 ax::mojom::EventFrom::kNone, intent);
104 ui::AXEventGenerator::TargetedEvent targeted_event(&ax_node, event_params);
105
106 bridge->OnAccessibilityEvent(targeted_event);
107
108 EXPECT_EQ(bridge->actual_notifications.size(), 1u);
109 EXPECT_EQ(
110 bridge->actual_notifications.find([NSAccessibilityCreatedNotification UTF8String])->second,
111 expectedTarget);
112 [engine shutDownEngine];
113 }

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

## ◆ TEST() [5/138]

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() [6/138]

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

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() [8/138]

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() [9/138]

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() [10/138]

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() [11/138]

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() [12/138]

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() [13/138]

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() [14/138]

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() [15/138]

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() [16/138]

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() [17/138]

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() [18/138]

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

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::kToggleButton);
269 }

References CreateSemanticsNode().

## ◆ TEST() [19/138]

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() [20/138]

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() [21/138]

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() [22/138]

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() [23/138]

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() [24/138]

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() [25/138]

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() [26/138]

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() [27/138]

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() [28/138]

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() [29/138]

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() [30/138]

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() [31/138]

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() [32/138]

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

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

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

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

Definition at line 38 of file FlutterChannelKeyResponderTest.mm.

38 {
39 __block NSMutableArray<id>* messages = [[NSMutableArray<id> alloc] init];
40 __block BOOL next_response = TRUE;
41 __block NSMutableArray<NSNumber*>* responses = [[NSMutableArray<NSNumber*> alloc] init];
42
43 id mockKeyEventChannel = OCMStrictClassMock([FlutterBasicMessageChannel class]);
44 OCMStub([mockKeyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
45 .andDo((^(NSInvocation* invocation) {
46 [invocation retainArguments];
47 NSDictionary* message;
48 [invocation getArgument:&message atIndex:2];
49 [messages addObject:message];
50
51 FlutterReply callback;
52 [invocation getArgument:&callback atIndex:3];
53 NSDictionary* keyMessage = @{
54 @"handled" : @(next_response),
55 };
56 callback(keyMessage);
57 }));
58
59 FlutterChannelKeyResponder* responder =
60 [[FlutterChannelKeyResponder alloc] initWithChannel:mockKeyEventChannel];
61
62 // Initial empty modifiers. This can happen when user opens window while modifier key is pressed
63 // and then releases the modifier. No events should be sent, but the callback
64 // should still be called.
65 // Regression test for https://github.com/flutter/flutter/issues/87339.
66 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, 60)
67 callback:^(BOOL handled) {
68 [responses addObject:@(handled)];
69 }];
70
71 EXPECT_EQ([messages count], 0u);
72 EXPECT_EQ([responses count], 1u);
73 EXPECT_EQ([responses[0] boolValue], TRUE);
74 [responses removeAllObjects];
75
76 // Key down
77 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", FALSE, 0)
78 callback:^(BOOL handled) {
79 [responses addObject:@(handled)];
80 }];
81
82 EXPECT_EQ([messages count], 1u);
83 EXPECT_STREQ([[messages lastObject][@"keymap"] UTF8String], "macos");
84 EXPECT_STREQ([[messages lastObject][@"type"] UTF8String], "keydown");
85 EXPECT_EQ([[messages lastObject][@"keyCode"] intValue], 0);
86 EXPECT_EQ([[messages lastObject][@"modifiers"] intValue], 0x0);
87 EXPECT_STREQ([[messages lastObject][@"characters"] UTF8String], "a");
88 EXPECT_STREQ([[messages lastObject][@"charactersIgnoringModifiers"] UTF8String], "a");
89
90 EXPECT_EQ([responses count], 1u);
91 EXPECT_EQ([[responses lastObject] boolValue], TRUE);
92
93 [messages removeAllObjects];
94 [responses removeAllObjects];
95
96 // Key up
97 next_response = FALSE;
98 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0x100, @"a", @"a", FALSE, 0)
99 callback:^(BOOL handled) {
100 [responses addObject:@(handled)];
101 }];
102
103 EXPECT_EQ([messages count], 1u);
104 EXPECT_STREQ([[messages lastObject][@"keymap"] UTF8String], "macos");
105 EXPECT_STREQ([[messages lastObject][@"type"] UTF8String], "keyup");
106 EXPECT_EQ([[messages lastObject][@"keyCode"] intValue], 0);
107 EXPECT_EQ([[messages lastObject][@"modifiers"] intValue], 0);
108 EXPECT_STREQ([[messages lastObject][@"characters"] UTF8String], "a");
109 EXPECT_STREQ([[messages lastObject][@"charactersIgnoringModifiers"] UTF8String], "a");
110
111 EXPECT_EQ([responses count], 1u);
112 EXPECT_EQ([[responses lastObject] boolValue], FALSE);
113
114 [messages removeAllObjects];
115 [responses removeAllObjects];
116
117 // LShift down
118 next_response = TRUE;
119 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, 56)
120 callback:^(BOOL handled) {
121 [responses addObject:@(handled)];
122 }];
123
124 EXPECT_EQ([messages count], 1u);
125 EXPECT_STREQ([[messages lastObject][@"keymap"] UTF8String], "macos");
126 EXPECT_STREQ([[messages lastObject][@"type"] UTF8String], "keydown");
127 EXPECT_EQ([[messages lastObject][@"keyCode"] intValue], 56);
128 EXPECT_EQ([[messages lastObject][@"modifiers"] intValue], 0x20002);
129
130 EXPECT_EQ([responses count], 1u);
131 EXPECT_EQ([[responses lastObject] boolValue], TRUE);
132
133 [messages removeAllObjects];
134 [responses removeAllObjects];
135
136 // RShift down
137 next_response = false;
138 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20006, @"", @"", FALSE, 60)
139 callback:^(BOOL handled) {
140 [responses addObject:@(handled)];
141 }];
142
143 EXPECT_EQ([messages count], 1u);
144 EXPECT_STREQ([[messages lastObject][@"keymap"] UTF8String], "macos");
145 EXPECT_STREQ([[messages lastObject][@"type"] UTF8String], "keydown");
146 EXPECT_EQ([[messages lastObject][@"keyCode"] intValue], 60);
147 EXPECT_EQ([[messages lastObject][@"modifiers"] intValue], 0x20006);
148
149 EXPECT_EQ([responses count], 1u);
150 EXPECT_EQ([[responses lastObject] boolValue], FALSE);
151
152 [messages removeAllObjects];
153 [responses removeAllObjects];
154
155 // LShift up
156 next_response = false;
157 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20104, @"", @"", FALSE, 56)
158 callback:^(BOOL handled) {
159 [responses addObject:@(handled)];
160 }];
161
162 EXPECT_EQ([messages count], 1u);
163 EXPECT_STREQ([[messages lastObject][@"keymap"] UTF8String], "macos");
164 EXPECT_STREQ([[messages lastObject][@"type"] UTF8String], "keyup");
165 EXPECT_EQ([[messages lastObject][@"keyCode"] intValue], 56);
166 EXPECT_EQ([[messages lastObject][@"modifiers"] intValue], 0x20004);
167
168 EXPECT_EQ([responses count], 1u);
169 EXPECT_EQ([[responses lastObject] boolValue], FALSE);
170
171 [messages removeAllObjects];
172 [responses removeAllObjects];
173
174 // RShift up
175 next_response = false;
176 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0, @"", @"", FALSE, 60)
177 callback:^(BOOL handled) {
178 [responses addObject:@(handled)];
179 }];
180
181 EXPECT_EQ([messages count], 1u);
182 EXPECT_STREQ([[messages lastObject][@"keymap"] UTF8String], "macos");
183 EXPECT_STREQ([[messages lastObject][@"type"] UTF8String], "keyup");
184 EXPECT_EQ([[messages lastObject][@"keyCode"] intValue], 60);
185 EXPECT_EQ([[messages lastObject][@"modifiers"] intValue], 0);
186
187 EXPECT_EQ([responses count], 1u);
188 EXPECT_EQ([[responses lastObject] boolValue], FALSE);
189
190 [messages removeAllObjects];
191 [responses removeAllObjects];
192
193 // RShift up again, should be ignored and not produce a keydown event, but the
194 // callback should be called.
195 next_response = false;
196 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, 60)
197 callback:^(BOOL handled) {
198 [responses addObject:@(handled)];
199 }];
200
201 EXPECT_EQ([messages count], 0u);
202 EXPECT_EQ([responses count], 1u);
203 EXPECT_EQ([responses[0] boolValue], TRUE);
204 }

References FlutterReply.

## ◆ TEST() [36/138]

flutter::testing::TEST | ( | FlutterChannelKeyResponderUnittests | ,
|  | EmptyResponseIsTakenAsHandled |
| ) |  |

Definition at line 206 of file FlutterChannelKeyResponderTest.mm.

206 {
207 __block NSMutableArray<id>* messages = [[NSMutableArray<id> alloc] init];
208 __block NSMutableArray<NSNumber*>* responses = [[NSMutableArray<NSNumber*> alloc] init];
209
210 id mockKeyEventChannel = OCMStrictClassMock([FlutterBasicMessageChannel class]);
211 OCMStub([mockKeyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
212 .andDo((^(NSInvocation* invocation) {
213 [invocation retainArguments];
214 NSDictionary* message;
215 [invocation getArgument:&message atIndex:2];
216 [messages addObject:message];
217
218 FlutterReply callback;
219 [invocation getArgument:&callback atIndex:3];
220 callback(nullptr);
221 }));
222
223 FlutterChannelKeyResponder* responder =
224 [[FlutterChannelKeyResponder alloc] initWithChannel:mockKeyEventChannel];
225 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", FALSE, 0)
226 callback:^(BOOL handled) {
227 [responses addObject:@(handled)];
228 }];
229
230 EXPECT_EQ([messages count], 1u);
231 EXPECT_STREQ([[messages lastObject][@"keymap"] UTF8String], "macos");
232 EXPECT_STREQ([[messages lastObject][@"type"] UTF8String], "keydown");
233 EXPECT_EQ([[messages lastObject][@"keyCode"] intValue], 0);
234 EXPECT_EQ([[messages lastObject][@"modifiers"] intValue], 0);
235 EXPECT_STREQ([[messages lastObject][@"characters"] UTF8String], "a");
236 EXPECT_STREQ([[messages lastObject][@"charactersIgnoringModifiers"] UTF8String], "a");
237
238 EXPECT_EQ([responses count], 1u);
239 EXPECT_EQ([[responses lastObject] boolValue], TRUE);
240 }

References FlutterReply.

## ◆ TEST() [37/138]

flutter::testing::TEST | ( | FlutterChannelKeyResponderUnittests | ,
|  | FollowsLayoutMap |
| ) |  |

Definition at line 242 of file FlutterChannelKeyResponderTest.mm.

242 {
243 __block NSMutableArray<id>* messages = [[NSMutableArray<id> alloc] init];
244 __block BOOL next_response = TRUE;
245 __block NSMutableArray<NSNumber*>* responses = [[NSMutableArray<NSNumber*> alloc] init];
246
247 id mockKeyEventChannel = OCMStrictClassMock([FlutterBasicMessageChannel class]);
248 OCMStub([mockKeyEventChannel sendMessage:[OCMArg any] reply:[OCMArg any]])
249 .andDo((^(NSInvocation* invocation) {
250 [invocation retainArguments];
251 NSDictionary* message;
252 [invocation getArgument:&message atIndex:2];
253 [messages addObject:message];
254
255 FlutterReply callback;
256 [invocation getArgument:&callback atIndex:3];
257 NSDictionary* keyMessage = @{
258 @"handled" : @(next_response),
259 };
260 callback(keyMessage);
261 }));
262
263 FlutterChannelKeyResponder* responder =
264 [[FlutterChannelKeyResponder alloc] initWithChannel:mockKeyEventChannel];
265
266 NSMutableDictionary<NSNumber*, NSNumber*>* layoutMap =
267 [NSMutableDictionary<NSNumber*, NSNumber*> dictionary];
268 responder.layoutMap = layoutMap;
269 // French layout
270 layoutMap[@(kVK_ANSI_A)] = @(kLogicalKeyQ);
271
272 [responder handleEvent:keyEvent(NSEventTypeKeyDown, kVK_ANSI_A, @"q", @"q", FALSE, 0)
273 callback:^(BOOL handled) {
274 [responses addObject:@(handled)];
275 }];
276
277 EXPECT_EQ([messages count], 1u);
278 EXPECT_STREQ([[messages lastObject][@"keymap"] UTF8String], "macos");
279 EXPECT_STREQ([[messages lastObject][@"type"] UTF8String], "keydown");
280 EXPECT_EQ([[messages lastObject][@"keyCode"] intValue], 0);
281 EXPECT_EQ([[messages lastObject][@"modifiers"] intValue], 0x0);
282 EXPECT_STREQ([[messages lastObject][@"characters"] UTF8String], "q");
283 EXPECT_STREQ([[messages lastObject][@"charactersIgnoringModifiers"] UTF8String], "q");
284 EXPECT_EQ([messages lastObject][@"specifiedLogicalKey"], @(kLogicalKeyQ));
285
286 EXPECT_EQ([responses count], 1u);
287 EXPECT_EQ([[responses lastObject] boolValue], TRUE);
288
289 [messages removeAllObjects];
290 [responses removeAllObjects];
291 }

References FlutterReply, and <FlutterKeyPrimaryResponder>::layoutMap.

## ◆ TEST() [38/138]

flutter::testing::TEST | ( | FlutterCompositorTest | ,
|  | TestCreate |
| ) |  |

Definition at line 88 of file FlutterCompositorTest.mm.

88 {
89 std::unique_ptr<flutter::FlutterCompositor> macos_compositor =
90 std::make_unique<FlutterCompositor>(MockViewProvider(),
91 /*platform_view_controller*/ nullptr);
92
93 FlutterBackingStore backing_store;
94 FlutterBackingStoreConfig config;
95 config.struct_size = sizeof(FlutterBackingStoreConfig);
96 config.size.width = 800;
97 config.size.height = 600;
98 macos_compositor->CreateBackingStore(&config, &backing_store);
99
100 ASSERT_EQ(backing_store.type, kFlutterBackingStoreTypeMetal);
101 ASSERT_NE(backing_store.metal.texture.texture, nil);
102 id<MTLTexture> texture = (__bridge id<MTLTexture>)backing_store.metal.texture.texture;
103 ASSERT_EQ(texture.width, 800ul);
104 ASSERT_EQ(texture.height, 600ul);
105 }

## ◆ TEST() [39/138]

flutter::testing::TEST | ( | FlutterCompositorTest | ,
|  | TestPresent |
| ) |  |

Definition at line 107 of file FlutterCompositorTest.mm.

107 {
108 __block NSArray<FlutterSurfacePresentInfo*>* presentedSurfaces = nil;
109
110 auto onPresent = ^(NSArray<FlutterSurfacePresentInfo*>* info) {
111 presentedSurfaces = info;
112 };
113
114 std::unique_ptr<flutter::FlutterCompositor> macos_compositor =
115 std::make_unique<FlutterCompositor>(MockViewProvider(onPresent),
116 /*platform_view_controller*/ nullptr);
117
118 FlutterBackingStore backing_store;
119 FlutterBackingStoreConfig config;
120 config.struct_size = sizeof(FlutterBackingStoreConfig);
121 config.size.width = 800;
122 config.size.height = 600;
123 macos_compositor->CreateBackingStore(&config, &backing_store);
124
125 FlutterLayer layers[] = {{
126 .struct_size = sizeof(FlutterLayer),
127 .type = kFlutterLayerContentTypeBackingStore,
128 .backing_store = &backing_store,
129 .offset = {0, 0},
130 .size = {800, 600},
131 }};
132 const FlutterLayer* layers_ptr = layers;
133
134 macos_compositor->Present(kFlutterImplicitViewId, &layers_ptr, 1);
135
136 ASSERT_EQ(presentedSurfaces.count, 1ul);
137 }

References kFlutterImplicitViewId.

## ◆ TEST() [40/138]

flutter::testing::TEST | ( | FlutterEmbedderExternalTextureUnittests | ,
|  | TestPopulateExternalTexture |
| ) |  |

Definition at line 128 of file FlutterEmbedderExternalTextureTest.mm.

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

References FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST() [41/138]

flutter::testing::TEST | ( | FlutterEmbedderExternalTextureUnittests | ,
|  | TestPopulateExternalTextureYUVA |
| ) |  |

Definition at line 181 of file FlutterEmbedderExternalTextureTest.mm.

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

References FlutterExternalTexture::populateTexture:, and texture_id.

## ◆ TEST() [42/138]

flutter::testing::TEST | ( | FlutterEmbedderExternalTextureUnittests | ,
|  | TestPopulateExternalTextureYUVA2 |
| ) |  |

Definition at line 236 of file FlutterEmbedderExternalTextureTest.mm.

236 {
237 // Constants.
238 const size_t width = 100;
239 const size_t height = 100;
240 const int64_t texture_id = 1;
241
242 // Set up the surface.
243 FlutterDarwinContextMetalSkia* darwinContextMetal =
244 [[FlutterDarwinContextMetalSkia alloc] initWithDefaultMTLDevice];
245 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
246 GrDirectContext* grContext = darwinContextMetal.mainContext.get();
247 sk_sp<SkSurface> gpuSurface(SkSurfaces::RenderTarget(grContext, skgpu::Budgeted::kNo, info));
248
249 // Create a texture.
250 TestExternalTexture* testExternalTexture =
251 [[TestExternalTexture alloc] initWidth:width
252 height:height
253 pixelFormatType:kCVPixelFormatType_420YpCbCr8BiPlanarFullRange];
254 FlutterExternalTexture* textureHolder =
255 [[FlutterExternalTexture alloc] initWithFlutterTexture:testExternalTexture
256 darwinMetalContext:darwinContextMetal];
257
258 // Callback to resolve the texture.
259 EmbedderExternalTextureMetal::ExternalTextureCallback callback = [&](int64_t texture_id, size_t w,
260 size_t h) {
261 EXPECT_TRUE(w == width);
262 EXPECT_TRUE(h == height);
263
264 FlutterMetalExternalTexture* texture = new FlutterMetalExternalTexture();
265 [textureHolder populateTexture:texture];
266
267 EXPECT_TRUE(texture->num_textures == 2);
268 EXPECT_TRUE(texture->textures != nullptr);
269 EXPECT_TRUE(texture->pixel_format == FlutterMetalExternalTexturePixelFormat::kYUVA);
270 EXPECT_TRUE(texture->yuv_color_space ==
271 FlutterMetalExternalTextureYUVColorSpace::kBT601FullRange);
272
273 return std::unique_ptr<FlutterMetalExternalTexture>(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() [43/138]

flutter::testing::TEST | ( | FlutterEmbedderExternalTextureUnittests | ,
|  | TestTextureResolution |
| ) |  |

Definition at line 69 of file FlutterEmbedderExternalTextureTest.mm.

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

References texture_id.

## ◆ TEST() [44/138]

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

Definition at line 119 of file FlutterEmbedderKeyResponderTest.mm.

119 {
120 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
121 __block BOOL last_handled = TRUE;
122 FlutterKeyEvent* event;
123
124 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
125 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
126 _Nullable _VoidPtr user_data) {
127 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
128 callback:callback
129 userData:user_data]];
130 }];
131
132 last_handled = FALSE;
133 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 123.0f, 0x100, @"a", @"a", FALSE, 0)
134 callback:^(BOOL handled) {
135 last_handled = handled;
136 }];
137
138 EXPECT_EQ([events count], 1u);
139 event = [events lastObject].data;
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 EXPECT_EQ(event->type, kFlutterKeyEventTypeRepeat);
163 EXPECT_EQ(event->physical, kPhysicalKeyA);
164 EXPECT_EQ(event->logical, kLogicalKeyA);
165 EXPECT_STREQ(event->character, "a");
166 EXPECT_EQ(event->synthesized, false);
167
168 EXPECT_EQ(last_handled, FALSE);
169 EXPECT_TRUE([[events lastObject] hasCallback]);
170 [[events lastObject] respond:TRUE];
171 EXPECT_EQ(last_handled, TRUE);
172
173 [events removeAllObjects];
174
175 last_handled = TRUE;
176 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 124.0f, 0x100, @"a", @"a", FALSE, kKeyCodeKeyA)
177 callback:^(BOOL handled) {
178 last_handled = handled;
179 }];
180
181 EXPECT_EQ([events count], 1u);
182 event = [events lastObject].data;
183 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
184 EXPECT_EQ(event->timestamp, 124000000.0f);
185 EXPECT_EQ(event->physical, kPhysicalKeyA);
186 EXPECT_EQ(event->logical, kLogicalKeyA);
187 EXPECT_EQ(event->character, nullptr);
188 EXPECT_EQ(event->synthesized, false);
189
190 EXPECT_EQ(last_handled, TRUE);
191 EXPECT_TRUE([[events lastObject] hasCallback]);
192 [[events lastObject] respond:FALSE]; // Check if responding FALSE works
193 EXPECT_EQ(last_handled, FALSE);
194
195 [events removeAllObjects];
196 }

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

## ◆ TEST() [45/138]

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

Definition at line 398 of file FlutterEmbedderKeyResponderTest.mm.

398 {
399 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
400 __block BOOL last_handled = TRUE;
401 FlutterKeyEvent* event;
402
403 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
404 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
405 _Nullable _VoidPtr user_data) {
406 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
407 callback:callback
408 userData:user_data]];
409 }];
410
411 last_handled = TRUE;
412 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", TRUE, kKeyCodeKeyA)
413 callback:^(BOOL handled) {
414 last_handled = handled;
415 }];
416
417 EXPECT_EQ([events count], 1u);
418 event = [events lastObject].data;
419 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
420 EXPECT_EQ(event->physical, kPhysicalKeyA);
421 EXPECT_EQ(event->logical, kLogicalKeyA);
422 EXPECT_STREQ(event->character, "a");
423 EXPECT_EQ(event->synthesized, false);
424 EXPECT_EQ(last_handled, TRUE);
425 [[events lastObject] respond:FALSE];
426 EXPECT_EQ(last_handled, FALSE);
427
428 [events removeAllObjects];
429 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [46/138]

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

Definition at line 1053 of file FlutterEmbedderKeyResponderTest.mm.

1053 {
1054 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
1055 __block BOOL last_handled = TRUE;
1056 id keyEventCallback = ^(BOOL handled) {
1057 last_handled = handled;
1058 };
1059 FlutterKeyEvent* event;
1060
1061 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
1062 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
1063 _Nullable _VoidPtr user_data) {
1064 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
1065 callback:callback
1066 userData:user_data]];
1067 }];
1068
1069 // In: CapsLock down
1070 // Out: CapsLock down & *CapsLock Up
1071 last_handled = FALSE;
1072 [responder
1073 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x10100, @"", @"", FALSE, kKeyCodeCapsLock)
1074 callback:keyEventCallback];
1075
1076 EXPECT_EQ([events count], 2u);
1077
1078 event = [events firstObject].data;
1079 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1080 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1081 EXPECT_EQ(event->logical, kLogicalCapsLock);
1082 EXPECT_STREQ(event->character, nullptr);
1083 EXPECT_EQ(event->synthesized, false);
1084 EXPECT_TRUE([[events firstObject] hasCallback]);
1085
1086 event = [events lastObject].data;
1087 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1088 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1089 EXPECT_EQ(event->logical, kLogicalCapsLock);
1090 EXPECT_STREQ(event->character, nullptr);
1091 EXPECT_EQ(event->synthesized, true);
1092 EXPECT_FALSE([[events lastObject] hasCallback]);
1093
1094 EXPECT_EQ(last_handled, FALSE);
1095 [[events firstObject] respond:TRUE];
1096 EXPECT_EQ(last_handled, TRUE);
1097
1098 [events removeAllObjects];
1099
1100 // In: CapsLock up
1101 // Out: CapsLock down & *CapsLock Up
1102 last_handled = FALSE;
1103 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeCapsLock)
1104 callback:keyEventCallback];
1105
1106 EXPECT_EQ([events count], 2u);
1107
1108 event = [events firstObject].data;
1109 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1110 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1111 EXPECT_EQ(event->logical, kLogicalCapsLock);
1112 EXPECT_STREQ(event->character, nullptr);
1113 EXPECT_EQ(event->synthesized, false);
1114 EXPECT_TRUE([[events firstObject] hasCallback]);
1115
1116 event = [events lastObject].data;
1117 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1118 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1119 EXPECT_EQ(event->logical, kLogicalCapsLock);
1120 EXPECT_STREQ(event->character, nullptr);
1121 EXPECT_EQ(event->synthesized, true);
1122 EXPECT_FALSE([[events lastObject] hasCallback]);
1123
1124 EXPECT_EQ(last_handled, FALSE);
1125 [[events firstObject] respond:TRUE];
1126 EXPECT_EQ(last_handled, TRUE);
1127
1128 [events removeAllObjects];
1129 }

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

## ◆ TEST() [47/138]

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

Definition at line 693 of file FlutterEmbedderKeyResponderTest.mm.

693 {
694 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
695 FlutterKeyEvent* event;
696
697 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
698 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
699 _Nullable _VoidPtr user_data) {
700 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
701 callback:callback
702 userData:user_data]];
703 }];
704
705 [responder
706 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
707 callback:^(BOOL handled){
708 }];
709
710 EXPECT_EQ([events count], 1u);
711 event = [events lastObject].data;
712 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
713 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
714 EXPECT_EQ(event->logical, kLogicalShiftLeft);
715 EXPECT_STREQ(event->character, nullptr);
716 EXPECT_EQ(event->synthesized, false);
717 [[events lastObject] respond:TRUE];
718
719 [events removeAllObjects];
720
721 [responder
722 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20106, @"", @"", FALSE, kKeyCodeShiftRight)
723 callback:^(BOOL handled){
724 }];
725
726 EXPECT_EQ([events count], 1u);
727 event = [events lastObject].data;
728 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
729 EXPECT_EQ(event->physical, kPhysicalShiftRight);
730 EXPECT_EQ(event->logical, kLogicalShiftRight);
731 EXPECT_STREQ(event->character, nullptr);
732 EXPECT_EQ(event->synthesized, false);
733 [[events lastObject] respond:TRUE];
734
735 [events removeAllObjects];
736
737 [responder
738 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20104, @"", @"", FALSE, kKeyCodeShiftLeft)
739 callback:^(BOOL handled){
740 }];
741
742 EXPECT_EQ([events count], 1u);
743 event = [events lastObject].data;
744 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
745 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
746 EXPECT_EQ(event->logical, kLogicalShiftLeft);
747 EXPECT_STREQ(event->character, nullptr);
748 EXPECT_EQ(event->synthesized, false);
749 [[events lastObject] respond:TRUE];
750
751 [events removeAllObjects];
752
753 [responder
754 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftRight)
755 callback:^(BOOL handled){
756 }];
757
758 EXPECT_EQ([events count], 1u);
759 event = [events lastObject].data;
760 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
761 EXPECT_EQ(event->physical, kPhysicalShiftRight);
762 EXPECT_EQ(event->logical, kLogicalShiftRight);
763 EXPECT_STREQ(event->character, nullptr);
764 EXPECT_EQ(event->synthesized, false);
765 [[events lastObject] respond:TRUE];
766
767 [events removeAllObjects];
768 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [48/138]

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

Definition at line 368 of file FlutterEmbedderKeyResponderTest.mm.

368 {
369 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
370 FlutterKeyEvent* event;
371 __block BOOL last_handled = TRUE;
372
373 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
374 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
375 _Nullable _VoidPtr user_data) {
376 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
377 callback:callback
378 userData:user_data]];
379 }];
380
381 last_handled = FALSE;
382 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0x100, @"a", @"a", FALSE, kKeyCodeKeyA)
383 callback:^(BOOL handled) {
384 last_handled = handled;
385 }];
386
387 EXPECT_EQ([events count], 1u);
388 EXPECT_EQ(last_handled, TRUE);
389 event = [events lastObject].data;
390 EXPECT_EQ(event->physical, 0ull);
391 EXPECT_EQ(event->logical, 0ull);
392 EXPECT_FALSE([[events lastObject] hasCallback]);
393 EXPECT_EQ(last_handled, TRUE);
394
395 [events removeAllObjects];
396 }

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

## ◆ TEST() [49/138]

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

Definition at line 268 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [50/138]

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

Definition at line 198 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [51/138]

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

Definition at line 545 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [52/138]

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

Definition at line 1132 of file FlutterEmbedderKeyResponderTest.mm.

1132 {
1133 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
1134 FlutterKeyEvent* event;
1135 __block BOOL last_handled = TRUE;
1136 id keyEventCallback = ^(BOOL handled) {
1137 last_handled = handled;
1138 };
1139
1140 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
1141 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
1142 _Nullable _VoidPtr user_data) {
1143 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
1144 callback:callback
1145 userData:user_data]];
1146 }];
1147
1148 // In: CapsLock down
1149 // Out: (empty)
1150 last_handled = FALSE;
1151 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeCapsLock)
1152 callback:keyEventCallback];
1153
1154 EXPECT_EQ([events count], 1u);
1155 EXPECT_EQ(last_handled, TRUE);
1156 event = [events lastObject].data;
1157 EXPECT_EQ(event->physical, 0ull);
1158 EXPECT_EQ(event->logical, 0ull);
1159 EXPECT_FALSE([[events lastObject] hasCallback]);
1160 EXPECT_EQ(last_handled, TRUE);
1161
1162 [events removeAllObjects];
1163 }

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

## ◆ TEST() [53/138]

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

Definition at line 1166 of file FlutterEmbedderKeyResponderTest.mm.

1166 {
1167 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
1168 __block BOOL last_handled = TRUE;
1169 id keyEventCallback = ^(BOOL handled) {
1170 last_handled = handled;
1171 };
1172 FlutterKeyEvent* event;
1173
1174 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
1175 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
1176 _Nullable _VoidPtr user_data) {
1177 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
1178 callback:callback
1179 userData:user_data]];
1180 }];
1181
1182 last_handled = FALSE;
1183 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x10100, @"A", @"a", FALSE, kKeyCodeKeyA)
1184 callback:keyEventCallback];
1185
1186 EXPECT_EQ([events count], 3u);
1187
1188 event = events[0].data;
1189 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1190 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1191 EXPECT_EQ(event->logical, kLogicalCapsLock);
1192 EXPECT_STREQ(event->character, nullptr);
1193 EXPECT_EQ(event->synthesized, true);
1194 EXPECT_FALSE([events[0] hasCallback]);
1195
1196 event = events[1].data;
1197 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1198 EXPECT_EQ(event->physical, kPhysicalCapsLock);
1199 EXPECT_EQ(event->logical, kLogicalCapsLock);
1200 EXPECT_STREQ(event->character, nullptr);
1201 EXPECT_EQ(event->synthesized, true);
1202 EXPECT_FALSE([events[1] hasCallback]);
1203
1204 event = events[2].data;
1205 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1206 EXPECT_EQ(event->physical, kPhysicalKeyA);
1207 EXPECT_EQ(event->logical, kLogicalKeyA);
1208 EXPECT_STREQ(event->character, "A");
1209 EXPECT_EQ(event->synthesized, false);
1210 EXPECT_TRUE([events[2] hasCallback]);
1211
1212 EXPECT_EQ(last_handled, FALSE);
1213 [[events lastObject] respond:TRUE];
1214 EXPECT_EQ(last_handled, TRUE);
1215
1216 [events removeAllObjects];
1217 }

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

## ◆ TEST() [54/138]

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

Definition at line 309 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [55/138]

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

Definition at line 775 of file FlutterEmbedderKeyResponderTest.mm.

775 {
776 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
777 __block BOOL last_handled = TRUE;
778 id keyEventCallback = ^(BOOL handled) {
779 last_handled = handled;
780 };
781 FlutterKeyEvent* event;
782
783 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
784 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
785 _Nullable _VoidPtr user_data) {
786 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
787 callback:callback
788 userData:user_data]];
789 }];
790
791 // Case 1:
792 // In: L down, (L up), L down, L up
793 // Out: L down, L up
794 last_handled = FALSE;
795 [responder
796 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
797 callback:keyEventCallback];
798
799 EXPECT_EQ([events count], 1u);
800 event = [events lastObject].data;
801 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
802 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
803 EXPECT_EQ(event->logical, kLogicalShiftLeft);
804 EXPECT_STREQ(event->character, nullptr);
805 EXPECT_EQ(event->synthesized, false);
806
807 EXPECT_EQ(last_handled, FALSE);
808 EXPECT_TRUE([[events lastObject] hasCallback]);
809 [[events lastObject] respond:TRUE];
810 EXPECT_EQ(last_handled, TRUE);
811
812 [events removeAllObjects];
813
814 last_handled = FALSE;
815 [responder
816 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
817 callback:keyEventCallback];
818
819 EXPECT_EQ([events count], 1u);
820 EXPECT_EQ([events lastObject].data->physical, 0u);
821 EXPECT_EQ([events lastObject].data->logical, 0u);
822 EXPECT_FALSE([[events lastObject] hasCallback]);
823 EXPECT_EQ(last_handled, TRUE);
824 [events removeAllObjects];
825
826 last_handled = FALSE;
827 [responder
828 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftLeft)
829 callback:keyEventCallback];
830
831 EXPECT_EQ([events count], 1u);
832 event = [events lastObject].data;
833 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
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 // Case 2:
847 // In: (L down), L up
848 // Out:
849
850 last_handled = FALSE;
851 [responder
852 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftLeft)
853 callback:keyEventCallback];
854
855 EXPECT_EQ([events count], 1u);
856 EXPECT_EQ([events lastObject].data->physical, 0u);
857 EXPECT_EQ([events lastObject].data->logical, 0u);
858 EXPECT_FALSE([[events lastObject] hasCallback]);
859 EXPECT_EQ(last_handled, TRUE);
860 [events removeAllObjects];
861
862 // Case 3:
863 // In: L down, (L up), (R down), R up
864 // Out: L down, *L up
865
866 last_handled = FALSE;
867 [responder
868 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
869 callback:keyEventCallback];
870
871 EXPECT_EQ([events count], 1u);
872 event = [events lastObject].data;
873 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
874 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
875 EXPECT_EQ(event->logical, kLogicalShiftLeft);
876 EXPECT_STREQ(event->character, nullptr);
877 EXPECT_EQ(event->synthesized, false);
878
879 EXPECT_EQ(last_handled, FALSE);
880 EXPECT_TRUE([[events lastObject] hasCallback]);
881 [[events lastObject] respond:TRUE];
882 EXPECT_EQ(last_handled, TRUE);
883
884 [events removeAllObjects];
885
886 last_handled = FALSE;
887 [responder
888 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftRight)
889 callback:keyEventCallback];
890
891 EXPECT_EQ([events count], 1u);
892 event = [events lastObject].data;
893 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
894 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
895 EXPECT_EQ(event->logical, kLogicalShiftLeft);
896 EXPECT_STREQ(event->character, nullptr);
897 EXPECT_EQ(event->synthesized, true);
898
899 // The primary event is automatically replied with TRUE, unrelated to the received event.
900 EXPECT_EQ(last_handled, TRUE);
901 EXPECT_FALSE([[events lastObject] hasCallback]);
902
903 [events removeAllObjects];
904
905 // Case 4:
906 // In: L down, R down, (L up), R up
907 // Out: L down, R down *L up & R up
908
909 last_handled = FALSE;
910 [responder
911 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20102, @"", @"", FALSE, kKeyCodeShiftLeft)
912 callback:keyEventCallback];
913
914 EXPECT_EQ([events count], 1u);
915 event = [events lastObject].data;
916 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
917 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
918 EXPECT_EQ(event->logical, kLogicalShiftLeft);
919 EXPECT_STREQ(event->character, nullptr);
920 EXPECT_EQ(event->synthesized, false);
921
922 EXPECT_EQ(last_handled, FALSE);
923 EXPECT_TRUE([[events lastObject] hasCallback]);
924 [[events lastObject] respond:TRUE];
925 EXPECT_EQ(last_handled, TRUE);
926
927 [events removeAllObjects];
928
929 last_handled = FALSE;
930 [responder
931 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x20106, @"", @"", FALSE, kKeyCodeShiftRight)
932 callback:keyEventCallback];
933
934 EXPECT_EQ([events count], 1u);
935 event = [events lastObject].data;
936 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
937 EXPECT_EQ(event->physical, kPhysicalShiftRight);
938 EXPECT_EQ(event->logical, kLogicalShiftRight);
939 EXPECT_STREQ(event->character, nullptr);
940 EXPECT_EQ(event->synthesized, false);
941
942 EXPECT_EQ(last_handled, FALSE);
943 EXPECT_TRUE([[events lastObject] hasCallback]);
944 [[events lastObject] respond:TRUE];
945 EXPECT_EQ(last_handled, TRUE);
946
947 [events removeAllObjects];
948
949 last_handled = FALSE;
950 [responder
951 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftRight)
952 callback:keyEventCallback];
953
954 EXPECT_EQ([events count], 2u);
955 event = [events firstObject].data;
956 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
957 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
958 EXPECT_EQ(event->logical, kLogicalShiftLeft);
959 EXPECT_STREQ(event->character, nullptr);
960 EXPECT_EQ(event->synthesized, true);
961
962 EXPECT_FALSE([[events firstObject] hasCallback]);
963
964 event = [events lastObject].data;
965 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
966 EXPECT_EQ(event->physical, kPhysicalShiftRight);
967 EXPECT_EQ(event->logical, kLogicalShiftRight);
968 EXPECT_STREQ(event->character, nullptr);
969 EXPECT_EQ(event->synthesized, false);
970
971 EXPECT_EQ(last_handled, FALSE);
972 EXPECT_TRUE([[events lastObject] hasCallback]);
973 [[events lastObject] respond:TRUE];
974 EXPECT_EQ(last_handled, TRUE);
975
976 [events removeAllObjects];
977 }

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

## ◆ TEST() [56/138]

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

Definition at line 979 of file FlutterEmbedderKeyResponderTest.mm.

979 {
980 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
981 __block BOOL last_handled = TRUE;
982 id keyEventCallback = ^(BOOL handled) {
983 last_handled = handled;
984 };
985 FlutterKeyEvent* event;
986
987 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
988 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
989 _Nullable _VoidPtr user_data) {
990 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
991 callback:callback
992 userData:user_data]];
993 }];
994
995 // In: (LShift down), A down, (LShift up), A up
996 // Out: *LS down & A down, *LS up & A up
997
998 last_handled = FALSE;
999 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x20102, @"A", @"A", FALSE, kKeyCodeKeyA)
1000 callback:keyEventCallback];
1001
1002 EXPECT_EQ([events count], 2u);
1003 event = [events firstObject].data;
1004 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1005 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
1006 EXPECT_EQ(event->logical, kLogicalShiftLeft);
1007 EXPECT_STREQ(event->character, nullptr);
1008 EXPECT_EQ(event->synthesized, true);
1009 EXPECT_FALSE([[events firstObject] hasCallback]);
1010
1011 event = [events lastObject].data;
1012 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
1013 EXPECT_EQ(event->physical, kPhysicalKeyA);
1014 EXPECT_EQ(event->logical, kLogicalKeyA);
1015 EXPECT_STREQ(event->character, "A");
1016 EXPECT_EQ(event->synthesized, false);
1017 EXPECT_TRUE([[events lastObject] hasCallback]);
1018
1019 EXPECT_EQ(last_handled, FALSE);
1020 [[events lastObject] respond:TRUE];
1021 EXPECT_EQ(last_handled, TRUE);
1022
1023 [events removeAllObjects];
1024
1025 last_handled = FALSE;
1026 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0x100, @"a", @"a", FALSE, kKeyCodeKeyA)
1027 callback:keyEventCallback];
1028
1029 EXPECT_EQ([events count], 2u);
1030 event = [events firstObject].data;
1031 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1032 EXPECT_EQ(event->physical, kPhysicalShiftLeft);
1033 EXPECT_EQ(event->logical, kLogicalShiftLeft);
1034 EXPECT_STREQ(event->character, nullptr);
1035 EXPECT_EQ(event->synthesized, true);
1036 EXPECT_FALSE([[events firstObject] hasCallback]);
1037
1038 event = [events lastObject].data;
1039 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
1040 EXPECT_EQ(event->physical, kPhysicalKeyA);
1041 EXPECT_EQ(event->logical, kLogicalKeyA);
1042 EXPECT_STREQ(event->character, nullptr);
1043 EXPECT_EQ(event->synthesized, false);
1044 EXPECT_TRUE([[events lastObject] hasCallback]);
1045
1046 EXPECT_EQ(last_handled, FALSE);
1047 [[events lastObject] respond:TRUE];
1048 EXPECT_EQ(last_handled, TRUE);
1049
1050 [events removeAllObjects];
1051 }

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

## ◆ TEST() [57/138]

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

Definition at line 435 of file FlutterEmbedderKeyResponderTest.mm.

435 {
436 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
437 FlutterKeyEvent* event;
438
439 FlutterEmbedderKeyResponder* responder = [[FlutterEmbedderKeyResponder alloc]
440 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
441 _Nullable _VoidPtr user_data) {
442 [events addObject:[[TestKeyEvent alloc] initWithEvent:&event
443 callback:callback
444 userData:user_data]];
445 }];
446
447 [responder handleEvent:keyEvent(NSEventTypeFlagsChanged, 123.0f, 0x20104, @"", @"", FALSE,
448 kKeyCodeShiftRight)
449 callback:^(BOOL handled){
450 }];
451
452 EXPECT_EQ([events count], 1u);
453 event = [events lastObject].data;
454 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
455 EXPECT_EQ(event->timestamp, 123000000.0f);
456 EXPECT_EQ(event->physical, kPhysicalShiftRight);
457 EXPECT_EQ(event->logical, kLogicalShiftRight);
458 EXPECT_STREQ(event->character, nullptr);
459 EXPECT_EQ(event->synthesized, false);
460 [[events lastObject] respond:TRUE];
461
462 [events removeAllObjects];
463
464 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x20104, @"A", @"A", FALSE, kKeyCodeKeyA)
465 callback:^(BOOL handled){
466 }];
467
468 EXPECT_EQ([events count], 1u);
469 event = [events lastObject].data;
470 EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
471 EXPECT_EQ(event->physical, kPhysicalKeyA);
472 EXPECT_EQ(event->logical, kLogicalKeyA);
473 EXPECT_STREQ(event->character, "A");
474 EXPECT_EQ(event->synthesized, false);
475 [[events lastObject] respond:TRUE];
476
477 [events removeAllObjects];
478
479 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x20104, @"A", @"A", TRUE, kKeyCodeKeyA)
480 callback:^(BOOL handled){
481 }];
482
483 EXPECT_EQ([events count], 1u);
484 event = [events lastObject].data;
485 EXPECT_EQ(event->type, kFlutterKeyEventTypeRepeat);
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
495 handleEvent:keyEvent(NSEventTypeFlagsChanged, 0x100, @"", @"", FALSE, kKeyCodeShiftRight)
496 callback:^(BOOL handled){
497 }];
498
499 EXPECT_EQ([events count], 1u);
500 event = [events lastObject].data;
501 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
502 EXPECT_EQ(event->physical, kPhysicalShiftRight);
503 EXPECT_EQ(event->logical, kLogicalShiftRight);
504 EXPECT_STREQ(event->character, nullptr);
505 EXPECT_EQ(event->synthesized, false);
506 [[events lastObject] respond:TRUE];
507
508 [events removeAllObjects];
509
510 [responder handleEvent:keyEvent(NSEventTypeKeyDown, 0x100, @"a", @"a", TRUE, kKeyCodeKeyA)
511 callback:^(BOOL handled){
512 }];
513
514 EXPECT_EQ([events count], 1u);
515 event = [events lastObject].data;
516 EXPECT_EQ(event->type, kFlutterKeyEventTypeRepeat);
517 EXPECT_EQ(event->physical, kPhysicalKeyA);
518 EXPECT_EQ(event->logical, kLogicalKeyA);
519 EXPECT_STREQ(event->character, "a");
520 EXPECT_EQ(event->synthesized, false);
521
522 [events removeAllObjects];
523
524 [responder handleEvent:keyEvent(NSEventTypeKeyUp, 0x100, @"a", @"a", FALSE, kKeyCodeKeyA)
525 callback:^(BOOL handled){
526 }];
527
528 EXPECT_EQ([events count], 1u);
529 event = [events lastObject].data;
530 EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
531 EXPECT_EQ(event->physical, kPhysicalKeyA);
532 EXPECT_EQ(event->logical, kLogicalKeyA);
533 EXPECT_STREQ(event->character, nullptr);
534 EXPECT_EQ(event->synthesized, false);
535 [[events lastObject] respond:TRUE];
536
537 [events removeAllObjects];
538 }

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

## ◆ TEST() [58/138]

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

Definition at line 458 of file FlutterKeyboardManagerTest.mm.

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

## ◆ TEST() [59/138]

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

Definition at line 434 of file FlutterKeyboardManagerTest.mm.

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

## ◆ TEST() [60/138]

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

Definition at line 442 of file FlutterKeyboardManagerTest.mm.

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

## ◆ TEST() [61/138]

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

Definition at line 446 of file FlutterKeyboardManagerTest.mm.

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

## ◆ TEST() [62/138]

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

Definition at line 450 of file FlutterKeyboardManagerTest.mm.

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

## ◆ TEST() [63/138]

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

Definition at line 454 of file FlutterKeyboardManagerTest.mm.

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

## ◆ TEST() [64/138]

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

Definition at line 438 of file FlutterKeyboardManagerTest.mm.

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

## ◆ TEST() [65/138]

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

Definition at line 430 of file FlutterKeyboardManagerTest.mm.

430 {
431 ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] singlePrimaryResponder]);
432 }

## ◆ TEST() [66/138]

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

Definition at line 183 of file FlutterMenuPluginTest.mm.

183 {
184 ASSERT_TRUE([[FlutterMenuPluginTestObjc alloc] testSetMenu]);
185 }

## ◆ TEST() [67/138]

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

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

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() [70/138]

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() [71/138]

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() [72/138]

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() [73/138]

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() [74/138]

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() [75/138]

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() [76/138]

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() [77/138]

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() [78/138]

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() [79/138]

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() [80/138]

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() [81/138]

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() [82/138]

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() [83/138]

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() [84/138]

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

Definition at line 97 of file FlutterSurfaceManagerTest.mm.

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

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

## ◆ TEST() [85/138]

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

Definition at line 171 of file FlutterSurfaceManagerTest.mm.

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

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

## ◆ TEST() [86/138]

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

Definition at line 65 of file FlutterSurfaceManagerTest.mm.

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

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

## ◆ TEST() [87/138]

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

Definition at line 128 of file FlutterSurfaceManagerTest.mm.

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

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

## ◆ TEST() [88/138]

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

Definition at line 78 of file FlutterSurfaceManagerTest.mm.

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

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

## ◆ TEST() [89/138]

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

Definition at line 1985 of file FlutterTextInputPluginTest.mm.

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

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

## ◆ TEST() [90/138]

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

Definition at line 1920 of file FlutterTextInputPluginTest.mm.

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

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

## ◆ TEST() [91/138]

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

Definition at line 1900 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [92/138]

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

Definition at line 2052 of file FlutterTextInputPluginTest.mm.

2052 {
2053 id engineMock = flutter::testing::CreateMockFlutterEngine(@"");
2054 id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger));
2055 OCMStub( // NOLINT(google-objc-avoid-throwing-exception)
2056 [engineMock binaryMessenger])
2057 .andReturn(binaryMessengerMock);
2058
2059 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engineMock
2060 nibName:@""
2061 bundle:nil];
2062
2063 FlutterTextInputPlugin* plugin =
2064 [[FlutterTextInputPlugin alloc] initWithViewController:viewController];
2065
2066 ASSERT_TRUE(NSIsEmptyRect(plugin.frame));
2067 ASSERT_TRUE(plugin.clipsToBounds);
2068 }

References CreateMockFlutterEngine().

## ◆ TEST() [93/138]

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

Definition at line 2019 of file FlutterTextInputPluginTest.mm.

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

References FlutterMethodCall::methodCallWithMethodName:arguments:.

## ◆ TEST() [94/138]

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

Definition at line 1858 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [95/138]

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

Definition at line 1838 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [96/138]

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

Definition at line 1850 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [97/138]

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

Definition at line 1854 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [98/138]

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

Definition at line 1842 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [99/138]

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

Definition at line 1846 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [100/138]

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

Definition at line 1834 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [101/138]

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

Definition at line 1830 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [102/138]

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

Definition at line 1884 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [103/138]

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

Definition at line 1888 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [104/138]

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

Definition at line 1818 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [105/138]

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

Definition at line 1863 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [106/138]

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

Definition at line 1867 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [107/138]

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

Definition at line 1871 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [108/138]

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

Definition at line 1912 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [109/138]

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

Definition at line 1892 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [110/138]

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

Definition at line 1880 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [111/138]

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

Definition at line 1896 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [112/138]

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

Definition at line 1908 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [113/138]

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

Definition at line 1916 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [114/138]

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

Definition at line 1876 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [115/138]

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

Definition at line 1826 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [116/138]

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

Definition at line 1822 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [117/138]

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

Definition at line 1904 of file FlutterTextInputPluginTest.mm.

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

## ◆ TEST() [118/138]

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

Definition at line 28 of file FlutterTextInputSemanticsObjectTest.mm.

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

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

## ◆ TEST() [119/138]

flutter::testing::TEST | ( | FlutterViewController | ,
|  | CanSetMouseTrackingModeBeforeViewLoaded |
| ) |  |

Definition at line 193 of file FlutterViewControllerTest.mm.

193 {
194 NSString* fixtures = @(testing::GetFixturesPath());
195 FlutterDartProject* project = [[FlutterDartProject alloc]
196 initWithAssetsPath:fixtures
197 ICUDataPath:[fixtures stringByAppendingString:@"/icudtl.dat"]];
198 FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:project];
199 viewController.mouseTrackingMode = kFlutterMouseTrackingModeInActiveApp;
200 ASSERT_EQ(viewController.mouseTrackingMode, kFlutterMouseTrackingModeInActiveApp);
201 }

References FlutterViewController::mouseTrackingMode.

## ◆ TEST() [120/138]

flutter::testing::TEST | ( | FlutterViewController | ,
|  | FlutterViewAcceptsFirstMouse |
| ) |  |

Definition at line 161 of file FlutterViewControllerTest.mm.

161 {
162 FlutterViewController* viewControllerMock = CreateMockViewController();
163 [viewControllerMock loadView];
164 EXPECT_EQ([viewControllerMock.flutterView acceptsFirstMouse:nil], YES);
165 }

References CreateMockViewController().

## ◆ TEST() [121/138]

flutter::testing::TEST | ( | FlutterViewController | ,
|  | HasViewThatHidesOtherViewsInAccessibility |
| ) |  |

Definition at line 140 of file FlutterViewControllerTest.mm.

140 {
141 FlutterViewController* viewControllerMock = CreateMockViewController();
142
143 [viewControllerMock loadView];
144 auto subViews = [viewControllerMock.view subviews];
145
146 EXPECT_EQ([subViews count], 1u);
147 EXPECT_EQ(subViews[0], viewControllerMock.flutterView);
148
149 NSTextField* textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 1, 1)];
150 [viewControllerMock.view addSubview:textField];
151
152 subViews = [viewControllerMock.view subviews];
153 EXPECT_EQ([subViews count], 2u);
154
155 auto accessibilityChildren = viewControllerMock.view.accessibilityChildren;
156 // The accessibilityChildren should only contains the FlutterView.
157 EXPECT_EQ([accessibilityChildren count], 1u);
158 EXPECT_EQ(accessibilityChildren[0], viewControllerMock.flutterView);
159 }

References CreateMockViewController().

## ◆ TEST() [122/138]

flutter::testing::TEST | ( | FlutterViewController | ,
|  | ReparentsPluginWhenAccessibilityDisabled |
| ) |  |

Definition at line 167 of file FlutterViewControllerTest.mm.

167 {
168 FlutterEngine* engine = CreateTestEngine();
169 FlutterViewController* viewController = [[FlutterViewController alloc] initWithEngine:engine
170 nibName:nil
171 bundle:nil];
172 [viewController loadView];
173 [engine setViewController:viewController];
174 // Creates a NSWindow so that sub view can be first responder.
175 NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600)
176 styleMask:NSBorderlessWindowMask
177 backing:NSBackingStoreBuffered
178 defer:NO];
179 window.contentView = viewController.view;
180 NSView* dummyView = [[NSView alloc] initWithFrame:CGRectZero];
181 [viewController.view addSubview:dummyView];
182 // Attaches FlutterTextInputPlugin to the view;
183 [dummyView addSubview:viewController.textInputPlugin];
184 // Makes sure the textInputPlugin can be the first responder.
185 EXPECT_TRUE([window makeFirstResponder:viewController.textInputPlugin]);
186 EXPECT_EQ([window firstResponder], viewController.textInputPlugin);
187 EXPECT_FALSE(viewController.textInputPlugin.superview == viewController.view);
188 [viewController onAccessibilityStatusChanged:NO];
189 // FlutterView becomes child of view controller
190 EXPECT_TRUE(viewController.textInputPlugin.superview == viewController.view);
191 }

References FlutterViewController::onAccessibilityStatusChanged:.

## ◆ TEST() [123/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | TestCtrlTabKeyEventIsPropagated |
| ) |  |

Definition at line 215 of file FlutterViewControllerTest.mm.

215 {
216 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testCtrlTabKeyEventIsPropagated]);
217 }

## ◆ TEST() [124/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | TestFlagsChangedEventsArePropagatedIfNotHandled |
| ) |  |

Definition at line 223 of file FlutterViewControllerTest.mm.

223 {
224 ASSERT_TRUE(
225 [[FlutterViewControllerTestObjC alloc] testFlagsChangedEventsArePropagatedIfNotHandled]);
226 }

## ◆ TEST() [125/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | testFlutterViewIsConfigured |
| ) |  |

Definition at line 248 of file FlutterViewControllerTest.mm.

248 {
249 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testFlutterViewIsConfigured]);
250 }

## ◆ TEST() [126/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | TestKeyboardIsRestartedOnEngineRestart |
| ) |  |

Definition at line 228 of file FlutterViewControllerTest.mm.

228 {
229 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyboardIsRestartedOnEngineRestart]);
230 }

## ◆ TEST() [127/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | TestKeyEquivalentIsPassedToTextInputPlugin |
| ) |  |

Definition at line 219 of file FlutterViewControllerTest.mm.

219 {
220 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEquivalentIsPassedToTextInputPlugin]);
221 }

## ◆ TEST() [128/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | TestKeyEventsAreNotPropagatedIfHandled |
| ) |  |

Definition at line 211 of file FlutterViewControllerTest.mm.

211 {
212 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEventsAreNotPropagatedIfHandled]);
213 }

## ◆ TEST() [129/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | TestKeyEventsArePropagatedIfNotHandled |
| ) |  |

Definition at line 207 of file FlutterViewControllerTest.mm.

207 {
208 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEventsArePropagatedIfNotHandled]);
209 }

## ◆ TEST() [130/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | TestKeyEventsAreSentToFramework |
| ) |  |

Definition at line 203 of file FlutterViewControllerTest.mm.

203 {
204 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testKeyEventsAreSentToFramework]);
205 }

## ◆ TEST() [131/138]

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

Definition at line 252 of file FlutterViewControllerTest.mm.

252 {
253 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testLookupKeyAssets]);
254 }

## ◆ TEST() [132/138]

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

Definition at line 256 of file FlutterViewControllerTest.mm.

256 {
257 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testLookupKeyAssetsWithPackage]);
258 }

## ◆ TEST() [133/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | TestModifierKeysAreSynthesizedOnMouseMove |
| ) |  |

Definition at line 240 of file FlutterViewControllerTest.mm.

240 {
241 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testModifierKeysAreSynthesizedOnMouseMove]);
242 }

## ◆ TEST() [134/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | TestMouseDownUpEventsSentToNextResponder |
| ) |  |

Definition at line 236 of file FlutterViewControllerTest.mm.

236 {
237 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testMouseDownUpEventsSentToNextResponder]);
238 }

## ◆ TEST() [135/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | TestTrackpadGesturesAreSentToFramework |
| ) |  |

Definition at line 232 of file FlutterViewControllerTest.mm.

232 {
233 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testTrackpadGesturesAreSentToFramework]);
234 }

## ◆ TEST() [136/138]

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

Definition at line 260 of file FlutterViewControllerTest.mm.

260 {
261 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testViewControllerIsReleased]);
262 }

## ◆ TEST() [137/138]

flutter::testing::TEST | ( | FlutterViewControllerTest | ,
|  | testViewWillAppearCalledMultipleTimes |
| ) |  |

Definition at line 244 of file FlutterViewControllerTest.mm.

244 {
245 ASSERT_TRUE([[FlutterViewControllerTestObjC alloc] testViewWillAppearCalledMultipleTimes]);
246 }

## ◆ TEST() [138/138]

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_F() [1/32]

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

Definition at line 122 of file FlutterEngineTest.mm.

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

## ◆ TEST_F() [2/32]

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

Definition at line 185 of file FlutterEngineTest.mm.

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

## ◆ TEST_F() [3/32]

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

Definition at line 272 of file FlutterEngineTest.mm.

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

References user_data.

## ◆ TEST_F() [4/32]

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

Definition at line 366 of file FlutterEngineTest.mm.

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

References user_data.

## ◆ TEST_F() [5/32]

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

Definition at line 488 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [6/32]

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

Definition at line 527 of file FlutterEngineTest.mm.

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

References user_data.

## ◆ TEST_F() [7/32]

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

Definition at line 212 of file FlutterEngineTest.mm.

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

References FlutterEngine::viewController.

## ◆ TEST_F() [8/32]

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

Definition at line 242 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [9/32]

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

Definition at line 565 of file FlutterEngineTest.mm.

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

References FlutterEngine::binaryMessenger.

## ◆ TEST_F() [10/32]

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

Definition at line 589 of file FlutterEngineTest.mm.

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

## ◆ TEST_F() [11/32]

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

Definition at line 1067 of file FlutterEngineTest.mm.

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

References CreateMockFlutterEngine().

## ◆ TEST_F() [12/32]

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

Definition at line 973 of file FlutterEngineTest.mm.

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

References CreateMockFlutterEngine().

## ◆ TEST_F() [13/32]

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

Definition at line 996 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [14/32]

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

Definition at line 879 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [15/32]

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

Definition at line 128 of file FlutterEngineTest.mm.

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

## ◆ TEST_F() [16/32]

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

Definition at line 724 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [17/32]

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

Definition at line 742 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [18/32]

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

Definition at line 957 of file FlutterEngineTest.mm.

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

References CreateMockFlutterEngine().

## ◆ TEST_F() [19/32]

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

Definition at line 816 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [20/32]

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

Definition at line 848 of file FlutterEngineTest.mm.

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

References FlutterEngine::viewController.

## ◆ TEST_F() [21/32]

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

Definition at line 667 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [22/32]

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

Definition at line 166 of file FlutterEngineTest.mm.

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

## ◆ TEST_F() [23/32]

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

Definition at line 472 of file FlutterEngineTest.mm.

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

## ◆ TEST_F() [24/32]

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

Definition at line 447 of file FlutterEngineTest.mm.

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

References FlutterEngine::viewController.

## ◆ TEST_F() [25/32]

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

Definition at line 611 of file FlutterEngineTest.mm.

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

## ◆ TEST_F() [26/32]

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

Definition at line 623 of file FlutterEngineTest.mm.

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

## ◆ TEST_F() [27/32]

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

Definition at line 640 of file FlutterEngineTest.mm.

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

## ◆ TEST_F() [28/32]

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

Definition at line 760 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [29/32]

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

Definition at line 780 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [30/32]

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

Definition at line 149 of file FlutterEngineTest.mm.

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

## ◆ TEST_F() [31/32]

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

Definition at line 802 of file FlutterEngineTest.mm.

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

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

## ◆ TEST_F() [32/32]

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

Definition at line 1082 of file FlutterEngineTest.mm.

1082 {
1083 id<NSApplicationDelegate> previousDelegate = [[NSApplication sharedApplication] delegate];
1084 FakeLifecycleProvider* fakeAppDelegate = [[FakeLifecycleProvider alloc] init];
1085 [NSApplication sharedApplication].delegate = fakeAppDelegate;
1086
1087 FakeAppDelegatePlugin* plugin = [[FakeAppDelegatePlugin alloc] init];
1088
1089 @autoreleasepool {
1090 FlutterEngine* engine = [[FlutterEngine alloc] initWithName:@"test" project:nil];
1091
1092 [[engine registrarForPlugin:@"TestPlugin"] addApplicationDelegate:plugin];
1093 EXPECT_TRUE([fakeAppDelegate hasDelegate:plugin]);
1094 }
1095
1096 // When the engine is released, it should unregister any plugins it had
1097 // registered on its behalf.
1098 EXPECT_FALSE([fakeAppDelegate hasDelegate:plugin]);
1099
1100 [NSApplication sharedApplication].delegate = previousDelegate;
1101 }
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:15
+[FlutterSurface fromFlutterMetalTexture:]
nullable FlutterSurface * fromFlutterMetalTexture:(nonnull const FlutterMetalTexture *texture)
FlutterViewControllerTestObjC
Definition: FlutterViewControllerTest.mm:58
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:22
+[FlutterMethodCall methodCallWithMethodName:arguments:]
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
FlutterBasicMessageChannel
Definition: FlutterChannels.h:39
-[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:222
-[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:47
-[FlutterViewController onAccessibilityStatusChanged:]
void onAccessibilityStatusChanged:(BOOL enabled)
TestKeyEvent
Definition: FlutterEmbedderKeyResponderTest.mm:14
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
FlutterTextFieldMock
Definition: FlutterTextInputPluginTest.mm:20
FlutterEngine::viewController
FlutterViewController * viewController
Definition: FlutterEngine.h:86
TestFlutterPlatformViewFactory
Definition: TestFlutterPlatformView.h:16
TestPlatformViewFactory
Definition: FlutterEngineTest.mm:46
FakeLifecycleProvider
Definition: FlutterEngineTest.mm:68
-[FlutterAppLifecycleProvider-p addApplicationLifecycleDelegate:]
void addApplicationLifecycleDelegate:(nonnull NSObject< FlutterAppLifecycleDelegate > *delegate)
FakeAppDelegatePlugin
Definition: FlutterEngineTest.mm:110
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)
FlutterExternalTexture
Definition: FlutterExternalTexture.h:15
FlutterTextFieldMock::lastUpdatedSelection
NSRange lastUpdatedSelection
Definition: FlutterTextInputPluginTest.mm:23
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:24
FlutterThreadSynchronizer
Definition: FlutterThreadSynchronizer.h:13
AppDelegateNoopFlutterAppLifecycleDelegate
Definition: FlutterAppDelegateTest.mm:10
FlutterSurfacePresentInfo::surface
FlutterSurface * surface
Definition: FlutterSurfaceManager.h:17
AppDelegateTestFlutterAppLifecycleDelegate
Definition: FlutterAppDelegateTest.mm:17
PlainAppDelegate
Definition: FlutterEngineTest.mm:56
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:29
-[FlutterAppLifecycleDelegate-p handleDidFinishLaunching:]
void handleDidFinishLaunching:(NSNotification *notification)
FlutterResult
void(^ FlutterResult)(id _Nullable result)
Definition: FlutterChannels.h:196
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
FlutterChannelKeyResponder
Definition: FlutterChannelKeyResponder.h:17
+[FlutterMethodChannel methodChannelWithName:binaryMessenger:codec:]
instancetype methodChannelWithName:binaryMessenger:codec:(NSString *name,[binaryMessenger] NSObject< FlutterBinaryMessenger > *messenger,[codec] NSObject< FlutterMethodCodec > *codec)
FlutterReply
NS_ASSUME_NONNULL_BEGIN typedef void(^ FlutterReply)(id _Nullable reply)
FlutterSurfacePresentInfo
Definition: FlutterSurfaceManager.h:15
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:298
TestView::presentedFrameSize
CGSize presentedFrameSize
Definition: FlutterSurfaceManagerTest.mm:17
flutter::AppLifecycleState::kResumed
@ kResumed
FlutterView
Definition: FlutterView.h:39
flutter::AppLifecycleState::kDetached
@ kDetached
flutter::testing::CreateSurfaceManager
static FlutterSurfaceManager * CreateSurfaceManager(TestView *testView)
Definition: FlutterSurfaceManagerTest.mm:42
-[FlutterAppLifecycleDelegate-p handleWillBecomeActive:]
void handleWillBecomeActive:(NSNotification *notification)
FlutterJSONMethodCodec
Definition: FlutterCodecs.h:453
-[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
-[FlutterEngine shutDownEngine]
void shutDownEngine()
Definition: FlutterEngine.mm:1016
FlutterDartProject
Definition: FlutterDartProject.mm:24
FlutterKeyboardManagerUnittestsObjC
Definition: FlutterKeyboardManagerTest.mm:418
FlutterEngineTerminationHandler::acceptingRequests
BOOL acceptingRequests
Definition: FlutterEngine_Internal.h:58
FlutterBinaryMessenger-p
Definition: FlutterBinaryMessenger.h:48
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:24
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:51
-[FlutterAppLifecycleDelegate-p handleDidResignActive:]
void handleDidResignActive:(NSNotification *notification)
flutter::AppLifecycleState::kPaused
@ kPaused
TestFlutterAppLifecycleDelegate
Definition: FlutterAppLifecycleDelegateTest.mm:10