Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: ui/views/controls/menu/menu_runner_cocoa_unittest.mm

Issue 1829603002: MacViews: Fix flaky MenuRunnerCocoaTests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Style improvements. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ui/views/controls/menu/menu_runner_impl_cocoa.h" 5 #import "ui/views/controls/menu/menu_runner_impl_cocoa.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
11 #import "testing/gtest_mac.h" 11 #import "testing/gtest_mac.h"
12 #import "ui/base/cocoa/menu_controller.h"
12 #include "ui/base/models/simple_menu_model.h" 13 #include "ui/base/models/simple_menu_model.h"
13 #include "ui/events/event_utils.h" 14 #include "ui/events/event_utils.h"
14 #include "ui/views/test/views_test_base.h" 15 #include "ui/views/test/views_test_base.h"
15 16
17 // A helper class to handle menu open notifications.
18 @interface MenuOpenWatcher : NSObject {
19 dispatch_block_t openCallback_;
tapted 2016/03/24 02:10:36 nit: @private
20 }
21
22 // Method to handle menu open notification.
23 - (void)menuWillOpen:(NSNotification*)notification;
24
25 // Block to be invoked on menu open notification. Weak. Clients must ensure that
26 // it remains in a valid state.
27 @property(nonatomic, assign) dispatch_block_t openCallback;
28
29 @end
30
31 @implementation MenuOpenWatcher
32
33 @synthesize openCallback = openCallback_;
34
35 - (id)init {
36 if (self = [super init]) {
tapted 2016/03/24 02:10:36 nit: extra parens around assignment used as condit
37 [[NSNotificationCenter defaultCenter]
38 addObserver:self
39 selector:@selector(menuWillOpen:)
40 name:kMenuControllerMenuWillOpenNotification
41 object:nil];
42 }
43 return self;
44 }
45
46 - (void)dealloc {
47 [[NSNotificationCenter defaultCenter] removeObserver:self];
48 [super dealloc];
49 }
50
51 - (void)menuWillOpen:(NSNotification*)notification {
52 if (openCallback_)
53 openCallback_();
54 }
55
56 @end
57
16 namespace views { 58 namespace views {
17 namespace test { 59 namespace test {
18 namespace { 60 namespace {
19 61
20 class TestModel : public ui::SimpleMenuModel { 62 class TestModel : public ui::SimpleMenuModel {
tapted 2016/03/24 02:10:36 Can we override MenuModel::MenuWillShow? Here, or
karandeepb 2016/04/06 05:52:48 Done. Though the code looks slightly uglier now si
21 public: 63 public:
22 TestModel() : ui::SimpleMenuModel(&delegate_), delegate_(this) {} 64 TestModel() : ui::SimpleMenuModel(&delegate_), delegate_(this) {}
23 65
24 void set_checked_command(int command) { checked_command_ = command; } 66 void set_checked_command(int command) { checked_command_ = command; }
25 67
26 private: 68 private:
27 class Delegate : public ui::SimpleMenuModel::Delegate { 69 class Delegate : public ui::SimpleMenuModel::Delegate {
28 public: 70 public:
29 explicit Delegate(TestModel* model) : model_(model) {} 71 explicit Delegate(TestModel* model) : model_(model) {}
30 bool IsCommandIdChecked(int command_id) const override { 72 bool IsCommandIdChecked(int command_id) const override {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 menu_->AddCheckItem(0, base::ASCIIToUTF16("Menu Item")); 112 menu_->AddCheckItem(0, base::ASCIIToUTF16("Menu Item"));
71 113
72 parent_ = new views::Widget(); 114 parent_ = new views::Widget();
73 parent_->Init(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS)); 115 parent_->Init(CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS));
74 parent_->SetBounds( 116 parent_->SetBounds(
75 gfx::Rect(kWindowOffset, kWindowOffset, kWindowWidth, kWindowHeight)); 117 gfx::Rect(kWindowOffset, kWindowOffset, kWindowWidth, kWindowHeight));
76 parent_->Show(); 118 parent_->Show();
77 119
78 runner_ = new internal::MenuRunnerImplCocoa(menu_.get()); 120 runner_ = new internal::MenuRunnerImplCocoa(menu_.get());
79 EXPECT_FALSE(runner_->IsRunning()); 121 EXPECT_FALSE(runner_->IsRunning());
122 menu_watcher_.reset([[MenuOpenWatcher alloc] init]);
80 } 123 }
81 124
82 void TearDown() override { 125 void TearDown() override {
83 if (runner_) { 126 if (runner_) {
84 runner_->Release(); 127 runner_->Release();
85 runner_ = NULL; 128 runner_ = NULL;
86 } 129 }
87 130
88 parent_->CloseNow(); 131 parent_->CloseNow();
89 ViewsTestBase::TearDown(); 132 ViewsTestBase::TearDown();
90 } 133 }
91 134
92 // Runs the menu after scheduling |block| on the run loop. 135 // Runs the menu after scheduling |block| on the run loop.
93 MenuRunner::RunResult RunMenu(dispatch_block_t block) { 136 MenuRunner::RunResult RunMenu(dispatch_block_t block) {
94 CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^{ 137 [menu_watcher_ setOpenCallback:^{
95 EXPECT_TRUE(runner_->IsRunning()); 138 EXPECT_TRUE(runner_->IsRunning());
96 block(); 139 block();
97 }); 140 }];
98 return runner_->RunMenuAt(parent_, NULL, gfx::Rect(), MENU_ANCHOR_TOPLEFT, 141 MenuRunner::RunResult result =
99 MenuRunner::CONTEXT_MENU); 142 runner_->RunMenuAt(parent_, NULL, gfx::Rect(), MENU_ANCHOR_TOPLEFT,
tapted 2016/03/24 02:10:36 nit (while you're here) NULL -> nullptr
karandeepb 2016/04/06 05:52:48 Done.
143 MenuRunner::CONTEXT_MENU);
144 [menu_watcher_ setOpenCallback:nil];
145 return result;
100 } 146 }
101 147
102 // Runs then cancels a combobox menu and captures the frame of the anchoring 148 // Runs then cancels a combobox menu and captures the frame of the anchoring
103 // view. 149 // view.
104 MenuRunner::RunResult RunMenuAt(const gfx::Rect& anchor) { 150 MenuRunner::RunResult RunMenuAt(const gfx::Rect& anchor) {
105 last_anchor_frame_ = NSZeroRect; 151 last_anchor_frame_ = NSZeroRect;
106 152
107 // Should be one child (the compositor layer) before showing, and it should 153 // Should be one child (the compositor layer) before showing, and it should
108 // go up by one (the anchor view) while the menu is shown. 154 // go up by one (the anchor view) while the menu is shown.
109 EXPECT_EQ(1u, [[parent_->GetNativeView() subviews] count]); 155 EXPECT_EQ(1u, [[parent_->GetNativeView() subviews] count]);
110 CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^{ 156
157 [menu_watcher_ setOpenCallback:^{
111 NSArray* subviews = [parent_->GetNativeView() subviews]; 158 NSArray* subviews = [parent_->GetNativeView() subviews];
112 EXPECT_EQ(2u, [subviews count]); 159 EXPECT_EQ(2u, [subviews count]);
113 last_anchor_frame_ = [[subviews objectAtIndex:1] frame]; 160 last_anchor_frame_ = [[subviews objectAtIndex:1] frame];
114 runner_->Cancel(); 161 runner_->Cancel();
115 }); 162 }];
163
116 MenuRunner::RunResult result = runner_->RunMenuAt( 164 MenuRunner::RunResult result = runner_->RunMenuAt(
117 parent_, nullptr, anchor, MENU_ANCHOR_TOPLEFT, MenuRunner::COMBOBOX); 165 parent_, nullptr, anchor, MENU_ANCHOR_TOPLEFT, MenuRunner::COMBOBOX);
118 166
119 // Ensure the anchor view is removed. 167 // Ensure the anchor view is removed.
120 EXPECT_EQ(1u, [[parent_->GetNativeView() subviews] count]); 168 EXPECT_EQ(1u, [[parent_->GetNativeView() subviews] count]);
169 [menu_watcher_ setOpenCallback:nil];
121 return result; 170 return result;
122 } 171 }
123 172
124 protected: 173 protected:
125 scoped_ptr<TestModel> menu_; 174 scoped_ptr<TestModel> menu_;
175 base::scoped_nsobject<MenuOpenWatcher> menu_watcher_;
126 internal::MenuRunnerImplCocoa* runner_ = nullptr; 176 internal::MenuRunnerImplCocoa* runner_ = nullptr;
127 views::Widget* parent_ = nullptr; 177 views::Widget* parent_ = nullptr;
128 NSRect last_anchor_frame_ = NSZeroRect; 178 NSRect last_anchor_frame_ = NSZeroRect;
129 179
130 private: 180 private:
131 DISALLOW_COPY_AND_ASSIGN(MenuRunnerCocoaTest); 181 DISALLOW_COPY_AND_ASSIGN(MenuRunnerCocoaTest);
132 }; 182 };
133 183
134 TEST_F(MenuRunnerCocoaTest, RunMenuAndCancel) { 184 TEST_F(MenuRunnerCocoaTest, RunMenuAndCancel) {
135 base::TimeDelta min_time = ui::EventTimeForNow(); 185 base::TimeDelta min_time = ui::EventTimeForNow();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // In RTL, Cocoa messes up the positioning unless the anchor rectangle is 267 // In RTL, Cocoa messes up the positioning unless the anchor rectangle is
218 // offset to the right of the view. The offset for the checkmark is also 268 // offset to the right of the view. The offset for the checkmark is also
219 // skipped, to give a better match to native behavior. 269 // skipped, to give a better match to native behavior.
220 base::i18n::SetICUDefaultLocale("he"); 270 base::i18n::SetICUDefaultLocale("he");
221 RunMenuAt(anchor_rect); 271 RunMenuAt(anchor_rect);
222 EXPECT_EQ(combobox_rect.right(), last_anchor_frame_.origin.x); 272 EXPECT_EQ(combobox_rect.right(), last_anchor_frame_.origin.x);
223 } 273 }
224 274
225 } // namespace test 275 } // namespace test
226 } // namespace views 276 } // namespace views
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698