1 #ifndef LIBGEODECOMP_MISC_TESTHELPER_H 2 #define LIBGEODECOMP_MISC_TESTHELPER_H 3 4 #include <libgeodecomp/geometry/coord.h> 5 #include <libgeodecomp/geometry/region.h> 6 #include <libgeodecomp/misc/stringops.h> 7 #include <libgeodecomp/misc/stdcontaineroverloads.h> 8 #include <libgeodecomp/storage/grid.h> 9 10 #ifdef __CODEGEARC__ 11 #include <math.h> 12 #else 13 #include <cmath> 14 #endif 15 16 #include <boost/filesystem.hpp> 17 #include <fstream> 18 #include <sstream> 19 #include <cxxtest/TestSuite.h> 20 21 /** 22 * This macro differs from TS_ASSERT_DELTA in that the error margin is relative 23 * rather than absolute 24 */ 25 #define TSM_ASSERT_ROUGHLY_EQUALS_DOUBLE(msg, va, vb, accuracy) \ 26 { \ 27 double tsa_comp1_a = va; \ 28 double tsa_comp1_b = vb; \ 29 double tsa_delta = std::max(fabs(tsa_comp1_a), fabs(tsa_comp1_b)) * accuracy; \ 30 TSM_ASSERT_DELTA(msg, tsa_comp1_a, tsa_comp1_b, tsa_delta); \ 31 } 32 33 34 #define TSM_ASSERT_EQUALS_DOUBLE(msg, va, vb) \ 35 { \ 36 TSM_ASSERT_ROUGHLY_EQUALS_DOUBLE(msg, va, vb, 2.0e-13); \ 37 } 38 39 40 #define TS_ASSERT_EQUALS_DOUBLE(va, vb) \ 41 { \ 42 TSM_ASSERT_EQUALS_DOUBLE("", va, vb); \ 43 } 44 45 46 #define TS_ASSERT_EQUALS_DOUBLE_VEC(va, vb) \ 47 { \ 48 std::vector<double> tsa_comp2_a = va; \ 49 std::vector<double> tsa_comp2_b = vb; \ 50 TS_ASSERT_EQUALS(tsa_comp2_a.size(), tsa_comp2_b.size()); \ 51 for (unsigned i = 0; i < tsa_comp2_b.size(); i++) { \ 52 TS_ASSERT_EQUALS_DOUBLE(tsa_comp2_a[i], tsa_comp2_b[i]); \ 53 } \ 54 } 55 56 57 #define TS_ASSERT_FILE(filename) \ 58 { \ 59 boost::filesystem::path path(filename); \ 60 TSM_ASSERT("File " + filename + " should exist, but doesn't", \ 61 boost::filesystem::exists(path)); \ 62 } 63 64 #define TS_ASSERT_NO_FILE(filename) \ 65 { \ 66 boost::filesystem::path path(filename); \ 67 TSM_ASSERT("File " + filename + " should not exist, but does", \ 68 !boost::filesystem::exists(path)); \ 69 } 70 71 #define TS_ASSERT_FILE_CONTENTS_EQUAL(_filename1, _filename2) \ 72 { \ 73 std::string filename1 = _filename1; \ 74 std::string filename2 = _filename2; \ 75 TS_ASSERT_FILE(filename1); \ 76 TS_ASSERT_FILE(filename2); \ 77 std::ifstream in1(filename1.c_str()); \ 78 std::ifstream in2(filename2.c_str()); \ 79 \ 80 char ch1, ch2; \ 81 int counter = 0; \ 82 while (in1.get(ch1)) { \ 83 if (in2.get(ch2)) { \ 84 std::string message = "Contents differ at byte " + \ 85 StringOps::itoa(counter); \ 86 TSM_ASSERT_EQUALS(message.c_str(), ch1, ch2); \ 87 } else { \ 88 TSM_ASSERT("File lengths differ", false); \ 89 break; \ 90 } \ 91 counter++; \ 92 } \ 93 if (in2.get(ch2)) { \ 94 TSM_ASSERT("File lengths differ", false); \ 95 } \ 96 } 97 98 #define TS_ASSERT_TEST_GRID2(_GRID_TYPE, _GRID, _EXPECTED_CYCLE, TYPENAME) \ 99 { \ 100 const _GRID_TYPE& assertGrid = _GRID; \ 101 unsigned expectedCycle = _EXPECTED_CYCLE; \ 102 bool ollKorrect = true; \ 103 std::ostringstream message; \ 104 \ 105 TS_ASSERT(assertGrid.getEdge().isEdgeCell); \ 106 if (!assertGrid.getEdge().isEdgeCell) { \ 107 ollKorrect = false; \ 108 message << "edgeCell isn't an edgeCell\n"; \ 109 } \ 110 if (!assertGrid.getEdge().valid()) { \ 111 ollKorrect = false; \ 112 message << "edgeCell isn't valid\n"; \ 113 } \ 114 CoordBox<_GRID_TYPE::DIM> box = assertGrid.boundingBox(); \ 115 for (TYPENAME CoordBox<_GRID_TYPE::DIM>::Iterator i = box.begin(); i != box.end(); ++i) { \ 116 bool flagValid = assertGrid.get(*i).valid(); \ 117 bool flagEdge = (assertGrid.get(*i).isEdgeCell == false); \ 118 bool flagCounter = (assertGrid.get(*i).cycleCounter == expectedCycle); \ 119 message << "actual: " << (assertGrid.get(*i).cycleCounter) \ 120 << " expected: " << expectedCycle << "\n"; \ 121 TS_ASSERT(flagValid); \ 122 TS_ASSERT(flagEdge); \ 123 TS_ASSERT(flagCounter); \ 124 bool flag = flagValid && flagEdge && flagCounter; \ 125 ollKorrect &= flag; \ 126 if (!flag) { \ 127 message << "TS_ASSERT_TEST_GRID failed at Coord " << *i << "\n"; \ 128 } \ 129 } \ 130 \ 131 if (!ollKorrect) { \ 132 std::cout << "message: " << message.str(); \ 133 } \ 134 } 135 136 #define TS_ASSERT_TEST_GRID(_GRID_TYPE, _GRID, _EXPECTED_CYCLE) \ 137 TS_ASSERT_TEST_GRID2(_GRID_TYPE, _GRID, _EXPECTED_CYCLE, ) 138 139 #define TS_ASSERT_TEST_GRID_REGION(_GRID_TYPE, _GRID, _REGION, _EXPECTED_CYCLE) \ 140 { \ 141 const _GRID_TYPE& assertGrid = _GRID; \ 142 Region<_GRID_TYPE::DIM> assertRegion = _REGION; \ 143 unsigned expectedCycle = _EXPECTED_CYCLE; \ 144 bool ollKorrect = true; \ 145 \ 146 ollKorrect &= assertGrid.getEdge().isEdgeCell; \ 147 ollKorrect &= assertGrid.getEdge().valid(); \ 148 Region<_GRID_TYPE::DIM>::Iterator end = assertRegion.end(); \ 149 for (Region<_GRID_TYPE::DIM>::Iterator i = assertRegion.begin(); i != end; ++i) { \ 150 bool flag = assertGrid.get(*i).valid(); \ 151 if (!flag) { \ 152 std::cout << "TestCell not valid\n"; \ 153 } \ 154 flag &= (assertGrid.get(*i).isEdgeCell == false); \ 155 if (!flag) { \ 156 std::cout << "TestCell claims to be edge cell\n"; \ 157 } \ 158 flag &= (assertGrid.get(*i).cycleCounter == expectedCycle); \ 159 if (!flag) { \ 160 std::cout << "TestCell cycle counter doesn't match expected value (" \ 161 << assertGrid.get(*i).cycleCounter << " != " \ 162 << expectedCycle << ")\n"; \ 163 } \ 164 TS_ASSERT(flag); \ 165 ollKorrect &= flag; \ 166 if (!flag) { \ 167 std::cout << "TS_ASSERT_TEST_GRID_REGION failed at Coord " << *i << "\n"; \ 168 } \ 169 } \ 170 } 171 172 #endif 173