blob: 34da4d35d42892f345106850246c846a5d44c1d1 [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/text/tree_builder_test_util.h"
#include "gtest/gtest.h"
#include "common/text/tree_utils.h"
namespace verible {
namespace {
// Tests descending when root is a leaf.
TEST(DescendPathTest, LeafOnly) {
SymbolPtr leaf = Leaf(0, "text");
EXPECT_EQ(leaf.get(), DescendPath(*leaf, {}));
EXPECT_DEATH(DescendPath(*leaf, {0}), "");
}
// Tests that descending stops at childless node.
TEST(DescendPathTest, EmptyNode) {
SymbolPtr node = Node();
EXPECT_EQ(node.get(), DescendPath(*node, {}));
EXPECT_DEATH(DescendPath(*node, {0}), "");
}
// Tests that descent can return nullptr nodes.
TEST(DescendPathTest, NodeNullChild) {
SymbolPtr node = Node(nullptr);
EXPECT_EQ(DescendPath(*node, {0}), nullptr);
EXPECT_DEATH(DescendPath(*node, {1}), ""); // out-of-bounds
}
// Tests that descending reaches a leaf single-child.
TEST(DescendPathTest, NodeLeaf) {
SymbolPtr node = Node(Leaf(0, "text"));
EXPECT_NE(&SymbolCastToLeaf(*DescendPath(*node, {0})), nullptr);
EXPECT_DEATH(DescendPath(*node, {0, 0}), ""); // out-of-bounds
EXPECT_DEATH(DescendPath(*node, {1}), ""); // out-of-bounds
}
// Tests that descending reaches a node single-child.
TEST(DescendPathTest, NodeNode) {
SymbolPtr node = Node(Node());
EXPECT_NE(&SymbolCastToNode(*DescendPath(*node, {0})), nullptr);
EXPECT_DEATH(DescendPath(*node, {0, 0}), ""); // out-of-bounds
EXPECT_DEATH(DescendPath(*node, {1}), ""); // out-of-bounds
}
// Tests that descending reaches a single-grandchild leaf.
TEST(DescendPathTest, NodeNodeLeaf) {
SymbolPtr node = Node(Node(Leaf(0, "text")));
EXPECT_NE(&SymbolCastToLeaf(*DescendPath(*node, {0, 0})), nullptr);
EXPECT_DEATH(DescendPath(*node, {0, 0, 0}), ""); // out-of-bounds
EXPECT_DEATH(DescendPath(*node, {0, 1}), ""); // out-of-bounds
EXPECT_DEATH(DescendPath(*node, {1}), ""); // out-of-bounds
}
// Tests that descending reaches a single-grandchild node.
TEST(DescendPathTest, NodeNodeNode) {
SymbolPtr node = Node(Node(Node()));
EXPECT_NE(&SymbolCastToNode(*DescendPath(*node, {0, 0})), nullptr);
EXPECT_DEATH(DescendPath(*node, {0, 0, 0}), ""); // out-of-bounds
EXPECT_DEATH(DescendPath(*node, {0, 1}), ""); // out-of-bounds
EXPECT_DEATH(DescendPath(*node, {1}), ""); // out-of-bounds
}
// Tests that descending reaches two terminal leaves.
TEST(DescendPathTest, NodeTwoLeaves) {
SymbolPtr node = Node(Leaf(0, "more"), Leaf(0, "text"));
const auto* leaf0 = &SymbolCastToLeaf(*DescendPath(*node, {0}));
const auto* leaf1 = &SymbolCastToLeaf(*DescendPath(*node, {1}));
EXPECT_NE(leaf0, nullptr);
EXPECT_NE(leaf1, nullptr);
EXPECT_NE(leaf0, leaf1);
EXPECT_DEATH(DescendPath(*node, {2}), ""); // out-of-bounds
}
// Tests that descending stops as a node with multiple children nodes.
TEST(DescendPathTest, NodeTwoSubNodes) {
SymbolPtr node = Node(Node(), Node());
const auto* subnode0 = &SymbolCastToNode(*DescendPath(*node, {0}));
const auto* subnode1 = &SymbolCastToNode(*DescendPath(*node, {1}));
EXPECT_NE(subnode0, nullptr);
EXPECT_NE(subnode1, nullptr);
EXPECT_NE(subnode0, subnode1);
EXPECT_DEATH(DescendPath(*node, {2}), ""); // out-of-bounds
}
// Tests that descending stops as a node with multiple children, some null.
TEST(DescendPathTest, NodeFirstChildLeafSecondChildNull) {
SymbolPtr node = Node(Leaf(0, "text"), nullptr);
const auto* leaf0 = &SymbolCastToLeaf(*DescendPath(*node, {0}));
const auto* leaf1 = DescendPath(*node, {1});
EXPECT_NE(leaf0, nullptr);
EXPECT_EQ(leaf1, nullptr);
EXPECT_DEATH(DescendPath(*node, {2}), ""); // out-of-bounds
EXPECT_DEATH(DescendPath(*node, {0, 0}), ""); // out-of-bounds
}
// Tests that descending stops as a node with multiple children, some null.
TEST(DescendPathTest, NodeFirstChildNullSecondChildLeaf) {
SymbolPtr node = Node(nullptr, Leaf(0, "text"));
const auto* leaf0 = DescendPath(*node, {0});
const auto* leaf1 = &SymbolCastToLeaf(*DescendPath(*node, {1}));
EXPECT_EQ(leaf0, nullptr);
EXPECT_NE(leaf1, nullptr);
EXPECT_DEATH(DescendPath(*node, {2}), ""); // out-of-bounds
EXPECT_DEATH(DescendPath(*node, {1, 0}), ""); // out-of-bounds
}
// Tests that descending stops as a node with multiple children, some null.
TEST(DescendPathTest, NodeFirstChildNullSecondChildNode) {
SymbolPtr node = Node(nullptr, Node());
const auto* subnode0 = DescendPath(*node, {0});
const auto* subnode1 = &SymbolCastToNode(*DescendPath(*node, {1}));
EXPECT_EQ(subnode0, nullptr);
EXPECT_NE(subnode1, nullptr);
EXPECT_DEATH(DescendPath(*node, {2}), ""); // out-of-bounds
EXPECT_DEATH(DescendPath(*node, {1, 0}), ""); // out-of-bounds
}
// Tests that descending stops as a node with multiple children, some null.
TEST(DescendPathTest, NodeFirstChildNodeSecondChildNull) {
SymbolPtr node = Node(Node(), nullptr);
const auto* subnode0 = &SymbolCastToNode(*DescendPath(*node, {0}));
const auto* subnode1 = DescendPath(*node, {1});
EXPECT_NE(subnode0, nullptr);
EXPECT_EQ(subnode1, nullptr);
EXPECT_DEATH(DescendPath(*node, {2}), ""); // out-of-bounds
EXPECT_DEATH(DescendPath(*node, {0, 0}), ""); // out-of-bounds
}
} // namespace
} // namespace verible