Flutter macOS Embedder
flutter::testing Namespace Reference

Classes

class  FlutterEngineTest
 
class  MockFlutterEngineTest
 
class  FlutterMenuPluginTest
 
class  FlutterWindowControllerTest
 
class  FlutterWindowControllerRetainTest
 

Typedefs

using FlutterChannelKeyResponderTest = AutoreleasePoolTest
 
using FlutterEmbedderExternalTextureTest = AutoreleasePoolTest
 
using FlutterViewControllerTest = AutoreleasePoolTest
 
using FlutterViewControllerMockEngineTest = MockFlutterEngineTest
 

Functions

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

Variables

FlutterSemanticsFlags kEmptyFlags = FlutterSemanticsFlags{}
 

Typedef Documentation

◆ FlutterChannelKeyResponderTest

using flutter::testing::FlutterChannelKeyResponderTest = typedef AutoreleasePoolTest

Definition at line 73 of file FlutterChannelKeyResponderTest.mm.

◆ FlutterEmbedderExternalTextureTest

using flutter::testing::FlutterEmbedderExternalTextureTest = typedef AutoreleasePoolTest

Definition at line 94 of file FlutterEmbedderExternalTextureTest.mm.

◆ FlutterViewControllerMockEngineTest

◆ FlutterViewControllerTest

using flutter::testing::FlutterViewControllerTest = typedef AutoreleasePoolTest

Definition at line 184 of file FlutterViewControllerTest.mm.

Function Documentation

◆ CreateMockFlutterEngine()

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

Definition at line 76 of file FlutterEngineTestUtils.mm.

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

References FlutterPasteboard::setString:forType:.

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

◆ CreateMockViewController()

id flutter::testing::CreateMockViewController ( )

Definition at line 9 of file FlutterViewControllerTestUtils.mm.

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

Referenced by TEST_F().

◆ CreatePresentInfo()

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

Definition at line 53 of file FlutterSurfaceManagerTest.mm.

57  {}) {
59  res.surface = surface;
60  res.offset = offset;
61  res.zIndex = index;
62  res.paintRegion = paintRegion;
63  return res;
64 }
std::vector< FlutterRect > paintRegion

◆ CreateSemanticsNode()

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

Definition at line 20 of file accessibility_bridge_unittests.cc.

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

References kEmptyFlags.

Referenced by TEST().

◆ CreateSurfaceManager()

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

Definition at line 43 of file FlutterSurfaceManagerTest.mm.

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

Referenced by TEST().

◆ operator==()

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

Definition at line 200 of file FlutterSurfaceManagerTest.mm.

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

◆ TEST() [1/122]

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

Definition at line 79 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [2/122]

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

Definition at line 116 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [3/122]

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

Definition at line 566 of file accessibility_bridge_unittests.cc.

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

◆ TEST() [4/122]

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

Definition at line 45 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [5/122]

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

Definition at line 167 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [6/122]

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

Definition at line 215 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [7/122]

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

Definition at line 392 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [8/122]

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

Definition at line 329 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [9/122]

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

Definition at line 486 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [10/122]

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

Definition at line 310 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [11/122]

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

Definition at line 250 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [12/122]

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

Definition at line 576 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [13/122]

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

Definition at line 286 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [14/122]

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

Definition at line 269 of file accessibility_bridge_unittests.cc.

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

References CreateSemanticsNode().

◆ TEST() [15/122]

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

Definition at line 32 of file FlutterAppDelegateTest.mm.

32  {
33  FlutterAppDelegate* appDelegate = [[FlutterAppDelegate alloc] init];
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 }
void addApplicationLifecycleDelegate:(nonnull NSObject< FlutterAppLifecycleDelegate > *delegate)

References <FlutterAppLifecycleProvider>::addApplicationLifecycleDelegate:.

◆ TEST() [16/122]

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

Definition at line 57 of file FlutterAppDelegateTest.mm.

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

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

