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 3 // found in the LICENSE file. 4 5 #include "ui/app_list/views/search_box_view.h" 6 7 #include <cctype> 8 #include <map> 9 10 #include "base/strings/utf_string_conversions.h" 11 #include "ui/app_list/test/app_list_test_view_delegate.h" 12 #include "ui/app_list/views/search_box_view_delegate.h" 13 #include "ui/views/controls/textfield/textfield.h" 14 #include "ui/views/test/widget_test.h" 15 16 namespace app_list { 17 namespace test { 18 19 class KeyPressCounterView : public views::View { 20 public: 21 KeyPressCounterView() : count_(0) {} 22 virtual ~KeyPressCounterView() {} 23 24 int GetCountAndReset() { 25 int count = count_; 26 count_ = 0; 27 return count; 28 } 29 30 private: 31 // Overridden from views::View: 32 virtual bool OnKeyPressed(const ui::KeyEvent& key_event) OVERRIDE { 33 if (!::isalnum(static_cast<int>(key_event.key_code()))) { 34 ++count_; 35 return true; 36 } 37 return false; 38 } 39 int count_; 40 41 DISALLOW_COPY_AND_ASSIGN(KeyPressCounterView); 42 }; 43 44 class SearchBoxViewTest : public views::test::WidgetTest, 45 public SearchBoxViewDelegate { 46 public: 47 SearchBoxViewTest() : query_changed_count_(0) {} 48 virtual ~SearchBoxViewTest() {} 49 50 // Overridden from testing::Test: 51 virtual void SetUp() OVERRIDE { 52 views::test::WidgetTest::SetUp(); 53 widget_ = CreateTopLevelPlatformWidget(); 54 view_ = new SearchBoxView(this, &view_delegate_); 55 counter_view_ = new KeyPressCounterView(); 56 widget_->GetContentsView()->AddChildView(view_); 57 widget_->GetContentsView()->AddChildView(counter_view_); 58 view_->set_contents_view(counter_view_); 59 } 60 61 virtual void TearDown() OVERRIDE { 62 widget_->CloseNow(); 63 views::test::WidgetTest::TearDown(); 64 } 65 66 protected: 67 SearchBoxView* view() { return view_; } 68 69 void SetLongAutoLaunchTimeout() { 70 // Sets a long timeout that lasts longer than the test run. 71 view_delegate_.set_auto_launch_timeout(base::TimeDelta::FromDays(1)); 72 } 73 74 base::TimeDelta GetAutoLaunchTimeout() { 75 return view_delegate_.GetAutoLaunchTimeout(); 76 } 77 78 void ResetAutoLaunchTimeout() { 79 view_delegate_.set_auto_launch_timeout(base::TimeDelta()); 80 } 81 82 int GetContentsViewKeyPressCountAndReset() { 83 return counter_view_->GetCountAndReset(); 84 } 85 86 void KeyPress(ui::KeyboardCode key_code) { 87 ui::KeyEvent event(ui::ET_KEY_PRESSED, key_code, ui::EF_NONE); 88 view_->search_box()->OnKeyPressed(event); 89 // Emulates the input method. 90 if (::isalnum(static_cast<int>(key_code))) { 91 base::char16 character = ::tolower(static_cast<int>(key_code)); 92 view_->search_box()->InsertText(base::string16(1, character)); 93 } 94 } 95 96 std::string GetLastQueryAndReset() { 97 base::string16 query = last_query_; 98 last_query_.clear(); 99 return base::UTF16ToUTF8(query); 100 } 101 102 int GetQueryChangedCountAndReset() { 103 int result = query_changed_count_; 104 query_changed_count_ = 0; 105 return result; 106 } 107 108 private: 109 // Overridden from SearchBoxViewDelegate: 110 virtual void QueryChanged(SearchBoxView* sender) OVERRIDE { 111 ++query_changed_count_; 112 last_query_ = sender->search_box()->text(); 113 } 114 115 AppListTestViewDelegate view_delegate_; 116 views::Widget* widget_; 117 SearchBoxView* view_; 118 KeyPressCounterView* counter_view_; 119 base::string16 last_query_; 120 int query_changed_count_; 121 122 DISALLOW_COPY_AND_ASSIGN(SearchBoxViewTest); 123 }; 124 125 TEST_F(SearchBoxViewTest, Basic) { 126 KeyPress(ui::VKEY_A); 127 EXPECT_EQ("a", GetLastQueryAndReset()); 128 EXPECT_EQ(1, GetQueryChangedCountAndReset()); 129 EXPECT_EQ(0, GetContentsViewKeyPressCountAndReset()); 130 131 KeyPress(ui::VKEY_DOWN); 132 EXPECT_EQ(0, GetQueryChangedCountAndReset()); 133 EXPECT_EQ(1, GetContentsViewKeyPressCountAndReset()); 134 135 view()->ClearSearch(); 136 EXPECT_EQ(1, GetQueryChangedCountAndReset()); 137 EXPECT_TRUE(GetLastQueryAndReset().empty()); 138 } 139 140 TEST_F(SearchBoxViewTest, CancelAutoLaunch) { 141 SetLongAutoLaunchTimeout(); 142 ASSERT_NE(base::TimeDelta(), GetAutoLaunchTimeout()); 143 144 // Normal key event cancels the timeout. 145 KeyPress(ui::VKEY_A); 146 EXPECT_EQ(base::TimeDelta(), GetAutoLaunchTimeout()); 147 ResetAutoLaunchTimeout(); 148 149 // Unusual key event doesn't cancel -- it will be canceled in 150 // SearchResultListView. 151 SetLongAutoLaunchTimeout(); 152 KeyPress(ui::VKEY_DOWN); 153 EXPECT_NE(base::TimeDelta(), GetAutoLaunchTimeout()); 154 ResetAutoLaunchTimeout(); 155 156 // Clearing search box also cancels. 157 SetLongAutoLaunchTimeout(); 158 view()->ClearSearch(); 159 EXPECT_EQ(base::TimeDelta(), GetAutoLaunchTimeout()); 160 } 161 162 } // namespace test 163 } // namespace app_list 164