- Timestamp:
- 17/11/11 18:18:07 (6 months ago)
- Location:
- branches/e4fix
- Files:
-
- 6 modified
-
AISC_MKPTPS/Makefile (modified) (1 diff)
-
CORE/Makefile (modified) (2 diffs)
-
CORE/arb_string.cxx (modified) (1 diff)
-
SL/PRONUC/Makefile (modified) (1 diff)
-
UNIT_TESTER/TestEnvironment.cxx (modified) (2 diffs)
-
UNIT_TESTER/test_unit.h (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/e4fix/AISC_MKPTPS/Makefile
r7623 r8223 39 39 mkptypes.o: $(ARBHOME)/INCLUDE/arbtools.h 40 40 mkptypes.o: $(ARBHOME)/INCLUDE/attributes.h 41 mkptypes.o: $(ARBHOME)/INCLUDE/dupstr.h 41 42 mkptypes.o: $(ARBHOME)/INCLUDE/test_global.h 42 43 mkptypes.o: $(ARBHOME)/INCLUDE/test_unit.h -
branches/e4fix/CORE/Makefile
r8185 r8223 134 134 arb_string.o: arb_string.h 135 135 arb_string.o: $(ARBHOME)/INCLUDE/arb_assert.h 136 arb_string.o: $(ARBHOME)/INCLUDE/arbtools.h 136 137 arb_string.o: $(ARBHOME)/INCLUDE/attributes.h 137 138 arb_string.o: $(ARBHOME)/INCLUDE/dupstr.h 138 139 arb_string.o: $(ARBHOME)/INCLUDE/test_global.h 140 arb_string.o: $(ARBHOME)/INCLUDE/test_unit.h 139 141 140 142 pos_range.o: arb_core.h … … 142 144 pos_range.o: pos_range.h 143 145 pos_range.o: $(ARBHOME)/INCLUDE/arb_assert.h 146 pos_range.o: $(ARBHOME)/INCLUDE/arbtools.h 144 147 pos_range.o: $(ARBHOME)/INCLUDE/attributes.h 145 148 pos_range.o: $(ARBHOME)/INCLUDE/dupstr.h -
branches/e4fix/CORE/arb_string.cxx
r7314 r8223 69 69 70 70 71 72 71 // -------------------------------------------------------------------------------- 72 73 74 #ifdef UNIT_TESTS 75 76 #include <string> 77 #include <climits> 78 79 #ifndef TEST_UNIT_H 80 #include <test_unit.h> 81 #endif 82 83 using namespace std; 84 85 // ---------------------------------------------- 86 // some tests for unit-test-code itself 87 88 #define TEST_ASSERT_HEAPCOPY_EQUAL(copy,expected) do { \ 89 char *theCopy = (copy); \ 90 TEST_ASSERT_EQUAL(theCopy, expected); \ 91 free(theCopy); \ 92 } while(0) 93 94 void TEST_arbtest_strf() { 95 // tests string formatter from test_unit.h 96 using namespace arb_test; 97 TEST_ASSERT_HEAPCOPY_EQUAL(StaticCode::strf("<%i>", 7), "<7>"); 98 TEST_ASSERT_HEAPCOPY_EQUAL(StaticCode::strf("<%0*i>", 3, 7), "<007>"); 99 } 100 101 void TEST_arbtest_readable() { 102 using namespace arb_test; 103 104 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy('x')), "'x'"); 105 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(static_cast<unsigned char>('x'))), "'x'"); 106 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(static_cast<signed char>('x'))), "'x'"); 107 108 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(true)), "true"); 109 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(false)), "false"); 110 111 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(1)), "1"); 112 TEST_ASSERT_HEAPCOPY_EQUAL(val2hex(make_copy(2)), "0x2"); 113 114 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(3L)), "3"); 115 TEST_ASSERT_HEAPCOPY_EQUAL(val2hex(make_copy(4L)), "0x4"); 116 117 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(5U)), "5"); 118 TEST_ASSERT_HEAPCOPY_EQUAL(val2hex(make_copy(6U)), "0x6"); 119 120 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy("some\ntext\twhich\"special\\chars")), "\"some\\ntext\\twhich\\\"special\\\\chars\""); 121 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy("a\1\2\x1a\x7e\x7f\x80\xfe\xff")), "\"a\\1\\2\\x1a~\\x7f\\x80\\xfe\\xff\""); 122 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy((const char *)NULL)), "(null)"); 123 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy((const unsigned char *)NULL)), "(null)"); 124 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy((const signed char *)NULL)), "(null)"); 125 126 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(1.7)), "1.700000"); 127 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(177.0e20)), "17699999999999998951424.000000"); 128 TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(177.0e20F)), "17699999967695435988992.000000"); 129 } 130 131 void TEST_arbtest_copyable() { 132 using namespace arb_test; 133 134 int i = 7; 135 const char *s = "servas"; 136 137 TEST_ASSERT(make_copy(i) == make_copy(7)); 138 139 TEST_ASSERT(strcmp(make_copy(s), make_copy("servas")) == 0); 140 } 141 142 #define TEST_DESCRIPTIONS(d, tt, tf, ft, ff) do { \ 143 TEST_ASSERT_EQUAL((d).make(true, true), (tt)); \ 144 TEST_ASSERT_EQUAL((d).make(true, false), (tf)); \ 145 TEST_ASSERT_EQUAL((d).make(false, true), (ft)); \ 146 TEST_ASSERT_EQUAL((d).make(false, false), (ff)); \ 147 } while(0) 148 149 #define TEST_SIMPLE_DESCRIPTIONS(d, ae, nae) TEST_DESCRIPTIONS(d, ae, nae, nae, ae) 150 151 void TEST_arbtest_predicate_description() { 152 TEST_SIMPLE_DESCRIPTIONS(predicate_description("similar"), "is similar", "isnt similar"); 153 TEST_SIMPLE_DESCRIPTIONS(predicate_description("repairs"), "repairs", "doesnt repair"); 154 155 TEST_DESCRIPTIONS(predicate_description("equals", "differs"), 156 "equals", "doesnt equal", 157 "doesnt differ", "differs"); 158 159 TEST_DESCRIPTIONS(predicate_description("less_than", "more_than"), 160 "is less_than", "isnt less_than", 161 "isnt more_than", "is more_than"); 162 } 163 164 void TEST_arbtest_expectations() { 165 // used to TDD expectations 166 using namespace arb_test; 167 168 string apple = "Apfel"; 169 string pear = "Birne"; 170 string boskop = apple; 171 string pomegranate = "Granatapfel"; 172 173 TEST_EXPECT(that(apple).equals("Apfel")); 174 175 TEST_EXPECT(that(apple).differs(pear)); 176 TEST_EXPECT(that(apple).equals(boskop)); 177 TEST_EXPECT(wrong(that(pomegranate).equals(apple))); 178 179 match_expectation ff1 = that(1.0).equals(2-1); 180 match_expectation ff2 = that(boskop).equals(apple); 181 match_expectation ff3 = that(apple).equals(apple); 182 183 match_expectation nf1 = that(apple).equals(pear); 184 match_expectation nf2 = that(pomegranate).equals(apple); 185 match_expectation nf3 = that(apple).differs(boskop); 186 187 match_expectation a1 = all().of(ff1); 188 match_expectation a2 = all().of(ff1, ff2); 189 match_expectation a3 = all().of(ff1, ff2, ff3); 190 191 TEST_EXPECT(a1); 192 TEST_EXPECT(a2); 193 TEST_EXPECT(a3); 194 195 match_expectation n1 = none().of(ff1); 196 match_expectation n2 = none().of(ff1, ff2); 197 match_expectation n3 = none().of(ff1, ff2, ff3); 198 199 TEST_EXPECT(wrong(none().of(that(boskop).equals(apple)))); 200 TEST_EXPECT(wrong(n1)); 201 TEST_EXPECT(wrong(n2)); 202 TEST_EXPECT(wrong(n3)); 203 204 TEST_EXPECT(atleast(1).of(a1)); 205 TEST_EXPECT(atleast(1).of(a1, n1)); 206 TEST_EXPECT(atleast(1).of(n2, a1, n1)); 207 208 TEST_EXPECT(wrong(atleast(2).of(a1, n1, n2))); 209 TEST_EXPECT(wrong(atleast(2).of(a1, n1))); 210 TEST_EXPECT(wrong(atleast(2).of(a1))); // impossible 211 212 TEST_EXPECT(atmost(2).of(a1)); 213 TEST_EXPECT(atmost(2).of(a1, a2)); 214 TEST_EXPECT(atmost(2).of(a1, a2, n1)); 215 TEST_EXPECT(atmost(2).of(a1, n1, n2)); 216 TEST_EXPECT(atmost(2).of(n1, n2)); 217 TEST_EXPECT(wrong(atmost(2).of(a1, a2, a3))); 218 219 TEST_EXPECT(exacly(1).of(ff1, nf1, nf2)); 220 TEST_EXPECT(wrong(exacly(1).of(nf1, nf2))); 221 TEST_EXPECT(wrong(exacly(1).of(nf1, nf2, nf3))); 222 TEST_EXPECT(wrong(exacly(1).of(ff1, ff2, nf2))); 223 TEST_EXPECT(wrong(exacly(1).of(ff1, ff2, ff3))); 224 225 } 226 227 void TEST_replace_old_TEST_ASSERTS_by_expectations() { 228 // test various string-types are matchable (w/o casts) 229 { 230 const char *car_ccp = "Alfa"; 231 char *car_cp = strdup("Alfa"); 232 string car_str("Alfa"); 233 234 TEST_ASSERT_EQUAL(car_ccp, "Alfa"); 235 TEST_ASSERT_EQUAL(car_cp, "Alfa"); 236 TEST_ASSERT_EQUAL(car_str, "Alfa"); 237 238 TEST_ASSERT_EQUAL("Alfa", car_ccp); 239 TEST_ASSERT_EQUAL("Alfa", car_cp); 240 TEST_ASSERT_EQUAL("Alfa", car_str); 241 242 TEST_ASSERT_EQUAL(car_cp, car_ccp); 243 TEST_ASSERT_EQUAL(car_cp, car_str); 244 TEST_ASSERT_EQUAL(car_ccp, car_cp); 245 TEST_ASSERT_EQUAL(car_ccp, car_str); 246 TEST_ASSERT_EQUAL(car_str, car_cp); 247 TEST_ASSERT_EQUAL(car_str, car_ccp); 248 249 char *null = NULL; 250 TEST_ASSERT_NULL(NULL); 251 TEST_ASSERT_NULL(null); 252 253 TEST_ASSERT_CONTAINS(car_ccp, "lf"); 254 TEST_ASSERT_CONTAINS(car_cp, "fa"); 255 TEST_ASSERT_CONTAINS(car_str, "Al"); 256 257 free(car_cp); 258 } 259 260 // test various numeric types are matchable 261 262 { 263 short unsigned su = 7; 264 short s = -su; 265 266 unsigned iu = su; 267 int i = -iu; 268 269 long unsigned lu = (long unsigned)INT_MAX+3; 270 long l = -lu; 271 272 float f = s; 273 double d = i; 274 275 TEST_ASSERT_EQUAL(s, -7); 276 TEST_ASSERT_EQUAL(i, -7); 277 278 TEST_ASSERT_EQUAL(su, 7); TEST_ASSERT_EQUAL(iu, 7); 279 TEST_ASSERT_EQUAL(su, 7U); TEST_ASSERT_EQUAL(iu, 7U); 280 TEST_ASSERT_EQUAL(su, 7L); TEST_ASSERT_EQUAL(iu, 7L); 281 282 TEST_ASSERT_EQUAL(s, -su); TEST_ASSERT_EQUAL(s, -iu); 283 TEST_ASSERT_EQUAL(i, -iu); TEST_ASSERT_EQUAL(i, -su); 284 TEST_ASSERT_EQUAL(l, -lu); 285 286 TEST_ASSERT_EQUAL(f, d); 287 TEST_ASSERT_EQUAL(d, f); 288 } 289 290 TEST_ASSERT_ZERO(7-7); 291 } 292 293 // --- simulate user_type (which may be defined anywhere) --- 294 class user_type { 295 int x, y; 296 public: 297 user_type(int X, int Y) : x(X), y(Y) {} 298 299 int get_x() const { return x; } 300 int get_y() const { return y; } 301 302 user_type flipped() const { return user_type(y,x); } 303 304 int quadrant() const { 305 if (x == 0 || y == 0) return 0; // on axis 306 if (y>0) return x<0 ? 2 : 1; 307 return x<0 ? 3 : 4; 308 } 309 }; 310 // --- end of user_type --- 311 312 // helpers needed for tests: 313 inline bool operator == (const user_type& u1, const user_type& u2) { return u1.get_x() == u2.get_x() && u1.get_y() == u2.get_y(); } 314 inline char *val2readable(const user_type& u) { return arb_test::StaticCode::strf("user_type(%i,%i)", u.get_x(), u.get_y()); } 315 inline bool in_same_quadrant(const user_type& u1, const user_type& u2) { return u1.quadrant() == u2.quadrant(); } 316 317 void TEST_user_type_with_expectations() { 318 user_type ut1(3, 4); 319 user_type ut12(4, 4); 320 user_type ut2(-4, 4); 321 user_type ut3(-4, -8); 322 user_type ut4(4, -8); 323 324 TEST_EXPECT(that(ut1).differs(ut12)); 325 TEST_EXPECT(that(ut12).equals(ut12.flipped())); 326 TEST_EXPECT(that(ut1).differs(ut1.flipped())); 327 328 TEST_EXPECT(that(ut1).is(in_same_quadrant, ut12)); 329 TEST_EXPECT(none().of(that(ut1).is(in_same_quadrant, ut2), 330 that(ut2).is(in_same_quadrant, ut3), 331 that(ut3).is(in_same_quadrant, ut4))); 332 } 333 334 void TEST_similarity() { 335 double d1 = 0.7531; 336 double epsilon = 0.00001; 337 double d2 = d1-epsilon*0.6; 338 double d3 = d1+epsilon*0.6; 339 340 TEST_EXPECT(that(d1).is(epsilon_similar(epsilon), d2)); 341 TEST_EXPECT(that(d1).is(epsilon_similar(epsilon), d3)); 342 TEST_EXPECT(that(d2).is_not(epsilon_similar(epsilon), d3)); 343 344 TEST_ASSERT_SIMILAR(d1, d2, epsilon); 345 TEST_ASSERT_SIMILAR(d1, d3, epsilon); 346 } 347 348 void TEST_less_equal() { 349 int x = 7; 350 int y = 8; 351 int z = 9; 352 353 // less/more etc 354 355 TEST_EXPECT(that(x).less_than(y)); 356 TEST_EXPECT(that(x).less_or_equal(y)); 357 TEST_EXPECT(that(x).less_or_equal(x)); 358 359 TEST_EXPECT(that(y).more_than(x)); 360 TEST_EXPECT(that(y).more_or_equal(x)); 361 TEST_EXPECT(that(y).more_or_equal(y)); 362 363 TEST_ASSERT_LOWER_EQUAL(x, y); 364 TEST_ASSERT_LOWER_EQUAL(x, x); 365 TEST_ASSERT_LOWER(x, y); 366 TEST_ASSERT_IN_RANGE(y, x, z); 367 } 368 369 #endif // UNIT_TESTS 370 371 // -------------------------------------------------------------------------------- 372 373 -
branches/e4fix/SL/PRONUC/Makefile
r7423 r8223 79 79 iupac.o: $(ARBHOME)/INCLUDE/arb_core.h 80 80 iupac.o: $(ARBHOME)/INCLUDE/arbdb_base.h 81 iupac.o: $(ARBHOME)/INCLUDE/arbtools.h 81 82 iupac.o: $(ARBHOME)/INCLUDE/dupstr.h 82 83 iupac.o: $(ARBHOME)/INCLUDE/test_global.h -
branches/e4fix/UNIT_TESTER/TestEnvironment.cxx
r8177 r8223 183 183 if (!fp) { 184 184 GB_ERROR error = GB_IO_error("creating flag", flagfile); 185 StaticCode::errorf(__FILE__, __LINE__, "%s\n", error);185 HERE.errorf(true, "%s\n", error); 186 186 } 187 187 fclose(fp); … … 197 197 if (res != 0) { 198 198 GB_ERROR error = GB_IO_error("unlinking", flagfile); 199 StaticCode::errorf(__FILE__, __LINE__, "%s\n", error);199 HERE.errorf(true, "%s\n", error); 200 200 } 201 201 env_assert(!flagFileExists()); -
branches/e4fix/UNIT_TESTER/test_unit.h
r8104 r8223 16 16 #include <arb_assert.h> 17 17 #endif 18 #ifndef ARBTOOLS_H 19 #include <arbtools.h> 20 #endif 18 21 #ifndef _GLIBCXX_CSTDARG 19 22 #include <cstdarg> … … 25 28 #include <errno.h> 26 29 #endif 30 #ifndef DUPSTR_H 31 #include <dupstr.h> 32 #endif 33 34 #if defined(_GLIBCXX_STRING) 35 #define TESTS_KNOW_STRING 36 #endif 37 27 38 28 39 #define ENABLE_CRASH_TESTS // comment out this line to get rid of provoked SEGVs (e.g. while debugging test-code) 29 // #define TRACE_IS_EQUAL // print calls to numerical is_equal()30 40 31 41 /* Note: … … 36 46 * test is known to fail, but cannot be fixed atm for some reason 37 47 * 48 * Recommended test-assertion is TEST_EXPECT(that(..).xxx()) 49 * see examples in test-unit-tests in ../CORE/arb_string.cxx@UNIT_TESTS 38 50 */ 39 51 … … 44 56 namespace arb_test { 45 57 46 class StaticCode { 47 static void vcompiler_msg(const char *filename, int lineno, const char *message_type, const char *format, va_list parg) __attribute__((format(__printf__, 4, 0))) { 48 fprintf(stderr, "%s:%i: ", filename, lineno); 58 // ------------- 59 // str 60 61 class str { 62 char *s; 63 public: 64 str() : s(0) {} 65 str(const str& other) : s(nulldup(other.s)) {} 66 explicit str(char *S) : s(S) {} 67 str& operator = (const str& other) { 68 freedup(s, other.s); 69 return *this; 70 } 71 str& operator = (char *S) { 72 freeset(s, S); 73 return *this; 74 } 75 ~str() { free(s); } 76 77 bool exists() const { return s; } 78 void assign(char *S) { s = S; } 79 const char *value() const { return s; } 80 }; 81 82 // ----------------------- 83 // location info 84 85 #define WITHVALISTFROM(format,CODE) do { va_list parg; va_start(parg, format); CODE; va_end(parg); } while(0) 86 #define VPRINTFORMAT(format) WITHVALISTFROM(format, vfprintf(stderr, format, parg)) 87 #define VCOMPILERMSG(msgtype,format) WITHVALISTFROM(format, vcompiler_msg(msgtype, format, parg)) 88 89 class locinfo //! stores source code location 90 { 91 const char *file; 92 int line; 93 94 __attribute__((format(__printf__, 2, 0))) void vcompiler_msg(const char *message_type, const char *format, va_list parg) const { 95 fprintf(stderr, "%s:%i: ", file, line); 49 96 if (message_type) fprintf(stderr, "%s: ", message_type); 50 97 vfprintf(stderr, format, parg); 51 98 } 52 53 #define WITHVALISTFROM(format,CODE) do { va_list parg; va_start(parg, format); CODE; va_end(parg); } while(0)54 #define VPRINTFORMAT(format) WITHVALISTFROM(format, vfprintf(stderr, format, parg))55 #define VCOMPILERMSG(file,line,msgtype,format) WITHVALISTFROM(format, vcompiler_msg(file, line, msgtype, format, parg))56 99 57 100 public: 58 101 locinfo() : file(0), line(0) {} 102 locinfo(const char *file_, int line_) : file(file_), line(line_) {} 103 104 bool exists() const { return file; } 105 106 const char *get_file() const { return file; } 107 int get_line() const { return line; } 108 109 __attribute__((format(printf, 2, 3))) void warningf(const char *format, ...) const { 110 GlobalTestData& global = test_data(); 111 if (global.show_warnings) { 112 FlushedOutput yes; 113 VCOMPILERMSG("Warning", format); 114 GlobalTestData::print_annotation(); 115 global.warnings++; 116 } 117 } 118 119 __attribute__((format(printf, 3, 4))) void errorf(bool fail, const char *format, ...) const { 120 { 121 FlushedOutput yes; 122 VCOMPILERMSG("Error", format); 123 GlobalTestData::print_annotation(); 124 } 125 if (fail) TRIGGER_ASSERTION(false); // fake an assertion failure 126 } 127 __attribute__((format(printf, 3, 4))) void ioerrorf(bool fail, const char *format, ...) const { 128 { 129 FlushedOutput yes; 130 VCOMPILERMSG("Error", format); 131 fprintf(stderr, " (errno=%i='%s')", errno, strerror(errno)); 132 GlobalTestData::print_annotation(); 133 } 134 if (fail) TRIGGER_ASSERTION(false); // fake an assertion failure 135 } 136 }; 137 138 // -------------------- 139 // StaticCode 140 141 struct StaticCode { 59 142 static void printf(const char *format, ...) __attribute__((format(printf, 1, 2))) { 60 143 FlushedOutputNoLF yes; 61 144 VPRINTFORMAT(format); 62 145 } 63 static void warningf(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) {64 GlobalTestData& global = test_data();65 if (global.show_warnings) {66 FlushedOutput yes;67 VCOMPILERMSG(filename, lineno, "Warning", format);68 GlobalTestData::print_annotation();69 global.warnings++;70 }71 }72 static void errorf(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) {73 {74 FlushedOutput yes;75 VCOMPILERMSG(filename, lineno, "Error", format);76 GlobalTestData::print_annotation();77 }78 TRIGGER_ASSERTION(false); // fake an assertion failure79 }80 static void ioerrorf(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) {81 {82 FlushedOutput yes;83 VCOMPILERMSG(filename, lineno, "Error", format);84 fprintf(stderr, " (errno=%i='%s')", errno, strerror(errno));85 GlobalTestData::print_annotation();86 }87 TRIGGER_ASSERTION(false); // fake an assertion failure88 }89 146 #undef VPRINTFORMAT 90 147 #undef VCOMPILERMSG 91 148 #undef WITHVALISTFROM 92 149 93 static void print_readable_string(const char *s, FILE *out) {150 static char *readable_string(const char *s) { 94 151 // quote like C does! 95 152 if (s) { 96 fputc('\"', out); 97 for (int i_ = 0; s[i_]; ++i_) { 98 switch (s[i_]) { 99 case '\n': fputs("\\n", out); break; 100 case '\t': fputs("\\t", out); break; 101 case '\"': fputs("\\\"", out); break; 102 case '\\': fputs("\\\\", out); break; 103 default: fputc(s[i_], out); break; 153 size_t len = strlen(s)*4; 154 char *res = (char*)malloc(len+2+1); 155 156 int j = 0; 157 res[j++] = '\"'; 158 for (int i = 0; s[i]; ++i) { 159 unsigned char c = static_cast<unsigned char>(s[i]); 160 char esc = 0; 161 switch (c) { 162 case '\n': esc = 'n'; break; 163 case '\t': esc = 't'; break; 164 case '\"': esc = '\"'; break; 165 case '\\': esc = '\\'; break; 166 default: if (c<10) esc = c-1+'1'; break; 167 } 168 if (esc) { 169 res[j++] = '\\'; 170 res[j++] = esc; 171 } 172 else { 173 if (c >= 32 && c<127) { 174 res[j++] = c; 175 } 176 else { 177 j += sprintf(res+j, "\\x%02x", int(c)); 178 } 104 179 } 105 180 } 106 fputc('\"', out); 181 res[j++] = '\"'; 182 res[j++] = 0; 183 return res; 107 184 } 108 185 else { 109 fputs("(null)", out); 110 } 111 } 112 }; 113 114 inline void print(int i) { fprintf(stderr, "%i", i); } 115 inline void print_hex(int i) { fprintf(stderr, "0x%x", i); } 116 117 inline void print(long L) { fprintf(stderr, "%li", L); } 118 inline void print_hex(long L) { fprintf(stderr, "0x%lx", L); } 119 120 inline void print(const char *s) { StaticCode::print_readable_string(s, stderr); } 121 // no print_hex for strings 122 123 inline void print(size_t z) { fprintf(stderr, "%zu", z); } 124 inline void print_hex(size_t z) { fprintf(stderr, "0x%zx", z); } 125 126 inline void print(unsigned char c) { fprintf(stderr, "'%c'", c); } 127 inline void print_hex(unsigned char c) { print_hex(size_t(c)); } 128 129 inline void print(char c) { print((unsigned char)c); } 130 inline void print_hex(char c) { print_hex((unsigned char)c); } 186 return strdup("(null)"); 187 } 188 } 189 static void print_readable_string(const char *s, FILE *out) { 190 fputs(str(readable_string(s)).value(), out); 191 } 192 193 static char *vstrf(const char *format, va_list& parg) __attribute__((format(__printf__, 1, 0))) { 194 static const size_t max_vstrf_size = 10000; 195 static char vstrf_buf[max_vstrf_size]; 196 197 int printed = vsnprintf(vstrf_buf, max_vstrf_size, format, parg); 198 arb_assert(printed >= 0 && size_t(printed)<max_vstrf_size); 199 200 char *result = (char*)malloc(printed+1); 201 memcpy(result, vstrf_buf, printed); 202 result[printed] = 0; 203 return result; 204 } 205 206 static char *strf(const char *format, ...) __attribute__((format(__printf__, 1, 2))) { 207 va_list parg; 208 va_start(parg, format); 209 char *result = vstrf(format, parg); 210 va_end(parg); 211 return result; 212 } 213 214 }; 215 216 inline char *val2readable(bool b) { return strdup(b ? "true" : "false"); } 217 218 inline char *val2readable(int i) { return StaticCode::strf("%i", i); } 219 inline char *val2hex(int i) { return StaticCode::strf("0x%x", i); } 220 221 inline char *val2readable(long L) { return StaticCode::strf("%li", L); } 222 inline char *val2hex(long L) { return StaticCode::strf("0x%lx", L); } 223 224 inline char *val2readable(size_t z) { return StaticCode::strf("%zu", z); } 225 inline char *val2hex(size_t z) { return StaticCode::strf("0x%zx", z); } 131 226 132 227 // dont dup size_t: 133 228 #ifdef ARB_64 134 inline void print(unsigned u) { fprintf(stderr,"%u", u); }135 inline void print_hex(unsigned u) { fprintf(stderr,"0x%x", u); }229 inline char *val2readable(unsigned u) { return StaticCode::strf("%u", u); } 230 inline char *val2hex(unsigned u) { return StaticCode::strf("0x%x", u); } 136 231 #else 137 inline void print(long unsigned u) { fprintf(stderr,"%lu", u); }138 inline void print_hex(long unsigned u) { fprintf(stderr,"0x%lx", u); }232 inline char *val2readable(long unsigned u) { return StaticCode::strf("%lu", u); } 233 inline char *val2hex(long unsigned u) { return StaticCode::strf("0x%lx", u); } 139 234 #endif 235 236 inline char *val2readable(double d) { return StaticCode::strf("%f", d); } 237 238 inline char *val2readable(unsigned char c) { arb_assert(c); return StaticCode::strf("'%c'", c); } 239 inline char *val2readable(const char *s) { return StaticCode::readable_string(s); } 240 241 #ifdef TESTS_KNOW_STRING 242 inline char *val2readable(const std::string& s) { return StaticCode::readable_string(s.c_str()); } 243 #endif 244 245 template <typename T> inline void print(const T& t) { fputs(val2readable(make_copy(t)), stderr); } 246 template <typename T> inline void print_hex(const T& t) { fputs(val2hex(make_copy(t)), stderr); } 140 247 141 248 template <typename T1, typename T2> inline void print_pair(T1 t1, T2 t2) { 142 249 print(t1); 143 fputs(", ", stderr);250 fputs(",", stderr); 144 251 print(t2); 145 252 } … … 150 257 } 151 258 152 template <typename T> inline const char *nameoftype(T unspecialized) { 153 return specialized_nameoftype(unspecialized); // define instanciating type below! 154 } 155 156 #define NAMEOFTYPE(type) template <> inline const char * nameoftype<>(type) { return #type; } 157 NAMEOFTYPE(bool); 158 NAMEOFTYPE(char); 159 NAMEOFTYPE(unsigned char); 160 NAMEOFTYPE(const char*); 161 NAMEOFTYPE(int); 162 NAMEOFTYPE(unsigned int); 163 NAMEOFTYPE(long int); 164 NAMEOFTYPE(long unsigned int); 165 #undef NAMEOFTYPE 166 167 168 169 #ifdef TRACE_IS_EQUAL 170 template <typename T1, typename T2> inline bool bool_traced(const char *name, bool equal, T1 t1, T2 t2) { 171 fprintf(stderr, "%-5s = %s(%s ", (equal ? "true" : "false"), name, nameoftype(t1)); 172 print(t1); 173 fprintf(stderr, ",%s ", nameoftype(t2)); 174 print(t2); 175 fprintf(stderr, ")\n"); 176 return equal; 177 } 178 #else 179 template <typename T1, typename T2> inline bool bool_traced(const char *, bool equal, T1 , T2 ) { 180 return equal; 181 } 259 class epsilon_similar { 260 double epsilon; 261 public: 262 epsilon_similar(double epsilon_) : epsilon(epsilon_) {} 263 bool operator()(const double& d1, const double& d2) const { 264 double diff = d1-d2; 265 if (diff<0.0) diff = -diff; // do not use fabs() here 266 return diff <= epsilon; 267 } 268 }; 269 270 struct containing { 271 bool operator()(const char *str, const char *part) const { return strstr(str, part); } 272 #if defined(TESTS_KNOW_STRING) 273 bool operator()(const std::string& str, const std::string& part) const { return strstr(str.c_str(), part.c_str()); } 182 274 #endif 183 184 template <typename T1, typename T2> inline bool is_equal(T1 t1, T2 t2) { 185 return bool_traced("is_equal", t1 == t2, t1, t2); 186 } 187 template<> inline bool is_equal<>(const char *s1, const char *s2) { 188 return bool_traced("is_equal", (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0), s1, s2); 189 } 190 template <typename T1, typename T2> inline bool is_less(T1 t1, T2 t2) { 191 return bool_traced("is_less", t1 < t2, t1, t2); 192 } 193 194 195 template <typename T1, typename T2> inline void print_failed_compare(T1 t1, T2 t2, const char *prefix, const char *infix, const char *suffix) { 196 FlushedOutput yes; 197 fputs(prefix, stderr); 198 print_pair(t1, t2); 199 fputs(infix, stderr); 200 print_hex_pair(t1, t2); 201 fputs(suffix, stderr); 202 } 203 template <typename T1, typename T2> inline void print_failed_equal(T1 t1, T2 t2) { 204 print_failed_compare(t1, t2, "test_equal(", ") (", ") returns false"); 205 } 206 template <typename T1, typename T2> inline void print_failed_less_equal(T1 t1, T2 t2) { 207 print_failed_compare(t1, t2, "test_less_equal(", ") (", ") returns false"); 208 } 209 template <typename T1, typename T2> inline void print_failed_different(T1 t1, T2 t2) { 210 print_failed_compare(t1, t2, "test_different(", ") (", ") returns false"); 211 } 212 213 template<> inline void print_failed_equal<>(const char *s1, const char *s2) { 214 FlushedOutput yes; 215 fputs("test_equal(", stderr); 216 print(s1); 217 fputs(",\n ", stderr); 218 print(s2); 219 fputs(") returns false", stderr); 220 } 221 template<> inline void print_failed_different<>(const char *s1, const char *) { 222 FlushedOutput yes; 223 fputs("test_different(", stderr); 224 print(s1); 225 fputs(", <same>", stderr); 226 fputs(") returns false", stderr); 227 } 228 229 template <typename T1, typename T2> inline bool test_equal(T1 t1, T2 t2) { 230 bool equal = is_equal(t1, t2); 231 if (!equal) print_failed_equal(t1, t2); 232 return equal; 233 } 234 template <typename T1, typename T2> inline bool test_less_equal(T1 lower, T2 upper) { 235 bool less_equal = is_equal(lower, upper) || is_less(lower, upper); 236 if (!less_equal) print_failed_less_equal(lower, upper); 237 return less_equal; 238 } 239 template <typename T1, typename T2> inline bool test_different(T1 t1, T2 t2) { 240 bool different = !is_equal(t1, t2); 241 if (!different) print_failed_different(t1, t2); 242 return different; 243 } 244 245 #define ACCEPT_NON_CONST_ARGUMENTS(FUN,TYPE) \ 246 template<> inline bool FUN<>(TYPE p1, TYPE p2) { return FUN((const TYPE)p1, (const TYPE)p2); } \ 247 template<> inline bool FUN<>(TYPE p1, const TYPE p2) { return FUN((const TYPE)p1, p2); } \ 248 template<> inline bool FUN<>(const TYPE p1, TYPE p2) { return FUN(p1, (const TYPE)p2); } 249 250 ACCEPT_NON_CONST_ARGUMENTS(test_equal, char*); 251 ACCEPT_NON_CONST_ARGUMENTS(test_different, char*); 252 253 #ifdef ARB_64 254 typedef long int NULLPTR; 255 #else 256 typedef int NULLPTR; 257 #endif 258 259 #define ACCEPT_NULLPTR_ARGUMENTS(FUN,TYPE) \ 260 template<> inline bool FUN<>(TYPE p1, NULLPTR p2) { TEST_ASSERT(!p2); return FUN((const TYPE)p1, (const TYPE)p2); } \ 261 template<> inline bool FUN<>(const TYPE p1, NULLPTR p2) { TEST_ASSERT(!p2); return FUN((const TYPE)p1, (const TYPE)p2); } \ 262 template<> inline bool FUN<>(NULLPTR p1, TYPE p2) { TEST_ASSERT(!p1); return FUN((const TYPE)p1, (const TYPE)p2); } \ 263 template<> inline bool FUN<>(NULLPTR p1, const TYPE p2) { TEST_ASSERT(!p1); return FUN((const TYPE)p1, (const TYPE)p2); } 264 265 ACCEPT_NULLPTR_ARGUMENTS(test_equal, char*); 266 ACCEPT_NULLPTR_ARGUMENTS(test_different, char*); 267 268 inline bool test_similar(double d1, double d2, double epsilon) { 269 double diff = d1-d2; 270 if (diff<0.0) diff = -diff; // do not use fabs() here 271 272 bool in_epsilon_range = diff < epsilon; 273 if (!in_epsilon_range) { 274 StaticCode::printf("test_similar(%f,%f,%f) returns false\n", d1, d2, epsilon); 275 } 276 return in_epsilon_range; 277 } 278 279 inline bool test_equal(double d1, double d2) { return test_similar(d1, d2, 0.000001); } 280 281 inline bool test_strcontains(const char *str, const char *part) { 282 const char *found = strstr(str, part); 283 if (!found) StaticCode::printf("string '%s'\ndoes not contain '%s'\n", str, part); 284 return found; 285 } 286 287 // inline bool is_equal(double d1, double d2) { 288 // return is_similar(d1, d2, 0.000001); 289 // } 275 }; 290 276 291 277 inline bool files_are_equal(const char *file1, const char *file2) { … … 364 350 return !error; 365 351 } 352 353 354 // ------------------ 355 // copy 356 357 358 template <typename T> 359 class copy //! makes char* copyable, so it can be handled like most other types 360 { 361 T t; 362 public: 363 copy(const T& t_) : t(t_) {} 364 operator const T&() const { return t; } 365 }; 366 367 template <> 368 class copy<const char *> { 369 str t; 370 public: 371 copy(const char *t_) : t(str(t_ ? strdup(t_) : NULL)) {} 372 operator const char *() const { return t.value(); } 373 }; 374 375 template <typename T> class copy< copy<T> > { copy(const copy<T>& t_); }; // avoid copies of copies 376 377 template <typename T> inline copy<T> make_copy(const T& t) { return copy<T>(t); } 378 379 inline copy<const char *> make_copy(const char *p) { return copy<const char *>(p); } 380 inline copy<const char *> make_copy(char *p) { return copy<const char *>(p); } 381 inline copy<const char *> make_copy(const unsigned char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } 382 inline copy<const char *> make_copy(unsigned char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } 383 inline copy<const char *> make_copy(const signed char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } 384 inline copy<const char *> make_copy(signed char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } 385 386 inline copy<unsigned char> make_copy(char p) { return copy<unsigned char>(p); } 387 inline copy<unsigned char> make_copy(unsigned char p) { return copy<unsigned char>(p); } 388 inline copy<unsigned char> make_copy(signed char p) { return copy<unsigned char>(p); } 389 390 template <typename T> str readable(const copy<T>& v) { return str(val2readable(v)); } 391 template <typename T> str readableHex(const copy<T>& v) { return str(val2readableHex(v)); } 392 393 template <typename T> bool operator == (const copy<T>& v1, const copy<T>& v2) { return static_cast<const T&>(v1) == static_cast<const T&>(v2); } 394 template <typename T> bool operator != (const copy<T>& v1, const copy<T>& v2) { return !(v1 == v2); } 395 396 template <> inline bool operator == <const char *>(const copy<const char *>& v1, const copy<const char *>& v2) { 397 const char *val1 = v1; 398 const char *val2 = v2; 399 400 return (val1 == val2) || (val1 && val2 && (strcmp(val1, val2) == 0)); 401 } 402 403 404 405 // ------------------------------- 406 // some output functions 407 408 inline void print(const char *s) { fputs(s, stderr); } 409 inline void print(char c) { fputc(c, stderr); } 410 inline void print(int i) { fprintf(stderr, "%i", i); } 411 412 inline void space() { print(' '); } 413 inline void nl() { print('\n'); } 414 415 inline void print_indent(int indent) { while (indent--) space(); } 416 417 inline void spaced(const char *word) { space(); print(word); space(); } 418 inline void select_spaced(bool first, const char *singular, const char *plural) { spaced(first ? singular : plural); } 419 420 421 #define HASTOBE_CLONABLE(type) virtual type *clone() const = 0 422 #define MAKE_CLONABLE(type) type *clone() const { return new type(*this); } 423 424 // ------------------------------ 425 // abstract expectation 426 427 struct expectation //! something expected. can be fulfilled or not (and can explain why/not) 428 { 429 virtual ~expectation() {} 430 HASTOBE_CLONABLE(expectation); 431 432 virtual bool fulfilled() const = 0; 433 virtual void explain(int indent) const = 0; 434 virtual void dump_brief_description() const = 0; 435 }; 436 437 // ------------------- 438 // asserters 439 440 class asserter : virtual Noncopyable { 441 expectation *expected; 442 locinfo loc; 443 const char *code; 444 445 virtual void announce_failure() const { TRIGGER_ASSERTION(false); } 446 447 void err(const char *format) const { loc.errorf(false, format, code); } 448 void warn(const char *format) const { loc.warningf(format, code); } 449 450 public: 451 asserter(const expectation& e, const char *nontmp_code, const char *file, int line) 452 : expected(e.clone()), 453 loc(file, line), 454 code(nontmp_code) 455 {} 456 virtual ~asserter() { delete expected; } 457 458 const char *get_code() const { return code; } 459 460 void expect_that() const { 461 if (!expected->fulfilled()) { 462 err("Failed expectation '%s'"); 463 print("expectation fails because\n"); 464 expected->explain(2); print('\n'); 465 announce_failure(); 466 } 467 } 468 void expect_broken() const { 469 if (expected->fulfilled()) { 470 err("Previously broken expectation '%s' succeeds"); 471 announce_failure(); 472 } 473 else { 474 warn("Expectation '%s' known as broken (accepted until fixed)"); 475 print("Broken because\n"); 476 expected->explain(2); print('\n'); 477 } 478 } 479 void expect_wanted_behavior() const { 480 if (expected->fulfilled()) { 481 err("Wanted behavior '%s' reached"); 482 announce_failure(); 483 } 484 else { 485 warn("Wanted behavior: '%s'"); 486 print("Unsatisfied because\n"); 487 expected->explain(2); print('\n'); 488 } 489 } 490 491 }; 492 493 class debug_asserter : public asserter { 494 virtual void announce_failure() const { 495 print("<<< would trigger assertion now! >>>\n"); 496 } 497 public: 498 debug_asserter(const expectation& e, const char *code_, const char *file, int line) 499 : asserter(e, code_, file, line) 500 {} 501 502 void debug_expectations() { 503 fprintf(stderr, "-------------------- [Debugging expectations for '%s']\n", get_code()); 504 expect_that(); 505 expect_broken(); 506 expect_wanted_behavior(); 507 } 508 }; 509 510 // ---------------------------------------- 511 // matchable + matcher (abstract) 512 513 struct matchable //! can be matched with corresponding matcher. 514 { 515 virtual ~matchable() {} 516 HASTOBE_CLONABLE(matchable); 517 518 virtual const char *name() const = 0; 519 virtual const char *readable_value() const = 0; 520 }; 521 522 struct matcher //! can match things. 523 { 524 virtual ~matcher() {} 525 HASTOBE_CLONABLE(matcher); 526 527 virtual bool matches(const matchable& thing) const = 0; 528 virtual void dump_expectation(const matchable& thing, int indent) const = 0; 529 virtual void dump_brief_description(const matchable& thing) const = 0; 530 }; 531 532 // ---------------------------------------------- 533 // expectation from matchable + matcher 534 535 536 class match_expectation : public expectation //! expectation composed from matcher and corresponding matchable. 537 { 538 matchable *thing; 539 matcher *condition; 540 public: 541 match_expectation(const matchable& thing_, const matcher& condition_) 542 : thing(thing_.clone()), 543 condition(condition_.clone()) 544 {} 545 match_expectation(const match_expectation& other) 546 : thing(other.thing->clone()), 547 condition(other.condition->clone()) 548 {} 549 DECLARE_ASSIGNMENT_OPERATOR(match_expectation); 550 MAKE_CLONABLE(match_expectation); 551 ~match_expectation() { 552 delete thing; 553 delete condition; 554 } 555 556 bool fulfilled() const { return condition->matches(*thing); } 557 void explain(int indent) const { condition->dump_expectation(*thing, indent); } 558 void dump_brief_description() const { condition->dump_brief_description(*thing); } 559 }; 560 561 // ------------------- 562 // predicate 563 564 565 class predicate_description { 566 const char *primary; 567 const char *inverse; 568 mutable str tmp; 569 570 void erase_last_from_tmp() const { 571 char *t = const_cast<char*>(tmp.value()); 572 int len = strlen(t); 573 t[len-1] = 0; 574 } 575 576 static bool ends_with_s(const char *s) { 577 int len = strlen(s); 578 return s[len-1] == 's'; 579 } 580 581 const char *make(const char *desc, bool got) const { 582 if (ends_with_s(desc)) { 583 if (got) return desc; 584 tmp = StaticCode::strf("doesnt %s", desc); 585 erase_last_from_tmp(); 586 } 587 else { 588 tmp = StaticCode::strf("%s %s", got ? "is" : "isnt", desc); 589 } 590 return tmp.value(); 591 } 592 593 public: 594 predicate_description(const char *primary_) : primary(primary_), inverse(NULL) {} 595 predicate_description(const char *primary_, const char *inverse_) : primary(primary_), inverse(inverse_) {} 596 predicate_description(const predicate_description& other) : primary(other.primary), inverse(other.inverse) {} 597 DECLARE_ASSIGNMENT_OPERATOR(predicate_description); 598 599 const char *make(bool expected, bool got) const { 600 if (expected) return make(primary, got); 601 if (inverse) return make(inverse, !got); 602 return make(primary, !got); 603 } 604 }; 605 606 template <typename FUNC> 607 class predicate { 608 FUNC pred; 609 predicate_description description; 610 public: 611 predicate(FUNC pred_, const char *name) : pred(pred_), description(name) {} 612 predicate(FUNC pred_, const char *name, const char *inverse) : pred(pred_), description(name, inverse) {} 613 614 template <typename T> bool matches(const copy<T>& v1, const copy<T>& v2) const { return pred(v1, v2); } 615 const char *describe(bool expected, bool got) const { return description.make(expected, got); } 616 }; 617 618 template <typename FUNC> predicate<FUNC> make_predicate(FUNC func, const char *primary, const char *inverse) { 619 return predicate<FUNC>(func, primary, inverse); 620 } 621 622 // ------------------------------------------ 623 // matchable + matcher (for values) 624 625 template <typename T> inline bool equals(const copy<T>& t1, const copy<T>& t2) { return t1 == t2; } 626 template <typename T> inline bool less(const copy<T>& t1, const copy<T>& t2) { return t1 < t2; } 627 template <typename T> inline bool more(const copy<T>& t1, const copy<T>& t2) { return t1 > t2; } 628 629 template <typename T> 630 class matchable_value : public matchable //! matchable for values 631 { 632 copy<T> val; 633 mutable str readable; 634 const char * code; 635 public: 636 matchable_value(copy<T> val_, const char *nontemp_code) : val(val_), code(nontemp_code) {} 637 matchable_value(const matchable_value<T>& other) : val(other.val), readable(other.readable), code(other.code) {} 638 DECLARE_ASSIGNMENT_OPERATOR(matchable_value); 639 MAKE_CLONABLE(matchable_value<T>); 640 641 const copy<T>& value() const { return val; } 642 char *gen_description() const { return StaticCode::strf("%s (=%s)", code, val.readable()); } 643 644 const char *name() const { return code; } 645 const char *readable_value() const { 646 if (!readable.exists()) readable = arb_test::readable(val); 647 return readable.value(); 648 } 649 650 template <typename U> inline match_expectation equals_expectation(bool invert, const U& other, const char *code) const; 651 template <typename U> inline match_expectation lessThan_expectation(bool invert, const U& other, const char *code) const; 652 template <typename U> inline match_expectation moreThan_expectation(bool invert, const U& other, const char *code) const; 653 654 template <typename FUNC> inline match_expectation predicate_expectation(bool wanted, predicate<FUNC> pred, matchable_value<T> arg) const; 655 template <typename U, typename FUNC> inline match_expectation predicate_expectation(bool wanted, FUNC pred, const char *pred_code, const U& arg, const char *arg_code) const; 656 }; 657 658 template <typename T, typename U> 659 inline const matchable_value<T> make_matchable_value(const U& other, const char *code_) { 660 return matchable_value<T>(T(other), code_); 661 } 662 #if defined(TESTS_KNOW_STRING) 663 template<> 664 inline const matchable_value<const char*> make_matchable_value<const char *, std::string>(const std::string& other, const char *code_) { 665 return matchable_value<const char *>(other.c_str(), code_); 666 } 667 #endif 668 669 template <typename T> template <typename U> 670 inline match_expectation matchable_value<T>::equals_expectation(bool wanted, const U& other, const char *code_) const { 671 return predicate_expectation(wanted, make_predicate(equals<T>, "equals", "differs"), make_matchable_value<T,U>(other, code_)); 672 } 673 template <typename T> template <typename U> 674 inline match_expectation matchable_value<T>::lessThan_expectation(bool wanted, const U& other, const char *code_) const { 675 return predicate_expectation(wanted, make_predicate(less<T>, "less than", "more or equal"), make_matchable_value<T,U>(other, code_)); 676 } 677 template <typename T> template <typename U> 678 inline match_expectation matchable_value<T>::moreThan_expectation(bool wanted, const U& other, const char *code_) const { 679 return predicate_expectation(wanted, make_predicate(more<T>, "more than", "less or equal"), make_matchable_value<T,U>(other, code_)); 680 } 681 682 template <typename T> 683 class value_matcher : public matcher //! matcher for values 684 { 685 matchable_value<T> expected; 686 public: 687 value_matcher(const matchable_value<T>& expected_) : expected(expected_) {} 688 virtual ~value_matcher() {} 689 690 virtual bool matches(const copy<T>& v1, const copy<T>& v2) const = 0; 691 virtual const char *relation(bool isMatch) const = 0; 692 693 const matchable_value<T>& get_expected() const { return expected; } 694 695 bool matches(const matchable& thing) const { 696 const matchable_value<T>& value_thing = dynamic_cast<const matchable_value<T>&>(thing); 697 return matches(value_thing.value(), expected.value()); 698 } 699 700 void dump_expectation(const matchable& thing, int indent) const { 701 bool isMatch = matches(thing); 702 print_indent(indent); 703 fprintf(stderr, "'%s' %s '%s'", thing.name(), relation(isMatch), expected.name()); 704 705 const matchable_value<T>& value_thing = dynamic_cast<const matchable_value<T>&>(thing); 706 if (equals<T>(value_thing.value(), expected.value())) { 707 fprintf(stderr, " (both are %s)", value_thing.readable_value()); 708 } 709 else { 710 int diff = strlen(thing.name())-strlen(expected.name()); 711 712 print(", where\n"); 713 indent += 2;; 714 print_indent(indent); fprintf(stderr, "'%s'%*s is %s, and\n", thing.name(), (diff>0 ? 0 : -diff), "", thing.readable_value()); 715 print_indent(indent); fprintf(stderr, "'%s'%*s is %s", expected.name(), (diff<0 ? 0 : diff), "", expected.readable_value()); 716 } 717 } 718 void dump_brief_description(const matchable& thing) const { 719 print(thing.name()); 720 print('.'); 721 print(relation(true)); 722 print('('); print(expected.name()); print(')'); 723 } 724 725 }; 726 727 // --------------------------- 728 // predicate_matcher 729 730 731 template <typename T, typename FUNC> 732 class predicate_matcher : public value_matcher<T> { 733 predicate<FUNC> pred; 734 bool expected_result; 735 736 public: 737 predicate_matcher(bool wanted, predicate<FUNC> pred_, const matchable_value<T>& arg) 738 : value_matcher<T>(arg), 739 pred(pred_), 740 expected_result(wanted) 741 {} 742 MAKE_CLONABLE(predicate_matcher); 743 744 bool matches(const copy<T>& v1, const copy<T>& v2) const { return correlated(pred.matches(v1, v2), expected_result); } 745 const char *relation(bool isMatch) const { return pred.describe(expected_result, correlated(isMatch, expected_result)); } 746 }; 747 748 template <typename T> template <typename FUNC> 749 inline match_expectation matchable_value<T>::predicate_expectation(bool wanted, predicate<FUNC> pred, matchable_value<T> arg) const { 750 return match_expectation(*this, predicate_matcher<T,FUNC>(wanted, pred, arg)); 751 } 752 template <typename T> template <typename U, typename FUNC> 753 inline match_expectation matchable_value<T>::predicate_expectation(bool wanted, FUNC pred, const char *pred_code, const U& arg, const char *arg_code) const { 754 return match_expectation(*this, predicate_matcher<T,FUNC>(wanted, predicate<FUNC>(pred, pred_code), make_matchable_value<T,U>(arg, arg_code))); 755 } 756 757 // ------------------------------------------------ 758 // matchable + matcher (for expectations) 759 760 const int MAX_GROUP_SIZE = 3; 761 class expectation_group : public matchable //! group of expectation. matchable with group_matcher 762 { 763 int count; 764 expectation *depend_on[MAX_GROUP_SIZE]; 765 766 expectation_group& operator = (const expectation_group&); // forbidden 767 protected: 768 769 public: 770 expectation_group(const expectation& e) : count(1) { 771 depend_on[0] = e.clone(); 772 } 773 expectation_group(const expectation& e1, const expectation& e2) : count(2) { 774 depend_on[0] = e1.clone(); 775 depend_on[1] = e2.clone(); 776 } 777 expectation_group(const expectation_group& other) : count(other.count) { 778 for (int i = 0; i<count; ++i) { 779 depend_on[i] = other.depend_on[i]->clone(); 780 } 781 } 782 virtual ~expectation_group() { 783 for (int i = 0; i<count; ++i) { 784 delete depend_on[i]; 785 } 786 } 787 MAKE_CLONABLE(expectation_group); 788 789 expectation_group& add(const expectation& e) { depend_on[count++] = e.clone(); return *this; } 790 791 const char *name() const { 792 return "<expectation_group>"; 793 } 794 const char *readable_value() const { 795 return "<value of expectation_group>"; 796 } 797 798 const expectation& dependent(int i) const { arb_assert(i<count); return *depend_on[i]; } 799 int size() const { return count; } 800 int count_fulfilled() const { 801 int ff = 0; 802 for (int i = 0; i<count; ++i) { 803 ff += dependent(i).fulfilled(); 804 } 805 return ff; 806 } 807 void dump_some_expectations(int indent, bool fulfilled, bool unfulfilled) const { 808 if (fulfilled||unfulfilled) { 809 bool all = fulfilled && unfulfilled; 810 bool wanted = fulfilled; 811 812 bool printed = false; 813 for (int i = 0; i<size(); ++i) { 814 const expectation& e = dependent(i); 815 816 bool is_fulfilled = e.fulfilled(); 817 if (all || is_fulfilled == wanted) { 818 if (printed) print('\n'); 819 e.explain(indent); 820 printed = true; 821 } 822 } 823 } 824 } 825 void dump_brief_description() const { 826 print("of("); 827 bool printed = false; 828 for (int i = 0; i<size(); ++i) { 829 if (printed) print(", "); 830 const expectation& e = dependent(i); 831 e.dump_brief_description(); 832 printed = true; 833 } 834 print(')'); 835 } 836 }; 837 838 struct group_match //! result of matching an expectation_group with a group_matcher 839 { 840 const int count; 841 const int fulfilled; 842 const int min_req; 843 const int max_req; 844 const int diff; 845 846 int required(int what) const { return what == -1 ? count : what; } 847 group_match(const expectation_group& group, int min, int max) 848 : count(group.size()), 849 fulfilled(group.count_fulfilled()), 850 min_req(required(min)), 851 max_req(required(max)), 852 diff(fulfilled<min_req 853 ? fulfilled-min_req 854 : (fulfilled>max_req ? fulfilled-max_req : 0)) 855 {} 856 857 858 inline static void is(int a) { select_spaced(a == 1, "is", "are"); } 859 inline static void was(int a) { select_spaced(a < 2, "was", "were"); } 860 inline static void amountzero(int a, const char *zero) { a ? print(a) : print(zero); } 861 862 void dump_num_of(int amount, const char *thing) const { 863 amountzero(amount, "no"); 864 space(); 865 print(thing); 866 if (amount != 1) print('s'); 867 } 868 869 void dump(const expectation_group& group, int indent) const { 870 print_indent(indent); 871 if (count == 1) { 872 print("expectation "); 873 print("'"); 874 group.dependent(0).dump_brief_description(); 875 print("' "); 876 print(fulfilled ? "fulfilled" : "fails"); 877 print(diff ? " unexpectedly" : " as expected"); 878 } 879 else { 880 print("expected "); 881 int that_many; 882 if (min_req == max_req) { 883 if (diff>0 && min_req>0) print("only "); 884 that_many = min_req; 885 } 886 else { 887 if (diff) { 888 print("at"); select_spaced(diff<0, "least", "most"); 889 that_many = diff<0 ? min_req : max_req; 890 } 891 else { 892 fprintf(stderr, "%i-", min_req); 893 that_many = max_req; 894 } 895 } 896 dump_num_of(that_many, "fulfilled expectation"); 897 space(); 898 group.dump_brief_description(); 899 nl(); 900 901 indent += 2; 902 print_indent(indent); 903 if (diff == 0) print("and "); else print("but "); 904 905 if (diff<0 && fulfilled>0) print("only "); 906 amountzero(fulfilled, "none"); is(fulfilled); print("fulfilled"); 907 } 908 909 print(", because\n"); 910 bool show_fulfilled = diff >= 0; 911 bool show_unfulfilled = diff <= 0; 912 group.dump_some_expectations(indent+2, show_fulfilled, show_unfulfilled); 913 } 914 }; 915 916 class group_matcher : public matcher //! matches expectation_group for degree of fulfilledness 917 { 918 int min, max; 919 group_matcher(int min_, int max_) : min(min_), max(max_) {} 920 public: 921 MAKE_CLONABLE(group_matcher); 922 923 bool matches(const matchable& thing) const { 924 return group_match(dynamic_cast<const expectation_group&>(thing), min, max).diff == 0; 925 } 926 927 void dump_expectation(const matchable& thing, int indent) const { 928 const expectation_group& group = dynamic_cast<const expectation_group&>(thing); 929 group_match matching(group, min, max); 930 matching.dump(group, indent); 931 } 932 933 // factories 934 static group_matcher all() { return group_matcher(-1, -1); } 935 static group_matcher none() { return group_matcher(0, 0); } 936 static group_matcher atleast(int min_) { return group_matcher(min_, -1); } 937 static group_matcher atmost(int max_) { return group_matcher(0, max_); } 938 static group_matcher exacly(int amount) { return group_matcher(amount, amount); } 939 940 // match_expectation factories 941 match_expectation of(const expectation& e) const { 942 return match_expectation(expectation_group(e), *this); 943 } 944 match_expectation of(const expectation& e1, const expectation& e2) const { 945 return match_expectation(expectation_group(e1, e2), *this); 946 } 947 match_expectation of(const expectation& e1, const expectation& e2, const expectation& e3) const { 948 return match_expectation(expectation_group(e1, e2).add(e3), *this); 949 } 950 951 void dump_brief_description(const matchable& thing) const { 952 if (max == -1) { 953 if (min == -1) { 954 print("all"); 955 } 956 else { 957 fprintf(stderr, "atleast(%i)", min); 958 } 959 } 960 else if (max == 0) { 961 print("none"); 962 } 963 else if (min == max) { 964 fprintf(stderr, "exactly(%i)", min); 965 } 966 else { 967 fprintf(stderr, "[%i-%i]", min, max); 968 } 969 970 print('.'); 971 972 const expectation_group& group = dynamic_cast<const expectation_group&>(thing); 973 group.dump_brief_description(); 974 } 975 }; 976 977 // -------------------------- 978 // helper functions 979 980 981 template <typename T> const matchable_value<T> CREATE_matchable(const copy<T>& val, const char *code) { return matchable_value<T>(val, code); } 982 983 inline group_matcher all() { return group_matcher::all(); } 984 inline group_matcher none() { return group_matcher::none(); } 985 inline group_matcher atleast(int min) { return group_matcher::atleast(min); } 986 inline group_matcher atmost(int max) { return group_matcher::atmost(max); } 987 inline group_matcher exacly(int amount) { return group_matcher::exacly(amount); } 988 989 inline match_expectation wrong(const expectation& e) { return none().of(e); } 366 990 }; 367 991 368 992 // -------------------------------------------------------------------------------- 369 993 370 #define TEST_WARNING(format,strarg) arb_test::StaticCode::warningf(__FILE__, __LINE__, format, (strarg)) 371 #define TEST_WARNING2(format,strarg1,strarg2) arb_test::StaticCode::warningf(__FILE__, __LINE__, format, (strarg1), (strarg2)) 372 373 #define TEST_ERROR(format,strarg) arb_test::StaticCode::errorf(__FILE__, __LINE__, format, (strarg)) 374 #define TEST_ERROR2(format,strarg1,strarg2) arb_test::StaticCode::errorf(__FILE__, __LINE__, format, (strarg1), (strarg2)) 375 #define TEST_IOERROR(format,strarg) arb_test::StaticCode::ioerrorf(__FILE__, __LINE__, format, (strarg)) 994 #define MATCHABLE_ARGS_UNTYPED(val) val, #val 995 #define MATCHABLE_ARGS_TYPED(val) make_copy(val), #val 996 997 #define equals(val) equals_expectation(true, MATCHABLE_ARGS_UNTYPED(val)) 998 #define differs(val) equals_expectation(false, MATCHABLE_ARGS_UNTYPED(val)) 999 1000 #define less_than(val) lessThan_expectation(true, MATCHABLE_ARGS_UNTYPED(val)) 1001 #define more_than(val) moreThan_expectation(true, MATCHABLE_ARGS_UNTYPED(val)) 1002 1003 #define less_or_equal(val) moreThan_expectation(false, MATCHABLE_ARGS_UNTYPED(val)) 1004 #define more_or_equal(val) lessThan_expectation(false, MATCHABLE_ARGS_UNTYPED(val)) 1005 1006 #define is(pred,arg) predicate_expectation(true, MATCHABLE_ARGS_UNTYPED(pred), MATCHABLE_ARGS_UNTYPED(arg)) 1007 #define is_not(pred,arg) predicate_expectation(false, MATCHABLE_ARGS_UNTYPED(pred), MATCHABLE_ARGS_UNTYPED(arg)) 1008 1009 #define that(thing) CREATE_matchable(MATCHABLE_ARGS_TYPED(thing)) 1010 1011 #define TEST_EXPECT(EXPCTN) do { using namespace arb_test; asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).expect_that(); } while(0) 1012 #define TEST_EXPECT__BROKEN(EXPCTN) do { using namespace arb_test; asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).expect_broken(); } while(0) 1013 #define TEST_EXPECT__WANTED(EXPCTN) do { using namespace arb_test; asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).expect_wanted_behavior(); } while(0) 1014 1015 #define DEBUG_TEST_EXPECT(EXPCTN) do { \ 1016 using namespace arb_test; \ 1017 debug_asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__). \ 1018 debug_expectations(); \ 1019 debug_asserter(wrong(EXPCTN), "wrong(" #EXPCTN ")", __FILE__, __LINE__). \ 1020 debug_expectations(); \ 1021 } while(0) 1022 1023 // -------------------------------------------------------------------------------- 1024 1025 #define HERE arb_test::locinfo(__FILE__, __LINE__) 1026 1027 #define TEST_WARNING(format,strarg) HERE.warningf(format, (strarg)) 1028 #define TEST_WARNING2(format,strarg1,strarg2) HERE.warningf(format, (strarg1), (strarg2)) 1029 #define TEST_ERROR(format,strarg) HERE.errorf(true, format, (strarg)) 1030 #define TEST_ERROR2(format,strarg1,strarg2) HERE.errorf(true, format, (strarg1), (strarg2)) 1031 #define TEST_IOERROR(format,strarg) HERE.ioerrorf(true, format, (strarg)) 376 1032 377 1033 // -------------------------------------------------------------------------------- … … 394 1050 } while (0) 395 1051 396 397 #define TEST_ASSERT_ZERO(cond) TEST_ASSERT((cond) == 0) 398 #define TEST_ASSERT_ZERO__BROKEN(cond) TEST_ASSERT__BROKEN((cond) == 0) 1052 #define TEST_ASSERT_ZERO(cond) TEST_EXPECT(that(cond).equals(0)) 1053 #define TEST_ASSERT_ZERO__BROKEN(cond) TEST_EXPECT__BROKEN(that(cond).equals(0)) 399 1054 400 1055 #define TEST_ASSERT_ZERO_OR_SHOW_ERRNO(iocond) \ … … 546 1201 // -------------------------------------------------------------------------------- 547 1202 548 #define TEST_ASSERT_NULL(n) TEST_ASSERT(arb_test::test_equal(n, (typeof(n))NULL)) 549 #define TEST_ASSERT_NULL__BROKEN(n) TEST_ASSERT__BROKEN(arb_test::test_equal(n, (typeof(n))NULL)) 550 551 #define TEST_ASSERT_EQUAL(e1,t2) TEST_ASSERT(arb_test::test_equal(e1, t2)) 552 #define TEST_ASSERT_EQUAL__BROKEN(e1,t2) TEST_ASSERT__BROKEN(arb_test::test_equal(e1, t2)) 553 554 #define TEST_ASSERT_SIMILAR(e1,t2,epsilon) TEST_ASSERT(arb_test::test_similar(e1, t2, epsilon)) 555 #define TEST_ASSERT_SIMILAR__BROKEN(e1,t2,epsilon) TEST_ASSERT__BROKEN(arb_test::test_similar(e1, t2, epsilon)) 556 557 #define TEST_ASSERT_DIFFERENT(e1,t2) TEST_ASSERT(arb_test::test_different(e1, t2)) 558 #define TEST_ASSERT_DIFFERENT__BROKEN(e1,t2) TEST_ASSERT__BROKEN(arb_test::test_different(e1, t2)) 559 560 #define TEST_ASSERT_LOWER_EQUAL(lower,upper) TEST_ASSERT(arb_test::test_less_equal(lower, upper)) 561 #define TEST_ASSERT_LOWER(lower,upper) do { TEST_ASSERT_LOWER_EQUAL(lower, upper); TEST_ASSERT_DIFFERENT(lower, upper); } while(0) 562 #define TEST_ASSERT_IN_RANGE(val,lower,upper) do { TEST_ASSERT_LOWER_EQUAL(lower, val); TEST_ASSERT_LOWER_EQUAL(val, upper); } while(0) 563 564 565 #define TEST_ASSERT_CONTAINS(str, part) TEST_ASSERT(arb_test::test_strcontains(str, part)) 1203 #define TEST_ASSERT_EQUAL(e1,t2) TEST_EXPECT(that(e1).equals(t2)) 1204 #define TEST_ASSERT_EQUAL__BROKEN(e1,t2) TEST_EXPECT__BROKEN(that(e1).equals(t2)) 1205 1206 #define TEST_ASSERT_NULL(n) TEST_ASSERT_EQUAL(n, NULL) 1207 #define TEST_ASSERT_NULL__BROKEN(n) TEST_ASSERT_EQUAL__BROKEN(n, NULL) 1208 1209 #define TEST_ASSERT_SIMILAR(e1,t2,epsilon) TEST_EXPECT(that(e1).is(epsilon_similar(epsilon), t2)) 1210 #define TEST_ASSERT_SIMILAR__BROKEN(e1,t2,epsilon) TEST_EXPECT__BROKEN(that(e1).is(epsilon_similar(epsilon), t2)) 1211 1212 #define TEST_ASSERT_DIFFERENT(e1,t2) TEST_EXPECT(that(e1).differs(t2)); 1213 #define TEST_ASSERT_DIFFERENT__BROKEN(e1,t2) TEST_EXPECT__BROKEN(that(e1).differs(t2)); 1214 1215 #define TEST_ASSERT_LOWER_EQUAL(lower,upper) TEST_EXPECT(that(lower).less_or_equal(upper)) 1216 #define TEST_ASSERT_LOWER(lower,upper) TEST_EXPECT(that(lower).less_than(upper)) 1217 #define TEST_ASSERT_IN_RANGE(val,lower,upper) TEST_EXPECT(all().of(that(val).more_or_equal(lower), that(val).less_or_equal(upper))) 1218 1219 #define TEST_ASSERT_CONTAINS(str, part) TEST_EXPECT(that(str).is(containing(), part)) 566 1220 567 1221 // --------------------------------------------------------------------------------