◆ TEST() [17/122]

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

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

Definition at line 223 of file FlutterAppLifecycleDelegateTest.mm.

223  {
224  __weak FlutterAppLifecycleRegistrar* weakRegistrar;
225  __weak TestFlutterAppLifecycleDelegate* weakDelegate;
226  @autoreleasepool {
228  weakRegistrar = registrar;
230  weakDelegate = delegate;
231  [registrar addDelegate:delegate];
232  }
233  EXPECT_EQ(weakRegistrar, nil);
234  EXPECT_EQ(weakDelegate, nil);
235 }
void addDelegate:(NSObject< FlutterAppLifecycleDelegate > *delegate)

References FlutterAppLifecycleRegistrar::addDelegate:.

◆ TEST() [19/122]

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 }
void handleDidBecomeActive:(NSNotification *notification)

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

◆ TEST() [20/122]

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

Definition at line 209 of file FlutterAppLifecycleDelegateTest.mm.

209  {
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 }
void handleDidChangeOcclusionState:(NSNotification *notification)

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

◆ TEST() [21/122]

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

Definition at line 197 of file FlutterAppLifecycleDelegateTest.mm.

197  {
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 }
void handleDidChangeScreenParameters:(NSNotification *notification)

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

◆ TEST() [22/122]

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

Definition at line 87 of file FlutterAppLifecycleDelegateTest.mm.

87  {
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 }
void handleDidFinishLaunching:(NSNotification *notification)

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

◆ TEST() [23/122]

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

Definition at line 175 of file FlutterAppLifecycleDelegateTest.mm.

175  {
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 }
void handleDidHide:(NSNotification *notification)

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

◆ TEST() [24/122]

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

Definition at line 131 of file FlutterAppLifecycleDelegateTest.mm.

131  {
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 }
void handleDidResignActive:(NSNotification *notification)

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

◆ TEST() [25/122]

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

Definition at line 186 of file FlutterAppLifecycleDelegateTest.mm.

186  {
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 }
void handleDidUnhide:(NSNotification *notification)

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

◆ TEST() [26/122]

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

Definition at line 98 of file FlutterAppLifecycleDelegateTest.mm.

98  {
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 }
void handleWillBecomeActive:(NSNotification *notification)

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

◆ TEST() [27/122]

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

Definition at line 76 of file FlutterAppLifecycleDelegateTest.mm.

76  {
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 }
void handleWillFinishLaunching:(NSNotification *notification)

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

◆ TEST() [28/122]

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

Definition at line 153 of file FlutterAppLifecycleDelegateTest.mm.

153  {
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 }
void handleWillHide:(NSNotification *notification)

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

◆ TEST() [29/122]

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

Definition at line 120 of file FlutterAppLifecycleDelegateTest.mm.

120  {
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 }
void handleWillResignActive:(NSNotification *notification)

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

◆ TEST() [30/122]

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

Definition at line 142 of file FlutterAppLifecycleDelegateTest.mm.

142  {
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 }
void handleWillTerminate:(NSNotification *notification)

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

◆ TEST() [31/122]

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

Definition at line 164 of file FlutterAppLifecycleDelegateTest.mm.

164  {
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 }
void handleWillUnhide:(NSNotification *notification)

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

◆ TEST() [32/122]

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

Definition at line 118 of file FlutterEmbedderKeyResponderTest.mm.

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

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

◆ TEST() [33/122]

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

Definition at line 410 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

◆ TEST() [34/122]

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

Definition at line 1100 of file FlutterEmbedderKeyResponderTest.mm.

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

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

◆ TEST() [35/122]

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

Definition at line 720 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

◆ TEST() [36/122]

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

Definition at line 379 of file FlutterEmbedderKeyResponderTest.mm.

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

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

◆ TEST() [37/122]

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

Definition at line 274 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

◆ TEST() [38/122]

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

