BALL  1.4.79
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
classTest.h
Go to the documentation of this file.
1 // -*- Mode: C++; tab-width: 2; -*-
2 // vi: set ts=2:
3 //
4 
5 #ifndef BALL_CONCEPT_AUTODELETABLE_H
7 #endif
8 
9 #ifndef BALL_SYSTEM_H
10 # include <BALL/SYSTEM/file.h>
11 #endif
12 
13 #ifndef BALL_DATATYPE_REGULAREXPRESSION_H
15 #endif
16 
17 #include <string>
18 #include <list>
19 
20 #ifdef BALL_HAS_SSTREAM
21 # include <sstream>
22 #else
23 # include <strstream>
24 #endif
25 
34 #define PRECISION(a) \
35  TEST::precision = (a);
36 
50 #define START_TEST(class_name)\
51 /* define a special namespace for all internal variables */\
52 /* to avoid potential collisions */\
53 namespace TEST {\
54  int verbose = 0;\
55  bool all_tests = true;\
56  bool test = true;\
57  bool this_test;\
58  int exception = 0;\
59  string exception_name = "";\
60  const char* version_string = BALL_RELEASE_STRING;\
61  bool newline = false;\
62  list<string> tmp_file_list;\
63  std::ifstream infile;\
64  std::ifstream templatefile;\
65  bool equal_files;\
66  double precision = 1e-6;\
67 }\
68 \
69 \
70 int main(int argc, char **argv)\
71 {\
72 \
73  if (argc == 2) {\
74  if (!strcmp(argv[1], "-v"))\
75  TEST::verbose = 1;\
76  if (!strcmp(argv[1], "-V"))\
77  TEST::verbose = 2;\
78  };\
79 \
80  if ((argc > 2) || ((argc == 2) && (TEST::verbose == 0))) {\
81  std::cerr << "Checks " #class_name " class" << std::endl;\
82 \
83  std::cerr << "On successful operation it simply returns OK," << std::endl;\
84  std::cerr << "otherwise FAILURE is printed." << std::endl;\
85  std::cerr << "If called with an argument of -v, " << argv[0] << " prints detailed" << std::endl;\
86  std::cerr << "information about individual tests." << std::endl;\
87  std::cerr << "Option -V provides verbose information on" << std::endl;\
88  std::cerr << "every subtest." << std::endl;\
89  return 1;\
90  }\
91 \
92  if (TEST::verbose > 0)\
93  std::cout << "Version: " << TEST::version_string << std::endl;\
94 \
95  try {\
96 
97 
108 #define END_TEST \
109  /* global try block */\
110  }\
111  /* catch FileNotFound exceptions to print out the file name */\
112  catch (BALL::Exception::FileNotFound& e)\
113  {\
114  TEST::this_test = false;\
115  TEST::test = false;\
116  TEST::all_tests = false;\
117  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
118  {\
119  if (TEST::exception == 1) /* dummy to avoid compiler warnings */\
120  TEST::exception++;\
121  std::cout << std::endl << " (caught exception of type ";\
122  std::cout << e.getName();\
123  if ((e.getLine() > 0) && (!(e.getFile()[0] == '\0')))\
124  std::cout << " outside a subtest, which was thrown in line " << e.getLine() << " of file " << e.getFile();\
125  std::cout << " while looking for file " << e.getFilename();\
126  std::cout << " - unexpected!) " << std::endl;\
127  }\
128  }\
129  /* catch BALL exceptions to retrieve additional information */\
130  catch (BALL::Exception::GeneralException& e)\
131  {\
132  TEST::this_test = false;\
133  TEST::test = false;\
134  TEST::all_tests = false;\
135  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
136  {\
137  if (TEST::exception == 1) /* dummy to avoid compiler warnings */\
138  TEST::exception++;\
139  std::cout << std::endl << " (caught exception of type ";\
140  std::cout << e.getName();\
141  if ((e.getLine() > 0) && (!(e.getFile()[0] == '\0')))\
142  std::cout << " outside a subtest, which was thrown in line " << e.getLine() << " of file " << e.getFile();\
143  std::cout << " - unexpected!) " << std::endl;\
144  std::cout << " (message is: " << e.getMessage() << ")" << std::endl;\
145  }\
146  }\
147  /* catch all std::exception-derived exceptions */\
148  catch (std::exception& e)\
149  {\
150  TEST::this_test = false;\
151  TEST::test = false;\
152  TEST::all_tests = false;\
153  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
154  {\
155  std::cout << std::endl << " (caught expected STL exception outside a subtest: " << e.what() << ")" << std::endl;\
156  }\
157  }\
158 \
159  /* catch all non-BALL/non-STL exceptions */\
160  catch (...)\
161  {\
162  TEST::this_test = false;\
163  TEST::test = false;\
164  TEST::all_tests = false;\
165  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
166  {\
167  std::cout << std::endl << " (caught unidentified and unexpected exception outside a subtest!) " << std::endl;\
168  }\
169  }\
170  /* clean up all temporary files */\
171  while (TEST::tmp_file_list.size() > 0 && TEST::verbose < 1)\
172  {\
173  ::BALL::File::remove(TEST::tmp_file_list.back());\
174  TEST::tmp_file_list.pop_back();\
175  }\
176  /* check for exit code */\
177  if (!TEST::all_tests)\
178  {\
179  std::cout << "FAILED" << std::endl;\
180  return 1;\
181  } else {\
182  std::cout << "PASSED" << std::endl;\
183  return 0;\
184  }\
185  /* Finally, clean up pointers still pointing to */\
186  /* AutoDeletable objects, as this might lead to strange */\
187  /* warnings (still reachable) when using valgrind. */\
188  BALL::AutoDeletable::clearLastPtr(); \
189 }\
190 
191 
206 #define CHECK(test_name) \
207  TEST::test = true;\
208  TEST::newline = false;\
209  if (TEST::verbose > 0)\
210  std::cout << "checking " << #test_name << "... " << std::flush;\
211  try\
212  {\
213  while (true)\
214  {\
215 
216 
229 #define STATUS(message)\
230  if (TEST::verbose > 1)\
231  {\
232  if (!TEST::newline) \
233  {\
234  TEST::newline = true;\
235  std::cout << std::endl;\
236  }\
237  std::cout << " status (line " << __LINE__ << "): " << message << std::endl;\
238  }\
239 
240 
258 #define RESULT \
259  break;\
260  }\
261  }\
262  /* catch FileNotFound exceptions to print out the file name */\
263  catch (BALL::Exception::FileNotFound& e)\
264  {\
265  TEST::this_test = false;\
266  TEST::test = false;\
267  TEST::all_tests = false;\
268  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
269  {\
270  if (TEST::exception == 1) /* dummy to avoid compiler warnings */\
271  TEST::exception++;\
272  std::cout << std::endl << " (caught exception of type ";\
273  std::cout << e.getName();\
274  if ((e.getLine() > 0) && (!(e.getFile()[0] == '\0')))\
275  std::cout << " outside a subtest, which was thrown in line " << e.getLine() << " of file " << e.getFile();\
276  std::cout << " while looking for file " << e.getFilename();\
277  std::cout << " - unexpected!) " << std::endl;\
278  }\
279  }\
280  catch (::BALL::Exception::GeneralException& e)\
281  {\
282  TEST::this_test = false;\
283  TEST::test = false;\
284  TEST::all_tests = false;\
285  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
286  {\
287  if (!TEST::newline) \
288  {\
289  TEST::newline = true;\
290  std::cout << std::endl;\
291  }\
292  std::cout << " (caught exception of type ";\
293  std::cout << e.getName();\
294  if ((e.getLine() > 0) && (!(e.getFile()[0] == '\0')))\
295  std::cout << ", which was thrown in line " << e.getLine() << " of file " << e.getFile();\
296  std::cout << " - unexpected!) " << std::endl;\
297  std::cout << " (message is: " << e.getMessage() << ")" << std::endl;\
298  }\
299  }\
300  catch (...)\
301  {\
302  TEST::this_test = false;\
303  TEST::test = false;\
304  TEST::all_tests = false;\
305  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
306  {\
307  if (!TEST::newline) \
308  {\
309  TEST::newline = true;\
310  std::cout << std::endl;\
311  }\
312  std::cout << " (caught unidentified and unexpected exception!)" << std::endl;\
313  }\
314  }\
315 \
316  TEST::all_tests = TEST::all_tests && TEST::test;\
317  if (TEST::verbose > 0){\
318  if (TEST::newline)\
319  std::cout << " ";\
320  if (TEST::test){\
321  std::cout << "passed" << std::endl;\
322  } else {\
323  std::cout << "FAILED" << std::endl;\
324  }\
325  }\
326 
327 
334 #define NEW_TMP_FILE(filename)\
335  ::BALL::File::createTemporaryFilename(filename);\
336  TEST::tmp_file_list.push_back(filename);\
337  if (TEST::verbose > 1)\
338  {\
339  if (!TEST::newline) \
340  {\
341  TEST::newline = true;\
342  std::cout << std::endl;\
343  }\
344  std::cout << " creating new temporary file '" << filename << "' (line " << __LINE__ << ")" << std::endl;\
345  }\
346 
347 
354 #define NEW_TMP_FILE_WITH_SUFFIX(filename, suffix)\
355  ::BALL::File::createTemporaryFilename(filename, suffix);\
356  TEST::tmp_file_list.push_back(filename);\
357  if (TEST::verbose > 1)\
358  {\
359  if (!TEST::newline) \
360  {\
361  TEST::newline = true;\
362  std::cout << std::endl;\
363  }\
364  std::cout << " creating new temporary file '" << filename << "' (line " << __LINE__ << ")" << std::endl;\
365  }\
366 
367 
374 #define TEST_REAL_EQUAL(a,b) \
375  TEST::this_test = BALL_REAL_EQUAL((a), (b), TEST::precision); \
376  TEST::test = TEST::test && TEST::this_test;\
377  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
378  {\
379  if (!TEST::newline)\
380  {\
381  TEST::newline = true;\
382  std::cout << std::endl;\
383  }\
384  std::cout << " (line " << __LINE__ << " TEST_REAL_EQUAL("<< #a << ", " << #b << "): got " << (a) << ", expected " << (b) << ") ";\
385  if (TEST::this_test)\
386  std::cout << " + " << std::endl;\
387  else \
388  std::cout << " - " << std::endl;\
389  }\
390 
391 
401 #define TEST_EQUAL(a,b) \
402  {\
403  TEST::this_test = ((a) == (b));\
404  TEST::test = TEST::test && TEST::this_test;\
405  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
406  {\
407  if (!TEST::newline)\
408  {\
409  TEST::newline = true;\
410  std::cout << std::endl;\
411  }\
412  std::cout << " (line " << __LINE__ << " TEST_EQUAL(" << #a << ", " << #b << "): got " << (a) << ", expected " << (b) << ") ";\
413  if (TEST::this_test)\
414  std::cout << " + " << std::endl;\
415  else \
416  std::cout << " - " << std::endl;\
417  }\
418  }\
419 
420 
428 #define TEST_NOT_EQUAL(a,b) \
429  {\
430  TEST::this_test = !((a) == (b));\
431  TEST::test = TEST::test && TEST::this_test;\
432  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
433  {\
434  if (!TEST::newline)\
435  {\
436  TEST::newline = true;\
437  std::cout << std::endl;\
438  }\
439  std::cout << " (line " << __LINE__ << " TEST_NOT_EQUAL(" << #a << ", " << #b << "): got " << (a) << ", forbidden is " << (b) << ") ";\
440  if (TEST::this_test)\
441  std::cout << " + " << std::endl;\
442  else \
443  std::cout << " - " << std::endl;\
444  }\
445  }\
446 
447 
457 #define TEST_EXCEPTION(exception_type, command) \
458  {\
459  TEST::exception = 0;\
460  try\
461  {\
462  command;\
463  }\
464  catch (exception_type&)\
465  {\
466  TEST::exception = 1;\
467  }\
468  catch (::BALL::Exception::GeneralException& e)\
469  {\
470  TEST::exception = 2;\
471  TEST::exception_name = e.getName();\
472  }\
473  catch (...)\
474  { \
475  TEST::exception = 3;\
476  }\
477  TEST::this_test = (TEST::exception == 1);\
478  TEST::test = TEST::test && TEST::this_test;\
479  \
480  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
481  {\
482  if (!TEST::newline)\
483  {\
484  TEST::newline = true;\
485  std::cout << std::endl;\
486  }\
487  std::cout << " (line " << __LINE__ << " TEST_EXCEPTION(" << #exception_type << ", " << #command << "): ";\
488  switch (TEST::exception)\
489  {\
490  case 0: std::cout << " ERROR: no exception!) "; break;\
491  case 1: std::cout << " OK) "; break;\
492  case 2: std::cout << " ERROR: wrong exception: " << TEST::exception_name << ") "; break;\
493  case 3: std::cout << " ERROR: wrong exception!) "; break;\
494  }\
495  if (TEST::this_test)\
496  std::cout << " + " << std::endl;\
497  else \
498  std::cout << " - " << std::endl;\
499  }\
500  }\
501 
502 #ifdef BALL_DEBUG
503 
511 #define TEST_PRECONDITION_EXCEPTION(command) \
512  {\
513  TEST::exception = 0;\
514  try\
515  {\
516  command;\
517  }\
518  catch (Exception::Precondition&)\
519  {\
520  TEST::exception = 1;\
521  }\
522  catch (::BALL::Exception::GeneralException& e)\
523  {\
524  TEST::exception = 2;\
525  TEST::exception_name = e.getName();\
526  }\
527  catch (...)\
528  { \
529  TEST::exception = 3;\
530  }\
531  TEST::this_test = (TEST::exception == 1);\
532  TEST::test = TEST::test && TEST::this_test;\
533  \
534  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
535  {\
536  if (!TEST::newline)\
537  {\
538  TEST::newline = true;\
539  std::cout << std::endl;\
540  }\
541  std::cout << " (line " << __LINE__ << " TEST_PRECONDITION_EXCEPTION(" << ", " << #command << "): ";\
542  switch (TEST::exception)\
543  {\
544  case 0: std::cout << " ERROR: no exception!) "; break;\
545  case 1: std::cout << " OK) "; break;\
546  case 2: std::cout << " ERROR: wrong exception: " << TEST::exception_name << ") "; break;\
547  case 3: std::cout << " ERROR: wrong exception!) "; break;\
548  }\
549  if (TEST::this_test)\
550  std::cout << " + " << std::endl;\
551  else \
552  std::cout << " - " << std::endl;\
553  }\
554  }\
555 
556 #else
557 
558 # define TEST_PRECONDITION_EXCEPTION(command)\
559  if (TEST::verbose > 1)\
560  {\
561  std::cout << " TEST_EXCEPTION_PRECONDITION(" #command ") : (DEBUG mode disabled!)" << std::endl;\
562  }\
563 
564 #endif // BALL_DEBUG
565 
571 #define ABORT_IF(condition) \
572  if (condition) break;
573 
581 #define TEST_FILE(filename, templatename) \
582  {\
583  TEST::equal_files = true;\
584  TEST::infile.open(filename, std::ios::in);\
585  TEST::templatefile.open(templatename, std::ios::in);\
586  \
587  if (TEST::infile.good() && TEST::templatefile.good())\
588  {\
589  String TEST_FILE__template_line;\
590  String TEST_FILE__line;\
591  \
592  while (TEST::infile.good() && TEST::templatefile.good())\
593  {\
594  TEST_FILE__template_line.getline(TEST::templatefile);\
595  TEST_FILE__line.getline(TEST::infile);\
596  \
597  TEST::equal_files &= (TEST_FILE__template_line == TEST_FILE__line);\
598  if (TEST_FILE__template_line != TEST_FILE__line)\
599  {\
600  if (TEST::verbose > 0)\
601  {\
602  if (!TEST::newline)\
603  {\
604  TEST::newline = true;\
605  std::cout << std::endl;\
606  }\
607  \
608  std::cout << " TEST_FILE: line mismatch:\n got: '" << TEST_FILE__line << "'\n expected: '" << TEST_FILE__template_line << "'" << std::endl;\
609  }\
610  }\
611  }\
612  } else {\
613  TEST::equal_files = false;\
614  \
615  if (TEST::verbose > 0)\
616  {\
617  if (!TEST::newline)\
618  {\
619  TEST::newline = true;\
620  std::cout << std::endl;\
621  }\
622  \
623  std::cout << " (line " << __LINE__ << ": TEST_FILE(" << #filename << ", " << #templatename ;\
624  std::cout << ") : " << " cannot open file: \"";\
625  if (!TEST::infile.good())\
626  {\
627  std::cout << filename << "\" (input file) ";\
628  }\
629  if (!TEST::templatefile.good())\
630  {\
631  std::cout << templatename << "\" (template file) ";\
632  }\
633  std::cout << std::endl;\
634  \
635  }\
636  }\
637  TEST::infile.close();\
638  TEST::templatefile.close();\
639  TEST::infile.clear();\
640  TEST::templatefile.clear();\
641  \
642  TEST::this_test = TEST::equal_files;\
643  TEST::test = TEST::test && TEST::this_test;\
644  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
645  {\
646  if (!TEST::newline)\
647  {\
648  TEST::newline = true;\
649  std::cout << std::endl;\
650  }\
651  std::cout << " (line " << __LINE__ << ": TEST_FILE("<< #filename << ", " << #templatename << "): ";\
652  if (TEST::this_test)\
653  {\
654  std::cout << "true";\
655  } else {\
656  std::cout << "false";\
657  }\
658  \
659  if (TEST::this_test)\
660  {\
661  std::cout << " + " << std::endl;\
662  } else {\
663  std::cout << " - " << std::endl;\
664  }\
665  }\
666  }
667 
668 
677 #define TEST_FILE_REGEXP(filename, templatename) \
678  {\
679  TEST::equal_files = true;\
680  TEST::infile.open(filename, std::ios::in);\
681  TEST::templatefile.open(templatename, std::ios::in);\
682  \
683  if (TEST::infile.good() && TEST::templatefile.good())\
684  {\
685  String TEST_FILE__template_line;\
686  String TEST_FILE__line;\
687  \
688  while (TEST::infile.good() && TEST::templatefile.good())\
689  {\
690  TEST_FILE__template_line.getline(TEST::templatefile);\
691  TEST_FILE__line.getline(TEST::infile);\
692  \
693  if ((TEST_FILE__template_line.size() > 0) && (TEST_FILE__template_line[0] == '/') && (TEST_FILE__template_line[1] != '/'))\
694  {\
695  RegularExpression expression(TEST_FILE__template_line(1));\
696  bool match = expression.match(TEST_FILE__line);\
697  TEST::equal_files &= match;\
698  if (!match)\
699  {\
700  if (TEST::verbose > 0)\
701  {\
702  if (!TEST::newline)\
703  {\
704  TEST::newline = true;\
705  std::cout << std::endl;\
706  }\
707  \
708  std::cout << " TEST_FILE_REGEXP: regexp mismatch: " << TEST_FILE__line << " did not match " << TEST_FILE__template_line(1) << "." << std::endl;\
709  }\
710  }\
711  } else {\
712  TEST::equal_files &= (TEST_FILE__template_line == TEST_FILE__line);\
713  if (TEST_FILE__template_line != TEST_FILE__line)\
714  {\
715  if (TEST::verbose > 0)\
716  {\
717  if (!TEST::newline)\
718  {\
719  TEST::newline = true;\
720  std::cout << std::endl;\
721  }\
722  \
723  std::cout << " TEST_FILE: line mismatch:\n got: '" << TEST_FILE__line << "'\n expected: '" << TEST_FILE__template_line << "'" << std::endl;\
724  }\
725  }\
726  }\
727  }\
728  } else {\
729  TEST::equal_files = false;\
730  \
731  if (TEST::verbose > 0)\
732  {\
733  if (!TEST::newline)\
734  {\
735  TEST::newline = true;\
736  std::cout << std::endl;\
737  }\
738  \
739  std::cout << " (line " << __LINE__ << ": TEST_FILE_REGEXP(" << #filename << ", " << #templatename ;\
740  std::cout << ") : " << " cannot open file: \"";\
741  if (!TEST::infile.good())\
742  {\
743  std::cout << filename << "\" (input file) ";\
744  }\
745  if (!TEST::templatefile.good())\
746  {\
747  std::cout << templatename << "\" (template file) ";\
748  }\
749  std::cout << std::endl;\
750  \
751  }\
752  }\
753  TEST::infile.close();\
754  TEST::templatefile.close();\
755  TEST::infile.clear();\
756  TEST::templatefile.clear();\
757  \
758  TEST::this_test = TEST::equal_files;\
759  TEST::test = TEST::test && TEST::this_test;\
760  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
761  {\
762  if (!TEST::newline)\
763  {\
764  TEST::newline = true;\
765  std::cout << std::endl;\
766  }\
767  std::cout << " (line " << __LINE__ << ": TEST_FILE_REGEXP("<< #filename << ", " << #templatename << "): ";\
768  if (TEST::this_test)\
769  {\
770  std::cout << "true";\
771  } else {\
772  std::cout << "false";\
773  }\
774  \
775  if (TEST::this_test)\
776  {\
777  std::cout << " + " << std::endl;\
778  } else {\
779  std::cout << " - " << std::endl;\
780  }\
781  }\
782  }
783 
784 
797 #ifdef BALL_HAS_SSTREAM
798 #define CAPTURE_OUTPUT_LEVEL(level) \
799  {\
800  std::ostringstream TEST_strstr;\
801  Log.remove(std::cout);\
802  Log.remove(std::cerr);\
803  Log.insert(TEST_strstr, level, level);
804 #else
805 #define CAPTURE_OUTPUT_LEVEL(level) \
806  {\
807  std::ostrstream TEST_strstr;\
808  Log.remove(std::cout);\
809  Log.remove(std::cerr);\
810  Log.insert(TEST_strstr, level, level);
811 #endif
812 
825 #ifdef BALL_HAS_SSTREAM
826 #define CAPTURE_OUTPUT_LEVEL_RANGE(minlevel, maxlevel) \
827  {\
828  std::ostringstream TEST_strstr;\
829  Log.remove(std::cout);\
830  Log.remove(std::cerr);\
831  Log.insert(TEST_strstr, minlevel, maxlevel);
832 #else
833 #define CAPTURE_OUTPUT_LEVEL_RANGE(minlevel, maxlevel) \
834  {\
835  std::ostrstream TEST_strstr;\
836  Log.remove(std::cout);\
837  Log.remove(std::cerr);\
838  Log.insert(TEST_strstr, minlevel, maxlevel);
839 #endif
840 
845 #ifdef BALL_HAS_SSTREAM
846 #define COMPARE_OUTPUT(text) \
847  Log.remove(TEST_strstr);\
848  Log.insert(std::cout, LogStream::INFORMATION_LEVEL, LogStream::ERROR_LEVEL - 1);\
849  Log.insert(std::cerr, LogStream::ERROR_LEVEL);\
850  TEST::this_test = (::strncmp(TEST_strstr.str().c_str(), text, TEST_strstr.str().size()) == 0);\
851  TEST::test = TEST::test && TEST::this_test;\
852  \
853  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
854  {\
855  /* reserve space for the null-terminated content of the strstrem */\
856  char* TEST_strstr_contents = new char[TEST_strstr.str().size() + 1];\
857  ::strncpy(TEST_strstr_contents, TEST_strstr.str().c_str(), TEST_strstr.str().size());\
858  TEST_strstr_contents[TEST_strstr.str().size()] = '\0';\
859  \
860  if (!TEST::newline)\
861  {\
862  TEST::newline = true;\
863  std::cout << std::endl;\
864  }\
865  std::cout << " (line " << __LINE__ << " COMPARE_OUTPUT(" << #text << "): got '" << (TEST_strstr_contents) << "', expected '" << (text) << ") ";\
866  if (TEST::this_test)\
867  std::cout << " + " << std::endl;\
868  else \
869  std::cout << " - " << std::endl;\
870  delete [] TEST_strstr_contents;\
871  }\
872  }
873 #else
874 #define COMPARE_OUTPUT(text) \
875  Log.remove(TEST_strstr);\
876  Log.insert(std::cout, LogStream::INFORMATION_LEVEL, LogStream::ERROR_LEVEL - 1);\
877  Log.insert(std::cerr, LogStream::ERROR_LEVEL);\
878  TEST::this_test = (::strncmp(TEST_strstr.str(), text, TEST_strstr.str()!=0?strlen(TEST_strstr.str()):0) == 0);\
879  TEST::test = TEST::test && TEST::this_test;\
880  \
881  if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\
882  {\
883  /* reserve space for the null-terminated content of the strstrem */\
884  char* TEST_strstr_contents = new char[TEST_strstr.str()!=0?strlen(TEST_strstr.str()):0 + 1];\
885  ::strncpy(TEST_strstr_contents, TEST_strstr.str(), TEST_strstr.str()!=0?strlen(TEST_strstr.str()):0);\
886  TEST_strstr_contents[TEST_strstr.str()!=0?strlen(TEST_strstr.str()):0] = '\0';\
887  \
888  if (!TEST::newline)\
889  {\
890  TEST::newline = true;\
891  std::cout << std::endl;\
892  }\
893  std::cout << " (line " << __LINE__ << " COMPARE_OUTPUT(" << #text << "): got '" << (TEST_strstr_contents) << "', expected '" << (text) << "') ";\
894  if (TEST::this_test)\
895  std::cout << " + " << std::endl;\
896  else \
897  std::cout << " - " << std::endl;\
898  delete [] TEST_strstr_contents;\
899  }\
900  }
901 
902 #endif