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_->GetAppItemsForPage(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_->GetAppItemsForPage(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 |