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

Side by Side Diff: ui/app_list/cocoa/apps_search_results_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 #import "ui/app_list/cocoa/apps_search_results_controller.h"
6
7 #include <stddef.h>
8
9 #include "base/mac/scoped_nsobject.h"
10 #include "base/macros.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/sys_string_conversions.h"
14 #include "base/strings/utf_string_conversions.h"
15 #import "testing/gtest_mac.h"
16 #include "ui/app_list/test/app_list_test_model.h"
17 #include "ui/app_list/test/test_search_result.h"
18 #include "ui/base/models/simple_menu_model.h"
19 #import "ui/events/test/cocoa_test_event_utils.h"
20 #include "ui/gfx/image/image_skia_util_mac.h"
21 #import "ui/gfx/test/ui_cocoa_test_helper.h"
22
23 @interface TestAppsSearchResultsDelegate : NSObject<AppsSearchResultsDelegate> {
24 @private
25 app_list::test::AppListTestModel appListModel_;
26 app_list::SearchResult* lastOpenedResult_;
27 }
28
29 @property(readonly, nonatomic) app_list::SearchResult* lastOpenedResult;
30
31 - (void)quitMessageLoop;
32
33 @end
34
35 @implementation TestAppsSearchResultsDelegate
36
37 @synthesize lastOpenedResult = lastOpenedResult_;
38
39 - (app_list::AppListModel*)appListModel {
40 return &appListModel_;
41 }
42
43 - (void)openResult:(app_list::SearchResult*)result {
44 lastOpenedResult_ = result;
45 }
46
47 - (void)quitMessageLoop {
48 base::MessageLoop::current()->QuitNow();
49 }
50
51 @end
52
53 namespace app_list {
54 namespace test {
55 namespace {
56
57 const int kDefaultResultsCount = 3;
58
59 class SearchResultWithMenu : public TestSearchResult {
60 public:
61 SearchResultWithMenu(const std::string& title, const std::string& details)
62 : menu_model_(NULL),
63 menu_ready_(true) {
64 set_title(base::ASCIIToUTF16(title));
65 set_details(base::ASCIIToUTF16(details));
66 menu_model_.AddItem(0, base::UTF8ToUTF16("Menu For: " + title));
67 }
68
69 void SetMenuReadyForTesting(bool ready) {
70 menu_ready_ = ready;
71 }
72
73 ui::MenuModel* GetContextMenuModel() override {
74 if (!menu_ready_)
75 return NULL;
76
77 return &menu_model_;
78 }
79
80 private:
81 ui::SimpleMenuModel menu_model_;
82 bool menu_ready_;
83
84 DISALLOW_COPY_AND_ASSIGN(SearchResultWithMenu);
85 };
86
87 class AppsSearchResultsControllerTest : public ui::CocoaTest {
88 public:
89 AppsSearchResultsControllerTest() {}
90
91 void AddTestResultAtIndex(size_t index,
92 const std::string& title,
93 const std::string& details) {
94 std::unique_ptr<SearchResult> result(
95 new SearchResultWithMenu(title, details));
96 AppListModel::SearchResults* results = [delegate_ appListModel]->results();
97 results->AddAt(index, result.release());
98 }
99
100 SearchResult* ModelResultAt(size_t index) {
101 return [delegate_ appListModel]->results()->GetItemAt(index);
102 }
103
104 NSCell* ViewResultAt(NSInteger index) {
105 NSTableView* table_view = [apps_search_results_controller_ tableView];
106 return [table_view preparedCellAtColumn:0
107 row:index];
108 }
109
110 void SetMenuReadyAt(size_t index, bool ready) {
111 SearchResultWithMenu* result =
112 static_cast<SearchResultWithMenu*>(ModelResultAt(index));
113 result->SetMenuReadyForTesting(ready);
114 }
115
116 BOOL SimulateKeyAction(SEL c) {
117 return [apps_search_results_controller_ handleCommandBySelector:c];
118 }
119
120 void ExpectConsistent();
121
122 // ui::CocoaTest overrides:
123 void SetUp() override;
124 void TearDown() override;
125
126 protected:
127 base::scoped_nsobject<TestAppsSearchResultsDelegate> delegate_;
128 base::scoped_nsobject<AppsSearchResultsController>
129 apps_search_results_controller_;
130
131 private:
132 DISALLOW_COPY_AND_ASSIGN(AppsSearchResultsControllerTest);
133 };
134
135 void AppsSearchResultsControllerTest::ExpectConsistent() {
136 NSInteger item_count = [delegate_ appListModel]->results()->item_count();
137 ASSERT_EQ(item_count,
138 [[apps_search_results_controller_ tableView] numberOfRows]);
139
140 // Compare content strings to ensure the order of items is consistent, and any
141 // model data that should have been reloaded has been reloaded in the view.
142 for (NSInteger i = 0; i < item_count; ++i) {
143 SearchResult* result = ModelResultAt(i);
144 base::string16 string_in_model = result->title();
145 if (!result->details().empty())
146 string_in_model += base::ASCIIToUTF16("\n") + result->details();
147 EXPECT_NSEQ(base::SysUTF16ToNSString(string_in_model),
148 [[ViewResultAt(i) attributedStringValue] string]);
149 }
150 }
151
152 void AppsSearchResultsControllerTest::SetUp() {
153 apps_search_results_controller_.reset(
154 [[AppsSearchResultsController alloc] initWithAppsSearchResultsFrameSize:
155 NSMakeSize(400, 400)]);
156 // The view is initially hidden. Give it a non-zero height so it draws.
157 [[apps_search_results_controller_ view] setFrameSize:NSMakeSize(400, 400)];
158
159 delegate_.reset([[TestAppsSearchResultsDelegate alloc] init]);
160
161 // Populate with some results so that TEST_VIEW does something non-trivial.
162 for (int i = 0; i < kDefaultResultsCount; ++i)
163 AddTestResultAtIndex(i, base::StringPrintf("Result %d", i), "ItemDetail");
164
165 SearchResult::Tags test_tags;
166 // Apply markup to the substring "Result" in the first item.
167 test_tags.push_back(SearchResult::Tag(SearchResult::Tag::NONE, 0, 1));
168 test_tags.push_back(SearchResult::Tag(SearchResult::Tag::URL, 1, 2));
169 test_tags.push_back(SearchResult::Tag(SearchResult::Tag::MATCH, 2, 3));
170 test_tags.push_back(SearchResult::Tag(SearchResult::Tag::DIM, 3, 4));
171 test_tags.push_back(SearchResult::Tag(SearchResult::Tag::MATCH |
172 SearchResult::Tag::URL, 4, 5));
173 test_tags.push_back(SearchResult::Tag(SearchResult::Tag::MATCH |
174 SearchResult::Tag::DIM, 5, 6));
175
176 SearchResult* result = ModelResultAt(0);
177 result->SetIcon(gfx::ImageSkiaFromNSImage(
178 [NSImage imageNamed:NSImageNameStatusAvailable]));
179 result->set_title_tags(test_tags);
180
181 [apps_search_results_controller_ setDelegate:delegate_];
182
183 ui::CocoaTest::SetUp();
184 [[test_window() contentView] addSubview:
185 [apps_search_results_controller_ view]];
186 }
187
188 void AppsSearchResultsControllerTest::TearDown() {
189 [apps_search_results_controller_ setDelegate:nil];
190 ui::CocoaTest::TearDown();
191 }
192
193 NSEvent* MouseEventInRow(NSTableView* table_view, NSInteger row_index) {
194 NSRect row_rect = [table_view rectOfRow:row_index];
195 NSPoint point_in_view = NSMakePoint(NSMidX(row_rect), NSMidY(row_rect));
196 NSPoint point_in_window = [table_view convertPoint:point_in_view
197 toView:nil];
198 return cocoa_test_event_utils::LeftMouseDownAtPoint(point_in_window);
199 }
200
201 } // namespace
202
203 TEST_VIEW(AppsSearchResultsControllerTest,
204 [apps_search_results_controller_ view]);
205
206 TEST_F(AppsSearchResultsControllerTest, ModelObservers) {
207 NSTableView* table_view = [apps_search_results_controller_ tableView];
208 ExpectConsistent();
209
210 EXPECT_EQ(1, [table_view numberOfColumns]);
211 EXPECT_EQ(kDefaultResultsCount, [table_view numberOfRows]);
212
213 // Insert at start.
214 AddTestResultAtIndex(0, "One", std::string());
215 EXPECT_EQ(kDefaultResultsCount + 1, [table_view numberOfRows]);
216 ExpectConsistent();
217
218 // Remove from end.
219 [delegate_ appListModel]->results()->DeleteAt(kDefaultResultsCount);
220 EXPECT_EQ(kDefaultResultsCount, [table_view numberOfRows]);
221 ExpectConsistent();
222
223 // Insert at end.
224 AddTestResultAtIndex(kDefaultResultsCount, "Four", std::string());
225 EXPECT_EQ(kDefaultResultsCount + 1, [table_view numberOfRows]);
226 ExpectConsistent();
227
228 // Delete from start.
229 [delegate_ appListModel]->results()->DeleteAt(0);
230 EXPECT_EQ(kDefaultResultsCount, [table_view numberOfRows]);
231 ExpectConsistent();
232
233 // Test clearing results.
234 [delegate_ appListModel]->results()->DeleteAll();
235 EXPECT_EQ(0, [table_view numberOfRows]);
236 ExpectConsistent();
237 }
238
239 TEST_F(AppsSearchResultsControllerTest, KeyboardSelectAndActivate) {
240 NSTableView* table_view = [apps_search_results_controller_ tableView];
241 EXPECT_EQ(-1, [table_view selectedRow]);
242
243 // Pressing up when nothing is selected should select the last item.
244 EXPECT_TRUE(SimulateKeyAction(@selector(moveUp:)));
245 EXPECT_EQ(kDefaultResultsCount - 1, [table_view selectedRow]);
246 [table_view deselectAll:nil];
247 EXPECT_EQ(-1, [table_view selectedRow]);
248
249 // Pressing down when nothing is selected should select the first item.
250 EXPECT_TRUE(SimulateKeyAction(@selector(moveDown:)));
251 EXPECT_EQ(0, [table_view selectedRow]);
252
253 // Pressing up should wrap around.
254 EXPECT_TRUE(SimulateKeyAction(@selector(moveUp:)));
255 EXPECT_EQ(kDefaultResultsCount - 1, [table_view selectedRow]);
256
257 // Down should now also wrap, since the selection is at the end.
258 EXPECT_TRUE(SimulateKeyAction(@selector(moveDown:)));
259 EXPECT_EQ(0, [table_view selectedRow]);
260
261 // Regular down and up movement, ensuring the cells have correct backgrounds.
262 EXPECT_TRUE(SimulateKeyAction(@selector(moveDown:)));
263 EXPECT_EQ(1, [table_view selectedRow]);
264 EXPECT_EQ(NSBackgroundStyleDark, [ViewResultAt(1) backgroundStyle]);
265 EXPECT_EQ(NSBackgroundStyleLight, [ViewResultAt(0) backgroundStyle]);
266
267 EXPECT_TRUE(SimulateKeyAction(@selector(moveUp:)));
268 EXPECT_EQ(0, [table_view selectedRow]);
269 EXPECT_EQ(NSBackgroundStyleDark, [ViewResultAt(0) backgroundStyle]);
270 EXPECT_EQ(NSBackgroundStyleLight, [ViewResultAt(1) backgroundStyle]);
271
272 // Test activating items.
273 EXPECT_TRUE(SimulateKeyAction(@selector(insertNewline:)));
274 EXPECT_EQ(ModelResultAt(0), [delegate_ lastOpenedResult]);
275 EXPECT_TRUE(SimulateKeyAction(@selector(moveDown:)));
276 EXPECT_TRUE(SimulateKeyAction(@selector(insertNewline:)));
277 EXPECT_EQ(ModelResultAt(1), [delegate_ lastOpenedResult]);
278 }
279
280 TEST_F(AppsSearchResultsControllerTest, ContextMenus) {
281 NSTableView* table_view = [apps_search_results_controller_ tableView];
282 NSEvent* mouse_in_row_0 = MouseEventInRow(table_view, 0);
283 NSEvent* mouse_in_row_1 = MouseEventInRow(table_view, 1);
284
285 NSMenu* menu = [table_view menuForEvent:mouse_in_row_0];
286 EXPECT_EQ(1, [menu numberOfItems]);
287 EXPECT_NSEQ(@"Menu For: Result 0", [[menu itemAtIndex:0] title]);
288
289 // Test a context menu request while the item is still installing.
290 SetMenuReadyAt(1, false);
291 menu = [table_view menuForEvent:mouse_in_row_1];
292 EXPECT_EQ(nil, menu);
293
294 SetMenuReadyAt(1, true);
295 menu = [table_view menuForEvent:mouse_in_row_1];
296 EXPECT_EQ(1, [menu numberOfItems]);
297 EXPECT_NSEQ(@"Menu For: Result 1", [[menu itemAtIndex:0] title]);
298 }
299
300 } // namespace test
301 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698