Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: ui/app_list/apps_grid_view_unittest.cc

Issue 11784034: Skeleton for app_list on OSX, and refactoring for enable_app_list=1 on OS=="mac". (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase for 175876 and 175961 Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/app_list/apps_grid_view.cc ('k') | ui/app_list/cocoa/app_list_view_window.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/app_list/apps_grid_view.h"
6
7 #include <string>
8
9 #include "base/basictypes.h"
10 #include "base/compiler_specific.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop.h"
13 #include "base/stringprintf.h"
14 #include "base/timer.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "ui/app_list/app_list_item_model.h"
17 #include "ui/app_list/app_list_item_view.h"
18 #include "ui/app_list/app_list_model.h"
19 #include "ui/app_list/pagination_model.h"
20 #include "ui/app_list/test/apps_grid_view_test_api.h"
21
22 namespace app_list {
23 namespace test {
24
25 namespace {
26
27 const int kIconDimension = 48;
28 const int kCols = 2;
29 const int kRows = 2;
30 const int kTilesPerPage = kCols * kRows;
31
32 const int kWidth = 320;
33 const int kHeight = 240;
34
35 class PageFlipWaiter : public PaginationModelObserver {
36 public:
37 PageFlipWaiter(MessageLoopForUI* ui_loop,
38 PaginationModel* model)
39 : ui_loop_(ui_loop),
40 model_(model),
41 wait_(false),
42 page_changed_(false) {
43 model_->AddObserver(this);
44 }
45
46 virtual ~PageFlipWaiter() {
47 model_->RemoveObserver(this);
48 }
49
50 bool Wait(int time_out_ms) {
51 DCHECK(!wait_);
52 wait_ = true;
53 page_changed_ = false;
54 wait_timer_.Stop();
55 wait_timer_.Start(FROM_HERE,
56 base::TimeDelta::FromMilliseconds(time_out_ms),
57 this, &PageFlipWaiter::OnWaitTimeOut);
58 ui_loop_->Run();
59 wait_ = false;
60 return page_changed_;
61 }
62
63 private:
64 void OnWaitTimeOut() {
65 ui_loop_->Quit();
66 }
67
68 // PaginationModelObserver overrides:
69 virtual void TotalPagesChanged() OVERRIDE {
70 }
71 virtual void SelectedPageChanged(int old_selected,
72 int new_selected) OVERRIDE {
73 page_changed_ = true;
74 if (wait_)
75 ui_loop_->Quit();
76 }
77 virtual void TransitionChanged() OVERRIDE {
78 }
79
80 MessageLoopForUI* ui_loop_;
81 PaginationModel* model_;
82 bool wait_;
83 bool page_changed_;
84 base::OneShotTimer<PageFlipWaiter> wait_timer_;
85
86 DISALLOW_COPY_AND_ASSIGN(PageFlipWaiter);
87 };
88
89 } // namespace
90
91 class AppsGridViewTest : public testing::Test {
92 public:
93 AppsGridViewTest() {}
94 virtual ~AppsGridViewTest() {}
95
96 // testing::Test overrides:
97 virtual void SetUp() OVERRIDE {
98 model_.reset(new AppListModel);
99 pagination_model_.reset(new PaginationModel);
100
101 apps_grid_view_.reset(new AppsGridView(NULL, pagination_model_.get()));
102 apps_grid_view_->SetLayout(kIconDimension, kCols, kRows);
103 apps_grid_view_->SetBoundsRect(gfx::Rect(gfx::Size(kWidth, kHeight)));
104 apps_grid_view_->SetModel(model_.get());
105
106 test_api_.reset(new AppsGridViewTestApi(apps_grid_view_.get()));
107 }
108 virtual void TearDown() OVERRIDE {
109 apps_grid_view_.reset(); // Release apps grid view before models.
110 }
111
112 protected:
113 void PopulateApps(int n) {
114 for (int i = 0; i < n; ++i) {
115 std::string title = base::StringPrintf("Item %d", i);
116 model_->apps()->Add(CreateItem(title));
117 }
118 }
119
120 // Get a string of all apps in |model| joined with ','.
121 std::string GetModelContent() {
122 std::string content;
123 for (size_t i = 0; i < model_->apps()->item_count(); ++i) {
124 if (i > 0)
125 content += ',';
126 content += model_->apps()->GetItemAt(i)->title();
127 }
128 return content;
129 }
130
131 AppListItemModel* CreateItem(const std::string& title) {
132 AppListItemModel* item = new AppListItemModel;
133 item->SetTitle(title);
134 return item;
135 }
136
137 void HighlightItemAt(int index) {
138 AppListItemModel* item = model_->apps()->GetItemAt(index);
139 item->SetHighlighted(true);
140 }
141
142 AppListItemView* GetItemViewAt(int index) {
143 return static_cast<AppListItemView*>(
144 test_api_->GetViewAtModelIndex(index));
145 }
146
147 AppListItemView* GetItemViewForPoint(const gfx::Point& point) {
148 for (size_t i = 0; i < model_->apps()->item_count(); ++i) {
149 AppListItemView* view = GetItemViewAt(i);
150 if (view->bounds().Contains(point))
151 return view;
152 }
153 return NULL;
154 }
155
156 gfx::Rect GetItemTileRectAt(int row, int col) {
157 DCHECK_GT(model_->apps()->item_count(), 0u);
158
159 gfx::Insets insets(apps_grid_view_->GetInsets());
160 gfx::Rect rect(gfx::Point(insets.left(), insets.top()),
161 GetItemViewAt(0)->bounds().size());
162 rect.Offset(col * rect.width(), row * rect.height());
163 return rect;
164 }
165
166 // Points are in |apps_grid_view_|'s coordinates.
167 void SimulateDrag(AppsGridView::Pointer pointer,
168 const gfx::Point& from,
169 const gfx::Point& to) {
170 AppListItemView* view = GetItemViewForPoint(from);
171 DCHECK(view);
172
173 gfx::Point translated_from = gfx::PointAtOffsetFromOrigin(
174 from - view->bounds().origin());
175 gfx::Point translated_to = gfx::PointAtOffsetFromOrigin(
176 to - view->bounds().origin());
177
178 ui::MouseEvent pressed_event(ui::ET_MOUSE_PRESSED,
179 translated_from, from, 0);
180 apps_grid_view_->InitiateDrag(view, pointer, pressed_event);
181
182 ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED,
183 translated_to, to, 0);
184 apps_grid_view_->UpdateDrag(view, pointer, drag_event);
185 }
186
187 void SimulateKeyPress(ui::KeyboardCode key_code) {
188 ui::KeyEvent key_event(ui::ET_KEY_PRESSED, key_code, 0, false);
189 apps_grid_view_->OnKeyPressed(key_event);
190 }
191
192 scoped_ptr<AppListModel> model_;
193 scoped_ptr<PaginationModel> pagination_model_;
194 scoped_ptr<AppsGridView> apps_grid_view_;
195 scoped_ptr<AppsGridViewTestApi> test_api_;
196
197 MessageLoopForUI message_loop_;
198
199 private:
200 DISALLOW_COPY_AND_ASSIGN(AppsGridViewTest);
201 };
202
203 TEST_F(AppsGridViewTest, CreatePage) {
204 // Fully populates a page.
205 const int kPages = 1;
206 PopulateApps(kPages * kTilesPerPage);
207 EXPECT_EQ(kPages, pagination_model_->total_pages());
208
209 // Adds one more and gets a new page created.
210 model_->apps()->Add(CreateItem(std::string("Extra")));
211 EXPECT_EQ(kPages + 1, pagination_model_->total_pages());
212 }
213
214 TEST_F(AppsGridViewTest, EnsureHighlightedVisible) {
215 const int kPages = 3;
216 PopulateApps(kPages * kTilesPerPage);
217 EXPECT_EQ(kPages, pagination_model_->total_pages());
218 EXPECT_EQ(0, pagination_model_->selected_page());
219
220 // Highlight first one and last one one first page and first page should be
221 // selected.
222 HighlightItemAt(0);
223 EXPECT_EQ(0, pagination_model_->selected_page());
224 HighlightItemAt(kTilesPerPage - 1);
225 EXPECT_EQ(0, pagination_model_->selected_page());
226
227 // Highlight first one on 2nd page and 2nd page should be selected.
228 HighlightItemAt(kTilesPerPage + 1);
229 EXPECT_EQ(1, pagination_model_->selected_page());
230
231 // Highlight last one in the model and last page should be selected.
232 HighlightItemAt(model_->apps()->item_count() - 1);
233 EXPECT_EQ(kPages - 1, pagination_model_->selected_page());
234 }
235
236 TEST_F(AppsGridViewTest, RemoveSelectedLastApp) {
237 const int kTotalItems = 2;
238 const int kLastItemIndex = kTotalItems - 1;
239
240 PopulateApps(kTotalItems);
241
242 AppListItemView* last_view = GetItemViewAt(kLastItemIndex);
243 apps_grid_view_->SetSelectedView(last_view);
244 model_->apps()->DeleteAt(kLastItemIndex);
245
246 EXPECT_FALSE(apps_grid_view_->IsSelectedView(last_view));
247
248 // No crash happens.
249 AppListItemView* view = GetItemViewAt(0);
250 apps_grid_view_->SetSelectedView(view);
251 EXPECT_TRUE(apps_grid_view_->IsSelectedView(view));
252 }
253
254 TEST_F(AppsGridViewTest, MouseDrag) {
255 const int kTotalItems = 4;
256 PopulateApps(kTotalItems);
257 EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
258 GetModelContent());
259
260 gfx::Point from = GetItemTileRectAt(0, 0).CenterPoint();
261 gfx::Point to = GetItemTileRectAt(0, 1).CenterPoint();
262
263 // Dragging changes model order.
264 SimulateDrag(AppsGridView::MOUSE, from, to);
265 apps_grid_view_->EndDrag(false);
266 EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"),
267 GetModelContent());
268 test_api_->LayoutToIdealBounds();
269
270 // Canceling drag should keep existing order.
271 SimulateDrag(AppsGridView::MOUSE, from, to);
272 apps_grid_view_->EndDrag(true);
273 EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"),
274 GetModelContent());
275 test_api_->LayoutToIdealBounds();
276
277 // Deleting an item keeps remaining intact.
278 SimulateDrag(AppsGridView::MOUSE, from, to);
279 model_->apps()->DeleteAt(1);
280 apps_grid_view_->EndDrag(false);
281 EXPECT_EQ(std::string("Item 1,Item 2,Item 3"),
282 GetModelContent());
283 test_api_->LayoutToIdealBounds();
284
285 // Adding a launcher item cancels the drag and respects the order.
286 SimulateDrag(AppsGridView::MOUSE, from, to);
287 model_->apps()->Add(CreateItem(std::string("Extra")));
288 apps_grid_view_->EndDrag(false);
289 EXPECT_EQ(std::string("Item 1,Item 2,Item 3,Extra"),
290 GetModelContent());
291 test_api_->LayoutToIdealBounds();
292 }
293
294 TEST_F(AppsGridViewTest, MouseDragFlipPage) {
295 test_api_->SetPageFlipDelay(10);
296 pagination_model_->SetTransitionDurations(10, 10);
297
298 PageFlipWaiter page_flip_waiter(&message_loop_,
299 pagination_model_.get());
300
301 const int kPages = 3;
302 PopulateApps(kPages * kTilesPerPage);
303 EXPECT_EQ(kPages, pagination_model_->total_pages());
304 EXPECT_EQ(0, pagination_model_->selected_page());
305
306 gfx::Point from = GetItemTileRectAt(0, 0).CenterPoint();
307 gfx::Point to = gfx::Point(apps_grid_view_->width(),
308 apps_grid_view_->height() / 2);
309
310 // Drag to right edge.
311 SimulateDrag(AppsGridView::MOUSE, from, to);
312
313 // Page should be flipped after sometime.
314 EXPECT_TRUE(page_flip_waiter.Wait(100));
315 EXPECT_EQ(1, pagination_model_->selected_page());
316
317 // Stay there and page should be flipped again.
318 EXPECT_TRUE(page_flip_waiter.Wait(100));
319 EXPECT_EQ(2, pagination_model_->selected_page());
320
321 // Stay there longer and no page flip happen since we are at the last page.
322 EXPECT_FALSE(page_flip_waiter.Wait(100));
323 EXPECT_EQ(2, pagination_model_->selected_page());
324
325 apps_grid_view_->EndDrag(true);
326
327 // Now drag to the left edge and test the other direction.
328 to.set_x(0);
329
330 SimulateDrag(AppsGridView::MOUSE, from, to);
331
332 EXPECT_TRUE(page_flip_waiter.Wait(100));
333 EXPECT_EQ(1, pagination_model_->selected_page());
334
335 EXPECT_TRUE(page_flip_waiter.Wait(100));
336 EXPECT_EQ(0, pagination_model_->selected_page());
337
338 EXPECT_FALSE(page_flip_waiter.Wait(100));
339 EXPECT_EQ(0, pagination_model_->selected_page());
340 apps_grid_view_->EndDrag(true);
341 }
342
343 TEST_F(AppsGridViewTest, SimultaneousDrag) {
344 const int kTotalItems = 4;
345 PopulateApps(kTotalItems);
346 EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
347 GetModelContent());
348
349 gfx::Point mouse_from = GetItemTileRectAt(0, 0).CenterPoint();
350 gfx::Point mouse_to = GetItemTileRectAt(0, 1).CenterPoint();
351
352 gfx::Point touch_from = GetItemTileRectAt(1, 0).CenterPoint();
353 gfx::Point touch_to = GetItemTileRectAt(1, 1).CenterPoint();
354
355 // Starts a mouse drag first then a touch drag.
356 SimulateDrag(AppsGridView::MOUSE, mouse_from, mouse_to);
357 SimulateDrag(AppsGridView::TOUCH, touch_from, touch_to);
358 // Finishes the drag and mouse drag wins.
359 apps_grid_view_->EndDrag(false);
360 EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"),
361 GetModelContent());
362 test_api_->LayoutToIdealBounds();
363
364 // Starts a touch drag first then a mouse drag.
365 SimulateDrag(AppsGridView::TOUCH, touch_from, touch_to);
366 SimulateDrag(AppsGridView::MOUSE, mouse_from, mouse_to);
367 // Finishes the drag and touch drag wins.
368 apps_grid_view_->EndDrag(false);
369 EXPECT_EQ(std::string("Item 1,Item 0,Item 3,Item 2"),
370 GetModelContent());
371 test_api_->LayoutToIdealBounds();
372 }
373
374 TEST_F(AppsGridViewTest, HighlightWithKeyboard) {
375 const int kTotalitems = 2;
376 PopulateApps(kTotalitems);
377 apps_grid_view_->SetSelectedView(GetItemViewAt(0));
378
379 // Try moving off the item to an invalid location.
380 SimulateKeyPress(ui::VKEY_UP);
381 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(0)));
382 SimulateKeyPress(ui::VKEY_DOWN);
383 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(0)));
384 SimulateKeyPress(ui::VKEY_LEFT);
385 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(0)));
386
387 // Move to the second item and try to go past it.
388 SimulateKeyPress(ui::VKEY_RIGHT);
389 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(1)));
390 SimulateKeyPress(ui::VKEY_RIGHT);
391 EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(1)));
392 }
393
394 } // namespace test
395 } // namespace app_list
OLDNEW
« no previous file with comments | « ui/app_list/apps_grid_view.cc ('k') | ui/app_list/cocoa/app_list_view_window.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698