RCFProto

- Main Page
- Classes
- Files

- File List

All Classes Functions Typedefs
Test.hpp
1
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2013, Delta V Software. All rights reserved.
6 // http://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF
12 // under GPL terms.
13 //
14 // Version: 2.0
15 // Contact: support <at> deltavsoft.com
16 //
17 //******************************************************************************
18
19 #ifndef RCF_TEST_TEST_HPP
20 #define RCF_TEST_TEST_HPP
21
22 #include <iostream>
23 #include <string>
24 #include <vector>
25 #include <string>
26
27 #include <RCF/util/VariableArgMacro.hpp>
28
29 #include <RCF/CustomAllocator.hpp>
30
31 #if defined(__GNUC__) && __GNUC__ >= 4
32 #ifdef RCF_TEST_BUILD_DLL
33 #define RCF_TEST_EXPORT __attribute__((visibility("default")))
34 #else
35 #define RCF_TEST_EXPORT __attribute__((visibility("default")))
36 #endif
37 #elif defined(__GNUC__)
38 #ifdef RCF_TEST_BUILD_DLL
39 #define RCF_TEST_EXPORT
40 #else
41 #define RCF_TEST_EXPORT
42 #endif
43 #else
44 #ifdef RCF_TEST_BUILD_DLL
45 #define RCF_TEST_EXPORT __declspec(dllexport)
46 #else
47 #define RCF_TEST_EXPORT
48 #endif
49 #endif
50
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."
53 #endif
54
55 namespace RCF {
56
57 // Test hierarchies.
58 class RCF_TEST_EXPORT TestHierarchy
59 {
60 public:
61
62 TestHierarchy();
63 void pushTestCase(const std::string & name);
64 void popTestCase();
65 std::string currentTestCase();
66 void onlyRunTestCase(const std::string & testCase, bool caseSensitive);
67 void enumerateTestCasesOnly();
68 bool shouldCurrentTestCaseRun();
69 bool didTestCaseRun();
70
71 private:
72
73 void split(
74 const std::string & s,
75 char delim,
76 std::vector<std::string> & elems);
77
78 bool doesCurrentTestCaseMatch();
79
80 std::vector<std::string> mCurrentTestCase;
81
82 std::vector<std::string> mTestCaseToRun;
83 bool mCaseSensitive;
84 bool mHasTestCaseRun;
85
86 bool mEnumerateOnly;
87 };
88
89 class RCF_TEST_EXPORT TestCase
90 {
91 public:
92 TestCase(const std::string & name);
93 TestCase(std::size_t n);
94 ~TestCase();
95
96 bool shouldRun();
97 void setHasRun();
98
99 private:
100
101 std::string mName;
102 bool mRunnable;
103 bool mHasRun;
104 };
105
106 #define TEST_CASE(name) TEST_CASE_IMPL(name, BOOST_PP_CAT(testCase, __LINE__))
107 #define TEST_CASE_IMPL(name, instName) \
108 for (RCF::TestCase instName((name)); instName.shouldRun(); instName.setHasRun())
109
110 class RCF_TEST_EXPORT TestEnv
111 {
112 public:
113 TestEnv();
114
115 void setTestCaseToRun(const std::string & testCase, bool caseSensitive = true);
116 void setEnumerationOnly();
117 void setAssertOnFail(bool assertOnFail);
118
119 typedef void (*PfnAssert)(const char * file, int line, const char * condition , const char * info);
120 void setPfnAssert(PfnAssert pfnAssert);
121
122 std::size_t getFailCount();
123 bool didTestCaseRun();
124
125 void printTestMessage(const std::string & msg);
126
127 void reportTestFailure(
128 const char * file,
129 int line,
130 const char * condition,
131 const char * info);
132
133 private:
134
135 friend class TestCase;
136
137 TestHierarchy mTestHierarchy;
138
139 std::size_t mFailCount;
140
141 bool mAssertOnFail;
142 PfnAssert mPfnAssert;
143 };
144
145 RCF_TEST_EXPORT TestEnv & gTestEnv();
146
147 std::string getRelativePathToCheckoutRoot();
148 std::string getRelativeTestDataPath();
149 std::string getWorkingDir();
150
151 } // namespace RCF
152
153 // RCF_CHECK
154
155 class RcfCheckFunctor : public util::VariableArgMacroFunctor
156 {
157 public:
158
159 RcfCheckFunctor & setArgs(const char * file, int line, const char * cond)
160 {
161 mFile = file;
162 mLine = line;
163 mCond = cond;
164 return *this;
165 }
166
167 ~RcfCheckFunctor()
168 {
169 std::string values(mArgs->str(), static_cast<std::size_t>(mArgs->tellp()));
170 RCF::gTestEnv().reportTestFailure(mFile, mLine, mCond, values.c_str());
171 }
172
173 private:
174 const char * mFile;
175 int mLine;
176 const char * mCond;
177 };
178
179 #ifdef _MSC_VER
180 #pragma warning( push )
181 #pragma warning( disable : 4355 ) // warning C4355: 'this' : used in base member initializer list
182 #endif
183
184 DECLARE_VARIABLE_ARG_MACRO( RCF_CHECK, RcfCheckFunctor );
185
186 #define RCF_CHECK(cond) \
187 if (cond); \
188 else \
189 ::VariableArgMacro<RcfCheckFunctor>() \
190 .setArgs(__FILE__, __LINE__, #cond) \
191 .cast( (::VariableArgMacro<RcfCheckFunctor> *) NULL ) \
192 .RCF_CHECK_A
193
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
197
198 #ifdef _MSC_VER
199 #pragma warning( pop )
200 #endif
201
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)
204
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)
207
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)
210
211 #define RCF_CHECK_FAIL() RCF_CHECK(0)
212 #define RCF_CHECK_OK() RCF_CHECK(1)
213
214 #endif // ! RCF_TEST_TEST_HPP