blob: 5f34de8f35bccda542e5c0767933b4ddfdfa8055 [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_compare.h"
#include "common/text/concrete_syntax_tree.h"
#include "common/text/tree_builder_test_util.h"
#include "gtest/gtest.h"
namespace verible {
namespace {
// Test empty tree equality
TEST(TreeEqualityTest, EmptyTreeEqualByEnum) {
SymbolPtr tree1 = nullptr;
SymbolPtr tree2 = nullptr;
EXPECT_TRUE(EqualTreesByEnum(tree1.get(), tree2.get()));
}
TEST(TreeEqualityTest, EmptyTreeEqualByEnumString) {
SymbolPtr tree1 = nullptr;
SymbolPtr tree2 = nullptr;
EXPECT_TRUE(EqualTreesByEnumString(tree1.get(), tree2.get()));
}
TEST(TreeEqualityTest, EmptyTreeNotLeavesByEnum) {
SymbolPtr tree1 = Leaf(3, "bar");
SymbolPtr tree2 = nullptr;
SymbolPtr tree3 = Leaf(5, "bar");
EXPECT_FALSE(EqualTreesByEnum(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTreesByEnum(tree1.get(), tree3.get()));
}
TEST(TreeEqualityTest, EmptyTreeNotLeavesByEnumString) {
SymbolPtr tree1 = Leaf(4, "foo");
SymbolPtr tree2 = nullptr;
SymbolPtr tree3 = Leaf(3, "bar");
EXPECT_FALSE(EqualTreesByEnumString(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree1.get(), tree3.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree2.get(), tree3.get()));
}
// Test leaf equality
TEST(TreeEqualityTest, LeavesEqualByEnum) {
SymbolPtr tree1 = Leaf(3, "bar");
SymbolPtr tree2 = Leaf(3, "foo");
EXPECT_TRUE(EqualTreesByEnum(tree1.get(), tree2.get()));
EXPECT_TRUE(EqualTreesByEnum(tree2.get(), tree1.get()));
}
TEST(TreeEqualityTest, LeavesEqualByEnumString) {
SymbolPtr tree1 = Leaf(3, "foo");
SymbolPtr tree2 = Leaf(3, "foo");
EXPECT_TRUE(EqualTreesByEnumString(tree1.get(), tree2.get()));
EXPECT_TRUE(EqualTreesByEnumString(tree2.get(), tree1.get()));
}
TEST(TreeEqualityTest, LeavesNotEqualByEnum) {
SymbolPtr tree1 = Leaf(3, "bar");
SymbolPtr tree2 = Leaf(5, "bar");
EXPECT_FALSE(EqualTreesByEnum(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTreesByEnum(tree2.get(), tree1.get()));
}
TEST(TreeEqualityTest, LeavesNotEqualByEnumString) {
SymbolPtr tree1 = Leaf(4, "foo");
SymbolPtr tree2 = Leaf(3, "foo");
SymbolPtr tree3 = Leaf(3, "bar");
EXPECT_FALSE(EqualTreesByEnumString(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree1.get(), tree3.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree2.get(), tree3.get()));
}
// Test Empty SyntaxTreeNode Equality
TEST(TreeEqualityTest, EmptyNodesEqualByEnum) {
SymbolPtr tree1 = Node();
SymbolPtr tree2 = Node();
EXPECT_TRUE(EqualTreesByEnum(tree1.get(), tree2.get()));
}
TEST(TreeEqualityTest, EmptyNodesEqualByEnumString) {
SymbolPtr tree1 = Node();
SymbolPtr tree2 = Node();
EXPECT_TRUE(EqualTreesByEnumString(tree1.get(), tree2.get()));
}
TEST(TreeEqualityTest, EmptyNodesNotEqualByEnum) {
SymbolPtr tree1 = Leaf(3, "bar");
SymbolPtr tree2 = Node();
SymbolPtr tree3 = Leaf(5, "bar");
EXPECT_FALSE(EqualTreesByEnum(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTreesByEnum(tree1.get(), tree3.get()));
}
TEST(TreeEqualityTest, EmptyNodesNotEqualByEnumString) {
SymbolPtr tree1 = Leaf(4, "foo");
SymbolPtr tree2 = Node();
SymbolPtr tree3 = Leaf(3, "bar");
EXPECT_FALSE(EqualTreesByEnumString(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree1.get(), tree3.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree2.get(), tree3.get()));
}
// Test SyntaxTreeNode equality
TEST(TreeEqualityTest, NonEmptyNodesEqualByEnum) {
SymbolPtr tree1 = Node(Leaf(1, "a"), Leaf(2, "b"));
SymbolPtr tree2 = Node(Leaf(1, "c"), Leaf(2, "c"));
EXPECT_TRUE(EqualTreesByEnum(tree1.get(), tree2.get()));
EXPECT_TRUE(EqualTreesByEnum(tree2.get(), tree1.get()));
}
TEST(TreeEqualityTest, NonEmptyNodesEqualByEnumString) {
SymbolPtr tree1 = Node(Leaf(1, "bar"), Leaf(2, "foo"));
SymbolPtr tree2 = Node(Leaf(1, "bar"), Leaf(2, "foo"));
EXPECT_TRUE(EqualTreesByEnumString(tree1.get(), tree2.get()));
EXPECT_TRUE(EqualTreesByEnumString(tree2.get(), tree1.get()));
}
TEST(TreeEqualityTest, NonEmptyNodesNotEqualByEnum) {
constexpr absl::string_view foo("");
SymbolPtr tree1 = Node(Leaf(1, foo), Leaf(2, foo));
SymbolPtr tree2 = Node(Leaf(1, foo), Leaf(2, foo), Leaf(3, foo));
SymbolPtr tree3 = Node(Leaf(3, foo), Leaf(1, foo), Leaf(2, foo));
EXPECT_FALSE(EqualTreesByEnumString(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree2.get(), tree1.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree1.get(), tree3.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree3.get(), tree1.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree2.get(), tree3.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree3.get(), tree2.get()));
}
TEST(TreeEqualityTest, NonEmptyNodesNotEqualByEnumString) {
constexpr absl::string_view foo("Foo"), bar("Bar");
SymbolPtr tree1 = Node(Leaf(1, bar), Leaf(2, foo));
SymbolPtr tree2 = Node(Leaf(1, foo), Leaf(2, bar));
SymbolPtr tree3 = Node(Leaf(3, foo), Leaf(1, foo), Leaf(2, bar));
EXPECT_FALSE(EqualTreesByEnumString(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree2.get(), tree1.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree1.get(), tree3.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree3.get(), tree1.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree2.get(), tree3.get()));
EXPECT_FALSE(EqualTreesByEnumString(tree3.get(), tree2.get()));
}
// Test arbitrary structure equality
TEST(TreeEqualityTest, ManyLayeredTreeEqual) {
SymbolPtr tree1 =
Node(Node(XLeaf(1), nullptr, XLeaf(2)), XLeaf(1), XLeaf(2), nullptr);
SymbolPtr tree2 =
Node(Node(XLeaf(1), nullptr, XLeaf(2)), XLeaf(1), XLeaf(2), nullptr);
EXPECT_TRUE(EqualTreesByEnum(tree1.get(), tree2.get()));
EXPECT_TRUE(EqualTreesByEnum(tree2.get(), tree1.get()));
}
TEST(TreeEqualityTest, SameStructureTreeNotEqual) {
SymbolPtr tree1 =
Node(Node(XLeaf(1), nullptr, XLeaf(3)), XLeaf(1), XLeaf(2), nullptr);
SymbolPtr tree2 =
Node(Node(XLeaf(1), nullptr, XLeaf(2)), XLeaf(1), XLeaf(2), nullptr);
EXPECT_FALSE(EqualTreesByEnum(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTreesByEnum(tree2.get(), tree1.get()));
}
TEST(TreeEqualityTest, DifferentStructureTreeNotEqual) {
SymbolPtr tree1 = Node(Node(XLeaf(1), nullptr, XLeaf(3)), XLeaf(1), XLeaf(2),
nullptr, Node(XLeaf(2)));
SymbolPtr tree2 = Node(Node(XLeaf(1), nullptr, XLeaf(2)), XLeaf(1), XLeaf(2),
nullptr, nullptr);
EXPECT_FALSE(EqualTreesByEnum(tree1.get(), tree2.get()));
}
TEST(TreeEqualityTest, SubTreeNotEqual) {
SymbolPtr tree1 = Node(Node(XLeaf(1), nullptr, XLeaf(3)), XLeaf(1), XLeaf(2),
nullptr, Node(XLeaf(2)));
SymbolPtr tree2 = Node(Node(Node(XLeaf(1), nullptr, XLeaf(3)), XLeaf(1),
XLeaf(2), nullptr, Node(XLeaf(2))));
EXPECT_FALSE(EqualTreesByEnum(tree1.get(), tree2.get()));
}
// Test exact token-by-token equality.
TEST(TreeEqualityTest, ExactEqualPerfectMatch) {
constexpr absl::string_view foo("foo"), bar("bar");
SymbolPtr tree1 = Node(Leaf(1, bar), Leaf(2, foo));
SymbolPtr tree2 = Node(Leaf(1, bar), Leaf(2, foo));
EXPECT_TRUE(EqualTrees(tree1.get(), tree2.get()));
EXPECT_TRUE(EqualTrees(tree2.get(), tree1.get()));
}
// Test for mismatch on different leaf tag.
TEST(TreeEqualityTest, ExactEqualMismatchLeafTag) {
constexpr absl::string_view foo("foo"), bar("bar");
SymbolPtr tree1 = Node(Leaf(1, bar), Leaf(2, foo));
SymbolPtr tree2 = Node(Leaf(1, bar), Leaf(3, foo));
EXPECT_FALSE(EqualTrees(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTrees(tree2.get(), tree1.get()));
}
// Test for mismatch on different token location.
TEST(TreeEqualityTest, ExactEqualMismatchTokenLocation) {
constexpr absl::string_view bar("barbar"), foo("foo");
// guarantee different ranges
const absl::string_view bar1(bar.substr(0, 3)), bar2(bar.substr(3, 3));
SymbolPtr tree1 = Node(Leaf(1, bar1), Leaf(2, foo));
SymbolPtr tree2 = Node(Leaf(1, bar2), Leaf(2, foo));
EXPECT_FALSE(EqualTrees(tree1.get(), tree2.get()));
EXPECT_FALSE(EqualTrees(tree2.get(), tree1.get()));
}
// Test for mismatch on different token text.
TEST(TreeEqualityTest, ExactEqualMismatchTokenText) {
constexpr absl::string_view bar("bar"), foo1("foo"), foo2("f00");
SymbolPtr tree1 = Node(Leaf(1, bar), Leaf(2, foo1));
SymbolPtr tree2 = Node(Leaf(1, bar), Leaf(2, foo2));
EXPECT_FALSE(EqualTrees(tree1.get(), tree2.get()));
}
} // namespace
} // namespace verible