diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/testing/gtest_extensions/assertions.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/testing/gtest_extensions/assertions.h')
-rw-r--r-- | library/cpp/testing/gtest_extensions/assertions.h | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/library/cpp/testing/gtest_extensions/assertions.h b/library/cpp/testing/gtest_extensions/assertions.h new file mode 100644 index 0000000000..e8ea07b5df --- /dev/null +++ b/library/cpp/testing/gtest_extensions/assertions.h @@ -0,0 +1,111 @@ +#pragma once + +#include <util/generic/string.h> + +#include <gtest/gtest.h> +#include <gmock/gmock.h> + +/** + * Check that the given statement throws an exception of the given type, + * and that the thrown exception message contains the given substring. + */ +#define EXPECT_THROW_MESSAGE_HAS_SUBSTR(statement, expectedException, substring) \ + _Y_GTEST_EXPECT_THROW_MESSAGE_HAS_SUBSTR_IMPL_(statement, expectedException, substring, GTEST_NONFATAL_FAILURE_) + +/** + * Check that the given statement throws an exception of the given type, + * and that the thrown exception message contains the given substring. + */ +#define ASSERT_THROW_MESSAGE_HAS_SUBSTR(statement, expectedException, substring) \ + _Y_GTEST_EXPECT_THROW_MESSAGE_HAS_SUBSTR_IMPL_(statement, expectedException, substring, GTEST_FATAL_FAILURE_) + + +// Improve default macros. New implementation shows better exception messages. +// See https://github.com/google/googletest/issues/2878 + +#undef EXPECT_THROW +#define EXPECT_THROW(statement, expectedException) \ + _Y_GTEST_EXPECT_THROW_IMPL_(statement, expectedException, GTEST_NONFATAL_FAILURE_) + +#undef ASSERT_THROW +#define ASSERT_THROW(statement, expectedException) \ + _Y_GTEST_EXPECT_THROW_IMPL_(statement, expectedException, GTEST_FATAL_FAILURE_) + +#undef EXPECT_NO_THROW +#define EXPECT_NO_THROW(statement) \ + _Y_GTEST_EXPECT_NO_THROW_IMPL_(statement, GTEST_NONFATAL_FAILURE_) + +#undef ASSERT_NO_THROW +#define ASSERT_NO_THROW(statement) \ + _Y_GTEST_EXPECT_NO_THROW_IMPL_(statement, GTEST_FATAL_FAILURE_) + + +// Implementation details + +namespace NGTest::NInternal { + TString FormatErrorWrongException(const char* statement, const char* type); + TString FormatErrorWrongException(const char* statement, const char* type, TString contains); + TString FormatErrorUnexpectedException(const char* statement); + bool ExceptionMessageContains(const std::exception& err, TString contains); +} + +#define _Y_GTEST_EXPECT_THROW_IMPL_(statement, expectedException, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::TString gtestMsg = ""; ::testing::internal::AlwaysTrue()) { \ + bool gtestCaughtExpected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (expectedException const&) { \ + gtestCaughtExpected = true; \ + } catch (...) { \ + gtestMsg = ::NGTest::NInternal::FormatErrorWrongException( \ + #statement, #expectedException); \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } if (!gtestCaughtExpected) { \ + gtestMsg = ::NGTest::NInternal::FormatErrorWrongException( \ + #statement, #expectedException); \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtestMsg.c_str()) + +#define _Y_GTEST_EXPECT_THROW_MESSAGE_HAS_SUBSTR_IMPL_(statement, expectedException, substring, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::TString gtestMsg = ""; ::testing::internal::AlwaysTrue()) { \ + bool gtestCaughtExpected = false; \ + ::TString gtestSubstring{substring}; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (expectedException const& gtestError) { \ + if (!::NGTest::NInternal::ExceptionMessageContains(gtestError, gtestSubstring)) { \ + gtestMsg = ::NGTest::NInternal::FormatErrorWrongException( \ + #statement, #expectedException, gtestSubstring); \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrowsubstr_, __LINE__); \ + } \ + gtestCaughtExpected = true; \ + } catch (...) { \ + gtestMsg = ::NGTest::NInternal::FormatErrorWrongException( \ + #statement, #expectedException, gtestSubstring); \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrowsubstr_, __LINE__); \ + } if (!gtestCaughtExpected) { \ + gtestMsg = ::NGTest::NInternal::FormatErrorWrongException( \ + #statement, #expectedException, gtestSubstring); \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrowsubstr_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrowsubstr_, __LINE__): \ + fail(gtestMsg.c_str()) + +#define _Y_GTEST_EXPECT_NO_THROW_IMPL_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::TString gtestMsg = ""; ::testing::internal::AlwaysTrue()) { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (...) { \ + gtestMsg = ::NGTest::NInternal::FormatErrorUnexpectedException(#statement); \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ + fail(gtestMsg.c_str()) |