Definition at line 200 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

◆ TEST() [39/122]

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

Definition at line 564 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

◆ TEST() [40/122]

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

Definition at line 1183 of file FlutterEmbedderKeyResponderTest.mm.

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

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

◆ TEST() [41/122]

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

Definition at line 1218 of file FlutterEmbedderKeyResponderTest.mm.

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

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

◆ TEST() [42/122]

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

Definition at line 317 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

◆ TEST() [43/122]

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

Definition at line 806 of file FlutterEmbedderKeyResponderTest.mm.

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

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

◆ TEST() [44/122]

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

Definition at line 1022 of file FlutterEmbedderKeyResponderTest.mm.

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

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

◆ TEST() [45/122]

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

Definition at line 448 of file FlutterEmbedderKeyResponderTest.mm.

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

References <FlutterKeyPrimaryResponder>::handleEvent:callback:.

◆ TEST() [46/122]

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

Definition at line 469 of file FlutterKeyboardManagerTest.mm.

469  {
470  ASSERT_TRUE([[FlutterKeyboardManagerUnittestsObjC alloc] correctLogicalKeyForLayouts]);
471 }

◆ TEST() [47/122]

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

Definition at line 445 of file FlutterKeyboardManagerTest.mm.

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

◆ TEST() [48/122]

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

Definition at line 453 of file FlutterKeyboardManagerTest.mm.

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

◆ TEST() [49/122]

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

Definition at line 457 of file FlutterKeyboardManagerTest.mm.

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

◆ TEST() [50/122]

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

Definition at line 461 of file FlutterKeyboardManagerTest.mm.

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

◆ TEST() [51/122]

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

Definition at line 465 of file FlutterKeyboardManagerTest.mm.

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

◆ TEST() [52/122]

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

Definition at line 473 of file FlutterKeyboardManagerTest.mm.

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

◆ TEST() [53/122]

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

Definition at line 449 of file FlutterKeyboardManagerTest.mm.

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

◆ TEST() [54/122]

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

Definition at line 441 of file FlutterKeyboardManagerTest.mm.

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

◆ TEST() [55/122]

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

Definition at line 32 of file FlutterPlatformNodeDelegateMacTest.mm.

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

References FlutterViewController::engine.

◆ TEST() [56/122]

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

Definition at line 153 of file FlutterPlatformNodeDelegateMacTest.mm.

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

References FlutterViewController::engine.

◆ TEST() [57/122]

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

Definition at line 315 of file FlutterPlatformNodeDelegateMacTest.mm.

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

References FlutterViewController::engine.

◆ TEST() [58/122]

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

Definition at line 70 of file FlutterPlatformNodeDelegateMacTest.mm.

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

References FlutterViewController::engine.

◆ TEST() [59/122]

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

Definition at line 113 of file FlutterPlatformNodeDelegateMacTest.mm.

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

References FlutterViewController::engine.

◆ TEST() [60/122]

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

Definition at line 230 of file FlutterPlatformNodeDelegateMacTest.mm.

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

References FlutterViewController::engine.

◆ TEST() [61/122]

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

Definition at line 121 of file flutter_platform_node_delegate_unittests.cc.

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

◆ TEST() [62/122]

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

Definition at line 172 of file flutter_platform_node_delegate_unittests.cc.

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

◆ TEST() [63/122]

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

Definition at line 91 of file flutter_platform_node_delegate_unittests.cc.

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

◆ TEST() [64/122]

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

Definition at line 300 of file flutter_platform_node_delegate_unittests.cc.

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

◆ TEST() [65/122]

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

Definition at line 43 of file flutter_platform_node_delegate_unittests.cc.

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

◆ TEST() [66/122]

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

Definition at line 223 of file flutter_platform_node_delegate_unittests.cc.

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

◆ TEST() [67/122]

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

Definition at line 15 of file flutter_platform_node_delegate_unittests.cc.

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

