//----------------------------------------------------------------------------// // // // ozz-animation is hosted at http://github.com/guillaumeblanc/ozz-animation // // and distributed under the MIT License (MIT). // // // // Copyright (c) Guillaume Blanc // // // // Permission is hereby granted, free of charge, to any person obtaining a // // copy of this software and associated documentation files (the "Software"), // // to deal in the Software without restriction, including without limitation // // the rights to use, copy, modify, merge, publish, distribute, sublicense, // // and/or sell copies of the Software, and to permit persons to whom the // // Software is furnished to do so, subject to the following conditions: // // // // The above copyright notice and this permission notice shall be included in // // all copies or substantial portions of the Software. // // // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // // DEALINGS IN THE SOFTWARE. // // // //----------------------------------------------------------------------------// #ifndef OZZ_OZZ_BASE_GTEST_HELPER_H_ #define OZZ_OZZ_BASE_GTEST_HELPER_H_ #include #include "gtest/gtest.h" // EXPECT_ASSERTION expands to real death test if assertions are enabled. // Parameters: // statement - A statement that a macro such as EXPECT_DEATH would test // for program termination. // regex - A regex that a macro such as EXPECT_DEATH would use to test // the output of statement. #ifdef NDEBUG // Expands to nothing if asserts aren't enabled (ie: NDEBUG is defined) #define EXPECT_ASSERTION(_statement, _regex) \ do { \ } while (void(0), false); #else // NDEBUG #ifdef _WIN32 #include #include namespace internal { // Provides a hook during abort to ensure EXIT_FAILURE is returned. inline int AbortHook(int, char*, int*) { exit(EXIT_FAILURE); } } // namespace internal #define EXPECT_ASSERTION(_statement, _regex) \ do { \ /* During death tests executions:*/ \ /* Disables popping message boxes during crt and stl assertions*/ \ int old_mode = 0; \ (void)old_mode; \ _CRT_REPORT_HOOK old_hook = nullptr; \ (void)old_hook; \ if (testing::internal::GTEST_FLAG(internal_run_death_test).length() > 0) { \ old_mode = _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); \ old_hook = _CrtSetReportHook(&internal::AbortHook); \ } \ EXPECT_DEATH((void)(_statement), _regex); \ if (testing::internal::GTEST_FLAG(internal_run_death_test).length() > 0) { \ _CrtSetReportMode(_CRT_ASSERT, old_mode); \ (void)_CrtSetReportHook(old_hook); \ } \ \ } while (void(0), 0) #else // _WIN32 #define EXPECT_ASSERTION(_statement, _regex) EXPECT_DEATH(_statement, _regex) #endif // _WIN32 #endif // NDEBUG // EXPECT_EQ_LOG* executes _expression and compares its result with _eq. // While executing _expression, EXPECT_EQ_LOG redirects _output (ex: // std::clog) and then expects that the output matched the regular expression // _re. #define EXPECT_EQ_LOG(_expression, _eq, _output, _re) \ do { \ internal::RedirectOuputTester tester(_output, _re); \ EXPECT_EQ(_expression, _eq); \ \ } while (void(0), 0) // There are multiple declinations EXPECT_EQ_LOG*, to match with clog, cerr and // cout outputs, and verbose level option. // Specialises EXPECT_EQ_LOG* for verbose clog output type. #define EXPECT_EQ_LOG_LOGV(_expression, _eq, _re) \ EXPECT_EQ_LOG(_expression, _eq, std::clog, \ ozz::log::kVerbose <= ozz::log::GetLevel() ? _re : nullptr) // Specialises EXPECT_EQ_LOG* for standard clog output type. #define EXPECT_EQ_LOG_LOG(_expression, _eq, _re) \ EXPECT_EQ_LOG(_expression, _eq, std::clog, \ ozz::log::kStandard <= ozz::log::GetLevel() ? _re : nullptr) // Specialises EXPECT_EQ_LOG* for standard cout output type. #define EXPECT_EQ_LOG_OUT(_expression, _eq, _re) \ EXPECT_EQ_LOG(_expression, _eq, std::cout, \ ozz::log::kStandard <= ozz::log::GetLevel() ? _re : nullptr) // Specialises EXPECT_EQ_LOG* for standard cerr output type. #define EXPECT_EQ_LOG_ERR(_expression, _eq, _re) \ EXPECT_EQ_LOG(_expression, _eq, std::cerr, \ ozz::log::kStandard <= ozz::log::GetLevel() ? _re : nullptr) // EXPECT_EQ_LOG* executes _expression while redirecting _output (ex: // std::clog) and then expects that the output matched the regular expression // _re. #define EXPECT_LOG(_expression, _output, _re) \ do { \ internal::RedirectOuputTester tester(_output, _re); \ (_expression); \ \ } while (void(0), 0) // There are multiple declinations EXPECT_LOG*, to match with clog, cerr and // cout outputs, and verbose level option. // Specialises EXPECT_LOG* for verbose clog output type. #define EXPECT_LOG_LOGV(_expression, _re) \ EXPECT_LOG(_expression, std::clog, \ ozz::log::kVerbose <= ozz::log::GetLevel() ? _re : nullptr) // Specialises EXPECT_LOG* for standard clog output type. #define EXPECT_LOG_LOG(_expression, _re) \ EXPECT_LOG(_expression, std::clog, \ ozz::log::kStandard <= ozz::log::GetLevel() ? _re : nullptr) // Specialises EXPECT_LOG* for standard cout output type. #define EXPECT_LOG_OUT(_expression, _re) \ EXPECT_LOG(_expression, std::cout, \ ozz::log::kStandard <= ozz::log::GetLevel() ? _re : nullptr) // Specialises EXPECT_LOG* for standard cerr output type. #define EXPECT_LOG_ERR(_expression, _re) \ EXPECT_LOG(_expression, std::cerr, \ ozz::log::kStandard <= ozz::log::GetLevel() ? _re : nullptr) namespace internal { class RedirectOuputTester { public: // Specify a nullptr _regex to test an empty output RedirectOuputTester(std::ostream& _ostream, const char* _regex) : ostream_(_ostream), old_(_ostream.rdbuf()), regex_(_regex) { // Redirect ostream_ buffer. ostream_.rdbuf(redirect_.rdbuf()); } ~RedirectOuputTester() { if (regex_) { EXPECT_TRUE(::testing::internal::RE::PartialMatch(redirect_.str().c_str(), regex_)); } else { EXPECT_EQ(redirect_.str().size(), 0u); } // Restore ostream_ buffer. ostream_.rdbuf(old_); // finally outputs everything temporary redirected. ostream_ << redirect_.str(); } private: std::ostream& ostream_; std::streambuf* old_; const char* regex_; std::stringstream redirect_; }; } // namespace internal #endif // OZZ_OZZ_BASE_GTEST_HELPER_H_