source: tags/ms_r18q1/UNIT_TESTER/test_unit.h

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