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"
18 class TestObserver : public AppListItemListObserver {
25 virtual ~TestObserver() {
28 // AppListItemListObserver overriden:
29 virtual void OnListItemAdded(size_t index, AppListItem* item) OVERRIDE {
33 virtual void OnListItemRemoved(size_t index, AppListItem* item) OVERRIDE {
37 size_t items_added() const { return items_added_; }
38 size_t items_removed() const { return items_removed_; }
42 size_t items_removed_;
44 DISALLOW_COPY_AND_ASSIGN(TestObserver);
47 std::string GetItemName(int id) {
48 return base::StringPrintf("Item %d", id);
53 class AppListItemListTest : public testing::Test {
55 AppListItemListTest() {}
56 virtual ~AppListItemListTest() {}
58 // testing::Test overrides:
59 virtual void SetUp() OVERRIDE {
60 item_list_.AddObserver(&observer_);
63 virtual void TearDown() OVERRIDE {
64 item_list_.RemoveObserver(&observer_);
68 scoped_ptr<AppListItem> CreateItem(const std::string& title,
69 const std::string& full_name) {
70 scoped_ptr<AppListItem> item(new AppListItem(title));
71 size_t nitems = item_list_.item_count();
72 syncer::StringOrdinal position;
74 position = syncer::StringOrdinal::CreateInitialOrdinal();
76 position = item_list_.item_at(nitems - 1)->position().CreateAfter();
77 item->set_position(position);
78 item->SetTitleAndFullName(title, full_name);
82 AppListItem* CreateAndAddItem(const std::string& title,
83 const std::string& full_name) {
84 scoped_ptr<AppListItem> item(CreateItem(title, full_name));
85 return item_list_.AddItem(item.Pass());
88 scoped_ptr<AppListItem> RemoveItem(const std::string& id) {
89 return item_list_.RemoveItem(id);
92 scoped_ptr<AppListItem> RemoveItemAt(size_t index) {
93 return item_list_.RemoveItemAt(index);
96 syncer::StringOrdinal CreatePositionBefore(
97 const syncer::StringOrdinal& position) {
98 return item_list_.CreatePositionBefore(position);
101 bool VerifyItemListOrdinals() {
103 for (size_t i = 1; i < item_list_.item_count(); ++i) {
104 res &= (item_list_.item_at(i - 1)->position().LessThan(
105 item_list_.item_at(i)->position()));
112 bool VerifyItemOrder4(size_t a, size_t b, size_t c, size_t d) {
113 if ((GetItemName(a) == item_list_.item_at(0)->id()) &&
114 (GetItemName(b) == item_list_.item_at(1)->id()) &&
115 (GetItemName(c) == item_list_.item_at(2)->id()) &&
116 (GetItemName(d) == item_list_.item_at(3)->id()))
124 for (size_t i = 0; i < item_list_.item_count(); ++i)
125 VLOG(1) << " " << item_list_.item_at(i)->ToDebugString();
128 AppListItemList item_list_;
129 TestObserver observer_;
132 DISALLOW_COPY_AND_ASSIGN(AppListItemListTest);
135 TEST_F(AppListItemListTest, FindItemIndex) {
136 AppListItem* item_0 = CreateAndAddItem(GetItemName(0), GetItemName(0));
137 AppListItem* item_1 = CreateAndAddItem(GetItemName(1), GetItemName(1));
138 AppListItem* item_2 = CreateAndAddItem(GetItemName(2), GetItemName(2));
139 EXPECT_EQ(observer_.items_added(), 3u);
140 EXPECT_EQ(item_list_.item_count(), 3u);
141 EXPECT_EQ(item_0, item_list_.item_at(0));
142 EXPECT_EQ(item_1, item_list_.item_at(1));
143 EXPECT_EQ(item_2, item_list_.item_at(2));
144 EXPECT_TRUE(VerifyItemListOrdinals());
147 EXPECT_TRUE(item_list_.FindItemIndex(item_0->id(), &index));
148 EXPECT_EQ(index, 0u);
149 EXPECT_TRUE(item_list_.FindItemIndex(item_1->id(), &index));
150 EXPECT_EQ(index, 1u);
151 EXPECT_TRUE(item_list_.FindItemIndex(item_2->id(), &index));
152 EXPECT_EQ(index, 2u);
154 scoped_ptr<AppListItem> item_3(
155 CreateItem(GetItemName(3), GetItemName(3)));
156 EXPECT_FALSE(item_list_.FindItemIndex(item_3->id(), &index));
159 TEST_F(AppListItemListTest, RemoveItemAt) {
160 AppListItem* item_0 = CreateAndAddItem(GetItemName(0), GetItemName(0));
161 AppListItem* item_1 = CreateAndAddItem(GetItemName(1), GetItemName(1));
162 AppListItem* item_2 = CreateAndAddItem(GetItemName(2), GetItemName(2));
163 EXPECT_EQ(item_list_.item_count(), 3u);
164 EXPECT_EQ(observer_.items_added(), 3u);
166 EXPECT_TRUE(item_list_.FindItemIndex(item_1->id(), &index));
167 EXPECT_EQ(index, 1u);
168 EXPECT_TRUE(VerifyItemListOrdinals());
170 scoped_ptr<AppListItem> item_removed = RemoveItemAt(1);
171 EXPECT_EQ(item_removed, item_1);
172 EXPECT_FALSE(item_list_.FindItem(item_1->id()));
173 EXPECT_EQ(item_list_.item_count(), 2u);
174 EXPECT_EQ(observer_.items_removed(), 1u);
175 EXPECT_EQ(item_list_.item_at(0), item_0);
176 EXPECT_EQ(item_list_.item_at(1), item_2);
177 EXPECT_TRUE(VerifyItemListOrdinals());
180 TEST_F(AppListItemListTest, RemoveItem) {
181 AppListItem* item_0 = CreateAndAddItem(GetItemName(0), GetItemName(0));
182 AppListItem* item_1 = CreateAndAddItem(GetItemName(1), GetItemName(1));
183 AppListItem* item_2 = CreateAndAddItem(GetItemName(2), GetItemName(2));
184 EXPECT_EQ(item_list_.item_count(), 3u);
185 EXPECT_EQ(observer_.items_added(), 3u);
186 EXPECT_EQ(item_0, item_list_.item_at(0));
187 EXPECT_EQ(item_1, item_list_.item_at(1));
188 EXPECT_EQ(item_2, item_list_.item_at(2));
189 EXPECT_TRUE(VerifyItemListOrdinals());
192 EXPECT_TRUE(item_list_.FindItemIndex(item_1->id(), &index));
193 EXPECT_EQ(index, 1u);
195 scoped_ptr<AppListItem> item_removed = RemoveItem(item_1->id());
196 EXPECT_EQ(item_removed, item_1);
197 EXPECT_FALSE(item_list_.FindItem(item_1->id()));
198 EXPECT_EQ(item_list_.item_count(), 2u);
199 EXPECT_EQ(observer_.items_removed(), 1u);
200 EXPECT_TRUE(VerifyItemListOrdinals());
202 scoped_ptr<AppListItem> not_found_item = RemoveItem("Bogus");
203 EXPECT_FALSE(not_found_item.get());
206 TEST_F(AppListItemListTest, MoveItem) {
207 CreateAndAddItem(GetItemName(0), GetItemName(0));
208 CreateAndAddItem(GetItemName(1), GetItemName(1));
209 CreateAndAddItem(GetItemName(2), GetItemName(2));
210 CreateAndAddItem(GetItemName(3), GetItemName(3));
211 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
213 item_list_.MoveItem(0, 1);
214 EXPECT_TRUE(VerifyItemListOrdinals());
215 EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
217 item_list_.MoveItem(1, 2);
218 EXPECT_TRUE(VerifyItemListOrdinals());
219 EXPECT_TRUE(VerifyItemOrder4(1, 2, 0, 3));
221 item_list_.MoveItem(2, 3);
222 EXPECT_TRUE(VerifyItemListOrdinals());
223 EXPECT_TRUE(VerifyItemOrder4(1, 2, 3, 0));
225 item_list_.MoveItem(3, 0);
226 EXPECT_TRUE(VerifyItemListOrdinals());
227 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
229 item_list_.MoveItem(0, 3);
230 EXPECT_TRUE(VerifyItemListOrdinals());
231 EXPECT_TRUE(VerifyItemOrder4(1, 2, 3, 0));
234 TEST_F(AppListItemListTest, CreatePositionBefore) {
235 CreateAndAddItem(GetItemName(0), GetItemName(0));
236 syncer::StringOrdinal position0 = item_list_.item_at(0)->position();
237 syncer::StringOrdinal new_position;
238 new_position = CreatePositionBefore(position0.CreateBefore());
239 EXPECT_TRUE(new_position.LessThan(position0));
240 new_position = CreatePositionBefore(position0);
241 EXPECT_TRUE(new_position.LessThan(position0));
242 new_position = CreatePositionBefore(position0.CreateAfter());
243 EXPECT_TRUE(new_position.GreaterThan(position0));
245 CreateAndAddItem(GetItemName(1), GetItemName(1));
246 syncer::StringOrdinal position1 = item_list_.item_at(1)->position();
247 EXPECT_TRUE(position1.GreaterThan(position0));
248 new_position = CreatePositionBefore(position1);
249 EXPECT_TRUE(new_position.GreaterThan(position0));
250 EXPECT_TRUE(new_position.LessThan(position1));
252 // Invalid ordinal should return a position at the end of the list.
253 new_position = CreatePositionBefore(syncer::StringOrdinal());
254 EXPECT_TRUE(new_position.GreaterThan(position1));
257 TEST_F(AppListItemListTest, SetItemPosition) {
258 CreateAndAddItem(GetItemName(0), GetItemName(0));
259 CreateAndAddItem(GetItemName(1), GetItemName(1));
260 CreateAndAddItem(GetItemName(2), GetItemName(2));
261 CreateAndAddItem(GetItemName(3), GetItemName(3));
262 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
264 // No change to position.
265 item_list_.SetItemPosition(item_list_.item_at(0),
266 item_list_.item_at(0)->position());
267 EXPECT_TRUE(VerifyItemListOrdinals());
268 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
270 item_list_.SetItemPosition(item_list_.item_at(0),
271 item_list_.item_at(0)->position().CreateBetween(
272 item_list_.item_at(1)->position()));
273 EXPECT_TRUE(VerifyItemListOrdinals());
274 EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
276 item_list_.SetItemPosition(item_list_.item_at(0),
277 item_list_.item_at(1)->position().CreateBetween(
278 item_list_.item_at(2)->position()));
279 EXPECT_TRUE(VerifyItemListOrdinals());
280 EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
282 item_list_.SetItemPosition(item_list_.item_at(1),
283 item_list_.item_at(2)->position().CreateBetween(
284 item_list_.item_at(3)->position()));
285 EXPECT_TRUE(VerifyItemListOrdinals());
286 EXPECT_TRUE(VerifyItemOrder4(1, 2, 0, 3));
288 item_list_.SetItemPosition(item_list_.item_at(0),
289 item_list_.item_at(3)->position().CreateAfter());
290 EXPECT_TRUE(VerifyItemListOrdinals());
291 EXPECT_TRUE(VerifyItemOrder4(2, 0, 3, 1));
293 item_list_.SetItemPosition(item_list_.item_at(3),
294 item_list_.item_at(3)->position().CreateAfter());
295 EXPECT_TRUE(VerifyItemListOrdinals());
296 EXPECT_TRUE(VerifyItemOrder4(2, 0, 3, 1));
299 } // namespace app_list