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