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