ast_test_matchers.h 4.8 KB

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