Flutter macOS Embedder
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 FlutterSurfaceManagerCreateSurfaceManager (TestView *testView)
 
static FlutterSurfacePresentInfoCreatePresentInfo (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  {}) {
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];
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];
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];
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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  {
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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.
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) {
1005  }));
1006  OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kResumed])
1007  .andDo((^(NSInvocation* invocation) {
1009  }));
1010  OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kInactive])
1011  .andDo((^(NSInvocation* invocation) {
1013  }));
1014  OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kHidden])
1015  .andDo((^(NSInvocation* invocation) {
1017  }));
1018  OCMStub([engineMock setApplicationState:flutter::AppLifecycleState::kPaused])
1019  .andDo((^(NSInvocation* invocation) {
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.
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 =
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 =
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();
763  initWithName:@"foo"
764  binaryMessenger:engine.binaryMessenger
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();
783  initWithName:@"foo"
784  binaryMessenger:engine.binaryMessenger
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
FlutterMenuPluginTestObjc
Definition: FlutterMenuPluginTest.mm:21
-[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