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

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