◆ TEST() [68/122]

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

Definition at line 275 of file flutter_platform_node_delegate_unittests.cc.

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

◆ TEST() [69/122]

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

Definition at line 218 of file FlutterPlatformViewControllerTest.mm.

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

◆ TEST() [70/122]

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

Definition at line 254 of file FlutterPlatformViewControllerTest.mm.

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

◆ TEST() [71/122]

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

Definition at line 101 of file FlutterPlatformViewControllerTest.mm.

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

◆ TEST() [72/122]

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

Definition at line 14 of file FlutterPlatformViewControllerTest.mm.

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

◆ TEST() [73/122]

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

Definition at line 198 of file FlutterPlatformViewControllerTest.mm.

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

◆ TEST() [74/122]

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

Definition at line 38 of file FlutterPlatformViewControllerTest.mm.

38  {
39  // Use id so we can access handleMethodCall method.
40  id platformViewController = [[FlutterPlatformViewController alloc] init];
41 
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 }
id args
Arguments passed via the params value in the create method call.

References TestFlutterPlatformView::args.

◆ TEST() [75/122]

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

Definition at line 276 of file FlutterPlatformViewControllerTest.mm.

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

◆ TEST() [76/122]

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

Definition at line 312 of file FlutterPlatformViewControllerTest.mm.

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

◆ TEST() [77/122]

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

Definition at line 144 of file FlutterPlatformViewControllerTest.mm.

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

◆ TEST() [78/122]

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

Definition at line 98 of file FlutterSurfaceManagerTest.mm.

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

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

◆ TEST() [79/122]

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

Definition at line 173 of file FlutterSurfaceManagerTest.mm.

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

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

◆ TEST() [80/122]

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

Definition at line 204 of file FlutterSurfaceManagerTest.mm.

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

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

◆ TEST() [81/122]

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

Definition at line 66 of file FlutterSurfaceManagerTest.mm.

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

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

◆ TEST() [82/122]

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

Definition at line 134 of file FlutterSurfaceManagerTest.mm.

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

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

◆ TEST() [83/122]

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

Definition at line 79 of file FlutterSurfaceManagerTest.mm.

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

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

◆ TEST() [84/122]

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

Definition at line 2314 of file FlutterTextInputPluginTest.mm.

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

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

◆ TEST() [85/122]

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

Definition at line 2248 of file FlutterTextInputPluginTest.mm.

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

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

◆ TEST() [86/122]

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

Definition at line 2390 of file FlutterTextInputPluginTest.mm.

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

References FlutterMethodCall::methodCallWithMethodName:arguments:.

◆ TEST() [87/122]

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

Definition at line 2172 of file FlutterTextInputPluginTest.mm.

2172  {
2173  ASSERT_TRUE([[FlutterInputPluginTestObjc alloc] handleArrowKeyWhenImePopoverIsActive]);
2174 }

◆ TEST() [88/122]

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

Definition at line 2434 of file FlutterTextInputPluginTest.mm.

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

References CreateMockFlutterEngine().

◆ TEST() [89/122]

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

Definition at line 2526 of file FlutterTextInputPluginTest.mm.

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

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

◆ TEST() [90/122]

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

Definition at line 2488 of file FlutterTextInputPluginTest.mm.

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

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

◆ TEST() [91/122]

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

Definition at line 2483 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [92/122]

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

Definition at line 2348 of file FlutterTextInputPluginTest.mm.

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

References FlutterMethodCall::methodCallWithMethodName:arguments:.

◆ TEST() [93/122]

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

Definition at line 2196 of file FlutterTextInputPluginTest.mm.

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

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

◆ TEST() [94/122]

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

Definition at line 2130 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [95/122]

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

Definition at line 2110 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [96/122]

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

Definition at line 2122 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [97/122]

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

Definition at line 2126 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [98/122]

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

Definition at line 2114 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [99/122]

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

