| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "ui/app_list/views/apps_grid_view.h" | 5 #include "ui/app_list/views/apps_grid_view.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/timer/timer.h" | 14 #include "base/timer/timer.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "ui/app_list/app_list_item_model.h" | 16 #include "ui/app_list/app_list_item_model.h" |
| 17 #include "ui/app_list/app_list_model.h" | 17 #include "ui/app_list/app_list_model.h" |
| 18 #include "ui/app_list/pagination_model.h" | 18 #include "ui/app_list/pagination_model.h" |
| 19 #include "ui/app_list/test/app_list_test_model.h" | 19 #include "ui/app_list/test/app_list_test_model.h" |
| 20 #include "ui/app_list/views/app_list_item_view.h" | 20 #include "ui/app_list/views/app_list_item_view.h" |
| 21 #include "ui/app_list/views/test/apps_grid_view_test_api.h" | 21 #include "ui/app_list/views/test/apps_grid_view_test_api.h" |
| 22 #include "ui/views/test/views_test_base.h" |
| 22 | 23 |
| 23 namespace app_list { | 24 namespace app_list { |
| 24 namespace test { | 25 namespace test { |
| 25 | 26 |
| 26 namespace { | 27 namespace { |
| 27 | 28 |
| 28 const int kIconDimension = 48; | 29 const int kIconDimension = 48; |
| 29 const int kCols = 2; | 30 const int kCols = 2; |
| 30 const int kRows = 2; | 31 const int kRows = 2; |
| 31 const int kTilesPerPage = kCols * kRows; | 32 const int kTilesPerPage = kCols * kRows; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 PaginationModel* model_; | 85 PaginationModel* model_; |
| 85 bool wait_; | 86 bool wait_; |
| 86 bool page_changed_; | 87 bool page_changed_; |
| 87 base::OneShotTimer<PageFlipWaiter> wait_timer_; | 88 base::OneShotTimer<PageFlipWaiter> wait_timer_; |
| 88 | 89 |
| 89 DISALLOW_COPY_AND_ASSIGN(PageFlipWaiter); | 90 DISALLOW_COPY_AND_ASSIGN(PageFlipWaiter); |
| 90 }; | 91 }; |
| 91 | 92 |
| 92 } // namespace | 93 } // namespace |
| 93 | 94 |
| 94 class AppsGridViewTest : public testing::Test { | 95 class AppsGridViewTest : public views::ViewsTestBase { |
| 95 public: | 96 public: |
| 96 AppsGridViewTest() {} | 97 AppsGridViewTest() {} |
| 97 virtual ~AppsGridViewTest() {} | 98 virtual ~AppsGridViewTest() {} |
| 98 | 99 |
| 99 // testing::Test overrides: | 100 // testing::Test overrides: |
| 100 virtual void SetUp() OVERRIDE { | 101 virtual void SetUp() OVERRIDE { |
| 102 views::ViewsTestBase::SetUp(); |
| 101 model_.reset(new AppListTestModel); | 103 model_.reset(new AppListTestModel); |
| 102 pagination_model_.reset(new PaginationModel); | 104 pagination_model_.reset(new PaginationModel); |
| 103 | 105 |
| 104 apps_grid_view_.reset( | 106 apps_grid_view_.reset( |
| 105 new AppsGridView(NULL, pagination_model_.get(), NULL)); | 107 new AppsGridView(NULL, pagination_model_.get(), NULL)); |
| 106 apps_grid_view_->SetLayout(kIconDimension, kCols, kRows); | 108 apps_grid_view_->SetLayout(kIconDimension, kCols, kRows); |
| 107 apps_grid_view_->SetBoundsRect(gfx::Rect(gfx::Size(kWidth, kHeight))); | 109 apps_grid_view_->SetBoundsRect(gfx::Rect(gfx::Size(kWidth, kHeight))); |
| 108 apps_grid_view_->SetModel(model_.get()); | 110 apps_grid_view_->SetModel(model_.get()); |
| 109 | 111 |
| 110 test_api_.reset(new AppsGridViewTestApi(apps_grid_view_.get())); | 112 test_api_.reset(new AppsGridViewTestApi(apps_grid_view_.get())); |
| 111 } | 113 } |
| 112 virtual void TearDown() OVERRIDE { | 114 virtual void TearDown() OVERRIDE { |
| 113 apps_grid_view_.reset(); // Release apps grid view before models. | 115 apps_grid_view_.reset(); // Release apps grid view before models. |
| 116 views::ViewsTestBase::TearDown(); |
| 114 } | 117 } |
| 115 | 118 |
| 116 protected: | 119 protected: |
| 117 AppListItemView* GetItemViewAt(int index) { | 120 AppListItemView* GetItemViewAt(int index) { |
| 118 return static_cast<AppListItemView*>( | 121 return static_cast<AppListItemView*>( |
| 119 test_api_->GetViewAtModelIndex(index)); | 122 test_api_->GetViewAtModelIndex(index)); |
| 120 } | 123 } |
| 121 | 124 |
| 122 AppListItemView* GetItemViewForPoint(const gfx::Point& point) { | 125 AppListItemView* GetItemViewForPoint(const gfx::Point& point) { |
| 123 for (size_t i = 0; i < model_->apps()->item_count(); ++i) { | 126 for (size_t p = 0; p < model_->GetNumAppPages(); ++p) { |
| 124 AppListItemView* view = GetItemViewAt(i); | 127 const AppListModel::AppItems& apps = model_->GetAppItems(p); |
| 125 if (view->bounds().Contains(point)) | 128 size_t offset = p * model_->GetNumAppsPerPage(); |
| 126 return view; | 129 for (size_t i = 0; i < apps.item_count(); ++i) { |
| 130 AppListItemView* view = GetItemViewAt(offset + i); |
| 131 if (view->bounds().Contains(point)) |
| 132 return view; |
| 133 } |
| 127 } | 134 } |
| 128 return NULL; | 135 return NULL; |
| 129 } | 136 } |
| 130 | 137 |
| 131 gfx::Rect GetItemTileRectAt(int row, int col) { | 138 gfx::Rect GetItemTileRectAt(int row, int col) { |
| 132 DCHECK_GT(model_->apps()->item_count(), 0u); | 139 DCHECK_GT(model_->GetAppItems(0).item_count(), 0u); |
| 133 | 140 |
| 134 gfx::Insets insets(apps_grid_view_->GetInsets()); | 141 gfx::Insets insets(apps_grid_view_->GetInsets()); |
| 135 gfx::Rect rect(gfx::Point(insets.left(), insets.top()), | 142 gfx::Rect rect(gfx::Point(insets.left(), insets.top()), |
| 136 GetItemViewAt(0)->bounds().size()); | 143 GetItemViewAt(0)->bounds().size()); |
| 137 rect.Offset(col * rect.width(), row * rect.height()); | 144 rect.Offset(col * rect.width(), row * rect.height()); |
| 138 return rect; | 145 return rect; |
| 139 } | 146 } |
| 140 | 147 |
| 141 // Points are in |apps_grid_view_|'s coordinates. | 148 // Points are in |apps_grid_view_|'s coordinates. |
| 142 void SimulateDrag(AppsGridView::Pointer pointer, | 149 void SimulateDrag(AppsGridView::Pointer pointer, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 162 void SimulateKeyPress(ui::KeyboardCode key_code) { | 169 void SimulateKeyPress(ui::KeyboardCode key_code) { |
| 163 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, key_code, 0, false); | 170 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, key_code, 0, false); |
| 164 apps_grid_view_->OnKeyPressed(key_event); | 171 apps_grid_view_->OnKeyPressed(key_event); |
| 165 } | 172 } |
| 166 | 173 |
| 167 scoped_ptr<AppListTestModel> model_; | 174 scoped_ptr<AppListTestModel> model_; |
| 168 scoped_ptr<PaginationModel> pagination_model_; | 175 scoped_ptr<PaginationModel> pagination_model_; |
| 169 scoped_ptr<AppsGridView> apps_grid_view_; | 176 scoped_ptr<AppsGridView> apps_grid_view_; |
| 170 scoped_ptr<AppsGridViewTestApi> test_api_; | 177 scoped_ptr<AppsGridViewTestApi> test_api_; |
| 171 | 178 |
| 172 base::MessageLoopForUI message_loop_; | |
| 173 | |
| 174 private: | 179 private: |
| 175 DISALLOW_COPY_AND_ASSIGN(AppsGridViewTest); | 180 DISALLOW_COPY_AND_ASSIGN(AppsGridViewTest); |
| 176 }; | 181 }; |
| 177 | 182 |
| 178 TEST_F(AppsGridViewTest, CreatePage) { | 183 TEST_F(AppsGridViewTest, CreatePage) { |
| 179 // Fully populates a page. | 184 // Fully populates a page. |
| 180 const int kPages = 1; | 185 const int kPages = 1; |
| 181 model_->PopulateApps(kPages * kTilesPerPage); | 186 model_->PopulateApps(kPages * kTilesPerPage); |
| 182 EXPECT_EQ(kPages, pagination_model_->total_pages()); | 187 EXPECT_EQ(kPages, pagination_model_->total_pages()); |
| 183 | 188 |
| 184 // Adds one more and gets a new page created. | 189 // Adds one more and gets a new page created. |
| 185 model_->AddItem(std::string("Extra")); | 190 model_->CreateAndAddItem(std::string("Extra")); |
| 186 EXPECT_EQ(kPages + 1, pagination_model_->total_pages()); | 191 EXPECT_EQ(kPages + 1, pagination_model_->total_pages()); |
| 187 } | 192 } |
| 188 | 193 |
| 189 TEST_F(AppsGridViewTest, EnsureHighlightedVisible) { | 194 TEST_F(AppsGridViewTest, EnsureHighlightedVisible) { |
| 190 const int kPages = 3; | 195 const int kPages = 3; |
| 191 model_->PopulateApps(kPages * kTilesPerPage); | 196 model_->PopulateApps(kPages * kTilesPerPage); |
| 192 EXPECT_EQ(kPages, pagination_model_->total_pages()); | 197 EXPECT_EQ(kPages, pagination_model_->total_pages()); |
| 193 EXPECT_EQ(0, pagination_model_->selected_page()); | 198 EXPECT_EQ(0, pagination_model_->selected_page()); |
| 194 | 199 |
| 195 // Highlight first one and last one one first page and first page should be | 200 // Highlight first one and last one one first page and first page should be |
| 196 // selected. | 201 // selected. |
| 197 model_->HighlightItemAt(0); | 202 model_->HighlightItemAt(0); |
| 198 EXPECT_EQ(0, pagination_model_->selected_page()); | 203 EXPECT_EQ(0, pagination_model_->selected_page()); |
| 199 model_->HighlightItemAt(kTilesPerPage - 1); | 204 model_->HighlightItemAt(kTilesPerPage - 1); |
| 200 EXPECT_EQ(0, pagination_model_->selected_page()); | 205 EXPECT_EQ(0, pagination_model_->selected_page()); |
| 201 | 206 |
| 202 // Highlight first one on 2nd page and 2nd page should be selected. | 207 // Highlight first one on 2nd page and 2nd page should be selected. |
| 203 model_->HighlightItemAt(kTilesPerPage + 1); | 208 model_->HighlightItemAt(kTilesPerPage + 1); |
| 204 EXPECT_EQ(1, pagination_model_->selected_page()); | 209 EXPECT_EQ(1, pagination_model_->selected_page()); |
| 205 | 210 |
| 206 // Highlight last one in the model and last page should be selected. | 211 // Highlight last one in the model and last page should be selected. |
| 207 model_->HighlightItemAt(model_->apps()->item_count() - 1); | 212 model_->HighlightItemAt(kPages * kTilesPerPage - 1); |
| 208 EXPECT_EQ(kPages - 1, pagination_model_->selected_page()); | 213 EXPECT_EQ(kPages - 1, pagination_model_->selected_page()); |
| 209 } | 214 } |
| 210 | 215 |
| 211 TEST_F(AppsGridViewTest, RemoveSelectedLastApp) { | 216 TEST_F(AppsGridViewTest, RemoveSelectedLastApp) { |
| 212 const int kTotalItems = 2; | 217 const int kTotalItems = 2; |
| 213 const int kLastItemIndex = kTotalItems - 1; | 218 const int kLastItemIndex = kTotalItems - 1; |
| 214 | 219 |
| 215 model_->PopulateApps(kTotalItems); | 220 model_->PopulateApps(kTotalItems); |
| 216 | 221 |
| 217 AppListItemView* last_view = GetItemViewAt(kLastItemIndex); | 222 AppListItemView* last_view = GetItemViewAt(kLastItemIndex); |
| 218 apps_grid_view_->SetSelectedView(last_view); | 223 apps_grid_view_->SetSelectedView(last_view); |
| 219 model_->apps()->DeleteAt(kLastItemIndex); | 224 model_->DeleteItemAt(0, kLastItemIndex); |
| 220 | 225 |
| 221 EXPECT_FALSE(apps_grid_view_->IsSelectedView(last_view)); | 226 EXPECT_FALSE(apps_grid_view_->IsSelectedView(last_view)); |
| 222 | 227 |
| 223 // No crash happens. | 228 // No crash happens. |
| 224 AppListItemView* view = GetItemViewAt(0); | 229 AppListItemView* view = GetItemViewAt(0); |
| 225 apps_grid_view_->SetSelectedView(view); | 230 apps_grid_view_->SetSelectedView(view); |
| 226 EXPECT_TRUE(apps_grid_view_->IsSelectedView(view)); | 231 EXPECT_TRUE(apps_grid_view_->IsSelectedView(view)); |
| 227 } | 232 } |
| 228 | 233 |
| 229 TEST_F(AppsGridViewTest, MouseDrag) { | 234 TEST_F(AppsGridViewTest, MouseDrag) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 244 | 249 |
| 245 // Canceling drag should keep existing order. | 250 // Canceling drag should keep existing order. |
| 246 SimulateDrag(AppsGridView::MOUSE, from, to); | 251 SimulateDrag(AppsGridView::MOUSE, from, to); |
| 247 apps_grid_view_->EndDrag(true); | 252 apps_grid_view_->EndDrag(true); |
| 248 EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"), | 253 EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"), |
| 249 model_->GetModelContent()); | 254 model_->GetModelContent()); |
| 250 test_api_->LayoutToIdealBounds(); | 255 test_api_->LayoutToIdealBounds(); |
| 251 | 256 |
| 252 // Deleting an item keeps remaining intact. | 257 // Deleting an item keeps remaining intact. |
| 253 SimulateDrag(AppsGridView::MOUSE, from, to); | 258 SimulateDrag(AppsGridView::MOUSE, from, to); |
| 254 model_->apps()->DeleteAt(1); | 259 model_->DeleteItemAt(0, 1); |
| 255 apps_grid_view_->EndDrag(false); | 260 apps_grid_view_->EndDrag(false); |
| 256 EXPECT_EQ(std::string("Item 1,Item 2,Item 3"), | 261 EXPECT_EQ(std::string("Item 1,Item 2,Item 3"), |
| 257 model_->GetModelContent()); | 262 model_->GetModelContent()); |
| 258 test_api_->LayoutToIdealBounds(); | 263 test_api_->LayoutToIdealBounds(); |
| 259 | 264 |
| 260 // Adding a launcher item cancels the drag and respects the order. | 265 // Adding a launcher item cancels the drag and respects the order. |
| 261 SimulateDrag(AppsGridView::MOUSE, from, to); | 266 SimulateDrag(AppsGridView::MOUSE, from, to); |
| 262 model_->AddItem(std::string("Extra")); | 267 model_->CreateAndAddItem(std::string("Extra")); |
| 263 apps_grid_view_->EndDrag(false); | 268 apps_grid_view_->EndDrag(false); |
| 264 EXPECT_EQ(std::string("Item 1,Item 2,Item 3,Extra"), | 269 EXPECT_EQ(std::string("Item 1,Item 2,Item 3,Extra"), |
| 265 model_->GetModelContent()); | 270 model_->GetModelContent()); |
| 266 test_api_->LayoutToIdealBounds(); | 271 test_api_->LayoutToIdealBounds(); |
| 267 } | 272 } |
| 268 | 273 |
| 269 TEST_F(AppsGridViewTest, MouseDragFlipPage) { | 274 TEST_F(AppsGridViewTest, MouseDragFlipPage) { |
| 270 test_api_->SetPageFlipDelay(10); | 275 test_api_->SetPageFlipDelay(10); |
| 271 pagination_model_->SetTransitionDurations(10, 10); | 276 pagination_model_->SetTransitionDurations(10, 10); |
| 272 | 277 |
| 273 PageFlipWaiter page_flip_waiter(&message_loop_, | 278 PageFlipWaiter page_flip_waiter(message_loop(), |
| 274 pagination_model_.get()); | 279 pagination_model_.get()); |
| 275 | 280 |
| 276 const int kPages = 3; | 281 const int kPages = 3; |
| 277 model_->PopulateApps(kPages * kTilesPerPage); | 282 model_->PopulateApps(kPages * kTilesPerPage); |
| 278 EXPECT_EQ(kPages, pagination_model_->total_pages()); | 283 EXPECT_EQ(kPages, pagination_model_->total_pages()); |
| 279 EXPECT_EQ(0, pagination_model_->selected_page()); | 284 EXPECT_EQ(0, pagination_model_->selected_page()); |
| 280 | 285 |
| 281 gfx::Point from = GetItemTileRectAt(0, 0).CenterPoint(); | 286 gfx::Point from = GetItemTileRectAt(0, 0).CenterPoint(); |
| 282 gfx::Point to = gfx::Point(apps_grid_view_->width(), | 287 gfx::Point to = gfx::Point(apps_grid_view_->width(), |
| 283 apps_grid_view_->height() / 2); | 288 apps_grid_view_->height() / 2); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 SimulateKeyPress(ui::VKEY_UP); | 429 SimulateKeyPress(ui::VKEY_UP); |
| 425 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt( | 430 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt( |
| 426 first_index_on_page2))); | 431 first_index_on_page2))); |
| 427 } | 432 } |
| 428 | 433 |
| 429 TEST_F(AppsGridViewTest, ItemLabelShortNameOverride) { | 434 TEST_F(AppsGridViewTest, ItemLabelShortNameOverride) { |
| 430 // If the app's full name and short name differ, the title label's tooltip | 435 // If the app's full name and short name differ, the title label's tooltip |
| 431 // should always be the full name of the app. | 436 // should always be the full name of the app. |
| 432 std::string expected_text("xyz"); | 437 std::string expected_text("xyz"); |
| 433 std::string expected_tooltip("tooltip"); | 438 std::string expected_tooltip("tooltip"); |
| 434 model_->AddItem(expected_text, expected_tooltip); | 439 model_->CreateAndAddItem(expected_text, expected_tooltip); |
| 435 | 440 |
| 436 string16 actual_tooltip; | 441 string16 actual_tooltip; |
| 437 AppListItemView* item_view = GetItemViewAt(0); | 442 AppListItemView* item_view = GetItemViewAt(0); |
| 438 ASSERT_TRUE(item_view); | 443 ASSERT_TRUE(item_view); |
| 439 const views::Label* title_label = item_view->title(); | 444 const views::Label* title_label = item_view->title(); |
| 440 EXPECT_TRUE(title_label->GetTooltipText( | 445 EXPECT_TRUE(title_label->GetTooltipText( |
| 441 title_label->bounds().CenterPoint(), &actual_tooltip)); | 446 title_label->bounds().CenterPoint(), &actual_tooltip)); |
| 442 EXPECT_EQ(expected_tooltip, UTF16ToUTF8(actual_tooltip)); | 447 EXPECT_EQ(expected_tooltip, UTF16ToUTF8(actual_tooltip)); |
| 443 EXPECT_EQ(expected_text, UTF16ToUTF8(title_label->text())); | 448 EXPECT_EQ(expected_text, UTF16ToUTF8(title_label->text())); |
| 444 } | 449 } |
| 445 | 450 |
| 446 TEST_F(AppsGridViewTest, ItemLabelNoShortName) { | 451 TEST_F(AppsGridViewTest, ItemLabelNoShortName) { |
| 447 // If the app's full name and short name are the same, use the default tooltip | 452 // If the app's full name and short name are the same, use the default tooltip |
| 448 // behavior of the label (only show a tooltip if the title is truncated). | 453 // behavior of the label (only show a tooltip if the title is truncated). |
| 449 std::string title("a"); | 454 std::string title("a"); |
| 450 model_->AddItem(title, title); | 455 model_->CreateAndAddItem(title, title); |
| 451 | 456 |
| 452 string16 actual_tooltip; | 457 string16 actual_tooltip; |
| 453 AppListItemView* item_view = GetItemViewAt(0); | 458 AppListItemView* item_view = GetItemViewAt(0); |
| 454 ASSERT_TRUE(item_view); | 459 ASSERT_TRUE(item_view); |
| 455 const views::Label* title_label = item_view->title(); | 460 const views::Label* title_label = item_view->title(); |
| 456 EXPECT_FALSE(title_label->GetTooltipText( | 461 EXPECT_FALSE(title_label->GetTooltipText( |
| 457 title_label->bounds().CenterPoint(), &actual_tooltip)); | 462 title_label->bounds().CenterPoint(), &actual_tooltip)); |
| 458 EXPECT_EQ(title, UTF16ToUTF8(title_label->text())); | 463 EXPECT_EQ(title, UTF16ToUTF8(title_label->text())); |
| 459 } | 464 } |
| 460 | 465 |
| 461 } // namespace test | 466 } // namespace test |
| 462 } // namespace app_list | 467 } // namespace app_list |
| OLD | NEW |