Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / ui / views / controls / combobox / combobox_unittest.cc
blob65ca154a029c2067d713fb4f2fb474baea20d258
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/views/controls/combobox/combobox.h"
7 #include <set>
9 #include "base/basictypes.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "ui/base/ime/text_input_client.h"
12 #include "ui/base/models/combobox_model.h"
13 #include "ui/events/event.h"
14 #include "ui/events/event_constants.h"
15 #include "ui/events/keycodes/keyboard_codes.h"
16 #include "ui/views/controls/combobox/combobox_listener.h"
17 #include "ui/views/controls/menu/menu_runner.h"
18 #include "ui/views/controls/menu/menu_runner_handler.h"
19 #include "ui/views/ime/mock_input_method.h"
20 #include "ui/views/test/menu_runner_test_api.h"
21 #include "ui/views/test/views_test_base.h"
22 #include "ui/views/widget/widget.h"
24 using base::ASCIIToUTF16;
26 namespace views {
28 namespace {
30 // An dummy implementation of MenuRunnerHandler to check if the dropdown menu is
31 // shown or not.
32 class TestMenuRunnerHandler : public MenuRunnerHandler {
33 public:
34 TestMenuRunnerHandler() : executed_(false) {}
36 bool executed() const { return executed_; }
38 MenuRunner::RunResult RunMenuAt(Widget* parent,
39 MenuButton* button,
40 const gfx::Rect& bounds,
41 MenuAnchorPosition anchor,
42 ui::MenuSourceType source_type,
43 int32 types) override {
44 executed_ = true;
45 return MenuRunner::NORMAL_EXIT;
48 private:
49 bool executed_;
51 DISALLOW_COPY_AND_ASSIGN(TestMenuRunnerHandler);
54 // A wrapper of Combobox to intercept the result of OnKeyPressed() and
55 // OnKeyReleased() methods.
56 class TestCombobox : public Combobox {
57 public:
58 explicit TestCombobox(ui::ComboboxModel* model)
59 : Combobox(model),
60 key_handled_(false),
61 key_received_(false) {}
63 bool OnKeyPressed(const ui::KeyEvent& e) override {
64 key_received_ = true;
65 key_handled_ = Combobox::OnKeyPressed(e);
66 return key_handled_;
69 bool OnKeyReleased(const ui::KeyEvent& e) override {
70 key_received_ = true;
71 key_handled_ = Combobox::OnKeyReleased(e);
72 return key_handled_;
75 bool key_handled() const { return key_handled_; }
76 bool key_received() const { return key_received_; }
78 void clear() {
79 key_received_ = key_handled_ = false;
82 private:
83 bool key_handled_;
84 bool key_received_;
86 DISALLOW_COPY_AND_ASSIGN(TestCombobox);
89 // A concrete class is needed to test the combobox.
90 class TestComboboxModel : public ui::ComboboxModel {
91 public:
92 TestComboboxModel() {}
93 ~TestComboboxModel() override {}
95 static const int kItemCount = 10;
97 // ui::ComboboxModel:
98 int GetItemCount() const override { return kItemCount; }
99 base::string16 GetItemAt(int index) override {
100 if (IsItemSeparatorAt(index)) {
101 NOTREACHED();
102 return ASCIIToUTF16("SEPARATOR");
104 return ASCIIToUTF16(index % 2 == 0 ? "PEANUT BUTTER" : "JELLY");
106 bool IsItemSeparatorAt(int index) override {
107 return separators_.find(index) != separators_.end();
110 int GetDefaultIndex() const override {
111 // Return the first index that is not a separator.
112 for (int index = 0; index < kItemCount; ++index) {
113 if (separators_.find(index) == separators_.end())
114 return index;
116 NOTREACHED();
117 return 0;
120 void SetSeparators(const std::set<int>& separators) {
121 separators_ = separators;
124 private:
125 std::set<int> separators_;
127 DISALLOW_COPY_AND_ASSIGN(TestComboboxModel);
130 // A combobox model which refers to a vector.
131 class VectorComboboxModel : public ui::ComboboxModel {
132 public:
133 explicit VectorComboboxModel(std::vector<std::string>* values)
134 : values_(values) {}
135 ~VectorComboboxModel() override {}
137 // ui::ComboboxModel:
138 int GetItemCount() const override { return (int)values_->size(); }
139 base::string16 GetItemAt(int index) override {
140 return ASCIIToUTF16(values_->at(index));
142 bool IsItemSeparatorAt(int index) override { return false; }
144 private:
145 std::vector<std::string>* values_;
148 class EvilListener : public ComboboxListener {
149 public:
150 EvilListener() : deleted_(false) {}
151 ~EvilListener() override{};
153 // ComboboxListener:
154 void OnPerformAction(Combobox* combobox) override {
155 delete combobox;
156 deleted_ = true;
159 bool deleted() const { return deleted_; }
161 private:
162 bool deleted_;
164 DISALLOW_COPY_AND_ASSIGN(EvilListener);
167 class TestComboboxListener : public views::ComboboxListener {
168 public:
169 TestComboboxListener() : perform_action_index_(-1), actions_performed_(0) {}
170 ~TestComboboxListener() override {}
172 void OnPerformAction(views::Combobox* combobox) override {
173 perform_action_index_ = combobox->selected_index();
174 actions_performed_++;
177 int perform_action_index() const {
178 return perform_action_index_;
181 bool on_perform_action_called() const {
182 return actions_performed_ > 0;
185 int actions_performed() const {
186 return actions_performed_;
189 private:
190 int perform_action_index_;
191 int actions_performed_;
193 private:
194 DISALLOW_COPY_AND_ASSIGN(TestComboboxListener);
197 } // namespace
199 class ComboboxTest : public ViewsTestBase {
200 public:
201 ComboboxTest() : widget_(NULL), combobox_(NULL) {}
203 void TearDown() override {
204 if (widget_)
205 widget_->Close();
206 ViewsTestBase::TearDown();
209 void InitCombobox(const std::set<int>* separators) {
210 model_.reset(new TestComboboxModel());
212 if (separators)
213 model_->SetSeparators(*separators);
215 ASSERT_FALSE(combobox_);
216 combobox_ = new TestCombobox(model_.get());
217 combobox_->set_id(1);
219 widget_ = new Widget;
220 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
221 params.bounds = gfx::Rect(200, 200, 200, 200);
222 widget_->Init(params);
223 View* container = new View();
224 widget_->SetContentsView(container);
225 container->AddChildView(combobox_);
227 widget_->ReplaceInputMethod(new MockInputMethod);
229 // Assumes the Widget is always focused.
230 widget_->GetInputMethod()->OnFocus();
232 combobox_->RequestFocus();
233 combobox_->SizeToPreferredSize();
236 protected:
237 void SendKeyEvent(ui::KeyboardCode key_code) {
238 SendKeyEventWithType(key_code, ui::ET_KEY_PRESSED);
241 void SendKeyEventWithType(ui::KeyboardCode key_code, ui::EventType type) {
242 ui::KeyEvent event(type, key_code, ui::EF_NONE);
243 widget_->GetInputMethod()->DispatchKeyEvent(event);
246 View* GetFocusedView() {
247 return widget_->GetFocusManager()->GetFocusedView();
250 void PerformClick(const gfx::Point& point) {
251 ui::MouseEvent pressed_event = ui::MouseEvent(ui::ET_MOUSE_PRESSED, point,
252 point,
253 ui::EF_LEFT_MOUSE_BUTTON,
254 ui::EF_LEFT_MOUSE_BUTTON);
255 widget_->OnMouseEvent(&pressed_event);
256 ui::MouseEvent released_event = ui::MouseEvent(ui::ET_MOUSE_RELEASED, point,
257 point,
258 ui::EF_LEFT_MOUSE_BUTTON,
259 ui::EF_LEFT_MOUSE_BUTTON);
260 widget_->OnMouseEvent(&released_event);
263 // We need widget to populate wrapper class.
264 Widget* widget_;
266 // |combobox_| will be allocated InitCombobox() and then owned by |widget_|.
267 TestCombobox* combobox_;
269 // Combobox does not take ownership of the model, hence it needs to be scoped.
270 scoped_ptr<TestComboboxModel> model_;
273 TEST_F(ComboboxTest, KeyTest) {
274 InitCombobox(NULL);
275 SendKeyEvent(ui::VKEY_END);
276 EXPECT_EQ(combobox_->selected_index() + 1, model_->GetItemCount());
277 SendKeyEvent(ui::VKEY_HOME);
278 EXPECT_EQ(combobox_->selected_index(), 0);
279 SendKeyEvent(ui::VKEY_DOWN);
280 SendKeyEvent(ui::VKEY_DOWN);
281 EXPECT_EQ(combobox_->selected_index(), 2);
282 SendKeyEvent(ui::VKEY_RIGHT);
283 EXPECT_EQ(combobox_->selected_index(), 2);
284 SendKeyEvent(ui::VKEY_LEFT);
285 EXPECT_EQ(combobox_->selected_index(), 2);
286 SendKeyEvent(ui::VKEY_UP);
287 EXPECT_EQ(combobox_->selected_index(), 1);
288 SendKeyEvent(ui::VKEY_PRIOR);
289 EXPECT_EQ(combobox_->selected_index(), 0);
290 SendKeyEvent(ui::VKEY_NEXT);
291 EXPECT_EQ(combobox_->selected_index(), model_->GetItemCount() - 1);
294 // Check that if a combobox is disabled before it has a native wrapper, then the
295 // native wrapper inherits the disabled state when it gets created.
296 TEST_F(ComboboxTest, DisabilityTest) {
297 model_.reset(new TestComboboxModel());
299 ASSERT_FALSE(combobox_);
300 combobox_ = new TestCombobox(model_.get());
301 combobox_->SetEnabled(false);
303 widget_ = new Widget;
304 Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
305 params.bounds = gfx::Rect(100, 100, 100, 100);
306 widget_->Init(params);
307 View* container = new View();
308 widget_->SetContentsView(container);
309 container->AddChildView(combobox_);
310 EXPECT_FALSE(combobox_->enabled());
313 // Verifies that we don't select a separator line in combobox when navigating
314 // through keyboard.
315 TEST_F(ComboboxTest, SkipSeparatorSimple) {
316 std::set<int> separators;
317 separators.insert(2);
318 InitCombobox(&separators);
319 EXPECT_EQ(0, combobox_->selected_index());
320 SendKeyEvent(ui::VKEY_DOWN);
321 EXPECT_EQ(1, combobox_->selected_index());
322 SendKeyEvent(ui::VKEY_DOWN);
323 EXPECT_EQ(3, combobox_->selected_index());
324 SendKeyEvent(ui::VKEY_UP);
325 EXPECT_EQ(1, combobox_->selected_index());
326 SendKeyEvent(ui::VKEY_HOME);
327 EXPECT_EQ(0, combobox_->selected_index());
328 SendKeyEvent(ui::VKEY_PRIOR);
329 EXPECT_EQ(0, combobox_->selected_index());
330 SendKeyEvent(ui::VKEY_END);
331 EXPECT_EQ(9, combobox_->selected_index());
334 // Verifies that we never select the separator that is in the beginning of the
335 // combobox list when navigating through keyboard.
336 TEST_F(ComboboxTest, SkipSeparatorBeginning) {
337 std::set<int> separators;
338 separators.insert(0);
339 InitCombobox(&separators);
340 EXPECT_EQ(1, combobox_->selected_index());
341 SendKeyEvent(ui::VKEY_DOWN);
342 EXPECT_EQ(2, combobox_->selected_index());
343 SendKeyEvent(ui::VKEY_DOWN);
344 EXPECT_EQ(3, combobox_->selected_index());
345 SendKeyEvent(ui::VKEY_UP);
346 EXPECT_EQ(2, combobox_->selected_index());
347 SendKeyEvent(ui::VKEY_HOME);
348 EXPECT_EQ(1, combobox_->selected_index());
349 SendKeyEvent(ui::VKEY_PRIOR);
350 EXPECT_EQ(1, combobox_->selected_index());
351 SendKeyEvent(ui::VKEY_END);
352 EXPECT_EQ(9, combobox_->selected_index());
355 // Verifies that we never select the separator that is in the end of the
356 // combobox list when navigating through keyboard.
357 TEST_F(ComboboxTest, SkipSeparatorEnd) {
358 std::set<int> separators;
359 separators.insert(TestComboboxModel::kItemCount - 1);
360 InitCombobox(&separators);
361 combobox_->SetSelectedIndex(8);
362 SendKeyEvent(ui::VKEY_DOWN);
363 EXPECT_EQ(8, combobox_->selected_index());
364 SendKeyEvent(ui::VKEY_UP);
365 EXPECT_EQ(7, combobox_->selected_index());
366 SendKeyEvent(ui::VKEY_END);
367 EXPECT_EQ(8, combobox_->selected_index());
370 // Verifies that we never select any of the adjacent separators (multiple
371 // consecutive) that appear in the beginning of the combobox list when
372 // navigating through keyboard.
373 TEST_F(ComboboxTest, SkipMultipleSeparatorsAtBeginning) {
374 std::set<int> separators;
375 separators.insert(0);
376 separators.insert(1);
377 separators.insert(2);
378 InitCombobox(&separators);
379 EXPECT_EQ(3, combobox_->selected_index());
380 SendKeyEvent(ui::VKEY_DOWN);
381 EXPECT_EQ(4, combobox_->selected_index());
382 SendKeyEvent(ui::VKEY_UP);
383 EXPECT_EQ(3, combobox_->selected_index());
384 SendKeyEvent(ui::VKEY_NEXT);
385 EXPECT_EQ(9, combobox_->selected_index());
386 SendKeyEvent(ui::VKEY_HOME);
387 EXPECT_EQ(3, combobox_->selected_index());
388 SendKeyEvent(ui::VKEY_END);
389 EXPECT_EQ(9, combobox_->selected_index());
390 SendKeyEvent(ui::VKEY_PRIOR);
391 EXPECT_EQ(3, combobox_->selected_index());
394 // Verifies that we never select any of the adjacent separators (multiple
395 // consecutive) that appear in the middle of the combobox list when navigating
396 // through keyboard.
397 TEST_F(ComboboxTest, SkipMultipleAdjacentSeparatorsAtMiddle) {
398 std::set<int> separators;
399 separators.insert(4);
400 separators.insert(5);
401 separators.insert(6);
402 InitCombobox(&separators);
403 combobox_->SetSelectedIndex(3);
404 SendKeyEvent(ui::VKEY_DOWN);
405 EXPECT_EQ(7, combobox_->selected_index());
406 SendKeyEvent(ui::VKEY_UP);
407 EXPECT_EQ(3, combobox_->selected_index());
410 // Verifies that we never select any of the adjacent separators (multiple
411 // consecutive) that appear in the end of the combobox list when navigating
412 // through keyboard.
413 TEST_F(ComboboxTest, SkipMultipleSeparatorsAtEnd) {
414 std::set<int> separators;
415 separators.insert(7);
416 separators.insert(8);
417 separators.insert(9);
418 InitCombobox(&separators);
419 combobox_->SetSelectedIndex(6);
420 SendKeyEvent(ui::VKEY_DOWN);
421 EXPECT_EQ(6, combobox_->selected_index());
422 SendKeyEvent(ui::VKEY_UP);
423 EXPECT_EQ(5, combobox_->selected_index());
424 SendKeyEvent(ui::VKEY_HOME);
425 EXPECT_EQ(0, combobox_->selected_index());
426 SendKeyEvent(ui::VKEY_NEXT);
427 EXPECT_EQ(6, combobox_->selected_index());
428 SendKeyEvent(ui::VKEY_PRIOR);
429 EXPECT_EQ(0, combobox_->selected_index());
430 SendKeyEvent(ui::VKEY_END);
431 EXPECT_EQ(6, combobox_->selected_index());
434 TEST_F(ComboboxTest, GetTextForRowTest) {
435 std::set<int> separators;
436 separators.insert(0);
437 separators.insert(1);
438 separators.insert(9);
439 InitCombobox(&separators);
440 for (int i = 0; i < combobox_->GetRowCount(); ++i) {
441 if (separators.count(i) != 0) {
442 EXPECT_TRUE(combobox_->GetTextForRow(i).empty()) << i;
443 } else {
444 EXPECT_EQ(ASCIIToUTF16(i % 2 == 0 ? "PEANUT BUTTER" : "JELLY"),
445 combobox_->GetTextForRow(i)) << i;
450 // Verifies selecting the first matching value (and returning whether found).
451 TEST_F(ComboboxTest, SelectValue) {
452 InitCombobox(NULL);
453 ASSERT_EQ(model_->GetDefaultIndex(), combobox_->selected_index());
454 EXPECT_TRUE(combobox_->SelectValue(ASCIIToUTF16("PEANUT BUTTER")));
455 EXPECT_EQ(0, combobox_->selected_index());
456 EXPECT_TRUE(combobox_->SelectValue(ASCIIToUTF16("JELLY")));
457 EXPECT_EQ(1, combobox_->selected_index());
458 EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("BANANAS")));
459 EXPECT_EQ(1, combobox_->selected_index());
461 // With the action style, the selected index is always 0.
462 combobox_->SetStyle(Combobox::STYLE_ACTION);
463 EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("PEANUT BUTTER")));
464 EXPECT_EQ(0, combobox_->selected_index());
465 EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("JELLY")));
466 EXPECT_EQ(0, combobox_->selected_index());
467 EXPECT_FALSE(combobox_->SelectValue(ASCIIToUTF16("BANANAS")));
468 EXPECT_EQ(0, combobox_->selected_index());
471 TEST_F(ComboboxTest, SelectIndexActionStyle) {
472 InitCombobox(NULL);
474 // With the action style, the selected index is always 0.
475 combobox_->SetStyle(Combobox::STYLE_ACTION);
476 combobox_->SetSelectedIndex(1);
477 EXPECT_EQ(0, combobox_->selected_index());
478 combobox_->SetSelectedIndex(2);
479 EXPECT_EQ(0, combobox_->selected_index());
480 combobox_->SetSelectedIndex(3);
481 EXPECT_EQ(0, combobox_->selected_index());
484 TEST_F(ComboboxTest, ListenerHandlesDelete) {
485 TestComboboxModel model;
487 // |combobox| will be deleted on change.
488 TestCombobox* combobox = new TestCombobox(&model);
489 scoped_ptr<EvilListener> evil_listener(new EvilListener());
490 combobox->set_listener(evil_listener.get());
491 ASSERT_NO_FATAL_FAILURE(combobox->ExecuteCommand(2));
492 EXPECT_TRUE(evil_listener->deleted());
494 // With STYLE_ACTION
495 // |combobox| will be deleted on change.
496 combobox = new TestCombobox(&model);
497 evil_listener.reset(new EvilListener());
498 combobox->set_listener(evil_listener.get());
499 combobox->SetStyle(Combobox::STYLE_ACTION);
500 ASSERT_NO_FATAL_FAILURE(combobox->ExecuteCommand(2));
501 EXPECT_TRUE(evil_listener->deleted());
504 TEST_F(ComboboxTest, Click) {
505 InitCombobox(NULL);
507 TestComboboxListener listener;
508 combobox_->set_listener(&listener);
510 combobox_->Layout();
512 // Click the left side. The menu is shown.
513 TestMenuRunnerHandler* test_menu_runner_handler = new TestMenuRunnerHandler();
514 scoped_ptr<MenuRunnerHandler> menu_runner_handler(test_menu_runner_handler);
515 test::MenuRunnerTestAPI test_api(
516 combobox_->dropdown_list_menu_runner_.get());
517 test_api.SetMenuRunnerHandler(menu_runner_handler.Pass());
518 PerformClick(gfx::Point(combobox_->x() + 1,
519 combobox_->y() + combobox_->height() / 2));
520 EXPECT_FALSE(listener.on_perform_action_called());
521 EXPECT_TRUE(test_menu_runner_handler->executed());
524 TEST_F(ComboboxTest, ClickButDisabled) {
525 InitCombobox(NULL);
527 TestComboboxListener listener;
528 combobox_->set_listener(&listener);
530 combobox_->Layout();
531 combobox_->SetEnabled(false);
533 // Click the left side, but nothing happens since the combobox is disabled.
534 TestMenuRunnerHandler* test_menu_runner_handler = new TestMenuRunnerHandler();
535 scoped_ptr<MenuRunnerHandler> menu_runner_handler(test_menu_runner_handler);
536 test::MenuRunnerTestAPI test_api(
537 combobox_->dropdown_list_menu_runner_.get());
538 test_api.SetMenuRunnerHandler(menu_runner_handler.Pass());
539 PerformClick(gfx::Point(combobox_->x() + 1,
540 combobox_->y() + combobox_->height() / 2));
541 EXPECT_FALSE(listener.on_perform_action_called());
542 EXPECT_FALSE(test_menu_runner_handler->executed());
545 TEST_F(ComboboxTest, NotifyOnClickWithReturnKey) {
546 InitCombobox(NULL);
548 TestComboboxListener listener;
549 combobox_->set_listener(&listener);
551 // With STYLE_NORMAL, the click event is ignored.
552 SendKeyEvent(ui::VKEY_RETURN);
553 EXPECT_FALSE(listener.on_perform_action_called());
555 // With STYLE_ACTION, the click event is notified.
556 combobox_->SetStyle(Combobox::STYLE_ACTION);
557 SendKeyEvent(ui::VKEY_RETURN);
558 EXPECT_TRUE(listener.on_perform_action_called());
559 EXPECT_EQ(0, listener.perform_action_index());
562 TEST_F(ComboboxTest, NotifyOnClickWithSpaceKey) {
563 InitCombobox(NULL);
565 TestComboboxListener listener;
566 combobox_->set_listener(&listener);
568 // With STYLE_NORMAL, the click event is ignored.
569 SendKeyEvent(ui::VKEY_SPACE);
570 EXPECT_FALSE(listener.on_perform_action_called());
571 SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED);
572 EXPECT_FALSE(listener.on_perform_action_called());
574 // With STYLE_ACTION, the click event is notified after releasing.
575 combobox_->SetStyle(Combobox::STYLE_ACTION);
576 SendKeyEvent(ui::VKEY_SPACE);
577 EXPECT_FALSE(listener.on_perform_action_called());
578 SendKeyEventWithType(ui::VKEY_SPACE, ui::ET_KEY_RELEASED);
579 EXPECT_TRUE(listener.on_perform_action_called());
580 EXPECT_EQ(0, listener.perform_action_index());
583 TEST_F(ComboboxTest, NotifyOnClickWithMouse) {
584 InitCombobox(NULL);
586 TestComboboxListener listener;
587 combobox_->set_listener(&listener);
589 combobox_->SetStyle(Combobox::STYLE_ACTION);
590 combobox_->Layout();
592 // Click the right side (arrow button). The menu is shown.
593 TestMenuRunnerHandler* test_menu_runner_handler = new TestMenuRunnerHandler();
594 scoped_ptr<MenuRunnerHandler> menu_runner_handler(test_menu_runner_handler);
595 scoped_ptr<test::MenuRunnerTestAPI> test_api(
596 new test::MenuRunnerTestAPI(combobox_->dropdown_list_menu_runner_.get()));
597 test_api->SetMenuRunnerHandler(menu_runner_handler.Pass());
599 PerformClick(gfx::Point(combobox_->x() + combobox_->width() - 1,
600 combobox_->y() + combobox_->height() / 2));
601 EXPECT_FALSE(listener.on_perform_action_called());
602 EXPECT_TRUE(test_menu_runner_handler->executed());
604 // Click the left side (text button). The click event is notified.
605 test_menu_runner_handler = new TestMenuRunnerHandler();
606 menu_runner_handler.reset(test_menu_runner_handler);
607 test_api.reset(
608 new test::MenuRunnerTestAPI(combobox_->dropdown_list_menu_runner_.get()));
609 test_api->SetMenuRunnerHandler(menu_runner_handler.Pass());
610 PerformClick(gfx::Point(combobox_->x() + 1,
611 combobox_->y() + combobox_->height() / 2));
612 EXPECT_TRUE(listener.on_perform_action_called());
613 EXPECT_FALSE(test_menu_runner_handler->executed());
614 EXPECT_EQ(0, listener.perform_action_index());
617 TEST_F(ComboboxTest, ConsumingPressKeyEvents) {
618 InitCombobox(NULL);
620 EXPECT_FALSE(combobox_->OnKeyPressed(
621 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE)));
622 EXPECT_FALSE(combobox_->OnKeyPressed(
623 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, ui::EF_NONE)));
625 // When the combobox's style is STYLE_ACTION, pressing events of a space key
626 // or an enter key will be consumed.
627 combobox_->SetStyle(Combobox::STYLE_ACTION);
628 EXPECT_TRUE(combobox_->OnKeyPressed(
629 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE)));
630 EXPECT_TRUE(combobox_->OnKeyPressed(
631 ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_SPACE, ui::EF_NONE)));
634 TEST_F(ComboboxTest, ContentWidth) {
635 std::vector<std::string> values;
636 VectorComboboxModel model(&values);
637 TestCombobox combobox(&model);
639 std::string long_item = "this is the long item";
640 std::string short_item = "s";
642 values.resize(1);
643 values[0] = long_item;
644 combobox.ModelChanged();
646 const int long_item_width = combobox.content_size_.width();
648 values[0] = short_item;
649 combobox.ModelChanged();
651 const int short_item_width = combobox.content_size_.width();
653 values.resize(2);
654 values[0] = short_item;
655 values[1] = long_item;
656 combobox.ModelChanged();
658 // When the style is STYLE_NORMAL, the width will fit with the longest item.
659 combobox.SetStyle(Combobox::STYLE_NORMAL);
660 EXPECT_EQ(long_item_width, combobox.content_size_.width());
662 // When the style is STYLE_ACTION, the width will fit with the first items'
663 // width.
664 combobox.SetStyle(Combobox::STYLE_ACTION);
665 EXPECT_EQ(short_item_width, combobox.content_size_.width());
668 TEST_F(ComboboxTest, TypingPrefixNotifiesListener) {
669 InitCombobox(NULL);
671 TestComboboxListener listener;
672 combobox_->set_listener(&listener);
674 // Type the first character of the second menu item ("JELLY").
675 combobox_->GetTextInputClient()->InsertChar('J', ui::EF_NONE);
676 EXPECT_EQ(1, listener.actions_performed());
677 EXPECT_EQ(1, listener.perform_action_index());
679 // Type the second character of "JELLY", item shouldn't change and
680 // OnPerformAction() shouldn't be re-called.
681 combobox_->GetTextInputClient()->InsertChar('E', ui::EF_NONE);
682 EXPECT_EQ(1, listener.actions_performed());
683 EXPECT_EQ(1, listener.perform_action_index());
685 // Clears the typed text.
686 combobox_->OnBlur();
688 // Type the first character of "PEANUT BUTTER", which should change the
689 // selected index and perform an action.
690 combobox_->GetTextInputClient()->InsertChar('P', ui::EF_NONE);
691 EXPECT_EQ(2, listener.actions_performed());
692 EXPECT_EQ(2, listener.perform_action_index());
695 } // namespace views