source: tags/arb-6.0/UNIT_TESTER/test_unit.h

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