Upstream version 10.39.225.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   virtual ~TestObserver() {
23   }
24
25   // AppListItemListObserver overriden:
26   virtual void OnListItemAdded(size_t index, AppListItem* item) OVERRIDE {
27     ++items_added_;
28   }
29
30   virtual void OnListItemRemoved(size_t index, AppListItem* item) OVERRIDE {
31     ++items_removed_;
32   }
33
34   virtual void OnListItemMoved(size_t from_index,
35                                size_t to_index,
36                                AppListItem* item) OVERRIDE {
37     ++items_moved_;
38   }
39
40   size_t items_added() const { return items_added_; }
41   size_t items_removed() const { return items_removed_; }
42   size_t items_moved() const { return items_moved_; }
43
44   void ResetCounts() {
45     items_added_ = 0;
46     items_removed_ = 0;
47     items_moved_ = 0;
48   }
49
50  private:
51   size_t items_added_;
52   size_t items_removed_;
53   size_t items_moved_;
54
55   DISALLOW_COPY_AND_ASSIGN(TestObserver);
56 };
57
58 std::string GetItemId(int id) {
59   return base::StringPrintf("Item %d", id);
60 }
61
62 }  // namespace
63
64 class AppListItemListTest : public testing::Test {
65  public:
66   AppListItemListTest() {}
67   virtual ~AppListItemListTest() {}
68
69   // testing::Test overrides:
70   virtual void SetUp() OVERRIDE {
71     item_list_.AddObserver(&observer_);
72   }
73
74   virtual void TearDown() OVERRIDE {
75     item_list_.RemoveObserver(&observer_);
76   }
77
78  protected:
79   AppListItem* FindItem(const std::string& id) {
80     return item_list_.FindItem(id);
81   }
82
83   bool FindItemIndex(const std::string& id, size_t* index) {
84     return item_list_.FindItemIndex(id, index);
85   }
86
87   scoped_ptr<AppListItem> CreateItem(const std::string& name) {
88     scoped_ptr<AppListItem> item(new AppListItem(name));
89     size_t nitems = item_list_.item_count();
90     syncer::StringOrdinal position;
91     if (nitems == 0)
92       position = syncer::StringOrdinal::CreateInitialOrdinal();
93     else
94       position = item_list_.item_at(nitems - 1)->position().CreateAfter();
95     item->set_position(position);
96     return item.Pass();
97   }
98
99   AppListItem* CreateAndAddItem(const std::string& name) {
100     scoped_ptr<AppListItem> item(CreateItem(name));
101     return item_list_.AddItem(item.Pass());
102   }
103
104   scoped_ptr<AppListItem> RemoveItem(const std::string& id) {
105     return item_list_.RemoveItem(id);
106   }
107
108   scoped_ptr<AppListItem> RemoveItemAt(size_t index) {
109     return item_list_.RemoveItemAt(index);
110   }
111
112   syncer::StringOrdinal CreatePositionBefore(
113       const syncer::StringOrdinal& position) {
114     return item_list_.CreatePositionBefore(position);
115   }
116
117   bool VerifyItemListOrdinals() {
118     bool res = true;
119     for (size_t i = 1; i < item_list_.item_count(); ++i) {
120       res &= (item_list_.item_at(i - 1)->position().LessThan(
121           item_list_.item_at(i)->position()));
122     }
123     if (!res)
124       PrintItems();
125     return res;
126   }
127
128   bool VerifyItemOrder4(size_t a, size_t b, size_t c, size_t d) {
129     if ((GetItemId(a) == item_list_.item_at(0)->id()) &&
130         (GetItemId(b) == item_list_.item_at(1)->id()) &&
131         (GetItemId(c) == item_list_.item_at(2)->id()) &&
132         (GetItemId(d) == item_list_.item_at(3)->id()))
133       return true;
134     PrintItems();
135     return false;
136   }
137
138   void PrintItems() {
139     VLOG(1) << "ITEMS:";
140     for (size_t i = 0; i < item_list_.item_count(); ++i)
141       VLOG(1) << " " << item_list_.item_at(i)->ToDebugString();
142   }
143
144   AppListItemList item_list_;
145   TestObserver observer_;
146
147  private:
148   DISALLOW_COPY_AND_ASSIGN(AppListItemListTest);
149 };
150
151 TEST_F(AppListItemListTest, FindItemIndex) {
152   AppListItem* item_0 = CreateAndAddItem(GetItemId(0));
153   AppListItem* item_1 = CreateAndAddItem(GetItemId(1));
154   AppListItem* item_2 = CreateAndAddItem(GetItemId(2));
155   EXPECT_EQ(observer_.items_added(), 3u);
156   EXPECT_EQ(item_list_.item_count(), 3u);
157   EXPECT_EQ(item_0, item_list_.item_at(0));
158   EXPECT_EQ(item_1, item_list_.item_at(1));
159   EXPECT_EQ(item_2, item_list_.item_at(2));
160   EXPECT_TRUE(VerifyItemListOrdinals());
161
162   size_t index;
163   EXPECT_TRUE(FindItemIndex(item_0->id(), &index));
164   EXPECT_EQ(index, 0u);
165   EXPECT_TRUE(FindItemIndex(item_1->id(), &index));
166   EXPECT_EQ(index, 1u);
167   EXPECT_TRUE(FindItemIndex(item_2->id(), &index));
168   EXPECT_EQ(index, 2u);
169
170   scoped_ptr<AppListItem> item_3(CreateItem(GetItemId(3)));
171   EXPECT_FALSE(FindItemIndex(item_3->id(), &index));
172 }
173
174 TEST_F(AppListItemListTest, RemoveItemAt) {
175   AppListItem* item_0 = CreateAndAddItem(GetItemId(0));
176   AppListItem* item_1 = CreateAndAddItem(GetItemId(1));
177   AppListItem* item_2 = CreateAndAddItem(GetItemId(2));
178   EXPECT_EQ(item_list_.item_count(), 3u);
179   EXPECT_EQ(observer_.items_added(), 3u);
180   size_t index;
181   EXPECT_TRUE(FindItemIndex(item_1->id(), &index));
182   EXPECT_EQ(index, 1u);
183   EXPECT_TRUE(VerifyItemListOrdinals());
184
185   scoped_ptr<AppListItem> item_removed = RemoveItemAt(1);
186   EXPECT_EQ(item_removed, item_1);
187   EXPECT_FALSE(FindItem(item_1->id()));
188   EXPECT_EQ(item_list_.item_count(), 2u);
189   EXPECT_EQ(observer_.items_removed(), 1u);
190   EXPECT_EQ(item_list_.item_at(0), item_0);
191   EXPECT_EQ(item_list_.item_at(1), item_2);
192   EXPECT_TRUE(VerifyItemListOrdinals());
193 }
194
195 TEST_F(AppListItemListTest, RemoveItem) {
196   AppListItem* item_0 = CreateAndAddItem(GetItemId(0));
197   AppListItem* item_1 = CreateAndAddItem(GetItemId(1));
198   AppListItem* item_2 = CreateAndAddItem(GetItemId(2));
199   EXPECT_EQ(item_list_.item_count(), 3u);
200   EXPECT_EQ(observer_.items_added(), 3u);
201   EXPECT_EQ(item_0, item_list_.item_at(0));
202   EXPECT_EQ(item_1, item_list_.item_at(1));
203   EXPECT_EQ(item_2, item_list_.item_at(2));
204   EXPECT_TRUE(VerifyItemListOrdinals());
205
206   size_t index;
207   EXPECT_TRUE(FindItemIndex(item_1->id(), &index));
208   EXPECT_EQ(index, 1u);
209
210   scoped_ptr<AppListItem> item_removed = RemoveItem(item_1->id());
211   EXPECT_EQ(item_removed, item_1);
212   EXPECT_FALSE(FindItem(item_1->id()));
213   EXPECT_EQ(item_list_.item_count(), 2u);
214   EXPECT_EQ(observer_.items_removed(), 1u);
215   EXPECT_TRUE(VerifyItemListOrdinals());
216 }
217
218 TEST_F(AppListItemListTest, MoveItem) {
219   CreateAndAddItem(GetItemId(0));
220   CreateAndAddItem(GetItemId(1));
221   CreateAndAddItem(GetItemId(2));
222   CreateAndAddItem(GetItemId(3));
223
224   EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
225
226   item_list_.MoveItem(0, 0);
227   EXPECT_EQ(0u, observer_.items_moved());
228   EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
229
230   item_list_.MoveItem(0, 1);
231   EXPECT_EQ(1u, observer_.items_moved());
232   EXPECT_TRUE(VerifyItemListOrdinals());
233   EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
234
235   item_list_.MoveItem(1, 2);
236   EXPECT_EQ(2u, observer_.items_moved());
237   EXPECT_TRUE(VerifyItemListOrdinals());
238   EXPECT_TRUE(VerifyItemOrder4(1, 2, 0, 3));
239
240   item_list_.MoveItem(2, 1);
241   EXPECT_EQ(3u, observer_.items_moved());
242   EXPECT_TRUE(VerifyItemListOrdinals());
243   EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
244
245   item_list_.MoveItem(3, 0);
246   EXPECT_EQ(4u, observer_.items_moved());
247   EXPECT_TRUE(VerifyItemListOrdinals());
248   EXPECT_TRUE(VerifyItemOrder4(3, 1, 0, 2));
249
250   item_list_.MoveItem(0, 3);
251   EXPECT_EQ(5u, observer_.items_moved());
252   EXPECT_TRUE(VerifyItemListOrdinals());
253   EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
254 }
255
256 TEST_F(AppListItemListTest, SamePosition) {
257   CreateAndAddItem(GetItemId(0));
258   CreateAndAddItem(GetItemId(1));
259   CreateAndAddItem(GetItemId(2));
260   CreateAndAddItem(GetItemId(3));
261   item_list_.SetItemPosition(item_list_.item_at(2),
262                              item_list_.item_at(1)->position());
263   EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
264   EXPECT_TRUE(item_list_.item_at(1)->position().Equals(
265       item_list_.item_at(2)->position()));
266   // Moving an item to position 1 should fix the position.
267   observer_.ResetCounts();
268   item_list_.MoveItem(0, 1);
269   EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
270   EXPECT_TRUE(item_list_.item_at(0)->position().LessThan(
271       item_list_.item_at(1)->position()));
272   EXPECT_TRUE(item_list_.item_at(1)->position().LessThan(
273       item_list_.item_at(2)->position()));
274   EXPECT_TRUE(item_list_.item_at(2)->position().LessThan(
275       item_list_.item_at(3)->position()));
276   // One extra move notification for fixed position.
277   EXPECT_EQ(2u, observer_.items_moved());
278
279   // Restore the original order.
280   item_list_.MoveItem(1, 0);
281   EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
282
283   // Set all four items to the same position.
284   item_list_.SetItemPosition(item_list_.item_at(1),
285                              item_list_.item_at(0)->position());
286   item_list_.SetItemPosition(item_list_.item_at(2),
287                              item_list_.item_at(0)->position());
288   item_list_.SetItemPosition(item_list_.item_at(3),
289                              item_list_.item_at(0)->position());
290   // Move should fix the position of the items.
291   observer_.ResetCounts();
292   item_list_.MoveItem(0, 1);
293   EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
294   EXPECT_TRUE(item_list_.item_at(0)->position().LessThan(
295       item_list_.item_at(1)->position()));
296   EXPECT_TRUE(item_list_.item_at(1)->position().LessThan(
297       item_list_.item_at(2)->position()));
298   EXPECT_TRUE(item_list_.item_at(2)->position().LessThan(
299       item_list_.item_at(3)->position()));
300   // One extra move notification for fixed position.
301   EXPECT_EQ(2u, observer_.items_moved());
302 }
303
304 TEST_F(AppListItemListTest, CreatePositionBefore) {
305   CreateAndAddItem(GetItemId(0));
306   syncer::StringOrdinal position0 = item_list_.item_at(0)->position();
307   syncer::StringOrdinal new_position;
308   new_position = CreatePositionBefore(position0.CreateBefore());
309   EXPECT_TRUE(new_position.LessThan(position0));
310   new_position = CreatePositionBefore(position0);
311   EXPECT_TRUE(new_position.LessThan(position0));
312   new_position = CreatePositionBefore(position0.CreateAfter());
313   EXPECT_TRUE(new_position.GreaterThan(position0));
314
315   CreateAndAddItem(GetItemId(1));
316   syncer::StringOrdinal position1 = item_list_.item_at(1)->position();
317   EXPECT_TRUE(position1.GreaterThan(position0));
318   new_position = CreatePositionBefore(position1);
319   EXPECT_TRUE(new_position.GreaterThan(position0));
320   EXPECT_TRUE(new_position.LessThan(position1));
321
322   // Invalid ordinal should return a position at the end of the list.
323   new_position = CreatePositionBefore(syncer::StringOrdinal());
324   EXPECT_TRUE(new_position.GreaterThan(position1));
325 }
326
327 TEST_F(AppListItemListTest, SetItemPosition) {
328   CreateAndAddItem(GetItemId(0));
329   CreateAndAddItem(GetItemId(1));
330   CreateAndAddItem(GetItemId(2));
331   CreateAndAddItem(GetItemId(3));
332   EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
333
334   // No change to position.
335   item_list_.SetItemPosition(item_list_.item_at(0),
336                              item_list_.item_at(0)->position());
337   EXPECT_TRUE(VerifyItemListOrdinals());
338   EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
339   // No order change.
340   item_list_.SetItemPosition(item_list_.item_at(0),
341                              item_list_.item_at(0)->position().CreateBetween(
342                                  item_list_.item_at(1)->position()));
343   EXPECT_TRUE(VerifyItemListOrdinals());
344   EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
345   // 0 -> 1
346   item_list_.SetItemPosition(item_list_.item_at(0),
347                              item_list_.item_at(1)->position().CreateBetween(
348                                  item_list_.item_at(2)->position()));
349   EXPECT_TRUE(VerifyItemListOrdinals());
350   EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
351   // 1 -> 2
352   item_list_.SetItemPosition(item_list_.item_at(1),
353                              item_list_.item_at(2)->position().CreateBetween(
354                                  item_list_.item_at(3)->position()));
355   EXPECT_TRUE(VerifyItemListOrdinals());
356   EXPECT_TRUE(VerifyItemOrder4(1, 2, 0, 3));
357   // 0 -> last
358   item_list_.SetItemPosition(item_list_.item_at(0),
359                              item_list_.item_at(3)->position().CreateAfter());
360   EXPECT_TRUE(VerifyItemListOrdinals());
361   EXPECT_TRUE(VerifyItemOrder4(2, 0, 3, 1));
362   // last -> last
363   item_list_.SetItemPosition(item_list_.item_at(3),
364                              item_list_.item_at(3)->position().CreateAfter());
365   EXPECT_TRUE(VerifyItemListOrdinals());
366   EXPECT_TRUE(VerifyItemOrder4(2, 0, 3, 1));
367 }
368
369 }  // namespace app_list