Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
FlutterMenuPluginTest.mm
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
7
20#include "gtest/gtest.h"
21
23@property(nonatomic, readonly) id<FlutterPlugin> plugin;
24@property(nonatomic, readonly) FlutterMethodChannel* channel;
25@end
26
27@implementation FakePluginRegistrar
28
29// Synthesize properties declared in FlutterPluginRegistrar protocol.
30@synthesize messenger;
31@synthesize textures;
32@synthesize view;
33
34- (void)addMethodCallDelegate:(nonnull id<FlutterPlugin>)delegate
35 channel:(nonnull FlutterMethodChannel*)channel {
36 _plugin = delegate;
38 [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
39 [delegate handleMethodCall:call result:result];
40 }];
41}
42
43- (void)addApplicationDelegate:(nonnull NSObject<FlutterAppLifecycleDelegate>*)delegate {
44}
45
46- (void)registerViewFactory:(nonnull NSObject<FlutterPlatformViewFactory>*)factory
47 withId:(nonnull NSString*)factoryId {
48}
49
50- (void)publish:(nonnull NSObject*)value {
51}
52
53- (nullable NSObject*)valuePublishedByPlugin:(nonnull NSString*)pluginKey {
54 return nil;
55}
56
57- (nonnull NSString*)lookupKeyForAsset:(nonnull NSString*)asset {
58 return @"";
59}
60
61- (nonnull NSString*)lookupKeyForAsset:(nonnull NSString*)asset
62 fromPackage:(nonnull NSString*)package {
63 return @"";
64}
65
66- (NSViewController*)viewController {
67 return nil;
68}
69@end
70
71namespace flutter::testing {
72
73// FlutterMenuPluginTest is an AutoreleasePoolTest that allocates an NSView.
74//
75// This supports the use of NSApplication features that rely on the assumption of a view, such as
76// when modifying the application menu bar, or even accessing the NSApplication.localizedName
77// property.
78//
79// See: https://github.com/flutter/flutter/issues/104748#issuecomment-1159336728
81 public:
84
85 private:
86 NSView* view_;
87};
88
89FlutterMenuPluginTest::FlutterMenuPluginTest() {
90 view_ = [[NSView alloc] initWithFrame:NSZeroRect];
91 view_.wantsLayer = YES;
92}
93
95 // Build a simulation of the default main menu.
96 NSMenu* mainMenu = [[NSMenu alloc] init];
97 NSMenuItem* appNameMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"APP_NAME", nil)
98 action:nil
99 keyEquivalent:@""];
100 NSMenu* submenu =
101 [[NSMenu alloc] initWithTitle:NSLocalizedString(@"Prexisting APP_NAME menu", nil)];
102 [submenu addItem:[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"About APP_NAME", nil)
103 action:nil
104 keyEquivalent:@""]];
105 appNameMenu.submenu = submenu;
106 [mainMenu addItem:appNameMenu];
107 [NSApp setMainMenu:mainMenu];
108
109 FakePluginRegistrar* registrar = [[FakePluginRegistrar alloc] init];
111 FlutterMenuPlugin* plugin = [registrar plugin];
112
113 NSDictionary* testMenus = @{
114 @"0" : @[
115 @{
116 @"id" : [NSNumber numberWithInt:1],
117 @"label" : @"APP_NAME",
118 @"tooltip" : @"APP_NAME",
119 @"enabled" : @(YES),
120 @"children" : @[
121 @{
122 @"id" : [NSNumber numberWithInt:3],
123 @"platformProvidedMenu" : @(static_cast<int>(flutter::PlatformProvidedMenu::kQuit)),
124 @"enabled" : @(YES),
125 },
126 @{
127 @"id" : [NSNumber numberWithInt:2],
128 @"label" : @"APP_NAME Info",
129 @"tooltip" : @"APP_NAME Info Tooltip",
130 @"enabled" : @(YES),
131 @"shortcutTrigger" : [NSNumber numberWithUnsignedLongLong:0x61],
132 @"shortcutModifiers" : [NSNumber numberWithUnsignedInt:0],
133 },
134 ],
135 },
136 @{
137 @"id" : [NSNumber numberWithInt:4],
138 @"label" : @"Help for APP_NAME",
139 @"enabled" : @(YES),
140 @"children" : @[
141 @{
142 @"id" : [NSNumber numberWithInt:5],
143 @"label" : @"Help me!",
144 @"tooltip" : @"Help me tooltip!",
145 @"enabled" : @(YES),
146 },
147 @{
148 @"id" : [NSNumber numberWithInt:6],
149 @"label" : @"",
150 @"enabled" : @(NO),
151 @"isDivider" : @(YES),
152 },
153 @{
154 @"id" : [NSNumber numberWithInt:7],
155 @"label" : @"Search help",
156 @"enabled" : @(NO),
157 },
158 ],
159 },
160 ],
161 };
162
163 __block id available = @NO;
164 [plugin handleMethodCall:[FlutterMethodCall methodCallWithMethodName:@"Menu.isPluginAvailable"
165 arguments:nil]
166 result:^(id _Nullable result) {
167 available = result;
168 }];
169
170 EXPECT_TRUE(available);
171
173 arguments:testMenus]
174 result:^(id _Nullable result){
175 }];
176
177 EXPECT_EQ([NSApp.mainMenu numberOfItems], 2);
178 NSMenuItem* firstMenu = [NSApp.mainMenu itemAtIndex:0];
179 EXPECT_TRUE([[firstMenu title] isEqualToString:@"flutter_desktop_darwin_unittests"]);
180 EXPECT_TRUE([[firstMenu toolTip] isEqualToString:@"flutter_desktop_darwin_unittests"]);
181 EXPECT_EQ([firstMenu tag], 1);
182 EXPECT_TRUE([firstMenu isEnabled]);
183 EXPECT_FALSE([firstMenu isHidden]);
184 EXPECT_TRUE([[firstMenu keyEquivalent] isEqualToString:@"\0"]);
185
186 EXPECT_EQ([[firstMenu submenu] numberOfItems], 1);
187 NSMenuItem* firstItem = [[firstMenu submenu] itemAtIndex:0];
188 EXPECT_TRUE([[firstItem title] isEqualToString:@"flutter_desktop_darwin_unittests Info"]);
189 EXPECT_TRUE(
190 [[firstItem toolTip] isEqualToString:@"flutter_desktop_darwin_unittests Info Tooltip"]);
191 EXPECT_TRUE([[firstItem keyEquivalent] isEqualToString:@"a"]);
192 EXPECT_TRUE([firstItem isEnabled]);
193 EXPECT_FALSE([firstItem isHidden]);
194 EXPECT_TRUE(
195 [NSStringFromSelector([firstItem action]) isEqualToString:@"flutterMenuItemSelected:"]);
196 EXPECT_EQ([firstItem tag], 2);
197
198 NSMenuItem* secondMenu = [NSApp.mainMenu itemAtIndex:1];
199 EXPECT_TRUE([[secondMenu title] isEqualToString:@"Help for flutter_desktop_darwin_unittests"]);
200 EXPECT_EQ([secondMenu toolTip], nil);
201 EXPECT_EQ([secondMenu tag], 4);
202 EXPECT_TRUE([secondMenu isEnabled]);
203 EXPECT_FALSE([secondMenu isHidden]);
204
205 EXPECT_EQ([[secondMenu submenu] numberOfItems], 3);
206 NSMenuItem* secondMenuFirst = [[secondMenu submenu] itemAtIndex:0];
207 EXPECT_TRUE([[secondMenuFirst title] isEqualToString:@"Help me!"]);
208 EXPECT_TRUE([[secondMenuFirst toolTip] isEqualToString:@"Help me tooltip!"]);
209 EXPECT_TRUE([secondMenuFirst isEnabled]);
210 EXPECT_FALSE([secondMenuFirst isHidden]);
211 EXPECT_TRUE(
212 [NSStringFromSelector([secondMenuFirst action]) isEqualToString:@"flutterMenuItemSelected:"]);
213 EXPECT_EQ([secondMenuFirst tag], 5);
214
215 NSMenuItem* secondMenuDivider = [[secondMenu submenu] itemAtIndex:1];
216 EXPECT_TRUE([[secondMenuDivider title] isEqualToString:@""]);
217 EXPECT_EQ([secondMenuDivider toolTip], nil);
218 EXPECT_TRUE([[secondMenuDivider keyEquivalent] isEqualToString:@""]);
219 EXPECT_FALSE([secondMenuDivider isEnabled]);
220 EXPECT_FALSE([secondMenuDivider isHidden]);
221 EXPECT_EQ([secondMenuDivider action], nil);
222 EXPECT_EQ([secondMenuDivider tag], 0);
223
224 NSMenuItem* secondMenuLast = [[secondMenu submenu] itemAtIndex:2];
225 EXPECT_TRUE([[secondMenuLast title] isEqualToString:@"Search help"]);
226 EXPECT_EQ([secondMenuLast toolTip], nil);
227 EXPECT_FALSE([secondMenuLast isEnabled]);
228 EXPECT_FALSE([secondMenuLast isHidden]);
229 EXPECT_TRUE(
230 [NSStringFromSelector([secondMenuLast action]) isEqualToString:@"flutterMenuItemSelected:"]);
231 EXPECT_EQ([secondMenuLast tag], 7);
232}
233
234} // namespace flutter::testing
FlutterTextInputPlugin * _plugin
FlutterMethodChannel * _channel
HWND(* FlutterPlatformViewFactory)(const FlutterPlatformViewCreationParameters *)
FlutterMethodChannel * channel
id< FlutterPlugin > plugin
void registerWithRegistrar:(nonnull id< FlutterPluginRegistrar > registrar)
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
void handleMethodCall:result:(FlutterMethodCall *call,[result] FlutterResult result)
UIViewController * viewController
id< FlutterBinaryMessenger > messenger
id< FlutterTextureRegistry > textures