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

Side by Side Diff: ui/app_list/cocoa/apps_grid_controller_unittest.mm

Issue 2131463002: Purge the App Launcher code from Mac (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Zap mac-specific icon assets Created 4 years, 5 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
OLDNEW
(Empty)
1 // Copyright 2013 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 <stddef.h>
6
7 #include "base/mac/foundation_util.h"
8 #include "base/mac/scoped_nsobject.h"
9 #include "base/macros.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "skia/ext/skia_utils_mac.h"
12 #import "testing/gtest_mac.h"
13 #include "ui/app_list/app_list_constants.h"
14 #include "ui/app_list/app_list_item.h"
15 #import "ui/app_list/cocoa/apps_collection_view_drag_manager.h"
16 #import "ui/app_list/cocoa/apps_grid_controller.h"
17 #import "ui/app_list/cocoa/apps_grid_view_item.h"
18 #import "ui/app_list/cocoa/apps_pagination_model_observer.h"
19 #import "ui/app_list/cocoa/test/apps_grid_controller_test_helper.h"
20 #include "ui/app_list/test/app_list_test_model.h"
21 #include "ui/app_list/test/app_list_test_view_delegate.h"
22 #include "ui/base/models/simple_menu_model.h"
23 #import "ui/events/test/cocoa_test_event_utils.h"
24
25 @interface TestPaginationObserver : NSObject<AppsPaginationModelObserver> {
26 @private
27 NSInteger hoveredSegmentForTest_;
28 int totalPagesChangedCount_;
29 int selectedPageChangedCount_;
30 int lastNewSelectedPage_;
31 bool visibilityDidChange_;
32 }
33
34 @property(assign, nonatomic) NSInteger hoveredSegmentForTest;
35 @property(assign, nonatomic) int totalPagesChangedCount;
36 @property(assign, nonatomic) int selectedPageChangedCount;
37 @property(assign, nonatomic) int lastNewSelectedPage;
38
39 - (bool)readVisibilityDidChange;
40
41 @end
42
43 @implementation TestPaginationObserver
44
45 @synthesize hoveredSegmentForTest = hoveredSegmentForTest_;
46 @synthesize totalPagesChangedCount = totalPagesChangedCount_;
47 @synthesize selectedPageChangedCount = selectedPageChangedCount_;
48 @synthesize lastNewSelectedPage = lastNewSelectedPage_;
49
50 - (id)init {
51 if ((self = [super init]))
52 hoveredSegmentForTest_ = -1;
53
54 return self;
55 }
56
57 - (bool)readVisibilityDidChange {
58 bool truth = visibilityDidChange_;
59 visibilityDidChange_ = false;
60 return truth;
61 }
62
63 - (void)totalPagesChanged {
64 ++totalPagesChangedCount_;
65 }
66
67 - (void)selectedPageChanged:(int)newSelected {
68 ++selectedPageChangedCount_;
69 lastNewSelectedPage_ = newSelected;
70 }
71
72 - (void)pageVisibilityChanged {
73 visibilityDidChange_ = true;
74 }
75
76 - (NSInteger)pagerSegmentAtLocation:(NSPoint)locationInWindow {
77 return hoveredSegmentForTest_;
78 }
79
80 @end
81
82 namespace app_list {
83 namespace test {
84
85 namespace {
86
87 class AppsGridControllerTest : public AppsGridControllerTestHelper {
88 public:
89 AppsGridControllerTest() {}
90
91 AppListTestViewDelegate* delegate() {
92 return owned_delegate_.get();
93 }
94
95 NSColor* ButtonTitleColorAt(size_t index) {
96 NSDictionary* attributes =
97 [[[GetItemViewAt(index) cell] attributedTitle] attributesAtIndex:0
98 effectiveRange:NULL];
99 return [attributes objectForKey:NSForegroundColorAttributeName];
100 }
101
102 void SetUp() override {
103 owned_apps_grid_controller_.reset([[AppsGridController alloc] init]);
104 owned_delegate_.reset(new AppListTestViewDelegate);
105 [owned_apps_grid_controller_ setDelegate:owned_delegate_.get()];
106 AppsGridControllerTestHelper::SetUpWithGridController(
107 owned_apps_grid_controller_.get());
108
109 [[test_window() contentView] addSubview:[apps_grid_controller_ view]];
110 [test_window() makePretendKeyWindowAndSetFirstResponder:
111 [apps_grid_controller_ collectionViewAtPageIndex:0]];
112 }
113
114 void TearDown() override {
115 [owned_apps_grid_controller_ setDelegate:NULL];
116 owned_apps_grid_controller_.reset();
117 AppsGridControllerTestHelper::TearDown();
118 }
119
120 void ReplaceTestModel(int item_count) {
121 // Clear the delegate before reseting and destroying the model.
122 [owned_apps_grid_controller_ setDelegate:NULL];
123
124 owned_delegate_->ReplaceTestModel(item_count);
125 [owned_apps_grid_controller_ setDelegate:owned_delegate_.get()];
126 }
127
128 AppListTestModel* model() { return owned_delegate_->GetTestModel(); }
129
130 private:
131 base::scoped_nsobject<AppsGridController> owned_apps_grid_controller_;
132 std::unique_ptr<AppListTestViewDelegate> owned_delegate_;
133
134 DISALLOW_COPY_AND_ASSIGN(AppsGridControllerTest);
135 };
136
137 class AppListItemWithMenu : public AppListItem {
138 public:
139 explicit AppListItemWithMenu(const std::string& id)
140 : AppListItem(id),
141 menu_model_(NULL),
142 menu_ready_(true) {
143 SetName(id);
144 menu_model_.AddItem(0, base::UTF8ToUTF16("Menu For: " + id));
145 }
146
147 void SetMenuReadyForTesting(bool ready) {
148 menu_ready_ = ready;
149 }
150
151 ui::MenuModel* GetContextMenuModel() override {
152 if (!menu_ready_)
153 return NULL;
154
155 return &menu_model_;
156 }
157
158 private:
159 ui::SimpleMenuModel menu_model_;
160 bool menu_ready_;
161
162 DISALLOW_COPY_AND_ASSIGN(AppListItemWithMenu);
163 };
164
165 // Generate a mouse event at the centre of the view in |page| with the given
166 // |index_in_page| that can be used to initiate, update and complete drag
167 // operations.
168 NSEvent* MouseEventInCell(NSCollectionView* page, size_t index_in_page) {
169 NSRect cell_rect = [page frameForItemAtIndex:index_in_page];
170 NSPoint point_in_view = NSMakePoint(NSMidX(cell_rect), NSMidY(cell_rect));
171 NSPoint point_in_window = [page convertPoint:point_in_view
172 toView:nil];
173 return cocoa_test_event_utils::LeftMouseDownAtPoint(point_in_window);
174 }
175
176 NSEvent* MouseEventForScroll(NSView* view, CGFloat relative_x) {
177 NSRect view_rect = [view frame];
178 NSPoint point_in_view = NSMakePoint(NSMidX(view_rect), NSMidY(view_rect));
179 point_in_view.x += point_in_view.x * relative_x;
180 NSPoint point_in_window = [view convertPoint:point_in_view
181 toView:nil];
182 return cocoa_test_event_utils::LeftMouseDownAtPoint(point_in_window);
183 }
184
185 } // namespace
186
187 TEST_VIEW(AppsGridControllerTest, [apps_grid_controller_ view]);
188
189 // Test showing with an empty model.
190 TEST_F(AppsGridControllerTest, EmptyModelAndShow) {
191 EXPECT_TRUE([[apps_grid_controller_ view] superview]);
192
193 // First page should always exist, even if empty.
194 EXPECT_EQ(1u, [apps_grid_controller_ pageCount]);
195 EXPECT_EQ(0u, [[GetPageAt(0) content] count]);
196 EXPECT_TRUE([GetPageAt(0) superview]); // The pages container.
197 EXPECT_TRUE([[GetPageAt(0) superview] superview]);
198 }
199
200 // Test with a single item.
201 // This test is disabled in builders until the delay to wait for the collection
202 // view to load subviews can be removed, or some other solution is found.
203 TEST_F(AppsGridControllerTest, DISABLED_SingleEntryModel) {
204 // We need to "wake up" the NSCollectionView, otherwise it does not
205 // immediately update its subviews later in this function.
206 // When this test is run by itself, it's enough just to send a keypress (and
207 // this delay is not needed).
208 DelayForCollectionView();
209 EXPECT_EQ(1u, [apps_grid_controller_ pageCount]);
210 EXPECT_EQ(0u, [[GetPageAt(0) content] count]);
211
212 model()->PopulateApps(1);
213 SinkEvents();
214 EXPECT_FALSE([GetPageAt(0) animations]);
215
216 EXPECT_EQ(1u, [[GetPageAt(0) content] count]);
217 NSArray* subviews = [GetPageAt(0) subviews];
218 EXPECT_EQ(1u, [subviews count]);
219
220 // Note that using GetItemViewAt(0) here also works, and returns non-nil even
221 // without the delay, but a "click" on it does not register without the delay.
222 NSView* subview = [subviews objectAtIndex:0];
223
224 // Launch the item.
225 SimulateClick(subview);
226 SinkEvents();
227 EXPECT_EQ(1, model()->activate_count());
228 ASSERT_TRUE(model()->last_activated());
229 EXPECT_EQ(std::string("Item 0"), model()->last_activated()->name());
230 }
231
232 // Test activating an item on the second page (the 17th item).
233 TEST_F(AppsGridControllerTest, DISABLED_TwoPageModel) {
234 DelayForCollectionView();
235 ReplaceTestModel(kItemsPerPage * 2);
236 [apps_grid_controller_ scrollToPage:1];
237
238 // The NSScrollView animator ignores the duration configured on the
239 // NSAnimationContext (set by CocoaTest::Init), so we need to delay here.
240 DelayForCollectionView();
241 NSArray* subviews = [GetPageAt(1) subviews];
242 NSView* subview = [subviews objectAtIndex:0];
243 // Launch the item.
244 SimulateClick(subview);
245 SinkEvents();
246 EXPECT_EQ(1, model()->activate_count());
247 ASSERT_TRUE(model()->last_activated());
248 EXPECT_EQ(std::string("Item 16"), model()->last_activated()->name());
249 }
250
251 // Test setModel.
252 TEST_F(AppsGridControllerTest, ReplaceModel) {
253 const size_t kOrigItems = 1;
254 const size_t kNewItems = 2;
255
256 model()->PopulateApps(kOrigItems);
257 EXPECT_EQ(kOrigItems, [[GetPageAt(0) content] count]);
258
259 ReplaceTestModel(kNewItems);
260 EXPECT_EQ(kNewItems, [[GetPageAt(0) content] count]);
261 }
262
263 // Test pagination.
264 TEST_F(AppsGridControllerTest, Pagination) {
265 model()->PopulateApps(1);
266 EXPECT_EQ(1u, [apps_grid_controller_ pageCount]);
267 EXPECT_EQ(1u, [[GetPageAt(0) content] count]);
268
269 ReplaceTestModel(kItemsPerPage);
270 EXPECT_EQ(1u, [apps_grid_controller_ pageCount]);
271 EXPECT_EQ(kItemsPerPage, [[GetPageAt(0) content] count]);
272
273 // Test adding an item onto the next page.
274 model()->PopulateApps(1); // Now 17 items.
275 EXPECT_EQ(2u, [apps_grid_controller_ pageCount]);
276 EXPECT_EQ(kItemsPerPage, [[GetPageAt(0) content] count]);
277 EXPECT_EQ(1u, [[GetPageAt(1) content] count]);
278
279 // Test N pages with the last page having one empty spot.
280 const size_t kPagesToTest = 3;
281 ReplaceTestModel(kPagesToTest * kItemsPerPage - 1);
282 EXPECT_EQ(kPagesToTest, [apps_grid_controller_ pageCount]);
283 for (size_t page_index = 0; page_index < kPagesToTest - 1; ++page_index) {
284 EXPECT_EQ(kItemsPerPage, [[GetPageAt(page_index) content] count]);
285 }
286 EXPECT_EQ(kItemsPerPage - 1, [[GetPageAt(kPagesToTest - 1) content] count]);
287
288 // Test removing pages.
289 ReplaceTestModel(1);
290 EXPECT_EQ(1u, [apps_grid_controller_ pageCount]);
291 EXPECT_EQ(1u, [[GetPageAt(0) content] count]);
292 }
293
294 // Tests basic keyboard navigation on the first page.
295 TEST_F(AppsGridControllerTest, FirstPageKeyboardNavigation) {
296 model()->PopulateApps(kItemsPerPage - 2);
297 EXPECT_EQ(kItemsPerPage - 2, [[GetPageAt(0) content] count]);
298
299 SimulateKeyAction(@selector(moveRight:));
300 EXPECT_EQ(0u, [apps_grid_controller_ selectedItemIndex]);
301
302 SimulateKeyAction(@selector(moveRight:));
303 EXPECT_EQ(1u, [apps_grid_controller_ selectedItemIndex]);
304
305 SimulateKeyAction(@selector(moveDown:));
306 EXPECT_EQ(5u, [apps_grid_controller_ selectedItemIndex]);
307
308 SimulateKeyAction(@selector(moveLeft:));
309 EXPECT_EQ(4u, [apps_grid_controller_ selectedItemIndex]);
310
311 SimulateKeyAction(@selector(moveUp:));
312 EXPECT_EQ(0u, [apps_grid_controller_ selectedItemIndex]);
313
314 // Go to the third item, and launch it.
315 SimulateKeyAction(@selector(moveRight:));
316 SimulateKeyAction(@selector(moveRight:));
317 EXPECT_EQ(2u, [apps_grid_controller_ selectedItemIndex]);
318 SimulateKeyAction(@selector(insertNewline:));
319 EXPECT_EQ(1, model()->activate_count());
320 ASSERT_TRUE(model()->last_activated());
321 EXPECT_EQ(std::string("Item 2"), model()->last_activated()->name());
322 }
323
324 // Tests keyboard navigation across pages.
325 TEST_F(AppsGridControllerTest, CrossPageKeyboardNavigation) {
326 model()->PopulateApps(kItemsPerPage + 10);
327 EXPECT_EQ(kItemsPerPage, [[GetPageAt(0) content] count]);
328 EXPECT_EQ(10u, [[GetPageAt(1) content] count]);
329
330 // Moving Left, Up, or PageUp from the top-left corner of the first page does
331 // nothing.
332 [apps_grid_controller_ selectItemAtIndex:0];
333 SimulateKeyAction(@selector(moveLeft:));
334 EXPECT_EQ(0u, [apps_grid_controller_ selectedItemIndex]);
335 SimulateKeyAction(@selector(moveUp:));
336 EXPECT_EQ(0u, [apps_grid_controller_ selectedItemIndex]);
337 SimulateKeyAction(@selector(scrollPageUp:));
338 EXPECT_EQ(0u, [apps_grid_controller_ selectedItemIndex]);
339
340 // Moving Right from the right side goes to the next page. Moving Left goes
341 // back to the first page.
342 [apps_grid_controller_ selectItemAtIndex:3];
343 SimulateKeyAction(@selector(moveRight:));
344 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
345 EXPECT_EQ(kItemsPerPage, [apps_grid_controller_ selectedItemIndex]);
346 SimulateKeyAction(@selector(moveLeft:));
347 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
348 EXPECT_EQ(3u, [apps_grid_controller_ selectedItemIndex]);
349
350 // Moving Down from the bottom does nothing.
351 [apps_grid_controller_ selectItemAtIndex:13];
352 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
353 SimulateKeyAction(@selector(moveDown:));
354 EXPECT_EQ(13u, [apps_grid_controller_ selectedItemIndex]);
355
356 // Moving Right into a non-existent square on the next page will select the
357 // last item.
358 [apps_grid_controller_ selectItemAtIndex:15];
359 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
360 SimulateKeyAction(@selector(moveRight:));
361 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
362 EXPECT_EQ(kItemsPerPage + 9, [apps_grid_controller_ selectedItemIndex]);
363
364 // PageDown and PageUp switches pages while maintaining the same selection
365 // position.
366 [apps_grid_controller_ selectItemAtIndex:6];
367 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
368 SimulateKeyAction(@selector(scrollPageDown:));
369 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
370 EXPECT_EQ(kItemsPerPage + 6, [apps_grid_controller_ selectedItemIndex]);
371 SimulateKeyAction(@selector(scrollPageUp:));
372 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
373 EXPECT_EQ(6u, [apps_grid_controller_ selectedItemIndex]);
374
375 // PageDown into a non-existent square on the next page will select the last
376 // item.
377 [apps_grid_controller_ selectItemAtIndex:11];
378 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
379 SimulateKeyAction(@selector(scrollPageDown:));
380 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
381 EXPECT_EQ(kItemsPerPage + 9, [apps_grid_controller_ selectedItemIndex]);
382
383 // Moving Right, Down, or PageDown from the bottom-right corner of the last
384 // page (not the last item) does nothing.
385 [apps_grid_controller_ selectItemAtIndex:kItemsPerPage + 9];
386 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
387 SimulateKeyAction(@selector(moveRight:));
388 EXPECT_EQ(kItemsPerPage + 9, [apps_grid_controller_ selectedItemIndex]);
389 SimulateKeyAction(@selector(moveDown:));
390 EXPECT_EQ(kItemsPerPage + 9, [apps_grid_controller_ selectedItemIndex]);
391 SimulateKeyAction(@selector(scrollPageDown:));
392 EXPECT_EQ(kItemsPerPage + 9, [apps_grid_controller_ selectedItemIndex]);
393
394 // After page switch, arrow keys select first item on current page.
395 [apps_grid_controller_ scrollToPage:0];
396 [apps_grid_controller_ scrollToPage:1];
397 EXPECT_EQ(static_cast<NSUInteger>(NSNotFound),
398 [apps_grid_controller_ selectedItemIndex]);
399 SimulateKeyAction(@selector(moveUp:));
400 EXPECT_EQ(kItemsPerPage, [apps_grid_controller_ selectedItemIndex]);
401 }
402
403 // Highlighting an item should cause the page it's on to be visible.
404 TEST_F(AppsGridControllerTest, EnsureHighlightedVisible) {
405 model()->PopulateApps(3 * kItemsPerPage);
406 EXPECT_EQ(kItemsPerPage, [[GetPageAt(2) content] count]);
407
408 // First and last items of first page.
409 [apps_grid_controller_ selectItemAtIndex:0];
410 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
411 [apps_grid_controller_ selectItemAtIndex:kItemsPerPage - 1];
412 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
413
414 // First item of second page.
415 [apps_grid_controller_ selectItemAtIndex:kItemsPerPage + 1];
416 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
417
418 // Last item in model.
419 [apps_grid_controller_ selectItemAtIndex:3 * kItemsPerPage - 1];
420 EXPECT_EQ(2u, [apps_grid_controller_ visiblePage]);
421 }
422
423 // Test runtime updates: adding items, removing items, and moving items (e.g. in
424 // response to app install, uninstall, and chrome sync changes. Also test
425 // changing titles and icons.
426 TEST_F(AppsGridControllerTest, ModelUpdate) {
427 model()->PopulateApps(2);
428 EXPECT_EQ(2u, [[GetPageAt(0) content] count]);
429 EXPECT_EQ(std::string("|Item 0,Item 1|"), GetViewContent());
430
431 // Add an item (PopulateApps will create a new "Item 2").
432 model()->PopulateApps(1);
433 EXPECT_EQ(3u, [[GetPageAt(0) content] count]);
434 NSButton* button = GetItemViewAt(2);
435 EXPECT_NSEQ(@"Item 2", [button title]);
436 EXPECT_EQ(std::string("|Item 0,Item 1,Item 2|"), GetViewContent());
437
438 // Update the title via the ItemModelObserver.
439 app_list::AppListItem* item_model =
440 model()->top_level_item_list()->item_at(2);
441 model()->SetItemName(item_model, "UpdatedItem");
442 EXPECT_NSEQ(@"UpdatedItem", [button title]);
443
444 // Test icon updates through the model observer by ensuring the icon changes.
445 item_model->SetIcon(gfx::ImageSkia());
446 NSSize icon_size = [[button image] size];
447 EXPECT_EQ(0, icon_size.width);
448 EXPECT_EQ(0, icon_size.height);
449
450 SkBitmap bitmap;
451 const int kTestImageSize = 10;
452 const int kTargetImageSize = 48;
453 bitmap.setInfo(SkImageInfo::MakeN32Premul(kTestImageSize, kTestImageSize));
454 item_model->SetIcon(gfx::ImageSkia::CreateFrom1xBitmap(bitmap));
455 icon_size = [[button image] size];
456 // Icon should always be resized to 48x48.
457 EXPECT_EQ(kTargetImageSize, icon_size.width);
458 EXPECT_EQ(kTargetImageSize, icon_size.height);
459 }
460
461 TEST_F(AppsGridControllerTest, ModelAdd) {
462 model()->PopulateApps(2);
463 EXPECT_EQ(2u, [[GetPageAt(0) content] count]);
464 EXPECT_EQ(std::string("|Item 0,Item 1|"), GetViewContent());
465
466 app_list::AppListItemList* item_list = model()->top_level_item_list();
467
468 model()->CreateAndAddItem("Item 2");
469 ASSERT_EQ(3u, item_list->item_count());
470 EXPECT_EQ(3u, [apps_grid_controller_ itemCount]);
471 EXPECT_EQ(std::string("|Item 0,Item 1,Item 2|"), GetViewContent());
472
473 // Test adding an item whose position is in the middle.
474 app_list::AppListItem* item0 = item_list->item_at(0);
475 app_list::AppListItem* item1 = item_list->item_at(1);
476 app_list::AppListItem* item3 = model()->CreateItem("Item Three");
477 model()->AddItem(item3);
478 item_list->SetItemPosition(
479 item3, item0->position().CreateBetween(item1->position()));
480 EXPECT_EQ(4u, [apps_grid_controller_ itemCount]);
481 EXPECT_EQ(std::string("|Item 0,Item Three,Item 1,Item 2|"), GetViewContent());
482 }
483
484 TEST_F(AppsGridControllerTest, ModelMove) {
485 model()->PopulateApps(3);
486 EXPECT_EQ(3u, [[GetPageAt(0) content] count]);
487 EXPECT_EQ(std::string("|Item 0,Item 1,Item 2|"), GetViewContent());
488
489 // Test swapping items (e.g. rearranging via sync).
490 model()->top_level_item_list()->MoveItem(1, 2);
491 EXPECT_EQ(std::string("|Item 0,Item 2,Item 1|"), GetViewContent());
492 }
493
494 TEST_F(AppsGridControllerTest, ModelRemove) {
495 model()->PopulateApps(3);
496 EXPECT_EQ(3u, [[GetPageAt(0) content] count]);
497 EXPECT_EQ(std::string("|Item 0,Item 1,Item 2|"), GetViewContent());
498
499 // Test removing an item at the end.
500 model()->DeleteItem("Item 2");
501 EXPECT_EQ(2u, [apps_grid_controller_ itemCount]);
502 EXPECT_EQ(std::string("|Item 0,Item 1|"), GetViewContent());
503
504 // Test removing in the middle.
505 model()->CreateAndAddItem("Item 2");
506 EXPECT_EQ(3u, [apps_grid_controller_ itemCount]);
507 EXPECT_EQ(std::string("|Item 0,Item 1,Item 2|"), GetViewContent());
508 model()->DeleteItem("Item 1");
509 EXPECT_EQ(2u, [apps_grid_controller_ itemCount]);
510 EXPECT_EQ(std::string("|Item 0,Item 2|"), GetViewContent());
511 }
512
513 TEST_F(AppsGridControllerTest, ModelRemoveSeveral) {
514 model()->PopulateApps(3);
515 EXPECT_EQ(3u, [[GetPageAt(0) content] count]);
516 EXPECT_EQ(std::string("|Item 0,Item 1,Item 2|"), GetViewContent());
517
518 // Test removing multiple items via the model.
519 model()->DeleteItem("Item 0");
520 model()->DeleteItem("Item 1");
521 model()->DeleteItem("Item 2");
522 EXPECT_EQ(0u, [apps_grid_controller_ itemCount]);
523 EXPECT_EQ(std::string("||"), GetViewContent());
524 }
525
526 TEST_F(AppsGridControllerTest, ModelRemovePage) {
527 app_list::AppListItemList* item_list = model()->top_level_item_list();
528
529 model()->PopulateApps(kItemsPerPage + 1);
530 ASSERT_EQ(kItemsPerPage + 1, item_list->item_count());
531 EXPECT_EQ(kItemsPerPage + 1, [apps_grid_controller_ itemCount]);
532 EXPECT_EQ(2u, [apps_grid_controller_ pageCount]);
533
534 // Test removing the last item when there is one item on the second page.
535 app_list::AppListItem* last_item = item_list->item_at(kItemsPerPage);
536 model()->DeleteItem(last_item->id());
537 EXPECT_EQ(kItemsPerPage, item_list->item_count());
538 EXPECT_EQ(kItemsPerPage, [apps_grid_controller_ itemCount]);
539 EXPECT_EQ(1u, [apps_grid_controller_ pageCount]);
540 }
541
542 // Test install progress bars, and install flow with item highlighting.
543 TEST_F(AppsGridControllerTest, ItemInstallProgress) {
544 ReplaceTestModel(kItemsPerPage + 1);
545 EXPECT_EQ(2u, [apps_grid_controller_ pageCount]);
546 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
547 // The single item on the second page.
548 int kTestItemIndex = kItemsPerPage;
549 app_list::AppListItem* item_model =
550 model()->top_level_item_list()->item_at(kTestItemIndex);
551
552 // Highlighting an item should activate the page it is on.
553 model()->HighlightItemAt(kTestItemIndex);
554 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
555
556 // Starting install should add a progress bar, and temporarily clear the
557 // button title.
558 NSButton* button = GetItemViewAt(kTestItemIndex);
559 NSView* containerView = [button superview];
560 EXPECT_EQ(1u, [[containerView subviews] count]);
561 EXPECT_NSEQ(@"Item 16", [button title]);
562 model()->HighlightItemAt(kTestItemIndex);
563 item_model->SetIsInstalling(true);
564 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
565
566 EXPECT_EQ(2u, [[containerView subviews] count]);
567 EXPECT_NSEQ(@"", [button title]);
568 NSProgressIndicator* progressIndicator =
569 [[containerView subviews] objectAtIndex:1];
570 EXPECT_FALSE([progressIndicator isIndeterminate]);
571 EXPECT_EQ(0.0, [progressIndicator doubleValue]);
572
573 // Updating the progress in the model should update the progress bar.
574 item_model->SetPercentDownloaded(50);
575 EXPECT_EQ(50.0, [progressIndicator doubleValue]);
576
577 // Two things can be installing simultaneously. When one starts or completes
578 // the model builder will ask for the item to be highlighted.
579 const int kAlternateTestItemIndex = 0;
580 model()->HighlightItemAt(kAlternateTestItemIndex);
581 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
582
583 // Update the first item (page doesn't change on updates).
584 item_model->SetPercentDownloaded(100);
585 EXPECT_EQ(100.0, [progressIndicator doubleValue]);
586 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
587
588 // A percent of -1 indicates the download is complete and the unpack/install
589 // process has started.
590 item_model->SetPercentDownloaded(-1);
591 EXPECT_TRUE([progressIndicator isIndeterminate]);
592
593 // Completing install removes the progress bar, and restores the title.
594 // ExtensionAppModelBuilder will reload the ExtensionAppItem, which also
595 // highlights. Do the same here.
596 model()->HighlightItemAt(kTestItemIndex);
597 item_model->SetIsInstalling(false);
598 EXPECT_EQ(1u, [[containerView subviews] count]);
599 EXPECT_NSEQ(@"Item 16", [button title]);
600 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
601
602 // Things should cleanup OK with |alternate_item_model| left installing.
603 }
604
605 // Test mouseover selection.
606 TEST_F(AppsGridControllerTest, MouseoverSelects) {
607 model()->PopulateApps(2);
608 EXPECT_EQ(nil, GetSelectedView());
609
610 // Test entering and exiting the first item.
611 SimulateMouseEnterItemAt(0);
612 EXPECT_EQ(GetItemViewAt(0), GetSelectedView());
613 SimulateMouseExitItemAt(0);
614 EXPECT_EQ(nil, GetSelectedView());
615
616 // AppKit doesn't guarantee the order, so test moving between items.
617 SimulateMouseEnterItemAt(0);
618 EXPECT_EQ(GetItemViewAt(0), GetSelectedView());
619 SimulateMouseEnterItemAt(1);
620 EXPECT_EQ(GetItemViewAt(1), GetSelectedView());
621 SimulateMouseExitItemAt(0);
622 EXPECT_EQ(GetItemViewAt(1), GetSelectedView());
623 SimulateMouseExitItemAt(1);
624 EXPECT_EQ(nil, GetSelectedView());
625 }
626
627 // Test AppsGridPaginationObserver totalPagesChanged().
628 TEST_F(AppsGridControllerTest, PaginationObserverPagesChanged) {
629 base::scoped_nsobject<TestPaginationObserver> observer(
630 [[TestPaginationObserver alloc] init]);
631 [apps_grid_controller_ setPaginationObserver:observer];
632
633 // Test totalPagesChanged.
634 model()->PopulateApps(kItemsPerPage);
635 EXPECT_EQ(0, [observer totalPagesChangedCount]);
636 EXPECT_EQ(1u, [apps_grid_controller_ pageCount]);
637 model()->PopulateApps(1);
638 EXPECT_EQ(1, [observer totalPagesChangedCount]);
639 EXPECT_EQ(2u, [apps_grid_controller_ pageCount]);
640 ReplaceTestModel(0);
641 EXPECT_EQ(2, [observer totalPagesChangedCount]);
642 EXPECT_EQ(1u, [apps_grid_controller_ pageCount]);
643 ReplaceTestModel(kItemsPerPage * 3 + 1);
644 EXPECT_EQ(3, [observer totalPagesChangedCount]);
645 EXPECT_EQ(4u, [apps_grid_controller_ pageCount]);
646
647 EXPECT_FALSE([observer readVisibilityDidChange]);
648 EXPECT_EQ(0, [observer selectedPageChangedCount]);
649
650 [apps_grid_controller_ setPaginationObserver:nil];
651 }
652
653 // Test AppsGridPaginationObserver selectedPageChanged().
654 TEST_F(AppsGridControllerTest, PaginationObserverSelectedPageChanged) {
655 base::scoped_nsobject<TestPaginationObserver> observer(
656 [[TestPaginationObserver alloc] init]);
657 [apps_grid_controller_ setPaginationObserver:observer];
658 EXPECT_EQ(0, [[NSAnimationContext currentContext] duration]);
659
660 ReplaceTestModel(kItemsPerPage * 3 + 1);
661 EXPECT_EQ(1, [observer totalPagesChangedCount]);
662 EXPECT_EQ(4u, [apps_grid_controller_ pageCount]);
663
664 EXPECT_FALSE([observer readVisibilityDidChange]);
665 EXPECT_EQ(0, [observer selectedPageChangedCount]);
666
667 [apps_grid_controller_ scrollToPage:1];
668 EXPECT_EQ(1, [observer selectedPageChangedCount]);
669 EXPECT_EQ(1, [observer lastNewSelectedPage]);
670 EXPECT_TRUE([observer readVisibilityDidChange]);
671 EXPECT_FALSE([observer readVisibilityDidChange]); // Testing test behaviour.
672 EXPECT_EQ(0.0, [apps_grid_controller_ visiblePortionOfPage:0]);
673 EXPECT_EQ(1.0, [apps_grid_controller_ visiblePortionOfPage:1]);
674 EXPECT_EQ(0.0, [apps_grid_controller_ visiblePortionOfPage:2]);
675 EXPECT_EQ(0.0, [apps_grid_controller_ visiblePortionOfPage:3]);
676
677 [apps_grid_controller_ scrollToPage:0];
678 EXPECT_EQ(2, [observer selectedPageChangedCount]);
679 EXPECT_EQ(0, [observer lastNewSelectedPage]);
680 EXPECT_TRUE([observer readVisibilityDidChange]);
681 EXPECT_EQ(1.0, [apps_grid_controller_ visiblePortionOfPage:0]);
682 EXPECT_EQ(0.0, [apps_grid_controller_ visiblePortionOfPage:1]);
683
684 [apps_grid_controller_ scrollToPage:3];
685 // Note: with no animations, there is only a single page change. However, with
686 // animations we expect multiple updates depending on the rate that the scroll
687 // view updates and sends out NSViewBoundsDidChangeNotification.
688 EXPECT_EQ(3, [observer selectedPageChangedCount]);
689 EXPECT_EQ(3, [observer lastNewSelectedPage]);
690 EXPECT_TRUE([observer readVisibilityDidChange]);
691 EXPECT_EQ(0.0, [apps_grid_controller_ visiblePortionOfPage:0]);
692 EXPECT_EQ(1.0, [apps_grid_controller_ visiblePortionOfPage:3]);
693
694 [apps_grid_controller_ setPaginationObserver:nil];
695 }
696
697 // Test basic item moves with two items; swapping them around, dragging outside
698 // of the view bounds, and dragging on the background.
699 TEST_F(AppsGridControllerTest, DragAndDropSimple) {
700 model()->PopulateApps(2);
701 NSCollectionView* page = [apps_grid_controller_ collectionViewAtPageIndex:0];
702 NSEvent* mouse_at_cell_0 = MouseEventInCell(page, 0);
703 NSEvent* mouse_at_cell_1 = MouseEventInCell(page, 1);
704 NSEvent* mouse_at_page_centre = MouseEventInCell(page, 6);
705 NSEvent* mouse_off_page = MouseEventInCell(page, kItemsPerPage * 2);
706
707 const std::string kOrdered = "Item 0,Item 1";
708 const std::string kSwapped = "Item 1,Item 0";
709 const std::string kOrderedView = "|Item 0,Item 1|";
710 const std::string kSwappedView = "|Item 1,Item 0|";
711
712 EXPECT_EQ(kOrdered, model()->GetModelContent());
713 EXPECT_EQ(kOrderedView, GetViewContent());
714 AppsCollectionViewDragManager* drag_manager =
715 [apps_grid_controller_ dragManager];
716
717 // Drag first item over the second item and release.
718 [drag_manager onMouseDownInPage:page
719 withEvent:mouse_at_cell_0];
720 [drag_manager onMouseDragged:mouse_at_cell_1];
721 EXPECT_EQ(kOrdered, model()->GetModelContent());
722 EXPECT_EQ(kSwappedView, GetViewContent()); // View swaps first.
723 [drag_manager onMouseUp:mouse_at_cell_1];
724 EXPECT_EQ(kSwapped, model()->GetModelContent());
725 EXPECT_EQ(kSwappedView, GetViewContent());
726
727 // Drag item back.
728 [drag_manager onMouseDownInPage:page
729 withEvent:mouse_at_cell_1];
730 [drag_manager onMouseDragged:mouse_at_cell_0];
731 EXPECT_EQ(kSwapped, model()->GetModelContent());
732 EXPECT_EQ(kOrderedView, GetViewContent());
733 [drag_manager onMouseUp:mouse_at_cell_0];
734 EXPECT_EQ(kOrdered, model()->GetModelContent());
735 EXPECT_EQ(kOrderedView, GetViewContent());
736
737 // Drag first item to centre of view (should put in last place).
738 [drag_manager onMouseDownInPage:page
739 withEvent:mouse_at_cell_0];
740 [drag_manager onMouseDragged:mouse_at_page_centre];
741 EXPECT_EQ(kOrdered, model()->GetModelContent());
742 EXPECT_EQ(kSwappedView, GetViewContent());
743 [drag_manager onMouseUp:mouse_at_page_centre];
744 EXPECT_EQ(kSwapped, model()->GetModelContent());
745 EXPECT_EQ(kSwappedView, GetViewContent());
746
747 // Drag item to centre again (should leave it in the last place).
748 [drag_manager onMouseDownInPage:page
749 withEvent:mouse_at_cell_1];
750 [drag_manager onMouseDragged:mouse_at_page_centre];
751 EXPECT_EQ(kSwapped, model()->GetModelContent());
752 EXPECT_EQ(kSwappedView, GetViewContent());
753 [drag_manager onMouseUp:mouse_at_page_centre];
754 EXPECT_EQ(kSwapped, model()->GetModelContent());
755 EXPECT_EQ(kSwappedView, GetViewContent());
756
757 // Drag starting in the centre of the view, should do nothing.
758 [drag_manager onMouseDownInPage:page
759 withEvent:mouse_at_page_centre];
760 [drag_manager onMouseDragged:mouse_at_cell_0];
761 EXPECT_EQ(kSwapped, model()->GetModelContent());
762 EXPECT_EQ(kSwappedView, GetViewContent());
763 [drag_manager onMouseUp:mouse_at_cell_0];
764 EXPECT_EQ(kSwapped, model()->GetModelContent());
765 EXPECT_EQ(kSwappedView, GetViewContent());
766
767 // Click off page.
768 [drag_manager onMouseDownInPage:page
769 withEvent:mouse_off_page];
770 [drag_manager onMouseDragged:mouse_at_cell_0];
771 EXPECT_EQ(kSwapped, model()->GetModelContent());
772 EXPECT_EQ(kSwappedView, GetViewContent());
773 [drag_manager onMouseUp:mouse_at_cell_0];
774 EXPECT_EQ(kSwapped, model()->GetModelContent());
775 EXPECT_EQ(kSwappedView, GetViewContent());
776
777 // Drag to first over second item, then off page.
778 [drag_manager onMouseDownInPage:page
779 withEvent:mouse_at_cell_0];
780 [drag_manager onMouseDragged:mouse_at_cell_1];
781 EXPECT_EQ(kSwapped, model()->GetModelContent());
782 EXPECT_EQ(kOrderedView, GetViewContent());
783 [drag_manager onMouseDragged:mouse_off_page];
784 EXPECT_EQ(kSwapped, model()->GetModelContent());
785 EXPECT_EQ(kOrderedView, GetViewContent());
786 [drag_manager onMouseUp:mouse_off_page];
787 EXPECT_EQ(kOrdered, model()->GetModelContent());
788 EXPECT_EQ(kOrderedView, GetViewContent());
789
790 // Replace with an empty model, and ensure we do not break.
791 ReplaceTestModel(0);
792 EXPECT_EQ(std::string(), model()->GetModelContent());
793 EXPECT_EQ(std::string("||"), GetViewContent());
794 [drag_manager onMouseDownInPage:page
795 withEvent:mouse_at_cell_0];
796 [drag_manager onMouseDragged:mouse_at_cell_1];
797 [drag_manager onMouseUp:mouse_at_cell_1];
798 EXPECT_EQ(std::string(), model()->GetModelContent());
799 EXPECT_EQ(std::string("||"), GetViewContent());
800 }
801
802 // Test item moves between pages.
803 TEST_F(AppsGridControllerTest, DragAndDropMultiPage) {
804 const size_t kPagesToTest = 3;
805 // Put one item on the last page to hit more edge cases.
806 ReplaceTestModel(kItemsPerPage * (kPagesToTest - 1) + 1);
807 NSCollectionView* page[kPagesToTest];
808 for (size_t i = 0; i < kPagesToTest; ++i)
809 page[i] = [apps_grid_controller_ collectionViewAtPageIndex:i];
810
811 const std::string kSecondItemMovedToSecondPage =
812 "|Item 0,Item 2,Item 3,Item 4,Item 5,Item 6,Item 7,Item 8,"
813 "Item 9,Item 10,Item 11,Item 12,Item 13,Item 14,Item 15,Item 16|"
814 "|Item 17,Item 1,Item 18,Item 19,Item 20,Item 21,Item 22,Item 23,"
815 "Item 24,Item 25,Item 26,Item 27,Item 28,Item 29,Item 30,Item 31|"
816 "|Item 32|";
817
818 NSEvent* mouse_at_cell_0 = MouseEventInCell(page[0], 0);
819 NSEvent* mouse_at_cell_1 = MouseEventInCell(page[0], 1);
820 AppsCollectionViewDragManager* drag_manager =
821 [apps_grid_controller_ dragManager];
822 [drag_manager onMouseDownInPage:page[0]
823 withEvent:mouse_at_cell_1];
824
825 // Initiate dragging before changing pages.
826 [drag_manager onMouseDragged:mouse_at_cell_0];
827
828 // Scroll to the second page.
829 [apps_grid_controller_ scrollToPage:1];
830 [drag_manager onMouseDragged:mouse_at_cell_1];
831
832 // Do one exhaustive check, and then spot-check corner cases.
833 EXPECT_EQ(kSecondItemMovedToSecondPage, GetViewContent());
834 EXPECT_EQ(0u, GetPageIndexForItem(0));
835 EXPECT_EQ(1u, GetPageIndexForItem(1));
836 EXPECT_EQ(0u, GetPageIndexForItem(2));
837 EXPECT_EQ(0u, GetPageIndexForItem(16));
838 EXPECT_EQ(1u, GetPageIndexForItem(17));
839 EXPECT_EQ(1u, GetPageIndexForItem(31));
840 EXPECT_EQ(2u, GetPageIndexForItem(32));
841
842 // Scroll to the third page and drag some more.
843 [apps_grid_controller_ scrollToPage:2];
844 [drag_manager onMouseDragged:mouse_at_cell_1];
845 EXPECT_EQ(2u, GetPageIndexForItem(1));
846 EXPECT_EQ(1u, GetPageIndexForItem(31));
847 EXPECT_EQ(1u, GetPageIndexForItem(32));
848
849 // Scroll backwards.
850 [apps_grid_controller_ scrollToPage:1];
851 [drag_manager onMouseDragged:mouse_at_cell_1];
852 EXPECT_EQ(kSecondItemMovedToSecondPage, GetViewContent());
853 EXPECT_EQ(1u, GetPageIndexForItem(1));
854 EXPECT_EQ(1u, GetPageIndexForItem(31));
855 EXPECT_EQ(2u, GetPageIndexForItem(32));
856
857 // Simulate installing an item while dragging (or have it appear during sync).
858 model()->PopulateAppWithId(33);
859 // Item should go back to its position before the drag.
860 EXPECT_EQ(0u, GetPageIndexForItem(1));
861 EXPECT_EQ(1u, GetPageIndexForItem(31));
862 EXPECT_EQ(2u, GetPageIndexForItem(32));
863 // New item should appear at end.
864 EXPECT_EQ(2u, GetPageIndexForItem(33));
865
866 // Scroll to end again, and keep dragging (should be ignored).
867 [apps_grid_controller_ scrollToPage:2];
868 [drag_manager onMouseDragged:mouse_at_cell_0];
869 EXPECT_EQ(0u, GetPageIndexForItem(1));
870 [drag_manager onMouseUp:mouse_at_cell_0];
871 EXPECT_EQ(0u, GetPageIndexForItem(1));
872 }
873
874 // Test scrolling when dragging past edge or over the pager.
875 TEST_F(AppsGridControllerTest, ScrollingWhileDragging) {
876 base::scoped_nsobject<TestPaginationObserver> observer(
877 [[TestPaginationObserver alloc] init]);
878 [apps_grid_controller_ setPaginationObserver:observer];
879
880 ReplaceTestModel(kItemsPerPage * 3);
881 // Start on the middle page.
882 [apps_grid_controller_ scrollToPage:1];
883 NSCollectionView* page = [apps_grid_controller_ collectionViewAtPageIndex:1];
884 NSEvent* mouse_at_cell_0 = MouseEventInCell(page, 0);
885
886 NSEvent* at_center = MouseEventForScroll([apps_grid_controller_ view], 0.0);
887 NSEvent* at_left = MouseEventForScroll([apps_grid_controller_ view], -1.1);
888 NSEvent* at_right = MouseEventForScroll([apps_grid_controller_ view], 1.1);
889
890 AppsCollectionViewDragManager* drag_manager =
891 [apps_grid_controller_ dragManager];
892 [drag_manager onMouseDownInPage:page
893 withEvent:mouse_at_cell_0];
894 [drag_manager onMouseDragged:at_center];
895
896 // Nothing should be scheduled: target page is visible page.
897 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
898 EXPECT_EQ(1u, [apps_grid_controller_ scheduledScrollPage]);
899
900 // Drag to the left, should go to first page and no further.
901 [drag_manager onMouseDragged:at_left];
902 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
903 EXPECT_EQ(0u, [apps_grid_controller_ scheduledScrollPage]);
904 [apps_grid_controller_ scrollToPage:0]; // Commit without timer for testing.
905 [drag_manager onMouseDragged:at_left];
906 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
907 EXPECT_EQ(0u, [apps_grid_controller_ scheduledScrollPage]);
908
909 // Drag to the right, should go to last page and no futher.
910 [drag_manager onMouseDragged:at_right];
911 EXPECT_EQ(0u, [apps_grid_controller_ visiblePage]);
912 EXPECT_EQ(1u, [apps_grid_controller_ scheduledScrollPage]);
913 [apps_grid_controller_ scrollToPage:1];
914 [drag_manager onMouseDragged:at_right];
915 EXPECT_EQ(1u, [apps_grid_controller_ visiblePage]);
916 EXPECT_EQ(2u, [apps_grid_controller_ scheduledScrollPage]);
917 [apps_grid_controller_ scrollToPage:2];
918 [drag_manager onMouseDragged:at_right];
919 EXPECT_EQ(2u, [apps_grid_controller_ visiblePage]);
920 EXPECT_EQ(2u, [apps_grid_controller_ scheduledScrollPage]);
921
922 // Simulate a hover over the first pager segment.
923 [observer setHoveredSegmentForTest:0];
924 [drag_manager onMouseDragged:at_center];
925 EXPECT_EQ(2u, [apps_grid_controller_ visiblePage]);
926 EXPECT_EQ(0u, [apps_grid_controller_ scheduledScrollPage]);
927
928 // Drag it back, should cancel schedule.
929 [observer setHoveredSegmentForTest:-1];
930 [drag_manager onMouseDragged:at_center];
931 EXPECT_EQ(2u, [apps_grid_controller_ visiblePage]);
932 EXPECT_EQ(2u, [apps_grid_controller_ scheduledScrollPage]);
933
934 // Hover again, now over middle segment, and ensure a release also cancels.
935 [observer setHoveredSegmentForTest:1];
936 [drag_manager onMouseDragged:at_center];
937 EXPECT_EQ(2u, [apps_grid_controller_ visiblePage]);
938 EXPECT_EQ(1u, [apps_grid_controller_ scheduledScrollPage]);
939 [drag_manager onMouseUp:at_center];
940 EXPECT_EQ(2u, [apps_grid_controller_ visiblePage]);
941 EXPECT_EQ(2u, [apps_grid_controller_ scheduledScrollPage]);
942
943 [apps_grid_controller_ setPaginationObserver:nil];
944 }
945
946 TEST_F(AppsGridControllerTest, ContextMenus) {
947 AppListItemWithMenu* item_two_model = new AppListItemWithMenu("Item Two");
948 model()->AddItem(new AppListItemWithMenu("Item One"));
949 model()->AddItem(item_two_model);
950 EXPECT_EQ(2u, [apps_grid_controller_ itemCount]);
951
952 NSCollectionView* page = [apps_grid_controller_ collectionViewAtPageIndex:0];
953 NSEvent* mouse_at_cell_0 = MouseEventInCell(page, 0);
954 NSEvent* mouse_at_cell_1 = MouseEventInCell(page, 1);
955
956 NSMenu* menu = [page menuForEvent:mouse_at_cell_0];
957 EXPECT_EQ(1, [menu numberOfItems]);
958 EXPECT_NSEQ(@"Menu For: Item One", [[menu itemAtIndex:0] title]);
959
960 // Test a context menu request while the item is still installing.
961 item_two_model->SetMenuReadyForTesting(false);
962 menu = [page menuForEvent:mouse_at_cell_1];
963 EXPECT_EQ(nil, menu);
964
965 item_two_model->SetMenuReadyForTesting(true);
966 menu = [page menuForEvent:mouse_at_cell_1];
967 EXPECT_EQ(1, [menu numberOfItems]);
968 EXPECT_NSEQ(@"Menu For: Item Two", [[menu itemAtIndex:0] title]);
969
970 // Test that a button being held down with the left button does not also show
971 // a context menu.
972 [GetItemViewAt(0) highlight:YES];
973 EXPECT_FALSE([page menuForEvent:mouse_at_cell_0]);
974 [GetItemViewAt(0) highlight:NO];
975 EXPECT_TRUE([page menuForEvent:mouse_at_cell_0]);
976 }
977
978 } // namespace test
979 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698