blob: e824c787140d6f3bfe750be6d6975e011f04ee2d [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/analysis/matcher/descent_path.h"
#include <memory>
#include <vector>
#include "common/text/concrete_syntax_leaf.h"
#include "common/text/concrete_syntax_tree.h"
#include "common/text/symbol.h"
#include "common/text/token_info.h"
#include "common/text/tree_builder_test_util.h"
#include "gtest/gtest.h"
namespace verible {
namespace matcher {
namespace {
TEST(DescentPathTest, GetDescendantsFromPathNullTreeFail) {
SymbolPtr embedded_null = TNode(1, nullptr, TNode(2, nullptr));
DescentPath path = {NodeTag(2), NodeTag(3), NodeTag(4), LeafTag(100)};
auto descendants = GetAllDescendantsFromPath(*embedded_null, path);
EXPECT_EQ(descendants.size(), 0);
}
TEST(DescentPathTest, GetDescendantsFromPathEmbeddedNullPass) {
SymbolPtr root = TNode(
1, nullptr, TNode(2), nullptr, TNode(2, nullptr, XLeaf(10)), nullptr,
TNode(2, nullptr, XLeaf(10), nullptr, TNode(100, nullptr)));
DescentPath path = {NodeTag(2), LeafTag(10)};
auto descendants = GetAllDescendantsFromPath(*root, path);
EXPECT_EQ(descendants.size(), 2);
const auto* leaf1 = down_cast<const SyntaxTreeLeaf*>(descendants[0]);
const auto* leaf2 = down_cast<const SyntaxTreeLeaf*>(descendants[1]);
ASSERT_NE(leaf1, nullptr);
ASSERT_NE(leaf2, nullptr);
EXPECT_EQ(leaf1->get().token_enum(), 10);
EXPECT_EQ(leaf2->get().token_enum(), 10);
}
TEST(DescentPathTest, GetDescendantsFromPathSingle) {
SymbolPtr root = TNode(1, XLeaf(2), nullptr, TNode(2, XLeaf(10)));
DescentPath path = {NodeTag(2), LeafTag(10)};
auto descendants = GetAllDescendantsFromPath(*root, path);
EXPECT_EQ(descendants.size(), 1);
const auto* leaf = down_cast<const SyntaxTreeLeaf*>(descendants[0]);
ASSERT_NE(leaf, nullptr);
EXPECT_EQ(leaf->get().token_enum(), 10);
}
TEST(DescentPathTest, GetDescendantsFromPathMultiple) {
SymbolPtr root = TNode(1, TNode(2, TNode(100), TNode(100)));
DescentPath path = {NodeTag(2), NodeTag(100)};
auto descendants = GetAllDescendantsFromPath(*root, path);
EXPECT_EQ(descendants.size(), 2);
const auto* node1 = down_cast<const SyntaxTreeNode*>(descendants[0]);
const auto* node2 = down_cast<const SyntaxTreeNode*>(descendants[1]);
ASSERT_NE(node1, nullptr);
ASSERT_NE(node2, nullptr);
EXPECT_TRUE(node1->MatchesTag(100));
EXPECT_TRUE(node2->MatchesTag(100));
}
TEST(DescentPathTest, GetDescendantsFromPathMultiplePaths) {
SymbolPtr root =
TNode(1, TNode(2), TNode(2, XLeaf(10)), TNode(2, XLeaf(10), TNode(100)));
DescentPath path = {NodeTag(2), LeafTag(10)};
auto descendants = GetAllDescendantsFromPath(*root, path);
EXPECT_EQ(descendants.size(), 2);
const auto* leaf1 = down_cast<const SyntaxTreeLeaf*>(descendants[0]);
const auto* leaf2 = down_cast<const SyntaxTreeLeaf*>(descendants[1]);
ASSERT_NE(leaf1, nullptr);
ASSERT_NE(leaf2, nullptr);
EXPECT_EQ(leaf1->get().token_enum(), 10);
EXPECT_EQ(leaf2->get().token_enum(), 10);
}
TEST(DescentPathTest, GetDescendantsFromPathFailureGapInPath) {
SymbolPtr root = TNode(1, TNode(2, TNode(3, XLeaf(100))));
DescentPath path = {NodeTag(2), LeafTag(100)};
auto descendants = GetAllDescendantsFromPath(*root, path);
EXPECT_EQ(descendants.size(), 0);
}
TEST(DescentPathTest, GetDescendantsFromPathFailurePathTooLong) {
SymbolPtr root = TNode(1, TNode(2, TNode(3, XLeaf(100))));
DescentPath path = {NodeTag(2), NodeTag(3), NodeTag(4), LeafTag(100)};
auto descendants = GetAllDescendantsFromPath(*root, path);
EXPECT_EQ(descendants.size(), 0);
}
} // namespace
} // namespace matcher
} // namespace verible