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