blob: 45fce9a375df92ceb5d5415e23bfd582f699c5c4 [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/matcher_test_utils.h"
#include <map>
#include <utility>
#include "absl/strings/string_view.h"
#include "common/analysis/matcher/bound_symbol_manager.h"
#include "common/analysis/matcher/matcher.h"
#include "common/text/concrete_syntax_leaf.h"
#include "common/text/concrete_syntax_tree.h"
#include "common/text/symbol.h"
#include "common/text/visitors.h"
#include "gtest/gtest.h"
namespace verible {
namespace matcher {
void RunMatcherTestCase(const MatcherTestCase& test) {
BoundSymbolManager bound_symbol_manager;
ASSERT_NE(test.root, nullptr);
bool result = test.matcher.Matches(*test.root, &bound_symbol_manager);
EXPECT_EQ(result, test.expected_result);
if (test.expected_result) {
// If test passed, then all bound symbols should precisely matched expected.
EXPECT_EQ(test.expected_bound_nodes.size(), bound_symbol_manager.Size());
for (const auto& expected : test.expected_bound_nodes) {
EXPECT_TRUE(bound_symbol_manager.ContainsSymbol(expected.first));
auto matched_symbol = bound_symbol_manager.FindSymbol(expected.first);
ASSERT_NE(matched_symbol, nullptr);
EXPECT_EQ(expected.second, matched_symbol->Tag());
}
} else {
// If test failed, then it should not report any bound symbols
EXPECT_EQ(bound_symbol_manager.Size(), 0);
}
}
class MatchCounter : public TreeVisitorRecursive {
public:
explicit MatchCounter(const Matcher& matcher)
: matcher_(matcher), num_matches_(0) {}
int Count(const Symbol& symbol) {
num_matches_ = 0;
symbol.Accept(this);
return num_matches_;
}
void Visit(const SyntaxTreeLeaf& leaf) final { TestSymbol(leaf); }
void Visit(const SyntaxTreeNode& node) final { TestSymbol(node); }
private:
Matcher matcher_;
int num_matches_ = 0;
void TestSymbol(const Symbol& symbol) {
BoundSymbolManager manager;
bool found_match = matcher_.Matches(symbol, &manager);
if (found_match) {
num_matches_++;
}
}
};
void ExpectMatchesInAST(const Symbol& tree, const Matcher& matcher,
int num_matches, absl::string_view code) {
MatchCounter counter(matcher);
EXPECT_EQ(num_matches, counter.Count(tree)) << "code:\n" << code;
}
} // namespace matcher
} // namespace verible