| Index: ui/base/cocoa/menu_controller_unittest.mm
|
| diff --git a/ui/base/cocoa/menu_controller_unittest.mm b/ui/base/cocoa/menu_controller_unittest.mm
|
| index 24a86f021b341f6816283678508297e890195687..fabeff573eb68e03014331ac643e7e0272554be5 100644
|
| --- a/ui/base/cocoa/menu_controller_unittest.mm
|
| +++ b/ui/base/cocoa/menu_controller_unittest.mm
|
| @@ -4,6 +4,7 @@
|
|
|
| #import <Cocoa/Cocoa.h>
|
|
|
| +#include "base/mac/mac_util.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/run_loop.h"
|
| #include "base/strings/sys_string_conversions.h"
|
| @@ -20,6 +21,35 @@
|
|
|
| using base::ASCIIToUTF16;
|
|
|
| +@interface TestResponsiveMenuController : MenuController
|
| +@property(assign, nonatomic) BOOL processEarly;
|
| +@property(assign, nonatomic) BOOL sawItemEarly;
|
| +@end
|
| +
|
| +@implementation TestResponsiveMenuController {
|
| + BOOL sawItemEarly_;
|
| + BOOL processEarly_;
|
| +}
|
| +
|
| +@synthesize sawItemEarly = sawItemEarly_;
|
| +@synthesize processEarly = processEarly_;
|
| +
|
| +- (BOOL)processItemSelectedEarly:(id)sender {
|
| + sawItemEarly_ = YES;
|
| + if (!processEarly_)
|
| + return NO;
|
| +
|
| + [self itemSelected:sender];
|
| + return YES;
|
| +}
|
| +
|
| +@end
|
| +
|
| +@interface NSMenuItem (Private)
|
| +// Exposed to simulate in testing.
|
| +- (void)_sendItemSelectedNote;
|
| +@end
|
| +
|
| namespace ui {
|
|
|
| namespace {
|
| @@ -393,6 +423,81 @@ TEST_F(MenuControllerTest, OpenClose) {
|
| EXPECT_TRUE(delegate.did_close_);
|
| }
|
|
|
| +// Verify that the private API used by MenuController's ResponsiveNSMenuItem
|
| +// exists in the runtime. It's not a disaster if it disappears, (or AppKit
|
| +// stops invoking it) but consumers will stop receiving opportunities to
|
| +// -processItemSelectedEarly:.
|
| +TEST_F(MenuControllerTest, SendItemSelectedNoteExists) {
|
| + // -_sendItemSelectedNote doesn't exist on 10.9 or 10.10. NSPopUpButton menus
|
| + // on 10.9 don't animate out, and always suffer from the brief "flash" of the
|
| + // old selection when the menu disappears.
|
| + // TODO(tapted): Find a hook on 10.10 if we deem it necessary.
|
| + if (base::mac::IsAtMostOS10_10())
|
| + return;
|
| +
|
| + EXPECT_TRUE(
|
| + [NSMenuItem instancesRespondToSelector:@selector(_sendItemSelectedNote)]);
|
| +}
|
| +
|
| +// Emulate the flow for -[MenuController processItemSelectedEarly:].
|
| +TEST_F(MenuControllerTest, EmulateItemSelectedEarly) {
|
| + if (![NSMenuItem instancesRespondToSelector:@selector(_sendItemSelectedNote)])
|
| + return;
|
| +
|
| + base::MessageLoopForUI message_loop;
|
| +
|
| + Delegate delegate;
|
| + SimpleMenuModel model(&delegate);
|
| + model.AddItem(1, ASCIIToUTF16("foo"));
|
| +
|
| + base::scoped_nsobject<TestResponsiveMenuController> controller(
|
| + [[TestResponsiveMenuController alloc] initWithModel:&model
|
| + useWithPopUpButtonCell:NO]);
|
| + [controller setProcessEarly:YES];
|
| +
|
| + NSMenuItem* item = [[controller menu] itemAtIndex:0];
|
| + EXPECT_TRUE(item);
|
| +
|
| + [controller menuWillOpen:[controller menu]];
|
| +
|
| + // Pretend the first item got clicked. AppKit sends _sendItemSelectedNote to
|
| + // the menu item, then performs its action.
|
| + EXPECT_FALSE([controller sawItemEarly]);
|
| + EXPECT_EQ(0, delegate.execute_count_);
|
| + [item _sendItemSelectedNote];
|
| +
|
| + EXPECT_TRUE([controller sawItemEarly]);
|
| +
|
| + // Item gets executed early.
|
| + EXPECT_EQ(1, delegate.execute_count_);
|
| +
|
| + // Simulate dismissal. This happens before the action.
|
| + [controller menuDidClose:[controller menu]];
|
| +
|
| + // Perform the action normally. Shouldn't get executed again.
|
| + [[item target] performSelector:[item action] withObject:item];
|
| + EXPECT_EQ(1, delegate.execute_count_);
|
| +
|
| + // Repeat, without processing early.
|
| + [controller setProcessEarly:NO];
|
| + [controller setSawItemEarly:NO];
|
| + delegate.execute_count_ = 0;
|
| + delegate.did_show_ = delegate.did_close_ = false;
|
| +
|
| + [controller menuWillOpen:[controller menu]];
|
| + [item _sendItemSelectedNote];
|
| +
|
| + // Saw it, but didn't execute.
|
| + EXPECT_TRUE([controller sawItemEarly]);
|
| + EXPECT_EQ(0, delegate.execute_count_);
|
| +
|
| + [controller menuDidClose:[controller menu]];
|
| +
|
| + // Perform the action normally. Now executes.
|
| + [[item target] performSelector:[item action] withObject:item];
|
| + EXPECT_EQ(1, delegate.execute_count_);
|
| +}
|
| +
|
| } // namespace
|
|
|
| } // namespace ui
|
|
|