Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / app_list / app_list_item_list_unittest.cc
blob92986fff9a470e43fb76d565a8e29b5df932103a
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.
5 #include "ui/app_list/app_list_item_list.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/stringprintf.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "ui/app_list/app_list_folder_item.h"
11 #include "ui/app_list/app_list_item.h"
12 #include "ui/app_list/app_list_item_list_observer.h"
14 namespace app_list {
16 namespace {
18 class TestObserver : public AppListItemListObserver {
19 public:
20 TestObserver() : items_added_(0), items_removed_(0), items_moved_(0) {}
22 ~TestObserver() override {}
24 // AppListItemListObserver overriden:
25 void OnListItemAdded(size_t index, AppListItem* item) override {
26 ++items_added_;
29 void OnListItemRemoved(size_t index, AppListItem* item) override {
30 ++items_removed_;
33 void OnListItemMoved(size_t from_index,
34 size_t to_index,
35 AppListItem* item) override {
36 ++items_moved_;
39 size_t items_added() const { return items_added_; }
40 size_t items_removed() const { return items_removed_; }
41 size_t items_moved() const { return items_moved_; }
43 void ResetCounts() {
44 items_added_ = 0;
45 items_removed_ = 0;
46 items_moved_ = 0;
49 private:
50 size_t items_added_;
51 size_t items_removed_;
52 size_t items_moved_;
54 DISALLOW_COPY_AND_ASSIGN(TestObserver);
57 std::string GetItemId(int id) {
58 return base::StringPrintf("Item %d", id);
61 } // namespace
63 class AppListItemListTest : public testing::Test {
64 public:
65 AppListItemListTest() {}
66 ~AppListItemListTest() override {}
68 // testing::Test overrides:
69 void SetUp() override { item_list_.AddObserver(&observer_); }
71 void TearDown() override { item_list_.RemoveObserver(&observer_); }
73 protected:
74 AppListItem* FindItem(const std::string& id) {
75 return item_list_.FindItem(id);
78 bool FindItemIndex(const std::string& id, size_t* index) {
79 return item_list_.FindItemIndex(id, index);
82 scoped_ptr<AppListItem> CreateItem(const std::string& name) {
83 scoped_ptr<AppListItem> item(new AppListItem(name));
84 size_t nitems = item_list_.item_count();
85 syncer::StringOrdinal position;
86 if (nitems == 0)
87 position = syncer::StringOrdinal::CreateInitialOrdinal();
88 else
89 position = item_list_.item_at(nitems - 1)->position().CreateAfter();
90 item->set_position(position);
91 return item.Pass();
94 AppListItem* CreateAndAddItem(const std::string& name) {
95 scoped_ptr<AppListItem> item(CreateItem(name));
96 return item_list_.AddItem(item.Pass());
99 scoped_ptr<AppListItem> RemoveItem(const std::string& id) {
100 return item_list_.RemoveItem(id);
103 scoped_ptr<AppListItem> RemoveItemAt(size_t index) {
104 return item_list_.RemoveItemAt(index);
107 syncer::StringOrdinal CreatePositionBefore(
108 const syncer::StringOrdinal& position) {
109 return item_list_.CreatePositionBefore(position);
112 bool VerifyItemListOrdinals() {
113 bool res = true;
114 for (size_t i = 1; i < item_list_.item_count(); ++i) {
115 res &= (item_list_.item_at(i - 1)->position().LessThan(
116 item_list_.item_at(i)->position()));
118 if (!res)
119 PrintItems();
120 return res;
123 bool VerifyItemOrder4(size_t a, size_t b, size_t c, size_t d) {
124 if ((GetItemId(a) == item_list_.item_at(0)->id()) &&
125 (GetItemId(b) == item_list_.item_at(1)->id()) &&
126 (GetItemId(c) == item_list_.item_at(2)->id()) &&
127 (GetItemId(d) == item_list_.item_at(3)->id()))
128 return true;
129 PrintItems();
130 return false;
133 void PrintItems() {
134 VLOG(1) << "ITEMS:";
135 for (size_t i = 0; i < item_list_.item_count(); ++i)
136 VLOG(1) << " " << item_list_.item_at(i)->ToDebugString();
139 AppListItemList item_list_;
140 TestObserver observer_;
142 private:
143 DISALLOW_COPY_AND_ASSIGN(AppListItemListTest);
146 TEST_F(AppListItemListTest, FindItemIndex) {
147 AppListItem* item_0 = CreateAndAddItem(GetItemId(0));
148 AppListItem* item_1 = CreateAndAddItem(GetItemId(1));
149 AppListItem* item_2 = CreateAndAddItem(GetItemId(2));
150 EXPECT_EQ(observer_.items_added(), 3u);
151 EXPECT_EQ(item_list_.item_count(), 3u);
152 EXPECT_EQ(item_0, item_list_.item_at(0));
153 EXPECT_EQ(item_1, item_list_.item_at(1));
154 EXPECT_EQ(item_2, item_list_.item_at(2));
155 EXPECT_TRUE(VerifyItemListOrdinals());
157 size_t index;
158 EXPECT_TRUE(FindItemIndex(item_0->id(), &index));
159 EXPECT_EQ(index, 0u);
160 EXPECT_TRUE(FindItemIndex(item_1->id(), &index));
161 EXPECT_EQ(index, 1u);
162 EXPECT_TRUE(FindItemIndex(item_2->id(), &index));
163 EXPECT_EQ(index, 2u);
165 scoped_ptr<AppListItem> item_3(CreateItem(GetItemId(3)));
166 EXPECT_FALSE(FindItemIndex(item_3->id(), &index));
169 TEST_F(AppListItemListTest, RemoveItemAt) {
170 AppListItem* item_0 = CreateAndAddItem(GetItemId(0));
171 AppListItem* item_1 = CreateAndAddItem(GetItemId(1));
172 AppListItem* item_2 = CreateAndAddItem(GetItemId(2));
173 EXPECT_EQ(item_list_.item_count(), 3u);
174 EXPECT_EQ(observer_.items_added(), 3u);
175 size_t index;
176 EXPECT_TRUE(FindItemIndex(item_1->id(), &index));
177 EXPECT_EQ(index, 1u);
178 EXPECT_TRUE(VerifyItemListOrdinals());
180 scoped_ptr<AppListItem> item_removed = RemoveItemAt(1);
181 EXPECT_EQ(item_removed, item_1);
182 EXPECT_FALSE(FindItem(item_1->id()));
183 EXPECT_EQ(item_list_.item_count(), 2u);
184 EXPECT_EQ(observer_.items_removed(), 1u);
185 EXPECT_EQ(item_list_.item_at(0), item_0);
186 EXPECT_EQ(item_list_.item_at(1), item_2);
187 EXPECT_TRUE(VerifyItemListOrdinals());
190 TEST_F(AppListItemListTest, RemoveItem) {
191 AppListItem* item_0 = CreateAndAddItem(GetItemId(0));
192 AppListItem* item_1 = CreateAndAddItem(GetItemId(1));
193 AppListItem* item_2 = CreateAndAddItem(GetItemId(2));
194 EXPECT_EQ(item_list_.item_count(), 3u);
195 EXPECT_EQ(observer_.items_added(), 3u);
196 EXPECT_EQ(item_0, item_list_.item_at(0));
197 EXPECT_EQ(item_1, item_list_.item_at(1));
198 EXPECT_EQ(item_2, item_list_.item_at(2));
199 EXPECT_TRUE(VerifyItemListOrdinals());
201 size_t index;
202 EXPECT_TRUE(FindItemIndex(item_1->id(), &index));
203 EXPECT_EQ(index, 1u);
205 scoped_ptr<AppListItem> item_removed = RemoveItem(item_1->id());
206 EXPECT_EQ(item_removed, item_1);
207 EXPECT_FALSE(FindItem(item_1->id()));
208 EXPECT_EQ(item_list_.item_count(), 2u);
209 EXPECT_EQ(observer_.items_removed(), 1u);
210 EXPECT_TRUE(VerifyItemListOrdinals());
213 TEST_F(AppListItemListTest, MoveItem) {
214 CreateAndAddItem(GetItemId(0));
215 CreateAndAddItem(GetItemId(1));
216 CreateAndAddItem(GetItemId(2));
217 CreateAndAddItem(GetItemId(3));
219 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
221 item_list_.MoveItem(0, 0);
222 EXPECT_EQ(0u, observer_.items_moved());
223 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
225 item_list_.MoveItem(0, 1);
226 EXPECT_EQ(1u, observer_.items_moved());
227 EXPECT_TRUE(VerifyItemListOrdinals());
228 EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
230 item_list_.MoveItem(1, 2);
231 EXPECT_EQ(2u, observer_.items_moved());
232 EXPECT_TRUE(VerifyItemListOrdinals());
233 EXPECT_TRUE(VerifyItemOrder4(1, 2, 0, 3));
235 item_list_.MoveItem(2, 1);
236 EXPECT_EQ(3u, observer_.items_moved());
237 EXPECT_TRUE(VerifyItemListOrdinals());
238 EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
240 item_list_.MoveItem(3, 0);
241 EXPECT_EQ(4u, observer_.items_moved());
242 EXPECT_TRUE(VerifyItemListOrdinals());
243 EXPECT_TRUE(VerifyItemOrder4(3, 1, 0, 2));
245 item_list_.MoveItem(0, 3);
246 EXPECT_EQ(5u, observer_.items_moved());
247 EXPECT_TRUE(VerifyItemListOrdinals());
248 EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
251 TEST_F(AppListItemListTest, SamePosition) {
252 CreateAndAddItem(GetItemId(0));
253 CreateAndAddItem(GetItemId(1));
254 CreateAndAddItem(GetItemId(2));
255 CreateAndAddItem(GetItemId(3));
256 item_list_.SetItemPosition(item_list_.item_at(2),
257 item_list_.item_at(1)->position());
258 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
259 EXPECT_TRUE(item_list_.item_at(1)->position().Equals(
260 item_list_.item_at(2)->position()));
261 // Moving an item to position 1 should fix the position.
262 observer_.ResetCounts();
263 item_list_.MoveItem(0, 1);
264 EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
265 EXPECT_TRUE(item_list_.item_at(0)->position().LessThan(
266 item_list_.item_at(1)->position()));
267 EXPECT_TRUE(item_list_.item_at(1)->position().LessThan(
268 item_list_.item_at(2)->position()));
269 EXPECT_TRUE(item_list_.item_at(2)->position().LessThan(
270 item_list_.item_at(3)->position()));
271 // One extra move notification for fixed position.
272 EXPECT_EQ(2u, observer_.items_moved());
274 // Restore the original order.
275 item_list_.MoveItem(1, 0);
276 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
278 // Set all four items to the same position.
279 item_list_.SetItemPosition(item_list_.item_at(1),
280 item_list_.item_at(0)->position());
281 item_list_.SetItemPosition(item_list_.item_at(2),
282 item_list_.item_at(0)->position());
283 item_list_.SetItemPosition(item_list_.item_at(3),
284 item_list_.item_at(0)->position());
285 // Move should fix the position of the items.
286 observer_.ResetCounts();
287 item_list_.MoveItem(0, 1);
288 EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
289 EXPECT_TRUE(item_list_.item_at(0)->position().LessThan(
290 item_list_.item_at(1)->position()));
291 EXPECT_TRUE(item_list_.item_at(1)->position().LessThan(
292 item_list_.item_at(2)->position()));
293 EXPECT_TRUE(item_list_.item_at(2)->position().LessThan(
294 item_list_.item_at(3)->position()));
295 // One extra move notification for fixed position.
296 EXPECT_EQ(2u, observer_.items_moved());
299 TEST_F(AppListItemListTest, CreatePositionBefore) {
300 CreateAndAddItem(GetItemId(0));
301 syncer::StringOrdinal position0 = item_list_.item_at(0)->position();
302 syncer::StringOrdinal new_position;
303 new_position = CreatePositionBefore(position0.CreateBefore());
304 EXPECT_TRUE(new_position.LessThan(position0));
305 new_position = CreatePositionBefore(position0);
306 EXPECT_TRUE(new_position.LessThan(position0));
307 new_position = CreatePositionBefore(position0.CreateAfter());
308 EXPECT_TRUE(new_position.GreaterThan(position0));
310 CreateAndAddItem(GetItemId(1));
311 syncer::StringOrdinal position1 = item_list_.item_at(1)->position();
312 EXPECT_TRUE(position1.GreaterThan(position0));
313 new_position = CreatePositionBefore(position1);
314 EXPECT_TRUE(new_position.GreaterThan(position0));
315 EXPECT_TRUE(new_position.LessThan(position1));
317 // Invalid ordinal should return a position at the end of the list.
318 new_position = CreatePositionBefore(syncer::StringOrdinal());
319 EXPECT_TRUE(new_position.GreaterThan(position1));
322 TEST_F(AppListItemListTest, SetItemPosition) {
323 CreateAndAddItem(GetItemId(0));
324 CreateAndAddItem(GetItemId(1));
325 CreateAndAddItem(GetItemId(2));
326 CreateAndAddItem(GetItemId(3));
327 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
329 // No change to position.
330 item_list_.SetItemPosition(item_list_.item_at(0),
331 item_list_.item_at(0)->position());
332 EXPECT_TRUE(VerifyItemListOrdinals());
333 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
334 // No order change.
335 item_list_.SetItemPosition(item_list_.item_at(0),
336 item_list_.item_at(0)->position().CreateBetween(
337 item_list_.item_at(1)->position()));
338 EXPECT_TRUE(VerifyItemListOrdinals());
339 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
340 // 0 -> 1
341 item_list_.SetItemPosition(item_list_.item_at(0),
342 item_list_.item_at(1)->position().CreateBetween(
343 item_list_.item_at(2)->position()));
344 EXPECT_TRUE(VerifyItemListOrdinals());
345 EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
346 // 1 -> 2
347 item_list_.SetItemPosition(item_list_.item_at(1),
348 item_list_.item_at(2)->position().CreateBetween(
349 item_list_.item_at(3)->position()));
350 EXPECT_TRUE(VerifyItemListOrdinals());
351 EXPECT_TRUE(VerifyItemOrder4(1, 2, 0, 3));
352 // 0 -> last
353 item_list_.SetItemPosition(item_list_.item_at(0),
354 item_list_.item_at(3)->position().CreateAfter());
355 EXPECT_TRUE(VerifyItemListOrdinals());
356 EXPECT_TRUE(VerifyItemOrder4(2, 0, 3, 1));
357 // last -> last
358 item_list_.SetItemPosition(item_list_.item_at(3),
359 item_list_.item_at(3)->position().CreateAfter());
360 EXPECT_TRUE(VerifyItemListOrdinals());
361 EXPECT_TRUE(VerifyItemOrder4(2, 0, 3, 1));
364 } // namespace app_list