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/tree_node_model.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/compiler_specific.h"
      9 #include "base/memory/scoped_ptr.h"
     10 #include "base/strings/string16.h"
     11 #include "base/strings/stringprintf.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 using base::ASCIIToUTF16;
     16 
     17 namespace ui {
     18 
     19 class TreeNodeModelTest : public testing::Test, public TreeModelObserver {
     20  public:
     21   TreeNodeModelTest()
     22       : added_count_(0),
     23         removed_count_(0),
     24         changed_count_(0) {}
     25   virtual ~TreeNodeModelTest() {}
     26 
     27  protected:
     28   std::string GetObserverCountStateAndClear() {
     29     std::string result(base::StringPrintf("added=%d removed=%d changed=%d",
     30         added_count_, removed_count_, changed_count_));
     31     added_count_ = removed_count_ = changed_count_ = 0;
     32     return result;
     33   }
     34 
     35  private:
     36   // Overridden from TreeModelObserver:
     37   virtual void TreeNodesAdded(TreeModel* model,
     38                               TreeModelNode* parent,
     39                               int start,
     40                               int count) OVERRIDE {
     41     added_count_++;
     42   }
     43   virtual void TreeNodesRemoved(TreeModel* model,
     44                                 TreeModelNode* parent,
     45                                 int start,
     46                                 int count) OVERRIDE {
     47     removed_count_++;
     48   }
     49   virtual void TreeNodeChanged(TreeModel* model, TreeModelNode* node) OVERRIDE {
     50     changed_count_++;
     51   }
     52 
     53   int added_count_;
     54   int removed_count_;
     55   int changed_count_;
     56 
     57   DISALLOW_COPY_AND_ASSIGN(TreeNodeModelTest);
     58 };
     59 
     60 typedef TreeNodeWithValue<int> TestNode;
     61 
     62 // Verifies if the model is properly adding a new node in the tree and
     63 // notifying the observers.
     64 // The tree looks like this:
     65 // root
     66 // +-- child1
     67 //     +-- foo1
     68 //     +-- foo2
     69 // +-- child2
     70 TEST_F(TreeNodeModelTest, AddNode) {
     71   TestNode* root = new TestNode;
     72   TreeNodeModel<TestNode > model(root);
     73   model.AddObserver(this);
     74 
     75   TestNode* child1 = new TestNode;
     76   model.Add(root, child1, 0);
     77 
     78   EXPECT_EQ("added=1 removed=0 changed=0", GetObserverCountStateAndClear());
     79 
     80   for (int i = 0; i < 2; ++i)
     81     child1->Add(new TestNode, i);
     82 
     83   TestNode* child2 = new TestNode;
     84   model.Add(root, child2, 1);
     85 
     86   EXPECT_EQ("added=1 removed=0 changed=0", GetObserverCountStateAndClear());
     87 
     88   EXPECT_EQ(2, root->child_count());
     89   EXPECT_EQ(2, child1->child_count());
     90   EXPECT_EQ(0, child2->child_count());
     91 }
     92 
     93 // Verifies if the model is properly removing a node from the tree
     94 // and notifying the observers.
     95 TEST_F(TreeNodeModelTest, RemoveNode) {
     96   TestNode* root = new TestNode;
     97   TreeNodeModel<TestNode > model(root);
     98   model.AddObserver(this);
     99 
    100   TestNode* child1 = new TestNode;
    101   root->Add(child1, 0);
    102 
    103   EXPECT_EQ(1, model.GetChildCount(root));
    104 
    105   // Now remove |child1| from |root| and release the memory.
    106   delete model.Remove(root, child1);
    107 
    108   EXPECT_EQ("added=0 removed=1 changed=0", GetObserverCountStateAndClear());
    109 
    110   EXPECT_EQ(0, model.GetChildCount(root));
    111 }
    112 
    113 // Verifies if the nodes added under the root are all deleted when calling
    114 // RemoveAll. Note that is responsability of the caller to free the memory
    115 // of the nodes removed after RemoveAll is called.
    116 // The tree looks like this:
    117 // root
    118 // +-- child1
    119 //     +-- foo
    120 //         +-- bar0
    121 //         +-- bar1
    122 //         +-- bar2
    123 // +-- child2
    124 // +-- child3
    125 TEST_F(TreeNodeModelTest, RemoveAllNodes) {
    126   TestNode root;
    127 
    128   TestNode child1;
    129   TestNode child2;
    130   TestNode child3;
    131 
    132   root.Add(&child1, 0);
    133   root.Add(&child2, 1);
    134   root.Add(&child3, 2);
    135 
    136   TestNode* foo = new TestNode;
    137   child1.Add(foo, 0);
    138 
    139   // Add some nodes to |foo|.
    140   for (int i = 0; i < 3; ++i)
    141     foo->Add(new TestNode, i);
    142 
    143   EXPECT_EQ(3, root.child_count());
    144   EXPECT_EQ(1, child1.child_count());
    145   EXPECT_EQ(3, foo->child_count());
    146 
    147   // Now remove the child nodes from root.
    148   root.RemoveAll();
    149 
    150   EXPECT_EQ(0, root.child_count());
    151   EXPECT_TRUE(root.empty());
    152 
    153   EXPECT_EQ(1, child1.child_count());
    154   EXPECT_EQ(3, foo->child_count());
    155 }
    156 
    157 // Verifies if GetIndexOf() returns the correct index for the specified node.
    158 // The tree looks like this:
    159 // root
    160 // +-- child1
    161 //     +-- foo1
    162 // +-- child2
    163 TEST_F(TreeNodeModelTest, GetIndexOf) {
    164   TestNode root;
    165 
    166   TestNode* child1 = new TestNode;
    167   root.Add(child1, 0);
    168 
    169   TestNode* child2 = new TestNode;
    170   root.Add(child2, 1);
    171 
    172   TestNode* foo1 = new TestNode;
    173   child1->Add(foo1, 0);
    174 
    175   EXPECT_EQ(-1, root.GetIndexOf(&root));
    176   EXPECT_EQ(0, root.GetIndexOf(child1));
    177   EXPECT_EQ(1, root.GetIndexOf(child2));
    178   EXPECT_EQ(-1, root.GetIndexOf(foo1));
    179 
    180   EXPECT_EQ(-1, child1->GetIndexOf(&root));
    181   EXPECT_EQ(-1, child1->GetIndexOf(child1));
    182   EXPECT_EQ(-1, child1->GetIndexOf(child2));
    183   EXPECT_EQ(0, child1->GetIndexOf(foo1));
    184 
    185   EXPECT_EQ(-1, child2->GetIndexOf(&root));
    186   EXPECT_EQ(-1, child2->GetIndexOf(child2));
    187   EXPECT_EQ(-1, child2->GetIndexOf(child1));
    188   EXPECT_EQ(-1, child2->GetIndexOf(foo1));
    189 }
    190 
    191 // Verifies whether a specified node has or not an ancestor.
    192 // The tree looks like this:
    193 // root
    194 // +-- child1
    195 //     +-- foo1
    196 // +-- child2
    197 TEST_F(TreeNodeModelTest, HasAncestor) {
    198   TestNode root;
    199   TestNode* child1 = new TestNode;
    200   TestNode* child2 = new TestNode;
    201 
    202   root.Add(child1, 0);
    203   root.Add(child2, 1);
    204 
    205   TestNode* foo1 = new TestNode;
    206   child1->Add(foo1, 0);
    207 
    208   EXPECT_TRUE(root.HasAncestor(&root));
    209   EXPECT_FALSE(root.HasAncestor(child1));
    210   EXPECT_FALSE(root.HasAncestor(child2));
    211   EXPECT_FALSE(root.HasAncestor(foo1));
    212 
    213   EXPECT_TRUE(child1->HasAncestor(child1));
    214   EXPECT_TRUE(child1->HasAncestor(&root));
    215   EXPECT_FALSE(child1->HasAncestor(child2));
    216   EXPECT_FALSE(child1->HasAncestor(foo1));
    217 
    218   EXPECT_TRUE(child2->HasAncestor(child2));
    219   EXPECT_TRUE(child2->HasAncestor(&root));
    220   EXPECT_FALSE(child2->HasAncestor(child1));
    221   EXPECT_FALSE(child2->HasAncestor(foo1));
    222 
    223   EXPECT_TRUE(foo1->HasAncestor(foo1));
    224   EXPECT_TRUE(foo1->HasAncestor(child1));
    225   EXPECT_TRUE(foo1->HasAncestor(&root));
    226   EXPECT_FALSE(foo1->HasAncestor(child2));
    227 }
    228 
    229 // Verifies if GetTotalNodeCount returns the correct number of nodes from the
    230 // node specifed. The count should include the node itself.
    231 // The tree looks like this:
    232 // root
    233 // +-- child1
    234 //     +-- child2
    235 //         +-- child3
    236 // +-- foo1
    237 //     +-- foo2
    238 //         +-- foo3
    239 //     +-- foo4
    240 // +-- bar1
    241 //
    242 // The TotalNodeCount of root is:            9
    243 // The TotalNodeCount of child1 is:          3
    244 // The TotalNodeCount of child2 and foo2 is: 2
    245 // The TotalNodeCount of bar1 is:            1
    246 // And so on...
    247 TEST_F(TreeNodeModelTest, GetTotalNodeCount) {
    248   TestNode root;
    249 
    250   TestNode* child1 = new TestNode;
    251   TestNode* child2 = new TestNode;
    252   TestNode* child3 = new TestNode;
    253 
    254   root.Add(child1, 0);
    255   child1->Add(child2, 0);
    256   child2->Add(child3, 0);
    257 
    258   TestNode* foo1 = new TestNode;
    259   TestNode* foo2 = new TestNode;
    260   TestNode* foo3 = new TestNode;
    261   TestNode* foo4 = new TestNode;
    262 
    263   root.Add(foo1, 1);
    264   foo1->Add(foo2, 0);
    265   foo2->Add(foo3, 0);
    266   foo1->Add(foo4, 1);
    267 
    268   TestNode* bar1 = new TestNode;
    269 
    270   root.Add(bar1, 2);
    271 
    272   EXPECT_EQ(9, root.GetTotalNodeCount());
    273   EXPECT_EQ(3, child1->GetTotalNodeCount());
    274   EXPECT_EQ(2, child2->GetTotalNodeCount());
    275   EXPECT_EQ(2, foo2->GetTotalNodeCount());
    276   EXPECT_EQ(1, bar1->GetTotalNodeCount());
    277 }
    278 
    279 // Makes sure that we are notified when the node is renamed,
    280 // also makes sure the node is properly renamed.
    281 TEST_F(TreeNodeModelTest, SetTitle) {
    282   TestNode* root = new TestNode(ASCIIToUTF16("root"), 0);
    283   TreeNodeModel<TestNode > model(root);
    284   model.AddObserver(this);
    285 
    286   const base::string16 title(ASCIIToUTF16("root2"));
    287   model.SetTitle(root, title);
    288   EXPECT_EQ("added=0 removed=0 changed=1", GetObserverCountStateAndClear());
    289   EXPECT_EQ(title, root->GetTitle());
    290 }
    291 
    292 TEST_F(TreeNodeModelTest, BasicOperations) {
    293   TestNode root;
    294   EXPECT_EQ(0, root.child_count());
    295 
    296   TestNode* child1 = new TestNode;
    297   root.Add(child1, root.child_count());
    298   EXPECT_EQ(1, root.child_count());
    299   EXPECT_EQ(&root, child1->parent());
    300 
    301   TestNode* child2 = new TestNode;
    302   root.Add(child2, root.child_count());
    303   EXPECT_EQ(2, root.child_count());
    304   EXPECT_EQ(child1->parent(), child2->parent());
    305 
    306   scoped_ptr<TestNode > c2(root.Remove(child2));
    307   EXPECT_EQ(1, root.child_count());
    308   EXPECT_EQ(NULL, child2->parent());
    309 
    310   scoped_ptr<TestNode > c1(root.Remove(child1));
    311   EXPECT_EQ(0, root.child_count());
    312 }
    313 
    314 TEST_F(TreeNodeModelTest, IsRoot) {
    315   TestNode root;
    316   EXPECT_TRUE(root.is_root());
    317 
    318   TestNode* child1 = new TestNode;
    319   root.Add(child1, root.child_count());
    320   EXPECT_FALSE(child1->is_root());
    321 }
    322 
    323 }  // namespace ui
    324