Definition at line 2118 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [100/122]

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

Definition at line 2106 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [101/122]

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

Definition at line 2102 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [102/122]

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

Definition at line 2156 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [103/122]

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

Definition at line 2160 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [104/122]

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

Definition at line 2090 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [105/122]

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

Definition at line 2135 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [106/122]

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

Definition at line 2139 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [107/122]

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

Definition at line 2143 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [108/122]

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

Definition at line 2188 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [109/122]

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

Definition at line 2164 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [110/122]

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

Definition at line 2152 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [111/122]

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

Definition at line 2168 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [112/122]

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

Definition at line 2180 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [113/122]

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

Definition at line 2184 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [114/122]

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

Definition at line 2192 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [115/122]

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

Definition at line 2148 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [116/122]

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

Definition at line 2098 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [117/122]

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

Definition at line 2094 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [118/122]

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

Definition at line 2176 of file FlutterTextInputPluginTest.mm.

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

◆ TEST() [119/122]

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

Definition at line 2455 of file FlutterTextInputPluginTest.mm.

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

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

◆ TEST() [120/122]

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

Definition at line 27 of file FlutterTextInputSemanticsObjectTest.mm.

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

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

◆ TEST() [121/122]

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

Definition at line 19 of file FlutterViewEngineProviderTest.mm.

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

References CreateMockFlutterEngine().

◆ TEST() [122/122]

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

Definition at line 20 of file KeyCodeMapTest.mm.

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

References flutter::kLayoutGoals.

◆ TEST_F() [1/83]

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

Definition at line 221 of file AccessibilityBridgeMacTest.mm.

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

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

◆ TEST_F() [2/83]

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

Definition at line 270 of file AccessibilityBridgeMacTest.mm.

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

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

◆ TEST_F() [3/83]

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

Definition at line 150 of file AccessibilityBridgeMacTest.mm.

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

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

◆ TEST_F() [4/83]

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

Definition at line 90 of file AccessibilityBridgeMacTest.mm.

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

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

◆ TEST_F() [5/83]

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

Definition at line 75 of file FlutterChannelKeyResponderTest.mm.

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

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

◆ TEST_F() [6/83]

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

Definition at line 228 of file FlutterChannelKeyResponderTest.mm.

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

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

◆ TEST_F() [7/83]

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

Definition at line 252 of file FlutterChannelKeyResponderTest.mm.

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

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

◆ TEST_F() [8/83]

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

Definition at line 154 of file FlutterEmbedderExternalTextureTest.mm.

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

References FlutterExternalTexture::populateTexture:, and texture_id.

◆ TEST_F() [9/83]

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

Definition at line 413 of file FlutterEmbedderExternalTextureTest.mm.

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

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

◆ TEST_F() [10/83]

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

Definition at line 206 of file FlutterEmbedderExternalTextureTest.mm.

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

References FlutterExternalTexture::populateTexture:, and texture_id.

◆ TEST_F() [11/83]

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

Definition at line 260 of file FlutterEmbedderExternalTextureTest.mm.

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

References FlutterExternalTexture::populateTexture:, and texture_id.

◆ TEST_F() [12/83]

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

Definition at line 514 of file FlutterEmbedderExternalTextureTest.mm.

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

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

◆ TEST_F() [13/83]

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

Definition at line 464 of file FlutterEmbedderExternalTextureTest.mm.

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

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

◆ TEST_F() [14/83]

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

Definition at line 314 of file FlutterEmbedderExternalTextureTest.mm.

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

References texture_id.

◆ TEST_F() [15/83]

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

Definition at line 564 of file FlutterEmbedderExternalTextureTest.mm.

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

References CreateImpellerContext(), and texture_id.

◆ TEST_F() [16/83]

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

Definition at line 96 of file FlutterEmbedderExternalTextureTest.mm.

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

References texture_id.

◆ TEST_F() [17/83]

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

