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

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: Address review comments. Created 4 years, 8 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 #include "ui/base/models/simple_menu_model.h" 12 #include "ui/base/models/simple_menu_model.h"
13 #include "ui/events/event_utils.h" 13 #include "ui/events/event_utils.h"
14 #include "ui/views/test/views_test_base.h" 14 #include "ui/views/test/views_test_base.h"
15 15
16 namespace views { 16 namespace views {
17 namespace test { 17 namespace test {
18 namespace { 18 namespace {
19 19
20 class TestModel : public ui::SimpleMenuModel { 20 class TestModel : public ui::SimpleMenuModel {
21 public: 21 public:
22 TestModel() : ui::SimpleMenuModel(&delegate_), delegate_(this) {} 22 TestModel() : ui::SimpleMenuModel(&delegate_), delegate_(this) {}
23 23
24 void set_checked_command(int command) { checked_command_ = command; } 24 void set_checked_command(int command) { checked_command_ = command; }
25 25
26 void set_menu_open_callback(const base::Closure& callback) {
27 menu_open_callback_ = callback;
28 }
29
26 private: 30 private:
27 class Delegate : public ui::SimpleMenuModel::Delegate { 31 class Delegate : public ui::SimpleMenuModel::Delegate {
28 public: 32 public:
29 explicit Delegate(TestModel* model) : model_(model) {} 33 explicit Delegate(TestModel* model) : model_(model) {}
30 bool IsCommandIdChecked(int command_id) const override { 34 bool IsCommandIdChecked(int command_id) const override {
31 return command_id == model_->checked_command_; 35 return command_id == model_->checked_command_;
32 } 36 }
33 bool IsCommandIdEnabled(int command_id) const override { return true; } 37 bool IsCommandIdEnabled(int command_id) const override { return true; }
34 bool GetAcceleratorForCommandId(int command_id, 38 bool GetAcceleratorForCommandId(int command_id,
35 ui::Accelerator* accelerator) override { 39 ui::Accelerator* accelerator) override {
36 return false; 40 return false;
37 } 41 }
38 void ExecuteCommand(int command_id, int event_flags) override {} 42 void ExecuteCommand(int command_id, int event_flags) override {}
39 43
44 void MenuWillShow(SimpleMenuModel* source) override {
45 model_->menu_open_callback_.Run();
46 }
47
40 private: 48 private:
41 TestModel* model_; 49 TestModel* model_;
42 50
43 DISALLOW_COPY_AND_ASSIGN(Delegate); 51 DISALLOW_COPY_AND_ASSIGN(Delegate);
44 }; 52 };
45 53
46 private: 54 private:
47 int checked_command_ = -1; 55 int checked_command_ = -1;
48 Delegate delegate_; 56 Delegate delegate_;
57 base::Closure menu_open_callback_;
49 58
50 DISALLOW_COPY_AND_ASSIGN(TestModel); 59 DISALLOW_COPY_AND_ASSIGN(TestModel);
51 }; 60 };
52 61
53 } // namespace 62 } // namespace
54 63
55 class MenuRunnerCocoaTest : public ViewsTestBase { 64 class MenuRunnerCocoaTest : public ViewsTestBase {
56 public: 65 public:
57 enum { 66 enum {
58 kWindowHeight = 200, 67 kWindowHeight = 200,
(...skipping 23 matching lines...) Expand all
82 void TearDown() override { 91 void TearDown() override {
83 if (runner_) { 92 if (runner_) {
84 runner_->Release(); 93 runner_->Release();
85 runner_ = NULL; 94 runner_ = NULL;
86 } 95 }
87 96
88 parent_->CloseNow(); 97 parent_->CloseNow();
89 ViewsTestBase::TearDown(); 98 ViewsTestBase::TearDown();
90 } 99 }
91 100
92 // Runs the menu after scheduling |block| on the run loop. 101 // Runs the menu after registering |callback| as the menu open callback.
93 MenuRunner::RunResult RunMenu(dispatch_block_t block) { 102 MenuRunner::RunResult RunMenu(const base::Closure& callback) {
94 CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^{ 103 menu_->set_menu_open_callback(
95 EXPECT_TRUE(runner_->IsRunning()); 104 base::Bind(&MenuRunnerCocoaTest::RunMenuWrapperCallback,
96 block(); 105 base::Unretained(this), callback));
97 }); 106 return runner_->RunMenuAt(parent_, nullptr, gfx::Rect(),
98 return runner_->RunMenuAt(parent_, NULL, gfx::Rect(), MENU_ANCHOR_TOPLEFT, 107 MENU_ANCHOR_TOPLEFT, MenuRunner::CONTEXT_MENU);
99 MenuRunner::CONTEXT_MENU);
100 } 108 }
101 109
102 // Runs then cancels a combobox menu and captures the frame of the anchoring 110 // Runs then cancels a combobox menu and captures the frame of the anchoring
103 // view. 111 // view.
104 MenuRunner::RunResult RunMenuAt(const gfx::Rect& anchor) { 112 MenuRunner::RunResult RunMenuAt(const gfx::Rect& anchor) {
105 last_anchor_frame_ = NSZeroRect; 113 last_anchor_frame_ = NSZeroRect;
106 114
107 // Should be one child (the compositor layer) before showing, and it should 115 // 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. 116 // go up by one (the anchor view) while the menu is shown.
109 EXPECT_EQ(1u, [[parent_->GetNativeView() subviews] count]); 117 EXPECT_EQ(1u, [[parent_->GetNativeView() subviews] count]);
110 CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^{ 118
111 NSArray* subviews = [parent_->GetNativeView() subviews]; 119 menu_->set_menu_open_callback(base::Bind(
112 EXPECT_EQ(2u, [subviews count]); 120 &MenuRunnerCocoaTest::RunMenuAtCallback, base::Unretained(this)));
113 last_anchor_frame_ = [[subviews objectAtIndex:1] frame]; 121
114 runner_->Cancel();
115 });
116 MenuRunner::RunResult result = runner_->RunMenuAt( 122 MenuRunner::RunResult result = runner_->RunMenuAt(
117 parent_, nullptr, anchor, MENU_ANCHOR_TOPLEFT, MenuRunner::COMBOBOX); 123 parent_, nullptr, anchor, MENU_ANCHOR_TOPLEFT, MenuRunner::COMBOBOX);
118 124
119 // Ensure the anchor view is removed. 125 // Ensure the anchor view is removed.
120 EXPECT_EQ(1u, [[parent_->GetNativeView() subviews] count]); 126 EXPECT_EQ(1u, [[parent_->GetNativeView() subviews] count]);
121 return result; 127 return result;
122 } 128 }
123 129
130 void MenuCancelCallback() {
131 runner_->Cancel();
132 EXPECT_FALSE(runner_->IsRunning());
133 }
134
135 void MenuDeleteCallback() {
136 runner_->Release();
137 runner_ = nullptr;
138 }
139
124 protected: 140 protected:
125 scoped_ptr<TestModel> menu_; 141 scoped_ptr<TestModel> menu_;
126 internal::MenuRunnerImplCocoa* runner_ = nullptr; 142 internal::MenuRunnerImplCocoa* runner_ = nullptr;
127 views::Widget* parent_ = nullptr; 143 views::Widget* parent_ = nullptr;
128 NSRect last_anchor_frame_ = NSZeroRect; 144 NSRect last_anchor_frame_ = NSZeroRect;
129 145
130 private: 146 private:
147 void RunMenuWrapperCallback(const base::Closure& callback) {
148 EXPECT_TRUE(runner_->IsRunning());
149 callback.Run();
150 }
151
152 void RunMenuAtCallback() {
153 NSArray* subviews = [parent_->GetNativeView() subviews];
154 EXPECT_EQ(2u, [subviews count]);
155 last_anchor_frame_ = [[subviews objectAtIndex:1] frame];
156 runner_->Cancel();
157 }
158
131 DISALLOW_COPY_AND_ASSIGN(MenuRunnerCocoaTest); 159 DISALLOW_COPY_AND_ASSIGN(MenuRunnerCocoaTest);
132 }; 160 };
133 161
134 TEST_F(MenuRunnerCocoaTest, RunMenuAndCancel) { 162 TEST_F(MenuRunnerCocoaTest, RunMenuAndCancel) {
135 base::TimeDelta min_time = ui::EventTimeForNow(); 163 base::TimeDelta min_time = ui::EventTimeForNow();
136 164
137 MenuRunner::RunResult result = RunMenu(^{ 165 MenuRunner::RunResult result = RunMenu(base::Bind(
138 runner_->Cancel(); 166 &MenuRunnerCocoaTest::MenuCancelCallback, base::Unretained(this)));
139 EXPECT_FALSE(runner_->IsRunning());
140 });
141 167
142 EXPECT_EQ(MenuRunner::NORMAL_EXIT, result); 168 EXPECT_EQ(MenuRunner::NORMAL_EXIT, result);
143 EXPECT_FALSE(runner_->IsRunning()); 169 EXPECT_FALSE(runner_->IsRunning());
144 170
145 EXPECT_GE(runner_->GetClosingEventTime(), min_time); 171 EXPECT_GE(runner_->GetClosingEventTime(), min_time);
146 EXPECT_LE(runner_->GetClosingEventTime(), ui::EventTimeForNow()); 172 EXPECT_LE(runner_->GetClosingEventTime(), ui::EventTimeForNow());
147 173
148 // Cancel again. 174 // Cancel again.
149 runner_->Cancel(); 175 runner_->Cancel();
150 EXPECT_FALSE(runner_->IsRunning()); 176 EXPECT_FALSE(runner_->IsRunning());
151 } 177 }
152 178
153 TEST_F(MenuRunnerCocoaTest, RunMenuAndDelete) { 179 TEST_F(MenuRunnerCocoaTest, RunMenuAndDelete) {
154 MenuRunner::RunResult result = RunMenu(^{ 180 MenuRunner::RunResult result = RunMenu(base::Bind(
155 runner_->Release(); 181 &MenuRunnerCocoaTest::MenuDeleteCallback, base::Unretained(this)));
156 runner_ = NULL;
157 });
158
159 EXPECT_EQ(MenuRunner::MENU_DELETED, result); 182 EXPECT_EQ(MenuRunner::MENU_DELETED, result);
160 } 183 }
161 184
162 TEST_F(MenuRunnerCocoaTest, RunMenuTwice) { 185 TEST_F(MenuRunnerCocoaTest, RunMenuTwice) {
163 for (int i = 0; i < 2; ++i) { 186 for (int i = 0; i < 2; ++i) {
164 MenuRunner::RunResult result = RunMenu(^{ 187 MenuRunner::RunResult result = RunMenu(base::Bind(
165 runner_->Cancel(); 188 &MenuRunnerCocoaTest::MenuCancelCallback, base::Unretained(this)));
166 });
167 EXPECT_EQ(MenuRunner::NORMAL_EXIT, result); 189 EXPECT_EQ(MenuRunner::NORMAL_EXIT, result);
168 EXPECT_FALSE(runner_->IsRunning()); 190 EXPECT_FALSE(runner_->IsRunning());
169 } 191 }
170 } 192 }
171 193
172 TEST_F(MenuRunnerCocoaTest, CancelWithoutRunning) { 194 TEST_F(MenuRunnerCocoaTest, CancelWithoutRunning) {
173 runner_->Cancel(); 195 runner_->Cancel();
174 EXPECT_FALSE(runner_->IsRunning()); 196 EXPECT_FALSE(runner_->IsRunning());
175 EXPECT_EQ(base::TimeDelta(), runner_->GetClosingEventTime()); 197 EXPECT_EQ(base::TimeDelta(), runner_->GetClosingEventTime());
176 } 198 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 // In RTL, Cocoa messes up the positioning unless the anchor rectangle is 239 // 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 240 // offset to the right of the view. The offset for the checkmark is also
219 // skipped, to give a better match to native behavior. 241 // skipped, to give a better match to native behavior.
220 base::i18n::SetICUDefaultLocale("he"); 242 base::i18n::SetICUDefaultLocale("he");
221 RunMenuAt(anchor_rect); 243 RunMenuAt(anchor_rect);
222 EXPECT_EQ(combobox_rect.right(), last_anchor_frame_.origin.x); 244 EXPECT_EQ(combobox_rect.right(), last_anchor_frame_.origin.x);
223 } 245 }
224 246
225 } // namespace test 247 } // namespace test
226 } // namespace views 248 } // 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