| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "base/mac/foundation_util.h" | |
| 6 #include "base/memory/scoped_nsobject.h" | 5 #include "base/memory/scoped_nsobject.h" |
| 7 #include "base/message_loop.h" | |
| 8 #import "testing/gtest_mac.h" | 6 #import "testing/gtest_mac.h" |
| 9 #include "ui/app_list/app_list_item_model.h" | 7 #include "ui/app_list/app_list_item_model.h" |
| 10 #import "ui/app_list/cocoa/apps_grid_controller.h" | 8 #import "ui/app_list/cocoa/apps_grid_controller.h" |
| 11 #import "ui/app_list/cocoa/apps_grid_view_item.h" | 9 #import "ui/app_list/cocoa/apps_grid_view_item.h" |
| 10 #import "ui/app_list/cocoa/apps_pagination_model_observer.h" |
| 11 #import "ui/app_list/cocoa/test/apps_grid_controller_test_helper.h" |
| 12 #include "ui/app_list/test/app_list_test_model.h" | 12 #include "ui/app_list/test/app_list_test_model.h" |
| 13 #include "ui/app_list/test/app_list_test_view_delegate.h" | 13 #include "ui/app_list/test/app_list_test_view_delegate.h" |
| 14 #import "ui/base/test/cocoa_test_event_utils.h" | 14 |
| 15 #import "ui/base/test/ui_cocoa_test_helper.h" | 15 @interface TestPaginationObserver : NSObject<AppsPaginationModelObserver> { |
| 16 @private |
| 17 int totalPagesChangedCount_; |
| 18 int selectedPageChangedCount_; |
| 19 int lastOldSelectedPage_; |
| 20 int lastNewSelectedPage_; |
| 21 } |
| 22 |
| 23 @property (assign, nonatomic) int totalPagesChangedCount; |
| 24 @property (assign, nonatomic) int selectedPageChangedCount; |
| 25 @property (assign, nonatomic) int lastOldSelectedPage; |
| 26 @property (assign, nonatomic) int lastNewSelectedPage; |
| 27 |
| 28 @end |
| 29 |
| 30 @implementation TestPaginationObserver |
| 31 |
| 32 @synthesize totalPagesChangedCount = totalPagesChangedCount_; |
| 33 @synthesize selectedPageChangedCount = selectedPageChangedCount_; |
| 34 @synthesize lastOldSelectedPage = lastOldSelectedPage_; |
| 35 @synthesize lastNewSelectedPage = lastNewSelectedPage_; |
| 36 |
| 37 - (void)totalPagesChanged { |
| 38 ++totalPagesChangedCount_; |
| 39 } |
| 40 |
| 41 - (void)selectedPageChanged:(int)oldSelected |
| 42 newSelected:(int)newSelected { |
| 43 ++selectedPageChangedCount_; |
| 44 lastOldSelectedPage_ = oldSelected; |
| 45 lastNewSelectedPage_ = newSelected; |
| 46 } |
| 47 |
| 48 @end |
| 49 |
| 50 namespace app_list { |
| 51 namespace test { |
| 16 | 52 |
| 17 namespace { | 53 namespace { |
| 18 | 54 |
| 19 const size_t kItemsPerPage = 16; | 55 class AppsGridControllerTest : public AppsGridControllerTestHelper { |
| 20 | |
| 21 class AppsGridControllerTest : public ui::CocoaTest { | |
| 22 public: | 56 public: |
| 23 AppsGridControllerTest() { | 57 AppsGridControllerTest() {} |
| 24 Init(); | |
| 25 } | |
| 26 | 58 |
| 27 virtual void SetUp() OVERRIDE { | 59 virtual void SetUp() OVERRIDE { |
| 28 ui::CocoaTest::SetUp(); | 60 owned_apps_grid_controller_.reset([[AppsGridController alloc] init]); |
| 29 scoped_ptr<app_list::AppListViewDelegate> delegate( | 61 [owned_apps_grid_controller_ setDelegate:delegate_.get()]; |
| 30 new app_list::test::AppListTestViewDelegate); | 62 AppsGridControllerTestHelper::SetUpWithGridController( |
| 31 apps_grid_controller_.reset([[AppsGridController alloc] | 63 owned_apps_grid_controller_.get()); |
| 32 initWithViewDelegate:delegate.Pass()]); | |
| 33 | |
| 34 scoped_ptr<app_list::AppListModel> model( | |
| 35 new app_list::test::AppListTestModel); | |
| 36 [apps_grid_controller_ setModel:model.Pass()]; | |
| 37 | 64 |
| 38 [[test_window() contentView] addSubview:[apps_grid_controller_ view]]; | 65 [[test_window() contentView] addSubview:[apps_grid_controller_ view]]; |
| 39 [test_window() makePretendKeyWindowAndSetFirstResponder: | 66 [test_window() makePretendKeyWindowAndSetFirstResponder: |
| 40 [apps_grid_controller_ collectionViewAtPageIndex:0]]; | 67 [apps_grid_controller_ collectionViewAtPageIndex:0]]; |
| 41 } | 68 } |
| 42 | 69 |
| 43 virtual void TearDown() OVERRIDE { | 70 virtual void TearDown() OVERRIDE { |
| 44 apps_grid_controller_.reset(); | 71 owned_apps_grid_controller_.reset(); |
| 45 ui::CocoaTest::TearDown(); | 72 AppsGridControllerTestHelper::TearDown(); |
| 46 } | 73 } |
| 47 | 74 |
| 48 protected: | |
| 49 // Send a click to the test window in the centre of |view|. | |
| 50 void SimulateClick(NSView* view) { | |
| 51 std::pair<NSEvent*, NSEvent*> events( | |
| 52 cocoa_test_event_utils::MouseClickInView(view, 1)); | |
| 53 [NSApp postEvent:events.first atStart:NO]; | |
| 54 [NSApp postEvent:events.second atStart:NO]; | |
| 55 } | |
| 56 | |
| 57 // Send a key press to the first responder. | |
| 58 void SimulateKeyPress(unichar c) { | |
| 59 [test_window() keyDown:cocoa_test_event_utils::KeyEventWithCharacter(c)]; | |
| 60 } | |
| 61 | |
| 62 void SimulateMouseEnterItemAt(size_t index) { | |
| 63 [[apps_grid_controller_ itemAtIndex:index] mouseEntered: | |
| 64 cocoa_test_event_utils::EnterExitEventWithType(NSMouseEntered)]; | |
| 65 } | |
| 66 | |
| 67 void SimulateMouseExitItemAt(size_t index) { | |
| 68 [[apps_grid_controller_ itemAtIndex:index] mouseExited: | |
| 69 cocoa_test_event_utils::EnterExitEventWithType(NSMouseExited)]; | |
| 70 } | |
| 71 | |
| 72 // Do a bulk replacement of the items in the grid. | |
| 73 void ReplaceTestModel(int item_count) { | |
| 74 scoped_ptr<app_list::test::AppListTestModel> new_model( | |
| 75 new app_list::test::AppListTestModel); | |
| 76 new_model->PopulateApps(item_count); | |
| 77 [apps_grid_controller_ setModel:new_model.PassAs<app_list::AppListModel>()]; | |
| 78 } | |
| 79 | |
| 80 void DelayForCollectionView() { | |
| 81 message_loop_.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), | |
| 82 base::TimeDelta::FromMilliseconds(100)); | |
| 83 message_loop_.Run(); | |
| 84 } | |
| 85 | |
| 86 void SinkEvents() { | |
| 87 message_loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure()); | |
| 88 message_loop_.Run(); | |
| 89 } | |
| 90 | |
| 91 NSButton* GetItemViewAt(size_t index) { | |
| 92 return [[apps_grid_controller_ itemAtIndex:index] button]; | |
| 93 } | |
| 94 | |
| 95 NSCollectionView* GetPageAt(size_t index) { | |
| 96 return [apps_grid_controller_ collectionViewAtPageIndex:index]; | |
| 97 } | |
| 98 | |
| 99 // TODO(tapted): Update this to work for selections on other than the first | |
| 100 // page. | |
| 101 NSView* GetSelectedView() { | |
| 102 NSIndexSet* selection = [GetPageAt(0) selectionIndexes]; | |
| 103 if ([selection count]) { | |
| 104 AppsGridViewItem* item = base::mac::ObjCCastStrict<AppsGridViewItem>( | |
| 105 [GetPageAt(0) itemAtIndex:[selection firstIndex]]); | |
| 106 return [item button]; | |
| 107 } | |
| 108 | |
| 109 return nil; | |
| 110 } | |
| 111 | |
| 112 app_list::test::AppListTestViewDelegate* delegate() { | |
| 113 return static_cast<app_list::test::AppListTestViewDelegate*>( | |
| 114 [apps_grid_controller_ delegate]); | |
| 115 } | |
| 116 | |
| 117 app_list::test::AppListTestModel* model() { | |
| 118 return static_cast<app_list::test::AppListTestModel*>( | |
| 119 [apps_grid_controller_ model]); | |
| 120 } | |
| 121 | |
| 122 scoped_nsobject<AppsGridController> apps_grid_controller_; | |
| 123 | |
| 124 private: | 75 private: |
| 125 MessageLoopForUI message_loop_; | 76 scoped_nsobject<AppsGridController> owned_apps_grid_controller_; |
| 126 | 77 |
| 127 DISALLOW_COPY_AND_ASSIGN(AppsGridControllerTest); | 78 DISALLOW_COPY_AND_ASSIGN(AppsGridControllerTest); |
| 128 }; | 79 }; |
| 129 | 80 |
| 130 } // namespace | 81 } // namespace |
| 131 | 82 |
| 132 TEST_VIEW(AppsGridControllerTest, [apps_grid_controller_ view]); | 83 TEST_VIEW(AppsGridControllerTest, [apps_grid_controller_ view]); |
| 133 | 84 |
| 134 // Test showing with an empty model. | 85 // Test showing with an empty model. |
| 135 TEST_F(AppsGridControllerTest, EmptyModelAndShow) { | 86 TEST_F(AppsGridControllerTest, EmptyModelAndShow) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 } | 215 } |
| 265 | 216 |
| 266 // Test runtime updates: adding items, changing titles and icons. | 217 // Test runtime updates: adding items, changing titles and icons. |
| 267 TEST_F(AppsGridControllerTest, ModelUpdates) { | 218 TEST_F(AppsGridControllerTest, ModelUpdates) { |
| 268 model()->PopulateApps(2); | 219 model()->PopulateApps(2); |
| 269 EXPECT_EQ(2u, [[GetPageAt(0) content] count]); | 220 EXPECT_EQ(2u, [[GetPageAt(0) content] count]); |
| 270 | 221 |
| 271 // Add an item (PopulateApps will create a duplicate "Item 0"). | 222 // Add an item (PopulateApps will create a duplicate "Item 0"). |
| 272 model()->PopulateApps(1); | 223 model()->PopulateApps(1); |
| 273 EXPECT_EQ(3u, [[GetPageAt(0) content] count]); | 224 EXPECT_EQ(3u, [[GetPageAt(0) content] count]); |
| 274 NSButton* button = base::mac::ObjCCastStrict<NSButton>(GetItemViewAt(2)); | 225 NSButton* button = GetItemViewAt(2); |
| 275 EXPECT_NSEQ(@"Item 0", [button title]); | 226 EXPECT_NSEQ(@"Item 0", [button title]); |
| 276 | 227 |
| 277 // Update the title via the ItemModelObserver. | 228 // Update the title via the ItemModelObserver. |
| 278 app_list::AppListItemModel* item_model = model()->apps()->GetItemAt(2); | 229 app_list::AppListItemModel* item_model = model()->apps()->GetItemAt(2); |
| 279 item_model->SetTitle("UpdatedItem"); | 230 item_model->SetTitle("UpdatedItem"); |
| 280 EXPECT_NSEQ(@"UpdatedItem", [button title]); | 231 EXPECT_NSEQ(@"UpdatedItem", [button title]); |
| 281 | 232 |
| 282 // Update the icon, test by changing size. | 233 // Update the icon, test by changing size. |
| 283 NSSize icon_size = [[button image] size]; | 234 NSSize icon_size = [[button image] size]; |
| 284 EXPECT_EQ(0, icon_size.width); | 235 EXPECT_EQ(0, icon_size.width); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 307 // AppKit doesn't guarantee the order, so test moving between items. | 258 // AppKit doesn't guarantee the order, so test moving between items. |
| 308 SimulateMouseEnterItemAt(0); | 259 SimulateMouseEnterItemAt(0); |
| 309 EXPECT_EQ(GetItemViewAt(0), GetSelectedView()); | 260 EXPECT_EQ(GetItemViewAt(0), GetSelectedView()); |
| 310 SimulateMouseEnterItemAt(1); | 261 SimulateMouseEnterItemAt(1); |
| 311 EXPECT_EQ(GetItemViewAt(1), GetSelectedView()); | 262 EXPECT_EQ(GetItemViewAt(1), GetSelectedView()); |
| 312 SimulateMouseExitItemAt(0); | 263 SimulateMouseExitItemAt(0); |
| 313 EXPECT_EQ(GetItemViewAt(1), GetSelectedView()); | 264 EXPECT_EQ(GetItemViewAt(1), GetSelectedView()); |
| 314 SimulateMouseExitItemAt(1); | 265 SimulateMouseExitItemAt(1); |
| 315 EXPECT_EQ(nil, GetSelectedView()); | 266 EXPECT_EQ(nil, GetSelectedView()); |
| 316 } | 267 } |
| 268 |
| 269 // Test AppsGridPaginationObserver totalPagesChanged(). |
| 270 TEST_F(AppsGridControllerTest, PaginationObserverPagesChanged) { |
| 271 scoped_nsobject<TestPaginationObserver> observer( |
| 272 [[TestPaginationObserver alloc] init]); |
| 273 [apps_grid_controller_ setPaginationObserver:observer]; |
| 274 |
| 275 // Test totalPagesChanged. |
| 276 model()->PopulateApps(kItemsPerPage); |
| 277 EXPECT_EQ(0, [observer totalPagesChangedCount]); |
| 278 EXPECT_EQ(1u, [apps_grid_controller_ pageCount]); |
| 279 model()->PopulateApps(1); |
| 280 EXPECT_EQ(1, [observer totalPagesChangedCount]); |
| 281 EXPECT_EQ(2u, [apps_grid_controller_ pageCount]); |
| 282 ReplaceTestModel(0); |
| 283 EXPECT_EQ(2, [observer totalPagesChangedCount]); |
| 284 EXPECT_EQ(1u, [apps_grid_controller_ pageCount]); |
| 285 ReplaceTestModel(kItemsPerPage * 3 + 1); |
| 286 EXPECT_EQ(3, [observer totalPagesChangedCount]); |
| 287 EXPECT_EQ(4u, [apps_grid_controller_ pageCount]); |
| 288 |
| 289 EXPECT_EQ(0, [observer selectedPageChangedCount]); |
| 290 |
| 291 [apps_grid_controller_ setPaginationObserver:nil]; |
| 292 } |
| 293 |
| 294 // Test AppsGridPaginationObserver selectedPageChanged(). |
| 295 TEST_F(AppsGridControllerTest, PaginationObserverSelectedPageChanged) { |
| 296 scoped_nsobject<TestPaginationObserver> observer( |
| 297 [[TestPaginationObserver alloc] init]); |
| 298 [apps_grid_controller_ setPaginationObserver:observer]; |
| 299 EXPECT_EQ(0, [[NSAnimationContext currentContext] duration]); |
| 300 |
| 301 ReplaceTestModel(kItemsPerPage * 3 + 1); |
| 302 EXPECT_EQ(1, [observer totalPagesChangedCount]); |
| 303 EXPECT_EQ(4u, [apps_grid_controller_ pageCount]); |
| 304 |
| 305 EXPECT_EQ(0, [observer selectedPageChangedCount]); |
| 306 |
| 307 [apps_grid_controller_ scrollToPage:1]; |
| 308 EXPECT_EQ(1, [observer selectedPageChangedCount]); |
| 309 EXPECT_EQ(0, [observer lastOldSelectedPage]); |
| 310 EXPECT_EQ(1, [observer lastNewSelectedPage]); |
| 311 |
| 312 [apps_grid_controller_ scrollToPage:0]; |
| 313 EXPECT_EQ(2, [observer selectedPageChangedCount]); |
| 314 EXPECT_EQ(1, [observer lastOldSelectedPage]); |
| 315 EXPECT_EQ(0, [observer lastNewSelectedPage]); |
| 316 |
| 317 [apps_grid_controller_ scrollToPage:3]; |
| 318 // Note: with no animations, there is only a single page change. However, with |
| 319 // animations we expect multiple updates depending on the rate that the scroll |
| 320 // view updates and sends out NSViewBoundsDidChangeNotification. |
| 321 EXPECT_EQ(3, [observer selectedPageChangedCount]); |
| 322 EXPECT_EQ(0, [observer lastOldSelectedPage]); |
| 323 EXPECT_EQ(3, [observer lastNewSelectedPage]); |
| 324 |
| 325 [apps_grid_controller_ setPaginationObserver:nil]; |
| 326 } |
| 327 |
| 328 } // namespace test |
| 329 } // namespace app_list |
| OLD | NEW |