Home | History | Annotate | Download | only in views
      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