forked from carbon-language/carbon-lang
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ast_test_matchers.h
132 lines (111 loc) · 4.69 KB
/
ast_test_matchers.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// Googlemock matchers for the AST. Unless otherwise specified, all the
// functions in this file return matchers that can be applied to any
// AstNode or AstNode*.
//
// TODO: Provide matchers for all node Kinds, and establish more uniform
// conventions for them.
#ifndef CARBON_EXPLORER_AST_AST_TEST_MATCHERS_H_
#define CARBON_EXPLORER_AST_AST_TEST_MATCHERS_H_
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <ostream>
#include "explorer/ast/ast_node.h"
#include "explorer/ast/ast_test_matchers_internal.h"
#include "explorer/ast/expression.h"
namespace Carbon {
// Matches a Block node whose .statements() match `matcher`.
inline auto BlockContentsAre(
::testing::Matcher<llvm::ArrayRef<Nonnull<const Statement*>>> matcher) {
return TestingInternal::BlockContentsMatcher(std::move(matcher));
}
// Matches a literal with the given value.
// TODO: add overload for string literals
inline auto MatchesLiteral(int value) {
return TestingInternal::MatchesIntLiteralMatcher(value);
}
// The following functions all match a OperatorExpression with two
// operands that match `lhs` and `rhs` (respectively). The name of the function
// indicates what value of `.op()` they match.
inline auto MatchesMul(::testing::Matcher<AstNode> lhs,
::testing::Matcher<AstNode> rhs) {
return TestingInternal::BinaryOperatorExpressionMatcher(
Operator::Mul, std::move(lhs), std::move(rhs));
}
inline auto MatchesAdd(::testing::Matcher<AstNode> lhs,
::testing::Matcher<AstNode> rhs) {
return TestingInternal::BinaryOperatorExpressionMatcher(
Operator::Add, std::move(lhs), std::move(rhs));
}
inline auto MatchesAnd(::testing::Matcher<AstNode> lhs,
::testing::Matcher<AstNode> rhs) {
return TestingInternal::BinaryOperatorExpressionMatcher(
Operator::And, std::move(lhs), std::move(rhs));
}
inline auto MatchesEq(::testing::Matcher<AstNode> lhs,
::testing::Matcher<AstNode> rhs) {
return TestingInternal::BinaryOperatorExpressionMatcher(
Operator::Eq, std::move(lhs), std::move(rhs));
}
inline auto MatchesOr(::testing::Matcher<AstNode> lhs,
::testing::Matcher<AstNode> rhs) {
return TestingInternal::BinaryOperatorExpressionMatcher(
Operator::Or, std::move(lhs), std::move(rhs));
}
inline auto MatchesSub(::testing::Matcher<AstNode> lhs,
::testing::Matcher<AstNode> rhs) {
return TestingInternal::BinaryOperatorExpressionMatcher(
Operator::Sub, std::move(lhs), std::move(rhs));
}
// Matches a return statement with no operand.
inline auto MatchesEmptyReturn() {
return TestingInternal::MatchesReturnMatcher();
}
// Matches a return statement with an explicit operand that matches `matcher`.
inline auto MatchesReturn(::testing::Matcher<AstNode> matcher) {
return TestingInternal::MatchesReturnMatcher(matcher);
}
// Matches a FunctionDeclaration. By default the returned object matches any
// FunctionDeclaration, but it has methods for restricting the match, which can
// be chained fluent-style:
//
// EXPECT_THAT(node, MatchesFunctionDeclaration()
// .WithName("Foo")
// .WithBody(BlockContentsAre(...)));
//
// The available methods are:
//
// // *this only matches if the declared name matches name_matcher.
// WithName(::testing::Matcher<std::string> name_matcher)
//
// // *this only matches if the declaration has a body that matches
// // body_matcher.
// WithBody(::testing::Matcher<AstNode> body_matcher)
//
// TODO: Add method for matching only if the declaration has no body.
// TODO: Add methods for matching parameters, deduced parameters,
// and return term.
inline auto MatchesFunctionDeclaration() {
return TestingInternal::MatchesFunctionDeclarationMatcher();
}
// Matches an UnimplementedExpression with the given label, whose children
// match `children_matcher`.
inline auto MatchesUnimplementedExpression(
std::string label,
::testing::Matcher<llvm::ArrayRef<Nonnull<const AstNode*>>>
children_matcher) {
return TestingInternal::MatchesUnimplementedExpressionMatcher(
std::move(label), std::move(children_matcher));
}
// Matches an `AST` whose declarations match the given matcher. Unlike other
// matchers in this file, this matcher does not match pointers.
inline auto ASTDeclarations(
::testing::Matcher<std::vector<Nonnull<Declaration*>>>
declarations_matcher) {
return TestingInternal::ASTDeclarationsMatcher(
std::move(declarations_matcher));
}
} // namespace Carbon
#endif // CARBON_EXPLORER_AST_AST_TEST_MATCHERS_H_