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