initial commit
Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
291
libs/wxWidgets-3.3.1/include/wx/catch_cppunit.h
Normal file
291
libs/wxWidgets-3.3.1/include/wx/catch_cppunit.h
Normal file
@@ -0,0 +1,291 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/catch_cppunit.h
|
||||
// Purpose: Reimplementation of CppUnit macros in terms of CATCH
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2017-10-30
|
||||
// Copyright: (c) 2017 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_CATCH_CPPUNIT_H_
|
||||
#define _WX_CATCH_CPPUNIT_H_
|
||||
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
// CppUnit-compatible macros.
|
||||
|
||||
// CPPUNIT_ASSERTs are mapped to REQUIRE(), not CHECK(), as this is how CppUnit
|
||||
// works but in many cases they really should be CHECK()s instead, i.e. the
|
||||
// test should continue to run even if one assert failed. Unfortunately there
|
||||
// is no automatic way to know it, so the existing code will need to be
|
||||
// reviewed and CHECK() used explicitly where appropriate.
|
||||
//
|
||||
// Also notice that we don't use parentheses around x and y macro arguments in
|
||||
// the macro expansion, as usual. This is because these parentheses would then
|
||||
// appear in CATCH error messages if the assertion fails, making them much less
|
||||
// readable and omitting should be fine here, exceptionally, as the arguments
|
||||
// of these macros are usually just simple expressions.
|
||||
#define CPPUNIT_ASSERT(cond) REQUIRE(cond)
|
||||
#define CPPUNIT_ASSERT_EQUAL(x, y) REQUIRE(x == y)
|
||||
|
||||
// Using INFO() disallows putting more than one of these macros on the same
|
||||
// line but this can happen if they're used inside another macro, so wrap it
|
||||
// inside a scope.
|
||||
#define CPPUNIT_ASSERT_MESSAGE(msg, cond) \
|
||||
wxSTATEMENT_MACRO_BEGIN \
|
||||
INFO(msg); \
|
||||
REQUIRE(cond); \
|
||||
wxSTATEMENT_MACRO_END
|
||||
|
||||
#define CPPUNIT_ASSERT_EQUAL_MESSAGE(msg, x, y) \
|
||||
wxSTATEMENT_MACRO_BEGIN \
|
||||
INFO(msg); \
|
||||
REQUIRE(x == y); \
|
||||
wxSTATEMENT_MACRO_END
|
||||
|
||||
// CATCH Approx class uses the upper bound of "epsilon*(scale + max(|x|, |y|))"
|
||||
// for |x - y| which is not really compatible with our fixed delta, so we can't
|
||||
// use it here.
|
||||
#define CPPUNIT_ASSERT_DOUBLES_EQUAL(x, y, delta) \
|
||||
REQUIRE(std::abs(x - y) < delta)
|
||||
|
||||
#define CPPUNIT_FAIL(msg) FAIL(msg)
|
||||
|
||||
#define CPPUNIT_ASSERT_THROW(expr, exception) \
|
||||
try \
|
||||
{ \
|
||||
expr; \
|
||||
FAIL("Expected exception of type " #exception \
|
||||
" not thrown by " #expr); \
|
||||
} \
|
||||
catch ( exception& ) {}
|
||||
|
||||
// Define conversions to strings for some common wxWidgets types.
|
||||
namespace Catch
|
||||
{
|
||||
template <>
|
||||
struct StringMaker<wxUniChar>
|
||||
{
|
||||
static std::string convert(wxUniChar uc)
|
||||
{
|
||||
return wxString(uc).ToStdString(wxConvUTF8);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct StringMaker<wxUniCharRef>
|
||||
{
|
||||
static std::string convert(wxUniCharRef ucr)
|
||||
{
|
||||
return wxString(ucr).ToStdString(wxConvUTF8);
|
||||
}
|
||||
};
|
||||
|
||||
// While this conversion already works due to the existence of the stream
|
||||
// insertion operator for wxString, define a custom one making it more
|
||||
// obvious when strings containing non-printable characters differ.
|
||||
template <>
|
||||
struct StringMaker<wxString>
|
||||
{
|
||||
static std::string convert(const wxString& wxs)
|
||||
{
|
||||
std::string s;
|
||||
s.reserve(wxs.length() + 2);
|
||||
s += '"';
|
||||
for ( auto c : wxs )
|
||||
{
|
||||
if ( c >= 128 || !iswprint(c) )
|
||||
s += wxString::Format(wxASCII_STR("\\u%04X"), c).ToAscii();
|
||||
else
|
||||
s += c;
|
||||
}
|
||||
s += '"';
|
||||
|
||||
return s;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Use a different namespace for our mock ups of the real declarations in
|
||||
// CppUnit namespace to avoid clashes if we end up being linked with the real
|
||||
// CppUnit library, but bring it into scope with a using directive below to
|
||||
// make it possible to compile the original code using CppUnit unmodified.
|
||||
namespace CatchCppUnit
|
||||
{
|
||||
|
||||
namespace CppUnit
|
||||
{
|
||||
|
||||
// These classes don't really correspond to the real CppUnit ones, but contain
|
||||
// just the minimum we need to make CPPUNIT_TEST() macro and our mock up of
|
||||
// TestSuite class work.
|
||||
|
||||
class Test
|
||||
{
|
||||
public:
|
||||
// Name argument exists only for compatibility with the real CppUnit but is
|
||||
// not used here.
|
||||
explicit Test(const std::string& name = std::string()) : m_name(name) { }
|
||||
|
||||
virtual ~Test() = default;
|
||||
|
||||
virtual void runTest() = 0;
|
||||
|
||||
const std::string& getName() const { return m_name; }
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
};
|
||||
|
||||
class TestCase : public Test
|
||||
{
|
||||
public:
|
||||
explicit TestCase(const std::string& name = std::string()) : Test(name) { }
|
||||
|
||||
virtual void setUp() {}
|
||||
virtual void tearDown() {}
|
||||
};
|
||||
|
||||
class TestSuite : public Test
|
||||
{
|
||||
public:
|
||||
explicit TestSuite(const std::string& name = std::string()) : Test(name) { }
|
||||
|
||||
~TestSuite()
|
||||
{
|
||||
for ( size_t n = 0; n < m_tests.size(); ++n )
|
||||
{
|
||||
delete m_tests[n];
|
||||
}
|
||||
}
|
||||
|
||||
void addTest(Test* test) { m_tests.push_back(test); }
|
||||
size_t getChildTestCount() const { return m_tests.size(); }
|
||||
|
||||
void runTest() override
|
||||
{
|
||||
for ( size_t n = 0; n < m_tests.size(); ++n )
|
||||
{
|
||||
m_tests[n]->runTest();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Test*> m_tests;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(TestSuite);
|
||||
};
|
||||
|
||||
} // namespace CppUnit
|
||||
|
||||
} // namespace CatchCppUnit
|
||||
|
||||
using namespace CatchCppUnit;
|
||||
|
||||
// Helpers used in the implementation of the macros below.
|
||||
namespace wxPrivate
|
||||
{
|
||||
|
||||
// An object which resets a string to its old value when going out of scope.
|
||||
class TempStringAssign
|
||||
{
|
||||
public:
|
||||
explicit TempStringAssign(std::string& str, const char* value)
|
||||
: m_str(str),
|
||||
m_orig(str)
|
||||
{
|
||||
str = value;
|
||||
}
|
||||
|
||||
~TempStringAssign()
|
||||
{
|
||||
m_str = m_orig;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string& m_str;
|
||||
const std::string m_orig;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(TempStringAssign);
|
||||
};
|
||||
|
||||
// These two strings are used to implement wxGetCurrentTestName() and must be
|
||||
// defined in the test driver.
|
||||
extern std::string wxTheCurrentTestClass, wxTheCurrentTestMethod;
|
||||
|
||||
} // namespace wxPrivate
|
||||
|
||||
inline std::string wxGetCurrentTestName()
|
||||
{
|
||||
std::string s = wxPrivate::wxTheCurrentTestClass;
|
||||
if ( !s.empty() && !wxPrivate::wxTheCurrentTestMethod.empty() )
|
||||
s += "::";
|
||||
s += wxPrivate::wxTheCurrentTestMethod;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// Notice that the use of this macro unconditionally changes the protection for
|
||||
// everything that follows it to "public". This is necessary to allow taking
|
||||
// the address of the runTest() method in CPPUNIT_TEST_SUITE_REGISTRATION()
|
||||
// below and there just doesn't seem to be any way around it.
|
||||
#define CPPUNIT_TEST_SUITE(testclass) \
|
||||
public: \
|
||||
void runTest() override \
|
||||
{ \
|
||||
using namespace wxPrivate; \
|
||||
TempStringAssign setClass(wxTheCurrentTestClass, #testclass)
|
||||
|
||||
#define CPPUNIT_TEST(testname) \
|
||||
SECTION(#testname) \
|
||||
{ \
|
||||
TempStringAssign setMethod(wxTheCurrentTestMethod, #testname); \
|
||||
setUp(); \
|
||||
try \
|
||||
{ \
|
||||
testname(); \
|
||||
} \
|
||||
catch ( ... ) \
|
||||
{ \
|
||||
tearDown(); \
|
||||
throw; \
|
||||
} \
|
||||
tearDown(); \
|
||||
}
|
||||
|
||||
#define CPPUNIT_TEST_SUITE_END() \
|
||||
} \
|
||||
struct EatNextSemicolon
|
||||
|
||||
#define wxREGISTER_UNIT_TEST_WITH_TAGS(testclass, tags) \
|
||||
METHOD_AS_TEST_CASE(testclass::runTest, #testclass, tags) \
|
||||
struct EatNextSemicolon
|
||||
|
||||
#define CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(testclass, suitename) \
|
||||
wxREGISTER_UNIT_TEST_WITH_TAGS(testclass, "[" suitename "]")
|
||||
|
||||
// Existings tests always use both this macro and the named registration one
|
||||
// above, but we can't register the same test case twice with CATCH, so simply
|
||||
// ignore this one.
|
||||
#define CPPUNIT_TEST_SUITE_REGISTRATION(testclass) \
|
||||
struct EatNextSemicolon
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxWidgets-specific macros
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Convenient variant of INFO() which uses wxString::Format() internally.
|
||||
#define wxINFO_FMT_HELPER(fmt, ...) \
|
||||
wxString::Format(fmt, __VA_ARGS__).ToStdString(wxConvUTF8)
|
||||
|
||||
#define wxINFO_FMT(...) INFO(wxINFO_FMT_HELPER(__VA_ARGS__))
|
||||
|
||||
// Use this macro to assert with the given formatted message (it should contain
|
||||
// the format string and arguments in a separate pair of parentheses)
|
||||
#define WX_ASSERT_MESSAGE(msg, cond) \
|
||||
CPPUNIT_ASSERT_MESSAGE(std::string(wxString::Format msg .mb_str(wxConvLibc)), (cond))
|
||||
|
||||
#define WX_ASSERT_EQUAL_MESSAGE(msg, expected, actual) \
|
||||
CPPUNIT_ASSERT_EQUAL_MESSAGE(std::string(wxString::Format msg .mb_str(wxConvLibc)), \
|
||||
(expected), (actual))
|
||||
|
||||
#endif // _WX_CATCH_CPPUNIT_H_
|
||||
Reference in New Issue
Block a user