Definition at line 360 of file FlutterEmbedderExternalTextureTest.mm.

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

References CreateImpellerContext(), and texture_id.

◆ TEST_F() [18/83]

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

Definition at line 905 of file FlutterEngineTest.mm.

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

◆ TEST_F() [19/83]

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

Definition at line 142 of file FlutterEngineTest.mm.

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

◆ TEST_F() [20/83]

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

Definition at line 207 of file FlutterEngineTest.mm.

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

◆ TEST_F() [21/83]

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

Definition at line 294 of file FlutterEngineTest.mm.

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

References user_data, and FlutterEngine::viewController.

◆ TEST_F() [22/83]

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

Definition at line 394 of file FlutterEngineTest.mm.

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

References user_data, and FlutterEngine::viewController.

◆ TEST_F() [23/83]

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

Definition at line 519 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [24/83]

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

Definition at line 565 of file FlutterEngineTest.mm.

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

References FlutterEngine::shutDownEngine, and user_data.

◆ TEST_F() [25/83]

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

Definition at line 614 of file FlutterEngineTest.mm.

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

References FlutterEngine::shutDownEngine, and user_data.

◆ TEST_F() [26/83]

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

Definition at line 231 of file FlutterEngineTest.mm.

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

References FlutterEngine::viewController.

◆ TEST_F() [27/83]

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

Definition at line 262 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [28/83]

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

Definition at line 1317 of file FlutterEngineTest.mm.

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

References FlutterEngine::shutDownEngine.

◆ TEST_F() [29/83]

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

Definition at line 653 of file FlutterEngineTest.mm.

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

References FlutterEngine::binaryMessenger.

◆ TEST_F() [30/83]

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

Definition at line 677 of file FlutterEngineTest.mm.

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

◆ TEST_F() [31/83]

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

Definition at line 1230 of file FlutterEngineTest.mm.

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

References CreateMockFlutterEngine().

◆ TEST_F() [32/83]

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

Definition at line 1136 of file FlutterEngineTest.mm.

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

References CreateMockFlutterEngine().

◆ TEST_F() [33/83]

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

Definition at line 1159 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [34/83]

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

Definition at line 1042 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [35/83]

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

Definition at line 148 of file FlutterEngineTest.mm.

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

◆ TEST_F() [36/83]

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

Definition at line 827 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [37/83]

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

Definition at line 845 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [38/83]

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

Definition at line 1120 of file FlutterEngineTest.mm.

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

References CreateMockFlutterEngine().

◆ TEST_F() [39/83]

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

Definition at line 946 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [40/83]

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

Definition at line 978 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [41/83]

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

Definition at line 770 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [42/83]

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

Definition at line 188 of file FlutterEngineTest.mm.

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

◆ TEST_F() [43/83]

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

Definition at line 504 of file FlutterEngineTest.mm.

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

◆ TEST_F() [44/83]

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

Definition at line 1287 of file FlutterEngineTest.mm.

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

◆ TEST_F() [45/83]

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

Definition at line 479 of file FlutterEngineTest.mm.

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

References FlutterEngine::viewController.

◆ TEST_F() [46/83]

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

Definition at line 699 of file FlutterEngineTest.mm.

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

◆ TEST_F() [47/83]

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

Definition at line 711 of file FlutterEngineTest.mm.

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

◆ TEST_F() [48/83]

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

Definition at line 728 of file FlutterEngineTest.mm.

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

◆ TEST_F() [49/83]

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

Definition at line 749 of file FlutterEngineTest.mm.

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

◆ TEST_F() [50/83]

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

Definition at line 1009 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [51/83]

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

Definition at line 1345 of file FlutterEngineTest.mm.

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

References CreateMockFlutterEngine().

◆ TEST_F() [52/83]

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

Definition at line 932 of file FlutterEngineTest.mm.

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

◆ TEST_F() [53/83]

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

Definition at line 863 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [54/83]

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

