00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __PION_PIONUNITTESTDEFS_HEADER__
00011 #define __PION_PIONUNITTESTDEFS_HEADER__
00012
00013 #include <iostream>
00014 #include <fstream>
00015 #include <boost/test/unit_test.hpp>
00016 #include <boost/test/test_case_template.hpp>
00017 #include <pion/PionLogger.hpp>
00018
00019 #ifdef _MSC_VER
00020 #include <direct.h>
00021 #define CHANGE_DIRECTORY _chdir
00022 #define GET_DIRECTORY(a,b) _getcwd(a,b)
00023 #else
00024 #include <unistd.h>
00025 #define CHANGE_DIRECTORY chdir
00026 #define GET_DIRECTORY(a,b) getcwd(a,b)
00027 #endif
00028
00029 #define DIRECTORY_MAX_SIZE 1000
00030
00031
00032 struct PionUnitTest {
00033
00034
00035 static void doNothing(void* ctx, const char* msg, ...) {
00036 }
00037
00038
00039 static char* trim(char* str) {
00040 for (long len = strlen(str) - 1; len >= 0; len--) {
00041 if (str[len] == '\n' || str[len] == '\r')
00042 str[len] = '\0';
00043 else
00044 break;
00045 }
00046 return str;
00047 }
00048
00049
00050
00051 static bool read_lines_from_file(const std::string& filename, std::list<std::string>& lines) {
00052
00053 std::ifstream a_file(filename.c_str(), std::ios::in | std::ios::binary);
00054 if (! a_file.is_open())
00055 return false;
00056
00057
00058 static const unsigned int BUF_SIZE = 4096;
00059 char *ptr, buf[BUF_SIZE+1];
00060 buf[BUF_SIZE] = '\0';
00061 lines.clear();
00062
00063 while (a_file.getline(buf, BUF_SIZE)) {
00064 ptr = trim(buf);
00065 if (*ptr != '\0' && *ptr != '#')
00066 lines.push_back(ptr);
00067 }
00068
00069
00070 a_file.close();
00071
00072 return true;
00073 }
00074
00075
00076
00077 static bool check_files_match(const std::string& fileA, const std::string& fileB) {
00078
00079 std::list<std::string> a_lines, b_lines;
00080 BOOST_REQUIRE(read_lines_from_file(fileA, a_lines));
00081 BOOST_REQUIRE(read_lines_from_file(fileB, b_lines));
00082
00083
00084 a_lines.sort();
00085 b_lines.sort();
00086
00087
00088 return (a_lines == b_lines);
00089 }
00090
00091 static bool check_files_exact_match(const std::string& fileA, const std::string& fileB, bool ignore_line_endings = false) {
00092
00093 std::ifstream a_file(fileA.c_str(), std::ios::in | std::ios::binary);
00094 BOOST_REQUIRE(a_file.is_open());
00095
00096 std::ifstream b_file(fileB.c_str(), std::ios::in | std::ios::binary);
00097 BOOST_REQUIRE(b_file.is_open());
00098
00099
00100 static const unsigned int BUF_SIZE = 4096;
00101 char a_buf[BUF_SIZE];
00102 char b_buf[BUF_SIZE];
00103
00104 if (ignore_line_endings) {
00105 while (a_file.getline(a_buf, BUF_SIZE)) {
00106 if (! b_file.getline(b_buf, BUF_SIZE))
00107 return false;
00108 PionUnitTest::trim(a_buf);
00109 PionUnitTest::trim(b_buf);
00110 if (strlen(a_buf) != strlen(b_buf))
00111 return false;
00112 if (memcmp(a_buf, b_buf, strlen(a_buf)) != 0)
00113 return false;
00114 }
00115 if (b_file.getline(b_buf, BUF_SIZE))
00116 return false;
00117 } else {
00118 while (a_file.read(a_buf, BUF_SIZE)) {
00119 if (! b_file.read(b_buf, BUF_SIZE))
00120 return false;
00121 if (memcmp(a_buf, b_buf, BUF_SIZE) != 0)
00122 return false;
00123 }
00124 if (b_file.read(b_buf, BUF_SIZE))
00125 return false;
00126 }
00127 if (a_file.gcount() != b_file.gcount())
00128 return false;
00129 if (memcmp(a_buf, b_buf, a_file.gcount()) != 0)
00130 return false;
00131
00132 a_file.close();
00133 b_file.close();
00134
00135
00136 return true;
00137 }
00138 };
00139
00140
00141
00142
00143
00144
00145
00146
00147 struct PionUnitTestsConfig {
00148 PionUnitTestsConfig() {
00149 std::cout << "global setup for all pion unit tests\n";
00150
00151
00152 int argc = boost::unit_test::framework::master_test_suite().argc;
00153 char** argv = boost::unit_test::framework::master_test_suite().argv;
00154
00155 bool verbose = false;
00156 if (argc > 1) {
00157 if (argv[1][0] == '-' && argv[1][1] == 'v') {
00158 verbose = true;
00159 }
00160 }
00161 PION_LOG_CONFIG_BASIC;
00162 pion::PionLogger log_ptr = PION_GET_LOGGER("pion");
00163 if (verbose) {
00164 PION_LOG_SETLEVEL_WARN(log_ptr);
00165 } else {
00166 std::cout << "Use '-v' to enable logging of errors and warnings from pion.\n";
00167 PION_LOG_SETLEVEL_FATAL(log_ptr);
00168 }
00169 }
00170 ~PionUnitTestsConfig() {
00171 std::cout << "global teardown for all pion unit tests\n";
00172 }
00173 };
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 #define BOOST_AUTO_TEST_SUITE_FIXTURE_TEMPLATE(suite_name, fixture_types) \
00240 BOOST_AUTO_TEST_SUITE(suite_name) \
00241 typedef fixture_types BOOST_AUTO_TEST_CASE_FIXTURE_TYPES; \
00242
00243
00244 #define BOOST_AUTO_TEST_CASE_FIXTURE_TEMPLATE(test_name) \
00245 template<typename F> \
00246 struct test_name : public F \
00247 { void test_method(); }; \
00248 \
00249 struct BOOST_AUTO_TC_INVOKER( test_name ) { \
00250 template<typename TestType> \
00251 static void run( boost::type<TestType>* = 0 ) \
00252 { \
00253 test_name<TestType> t; \
00254 t.test_method(); \
00255 } \
00256 }; \
00257 \
00258 BOOST_AUTO_TU_REGISTRAR( test_name )( \
00259 boost::unit_test::ut_detail::template_test_case_gen< \
00260 BOOST_AUTO_TC_INVOKER( test_name ), \
00261 BOOST_AUTO_TEST_CASE_FIXTURE_TYPES >( \
00262 BOOST_STRINGIZE( test_name ) ) ); \
00263 \
00264 template<typename F> \
00265 void test_name<F>::test_method() \
00266
00267
00268
00269
00270
00271
00272 #define CHECK_THROW_WITH_SPECIFIC_MESSAGE(S, M) \
00273 bool exception_caught = false; \
00274 try { \
00275 S; \
00276 } catch (pion::PionException& e) { \
00277 exception_caught = true; \
00278 BOOST_CHECK_EQUAL(e.what(), M); \
00279 } \
00280 BOOST_CHECK(exception_caught);
00281
00282
00283 #endif