diff --git a/shell/platform/darwin/macos/framework/Source/FlutterMenuPluginTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterMenuPluginTest.mm index 915df002c3d12..3a13312eb8532 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterMenuPluginTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterMenuPluginTest.mm @@ -2,34 +2,86 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPlugin.h" +#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPlugin_Internal.h" + +#import "flutter/shell/platform/common/platform_provided_menu.h" +#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h" #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterPluginMacOS.h" #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterPluginRegistrarMacOS.h" #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h" -#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPlugin.h" -#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMenuPlugin_Internal.h" +#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObject.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h" - -#include "flutter/shell/platform/common/platform_provided_menu.h" +#include "flutter/testing/autoreleasepool_test.h" +#include "flutter/testing/testing.h" #include "gtest/gtest.h" -#import -#import "flutter/testing/testing.h" +@interface FakePluginRegistrar : NSObject +@property(nonatomic, readonly) id plugin; +@property(nonatomic, readonly) FlutterMethodChannel* channel; +@end + +@implementation FakePluginRegistrar +@synthesize messenger; +@synthesize textures; +@synthesize view; + +- (void)addMethodCallDelegate:(nonnull id)delegate + channel:(nonnull FlutterMethodChannel*)channel { + _plugin = delegate; + _channel = channel; + [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + [delegate handleMethodCall:call result:result]; + }]; +} + +- (void)addApplicationDelegate:(nonnull NSObject*)delegate { +} + +- (void)registerViewFactory:(nonnull NSObject*)factory + withId:(nonnull NSString*)factoryId { +} -@interface FlutterMenuPluginTestObjc : NSObject -- (bool)testSetMenu; +- (void)publish:(nonnull NSObject*)value { +} + +- (nonnull NSString*)lookupKeyForAsset:(nonnull NSString*)asset { + return @""; +} + +- (nonnull NSString*)lookupKeyForAsset:(nonnull NSString*)asset + fromPackage:(nonnull NSString*)package { + return @""; +} @end -@implementation FlutterMenuPluginTestObjc +namespace flutter::testing { -- (bool)testSetMenu { - // Workaround to deflake the test. - // See: https://github.com/flutter/flutter/issues/104748#issuecomment-1159336728 - NSView* view = [[NSView alloc] initWithFrame:NSZeroRect]; - view.wantsLayer = YES; +// FlutterMenuPluginTest is an AutoreleasePoolTest that allocates an NSView. +// +// This supports the use of NSApplication features that rely on the assumption of a view, such as +// when modifying the application menu bar, or even accessing the NSApplication.localizedName +// property. +// +// See: https://github.com/flutter/flutter/issues/104748#issuecomment-1159336728 +class FlutterMenuPluginTest : public AutoreleasePoolTest { + public: + FlutterMenuPluginTest(); + ~FlutterMenuPluginTest() = default; + + private: + NSView* view_; +}; + +FlutterMenuPluginTest::FlutterMenuPluginTest() { + view_ = [[NSView alloc] initWithFrame:NSZeroRect]; + view_.wantsLayer = YES; +} +TEST_F(FlutterMenuPluginTest, TestSetMenu) { // Build a simulation of the default main menu. NSMenu* mainMenu = [[NSMenu alloc] init]; NSMenuItem* appNameMenu = [[NSMenuItem alloc] initWithTitle:@"APP_NAME" @@ -43,26 +95,9 @@ - (bool)testSetMenu { [mainMenu addItem:appNameMenu]; [NSApp setMainMenu:mainMenu]; - id pluginRegistrarMock = - OCMProtocolMock(@protocol(FlutterPluginRegistrar)); - __block FlutterMethodChannel* pluginChannel; - __block FlutterMenuPlugin* plugin; - id binaryMessengerMock = OCMProtocolMock(@protocol(FlutterBinaryMessenger)); - OCMStub([pluginRegistrarMock messenger]).andReturn(binaryMessengerMock); - OCMStub( // NOLINT(google-objc-avoid-throwing-exception) - [pluginRegistrarMock addMethodCallDelegate:[OCMArg any] channel:[OCMArg any]]) - .andDo(^(NSInvocation* invocation) { - id delegate; - FlutterMethodChannel* channel; - [invocation getArgument:&delegate atIndex:2]; - [invocation getArgument:&channel atIndex:3]; - pluginChannel = channel; - plugin = delegate; - [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { - [delegate handleMethodCall:call result:result]; - }]; - }); - [FlutterMenuPlugin registerWithRegistrar:pluginRegistrarMock]; + FakePluginRegistrar* registrar = [[FakePluginRegistrar alloc] init]; + [FlutterMenuPlugin registerWithRegistrar:registrar]; + FlutterMenuPlugin* plugin = [registrar plugin]; NSDictionary* testMenus = @{ @"0" : @[ @@ -173,14 +208,6 @@ - (bool)testSetMenu { EXPECT_TRUE( [NSStringFromSelector([secondMenuLast action]) isEqualToString:@"flutterMenuItemSelected:"]); EXPECT_EQ([secondMenuLast tag], 7); - - return true; } -@end - -namespace flutter::testing { -TEST(FlutterMenuPluginTest, TestSetMenu) { - ASSERT_TRUE([[FlutterMenuPluginTestObjc alloc] testSetMenu]); -} } // namespace flutter::testing