| 1 | // ================================================================ // |
|---|
| 2 | // // |
|---|
| 3 | // File : arb_string.cxx // |
|---|
| 4 | // Purpose : // |
|---|
| 5 | // // |
|---|
| 6 | // Coded by Ralf Westram (coder@reallysoft.de) in November 2010 // |
|---|
| 7 | // Institute of Microbiology (Technical University Munich) // |
|---|
| 8 | // http://www.arb-home.de/ // |
|---|
| 9 | // // |
|---|
| 10 | // ================================================================ // |
|---|
| 11 | |
|---|
| 12 | #include "arb_string.h" |
|---|
| 13 | |
|---|
| 14 | #include <ctime> |
|---|
| 15 | #include <sys/time.h> |
|---|
| 16 | #include <Keeper.h> |
|---|
| 17 | |
|---|
| 18 | inline tm *get_current_time() { |
|---|
| 19 | timeval date; |
|---|
| 20 | tm *p; |
|---|
| 21 | |
|---|
| 22 | gettimeofday(&date, NULp); |
|---|
| 23 | |
|---|
| 24 | #if defined(DARWIN) |
|---|
| 25 | struct timespec local; |
|---|
| 26 | TIMEVAL_TO_TIMESPEC(&date, &local); // not avail in time.h of Linux gcc 2.95.3 |
|---|
| 27 | p = localtime(&local.tv_sec); |
|---|
| 28 | #else |
|---|
| 29 | p = localtime(&date.tv_sec); |
|---|
| 30 | #endif // DARWIN |
|---|
| 31 | |
|---|
| 32 | return p; |
|---|
| 33 | } |
|---|
| 34 | |
|---|
| 35 | const char *ARB_date_string() { |
|---|
| 36 | const char *date_string = NULp; |
|---|
| 37 | #if defined(UNIT_TESTS) |
|---|
| 38 | if (RUNNING_TEST()) { |
|---|
| 39 | date_string = "Thu Nov 29 22:33:09 1973"; // timestamp used in unittests (=@123456789 CET) |
|---|
| 40 | } |
|---|
| 41 | else |
|---|
| 42 | #endif |
|---|
| 43 | { |
|---|
| 44 | tm *p = get_current_time(); |
|---|
| 45 | char *readable = asctime(p); // points to a static buffer |
|---|
| 46 | char *cr = strchr(readable, '\n'); |
|---|
| 47 | arb_assert(cr); |
|---|
| 48 | cr[0] = 0; // cut of \n |
|---|
| 49 | date_string = readable; |
|---|
| 50 | } |
|---|
| 51 | return date_string; |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | const char *ARB_dateTime_suffix() { |
|---|
| 55 | /*! returns "YYYYMMDD_HHMMSS" */ |
|---|
| 56 | const unsigned SUFFIXLEN = 8+1+6; |
|---|
| 57 | static char buffer[SUFFIXLEN+1]; |
|---|
| 58 | tm *p = get_current_time(); |
|---|
| 59 | |
|---|
| 60 | #if defined(ASSERTION_USED) |
|---|
| 61 | size_t printed = |
|---|
| 62 | #endif |
|---|
| 63 | strftime(buffer, SUFFIXLEN+1, "%Y%m%d_%H%M%S", p); |
|---|
| 64 | arb_assert(printed == SUFFIXLEN); |
|---|
| 65 | buffer[SUFFIXLEN] = 0; |
|---|
| 66 | |
|---|
| 67 | return buffer; |
|---|
| 68 | } |
|---|
| 69 | |
|---|
| 70 | // -------------------------------------------------------------------------------- |
|---|
| 71 | |
|---|
| 72 | const char *ARB_keep_string(char *str) { |
|---|
| 73 | /*! keep an allocated string until program termination |
|---|
| 74 | * useful to avoid valgrind reporting leaks e.g for callback parameters |
|---|
| 75 | */ |
|---|
| 76 | static Keeper<char*> stringKeeper; |
|---|
| 77 | stringKeeper.keep(str); |
|---|
| 78 | return str; |
|---|
| 79 | } |
|---|
| 80 | |
|---|
| 81 | |
|---|
| 82 | // -------------------------------------------------------------------------------- |
|---|
| 83 | |
|---|
| 84 | |
|---|
| 85 | #ifdef UNIT_TESTS |
|---|
| 86 | |
|---|
| 87 | #include <string> |
|---|
| 88 | #include <climits> |
|---|
| 89 | |
|---|
| 90 | #ifndef TEST_UNIT_H |
|---|
| 91 | #include <test_unit.h> |
|---|
| 92 | #endif |
|---|
| 93 | |
|---|
| 94 | using namespace std; |
|---|
| 95 | |
|---|
| 96 | // ---------------------------------------------- |
|---|
| 97 | // some tests for unit-test-code itself |
|---|
| 98 | |
|---|
| 99 | #define TEST_EXPECT_HEAPCOPY_EQUAL(copy,expected) do { \ |
|---|
| 100 | char *theCopy = (copy); \ |
|---|
| 101 | TEST_EXPECT_EQUAL(theCopy, expected); \ |
|---|
| 102 | free(theCopy); \ |
|---|
| 103 | } while(0) |
|---|
| 104 | |
|---|
| 105 | void TEST_arbtest_strf() { |
|---|
| 106 | // tests string formatter from test_unit.h |
|---|
| 107 | using namespace arb_test; |
|---|
| 108 | TEST_EXPECT_HEAPCOPY_EQUAL(StaticCode::strf("<%i>", 7), "<7>"); |
|---|
| 109 | TEST_EXPECT_HEAPCOPY_EQUAL(StaticCode::strf("<%0*i>", 3, 7), "<007>"); |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | void TEST_arbtest_readable() { |
|---|
| 113 | using namespace arb_test; |
|---|
| 114 | |
|---|
| 115 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy('x')), "'x' (=0x78)"); |
|---|
| 116 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy(static_cast<unsigned char>('x'))), "'x' (=0x78)"); |
|---|
| 117 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy(static_cast<signed char>('x'))), "'x' (=0x78)"); |
|---|
| 118 | |
|---|
| 119 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy(true)), "true"); |
|---|
| 120 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy(false)), "false"); |
|---|
| 121 | |
|---|
| 122 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy(1)), "1"); |
|---|
| 123 | TEST_EXPECT_HEAPCOPY_EQUAL(val2hex(make_copy(2)), "0x2"); |
|---|
| 124 | |
|---|
| 125 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy(3L)), "3"); |
|---|
| 126 | TEST_EXPECT_HEAPCOPY_EQUAL(val2hex(make_copy(4L)), "0x4"); |
|---|
| 127 | |
|---|
| 128 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy(5U)), "5"); |
|---|
| 129 | TEST_EXPECT_HEAPCOPY_EQUAL(val2hex(make_copy(6U)), "0x6"); |
|---|
| 130 | |
|---|
| 131 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy("some\ntext\twhich\"special\\chars")), "\"some\\ntext\\twhich\\\"special\\\\chars\""); |
|---|
| 132 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy("a\x01\x02\x07\x08\x09\x0b\x0c\x0d\x1a\x22\x27\x5c\x7e\x7f\x80\xfe\xff")), |
|---|
| 133 | /* */ "\"a\\1\\2\\a\\b\\t\\v\\f\\r\\x1a\\\"'\\\\~\\x7f\\x80\\xfe\\xff\""); |
|---|
| 134 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy((const char *)NULp)), "(null)"); |
|---|
| 135 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy((const unsigned char *)NULp)), "(null)"); |
|---|
| 136 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy((const signed char *)NULp)), "(null)"); |
|---|
| 137 | |
|---|
| 138 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy(1.7)), "1.700000"); |
|---|
| 139 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy(177.0e20)), "17699999999999998951424.000000"); |
|---|
| 140 | TEST_EXPECT_HEAPCOPY_EQUAL(val2readable(make_copy(177.0e20F)), "17699999967695435988992.000000"); |
|---|
| 141 | } |
|---|
| 142 | |
|---|
| 143 | void TEST_arbtest_copyable() { |
|---|
| 144 | using namespace arb_test; |
|---|
| 145 | |
|---|
| 146 | int i = 7; |
|---|
| 147 | const char *s = "servas"; |
|---|
| 148 | |
|---|
| 149 | TEST_EXPECT(make_copy(i) == make_copy(7)); |
|---|
| 150 | TEST_EXPECT_ZERO(strcmp(make_copy(s), make_copy("servas"))); |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | #define TEST_DESCRIPTIONS(d, tt, tf, ft, ff) do { \ |
|---|
| 154 | TEST_EXPECT_EQUAL((d).make(true, true), (tt)); \ |
|---|
| 155 | TEST_EXPECT_EQUAL((d).make(true, false), (tf)); \ |
|---|
| 156 | TEST_EXPECT_EQUAL((d).make(false, true), (ft)); \ |
|---|
| 157 | TEST_EXPECT_EQUAL((d).make(false, false), (ff)); \ |
|---|
| 158 | } while(0) |
|---|
| 159 | |
|---|
| 160 | #define TEST_SIMPLE_DESCRIPTIONS(d, ae, nae) TEST_DESCRIPTIONS(d, ae, nae, ae, nae) |
|---|
| 161 | |
|---|
| 162 | void TEST_arbtest_predicate_description() { |
|---|
| 163 | TEST_SIMPLE_DESCRIPTIONS(predicate_description("similar"), "is similar", "isnt similar"); |
|---|
| 164 | TEST_SIMPLE_DESCRIPTIONS(predicate_description("repairs"), "repairs", "doesnt repair"); |
|---|
| 165 | |
|---|
| 166 | TEST_DESCRIPTIONS(predicate_description("equals", "differs"), |
|---|
| 167 | "equals", "doesnt equal", |
|---|
| 168 | "doesnt differ", "differs"); |
|---|
| 169 | |
|---|
| 170 | TEST_DESCRIPTIONS(predicate_description("less_than", "more_than"), |
|---|
| 171 | "is less_than", "isnt less_than", |
|---|
| 172 | "isnt more_than", "is more_than"); |
|---|
| 173 | } |
|---|
| 174 | |
|---|
| 175 | void TEST_arbtest_expectations() { |
|---|
| 176 | // used to TDD expectations |
|---|
| 177 | using namespace arb_test; |
|---|
| 178 | |
|---|
| 179 | string apple = "Apfel"; |
|---|
| 180 | string pear = "Birne"; |
|---|
| 181 | string boskop = apple; |
|---|
| 182 | string pomegranate = "Granatapfel"; |
|---|
| 183 | |
|---|
| 184 | TEST_EXPECTATION(that(apple).is_equal_to("Apfel")); |
|---|
| 185 | |
|---|
| 186 | TEST_EXPECTATION(that(apple).does_differ_from(pear)); |
|---|
| 187 | TEST_EXPECTATION(that(apple).is_equal_to(boskop)); |
|---|
| 188 | TEST_EXPECTATION(wrong(that(pomegranate).is_equal_to(apple))); |
|---|
| 189 | |
|---|
| 190 | match_expectation ff1 = that(1.0).is_equal_to(2-1); |
|---|
| 191 | match_expectation ff2 = that(boskop).is_equal_to(apple); |
|---|
| 192 | match_expectation ff3 = that(apple).is_equal_to(apple); |
|---|
| 193 | |
|---|
| 194 | match_expectation nf1 = that(apple).is_equal_to(pear); |
|---|
| 195 | match_expectation nf2 = that(pomegranate).is_equal_to(apple); |
|---|
| 196 | match_expectation nf3 = that(apple).does_differ_from(boskop); |
|---|
| 197 | |
|---|
| 198 | match_expectation a1 = all().of(ff1); |
|---|
| 199 | match_expectation a2 = all().of(ff1, ff2); |
|---|
| 200 | match_expectation a3 = all().of(ff1, ff2, ff3); |
|---|
| 201 | |
|---|
| 202 | TEST_EXPECTATION(a1); |
|---|
| 203 | TEST_EXPECTATION(a2); |
|---|
| 204 | TEST_EXPECTATION(a3); |
|---|
| 205 | |
|---|
| 206 | match_expectation n1 = none().of(ff1); |
|---|
| 207 | match_expectation n2 = none().of(ff1, ff2); |
|---|
| 208 | match_expectation n3 = none().of(ff1, ff2, ff3); |
|---|
| 209 | |
|---|
| 210 | TEST_EXPECTATION(wrong(none().of(that(boskop).is_equal_to(apple)))); |
|---|
| 211 | TEST_EXPECTATION(wrong(n1)); |
|---|
| 212 | TEST_EXPECTATION(wrong(n2)); |
|---|
| 213 | TEST_EXPECTATION(wrong(n3)); |
|---|
| 214 | |
|---|
| 215 | TEST_EXPECTATION(atleast(1).of(a1)); |
|---|
| 216 | TEST_EXPECTATION(atleast(1).of(a1, n1)); |
|---|
| 217 | TEST_EXPECTATION(atleast(1).of(n2, a1, n1)); |
|---|
| 218 | |
|---|
| 219 | TEST_EXPECTATION(wrong(atleast(2).of(a1, n1, n2))); |
|---|
| 220 | TEST_EXPECTATION(wrong(atleast(2).of(a1, n1))); |
|---|
| 221 | TEST_EXPECTATION(wrong(atleast(2).of(a1))); // impossible |
|---|
| 222 | |
|---|
| 223 | TEST_EXPECTATION(atmost(2).of(a1)); |
|---|
| 224 | TEST_EXPECTATION(atmost(2).of(a1, a2)); |
|---|
| 225 | TEST_EXPECTATION(atmost(2).of(a1, a2, n1)); |
|---|
| 226 | TEST_EXPECTATION(atmost(2).of(a1, n1, n2)); |
|---|
| 227 | TEST_EXPECTATION(atmost(2).of(n1, n2)); |
|---|
| 228 | TEST_EXPECTATION(wrong(atmost(2).of(a1, a2, a3))); |
|---|
| 229 | |
|---|
| 230 | TEST_EXPECTATION(exactly(1).of(ff1, nf1, nf2)); |
|---|
| 231 | TEST_EXPECTATION(wrong(exactly(1).of(nf1, nf2))); |
|---|
| 232 | TEST_EXPECTATION(wrong(exactly(1).of(nf1, nf2, nf3))); |
|---|
| 233 | TEST_EXPECTATION(wrong(exactly(1).of(ff1, ff2, nf2))); |
|---|
| 234 | TEST_EXPECTATION(wrong(exactly(1).of(ff1, ff2, ff3))); |
|---|
| 235 | |
|---|
| 236 | } |
|---|
| 237 | |
|---|
| 238 | void TEST_expectation_groups() { |
|---|
| 239 | using namespace arb_test; |
|---|
| 240 | |
|---|
| 241 | expectation_group no_expectations; |
|---|
| 242 | TEST_EXPECTATION(all().ofgroup(no_expectations)); |
|---|
| 243 | TEST_EXPECTATION(none().ofgroup(no_expectations)); |
|---|
| 244 | |
|---|
| 245 | expectation_group fulfilled_expectation (that(1).is_equal_to(1)); |
|---|
| 246 | expectation_group unfulfilled_expectation(that(1).is_equal_to(0)); |
|---|
| 247 | expectation_group some_fulfilled_expectations(that(1).is_equal_to(0), that(1).is_equal_to(1)); |
|---|
| 248 | |
|---|
| 249 | TEST_EXPECTATION(all().ofgroup(fulfilled_expectation)); |
|---|
| 250 | TEST_EXPECTATION(none().ofgroup(unfulfilled_expectation)); |
|---|
| 251 | |
|---|
| 252 | TEST_EXPECT(none().ofgroup(fulfilled_expectation).unfulfilled()); |
|---|
| 253 | TEST_EXPECT(all().ofgroup(unfulfilled_expectation).unfulfilled()); |
|---|
| 254 | |
|---|
| 255 | TEST_EXPECT(all().ofgroup(some_fulfilled_expectations).unfulfilled()); |
|---|
| 256 | TEST_EXPECT(none().ofgroup(some_fulfilled_expectations).unfulfilled()); |
|---|
| 257 | } |
|---|
| 258 | |
|---|
| 259 | void TEST_replace_old_TEST_EXPECTS_by_expectations() { |
|---|
| 260 | // test various string-types are matchable (w/o casts) |
|---|
| 261 | { |
|---|
| 262 | const char *car_ccp = "Alfa"; |
|---|
| 263 | char *car_cp = ARB_strdup("Alfa"); |
|---|
| 264 | string car_str("Alfa"); |
|---|
| 265 | |
|---|
| 266 | TEST_EXPECT_EQUAL(car_ccp, "Alfa"); |
|---|
| 267 | TEST_EXPECT_EQUAL(car_cp, "Alfa"); |
|---|
| 268 | TEST_EXPECT_EQUAL(car_str, "Alfa"); |
|---|
| 269 | |
|---|
| 270 | TEST_EXPECT_EQUAL("Alfa", car_ccp); |
|---|
| 271 | TEST_EXPECT_EQUAL("Alfa", car_cp); |
|---|
| 272 | TEST_EXPECT_EQUAL("Alfa", car_str); |
|---|
| 273 | |
|---|
| 274 | TEST_EXPECT_EQUAL(car_cp, car_ccp); |
|---|
| 275 | TEST_EXPECT_EQUAL(car_cp, car_str); |
|---|
| 276 | TEST_EXPECT_EQUAL(car_ccp, car_cp); |
|---|
| 277 | TEST_EXPECT_EQUAL(car_ccp, car_str); |
|---|
| 278 | TEST_EXPECT_EQUAL(car_str, car_cp); |
|---|
| 279 | TEST_EXPECT_EQUAL(car_str, car_ccp); |
|---|
| 280 | |
|---|
| 281 | char *null = NULp; |
|---|
| 282 | TEST_EXPECT_NULL((void*)NULp); |
|---|
| 283 | TEST_EXPECT_NULL(null); |
|---|
| 284 | |
|---|
| 285 | TEST_EXPECT_CONTAINS(car_ccp, "lf"); |
|---|
| 286 | TEST_EXPECT_CONTAINS(car_cp, "fa"); |
|---|
| 287 | TEST_EXPECT_CONTAINS(car_str, "Al"); |
|---|
| 288 | |
|---|
| 289 | free(car_cp); |
|---|
| 290 | } |
|---|
| 291 | |
|---|
| 292 | // test various numeric types are matchable |
|---|
| 293 | |
|---|
| 294 | { |
|---|
| 295 | short unsigned su = 7; |
|---|
| 296 | short s = -su; |
|---|
| 297 | |
|---|
| 298 | unsigned iu = su; |
|---|
| 299 | int i = -iu; |
|---|
| 300 | |
|---|
| 301 | long unsigned lu = (long unsigned)INT_MAX+3; |
|---|
| 302 | long l = -lu; |
|---|
| 303 | |
|---|
| 304 | float f = s; |
|---|
| 305 | double d = i; |
|---|
| 306 | |
|---|
| 307 | TEST_EXPECT_EQUAL(s, -7); |
|---|
| 308 | TEST_EXPECT_EQUAL(i, -7); |
|---|
| 309 | |
|---|
| 310 | TEST_EXPECT_EQUAL(su, 7); TEST_EXPECT_EQUAL(iu, 7); |
|---|
| 311 | TEST_EXPECT_EQUAL(su, 7U); TEST_EXPECT_EQUAL(iu, 7U); |
|---|
| 312 | TEST_EXPECT_EQUAL(su, 7L); TEST_EXPECT_EQUAL(iu, 7L); |
|---|
| 313 | |
|---|
| 314 | TEST_EXPECT_EQUAL(s, -su); TEST_EXPECT_EQUAL(s, -iu); |
|---|
| 315 | TEST_EXPECT_EQUAL(i, -iu); TEST_EXPECT_EQUAL(i, -su); |
|---|
| 316 | TEST_EXPECT_EQUAL(l, -lu); |
|---|
| 317 | |
|---|
| 318 | TEST_EXPECT_EQUAL(f, d); |
|---|
| 319 | TEST_EXPECT_EQUAL(d, f); |
|---|
| 320 | } |
|---|
| 321 | |
|---|
| 322 | TEST_EXPECT_ZERO(7-7); |
|---|
| 323 | } |
|---|
| 324 | |
|---|
| 325 | // --- simulate user_type (which may be defined anywhere) --- |
|---|
| 326 | class user_type { |
|---|
| 327 | int x, y; |
|---|
| 328 | public: |
|---|
| 329 | user_type(int X, int Y) : x(X), y(Y) {} |
|---|
| 330 | |
|---|
| 331 | int get_x() const { return x; } |
|---|
| 332 | int get_y() const { return y; } |
|---|
| 333 | |
|---|
| 334 | user_type flipped() const { return user_type(y,x); } |
|---|
| 335 | |
|---|
| 336 | int quadrant() const { |
|---|
| 337 | if (x == 0 || y == 0) return 0; // on axis |
|---|
| 338 | if (y>0) return x<0 ? 2 : 1; |
|---|
| 339 | return x<0 ? 3 : 4; |
|---|
| 340 | } |
|---|
| 341 | }; |
|---|
| 342 | // --- end of user_type --- |
|---|
| 343 | |
|---|
| 344 | // helpers needed for tests: |
|---|
| 345 | inline bool operator == (const user_type& u1, const user_type& u2) { return u1.get_x() == u2.get_x() && u1.get_y() == u2.get_y(); } |
|---|
| 346 | inline char *val2readable(const user_type& u) { return arb_test::StaticCode::strf("user_type(%i,%i)", u.get_x(), u.get_y()); } |
|---|
| 347 | inline bool in_same_quadrant(const user_type& u1, const user_type& u2) { return u1.quadrant() == u2.quadrant(); } |
|---|
| 348 | |
|---|
| 349 | void TEST_user_type_with_expectations() { |
|---|
| 350 | user_type ut1(3, 4); |
|---|
| 351 | user_type ut12(4, 4); |
|---|
| 352 | user_type ut2(-4, 4); |
|---|
| 353 | user_type ut3(-4, -8); |
|---|
| 354 | user_type ut4(4, -8); |
|---|
| 355 | |
|---|
| 356 | TEST_EXPECTATION(that(ut1).does_differ_from(ut12)); |
|---|
| 357 | TEST_EXPECTATION(that(ut12).is_equal_to(ut12.flipped())); |
|---|
| 358 | TEST_EXPECTATION(that(ut1).does_differ_from(ut1.flipped())); |
|---|
| 359 | |
|---|
| 360 | TEST_EXPECTATION(that(ut1).fulfills(in_same_quadrant, ut12)); |
|---|
| 361 | TEST_EXPECTATION(none().of(that(ut1).fulfills(in_same_quadrant, ut2), |
|---|
| 362 | that(ut2).fulfills(in_same_quadrant, ut3), |
|---|
| 363 | that(ut3).fulfills(in_same_quadrant, ut4))); |
|---|
| 364 | } |
|---|
| 365 | TEST_PUBLISH(TEST_user_type_with_expectations); |
|---|
| 366 | |
|---|
| 367 | void TEST_similarity() { |
|---|
| 368 | double d1 = 0.7531; |
|---|
| 369 | double epsilon = 0.00001; |
|---|
| 370 | double d2 = d1-epsilon*0.6; |
|---|
| 371 | double d3 = d1+epsilon*0.6; |
|---|
| 372 | |
|---|
| 373 | TEST_EXPECTATION(that(d1).fulfills(epsilon_similar(epsilon), d2)); |
|---|
| 374 | TEST_EXPECTATION(that(d1).fulfills(epsilon_similar(epsilon), d3)); |
|---|
| 375 | TEST_EXPECTATION(that(d2).contradicts(epsilon_similar(epsilon), d3)); |
|---|
| 376 | |
|---|
| 377 | TEST_EXPECT_SIMILAR(d1, d2, epsilon); |
|---|
| 378 | TEST_EXPECT_SIMILAR(d1, d3, epsilon); |
|---|
| 379 | } |
|---|
| 380 | |
|---|
| 381 | void TEST_less_equal() { |
|---|
| 382 | int x = 7; |
|---|
| 383 | int y = 8; |
|---|
| 384 | int z = 9; |
|---|
| 385 | |
|---|
| 386 | // less/more etc |
|---|
| 387 | |
|---|
| 388 | TEST_EXPECTATION(that(x).is_less_than(y)); |
|---|
| 389 | TEST_EXPECTATION(that(x).is_less_or_equal(y)); |
|---|
| 390 | TEST_EXPECTATION(that(x).is_less_or_equal(x)); |
|---|
| 391 | |
|---|
| 392 | TEST_EXPECTATION(that(y).is_more_than(x)); |
|---|
| 393 | TEST_EXPECTATION(that(y).is_more_or_equal(x)); |
|---|
| 394 | TEST_EXPECTATION(that(y).is_more_or_equal(y)); |
|---|
| 395 | |
|---|
| 396 | TEST_EXPECT_LESS_EQUAL(x, y); |
|---|
| 397 | TEST_EXPECT_LESS_EQUAL(x, x); |
|---|
| 398 | TEST_EXPECT_LESS(x, y); |
|---|
| 399 | TEST_EXPECT_IN_RANGE(y, x, z); |
|---|
| 400 | } |
|---|
| 401 | TEST_PUBLISH(TEST_less_equal); |
|---|
| 402 | |
|---|
| 403 | class readModified { // modifies on "read" (used to test unwanted double-evaluation) |
|---|
| 404 | int val; |
|---|
| 405 | public: |
|---|
| 406 | readModified(int v) : val(v) {} |
|---|
| 407 | void set(int n) { val = n; } |
|---|
| 408 | int getAndMod(int n) { |
|---|
| 409 | int v = val; |
|---|
| 410 | set(n); |
|---|
| 411 | return v; |
|---|
| 412 | } |
|---|
| 413 | }; |
|---|
| 414 | |
|---|
| 415 | #if !defined(__clang__) |
|---|
| 416 | // TEST_DISABLED_CLANG: evaluation order differs under clang |
|---|
| 417 | void TEST_single_eval() { |
|---|
| 418 | readModified mod(5); |
|---|
| 419 | TEST_EXPECT_EQUAL__BROKEN(mod.getAndMod(2), 2, 5); // now succeeds (this is no broken test; it tests behavior of TEST_EXPECT_EQUAL__BROKEN!) |
|---|
| 420 | |
|---|
| 421 | mod.set(5); |
|---|
| 422 | TEST_EXPECT_IN_RANGE(mod.getAndMod(10), 4, 6); |
|---|
| 423 | TEST_EXPECT_EQUAL(mod.getAndMod(10), 10); |
|---|
| 424 | TEST_EXPECT_IN_RANGE__BROKEN(mod.getAndMod(2), 8, 12); // @@@ tested expression is evaluated twice |
|---|
| 425 | TEST_EXPECT_EQUAL(mod.getAndMod(2), 2); |
|---|
| 426 | TEST_EXPECT_IN_RANGE(mod.getAndMod(33), 1, 3); |
|---|
| 427 | TEST_EXPECT_EQUAL(mod.getAndMod(33), 33); |
|---|
| 428 | TEST_EXPECT_IN_RANGE__BROKEN(mod.getAndMod(20), 32, 34); // @@@ tested expression is evaluated twice |
|---|
| 429 | TEST_EXPECT_EQUAL(mod.getAndMod(20), 20); |
|---|
| 430 | } |
|---|
| 431 | #endif |
|---|
| 432 | |
|---|
| 433 | enum MyEnum { |
|---|
| 434 | MY_UNKNOWN, |
|---|
| 435 | MY_RNA, |
|---|
| 436 | MY_DNA, |
|---|
| 437 | MY_AA, |
|---|
| 438 | }; |
|---|
| 439 | |
|---|
| 440 | void TEST_MyEnum_loop() { |
|---|
| 441 | int loops_performed = 0; |
|---|
| 442 | const char *db_name[]= { NULp, "TEST_trees.arb", "TEST_realign.arb", "TEST_realign.arb", NULp }; |
|---|
| 443 | for (int iat = MY_RNA; iat<=MY_AA; ++iat) { |
|---|
| 444 | MyEnum at = MyEnum(iat); |
|---|
| 445 | TEST_EXPECT(at>=1 && at<=3); |
|---|
| 446 | fprintf(stderr, "at=%i db_name[%i]='%s'\n", at, at, db_name[at]); |
|---|
| 447 | TEST_REJECT_NULL(db_name[at]); |
|---|
| 448 | loops_performed++; |
|---|
| 449 | } |
|---|
| 450 | TEST_EXPECT_EQUAL(loops_performed, 3); |
|---|
| 451 | } |
|---|
| 452 | |
|---|
| 453 | |
|---|
| 454 | void TEST_ARB_strchrnul() { |
|---|
| 455 | const char *check = "check"; |
|---|
| 456 | |
|---|
| 457 | TEST_EXPECT_EQUAL(ARB_strchrnul("check", 'c'), "check"); |
|---|
| 458 | TEST_EXPECT_EQUAL(ARB_strchrnul("check", 'e'), "eck"); |
|---|
| 459 | TEST_EXPECT_EQUAL(ARB_strchrnul("check", 'i'), ""); |
|---|
| 460 | TEST_EXPECT_EQUAL(ARB_strchrnul("check", '\0'), ""); |
|---|
| 461 | |
|---|
| 462 | TEST_EXPECT_EQUAL(ARB_strchrnul(check, 'c'), "check"); |
|---|
| 463 | TEST_EXPECT_EQUAL(ARB_strchrnul(check, 'e'), "eck"); |
|---|
| 464 | TEST_EXPECT_EQUAL(ARB_strchrnul(check, 'i'), ""); |
|---|
| 465 | TEST_EXPECT_EQUAL(ARB_strchrnul(check, '\0'), ""); |
|---|
| 466 | |
|---|
| 467 | TEST_EXPECT(ARB_strchrnul(check, 'c') == check); |
|---|
| 468 | TEST_EXPECT(ARB_strchrnul(check, 'e') == (check+2)); |
|---|
| 469 | TEST_EXPECT(ARB_strchrnul(check, 'i') == (check+5)); |
|---|
| 470 | TEST_EXPECT(ARB_strchrnul(check, '\0') == (check+5)); |
|---|
| 471 | } |
|---|
| 472 | |
|---|
| 473 | static const char *keepOne(char *s) { |
|---|
| 474 | static char *s2 = NULp; |
|---|
| 475 | reassign(s2, s); |
|---|
| 476 | return s2; |
|---|
| 477 | } |
|---|
| 478 | |
|---|
| 479 | #define TEST_EXPECT_STRPARTDUP_TO(start,end,expected) TEST_EXPECT_EQUAL(keepOne(ARB_strpartdup(start,end)),expected) |
|---|
| 480 | #define TEST_EXPECT_STRNDUP_TO(start,len,expected) TEST_EXPECT_EQUAL(keepOne(ARB_strndup(start,len)),expected) |
|---|
| 481 | |
|---|
| 482 | void TEST_string_duppers() { |
|---|
| 483 | const char *text = "text"; |
|---|
| 484 | const char *empty = ""; |
|---|
| 485 | |
|---|
| 486 | TEST_EXPECT_STRPARTDUP_TO(text, text+4, text); // dup with 0-byte |
|---|
| 487 | TEST_EXPECT_STRPARTDUP_TO(text, text+3, text); // dup w/o 0-byte (afterwards append 0-byte) |
|---|
| 488 | TEST_EXPECT_STRPARTDUP_TO(text, text, "t"); |
|---|
| 489 | TEST_EXPECT_STRPARTDUP_TO(text, text-1, empty); |
|---|
| 490 | |
|---|
| 491 | // copy whole string |
|---|
| 492 | TEST_EXPECT_STRPARTDUP_TO(text, NULp, text); |
|---|
| 493 | TEST_EXPECT_STRPARTDUP_TO(empty, NULp, empty); |
|---|
| 494 | |
|---|
| 495 | TEST_EXPECT_STRNDUP_TO(text, 5, text); // dup with 0-byte |
|---|
| 496 | TEST_EXPECT_STRNDUP_TO(text, 4, text); // dup w/o 0-byte (afterwards append 0-byte) |
|---|
| 497 | TEST_EXPECT_STRNDUP_TO(text, 1, "t"); |
|---|
| 498 | TEST_EXPECT_STRNDUP_TO(text, 0, empty); |
|---|
| 499 | |
|---|
| 500 | // error cases: |
|---|
| 501 | // a. "less" than empty string |
|---|
| 502 | TEST_EXPECT_NULL(ARB_strpartdup(text, text-2)); |
|---|
| 503 | TEST_EXPECT_NULL(ARB_strpartdup(text, text-200)); |
|---|
| 504 | |
|---|
| 505 | TEST_EXPECT_NULL(ARB_strndup(text, -1)); |
|---|
| 506 | TEST_EXPECT_NULL(ARB_strndup(text, -1000)); |
|---|
| 507 | |
|---|
| 508 | // b. no source -> no result |
|---|
| 509 | TEST_EXPECT_STRPARTDUP_TO(NULp, empty, NULp); |
|---|
| 510 | TEST_EXPECT_STRPARTDUP_TO(NULp, text, NULp); |
|---|
| 511 | TEST_EXPECT_STRPARTDUP_TO(NULp, NULp, NULp); |
|---|
| 512 | |
|---|
| 513 | keepOne(NULp); // =free |
|---|
| 514 | } |
|---|
| 515 | TEST_PUBLISH(TEST_string_duppers); |
|---|
| 516 | |
|---|
| 517 | #endif // UNIT_TESTS |
|---|
| 518 | |
|---|
| 519 | // -------------------------------------------------------------------------------- |
|---|
| 520 | |
|---|
| 521 | |
|---|