xmscore  1.0
TestTools.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
7 //------------------------------------------------------------------------------
8 
9 //----- Included files ---------------------------------------------------------
10 
11 // 1. Precompiled header
12 
13 // 2. My own header
15 
16 // 3. Standard library headers
17 #include <fstream>
18 #include <sstream>
19 
20 // 4. External library headers
21 #pragma warning(push)
22 #pragma warning(disable : 4103) // boost code: alignment change
23 #include <boost/filesystem.hpp>
24 #pragma warning(pop)
25 #include <boost/predef.h>
26 #include <cxxtest/GlobalFixture.h>
27 #include <cxxtest/TestSuite.h>
28 
29 #if BOOST_OS_WINDOWS
30 #include <Windows.h>
31 #elif BOOST_OS_LINUX
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #elif BOOST_OS_MACOS
35 #include <mach-o/dyld.h>
36 #endif
37 
38 // 5. Shared code headers
39 #include <xmscore/misc/XmLog.h>
41 #include <xmscore/points/pt.h>
42 
43 // 6. Non-shared code headers
44 
45 namespace xms
46 {
47 //----- Constants / Enumerations -----------------------------------------------
48 
49 //----- Classes / Structs ------------------------------------------------------
50 namespace
51 {
52 class CheckXmLogFixture : public CxxTest::GlobalFixture
53 {
54 public:
55  bool setUp() override;
56  bool tearDown() override;
57 };
58 
59 static CheckXmLogFixture fg_checkXmLogFixture;
60 static bool fg_checkLogForEachTest = false;
61 
62 //----- Internal functions -----------------------------------------------------
63 
64 //------------------------------------------------------------------------------
66 //------------------------------------------------------------------------------
67 bool CheckXmLogFixture::setUp()
68 {
69  if (fg_checkLogForEachTest)
70  {
72  std::string errors = XmLog::Instance().GetAndClearStackStr();
73  TS_ASSERT_EQUALS(std::string(), errors);
74  return errors == "";
75  }
76  else
77  {
79  return true;
80  }
81 } // CheckXmLogFixture::setUp
82 //------------------------------------------------------------------------------
84 //------------------------------------------------------------------------------
85 bool CheckXmLogFixture::tearDown()
86 {
87  if (fg_checkLogForEachTest)
88  {
90  std::string errors = XmLog::Instance().GetAndClearStackStr();
91  TS_ASSERT_EQUALS(std::string(), errors);
92  // if expected use TS_ASSERT_STACKED_ERRORS
93  return errors == "";
94  }
95  else
96  {
98  return true;
99  }
100 } // CheckXmLogFixture::tearDown
101 
102 //------------------------------------------------------------------------------
106 //------------------------------------------------------------------------------
107 bool iFindTestFile(const std::string& a_filePath)
108 {
109  FILE* fp;
110  bool found;
111 #if BOOST_OS_WINDOWS
112  if (fopen_s(&fp, a_filePath.c_str(), "r") || fp == nullptr)
113  found = false;
114  else
115  found = true;
116 #else
117  fp = fopen(a_filePath.c_str(), "r");
118  found = fp != NULL;
119 #endif
120  if (fp)
121  fclose(fp);
122  return found;
123 } // iFindTestFile
124 
125 } // namespace
126 
127 //----- Class / Function definitions -------------------------------------------
128 
134 //------------------------------------------------------------------------------
136 //------------------------------------------------------------------------------
138 : m_skippingMessages(false)
139 , m_defaultSet(false)
140 , m_defaultRetValue(0)
141 {
142 } // ETestMessagingState::ETestMessagingState
143 //------------------------------------------------------------------------------
146 //------------------------------------------------------------------------------
148 {
149  m_defaultSet = true;
150  m_defaultRetValue = a_;
151 } // ETestMessagingState::SetDefault
152 //------------------------------------------------------------------------------
154 //------------------------------------------------------------------------------
156 {
157  m_defaultSet = false;
158 } // ETestMessagingState::ClearDefault
159 //------------------------------------------------------------------------------
162 //------------------------------------------------------------------------------
164 {
165  return m_defaultRetValue;
166 } // ETestMessagingState::GetDefault
167 //------------------------------------------------------------------------------
170 //------------------------------------------------------------------------------
172 {
173  m_skippingMessages = a_;
174 } // ETestMessagingState::SetSkipping
175 //------------------------------------------------------------------------------
178 //------------------------------------------------------------------------------
180 {
181  return m_skippingMessages;
182 } // ETestMessagingState::GetSkippin
183 //------------------------------------------------------------------------------
186 //------------------------------------------------------------------------------
188 {
189  return m_defaultSet;
190 } // ETestMessagingState::DefaultValWasSet
191 //------------------------------------------------------------------------------
195 //------------------------------------------------------------------------------
196 void ttByPassMessages(int a_defaultChoice)
197 {
198  ttTestMessagingState().SetDefault(a_defaultChoice);
200 } // ttByPassMessages
201 //------------------------------------------------------------------------------
205 //------------------------------------------------------------------------------
207 {
209 } // ttSkippingMessages
210 //------------------------------------------------------------------------------
213 //------------------------------------------------------------------------------
215 {
216  return ttTestMessagingState().GetDefault();
217 } // ttByPassDefault
218 //------------------------------------------------------------------------------
220 //------------------------------------------------------------------------------
222 {
225 } // ttClearSkippingMessages
226 //------------------------------------------------------------------------------
229 //------------------------------------------------------------------------------
231 {
232  static ETestMessagingState m_;
233  return m_;
234 } // ttTestMessagingState
235 //------------------------------------------------------------------------------
238 //------------------------------------------------------------------------------
239 void ttCheckXmLogForEachTest(bool a_setting)
240 {
241  fg_checkLogForEachTest = a_setting;
242 } // ttSetCheckXmLogForEachTest
243 //------------------------------------------------------------------------------
246 //------------------------------------------------------------------------------
248 {
249  return fg_checkLogForEachTest;
250 } // ttCheckXmLogForEachTest
251 //------------------------------------------------------------------------------
256 //------------------------------------------------------------------------------
257 void ttAssertStackedErrors(const char* a_file, int a_line, const std::string& a_expected)
258 {
260  {
261  std::string errors = XmLog::Instance().GetAndClearStackStr();
262  _TS_ASSERT_EQUALS(a_file, a_line, a_expected, errors);
263  }
264 } // ttAssertStackedErrors
265 //------------------------------------------------------------------------------
276 //------------------------------------------------------------------------------
277 void ttGetTestFilePaths(const std::string& a_path,
278  const std::string& a_fileBase,
279  const std::string& a_extension,
280  std::string& a_baseFilePath,
281  std::string& a_outFilePath)
282 {
283  bool foundBase = false;
284 #if BOOST_OS_MACOS
285  // see if there is a different base file for mac os x
286  if (!foundBase)
287  {
288  a_baseFilePath = a_path + a_fileBase + "_baseMacOsX" + a_extension;
289  foundBase = iFindTestFile(a_baseFilePath);
290  }
291 #elif BOOST_OS_LINUX
292  // see if there is a different base file for linux
293  if (!foundBase)
294  {
295  a_baseFilePath = a_path + a_fileBase + "_baseLinux" + a_extension;
296  foundBase = iFindTestFile(a_baseFilePath);
297  }
298 #endif
299 
300 #if defined(ENV64BIT)
301  // see if there is a different base file for 64 bit
302  if (!foundBase)
303  {
304  a_baseFilePath = a_path + a_fileBase + "_base64" + a_extension;
305  foundBase = iFindTestFile(a_baseFilePath);
306  }
307 #elif defined(ENV32BIT)
308  // ensure either ENV32BIT or ENV64BIT is defined
309 #else
310 #error "Must define either ENV32BIT or ENV64BIT"
311 #endif
312  if (!foundBase)
313  a_baseFilePath = a_path + a_fileBase + "_base" + a_extension;
314 
315  a_outFilePath = a_path + a_fileBase + "_out" + a_extension;
316 } // ttGetTestFilePaths
317 //------------------------------------------------------------------------------
323 //------------------------------------------------------------------------------
324 bool ttTextFilesEqual(const std::string& a_file1,
325  const std::string& a_file2,
326  std::string& a_message)
327 {
328  std::ifstream iOut(a_file1), iBase(a_file2);
329  std::string lineOut, lineBase;
330  int lineCnt(1);
331  if (!iOut.is_open() || !iBase.is_open())
332  {
333  std::stringstream msg;
334  msg << "Unable to open file: "
335  << "\n";
336  if (!iOut.is_open())
337  {
338  msg << a_file1;
339  }
340  else
341  {
342  msg << a_file2;
343  }
344  a_message = msg.str();
345  return false;
346  }
347  while (!iOut.eof() && !iBase.eof())
348  {
349  std::getline(iOut, lineOut);
350  std::getline(iBase, lineBase);
351  // remove trailing \r character on unix os
352  lineOut.erase(lineOut.find_last_not_of("\n\r") + 1);
353  lineBase.erase(lineBase.find_last_not_of("\n\r") + 1);
354  if (lineOut != lineBase)
355  {
356  std::stringstream msg;
357  msg << "Files different on line " << lineCnt << "."
358  << "\n"
359  << "File: " << a_file1 << "."
360  << "\n"
361  << lineOut << "\n"
362  << "File: " << a_file2 << "."
363  << "\n"
364  << lineBase << "\n";
365  a_message = msg.str();
366  return false;
367  }
368  lineCnt++;
369  }
370  return true;
371 } // ttTextFilesEqual
372 //----- OVERLOAD ---------------------------------------------------------------
378 //----- OVERLOAD ---------------------------------------------------------------
379 void ttTextFilesEqual(const std::string& a_srcFile,
380  unsigned a_line,
381  const std::string& a_file1,
382  const std::string& a_file2)
383 {
384  std::string msg;
385  if (!ttTextFilesEqual(a_file1, a_file2, msg))
386  _TS_FAIL(a_srcFile.c_str(), a_line, msg.c_str());
387 } // ttTextFilesEqual
388 //------------------------------------------------------------------------------
394 //------------------------------------------------------------------------------
395 void ttStreamsEqual(const std::string& a_src,
396  unsigned int a_line,
397  std::istream& a_strm1,
398  std::istream& a_strm2)
399 {
400  std::string line1, line2;
401  unsigned int line_count(1);
402 
403  // clear the flags and rewind the streams
404  a_strm1.clear();
405  a_strm2.clear();
406 
407  a_strm1.seekg(0);
408  a_strm2.seekg(0);
409 
410  while (!a_strm1.eof() && !a_strm2.eof())
411  {
412  std::getline(a_strm1, line1);
413  std::getline(a_strm2, line2);
414 
415  if (line1 != line2)
416  {
417  std::stringstream msg;
418 
419  msg << "Streams different on line " << line_count << ".\n";
420  msg << "Stream1: \"" << line1 << "\"\n";
421  msg << "Stream2: \"" << line2 << "\"\n";
422 
423  _TS_FAIL(a_src.c_str(), a_line, msg.str().c_str());
424  }
425 
426  ++line_count;
427  }
428 
429  if ((a_strm1.eof() && !a_strm2.eof()) || (!a_strm1.eof() && a_strm2.eof()))
430  {
431  _TS_FAIL(a_src.c_str(), a_line, "Streams of different lengths");
432  }
433 } // ttStreamsEqual
434 //------------------------------------------------------------------------------
440 //------------------------------------------------------------------------------
441 bool ttEqualPointsXYZ(const Pt3d& a_pt1, const Pt3d& a_pt2, double a_tolerance)
442 {
443  return ttEqualPointsXYZ(a_pt1.x, a_pt1.y, a_pt1.z, a_pt2.x, a_pt2.y, a_pt2.z, a_tolerance);
444 } // ttEqualPointsXYZ
445 //------------------------------------------------------------------------------
455 //------------------------------------------------------------------------------
456 bool ttEqualPointsXYZ(double a_x1,
457  double a_y1,
458  double a_z1,
459  double a_x2,
460  double a_y2,
461  double a_z2,
462  double a_tolerance)
463 {
464  if ((fabs(a_x1 - a_x2) <= a_tolerance) && (fabs(a_y1 - a_y2) <= a_tolerance) &&
465  (fabs(a_z1 - a_z2) <= a_tolerance))
466  return true;
467  return false;
468 } // ttEqualPointsXYZ
469 //------------------------------------------------------------------------------
477 //------------------------------------------------------------------------------
478 bool ttEqualPointsXY(double a_x1, double a_y1, double a_x2, double a_y2, double a_tolerance)
479 {
480  double dx = fabs(a_x1 - a_x2);
481  double dy = fabs(a_y1 - a_y2);
482  if (dx > a_tolerance || dy > a_tolerance)
483  return false;
484  else if (sqrt(dx * dx + dy * dy) <= a_tolerance)
485  return true;
486  else
487  return false;
488 } // ttEqualPointsXY
489 //------------------------------------------------------------------------------
495 //------------------------------------------------------------------------------
496 bool ttEqualPointsXY(const Pt2d& a_pt1, const Pt2d& a_pt2, double a_tolerance)
497 {
498  return ttEqualPointsXY(a_pt1.x, a_pt1.y, a_pt2.x, a_pt2.y, a_tolerance);
499 } // ttEqualPointsXY
500 //------------------------------------------------------------------------------
506 //------------------------------------------------------------------------------
507 bool ttEqualPointsXY(const Pt3d& a_pt1, const Pt3d& a_pt2, double a_tolerance)
508 {
509  return ttEqualPointsXY(a_pt1.x, a_pt1.y, a_pt2.x, a_pt2.y, a_tolerance);
510 } // ttEqualPointsXY
511 
512 } // namespace xms
ETestMessagingState & ttTestMessagingState()
Get the batch mode singleton.
Definition: TestTools.cpp:230
T z
z coordinate
Definition: pt.h:799
void ttCheckXmLogForEachTest(bool a_setting)
Set check of XM_LOG before and after each test.
Definition: TestTools.cpp:239
Class to allow running in batch mode without ui elements. Currently only used for testing but it can ...
Definition: TestTools.h:201
bool m_defaultSet
Has a default result value been set?
Definition: TestTools.h:214
T x
x coordinate
Definition: pt.h:797
void ttGetTestFilePaths(const std::string &a_path, const std::string &a_fileBase, const std::string &a_extension, std::string &a_baseFilePath, std::string &a_outFilePath)
Get testing base and output file using the compiled for architecture. Checks for appended "MacOsX" fo...
Definition: TestTools.cpp:277
bool ttEqualPointsXY(double a_x1, double a_y1, double a_x2, double a_y2, double a_tolerance)
Returns true if the points are equal to within tolerance.
Definition: TestTools.cpp:478
bool ttSkippingMessages()
Has ttByPassMessages been called without calling ttClearSkippingMessages.
Definition: TestTools.cpp:206
ETestMessagingState()
Constructor.
Definition: TestTools.cpp:137
T x
x coordinate
Definition: pt.h:88
void ClearDefault()
Change to no default value set.
Definition: TestTools.cpp:155
bool ttEqualPointsXYZ(const Pt3d &a_pt1, const Pt3d &a_pt2, double a_tolerance)
Returns true if the points are equal to within tolerance.
Definition: TestTools.cpp:441
void ttByPassMessages(int a_defaultChoice)
Bypass the ui elements and just set return value.
Definition: TestTools.cpp:196
std::string GetAndClearStackStr()
Clears the error stack and returns its contents as a string.
Definition: XmLog.cpp:228
void ttClearSkippingMessages()
Turn off skipping ui elements.
Definition: TestTools.cpp:221
int GetDefault()
Get default value.
Definition: TestTools.cpp:163
bool m_skippingMessages
Are messages being skipped?
Definition: TestTools.h:213
void SetSkipping(bool a_)
Set if skipping messages.
Definition: TestTools.cpp:171
2D Point template class
Definition: pt.h:82
void SetDefault(int a_)
Set default result value.
Definition: TestTools.cpp:147
3d point template class
Definition: pt.h:791
T y
y coordinate
Definition: pt.h:89
T y
y coordinate
Definition: pt.h:798
64 or 32 bit detection.
int m_defaultRetValue
Default return value.
Definition: TestTools.h:215
Routines for creating and writing to logs and stacking errors.
bool ttTextFilesEqual(const std::string &a_file1, const std::string &a_file2, std::string &a_message)
Returns true if the two files are equal.
Definition: TestTools.cpp:324
static XmLog & Instance(bool a_delete=false, XmLog *a_new=NULL)
Get the instance of the singleton.
Definition: Singleton.h:37
void ttStreamsEqual(const std::string &a_src, unsigned int a_line, std::istream &a_strm1, std::istream &a_strm2)
Returns true if the two streams are equal.
Definition: TestTools.cpp:395
bool DefaultValWasSet()
Was default value set (true) or has it been cleared?
Definition: TestTools.cpp:187
void ttAssertStackedErrors(const char *a_file, int a_line, const std::string &a_expected)
CXX Test assert that the stackable XM_LOG has the expected errors.
Definition: TestTools.cpp:257
int ttByPassDefault()
Get the default choice when skipping messages.
Definition: TestTools.cpp:214
bool GetSkipping()
Get if skipping messages.
Definition: TestTools.cpp:179