1// Copyright (c) 2012 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/base/models/list_model.h"
6
7#include "base/basictypes.h"
8#include "base/compiler_specific.h"
9#include "base/memory/scoped_ptr.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace ui {
13
14class FooItem {
15 public:
16  explicit FooItem(int id) : id_(id) {}
17
18  int id() const { return id_; }
19
20 private:
21  int id_;
22  DISALLOW_COPY_AND_ASSIGN(FooItem);
23};
24
25class ListModelTest : public testing::Test,
26                      public ListModelObserver {
27 public:
28  ListModelTest()
29      : added_count_(0),
30        removed_count_(0),
31        moved_count_(0),
32        changed_count_(0) {
33  }
34
35  void ExpectCountsEqual(size_t added_count,
36                         size_t removed_count,
37                         size_t moved_count,
38                         size_t changed_count) {
39    EXPECT_EQ(added_count, added_count_);
40    EXPECT_EQ(removed_count, removed_count_);
41    EXPECT_EQ(moved_count, moved_count_);
42    EXPECT_EQ(changed_count, changed_count_);
43  }
44
45  void ClearCounts() {
46    added_count_ = removed_count_ = moved_count_ = changed_count_ = 0;
47  }
48
49  // ListModelObserver implementation:
50  virtual void ListItemsAdded(size_t start, size_t count) OVERRIDE {
51    added_count_ += count;
52  }
53  virtual void ListItemsRemoved(size_t start, size_t count) OVERRIDE {
54    removed_count_ += count;
55  }
56  virtual void ListItemMoved(size_t index, size_t target_index) OVERRIDE {
57    ++moved_count_;
58  }
59  virtual void ListItemsChanged(size_t start, size_t count) OVERRIDE {
60    changed_count_ += count;
61  }
62
63 private:
64  size_t added_count_;
65  size_t removed_count_;
66  size_t moved_count_;
67  size_t changed_count_;
68
69  DISALLOW_COPY_AND_ASSIGN(ListModelTest);
70};
71
72TEST_F(ListModelTest, Add) {
73  ListModel<FooItem> model;
74  model.AddObserver(this);
75
76  // Append FooItem(0)
77  model.Add(new FooItem(0));
78  ExpectCountsEqual(1, 0, 0, 0);
79
80  // Append FooItem(1)
81  model.Add(new FooItem(1));
82  ExpectCountsEqual(2, 0, 0, 0);
83
84  // Insert FooItem(2) at position 0
85  model.AddAt(0, new FooItem(2));
86  ExpectCountsEqual(3, 0, 0, 0);
87
88  // Total 3 items in model.
89  EXPECT_EQ(3U, model.item_count());
90
91  // First one should be FooItem(2), followed by FooItem(0) and FooItem(1)
92  EXPECT_EQ(2, model.GetItemAt(0)->id());
93  EXPECT_EQ(0, model.GetItemAt(1)->id());
94  EXPECT_EQ(1, model.GetItemAt(2)->id());
95}
96
97TEST_F(ListModelTest, Remove) {
98  ListModel<FooItem> model;
99  model.AddObserver(this);
100
101  model.Add(new FooItem(0));
102  model.Add(new FooItem(1));
103  model.Add(new FooItem(2));
104
105  ClearCounts();
106
107  // Remove item at index 1 from model and release memory.
108  model.DeleteAt(1);
109  ExpectCountsEqual(0, 1, 0, 0);
110
111  EXPECT_EQ(2U, model.item_count());
112  EXPECT_EQ(0, model.GetItemAt(0)->id());
113  EXPECT_EQ(2, model.GetItemAt(1)->id());
114
115  // Remove all items from model and delete them.
116  model.DeleteAll();
117  ExpectCountsEqual(0, 3, 0, 0);
118}
119
120TEST_F(ListModelTest, RemoveAll) {
121  ListModel<FooItem> model;
122  model.AddObserver(this);
123
124  scoped_ptr<FooItem> foo0(new FooItem(0));
125  scoped_ptr<FooItem> foo1(new FooItem(1));
126  scoped_ptr<FooItem> foo2(new FooItem(2));
127
128  model.Add(foo0.get());
129  model.Add(foo1.get());
130  model.Add(foo2.get());
131
132  ClearCounts();
133
134  // Remove all items and scoped_ptr above would release memory.
135  model.RemoveAll();
136  ExpectCountsEqual(0, 3, 0, 0);
137}
138
139TEST_F(ListModelTest, Move) {
140  ListModel<FooItem> model;
141  model.AddObserver(this);
142
143  model.Add(new FooItem(0));
144  model.Add(new FooItem(1));
145  model.Add(new FooItem(2));
146
147  ClearCounts();
148
149  // Moves item at index 0 to index 2.
150  model.Move(0, 2);
151  ExpectCountsEqual(0, 0, 1, 0);
152  EXPECT_EQ(1, model.GetItemAt(0)->id());
153  EXPECT_EQ(2, model.GetItemAt(1)->id());
154  EXPECT_EQ(0, model.GetItemAt(2)->id());
155}
156
157TEST_F(ListModelTest, FakeUpdate) {
158  ListModel<FooItem> model;
159  model.AddObserver(this);
160
161  model.Add(new FooItem(0));
162  model.Add(new FooItem(1));
163  model.Add(new FooItem(2));
164
165  ClearCounts();
166
167  model.NotifyItemsChanged(0, 1);
168  ExpectCountsEqual(0, 0, 0, 1);
169
170  model.NotifyItemsChanged(1, 2);
171  ExpectCountsEqual(0, 0, 0, 3);
172}
173
174}  // namespace ui
175