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 15using base::ASCIIToUTF16; 16 17namespace ui { 18 19class 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 60typedef 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 70TEST_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. 95TEST_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 125TEST_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 163TEST_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 197TEST_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... 247TEST_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. 281TEST_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 292TEST_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 314TEST_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