| // 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 |