source: trunk/UNIT_TESTER/test_unit.h

Last change on this file was 19339, checked in by westram, 22 months ago
  • reintegrates 'refactor' into 'trunk'
    • eliminates old interface of GBS_strstruct
    • add a few new unittests (editor-config string + some PT-SERVER-functions)
  • adds: log:branches/refactor@19300:19338
File size: 68.5 KB
Line 
1// ================================================================ //
2//                                                                  //
3//   File      : test_unit.h                                        //
4//   Purpose   : include into test code                             //
5//                                                                  //
6//   Coded by Ralf Westram (coder@reallysoft.de) in February 2010   //
7//   Institute of Microbiology (Technical University Munich)        //
8//   http://www.arb-home.de/                                        //
9//                                                                  //
10// ================================================================ //
11
12#ifndef TEST_UNIT_H
13#define TEST_UNIT_H
14
15#ifndef ARB_ASSERT_H
16#include <arb_assert.h>
17#endif
18#ifndef ARBTOOLS_H
19#include <arbtools.h>
20#endif
21#ifndef _GLIBCXX_CSTDARG
22#include <cstdarg>
23#endif
24#ifndef _CPP_CSTDLIB
25#include <cstdlib>
26#endif
27#ifndef ERRNO_H
28#include <errno.h>
29#endif
30#ifndef DUPSTR_H
31#include <dupstr.h>
32#endif
33
34#if defined(_GLIBCXX_STRING) || defined(_LIBCPP_STRING)
35#define TESTS_KNOW_STRING
36#endif
37#ifdef ARBDB_BASE_H
38#define TESTS_KNOW_ARBDB
39#endif
40#ifdef ARB_ERROR_H
41#define TESTS_KNOW_ARB_ERROR
42#endif
43
44
45#define ENABLE_CRASH_TESTS // comment out this line to get rid of provoked SEGVs (e.g. while debugging test-code)
46// (Note: another way to get rid of these tests is to RESTRICT_FUN='!crashtest' via Makefile.setup.local)
47
48/* Note:
49 * This file should not generate any static code.
50 * Only place define's or inline functions here.
51 *
52 * All macros named 'XXX__BROKEN' are intended to be used, when a
53 * test is known to fail, but cannot be fixed atm for some reason
54 *
55 * Recommended test-assertion is TEST_EXPECTATION(that(..).xxx())
56 * see examples in test-unit-tests in ../CORE/arb_string.cxx@UNIT_TESTS
57 */
58
59// --------------------------------------------------------------------------------
60// reduce build-time by disabling some optimizations for selected function (see #770)
61// The attributes here - opposed to global attributes defined in ../TEMPLATES/attributes.h
62// are only made available inside unit-test-sections!
63//
64// Good candidates for __ATTR__REDUCED_OPTIMIZE are TEST_xxx() functions for which
65// you encounter the following compiler warning:
66//     warning: PRE disabled
67//
68// Good candidates for __ATTR__NO_GCSE_OPTIMIZE are TEST_xxx() functions for which
69// you encounter the following compiler warnings:
70//     warning: const/copy propagation disabled
71//     warning: GCSE disabled
72
73#if (GCC_PATCHLEVEL_CODE >= 40603)
74# define __ATTR__NOVARTRACK __ATTR__OPTIMIZE("no-var-tracking") __ATTR__OPTIMIZE("no-var-tracking-assignments")
75// #define __ATTR__REDUCED_OPTIMIZE                                             // [*1]
76// #define __ATTR__REDUCED_OPTIMIZE   __ATTR__NOVARTRACK                        // [*2] duration compared to [*1]: 40-70% (40% for gcc 7.1)
77#define __ATTR__REDUCED_OPTIMIZE __ATTR__NOVARTRACK __ATTR__OPTIMIZE("s")       // [*3] duration compared to [*1]: ~30%
78#define __ATTR__NO_GCSE_OPTIMIZE __ATTR__OPTIMIZE("no-gcse")
79#else
80// (some) gcc versions prior to 4.6.3 have problems if single optimizations are disabled on function-basis
81// (e.g. 4.4.3 crashes with internal compiler error if __ATTR__OPTIMIZE("s") is used)
82// -> do not reduce optimization (#770 was not a problem with older versions anyway)
83# define __ATTR__REDUCED_OPTIMIZE
84# define __ATTR__NO_GCSE_OPTIMIZE
85#endif
86
87// for functions with both warning-types:
88# define __ATTR__REDUCED_OPTIMIZE__NO_GCSE __ATTR__REDUCED_OPTIMIZE __ATTR__NO_GCSE_OPTIMIZE
89
90// --------------------------------------------------------------------------------
91
92
93#define ANY_SETUP "any_env_setup"
94
95namespace arb_test {
96
97    // -------------
98    //      str
99
100    class str {
101        char *s;
102    public:
103        str() : s(NULp) {}
104        str(const str& other) : s(nulldup(other.s)) {}
105        explicit str(char *S) : s(S) {}
106        str& operator = (const str& other) {
107            freedup(s, other.s);
108            return *this;
109        }
110        str& operator = (char *S) {
111            freeset(s, S);
112            return *this;
113        }
114        ~str() { free(s); }
115
116        bool exists() const { return s; }
117        void assign(char *S) { s = S; }
118        const char *value() const { return s; }
119    };
120
121    // -----------------------
122    //      location info
123
124#define WITHVALISTFROM(format,CODE)  do { va_list parg; va_start(parg, format); CODE; va_end(parg); } while(0)
125#define VPRINTFORMAT(format)         WITHVALISTFROM(format, vfprintf(stderr, format, parg))
126#define VCOMPILERMSG(msgtype,format) WITHVALISTFROM(format, vcompiler_msg(msgtype, format, parg))
127
128    class locinfo { //! stores source code location
129        const char *file;
130        int         line;
131
132        __attribute__((format(__printf__, 2, 0))) void vcompiler_msg(const char *message_type, const char *format, va_list parg) const {
133            fprintf(stderr, "%s:%i: ", file, line);
134            if (message_type) fprintf(stderr, "%s: ", message_type);
135            vfprintf(stderr, format, parg);
136        }
137
138    public:
139        locinfo() : file(NULp), line(0) {}
140        locinfo(const char *file_, int line_) : file(file_), line(line_) {}
141
142        bool exists() const { return file; }
143
144        const char *get_file() const { return file; }
145        int get_line() const { return line; }
146
147        __attribute__((format(printf, 2, 3))) bool warningf(const char *format, ...) const {
148            GlobalTestData& global = test_data();
149            if (global.show_warnings) {
150                FlushedOutput yes;
151                VCOMPILERMSG("Warning", format);
152                GlobalTestData::print_annotation();
153                global.warnings++;
154            }
155            return global.show_warnings;
156        }
157
158        __attribute__((format(printf, 3, 4))) void errorf(bool fail, const char *format, ...) const {
159            {
160                FlushedOutput yes;
161                VCOMPILERMSG("Error", format);
162                GlobalTestData::print_annotation();
163            }
164            if (fail) TRIGGER_ASSERTION(false); // fake an assertion failure
165        }
166        __attribute__((format(printf, 3, 4))) void ioerrorf(bool fail, const char *format, ...) const {
167            {
168                FlushedOutput yes;
169                VCOMPILERMSG("Error", format);
170                fprintf(stderr, " (errno=%i='%s')", errno, strerror(errno));
171                GlobalTestData::print_annotation();
172            }
173            if (fail) TRIGGER_ASSERTION(false); // fake an assertion failure
174        }
175    };
176
177    // --------------------
178    //      StaticCode
179
180    struct StaticCode {
181        static void printf(const char *format, ...) __attribute__((format(printf, 1, 2))) {
182            FlushedOutputNoLF yes;
183            VPRINTFORMAT(format);
184        }
185#undef VPRINTFORMAT
186#undef VCOMPILERMSG
187#undef WITHVALISTFROM
188
189        static char *readable_string(const char *s) {
190            // quote like C does!
191            if (s) {
192                size_t  len     = strlen(s)*4;
193                char   *res     = (char*)malloc(len+2+1);
194                int     needSep = 0; // 0=none, 1=if digit follows, 2=if hex follows
195                int     j       = 0;
196
197                res[j++] = '\"';
198                for (int i = 0; s[i]; ++i) {
199                    unsigned char c   = static_cast<unsigned char>(s[i]);
200                    char          esc = 0;
201                    switch (c) {
202                        case '\a': esc = 'a'; break;
203                        case '\b': esc = 'b'; break;
204                        case '\f': esc = 'f'; break;
205                        case '\n': esc = 'n'; break;
206                        case '\r': esc = 'r'; break;
207                        case '\t': esc = 't'; break;
208                        case '\v': esc = 'v'; break;
209                        case '\"': esc = '\"'; break;
210                        case '\\': esc = '\\'; break;
211                    }
212
213                    if (esc) {
214                        res[j++] = '\\';
215                        res[j++] = esc;
216                        needSep  = 0;
217                    }
218                    else if (c>=1 && c<=9) {
219                        res[j++] = '\\';
220                        res[j++] = '0'+c;
221                        needSep  = 1; // need to break string if next char is a digit
222                    }
223                    else if (c >= 32 && c<127) {
224                        if (needSep>0) {
225                            bool breakString = strchr("0123456789", c);
226                            if (!breakString && needSep == 2) {
227                                breakString = strchr("abcdefABCDEF", c);
228                            }
229                            if (breakString) {
230                                res[j++] = '\"';
231                                res[j++] = ' ';
232                                res[j++] = '\"';
233                            }
234                        }
235                        res[j++] = c;
236                        needSep  = 0;
237                    }
238                    else {
239                        j       += sprintf(res+j, "\\x%02x", int(c));
240                        needSep  = 2; // need to break string if next char is a hex-digit
241                    }
242                }
243                res[j++] = '\"';
244                res[j++] = 0;
245                return res;
246            }
247            else {
248                return strdup("(null)");
249            }
250        }
251        static void print_readable_string(const char *s, FILE *out) {
252            fputs(str(readable_string(s)).value(), out);
253        }
254
255        static char *vstrf(const char *format, va_list& parg) __attribute__((format(__printf__, 1, 0))) {
256            static const size_t max_vstrf_size = 10000;
257            static char         vstrf_buf[max_vstrf_size];
258
259            int printed = vsnprintf(vstrf_buf, max_vstrf_size, format, parg);
260            arb_assert(printed >= 0 && size_t(printed)<max_vstrf_size);
261
262            char *result    = (char*)malloc(printed+1);
263            memcpy(result, vstrf_buf, printed);
264            result[printed] = 0;
265            return result;
266        }
267
268        static char *strf(const char *format, ...) __attribute__((format(__printf__, 1, 2))) {
269            va_list  parg;
270            va_start(parg, format);
271            char *result = vstrf(format, parg);
272            va_end(parg);
273            return result;
274        }
275
276    };
277
278    inline char *val2readable(bool b) { return strdup(b ? "true" : "false"); }
279
280    inline char *val2readable(int i) { return StaticCode::strf("%i", i); }
281    inline char *val2hex(int i) { return StaticCode::strf("0x%x", i); }
282
283    inline char *val2readable(long L) { return StaticCode::strf("%li", L); }
284    inline char *val2hex(long L) { return StaticCode::strf("0x%lx", L); }
285
286    inline char *val2readable(size_t z) { return StaticCode::strf("%zu", z); }
287    inline char *val2hex(size_t z) { return StaticCode::strf("0x%zx", z); }
288
289    // dont dup size_t:
290#ifdef ARB_64
291    inline char *val2readable(unsigned u) { return StaticCode::strf("%u", u); }
292    inline char *val2hex(unsigned u) { return StaticCode::strf("0x%x", u); }
293#else
294    inline char *val2readable(long unsigned u) { return StaticCode::strf("%lu", u); }
295    inline char *val2hex(long unsigned u) { return StaticCode::strf("0x%lx", u); }
296#endif
297
298    inline char *val2readable(double d) { return StaticCode::strf("%f", d); }
299
300    inline char *val2readable(unsigned char c) { return c<32 ? StaticCode::strf(" ^%c (=0x%02x)", c+'A'-1, int(c)) : StaticCode::strf("'%c' (=0x%02x)", c, int(c)); }
301    inline char *val2readable(const char *s) { return StaticCode::readable_string(s); }
302
303#ifdef TESTS_KNOW_STRING
304    inline char *val2readable(const std::string& s) { return StaticCode::readable_string(s.c_str()); }
305#endif
306#if defined(TESTS_KNOW_ARBDB)
307    inline char *val2readable(const GBDATA* gbd) { return StaticCode::strf("%p", gbd); }
308#endif
309
310    // ------------------
311    //      copy
312
313
314    template <typename T>
315    class copy { //! makes char* copyable, so it can be handled like most other types
316        T t;
317    public:
318        copy(const T& t_) : t(t_) {}
319        operator const T&() const { return t; }
320    };
321
322    template <>
323    class copy<const char *> {
324        str t;
325    public:
326        copy(const char *t_) : t(str(t_ ? strdup(t_) : NULp)) {}
327        operator const char *() const { return t.value(); }
328    };
329
330    template <typename T> class copy< copy<T> > { copy(const copy<T>& t_); }; // avoid copies of copies
331
332    template <typename T> inline copy<T> make_copy(const T& t) { return copy<T>(t); }
333
334    inline copy<const char *> make_copy(const char *p) { return copy<const char *>(p); }
335    inline copy<const char *> make_copy(char *p) { return copy<const char *>(p); }
336    inline copy<const char *> make_copy(const unsigned char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); }
337    inline copy<const char *> make_copy(unsigned char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); }
338    inline copy<const char *> make_copy(const signed char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); }
339    inline copy<const char *> make_copy(signed char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); }
340
341    inline copy<unsigned char> make_copy(char p) { return copy<unsigned char>(p); }
342    inline copy<unsigned char> make_copy(unsigned char p) { return copy<unsigned char>(p); }
343    inline copy<unsigned char> make_copy(signed char p) { return copy<unsigned char>(p); }
344
345    template <typename T> str readable(const copy<T>& v) { return str(val2readable(v)); }
346    template <typename T> str readableHex(const copy<T>& v) { return str(val2readableHex(v)); }
347
348    template <typename T> bool operator == (const copy<T>& v1, const copy<T>& v2) { return static_cast<const T&>(v1) == static_cast<const T&>(v2); }
349    template <typename T> bool operator != (const copy<T>& v1, const copy<T>& v2) { return !(v1 == v2); }
350
351    template <> inline bool operator == <const char *>(const copy<const char *>& v1, const copy<const char *>& v2) {
352        const char *val1 = v1;
353        const char *val2 = v2;
354
355        return (val1 == val2) || (val1 && val2 && (strcmp(val1, val2) == 0));
356    }
357
358
359    template <typename T> inline void print(const T& t) {
360        char *r = val2readable(make_copy(t));
361        fputs(r, stderr);
362        free(r);
363    }
364    template <typename T> inline void print_hex(const T& t) { fputs(val2hex(make_copy(t)), stderr); }
365
366    template <typename T1, typename T2> inline void print_pair(T1 t1, T2 t2) {
367        print(t1);
368        fputs(",", stderr);
369        print(t2);
370    }
371    template <typename T1, typename T2> inline void print_hex_pair(T1 t1, T2 t2) {
372        print_hex(t1);
373        fputc(',', stderr);
374        print_hex(t2);
375    }
376
377    class epsilon_similar {
378        double epsilon;
379    public:
380        epsilon_similar(double epsilon_) : epsilon(epsilon_) { arb_assert(epsilon>0.0); }
381        bool operator()(const double& d1, const double& d2) const {
382            double diff        = d1-d2;
383            if (diff<0.0) diff = -diff; // do not use fabs() here
384            return diff <= epsilon;
385        }
386    };
387
388    class containing {
389        static bool not_empty(const char *part) { arb_assert(part); return part[0]; }
390#if defined(TESTS_KNOW_STRING)
391        static bool not_empty(const std::string& part) { return !part.empty(); }
392#endif
393    public:
394        bool operator()(const char *str, const char *part) const {
395            arb_assert(str); // NULp str will crash strstr
396            arb_assert(not_empty(part)); // do NOT call with empty part - will always report true.
397            return not_empty(part) && strstr(str, part); // return false if part is empty (=safety fallback)
398        }
399#if defined(TESTS_KNOW_STRING)
400        bool operator()(const std::string& str, const std::string& part) const {
401            arb_assert(not_empty(part)); // see above
402            return not_empty(part) && strstr(str.c_str(), part.c_str());
403        }
404#endif
405    };
406
407    // -------------------------------
408    //      some output functions
409
410    inline void print(const char *s) { fputs(s, stderr); }
411    inline void print(char c) { fputc(c, stderr); }
412    inline void print(int i) { fprintf(stderr, "%i", i); }
413
414    inline void space() { print(' '); }
415    inline void nl() { print('\n'); }
416
417    inline void print_indent(int indent) { while (indent--) space(); }
418
419    inline void spaced(const char *word) { space(); print(word); space(); }
420    inline void select_spaced(bool first, const char *singular, const char *plural) { spaced(first ? singular : plural); }
421
422
423#define HASTOBE_CLONABLE(type) virtual type *clone() const = 0
424#define MAKE_CLONABLE(type)    type *clone() const OVERRIDE { return new type(*this); }
425
426    // ------------------------------
427    //      abstract expectation
428
429    struct expectation { //! something expected. can be fulfilled or not (and can explain why/not)
430        virtual ~expectation() {}
431        HASTOBE_CLONABLE(expectation);
432
433        virtual bool fulfilled() const              = 0;
434        virtual void explain(int indent) const      = 0;
435        virtual void dump_brief_description() const = 0;
436    };
437
438    // -------------------
439    //      asserters
440
441    class asserter : virtual Noncopyable {
442        expectation *expected;
443        locinfo      loc;
444        const char  *code;
445
446        virtual void announce_failure() const { TRIGGER_ASSERTION(false); }
447
448        void err(const char *format) const { loc.errorf(false, format, code); }
449        bool warn(const char *format) const { return loc.warningf(format, code); }
450
451    public:
452        asserter(const expectation& e, const char *nontmp_code, const char *file, int line)
453            : expected(e.clone()),
454              loc(file, line),
455              code(nontmp_code)
456        {}
457        virtual ~asserter() { delete expected; }
458
459        const char *get_code() const { return code; }
460
461        void expect_that() const {
462            if (!expected->fulfilled()) {
463                err("Failed expectation '%s'");
464                print("expectation fails because\n");
465                expected->explain(2); print('\n');
466                announce_failure();
467            }
468        }
469        void expect_broken() const {
470            if (expected->fulfilled()) {
471                err("Previously broken expectation '%s' succeeds");
472                announce_failure();
473            }
474            else {
475                if (warn("Expectation '%s' known as broken (accepted until fixed)")) {
476                    print("Broken because\n");
477                    expected->explain(2); print('\n');
478                }
479            }
480        }
481
482        void expect_wanted_behavior() const {
483            if (expected->fulfilled()) {
484                err("Wanted behavior '%s' reached");
485                announce_failure();
486            }
487            else {
488                if (warn("Wanted behavior: '%s'")) {
489                    print("Unsatisfied because\n");
490                    expected->explain(2); print('\n');
491                }
492            }
493        }
494
495        void expect_brokenif(bool condition, const char *condcode) {
496            GlobalTestData& global = test_data();
497
498            char *old_annotation = nulldup(global.get_annotation());
499            char *new_annotation = StaticCode::strf("when (%s) is %s; %s",
500                                                    condcode,
501                                                    str(val2readable(condition)).value(),
502                                                    null2empty(old_annotation));
503
504            global.annotate(new_annotation);
505            if (condition) expect_broken(); else expect_that();
506            global.annotate(old_annotation);
507
508            free(new_annotation);
509            free(old_annotation);
510        }
511    };
512
513    class debug_asserter : public asserter {
514        void announce_failure() const OVERRIDE {
515            print("<<< would trigger assertion now! >>>\n");
516        }
517    public:
518        debug_asserter(const expectation& e, const char *code_, const char *file, int line)
519            : asserter(e, code_, file, line)
520        {}
521
522        void debug_expectations() {
523            fprintf(stderr, "-------------------- [Debugging expectations for '%s']\n", get_code());
524            expect_that();
525            expect_broken();
526            expect_wanted_behavior();
527        }
528    };
529
530    // ----------------------------------------
531    //      matchable + matcher (abstract)
532
533    struct matchable { //! can be matched with corresponding matcher.
534        virtual ~matchable() {}
535        HASTOBE_CLONABLE(matchable);
536
537        virtual const char *name() const           = 0;
538        virtual const char *readable_value() const = 0;
539    };
540
541    struct matcher { //! can match things.
542        virtual ~matcher() {}
543        HASTOBE_CLONABLE(matcher);
544
545        virtual bool matches(const matchable& thing) const                      = 0;
546        virtual void dump_expectation(const matchable& thing, int indent) const = 0;
547        virtual void dump_brief_description(const matchable& thing) const       = 0;
548    };
549
550    // ----------------------------------------------
551    //      expectation from matchable + matcher
552
553
554    class match_expectation : public expectation { //! expectation composed from matcher and corresponding matchable.
555        matchable *thing;
556        matcher   *condition;
557    public:
558        match_expectation(const matchable& thing_, const matcher& condition_)
559            : thing(thing_.clone()),
560              condition(condition_.clone())
561        {}
562        match_expectation(const match_expectation& other)
563            : thing(other.thing->clone()),
564              condition(other.condition->clone())
565        {}
566        DECLARE_ASSIGNMENT_OPERATOR(match_expectation);
567        MAKE_CLONABLE(match_expectation);
568        ~match_expectation() OVERRIDE {
569            delete thing;
570            delete condition;
571        }
572
573        bool fulfilled() const OVERRIDE { return condition->matches(*thing); }
574        bool unfulfilled() const { return !fulfilled(); }
575        void explain(int indent) const OVERRIDE { condition->dump_expectation(*thing, indent); }
576        void dump_brief_description() const OVERRIDE { condition->dump_brief_description(*thing); }
577    };
578
579    // -------------------
580    //      predicate
581
582
583    class predicate_description {
584        const char  *primary;
585        const char  *inverse;
586        mutable str  tmp;
587
588        void erase_last_from_tmp() const {
589            char *t   = const_cast<char*>(tmp.value());
590            int   len = strlen(t);
591            t[len-1]  = 0;
592        }
593
594        static bool ends_with_s(const char *s) {
595            int len          = strlen(s);
596            return s[len-1] == 's';
597        }
598
599        const char *make(const char *desc, bool got) const {
600            if (ends_with_s(desc)) {
601                if (got) return desc;
602                tmp = StaticCode::strf("doesnt %s", desc);
603                erase_last_from_tmp();
604            }
605            else {
606                tmp = StaticCode::strf("%s %s", got ? "is" : "isnt", desc);
607            }
608            return tmp.value();
609        }
610
611    public:
612        predicate_description(const char *primary_) : primary(primary_), inverse(NULp) {}
613        predicate_description(const char *primary_, const char *inverse_) : primary(primary_), inverse(inverse_) {}
614        // cppcheck-suppress uninitMemberVar (fails to detect default ctor of 'str')
615        predicate_description(const predicate_description& other) : primary(other.primary), inverse(other.inverse) {}
616        DECLARE_ASSIGNMENT_OPERATOR(predicate_description);
617
618        const char *make(bool expected, bool got) const {
619            if (expected) return make(primary, got);
620            if (inverse) return make(inverse, !got);
621            return make(primary, got);
622        }
623    };
624
625    template <typename FUNC>
626    class predicate {
627        FUNC                  pred;
628        predicate_description description;
629    public:
630        predicate(FUNC pred_, const char *name) : pred(pred_), description(name) {}
631        predicate(FUNC pred_, const char *name, const char *inverse) : pred(pred_), description(name, inverse) {}
632
633        template <typename T> bool matches(const copy<T>& v1, const copy<T>& v2) const { return pred(v1, v2); }
634        const char *describe(bool expected, bool got) const { return description.make(expected, got); }
635    };
636
637    template <typename FUNC> predicate<FUNC> make_predicate(FUNC func, const char *primary, const char *inverse) {
638        return predicate<FUNC>(func, primary, inverse);
639    }
640
641    // ------------------------------------------
642    //      matchable + matcher (for values)
643
644    template <typename T> inline bool equals(const copy<T>& t1, const copy<T>& t2) { return t1 == t2; }
645    template <typename T> inline bool less(const copy<T>& t1, const copy<T>& t2) { return t1 < t2; }
646    template <typename T> inline bool more(const copy<T>& t1, const copy<T>& t2) { return t1 > t2; }
647
648    template <typename T>
649    class matchable_value FINAL_TYPE : public matchable { //! matchable for values
650        copy<T>      val;
651        mutable str  readable;
652        const char * code;
653    public:
654        matchable_value(copy<T> val_, const char *nontemp_code) : val(val_), code(nontemp_code) {}
655        matchable_value(const matchable_value<T>& other) : val(other.val), readable(other.readable), code(other.code) {}
656        DECLARE_ASSIGNMENT_OPERATOR(matchable_value);
657        MAKE_CLONABLE(matchable_value<T>);
658
659        const copy<T>& value() const { return val; }
660        char *gen_description() const { return StaticCode::strf("%s (=%s)", code, val.readable()); }
661
662        const char *name() const OVERRIDE { return code; }
663        const char *readable_value() const OVERRIDE {
664            if (!readable.exists()) readable = arb_test::readable(val);
665            return readable.value();
666        }
667
668        template <typename U> inline match_expectation equals_expectation(bool invert, const U& other, const char *code) const;
669        template <typename U> inline match_expectation lessThan_expectation(bool invert, const U& other, const char *code) const;
670        template <typename U> inline match_expectation moreThan_expectation(bool invert, const U& other, const char *code) const;
671
672        inline match_expectation null_expectation(bool wantNULL) const;
673
674        template <typename FUNC> inline match_expectation predicate_expectation(bool wanted, predicate<FUNC> pred, matchable_value<T> arg) const;
675        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;
676    };
677
678    template <typename T, typename U>
679    inline const matchable_value<T> make_matchable_value(const U& other, const char *code_) {
680        return matchable_value<T>(T(other), code_);
681    }
682#if defined(TESTS_KNOW_STRING)
683    template<>
684    inline const matchable_value<const char*> make_matchable_value<const char *, std::string>(const std::string& other, const char *code_) {
685        return matchable_value<const char *>(other.c_str(), code_);
686    }
687#endif
688    template <typename T> template <typename U>
689    inline match_expectation matchable_value<T>::equals_expectation(bool wanted, const U& other, const char *code_) const {
690        return predicate_expectation(wanted, make_predicate(equals<T>, "equals", "differs"), make_matchable_value<T,U>(other, code_));
691    }
692    template <typename T> template <typename U>
693    inline match_expectation matchable_value<T>::lessThan_expectation(bool wanted, const U& other, const char *code_) const {
694        return predicate_expectation(wanted, make_predicate(less<T>, "less than", "more or equal"), make_matchable_value<T,U>(other, code_));
695    }
696    template <typename T> template <typename U>
697    inline match_expectation matchable_value<T>::moreThan_expectation(bool wanted, const U& other, const char *code_) const {
698        return predicate_expectation(wanted, make_predicate(more<T>, "more than", "less or equal"), make_matchable_value<T,U>(other, code_));
699    }
700    template <typename T>
701    inline match_expectation matchable_value<T>::null_expectation(bool wantNULL) const {
702        return equals_expectation(wantNULL, (T)NULp, "NULp");
703    }
704
705    template <typename T>
706    class value_matcher : public matcher { //! matcher for values
707        matchable_value<T> expected;
708    public:
709        value_matcher(const matchable_value<T>& expected_) : expected(expected_) {}
710        ~value_matcher() OVERRIDE {}
711
712        virtual bool matches(const copy<T>& v1, const copy<T>& v2) const = 0;
713        virtual const char *relation(bool isMatch) const                 = 0;
714
715        const matchable_value<T>& get_expected() const { return expected; }
716
717        bool matches(const matchable& thing) const FINAL_OVERRIDE {
718            const matchable_value<T>& value_thing = dynamic_cast<const matchable_value<T>&>(thing);
719            return matches(value_thing.value(), expected.value());
720        }
721
722        void dump_expectation(const matchable& thing, int indent) const OVERRIDE {
723            bool isMatch = matches(thing);
724            print_indent(indent);
725            fprintf(stderr, "'%s' %s '%s'", thing.name(), relation(isMatch), expected.name());
726
727            const matchable_value<T>& value_thing = dynamic_cast<const matchable_value<T>&>(thing);
728            if (equals<T>(value_thing.value(), expected.value())) {
729                fprintf(stderr, " (both are %s)", value_thing.readable_value());
730            }
731            else {
732                int diff = strlen(thing.name())-strlen(expected.name());
733
734                print(", where\n");
735                indent += 2;;
736                print_indent(indent); fprintf(stderr, "'%s'%*s is %s, and\n", thing.name(),    (diff>0 ? 0 : -diff), "", thing.readable_value());
737                print_indent(indent); fprintf(stderr, "'%s'%*s is %s",        expected.name(), (diff<0 ? 0 : diff),  "", expected.readable_value());
738            }
739        }
740        void dump_brief_description(const matchable& thing) const OVERRIDE {
741            print(thing.name());
742            print('.');
743            print(relation(true));
744            print('('); print(expected.name()); print(')');
745        }
746
747    };
748
749    // ---------------------------
750    //      predicate_matcher
751
752
753    template <typename T, typename FUNC>
754    // cppcheck-suppress noConstructor (fails to detect template ctor)
755    class predicate_matcher : public value_matcher<T> {
756        predicate<FUNC> pred;
757        bool            expected_result;
758
759    public:
760        predicate_matcher(bool wanted, predicate<FUNC> pred_, const matchable_value<T>& arg)
761            : value_matcher<T>(arg),
762              pred(pred_),
763              expected_result(wanted)
764        {}
765        MAKE_CLONABLE(predicate_matcher);
766
767        bool matches(const copy<T>& v1, const copy<T>& v2) const OVERRIDE { return correlated(pred.matches(v1, v2), expected_result); }
768        const char *relation(bool isMatch) const OVERRIDE { return pred.describe(expected_result, correlated(isMatch, expected_result)); }
769    };
770
771    template <typename T> template <typename FUNC>
772    inline match_expectation matchable_value<T>::predicate_expectation(bool wanted, predicate<FUNC> pred, matchable_value<T> arg) const {
773        return match_expectation(*this, predicate_matcher<T,FUNC>(wanted, pred, arg));
774    }
775    template <typename T> template <typename U, typename FUNC>
776    inline match_expectation matchable_value<T>::predicate_expectation(bool wanted, FUNC pred, const char *pred_code, const U& arg, const char *arg_code) const {
777        return match_expectation(*this, predicate_matcher<T,FUNC>(wanted, predicate<FUNC>(pred, pred_code), make_matchable_value<T,U>(arg, arg_code)));
778    }
779
780    // ------------------------------------------------
781    //      matchable + matcher (for expectations)
782
783    const int MAX_GROUP_SIZE = 5;
784    class expectation_group : public matchable { //! group of expectation. matchable with group_matcher
785        int          count;
786        expectation *depend_on[MAX_GROUP_SIZE];
787
788        expectation_group& operator = (const expectation_group&); // forbidden
789    protected:
790
791    public:
792        expectation_group() : count(0) { depend_on[0] = NULp; }
793        expectation_group(const expectation& e) : count(1) {
794            depend_on[0] = e.clone();
795        }
796        expectation_group(const expectation& e1, const expectation& e2) : count(2) {
797            depend_on[0] = e1.clone();
798            depend_on[1] = e2.clone();
799        }
800        expectation_group(const expectation_group& other) : count(other.count) {
801            for (int i = 0; i<count; ++i) {
802                depend_on[i] = other.depend_on[i]->clone();
803            }
804        }
805        ~expectation_group() OVERRIDE {
806            for (int i = 0; i<count; ++i) {
807                delete depend_on[i];
808            }
809        }
810        MAKE_CLONABLE(expectation_group);
811
812        expectation_group& add(const expectation& e) { depend_on[count++] = e.clone(); arb_assert(count <= MAX_GROUP_SIZE); return *this; }
813
814        const char *name() const OVERRIDE {
815            return "<expectation_group>";
816        }
817        const char *readable_value() const OVERRIDE {
818            return "<value of expectation_group>";
819        }
820
821        const expectation& dependent(int i) const { arb_assert(i<count); return *depend_on[i]; }
822        int size() const { return count; }
823        int count_fulfilled() const {
824            int ff = 0;
825            for (int i = 0; i<count; ++i) {
826                ff += dependent(i).fulfilled();
827            }
828            return ff;
829        }
830        void dump_some_expectations(int indent, bool fulfilled, bool unfulfilled) const {
831            if (fulfilled||unfulfilled) {
832                bool all    = fulfilled && unfulfilled;
833                bool wanted = fulfilled;
834
835                bool printed = false;
836                for (int i = 0; i<size(); ++i) {
837                    const expectation& e = dependent(i);
838
839                    bool is_fulfilled = e.fulfilled();
840                    if (all || is_fulfilled == wanted) {
841                        if (printed) print('\n');
842                        e.explain(indent);
843                        printed = true;
844                    }
845                }
846            }
847        }
848        void dump_brief_description() const {
849            print("of(");
850            bool printed = false;
851            for (int i = 0; i<size(); ++i) {
852                if (printed) print(", ");
853                const expectation& e = dependent(i);
854                e.dump_brief_description();
855                printed = true;
856            }
857            print(')');
858        }
859    };
860
861    struct group_match { //! result of matching an expectation_group with a group_matcher
862        const int count;
863        const int fulfilled;
864        const int min_req;
865        const int max_req;
866        const int diff;
867
868        int required(int what) const { return what == -1 ? count : what; }
869        group_match(const expectation_group& egroup, int min, int max)
870            : count(egroup.size()),
871              fulfilled(egroup.count_fulfilled()),
872              min_req(required(min)),
873              max_req(required(max)),
874              diff(fulfilled<min_req
875                   ? fulfilled-min_req
876                   : (fulfilled>max_req ? fulfilled-max_req : 0))
877        {}
878
879
880        inline static void is(int a) { select_spaced(a == 1, "is", "are"); }
881        inline static void was(int a) { select_spaced(a < 2, "was", "were"); }
882        inline static void amountzero(int a, const char *zero) { a ? print(a) : print(zero); }
883
884        void dump_num_of(int amount, const char *thing) const {
885            amountzero(amount, "no");
886            space();
887            print(thing);
888            if (amount != 1) print('s');
889        }
890
891        void dump(const expectation_group& group, int indent) const {
892            print_indent(indent);
893            if (count == 1) {
894                print("expectation ");
895                print("'");
896                group.dependent(0).dump_brief_description();
897                print("' ");
898                print(fulfilled ? "fulfilled" : "fails");
899                print(diff ? " unexpectedly" : " as expected");
900            }
901            else {
902                print("expected ");
903                int that_many;
904                if (min_req == max_req) {
905                    if (diff>0 && min_req>0) print("only ");
906                    that_many = min_req;
907                }
908                else {
909                    if (diff) {
910                        print("at"); select_spaced(diff<0, "least", "most");
911                        that_many = diff<0 ? min_req : max_req;
912                    }
913                    else {
914                        fprintf(stderr, "%i-", min_req);
915                        that_many = max_req;
916                    }
917                }
918                dump_num_of(that_many, "fulfilled expectation");
919                space();
920                group.dump_brief_description();
921                nl();
922
923                indent += 2;
924                print_indent(indent);
925                if (diff == 0) print("and "); else print("but ");
926
927                if (diff<0 && fulfilled>0) print("only ");
928                amountzero(fulfilled, "none"); is(fulfilled); print("fulfilled");
929            }
930
931            print(", because\n");
932            bool show_fulfilled   = diff >= 0;
933            bool show_unfulfilled = diff <= 0;
934            group.dump_some_expectations(indent+2, show_fulfilled, show_unfulfilled);
935        }
936    };
937
938    class group_matcher FINAL_TYPE : public matcher { //! matches expectation_group for degree of fulfilledness
939        int min, max;
940        group_matcher(int min_, int max_) : min(min_), max(max_) {}
941    public:
942        MAKE_CLONABLE(group_matcher);
943
944        bool matches(const matchable& thing) const OVERRIDE {
945            return group_match(dynamic_cast<const expectation_group&>(thing), min, max).diff == 0;
946        }
947
948        void dump_expectation(const matchable& thing, int indent) const OVERRIDE {
949            const expectation_group& group = dynamic_cast<const expectation_group&>(thing);
950            group_match matching(group, min, max);
951            matching.dump(group, indent);
952        }
953
954        // factories
955        static group_matcher all() { return group_matcher(-1, -1); }
956        static group_matcher none() { return group_matcher(0, 0); }
957        static group_matcher atleast(int min_) { return group_matcher(min_, -1); }
958        static group_matcher atmost(int max_) { return group_matcher(0, max_); }
959        static group_matcher exactly(int amount) { return group_matcher(amount, amount); }
960
961        // match_expectation factories
962        match_expectation of(const expectation& e) const {
963            return match_expectation(expectation_group(e), *this);
964        }
965        match_expectation of(const expectation& e1, const expectation& e2) const {
966            return match_expectation(expectation_group(e1, e2), *this);
967        }
968        match_expectation of(const expectation& e1, const expectation& e2, const expectation& e3) const {
969            return match_expectation(expectation_group(e1, e2).add(e3), *this);
970        }
971        match_expectation of(const expectation& e1, const expectation& e2, const expectation& e3, const expectation& e4) const {
972            return match_expectation(expectation_group(e1, e2).add(e3).add(e4), *this);
973        }
974
975        match_expectation ofgroup(const expectation_group& group) {
976            return match_expectation(group, *this);
977        }
978
979        void dump_brief_description(const matchable& thing) const OVERRIDE {
980            if (max == -1) {
981                if (min == -1) {
982                    print("all");
983                }
984                else {
985                    fprintf(stderr, "atleast(%i)", min);
986                }
987            }
988            else if (max == 0) {
989                print("none");
990            }
991            else if (min == max) {
992                fprintf(stderr, "exactly(%i)", min);
993            }
994            else {
995                fprintf(stderr, "[%i-%i]", min, max);
996            }
997
998            print('.');
999
1000            const expectation_group& group = dynamic_cast<const expectation_group&>(thing);
1001            group.dump_brief_description();
1002        }
1003    };
1004
1005    // --------------------------
1006    //      helper functions
1007
1008
1009    template <typename T> const matchable_value<T> CREATE_matchable(const copy<T>& val, const char *code) { return matchable_value<T>(val, code); }
1010
1011    inline group_matcher all() { return group_matcher::all(); }
1012    inline group_matcher none() { return group_matcher::none(); }
1013    inline group_matcher atleast(int min) { return group_matcher::atleast(min); }
1014    inline group_matcher atmost(int max) { return group_matcher::atmost(max); }
1015    inline group_matcher exactly(int amount) { return group_matcher::exactly(amount); }
1016
1017    inline match_expectation wrong(const expectation& e) { return none().of(e); }
1018};
1019
1020// --------------------------------------------------------------------------------
1021
1022#define MATCHABLE_ARGS_UNTYPED(val) val, #val
1023#define MATCHABLE_ARGS_TYPED(val)   make_copy(val), #val
1024
1025#define is_equal_to(val)      equals_expectation(true, MATCHABLE_ARGS_UNTYPED(val))
1026#define does_differ_from(val) equals_expectation(false, MATCHABLE_ARGS_UNTYPED(val))
1027
1028#define is_equal_to_NULL()      null_expectation(true)
1029#define does_differ_from_NULL() null_expectation(false)
1030
1031#define is_less_than(val) lessThan_expectation(true, MATCHABLE_ARGS_UNTYPED(val))
1032#define is_more_than(val) moreThan_expectation(true, MATCHABLE_ARGS_UNTYPED(val))
1033
1034#define is_less_or_equal(val) moreThan_expectation(false, MATCHABLE_ARGS_UNTYPED(val))
1035#define is_more_or_equal(val) lessThan_expectation(false, MATCHABLE_ARGS_UNTYPED(val))
1036
1037#define fulfills(pred,arg)    predicate_expectation(true, MATCHABLE_ARGS_UNTYPED(pred), MATCHABLE_ARGS_UNTYPED(arg))
1038#define contradicts(pred,arg) predicate_expectation(false, MATCHABLE_ARGS_UNTYPED(pred), MATCHABLE_ARGS_UNTYPED(arg))
1039
1040#define does_contain(val)   fulfills(containing(),val)
1041#define doesnt_contain(val) contradicts(containing(),val)
1042
1043#define that(thing) CREATE_matchable(MATCHABLE_ARGS_TYPED(thing))
1044// Warning: make sure you use 'that(xxx)' only once per macro!
1045//          (otherwise unwanted double evaluation takes place; see TEST_EXPECT_EQUAL__BROKEN for howto avoid it)
1046
1047
1048#define TEST_EXPECTATION(EXPCTN) do { using namespace arb_test; asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).expect_that(); } while(0)
1049#define TEST_EXPECTATION__BROKEN_SIMPLE(EXPCTN) do { using namespace arb_test; asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).expect_broken(); } while(0)
1050#define TEST_EXPECTATION__BROKEN_AT_LOC(WANTED,GOT,FILE,LINE) do { using namespace arb_test; asserter(WANTED, #WANTED, FILE, LINE).expect_broken(); asserter(GOT, #GOT, FILE, LINE).expect_that(); } while(0)
1051#define TEST_EXPECTATION__BROKEN(WANTED,GOT) TEST_EXPECTATION__BROKEN_AT_LOC(WANTED, GOT, __FILE__, __LINE__)
1052#define TEST_EXPECTATION__WANTED(EXPCTN) do { using namespace arb_test; asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).expect_wanted_behavior(); } while(0)
1053
1054#define TEST_EXPECTATION__BROKENIF(COND,EXPCTN) do { using namespace arb_test; asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).expect_brokenif(COND,#COND); } while(0)
1055
1056#define DEBUG_TEST_EXPECTATION(EXPCTN) do {                                             \
1057        using namespace arb_test;                                                       \
1058        debug_asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).                            \
1059            debug_expectations();                                                       \
1060        debug_asserter(wrong(EXPCTN), "wrong(" #EXPCTN ")", __FILE__, __LINE__).        \
1061            debug_expectations();                                                       \
1062    } while(0)
1063
1064// --------------------------------------------------------------------------------
1065
1066#define HERE arb_test::locinfo(__FILE__, __LINE__)
1067
1068#define TEST_WARNING(format,strarg)           HERE.warningf(format, (strarg))
1069#define TEST_WARNING2(format,strarg1,strarg2) HERE.warningf(format, (strarg1), (strarg2))
1070#define TEST_ERROR(format,strarg)             HERE.errorf(true, format, (strarg))
1071#define TEST_ERROR2(format,strarg1,strarg2)   HERE.errorf(true, format, (strarg1), (strarg2))
1072#define TEST_IOERROR(format,strarg)           HERE.ioerrorf(true, format, (strarg))
1073
1074// --------------------------------------------------------------------------------
1075
1076#define TEST_FAILS_INSIDE_VALGRIND(THETEST) do {                \
1077        if (!GBK_running_on_valgrind()) {                       \
1078            THETEST;                                            \
1079            TEST_WARNING("valgrind fails for '%s'", #THETEST);  \
1080        }                                                       \
1081    } while(0)
1082
1083// --------------------------------------------------------------------------------
1084
1085#define TEST_EXPECT_ZERO(cond)             TEST_EXPECT_EQUAL(cond, 0)
1086#define TEST_EXPECT_ZERO__BROKEN(cond,got) TEST_EXPECT_EQUAL__BROKEN(cond, 0, got)
1087#define TEST_REJECT_ZERO(cond)             TEST_EXPECTATION(that(cond).does_differ_from(0))
1088#define TEST_REJECT_ZERO__BROKEN(cond)     TEST_EXPECTATION__BROKEN_SIMPLE(that(cond).does_differ_from(0))
1089
1090#define TEST_EXPECT_ZERO_OR_SHOW_ERRNO(iocond)                  \
1091    do {                                                        \
1092        if ((iocond))                                           \
1093            TEST_IOERROR("I/O-failure in '%s'", #iocond);       \
1094    } while(0)
1095
1096// --------------------------------------------------------------------------------
1097
1098#define MISSING_TEST(description)                       \
1099    TEST_WARNING("Missing test '%s'", #description)
1100
1101// --------------------------------------------------------------------------------
1102
1103namespace arb_test {
1104    inline match_expectation reports_error(const char *error) { return that(error).does_differ_from_NULL(); }
1105    inline match_expectation doesnt_report_error(const char *error) { return that(error).is_equal_to_NULL(); }
1106    inline match_expectation reported_error_contains(const char *error, const char *part) { return error ? that(error).does_contain(part) : that(error).does_differ_from_NULL(); }
1107#if defined(TESTS_KNOW_ARB_ERROR)
1108    inline match_expectation reports_error(ARB_ERROR error) { return reports_error(error.deliver()); }
1109    inline match_expectation doesnt_report_error(ARB_ERROR error) { return doesnt_report_error(error.deliver()); }
1110    inline match_expectation reported_error_contains(ARB_ERROR error, const char *part) { return reported_error_contains(error.deliver(), part); }
1111#endif
1112};
1113
1114#define TEST_EXPECT_ERROR_CONTAINS(call,part)         TEST_EXPECTATION               (reported_error_contains(call, part))
1115#define TEST_EXPECT_ERROR_CONTAINS__BROKEN(call,part) instead_use__TEST_EXPECT_ANY_ERROR__BROKEN__or__TEST_EXPECT_ERROR_CONTAINS
1116#define TEST_EXPECT_ANY_ERROR(call)                   TEST_EXPECTATION               (reports_error(call))
1117#define TEST_EXPECT_ANY_ERROR__BROKEN(call)           TEST_EXPECTATION__BROKEN_SIMPLE(reports_error(call))
1118#define TEST_EXPECT_NO_ERROR(call)                    TEST_EXPECTATION               (doesnt_report_error(call))
1119#define TEST_EXPECT_NO_ERROR__BROKEN(call)            TEST_EXPECTATION__BROKEN_SIMPLE(doesnt_report_error(call))
1120
1121// --------------------------------------------------------------------------------
1122
1123#ifdef ARB_MSG_H
1124
1125namespace arb_test {
1126    inline match_expectation no_forgotten_error_exported() { return that(GB_incur_error()).is_equal_to_NULL(); }
1127
1128    class calling {
1129        bool     result;
1130        GB_ERROR error;
1131    public:
1132        calling(bool call)
1133            : result(call),
1134              error(GB_incur_error())
1135        {}
1136
1137        // functions below try to make failing expectations more readable
1138        match_expectation returns_result() const { return that(result).is_equal_to(true); }
1139        match_expectation doesnt_return_result() const { return that(result).is_equal_to(false); }
1140        match_expectation exports_error() const { return that(error).does_differ_from_NULL(); }
1141        match_expectation doesnt_export_error() const { return that(error).is_equal_to_NULL(); }
1142        match_expectation exports_error_containing(const char *expected_part) const {
1143            return error ? that(error).does_contain(expected_part) : exports_error();
1144        }
1145
1146        match_expectation either_result_or_error() const { return exactly(1).of(returns_result(), exports_error()); }
1147
1148        match_expectation does_neither_return_result_nor_export_error() const {
1149            return all().of(doesnt_return_result(),
1150                            doesnt_export_error());
1151        }
1152        match_expectation returns_result_and_doesnt_export_error() const {
1153            return all().of(either_result_or_error(),
1154                            returns_result(),
1155                            doesnt_export_error());
1156        }
1157        match_expectation doesnt_return_result_but_exports_error_containing(const char *expected_part) const {
1158            return all().of(either_result_or_error(),
1159                            doesnt_return_result(),
1160                            exports_error_containing(expected_part));
1161        }
1162    };
1163};
1164
1165#define TEST_EXPECT_ERROR_CLEAR() TEST_EXPECTATION(no_forgotten_error_exported())
1166
1167#define TEST_EXPECT_RESULT__NOERROREXPORTED(create_result)                                do { TEST_EXPECT_ERROR_CLEAR(); TEST_EXPECTATION               (calling((create_result)).returns_result_and_doesnt_export_error()); } while(0)
1168#define TEST_EXPECT_RESULT__NOERROREXPORTED__BROKEN(create_result)                        do { TEST_EXPECT_ERROR_CLEAR(); TEST_EXPECTATION__BROKEN_SIMPLE(calling((create_result)).returns_result_and_doesnt_export_error()); } while(0)
1169#define TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS(create_result,expected_part)         do { TEST_EXPECT_ERROR_CLEAR(); TEST_EXPECTATION               (calling((create_result)).doesnt_return_result_but_exports_error_containing(expected_part)); } while(0)
1170#define TEST_EXPECT_NORESULT__ERROREXPORTED_CONTAINS__BROKEN(create_result,expected_part) do { TEST_EXPECT_ERROR_CLEAR(); TEST_EXPECTATION__BROKEN_SIMPLE(calling((create_result)).doesnt_return_result_but_exports_error_containing(expected_part)); } while(0)
1171#define TEST_EXPECT_NORESULT__NOERROREXPORTED(create_result)                              do { TEST_EXPECT_ERROR_CLEAR(); TEST_EXPECTATION               (calling((create_result)).does_neither_return_result_nor_export_error()); } while(0)
1172#define TEST_EXPECT_NORESULT__NOERROREXPORTED__BROKEN(create_result)                      do { TEST_EXPECT_ERROR_CLEAR(); TEST_EXPECTATION__BROKEN_SIMPLE(calling((create_result)).does_neither_return_result_nor_export_error()); } while(0)
1173
1174#define TEST_EXPECT_EQUAL_STRINGCOPY__NOERROREXPORTED(create_strcopy,expected_result) do {      \
1175        char *result;                                                                           \
1176        TEST_EXPECT_RESULT__NOERROREXPORTED(result = create_strcopy);                           \
1177        TEST_EXPECT_EQUAL(result, expected_result);                                             \
1178        free(result);                                                                           \
1179    } while(0)
1180
1181#define TEST_EXPECT_EQUAL_STRINGCOPY__NOERROREXPORTED__BROKEN(create_strcopy,wanted,got) do {   \
1182        char *result;                                                                           \
1183        TEST_EXPECT_RESULT__NOERROREXPORTED(result = create_strcopy);                           \
1184        TEST_EXPECT_EQUAL__BROKEN(result, wanted, got);                                         \
1185        free(result);                                                                           \
1186    } while(0)
1187
1188#endif
1189// --------------------------------------------------------------------------------
1190// TEST_EXPECT_SEGFAULT and TEST_EXPECT_CODE_ASSERTION_FAILS
1191// only work if binary is linked with ARBDB
1192
1193#ifdef ENABLE_CRASH_TESTS
1194# ifdef ARB_CORE_H
1195
1196const bool DOES_SEGFAULT       = true;
1197const bool DOESNT_SEGFAULT     = false;
1198const bool CALL_WILL_SEGFAULT  = true;
1199const bool CALL_WONT_SEGFAULT  = false;
1200const bool FAILS_ASSERTION     = true;
1201const bool FULFILLS_ASSERTIONS = false;
1202
1203#  ifdef ASSERTION_USED
1204inline arb_test::match_expectation expect_callback(void (*cb)(), bool expect_SEGV, bool expect_assert_fail, bool call_would_SEGV) {
1205    using namespace arb_test;
1206
1207    bool& assertion_failed = test_data().assertion_failed;
1208    bool  old_state        = assertion_failed;
1209
1210    expectation_group expected;
1211    if (call_would_SEGV && GBK_running_on_valgrind()) {
1212        // don't provoke a SEGV when valgrinding
1213        expected.add(that(call_would_SEGV).is_equal_to(expect_SEGV));
1214    }
1215    else {
1216        expected.add(that(GBK_raises_SIGSEGV(cb)).is_equal_to(expect_SEGV));
1217        expected.add(that(assertion_failed).is_equal_to(expect_assert_fail));
1218    }
1219
1220    assertion_failed = old_state;
1221    return all().ofgroup(expected);
1222}
1223#  else
1224inline arb_test::match_expectation expect_callback(void (*cb)(), bool expect_SEGV, bool call_would_SEGV) {
1225    using namespace arb_test;
1226    if (call_would_SEGV && GBK_running_on_valgrind()) {
1227        // don't provoke a SEGV when valgrinding
1228        return that(call_would_SEGV).is_equal_to(expect_SEGV);
1229    }
1230    return that(GBK_raises_SIGSEGV(cb)).is_equal_to(expect_SEGV);
1231}
1232#  endif
1233# endif
1234
1235// Note: Please toggle all permutations of
1236//       * ../ARBDB/adstring.cxx@TEST_TEST_MACROS
1237//       * Makefile.local.setup@VALGRIND
1238//       * and DEBUG/NDEBUG mode in ../config.makefile@DEBUG
1239//       and run tests in adstring.cxx whenever you change the macros below!
1240//
1241// Note for callers:
1242//
1243//   These tests will normally not fail under valgrind. If CALL_WILL_SEGFAULT,
1244//   then the 'cb' will not be called (to avoid valgrind fails).
1245//   Should be no problem, because normally valgrinded unittests run
1246//   ADDITIONALLY to not-valgrinded unittests (where tests WILL fail in case).
1247
1248# ifdef ASSERTION_USED
1249
1250#  define TEST_EXPECT_NO_SEGFAULT(cb)                    TEST_EXPECTATION(expect_callback(cb,         DOESNT_SEGFAULT, FULFILLS_ASSERTIONS, CALL_WONT_SEGFAULT))
1251#  define TEST_EXPECT_NO_SEGFAULT__WANTED(cb)            TEST_EXPECTATION__WANTED(expect_callback(cb, DOESNT_SEGFAULT, FULFILLS_ASSERTIONS, CALL_WILL_SEGFAULT))
1252#  define TEST_EXPECT_CODE_ASSERTION_FAILS(cb)           TEST_EXPECTATION(expect_callback(cb,         DOES_SEGFAULT,   FAILS_ASSERTION,     CALL_WILL_SEGFAULT))
1253#  define TEST_EXPECT_CODE_ASSERTION_FAILS__WANTED(cb)   TEST_EXPECTATION__WANTED(expect_callback(cb, DOES_SEGFAULT,   FAILS_ASSERTION,     CALL_WONT_SEGFAULT))
1254#  define TEST_EXPECT_CODE_ASSERTION_FAILS__UNWANTED(cb) TEST_EXPECT_NO_SEGFAULT__WANTED(cb)
1255#  define TEST_EXPECT_SEGFAULT(cb)                       TEST_EXPECTATION(expect_callback(cb,         DOES_SEGFAULT,   FULFILLS_ASSERTIONS, CALL_WILL_SEGFAULT))
1256#  define TEST_EXPECT_SEGFAULT__WANTED(cb)               TEST_EXPECTATION__WANTED(expect_callback(cb, DOES_SEGFAULT,   FULFILLS_ASSERTIONS, CALL_WONT_SEGFAULT))
1257#  define TEST_EXPECT_SEGFAULT__UNWANTED(cb)             TEST_EXPECT_NO_SEGFAULT__WANTED(cb)
1258
1259# else // ENABLE_CRASH_TESTS but no ASSERTION_USED (test segfaults in NDEBUG mode)
1260
1261#  define TEST_EXPECT_NO_SEGFAULT(cb)                    TEST_EXPECTATION(expect_callback(cb,         DOESNT_SEGFAULT, CALL_WONT_SEGFAULT))
1262#  define TEST_EXPECT_NO_SEGFAULT__WANTED(cb)            TEST_EXPECTATION__WANTED(expect_callback(cb, DOESNT_SEGFAULT, CALL_WILL_SEGFAULT))
1263#  define TEST_EXPECT_CODE_ASSERTION_FAILS(cb)
1264#  define TEST_EXPECT_CODE_ASSERTION_FAILS__WANTED(cb)
1265#  define TEST_EXPECT_CODE_ASSERTION_FAILS__UNWANTED(cb)
1266#  define TEST_EXPECT_SEGFAULT(cb)                       TEST_EXPECTATION(expect_callback(cb,         DOES_SEGFAULT,   CALL_WILL_SEGFAULT))
1267#  define TEST_EXPECT_SEGFAULT__WANTED(cb)               TEST_EXPECTATION__WANTED(expect_callback(cb, DOES_SEGFAULT,   CALL_WONT_SEGFAULT))
1268#  define TEST_EXPECT_SEGFAULT__UNWANTED(cb)             TEST_EXPECT_NO_SEGFAULT__WANTED(cb)
1269
1270# endif
1271
1272#else // not ENABLE_CRASH_TESTS (i.e. skip these tests completely)
1273
1274# define TEST_EXPECT_NO_SEGFAULT(cb)
1275# define TEST_EXPECT_NO_SEGFAULT__WANTED(cb)
1276# define TEST_EXPECT_CODE_ASSERTION_FAILS(cb)
1277# define TEST_EXPECT_CODE_ASSERTION_FAILS__WANTED(cb)
1278# define TEST_EXPECT_CODE_ASSERTION_FAILS__UNWANTED(cb)
1279# define TEST_EXPECT_SEGFAULT(cb)
1280# define TEST_EXPECT_SEGFAULT__WANTED(cb)
1281# define TEST_EXPECT_SEGFAULT__UNWANTED(cb)
1282
1283#endif
1284
1285// --------------------------------------------------------------------------------
1286
1287namespace arb_test {
1288    template <typename T, typename U, typename V>
1289    inline void expect_broken(const arb_test::matchable_value<T>& That, const U& want, const V& got, const char *file, int line) {
1290        TEST_EXPECTATION__BROKEN_AT_LOC(That.is_equal_to(want), That.is_equal_to(got), file, line);
1291    }
1292};
1293
1294#define TEST_EXPECT_EQUAL(expr,want)             TEST_EXPECTATION(that(expr).is_equal_to(want))
1295#define TEST_EXPECT_EQUAL__BROKEN(expr,want,got) do{ using namespace arb_test; expect_broken(that(expr), want, got, __FILE__, __LINE__); }while(0)
1296#define TEST_EXPECT_EQUAL__IGNARG(expr,want,ign) TEST_EXPECTATION(that(expr).is_equal_to(want))
1297
1298#define TEST_EXPECT_SIMILAR(expr,want,epsilon)         TEST_EXPECTATION(that(expr).fulfills(epsilon_similar(epsilon), want))
1299#define TEST_EXPECT_SIMILAR__BROKEN(expr,want,epsilon) TEST_EXPECTATION__BROKEN_SIMPLE(that(expr).fulfills(epsilon_similar(epsilon), want))
1300
1301#define TEST_EXPECT_DIFFERENT(expr,want)         TEST_EXPECTATION(that(expr).does_differ_from(want));
1302#define TEST_EXPECT_DIFFERENT__BROKEN(expr,want) TEST_EXPECTATION__BROKEN_SIMPLE(that(expr).does_differ_from(want));
1303
1304#define TEST_EXPECT_LESS(val,ref)               TEST_EXPECTATION(that(val).is_less_than(ref))
1305#define TEST_EXPECT_LESS__BROKEN(val,ref)       TEST_EXPECTATION__BROKEN_SIMPLE(that(val).is_less_than(ref))
1306#define TEST_EXPECT_MORE(val,ref)               TEST_EXPECTATION(that(val).is_more_than(ref))
1307#define TEST_EXPECT_MORE__BROKEN(val,ref)       TEST_EXPECTATION__BROKEN_SIMPLE(that(val).is_more_than(ref))
1308#define TEST_EXPECT_LESS_EQUAL(val,ref)         TEST_EXPECTATION(that(val).is_less_or_equal(ref))
1309#define TEST_EXPECT_LESS_EQUAL__BROKEN(val,ref) TEST_EXPECTATION__BROKEN_SIMPLE(that(val).is_less_or_equal(ref))
1310#define TEST_EXPECT_MORE_EQUAL(val,ref)         TEST_EXPECTATION(that(val).is_more_or_equal(ref))
1311#define TEST_EXPECT_MORE_EQUAL__BROKEN(val,ref) TEST_EXPECTATION__BROKEN_SIMPLE(that(val).is_more_or_equal(ref))
1312
1313#define TEST_EXPECT_IN_RANGE(val,lower,higher)         TEST_EXPECTATION(all().of(that(val).is_more_or_equal(lower), that(val).is_less_or_equal(higher)))
1314#define TEST_EXPECT_IN_RANGE__BROKEN(val,lower,higher) TEST_EXPECTATION__BROKEN_SIMPLE(all().of(that(val).is_more_or_equal(lower), that(val).is_less_or_equal(higher)))
1315
1316#define TEST_EXPECT_CONTAINS(str,part)         TEST_EXPECTATION(that(str).does_contain(part))
1317#define TEST_EXPECT_CONTAINS__BROKEN(str,part) TEST_EXPECTATION__BROKEN_SIMPLE(that(str).does_contain(part))
1318
1319#define TEST_EXPECT_DOESNT_CONTAIN(str,part)         TEST_EXPECTATION(that(str).doesnt_contain(part))
1320#define TEST_EXPECT_DOESNT_CONTAIN__BROKEN(str,part) TEST_EXPECTATION__BROKEN_SIMPLE(that(str).doesnt_contain(part))
1321
1322#define TEST_EXPECT_NULL(n)                TEST_EXPECT_EQUAL(n, (typeof(n))NULp)
1323#define TEST_EXPECT_NULL__BROKEN(n,got)    TEST_EXPECT_EQUAL__BROKEN(n, (typeof(n))NULp, got)
1324#define TEST_EXPECT_NULL__BROKEN_SIMPLE(n) TEST_EXPECTATION__BROKEN_SIMPLE(that(n).is_equal_to((typeof(n))NULp))
1325#define TEST_REJECT_NULL(n)                TEST_EXPECT_DIFFERENT(n, (typeof(n))NULp)
1326#define TEST_REJECT_NULL__BROKEN(n)        TEST_EXPECT_DIFFERENT__BROKEN(n, (typeof(n))NULp)
1327
1328#define TEST_EXPECT(cond)         TEST_EXPECTATION(that(cond).is_equal_to(true))
1329#define TEST_EXPECT__BROKEN(cond) TEST_EXPECTATION__BROKEN_SIMPLE(that(cond).is_equal_to(true))
1330#define TEST_REJECT(cond)         TEST_EXPECTATION(that(cond).is_equal_to(false))
1331#define TEST_REJECT__BROKEN(cond) TEST_EXPECTATION__BROKEN_SIMPLE(that(cond).is_equal_to(false))
1332
1333// test class Validity:
1334#define TEST_VALIDITY(valid)             TEST_EXPECT_NULL((valid).why_not())
1335#define TEST_VALIDITY__BROKEN(valid,why) TEST_EXPECT_NULL__BROKEN((valid).why_not(),why)
1336
1337// test array contents
1338#define TEST_EXPECT_STRARRAY_CONTAINS(strings,separator,expected) do{   \
1339        char *joined = GBT_join_strings(strings,separator);             \
1340        TEST_EXPECT_EQUAL(joined, expected);                            \
1341        free(joined);                                                   \
1342    }while(0)
1343
1344#define TEST_EXPECT_STRARRAY_CONTAINS__BROKEN(strings,separator,want,got) do{   \
1345        char *joined = GBT_join_strings(strings,separator);                     \
1346        TEST_EXPECT_EQUAL__BROKEN(joined, want, got);                           \
1347        free(joined);                                                           \
1348    }while(0)
1349
1350// --------------------------------------------------------------------------------
1351// the macros in this section only work when
1352// - tested module depends on ARBDB and
1353// - some ARBDB header has been included
1354// Otherwise the section is skipped completely.
1355//
1356// @@@ ARBDB->ARBCORE later
1357
1358#ifdef ARB_DIFF_H
1359
1360namespace arb_test {
1361    inline bool memory_is_equal(const void *mem1, const void *mem2, size_t size) {
1362        FlushedOutputNoLF yes;
1363        return ARB_test_mem_equal(reinterpret_cast<const unsigned char *>(mem1),
1364                                  reinterpret_cast<const unsigned char *>(mem2), size, 0) == size;
1365    }
1366    inline bool files_are_equal(const char *file1, const char *file2) {
1367        FlushedOutputNoLF yes;
1368        return ARB_files_are_equal(file1, file2);
1369    }
1370    inline bool files_differ(const char *file1, const char *file2) {
1371        FlushedOutputNoLF yes;
1372        return ARB_files_differ(file1, file2);
1373    }
1374    inline bool textfiles_have_difflines(const char *fgot, const char *fwant, int expected_difflines) {
1375        FlushedOutputNoLF yes;
1376        return ARB_textfiles_have_difflines(fwant, fgot, expected_difflines, TDM_DIFF_LINECOUNT);
1377    }
1378    inline bool textfiles_dont_have_difflines(const char *fgot, const char *fwant, int unexpected_difflines) {
1379        FlushedOutputNoLF yes;
1380        return ARB_textfiles_have_difflines(fwant, fgot, unexpected_difflines, TDM_NOT_DIFF_LINECOUNT);
1381    }
1382    inline bool textfiles_have_difflines_ignoreDates(const char *fgot, const char *fwant, int expected_difflines) {
1383        FlushedOutputNoLF yes;
1384        return ARB_textfiles_have_difflines(fwant, fgot, expected_difflines, TDM_IGNORE_TIMESTAMPS);
1385    }
1386};
1387
1388#define TEST_COPY_FILE(src, dst) TEST_EXPECT_NO_ERROR(GB_copy_file(src, dst))
1389#define TEST_DUMP_FILE(src, dst) TEST_EXPECT(system(GBS_global_string("hexdump -C '%s' > '%s'", src, dst)) == 0)
1390
1391// Note: parameter order convention for the following calls is: 'createdresultfile, expectedresultfile, ...'
1392
1393#define TEST_EXPECT_TEXTFILE_DIFFLINES(fgot,fwant,diff)         TEST_EXPECT(arb_test::textfiles_have_difflines(fgot,fwant, diff))
1394#define TEST_EXPECT_TEXTFILE_DIFFLINES__BROKEN(fgot,fwant,diff) TEST_EXPECT__BROKEN(arb_test::textfiles_have_difflines(fgot,fwant, diff))
1395
1396#define TEST_EXPECT_TEXTFILE_DIFFLINES_IGNORE_DATES(fgot,fwant,diff)         TEST_EXPECT(arb_test::textfiles_have_difflines_ignoreDates(fgot,fwant, diff))
1397#define TEST_EXPECT_TEXTFILE_DIFFLINES_IGNORE_DATES__BROKEN(fgot,fwant,diff) TEST_EXPECT__BROKEN(arb_test::textfiles_have_difflines_ignoreDates(fgot,fwant, diff))
1398
1399#define TEST_EXPECT_FILES_EQUAL(f1,f2)                  TEST_EXPECT(arb_test::files_are_equal(f1,f2))
1400#define TEST_EXPECT_FILES_EQUAL__BROKEN(f1,f2)          TEST_EXPECT__BROKEN(arb_test::files_are_equal(f1,f2))
1401#define TEST_EXPECT_TEXTFILES_EQUAL(fgot,fwant)         TEST_EXPECT_TEXTFILE_DIFFLINES(fgot,fwant,0)
1402#define TEST_EXPECT_TEXTFILES_EQUAL__BROKEN(fgot,fwant) TEST_EXPECT_TEXTFILE_DIFFLINES__BROKEN(fgot,fwant,0)
1403
1404#define TEST_EXPECT_FILES_DIFFER(f1,f2)                  TEST_EXPECT(arb_test::files_differ(f1,f2))
1405#define TEST_EXPECT_FILES_DIFFER__BROKEN(f1,f2)          TEST_EXPECT__BROKEN(arb_test::files_differ(f1,f2))
1406#define TEST_EXPECT_TEXTFILES_DIFFER(fgot,fwant)         TEST_EXPECT(arb_test::textfiles_dont_have_difflines(fgot,fwant,0))
1407#define TEST_EXPECT_TEXTFILES_DIFFER__BROKEN(fgot,fwant) TEST_EXPECT__BROKEN(arb_test::textfiles_dont_have_difflines(fgot,fwant,0))
1408
1409#define TEST_EXPECT_MEM_EQUAL(m1,m2,size)         TEST_EXPECT(arb_test::memory_is_equal(m1,m2,size))
1410#define TEST_EXPECT_MEM_EQUAL__BROKEN(m1,m2,size) TEST_EXPECT__BROKEN(arb_test::memory_is_equal(m1,m2,size))
1411
1412#else
1413
1414#define WARN_MISS_ARBDIFF() need_include__arb_diff_h__BEFORE__test_unit_h
1415
1416#define TEST_EXPECT_TEXTFILE_DIFFLINES(fgot,fwant,diff)         WARN_MISS_ARBDIFF()
1417#define TEST_EXPECT_TEXTFILE_DIFFLINES__BROKEN(fgot,fwant,diff) WARN_MISS_ARBDIFF()
1418
1419#define TEST_EXPECT_TEXTFILE_DIFFLINES_IGNORE_DATES(fgot,fwant,diff)         WARN_MISS_ARBDIFF()
1420#define TEST_EXPECT_TEXTFILE_DIFFLINES_IGNORE_DATES__BROKEN(fgot,fwant,diff) WARN_MISS_ARBDIFF()
1421
1422#define TEST_EXPECT_FILES_EQUAL(f1,f2)                  WARN_MISS_ARBDIFF()
1423#define TEST_EXPECT_FILES_EQUAL__BROKEN(f1,f2)          WARN_MISS_ARBDIFF()
1424#define TEST_EXPECT_TEXTFILES_EQUAL(fgot,fwant)         WARN_MISS_ARBDIFF()
1425#define TEST_EXPECT_TEXTFILES_EQUAL__BROKEN(fgot,fwant) WARN_MISS_ARBDIFF()
1426
1427#define TEST_EXPECT_FILES_DIFFER(f1,f2)                  WARN_MISS_ARBDIFF()
1428#define TEST_EXPECT_FILES_DIFFER__BROKEN(f1,f2)          WARN_MISS_ARBDIFF()
1429#define TEST_EXPECT_TEXTFILES_DIFFER(fgot,fwant)         WARN_MISS_ARBDIFF()
1430#define TEST_EXPECT_TEXTFILES_DIFFER__BROKEN(fgot,fwant) WARN_MISS_ARBDIFF()
1431
1432#define TEST_EXPECT_MEM_EQUAL(m1,m2,size)         WARN_MISS_ARBDIFF()
1433#define TEST_EXPECT_MEM_EQUAL__BROKEN(m1,m2,size) WARN_MISS_ARBDIFF()
1434
1435#define memory_is_equal(m1,m2,size)                    WARN_MISS_ARBDIFF()
1436#define files_are_equal(f1,f2)                         WARN_MISS_ARBDIFF()
1437#define textfiles_have_difflines(f1,f2,ed)             WARN_MISS_ARBDIFF()
1438#define textfiles_have_difflines_ignoreDates(f1,f2,ed) WARN_MISS_ARBDIFF()
1439
1440#endif // ARB_DIFF_H
1441
1442// --------------------------------------------------------------------------------
1443// The macros in this section only work when
1444// - tested module depends on ARBDB and
1445// - TreeNode.h has been included
1446// Otherwise the section is skipped completely.
1447
1448#ifdef TREENODE_H
1449
1450namespace arb_test {
1451    inline match_expectation expect_newick_equals(NewickFormat format, const TreeNode *tree, const char *expected_newick) {
1452        char              *newick   = GBT_tree_2_newick(tree, format, false);
1453        match_expectation  expected = that(newick).is_equal_to(expected_newick);
1454        free(newick);
1455        return expected;
1456    }
1457    inline match_expectation saved_newick_equals(NewickFormat format, GBDATA *gb_main, const char *treename, const char *expected_newick) {
1458        expectation_group  expected;
1459        GB_transaction     ta(gb_main);
1460        TreeNode          *tree = GBT_read_tree(gb_main, treename, new SimpleRoot);
1461
1462        expected.add(that(tree).does_differ_from_NULL());
1463        if (tree) {
1464            expected.add(expect_newick_equals(format, tree, expected_newick));
1465            destroy(tree);
1466        }
1467        return all().ofgroup(expected);
1468    }
1469};
1470
1471#define TEST_EXPECT_NEWICK(format,tree,expected_newick)         TEST_EXPECTATION(arb_test::expect_newick_equals(format, tree, expected_newick))
1472#define TEST_EXPECT_NEWICK__BROKEN(format,tree,expected_newick) TEST_EXPECTATION__BROKEN_SIMPLE(arb_test::expect_newick_equals(format, tree, expected_newick))
1473
1474#define TEST_EXPECT_SAVED_NEWICK(format,gb_main,treename,expected_newick)         TEST_EXPECTATION(arb_test::saved_newick_equals(format, gb_main, treename, expected_newick))
1475#define TEST_EXPECT_SAVED_NEWICK__BROKEN(format,gb_main,treename,expected_newick) TEST_EXPECTATION__BROKEN_SIMPLE(arb_test::saved_newick_equals(format, gb_main, treename, expected_newick))
1476
1477#else
1478
1479#define WARN_MISS_ADTREE() need_include__TreeNode_h__BEFORE__test_unit_h
1480
1481#define TEST_EXPECT_NEWICK(format,tree,expected_newick)         WARN_MISS_ADTREE()
1482#define TEST_EXPECT_NEWICK__BROKEN(format,tree,expected_newick) WARN_MISS_ADTREE()
1483
1484#define TEST_EXPECT_SAVED_NEWICK(format,gb_main,treename,expected_newick)         WARN_MISS_ADTREE()
1485#define TEST_EXPECT_SAVED_NEWICK__BROKEN(format,gb_main,treename,expected_newick) WARN_MISS_ADTREE()
1486
1487#endif
1488
1489// --------------------------------------------------------------------------------
1490
1491#define TEST_SETUP_GLOBAL_ENVIRONMENT(modulename) do {                                                          \
1492        arb_test::test_data().raiseLocalFlag(ANY_SETUP);                                                        \
1493        TEST_EXPECT_NO_ERROR(GBK_system(GBS_global_string("../test_environment setup %s",  (modulename))));     \
1494    } while(0)
1495// cleanup is done (by Makefile.suite) after all unit tests have been run
1496
1497// --------------------------------------------------------------------------------
1498// Some functions do not export information about their source location (esp. when
1499// stabs-format is used).
1500// If that happens the test will fail and print 'INVALID' as result.
1501//
1502// Fix that problem by writing
1503//     TEST_PUBLISH(TEST_something)
1504// just behind the function TEST_something.
1505//
1506// If it cannot be fixed by that use
1507//
1508//     void TEST_something(); // prototype
1509//     TEST_PUBLISH(TEST_something);
1510//     TEST_something() {
1511//         ...
1512//     }
1513
1514#if defined(DEBUG)
1515#define TEST_PUBLISH(testfunction) void publish##testfunction() { testfunction(); }
1516#else // NDEBUG
1517#define TEST_PUBLISH(testfunction)
1518#endif
1519
1520// --------------------------------------------------------------------------------
1521
1522#else
1523#error test_unit.h included twice
1524#endif // TEST_UNIT_H
Note: See TracBrowser for help on using the repository browser.