Definition at line 883 of file FlutterEngineTest.mm.

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

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

◆ TEST_F() [55/83]

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

Definition at line 1266 of file FlutterEngineTest.mm.

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

◆ TEST_F() [56/83]

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

Definition at line 171 of file FlutterEngineTest.mm.

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

◆ TEST_F() [57/83]

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

Definition at line 1245 of file FlutterEngineTest.mm.

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

◆ TEST_F() [58/83]

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

Definition at line 90 of file FlutterMenuPluginTest.mm.

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

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

◆ TEST_F() [59/83]

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

Definition at line 278 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [60/83]

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

Definition at line 289 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [61/83]

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

Definition at line 331 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [62/83]

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

Definition at line 295 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [63/83]

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

Definition at line 283 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [64/83]

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

Definition at line 272 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [65/83]

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

Definition at line 266 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [66/83]

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

Definition at line 261 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [67/83]

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

Definition at line 319 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [68/83]

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

Definition at line 307 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [69/83]

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

Definition at line 313 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [70/83]

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

Definition at line 301 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [71/83]

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

Definition at line 325 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [72/83]

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

Definition at line 251 of file FlutterViewControllerTest.mm.

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

References FlutterViewController::mouseTrackingMode.

◆ TEST_F() [73/83]

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

Definition at line 208 of file FlutterViewControllerTest.mm.

208  {
209  FlutterViewController* viewControllerMock = CreateMockViewController();
210  [viewControllerMock loadView];
211  EXPECT_EQ([viewControllerMock.flutterView acceptsFirstMouse:nil], YES);
212 }

References CreateMockViewController().

◆ TEST_F() [74/83]

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

Definition at line 187 of file FlutterViewControllerTest.mm.

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

References CreateMockViewController().

◆ TEST_F() [75/83]

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

Definition at line 214 of file FlutterViewControllerTest.mm.

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

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

◆ TEST_F() [76/83]

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

Definition at line 336 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [77/83]

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

Definition at line 340 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [78/83]

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

Definition at line 344 of file FlutterViewControllerTest.mm.

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

◆ TEST_F() [79/83]

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

Definition at line 83 of file FlutterWindowControllerTest.mm.

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

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

◆ TEST_F() [80/83]

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

Definition at line 58 of file FlutterWindowControllerTest.mm.

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

References FlutterWindowCreationRequest::has_size, and InternalFlutter_WindowController_CreateRegularWindow().

◆ TEST_F() [81/83]

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

Definition at line 126 of file FlutterWindowControllerTest.mm.

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

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

◆ TEST_F() [82/83]

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

Definition at line 147 of file FlutterWindowControllerTest.mm.

147  {
149  .has_size = true,
150  .size = {.width = 800, .height = 600},
151  .on_should_close = [] {},
152  .on_will_close = [] {},
153  .notify_listeners = [] {},
154  };
155 
156  FlutterEngine* engine = GetFlutterEngine();
157  int64_t engine_id = reinterpret_cast<int64_t>(engine);
158 
159  IsolateScope isolate_scope(isolate());
160  int64_t handle = InternalFlutter_WindowController_CreateRegularWindow(engine_id, &request);
161  FlutterViewController* viewController = [engine viewControllerForIdentifier:handle];
162 
163  void* window_handle = InternalFlutter_Window_GetHandle(engine_id, handle);
164  EXPECT_EQ(window_handle, (__bridge void*)viewController.view.window);
165 }
FLUTTER_DARWIN_EXPORT void * InternalFlutter_Window_GetHandle(int64_t engine_id, FlutterViewIdentifier view_id)

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

◆ TEST_F() [83/83]

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

Definition at line 167 of file FlutterWindowControllerTest.mm.

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

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

Variable Documentation

◆ kEmptyFlags

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

Definition at line 18 of file accessibility_bridge_unittests.cc.

Referenced by CreateSemanticsNode().