source: tags/ms_r17q3/UNIT_TESTER/test_unit.h

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