19 #ifndef RCF_TEST_TEST_HPP
20 #define RCF_TEST_TEST_HPP
27 #include <RCF/util/VariableArgMacro.hpp>
29 #include <RCF/CustomAllocator.hpp>
31 #if defined(__GNUC__) && __GNUC__ >= 4
32 #ifdef RCF_TEST_BUILD_DLL
33 #define RCF_TEST_EXPORT __attribute__((visibility("default")))
35 #define RCF_TEST_EXPORT __attribute__((visibility("default")))
37 #elif defined(__GNUC__)
38 #ifdef RCF_TEST_BUILD_DLL
39 #define RCF_TEST_EXPORT
41 #define RCF_TEST_EXPORT
44 #ifdef RCF_TEST_BUILD_DLL
45 #define RCF_TEST_EXPORT __declspec(dllexport)
47 #define RCF_TEST_EXPORT
51 #if defined(RCF_TEST_BUILD_DLL) && defined(_MSC_VER) && !defined(_DLL)
52 #error "Error: DLL builds of RCF require dynamic runtime linking. Select one of the DLL options in Properties -> C/C++ -> Code Generation -> Runtime Library."
58 class RCF_TEST_EXPORT TestHierarchy
63 void pushTestCase(
const std::string & name);
65 std::string currentTestCase();
66 void onlyRunTestCase(
const std::string & testCase,
bool caseSensitive);
67 void enumerateTestCasesOnly();
68 bool shouldCurrentTestCaseRun();
69 bool didTestCaseRun();
74 const std::string & s,
76 std::vector<std::string> & elems);
78 bool doesCurrentTestCaseMatch();
80 std::vector<std::string> mCurrentTestCase;
82 std::vector<std::string> mTestCaseToRun;
89 class RCF_TEST_EXPORT TestCaseSentry
92 TestCaseSentry(
const std::string & name);
93 TestCaseSentry(std::size_t n);
106 #define TEST_CASE(name) TEST_CASE_IMPL(name, BOOST_PP_CAT(testCase, __LINE__))
107 #define TEST_CASE_IMPL(name, instName) \
108 for (RCF::TestCaseSentry instName((name)); instName.shouldRun(); instName.setHasRun())
110 class RCF_TEST_EXPORT TestEnv
115 void setTestCaseToRun(
const std::string & testCase,
bool caseSensitive =
true);
116 void setEnumerationOnly();
117 void setAssertOnFail(
bool assertOnFail);
119 typedef void (*PfnAssert)(
const char * file,
int line,
const char * condition ,
const char * info);
120 void setPfnAssert(PfnAssert pfnAssert);
122 std::size_t getFailCount();
123 bool didTestCaseRun();
125 void printTestMessage(
const std::string & msg);
127 void reportTestFailure(
130 const char * condition,
135 friend class TestCaseSentry;
137 TestHierarchy mTestHierarchy;
139 std::size_t mFailCount;
142 PfnAssert mPfnAssert;
145 RCF_TEST_EXPORT TestEnv & gTestEnv();
147 std::string getRelativePathToCheckoutRoot();
148 std::string getRelativeTestDataPath();
149 std::string getWorkingDir();
155 class RcfCheckFunctor :
public RCF::VariableArgMacroFunctor
159 RcfCheckFunctor & setArgs(
const char * file,
int line,
const char * cond)
169 std::string values(mArgs->str(),
static_cast<std::size_t
>(mArgs->tellp()));
170 RCF::gTestEnv().reportTestFailure(mFile, mLine, mCond, values.c_str());
180 #pragma warning( push )
181 #pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list
184 DECLARE_VARIABLE_ARG_MACRO( RCF_CHECK, RcfCheckFunctor );
186 #define RCF_CHECK(cond) \
189 ::VariableArgMacro<RcfCheckFunctor>() \
190 .setArgs(__FILE__, __LINE__, #cond) \
191 .cast( (::VariableArgMacro<RcfCheckFunctor> *) NULL ) \
194 #define RCF_CHECK_A(x) RCF_CHECK_OP(x, B)
195 #define RCF_CHECK_B(x) RCF_CHECK_OP(x, A)
196 #define RCF_CHECK_OP(x, next) RCF_CHECK_A.notify_((x), #x).RCF_CHECK_ ## next
199 #pragma warning( pop )
202 #define RCF_CHECK_EQ(a,b) RCF_CHECK(a == b)(a)(b)
203 #define RCF_CHECK_NEQ(a,b) RCF_CHECK(a != b)(a)(b)
205 #define RCF_CHECK_LT(a,b) RCF_CHECK(a < b)(a)(b)
206 #define RCF_CHECK_LTEQ(a,b) RCF_CHECK(a <= b)(a)(b)
208 #define RCF_CHECK_GT(a,b) RCF_CHECK(a > b)(a)(b)
209 #define RCF_CHECK_GTEQ(a,b) RCF_CHECK(a >= b)(a)(b)
211 #define RCF_CHECK_FAIL() RCF_CHECK(0)
212 #define RCF_CHECK_OK() RCF_CHECK(1)
214 #endif // ! RCF_TEST_TEST_HPP