Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ui / app_list / app_list_item_list_unittest.cc
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 "ui/app_list/app_list_item_list.h"
6
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"
13
14 namespace app_list {
15
16 namespace {
17
18 class TestObserver : public AppListItemListObserver {
19  public:
20   TestObserver() : items_added_(0), items_removed_(0), items_moved_(0) {}
21
22   ~TestObserver() override {}
23
24   // AppListItemListObserver overriden:
25   void OnListItemAdded(size_t index, AppListItem* item) override {
26     ++items_added_;
27   }
28
29   void OnListItemRemoved(size_t index, AppListItem* item) override {
30     ++items_removed_;
31   }
32
33   void OnListItemMoved(size_t from_index,
34                        size_t to_index,
35                        AppListItem* item) override {
36     ++items_moved_;
37   }
38
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_; }
42
43   void ResetCounts() {
44     items_added_ = 0;
45     items_removed_ = 0;
46     items_moved_ = 0;
47   }
48
49  private:
50   size_t items_added_;
51   size_t items_removed_;
52   size_t items_moved_;
53
54   DISALLOW_COPY_AND_ASSIGN(TestObserver);
55 };
56
57 std::string GetItemId(int id) {
58   return base::StringPrintf("Item %d", id);
59 }
60
61 }  // namespace
62
63 class AppListItemListTest : public testing::Test {
64  public:
65   AppListItemListTest() {}
66   ~AppListItemListTest() override {}
67
68   // testing::Test overrides:
69   void SetUp() override { item_list_.AddObserver(&observer_); }
70
71   void TearDown() override { item_list_.RemoveObserver(&observer_); }
72
73  protected:
74   AppListItem* FindItem(const std::string& id) {
75     return item_list_.FindItem(id);
76   }
77
78   bool FindItemIndex(const std::string& id, size_t* index) {
79     return item_list_.FindItemIndex(id, index);
80   }
81
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();
92   }
93
94   AppListItem* CreateAndAddItem(const std::string& name) {
95     scoped_ptr<AppListItem> item(CreateItem(name));
96     return item_list_.AddItem(item.Pass());
97   }
98
99   scoped_ptr<AppListItem> RemoveItem(const std::string& id) {
100     return item_list_.RemoveItem(id);
101   }
102
103   scoped_ptr<AppListItem> RemoveItemAt(size_t index) {
104     return item_list_.RemoveItemAt(index);
105   }
106
107   syncer::StringOrdinal CreatePositionBefore(
108       const syncer::StringOrdinal& position) {
109     return item_list_.CreatePositionBefore(position);
110   }
111
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()));
117     }
118     if (!res)
119       PrintItems();
120     return res;
121   }
122
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;
131   }
132
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();
137   }
138
139   AppListItemList item_list_;
140   TestObserver observer_;
141
142  private:
143   DISALLOW_COPY_AND_ASSIGN(AppListItemListTest);
144 };
145
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());
156
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);
164
165   scoped_ptr<AppListItem> item_3(CreateItem(GetItemId(3)));
166   EXPECT_FALSE(FindItemIndex(item_3->id(), &index));
167 }
168
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());
179
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());
188 }
189
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());
200
201   size_t index;
202   EXPECT_TRUE(FindItemIndex(item_1->id(), &index));
203   EXPECT_EQ(index, 1u);
204
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());
211 }
212
213 TEST_F(AppListItemListTest, MoveItem) {
214   CreateAndAddItem(GetItemId(0));
215   CreateAndAddItem(GetItemId(1));
216   CreateAndAddItem(GetItemId(2));
217   CreateAndAddItem(GetItemId(3));
218
219   EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
220
221   item_list_.MoveItem(0, 0);
222   EXPECT_EQ(0u, observer_.items_moved());
223   EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
224
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));
229
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));
234
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));
239
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));
244
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));
249 }
250
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());
273
274   // Restore the original order.
275   item_list_.MoveItem(1, 0);
276   EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
277
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());
297 }
298
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));
309
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));
316
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));
320 }
321
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));
328
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));
362 }
363
364 }  // namespace app_list