blob: bc1d95416df41df0cb169750d4d1c786f2b7c6dc [file] [log] [blame]
// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "common/util/expandable_tree_view.h"
#include <sstream>
#include <vector>
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "common/util/vector_tree.h"
#include "common/util/vector_tree_test_util.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace verible {
namespace {
using ::testing::ElementsAre;
using verible::testing::NamedInterval;
using verible::testing::VectorTreeTestType;
using ExpandableTreeViewTestType =
ExpandableTreeView<VectorTree<NamedInterval>>;
// Test that basic Tree View operations work on a singleton node.
TEST(ExpandableTreeViewTest, RootOnly) {
const VectorTreeTestType tree(verible::testing::MakeRootOnlyExampleTree());
const auto &value = tree.Value();
// View testing.
const ExpandableTreeViewTestType tree_view(tree);
EXPECT_EQ(&tree_view.Value().Value(), &value);
EXPECT_TRUE(tree_view.Value().IsExpanded());
// Iterator testing.
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
EXPECT_EQ(&*iter, &value);
ExpandableTreeViewTestType::iterator copy(iter);
++iter;
EXPECT_NE(iter, copy);
EXPECT_EQ(iter, end); // There was only one node to visit, the root.
}
TEST(ExpandableTreeViewTest, OneChildPolicyFullyExpanded) {
const auto tree = verible::testing::MakeOneChildPolicyExampleTree();
const ExpandableTreeViewTestType tree_view(tree);
// Iterator testing.
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
ExpandableTreeViewTestType::iterator copy(iter);
EXPECT_EQ(iter->left, 0);
EXPECT_EQ(iter->right, 3);
// Fully expanded means reaching deepest child first.
EXPECT_EQ(iter->name, "gen2");
++iter;
EXPECT_NE(iter, copy);
// There was only one node to visit, the only grandchild.
EXPECT_EQ(iter, end);
}
TEST(ExpandableTreeViewTest, OneChildPolicyUnexpanded) {
const auto tree = verible::testing::MakeOneChildPolicyExampleTree();
ExpandableTreeViewTestType tree_view(tree);
tree_view.Value().Unexpand(); // Mark root node as un-expanded.
EXPECT_FALSE(tree_view.Value().IsExpanded());
// Iterator testing.
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
ExpandableTreeViewTestType::iterator copy(iter);
EXPECT_EQ(iter->left, 0);
EXPECT_EQ(iter->right, 3);
// Unexpanded: skip any of root's children
EXPECT_EQ(iter->name, "root");
++iter;
EXPECT_NE(iter, copy);
// There was only one node to visit, the root.
EXPECT_EQ(iter, end);
}
TEST(ExpandableTreeViewTest, OneChildPolicyPartiallyExpanded) {
const auto tree = verible::testing::MakeOneChildPolicyExampleTree();
ExpandableTreeViewTestType tree_view(tree);
tree_view[0].Value().Unexpand(); // Mark root node as un-expanded.
EXPECT_FALSE(tree_view[0].Value().IsExpanded());
// Iterator testing.
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
ExpandableTreeViewTestType::iterator copy(iter);
EXPECT_EQ(iter->left, 0);
EXPECT_EQ(iter->right, 3);
// Partially expanded: don't expand beyond direct child
EXPECT_EQ(iter->name, "gen1");
++iter;
EXPECT_NE(iter, copy);
// There was only one node to visit, the root's only child.
EXPECT_EQ(iter, end);
}
TEST(ExpandableTreeViewTest, FamilyTreeFullyExpanded) {
const auto tree = verible::testing::MakeExampleFamilyTree();
const ExpandableTreeViewTestType tree_view(tree);
// Fully-expanded, expect to visit all grandchildren, and nothing else.
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "child1");
iter++; // post-increment
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "child2");
iter++;
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "child3");
iter++;
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "child4");
iter++;
EXPECT_EQ(iter, end);
}
TEST(ExpandableTreeViewTest, FamilyTreeFullyExpandedStrJoin) {
const auto tree = verible::testing::MakeExampleFamilyTree();
const ExpandableTreeViewTestType tree_view(tree);
std::ostringstream stream;
stream << absl::StrJoin(tree_view.begin(), tree_view.end(), "\n",
absl::StreamFormatter());
EXPECT_EQ(stream.str(),
"(0, 1, child1)\n(1, 2, child2)\n(2, 3, child3)\n(3, 4, child4)");
}
TEST(ExpandableTreeViewTest, FamilyTreeUnexpanded) {
const auto tree = verible::testing::MakeExampleFamilyTree();
ExpandableTreeViewTestType tree_view(tree);
tree_view.Value().Unexpand(); // expect to only visit root
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "grandparent");
iter++;
EXPECT_EQ(iter, end);
}
TEST(ExpandableTreeViewTest, FamilyTreeExpandedMixed) {
const auto tree = verible::testing::MakeExampleFamilyTree();
ExpandableTreeViewTestType tree_view(tree);
// Unexpand only one of the parents.
tree_view[0].Value().Unexpand();
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "parent1");
iter++;
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "child3");
iter++;
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "child4");
iter++;
EXPECT_EQ(iter, end);
}
TEST(ExpandableTreeViewTest, FamilyTreeExpandedMixed2) {
const auto tree = verible::testing::MakeExampleFamilyTree();
ExpandableTreeViewTestType tree_view(tree);
// Unexpand only one of the parents.
tree_view[1].Value().Unexpand();
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "child1");
iter++;
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "child2");
iter++;
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "parent2");
iter++;
EXPECT_EQ(iter, end);
}
TEST(ExpandableTreeViewTest, FamilyTreeExpandedOneLevel) {
const auto tree = verible::testing::MakeExampleFamilyTree();
ExpandableTreeViewTestType tree_view(tree);
// Expand only one level.
tree_view[0].Value().Unexpand();
tree_view[1].Value().Unexpand();
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "parent1");
iter++;
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "parent2");
iter++;
EXPECT_EQ(iter, end);
}
// Tests that function can be applied that un-expands nodes in the tree view.
TEST(ExpandableTreeViewTest, FamilyTreeApplyPreOrder) {
const auto tree = verible::testing::MakeExampleFamilyTree();
ExpandableTreeViewTestType tree_view(tree);
std::vector<absl::string_view> visit_order;
tree_view.ApplyPreOrder(
[=, &visit_order](
VectorTree<TreeViewNodeInfo<VectorTree<NamedInterval>>> &node) {
const absl::string_view name = node.Value().Value().name;
visit_order.push_back(name);
if (name[0] == 'p') {
node.Value().Unexpand();
}
});
EXPECT_THAT(visit_order,
ElementsAre("grandparent", "parent1", "child1", "child2",
"parent2", "child3", "child4"));
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "parent1");
iter++;
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "parent2");
iter++;
EXPECT_EQ(iter, end);
}
// Tests that function can be applied that un-expands nodes in the tree view.
TEST(ExpandableTreeViewTest, FamilyTreeApplyPostOrder) {
const auto tree = verible::testing::MakeExampleFamilyTree();
ExpandableTreeViewTestType tree_view(tree);
std::vector<absl::string_view> visit_order;
tree_view.ApplyPostOrder(
[=, &visit_order](
VectorTree<TreeViewNodeInfo<VectorTree<NamedInterval>>> &node) {
const absl::string_view name = node.Value().Value().name;
visit_order.push_back(name);
if (name[0] == 'p' && name.back() == '1') {
node.Value().Unexpand();
}
});
EXPECT_THAT(visit_order, ElementsAre("child1", "child2", "parent1", "child3",
"child4", "parent2", "grandparent"));
ExpandableTreeViewTestType::iterator iter(tree_view.begin()),
end(tree_view.end());
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "parent1");
iter++;
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "child3");
iter++;
ASSERT_NE(iter, end);
EXPECT_EQ(iter->name, "child4");
iter++;
EXPECT_EQ(iter, end);
}
} // namespace
} // namespace verible