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