blob: 4621d94fbdd92e60ee57328e81d50851f81c0c80 [file] [log] [blame]
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "app/tree_node_model.h"
#include "base/string16.h"
#include "base/string_number_conversions.h"
#include "base/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
class TreeNodeModelTest : public testing::Test, public TreeModelObserver {
public:
TreeNodeModelTest()
: added_count_(0),
removed_count_(0),
changed_count_(0) {}
void AssertObserverCount(int added_count, int removed_count,
int changed_count) {
ASSERT_EQ(added_count, added_count_);
ASSERT_EQ(removed_count, removed_count_);
ASSERT_EQ(changed_count, changed_count_);
}
void ClearCounts() {
added_count_ = removed_count_ = changed_count_ = 0;
}
// Begin TreeModelObserver implementation.
virtual void TreeNodesAdded(TreeModel* model, TreeModelNode* parent,
int start, int count) {
added_count_++;
}
virtual void TreeNodesRemoved(TreeModel* model, TreeModelNode* parent,
int start, int count) {
removed_count_++;
}
virtual void TreeNodeChanged(TreeModel* model, TreeModelNode* node) {
changed_count_++;
}
// End TreeModelObserver implementation.
private:
int added_count_;
int removed_count_;
int changed_count_;
DISALLOW_COPY_AND_ASSIGN(TreeNodeModelTest);
};
// Verify if the model is properly adding a new node in the tree and
// notifying the observers.
// The tree looks like this:
// root
// |-- child1
// | |-- foo1
// | |-- foo2
// +-- child2
TEST_F(TreeNodeModelTest, AddNode) {
TreeNodeWithValue<int>* root =
new TreeNodeWithValue<int>(ASCIIToUTF16("root"), 0);
TreeNodeModel<TreeNodeWithValue<int> > model(root);
model.AddObserver(this);
ClearCounts();
// Create the first root child.
TreeNodeWithValue<int>* child1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child 1"), 1);
model.Add(root, 0, child1);
AssertObserverCount(1, 0, 0);
// Add two nodes under the |child1|.
TreeNodeWithValue<int>* foo1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("foo1"), 3);
TreeNodeWithValue<int>* foo2 =
new TreeNodeWithValue<int>(ASCIIToUTF16("foo2"), 4);
child1->Add(0, foo1);
child1->Add(1, foo2);
// Create the second root child.
TreeNodeWithValue<int>* child2 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child 2"), 2);
root->Add(1, child2);
// Check if there is two nodes under the root.
ASSERT_EQ(2, model.GetChildCount(root));
// Check if there is two nodes under |child1|.
ASSERT_EQ(2, model.GetChildCount(child1));
// Check if there is none nodes under |child2|.
ASSERT_EQ(0, model.GetChildCount(child2));
}
// Verify if the model is properly removing a node from the tree
// and notifying the observers.
TEST_F(TreeNodeModelTest, RemoveNode) {
TreeNodeWithValue<int>* root =
new TreeNodeWithValue<int>(ASCIIToUTF16("root"), 0);
TreeNodeModel<TreeNodeWithValue<int> > model(root);
model.AddObserver(this);
ClearCounts();
// Create the first child node.
TreeNodeWithValue<int>* child1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child 1"), 1);
// And add it to the root node.
root->Add(0, child1);
ASSERT_EQ(1, model.GetChildCount(root));
// Now remove the |child1| from root and release the memory.
delete model.Remove(root, 0);
AssertObserverCount(0, 1, 0);
ASSERT_EQ(0, model.GetChildCount(root));
}
// Verify if the nodes added under the root are all deleted when calling
// RemoveAll. Note that is responsability of the caller to free the memory
// of the nodes removed after RemoveAll is called.
// The tree looks like this:
// root
// |-- child1
// | |-- foo1
// | |-- child0
// | |-- child1
// +-------|-- child2
TEST_F(TreeNodeModelTest, RemoveAllNodes) {
TreeNodeWithValue<int>* root =
new TreeNodeWithValue<int>(ASCIIToUTF16("root"), 0);
TreeNodeModel<TreeNodeWithValue<int> > model(root);
model.AddObserver(this);
ClearCounts();
// Create the first child node.
TreeNodeWithValue<int>* child1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child 1"), 1);
model.Add(root, 0, child1);
TreeNodeWithValue<int>* foo1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("foo1"), 2);
model.Add(child1, 0, foo1);
// Add some nodes to |foo1|.
for (int i = 0; i < 3; ++i) {
model.Add(foo1, i,
new TreeNodeWithValue<int>(ASCIIToUTF16("child") +
base::IntToString16(i), i));
}
ASSERT_EQ(3, model.GetChildCount(foo1));
// Now remove all nodes from root.
root->RemoveAll();
// Release memory, so we don't leak.
delete child1;
ASSERT_EQ(0, model.GetChildCount(root));
}
// Verify if the model returns correct indexes for the specified nodes.
// The tree looks like this:
// root
// |-- child1
// | |-- foo1
// +-- child2
TEST_F(TreeNodeModelTest, IndexOfChild) {
TreeNodeWithValue<int>* root =
new TreeNodeWithValue<int>(ASCIIToUTF16("root"), 0);
TreeNodeModel<TreeNodeWithValue<int> > model(root);
model.AddObserver(this);
ClearCounts();
TreeNodeWithValue<int>* child1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child 1"), 1);
model.Add(root, 0, child1);
TreeNodeWithValue<int>* child2 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child 2"), 2);
model.Add(root, 1, child2);
TreeNodeWithValue<int>* foo1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("foo1"), 0);
model.Add(child1, 0, foo1);
ASSERT_EQ(0, model.IndexOfChild(root, child1));
ASSERT_EQ(1, model.IndexOfChild(root, child2));
ASSERT_EQ(0, model.IndexOfChild(child1, foo1));
ASSERT_EQ(-1, model.IndexOfChild(root, foo1));
}
// Verify whether a specified node has or not an ancestor.
// The tree looks like this:
// root
// |-- child1
// |-- child2
TEST_F(TreeNodeModelTest, HasAncestor) {
TreeNodeWithValue<int>* root =
new TreeNodeWithValue<int>(ASCIIToUTF16("root"), 0);
TreeNodeModel<TreeNodeWithValue<int> > model(root);
TreeNodeWithValue<int>* child1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child 1"), 0);
model.Add(root, 0, child1);
TreeNodeWithValue<int>* child2 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child 2"), 1);
model.Add(root, 1, child2);
ASSERT_TRUE(root->HasAncestor(root));
ASSERT_FALSE(root->HasAncestor(child1));
ASSERT_TRUE(child1->HasAncestor(root));
ASSERT_FALSE(child1->HasAncestor(child2));
ASSERT_FALSE(child2->HasAncestor(child1));
}
// The tree looks like this:
// root
// |-- child1
// | |-- child2
// | |-- child3
// |-- foo1
// | |-- foo2
// | |-- foo3
// | |-- foo4
// +-- bar1
//
// The TotalNodeCount of root is: 9
// The TotalNodeCount of child1 is: 3
// The TotalNodeCount of bar1 is: 1
// And so on...
// The purpose here is to verify if the function returns the total of nodes
// under the specifed node correctly. The count should include the node it self.
TEST_F(TreeNodeModelTest, GetTotalNodeCount) {
TreeNodeWithValue<int>* root =
new TreeNodeWithValue<int>(ASCIIToUTF16("root"), 0);
TreeNodeModel<TreeNodeWithValue<int> > model(root);
TreeNodeWithValue<int>* child1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child1"), 1);
TreeNodeWithValue<int>* child2 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child2"), 2);
TreeNodeWithValue<int>* child3 =
new TreeNodeWithValue<int>(ASCIIToUTF16("child3"), 3);
TreeNodeWithValue<int>* foo1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("foo1"), 4);
TreeNodeWithValue<int>* foo2 =
new TreeNodeWithValue<int>(ASCIIToUTF16("foo2"), 5);
TreeNodeWithValue<int>* foo3 =
new TreeNodeWithValue<int>(ASCIIToUTF16("foo3"), 6);
TreeNodeWithValue<int>* foo4 =
new TreeNodeWithValue<int>(ASCIIToUTF16("foo4"), 7);
TreeNodeWithValue<int>* bar1 =
new TreeNodeWithValue<int>(ASCIIToUTF16("bar1"), 8);
model.Add(root, 0, child1);
model.Add(child1, 0, child2);
model.Add(child2, 0, child3);
model.Add(root, 1, foo1);
model.Add(foo1, 0, foo2);
model.Add(foo1, 1, foo4);
model.Add(foo2, 0, foo3);
model.Add(root, 0, bar1);
ASSERT_EQ(9, root->GetTotalNodeCount());
ASSERT_EQ(3, child1->GetTotalNodeCount());
ASSERT_EQ(1, bar1->GetTotalNodeCount());
ASSERT_EQ(2, foo2->GetTotalNodeCount());
}
// Makes sure that we are notified when the node is renamed,
// also makes sure the node is properly renamed.
TEST_F(TreeNodeModelTest, SetTitle) {
TreeNodeWithValue<int>* root =
new TreeNodeWithValue<int>(ASCIIToUTF16("root"), 0);
TreeNodeModel<TreeNodeWithValue<int> > model(root);
model.AddObserver(this);
ClearCounts();
const string16 title(ASCIIToUTF16("root2"));
model.SetTitle(root, title);
AssertObserverCount(0, 0, 1);
EXPECT_EQ(title, root->GetTitle());
}