| 1 | //===- unittests/ASTMatchers/GTestMatchersTest.cpp - GTest matcher unit tests // |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "ASTMatchersTest.h" |
| 10 | #include "clang/ASTMatchers/ASTMatchers.h" |
| 11 | #include "clang/ASTMatchers/GtestMatchers.h" |
| 12 | |
| 13 | namespace clang { |
| 14 | namespace ast_matchers { |
| 15 | |
| 16 | constexpr llvm::StringLiteral GtestMockDecls = R"cc( |
| 17 | static int testerr; |
| 18 | |
| 19 | #define GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ |
| 20 | switch (0) \ |
| 21 | case 0: \ |
| 22 | default: // NOLINT |
| 23 | |
| 24 | #define GTEST_NONFATAL_FAILURE_(code) testerr = code |
| 25 | |
| 26 | #define GTEST_FATAL_FAILURE_(code) testerr = code |
| 27 | |
| 28 | #define GTEST_ASSERT_(expression, on_failure) \ |
| 29 | GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ |
| 30 | if (const int gtest_ar = (expression)) \ |
| 31 | ; \ |
| 32 | else \ |
| 33 | on_failure(gtest_ar) |
| 34 | |
| 35 | // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. |
| 36 | // Don't use this in your code. |
| 37 | #define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \ |
| 38 | GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure) |
| 39 | |
| 40 | #define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ |
| 41 | GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) |
| 42 | #define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ |
| 43 | GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) |
| 44 | |
| 45 | #define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \ |
| 46 | GTEST_ASSERT_(pred_format(#v1, v1), on_failure) |
| 47 | |
| 48 | #define EXPECT_PRED_FORMAT1(pred_format, v1) \ |
| 49 | GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) |
| 50 | #define ASSERT_PRED_FORMAT1(pred_format, v1) \ |
| 51 | GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) |
| 52 | |
| 53 | #define EXPECT_EQ(val1, val2) \ |
| 54 | EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2) |
| 55 | #define EXPECT_NE(val1, val2) \ |
| 56 | EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) |
| 57 | #define EXPECT_GE(val1, val2) \ |
| 58 | EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) |
| 59 | #define EXPECT_GT(val1, val2) \ |
| 60 | EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) |
| 61 | #define EXPECT_LE(val1, val2) \ |
| 62 | EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) |
| 63 | #define EXPECT_LT(val1, val2) \ |
| 64 | EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) |
| 65 | |
| 66 | #define ASSERT_THAT(value, matcher) \ |
| 67 | ASSERT_PRED_FORMAT1( \ |
| 68 | ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) |
| 69 | #define EXPECT_THAT(value, matcher) \ |
| 70 | EXPECT_PRED_FORMAT1( \ |
| 71 | ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value) |
| 72 | |
| 73 | #define ASSERT_EQ(val1, val2) \ |
| 74 | ASSERT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2) |
| 75 | #define ASSERT_NE(val1, val2) \ |
| 76 | ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) |
| 77 | |
| 78 | #define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \ |
| 79 | ((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \ |
| 80 | nullptr) \ |
| 81 | .Setter(nullptr, 0, #mock_expr, #call) |
| 82 | |
| 83 | #define ON_CALL(obj, call) \ |
| 84 | GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call) |
| 85 | |
| 86 | #define EXPECT_CALL(obj, call) \ |
| 87 | GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call) |
| 88 | |
| 89 | namespace testing { |
| 90 | namespace internal { |
| 91 | class EqHelper { |
| 92 | public: |
| 93 | // This templatized version is for the general case. |
| 94 | template <typename T1, typename T2> |
| 95 | static int Compare(const char* lhs_expression, const char* rhs_expression, |
| 96 | const T1& lhs, const T2& rhs) { |
| 97 | return 0; |
| 98 | } |
| 99 | }; |
| 100 | template <typename T1, typename T2> |
| 101 | int CmpHelperNE(const char* expr1, const char* expr2, const T1& val1, |
| 102 | const T2& val2) { |
| 103 | return 0; |
| 104 | } |
| 105 | template <typename T1, typename T2> |
| 106 | int CmpHelperGE(const char* expr1, const char* expr2, const T1& val1, |
| 107 | const T2& val2) { |
| 108 | return 0; |
| 109 | } |
| 110 | template <typename T1, typename T2> |
| 111 | int CmpHelperGT(const char* expr1, const char* expr2, const T1& val1, |
| 112 | const T2& val2) { |
| 113 | return 0; |
| 114 | } |
| 115 | template <typename T1, typename T2> |
| 116 | int CmpHelperLE(const char* expr1, const char* expr2, const T1& val1, |
| 117 | const T2& val2) { |
| 118 | return 0; |
| 119 | } |
| 120 | template <typename T1, typename T2> |
| 121 | int CmpHelperLT(const char* expr1, const char* expr2, const T1& val1, |
| 122 | const T2& val2) { |
| 123 | return 0; |
| 124 | } |
| 125 | |
| 126 | // For implementing ASSERT_THAT() and EXPECT_THAT(). The template |
| 127 | // argument M must be a type that can be converted to a matcher. |
| 128 | template <typename M> |
| 129 | class PredicateFormatterFromMatcher { |
| 130 | public: |
| 131 | explicit PredicateFormatterFromMatcher(M m) : matcher_(m) {} |
| 132 | |
| 133 | // This template () operator allows a PredicateFormatterFromMatcher |
| 134 | // object to act as a predicate-formatter suitable for using with |
| 135 | // Google Test's EXPECT_PRED_FORMAT1() macro. |
| 136 | template <typename T> |
| 137 | int operator()(const char* value_text, const T& x) const { |
| 138 | return 0; |
| 139 | } |
| 140 | |
| 141 | private: |
| 142 | const M matcher_; |
| 143 | }; |
| 144 | |
| 145 | template <typename M> |
| 146 | inline PredicateFormatterFromMatcher<M> MakePredicateFormatterFromMatcher( |
| 147 | M matcher) { |
| 148 | return PredicateFormatterFromMatcher<M>(matcher); |
| 149 | } |
| 150 | |
| 151 | bool GetWithoutMatchers() { return false; } |
| 152 | |
| 153 | template <typename F> |
| 154 | class MockSpec { |
| 155 | public: |
| 156 | MockSpec<F>() {} |
| 157 | |
| 158 | bool InternalDefaultActionSetAt( |
| 159 | const char* file, int line, const char* obj, const char* call) { |
| 160 | return false; |
| 161 | } |
| 162 | |
| 163 | bool InternalExpectedAt( |
| 164 | const char* file, int line, const char* obj, const char* call) { |
| 165 | return false; |
| 166 | } |
| 167 | |
| 168 | MockSpec<F> operator()(bool, void*) { |
| 169 | return *this; |
| 170 | } |
| 171 | }; // class MockSpec |
| 172 | |
| 173 | } // namespace internal |
| 174 | |
| 175 | template <typename T> |
| 176 | int StrEq(T val) { |
| 177 | return 0; |
| 178 | } |
| 179 | template <typename T> |
| 180 | int Eq(T val) { |
| 181 | return 0; |
| 182 | } |
| 183 | |
| 184 | } // namespace testing |
| 185 | |
| 186 | class Mock { |
| 187 | public: |
| 188 | Mock() {} |
| 189 | testing::internal::MockSpec<int> gmock_TwoArgsMethod(int, int) { |
| 190 | return testing::internal::MockSpec<int>(); |
| 191 | } |
| 192 | testing::internal::MockSpec<int> gmock_TwoArgsMethod(bool, void*) { |
| 193 | return testing::internal::MockSpec<int>(); |
| 194 | } |
| 195 | }; // class Mock |
| 196 | )cc" ; |
| 197 | |
| 198 | static std::string wrapGtest(llvm::StringRef Input) { |
| 199 | return (GtestMockDecls + Input).str(); |
| 200 | } |
| 201 | |
| 202 | TEST(GtestAssertTest, ShouldMatchAssert) { |
| 203 | std::string Input = R"cc( |
| 204 | void Test() { ASSERT_EQ(1010, 4321); } |
| 205 | )cc" ; |
| 206 | EXPECT_TRUE(matches(wrapGtest(Input), |
| 207 | gtestAssert(GtestCmp::Eq, integerLiteral(equals(1010)), |
| 208 | integerLiteral(equals(4321))))); |
| 209 | } |
| 210 | |
| 211 | TEST(GtestAssertTest, ShouldNotMatchExpect) { |
| 212 | std::string Input = R"cc( |
| 213 | void Test() { EXPECT_EQ(2, 3); } |
| 214 | )cc" ; |
| 215 | EXPECT_TRUE( |
| 216 | notMatches(wrapGtest(Input), gtestAssert(GtestCmp::Eq, expr(), expr()))); |
| 217 | } |
| 218 | |
| 219 | TEST(GtestAssertTest, ShouldMatchNestedAssert) { |
| 220 | std::string Input = R"cc( |
| 221 | #define WRAPPER(a, b) ASSERT_EQ(a, b) |
| 222 | void Test() { WRAPPER(2, 3); } |
| 223 | )cc" ; |
| 224 | EXPECT_TRUE( |
| 225 | matches(wrapGtest(Input), gtestAssert(GtestCmp::Eq, expr(), expr()))); |
| 226 | } |
| 227 | |
| 228 | TEST(GtestExpectTest, ShouldMatchExpect) { |
| 229 | std::string Input = R"cc( |
| 230 | void Test() { EXPECT_EQ(1010, 4321); } |
| 231 | )cc" ; |
| 232 | EXPECT_TRUE(matches(wrapGtest(Input), |
| 233 | gtestExpect(GtestCmp::Eq, integerLiteral(equals(1010)), |
| 234 | integerLiteral(equals(4321))))); |
| 235 | } |
| 236 | |
| 237 | TEST(GtestExpectTest, ShouldNotMatchAssert) { |
| 238 | std::string Input = R"cc( |
| 239 | void Test() { ASSERT_EQ(2, 3); } |
| 240 | )cc" ; |
| 241 | EXPECT_TRUE( |
| 242 | notMatches(wrapGtest(Input), gtestExpect(GtestCmp::Eq, expr(), expr()))); |
| 243 | } |
| 244 | |
| 245 | TEST(GtestExpectTest, NeShouldMatchExpectNe) { |
| 246 | std::string Input = R"cc( |
| 247 | void Test() { EXPECT_NE(2, 3); } |
| 248 | )cc" ; |
| 249 | EXPECT_TRUE( |
| 250 | matches(wrapGtest(Input), gtestExpect(GtestCmp::Ne, expr(), expr()))); |
| 251 | } |
| 252 | |
| 253 | TEST(GtestExpectTest, LeShouldMatchExpectLe) { |
| 254 | std::string Input = R"cc( |
| 255 | void Test() { EXPECT_LE(2, 3); } |
| 256 | )cc" ; |
| 257 | EXPECT_TRUE( |
| 258 | matches(wrapGtest(Input), gtestExpect(GtestCmp::Le, expr(), expr()))); |
| 259 | } |
| 260 | |
| 261 | TEST(GtestExpectTest, LtShouldMatchExpectLt) { |
| 262 | std::string Input = R"cc( |
| 263 | void Test() { EXPECT_LT(2, 3); } |
| 264 | )cc" ; |
| 265 | EXPECT_TRUE( |
| 266 | matches(wrapGtest(Input), gtestExpect(GtestCmp::Lt, expr(), expr()))); |
| 267 | } |
| 268 | |
| 269 | TEST(GtestExpectTest, GeShouldMatchExpectGe) { |
| 270 | std::string Input = R"cc( |
| 271 | void Test() { EXPECT_GE(2, 3); } |
| 272 | )cc" ; |
| 273 | EXPECT_TRUE( |
| 274 | matches(wrapGtest(Input), gtestExpect(GtestCmp::Ge, expr(), expr()))); |
| 275 | } |
| 276 | |
| 277 | TEST(GtestExpectTest, GtShouldMatchExpectGt) { |
| 278 | std::string Input = R"cc( |
| 279 | void Test() { EXPECT_GT(2, 3); } |
| 280 | )cc" ; |
| 281 | EXPECT_TRUE( |
| 282 | matches(wrapGtest(Input), gtestExpect(GtestCmp::Gt, expr(), expr()))); |
| 283 | } |
| 284 | |
| 285 | TEST(GtestExpectTest, ThatShouldMatchAssertThat) { |
| 286 | std::string Input = R"cc( |
| 287 | using ::testing::Eq; |
| 288 | void Test() { ASSERT_THAT(2, Eq(2)); } |
| 289 | )cc" ; |
| 290 | EXPECT_TRUE(matches( |
| 291 | wrapGtest(Input), |
| 292 | gtestAssertThat( |
| 293 | expr(), callExpr(callee(functionDecl(hasName("::testing::Eq" ))))))); |
| 294 | } |
| 295 | |
| 296 | TEST(GtestExpectTest, ThatShouldMatchExpectThat) { |
| 297 | std::string Input = R"cc( |
| 298 | using ::testing::Eq; |
| 299 | void Test() { EXPECT_THAT(2, Eq(2)); } |
| 300 | )cc" ; |
| 301 | EXPECT_TRUE(matches( |
| 302 | wrapGtest(Input), |
| 303 | gtestExpectThat( |
| 304 | expr(), callExpr(callee(functionDecl(hasName("::testing::Eq" ))))))); |
| 305 | } |
| 306 | |
| 307 | TEST(GtestOnCallTest, CallShouldMatchOnCallWithoutParams1) { |
| 308 | std::string Input = R"cc( |
| 309 | void Test() { |
| 310 | Mock mock; |
| 311 | ON_CALL(mock, TwoArgsMethod); |
| 312 | } |
| 313 | )cc" ; |
| 314 | EXPECT_TRUE(matches(wrapGtest(Input), |
| 315 | gtestOnCall(expr(hasType(cxxRecordDecl(hasName("Mock" )))), |
| 316 | "TwoArgsMethod" , MockArgs::None))); |
| 317 | } |
| 318 | |
| 319 | TEST(GtestOnCallTest, CallShouldMatchOnCallWithoutParams2) { |
| 320 | std::string Input = R"cc( |
| 321 | void Test() { |
| 322 | Mock mock; |
| 323 | ON_CALL(mock, TwoArgsMethod); |
| 324 | } |
| 325 | )cc" ; |
| 326 | EXPECT_TRUE(matches( |
| 327 | wrapGtest(Input), |
| 328 | gtestOnCall(cxxMemberCallExpr( |
| 329 | callee(functionDecl(hasName("gmock_TwoArgsMethod" )))) |
| 330 | .bind("mock_call" ), |
| 331 | MockArgs::None))); |
| 332 | } |
| 333 | |
| 334 | TEST(GtestOnCallTest, CallShouldMatchOnCallWithParams1) { |
| 335 | std::string Input = R"cc( |
| 336 | void Test() { |
| 337 | Mock mock; |
| 338 | ON_CALL(mock, TwoArgsMethod(1, 2)); |
| 339 | } |
| 340 | )cc" ; |
| 341 | EXPECT_TRUE(matches(wrapGtest(Input), |
| 342 | gtestOnCall(expr(hasType(cxxRecordDecl(hasName("Mock" )))), |
| 343 | "TwoArgsMethod" , MockArgs::Some))); |
| 344 | } |
| 345 | |
| 346 | TEST(GtestOnCallTest, CallShouldMatchOnCallWithParams2) { |
| 347 | std::string Input = R"cc( |
| 348 | void Test() { |
| 349 | Mock mock; |
| 350 | ON_CALL(mock, TwoArgsMethod(1, 2)); |
| 351 | } |
| 352 | )cc" ; |
| 353 | EXPECT_TRUE(matches( |
| 354 | wrapGtest(Input), |
| 355 | gtestOnCall(cxxMemberCallExpr( |
| 356 | callee(functionDecl(hasName("gmock_TwoArgsMethod" )))) |
| 357 | .bind("mock_call" ), |
| 358 | MockArgs::Some))); |
| 359 | } |
| 360 | |
| 361 | TEST(GtestExpectCallTest, CallShouldMatchExpectCallWithoutParams1) { |
| 362 | std::string Input = R"cc( |
| 363 | void Test() { |
| 364 | Mock mock; |
| 365 | EXPECT_CALL(mock, TwoArgsMethod); |
| 366 | } |
| 367 | )cc" ; |
| 368 | EXPECT_TRUE( |
| 369 | matches(wrapGtest(Input), |
| 370 | gtestExpectCall(expr(hasType(cxxRecordDecl(hasName("Mock" )))), |
| 371 | "TwoArgsMethod" , MockArgs::None))); |
| 372 | } |
| 373 | |
| 374 | TEST(GtestExpectCallTest, CallShouldMatchExpectCallWithoutParams2) { |
| 375 | std::string Input = R"cc( |
| 376 | void Test() { |
| 377 | Mock mock; |
| 378 | EXPECT_CALL(mock, TwoArgsMethod); |
| 379 | } |
| 380 | )cc" ; |
| 381 | EXPECT_TRUE(matches( |
| 382 | wrapGtest(Input), |
| 383 | gtestExpectCall(cxxMemberCallExpr( |
| 384 | callee(functionDecl(hasName("gmock_TwoArgsMethod" )))) |
| 385 | .bind("mock_call" ), |
| 386 | MockArgs::None))); |
| 387 | } |
| 388 | |
| 389 | TEST(GtestExpectCallTest, CallShouldMatchExpectCallWithParams1) { |
| 390 | std::string Input = R"cc( |
| 391 | void Test() { |
| 392 | Mock mock; |
| 393 | EXPECT_CALL(mock, TwoArgsMethod(1, 2)); |
| 394 | } |
| 395 | )cc" ; |
| 396 | EXPECT_TRUE( |
| 397 | matches(wrapGtest(Input), |
| 398 | gtestExpectCall(expr(hasType(cxxRecordDecl(hasName("Mock" )))), |
| 399 | "TwoArgsMethod" , MockArgs::Some))); |
| 400 | } |
| 401 | |
| 402 | TEST(GtestExpectCallTest, CallShouldMatchExpectCallWithParams2) { |
| 403 | std::string Input = R"cc( |
| 404 | void Test() { |
| 405 | Mock mock; |
| 406 | EXPECT_CALL(mock, TwoArgsMethod(1, 2)); |
| 407 | } |
| 408 | )cc" ; |
| 409 | EXPECT_TRUE(matches( |
| 410 | wrapGtest(Input), |
| 411 | gtestExpectCall(cxxMemberCallExpr( |
| 412 | callee(functionDecl(hasName("gmock_TwoArgsMethod" )))) |
| 413 | .bind("mock_call" ), |
| 414 | MockArgs::Some))); |
| 415 | } |
| 416 | |
| 417 | } // end namespace ast_matchers |
| 418 | } // end namespace clang |
| 419 | |