Home | History | Annotate | Download | only in models
      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 
     12 namespace ui {
     13 
     14 class 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 
     25 class 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 
     72 TEST_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 
     97 TEST_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 
    120 TEST_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 
    139 TEST_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 
    157 TEST_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