AnimTestbed/3rdparty/ozz-animation/include/ozz/base/gtest_helper.h

176 lines
8.4 KiB
C++

//----------------------------------------------------------------------------//
// //
// 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 <sstream>
#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 <crtdbg.h>
#include <cstdlib>
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_