Changeset 8223 for branches

Show
Ignore:
Timestamp:
17/11/11 18:18:07 (6 months ago)
Author:
westram
Message:
Location:
branches/e4fix
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • branches/e4fix/AISC_MKPTPS/Makefile

    r7623 r8223  
    3939mkptypes.o: $(ARBHOME)/INCLUDE/arbtools.h 
    4040mkptypes.o: $(ARBHOME)/INCLUDE/attributes.h 
     41mkptypes.o: $(ARBHOME)/INCLUDE/dupstr.h 
    4142mkptypes.o: $(ARBHOME)/INCLUDE/test_global.h 
    4243mkptypes.o: $(ARBHOME)/INCLUDE/test_unit.h 
  • branches/e4fix/CORE/Makefile

    r8185 r8223  
    134134arb_string.o: arb_string.h 
    135135arb_string.o: $(ARBHOME)/INCLUDE/arb_assert.h 
     136arb_string.o: $(ARBHOME)/INCLUDE/arbtools.h 
    136137arb_string.o: $(ARBHOME)/INCLUDE/attributes.h 
    137138arb_string.o: $(ARBHOME)/INCLUDE/dupstr.h 
    138139arb_string.o: $(ARBHOME)/INCLUDE/test_global.h 
     140arb_string.o: $(ARBHOME)/INCLUDE/test_unit.h 
    139141 
    140142pos_range.o: arb_core.h 
     
    142144pos_range.o: pos_range.h 
    143145pos_range.o: $(ARBHOME)/INCLUDE/arb_assert.h 
     146pos_range.o: $(ARBHOME)/INCLUDE/arbtools.h 
    144147pos_range.o: $(ARBHOME)/INCLUDE/attributes.h 
    145148pos_range.o: $(ARBHOME)/INCLUDE/dupstr.h 
  • branches/e4fix/CORE/arb_string.cxx

    r7314 r8223  
    6969 
    7070 
    71  
    72  
     71// -------------------------------------------------------------------------------- 
     72 
     73 
     74#ifdef UNIT_TESTS 
     75 
     76#include <string> 
     77#include <climits> 
     78 
     79#ifndef TEST_UNIT_H 
     80#include <test_unit.h> 
     81#endif 
     82 
     83using namespace std; 
     84 
     85// ---------------------------------------------- 
     86//      some tests for unit-test-code itself 
     87 
     88#define TEST_ASSERT_HEAPCOPY_EQUAL(copy,expected) do {  \ 
     89        char *theCopy = (copy);                         \ 
     90        TEST_ASSERT_EQUAL(theCopy, expected);           \ 
     91        free(theCopy);                                  \ 
     92    } while(0) 
     93 
     94void TEST_arbtest_strf() { 
     95    // tests string formatter from test_unit.h 
     96    using namespace arb_test; 
     97    TEST_ASSERT_HEAPCOPY_EQUAL(StaticCode::strf("<%i>", 7), "<7>"); 
     98    TEST_ASSERT_HEAPCOPY_EQUAL(StaticCode::strf("<%0*i>", 3, 7), "<007>"); 
     99} 
     100 
     101void TEST_arbtest_readable() { 
     102    using namespace arb_test; 
     103 
     104    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy('x')), "'x'"); 
     105    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(static_cast<unsigned char>('x'))), "'x'"); 
     106    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(static_cast<signed char>('x'))), "'x'"); 
     107 
     108    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(true)), "true"); 
     109    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(false)), "false"); 
     110     
     111    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(1)), "1"); 
     112    TEST_ASSERT_HEAPCOPY_EQUAL(val2hex(make_copy(2)), "0x2"); 
     113 
     114    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(3L)), "3"); 
     115    TEST_ASSERT_HEAPCOPY_EQUAL(val2hex(make_copy(4L)), "0x4"); 
     116 
     117    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(5U)), "5"); 
     118    TEST_ASSERT_HEAPCOPY_EQUAL(val2hex(make_copy(6U)), "0x6"); 
     119     
     120    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy("some\ntext\twhich\"special\\chars")), "\"some\\ntext\\twhich\\\"special\\\\chars\""); 
     121    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy("a\1\2\x1a\x7e\x7f\x80\xfe\xff")), "\"a\\1\\2\\x1a~\\x7f\\x80\\xfe\\xff\""); 
     122    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy((const char *)NULL)), "(null)"); 
     123    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy((const unsigned char *)NULL)), "(null)"); 
     124    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy((const signed char *)NULL)), "(null)"); 
     125 
     126    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(1.7)), "1.700000"); 
     127    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(177.0e20)),  "17699999999999998951424.000000"); 
     128    TEST_ASSERT_HEAPCOPY_EQUAL(val2readable(make_copy(177.0e20F)), "17699999967695435988992.000000"); 
     129} 
     130 
     131void TEST_arbtest_copyable() { 
     132    using namespace arb_test; 
     133 
     134    int         i = 7; 
     135    const char *s = "servas"; 
     136 
     137    TEST_ASSERT(make_copy(i) == make_copy(7)); 
     138 
     139    TEST_ASSERT(strcmp(make_copy(s), make_copy("servas")) == 0); 
     140} 
     141 
     142#define TEST_DESCRIPTIONS(d, tt, tf, ft, ff) do {               \ 
     143        TEST_ASSERT_EQUAL((d).make(true, true), (tt));   \ 
     144        TEST_ASSERT_EQUAL((d).make(true, false), (tf));  \ 
     145        TEST_ASSERT_EQUAL((d).make(false, true), (ft));  \ 
     146        TEST_ASSERT_EQUAL((d).make(false, false), (ff)); \ 
     147    } while(0) 
     148 
     149#define TEST_SIMPLE_DESCRIPTIONS(d, ae, nae) TEST_DESCRIPTIONS(d, ae, nae, nae, ae) 
     150 
     151void TEST_arbtest_predicate_description() { 
     152    TEST_SIMPLE_DESCRIPTIONS(predicate_description("similar"), "is similar", "isnt similar"); 
     153    TEST_SIMPLE_DESCRIPTIONS(predicate_description("repairs"), "repairs", "doesnt repair"); 
     154 
     155    TEST_DESCRIPTIONS(predicate_description("equals", "differs"), 
     156                      "equals", "doesnt equal", 
     157                      "doesnt differ", "differs"); 
     158 
     159    TEST_DESCRIPTIONS(predicate_description("less_than", "more_than"), 
     160                      "is less_than", "isnt less_than", 
     161                      "isnt more_than", "is more_than"); 
     162} 
     163 
     164void TEST_arbtest_expectations() { 
     165    // used to TDD expectations 
     166    using namespace arb_test; 
     167 
     168    string apple       = "Apfel"; 
     169    string pear        = "Birne"; 
     170    string boskop      = apple; 
     171    string pomegranate = "Granatapfel"; 
     172 
     173    TEST_EXPECT(that(apple).equals("Apfel")); 
     174     
     175    TEST_EXPECT(that(apple).differs(pear)); 
     176    TEST_EXPECT(that(apple).equals(boskop)); 
     177    TEST_EXPECT(wrong(that(pomegranate).equals(apple))); 
     178 
     179    match_expectation ff1 = that(1.0).equals(2-1); 
     180    match_expectation ff2 = that(boskop).equals(apple); 
     181    match_expectation ff3 = that(apple).equals(apple); 
     182 
     183    match_expectation nf1 = that(apple).equals(pear); 
     184    match_expectation nf2 = that(pomegranate).equals(apple); 
     185    match_expectation nf3 = that(apple).differs(boskop); 
     186 
     187    match_expectation a1 = all().of(ff1); 
     188    match_expectation a2 = all().of(ff1, ff2); 
     189    match_expectation a3 = all().of(ff1, ff2, ff3); 
     190 
     191    TEST_EXPECT(a1); 
     192    TEST_EXPECT(a2); 
     193    TEST_EXPECT(a3); 
     194 
     195    match_expectation n1 = none().of(ff1); 
     196    match_expectation n2 = none().of(ff1, ff2); 
     197    match_expectation n3 = none().of(ff1, ff2, ff3); 
     198 
     199    TEST_EXPECT(wrong(none().of(that(boskop).equals(apple)))); 
     200    TEST_EXPECT(wrong(n1)); 
     201    TEST_EXPECT(wrong(n2)); 
     202    TEST_EXPECT(wrong(n3)); 
     203 
     204    TEST_EXPECT(atleast(1).of(a1)); 
     205    TEST_EXPECT(atleast(1).of(a1, n1)); 
     206    TEST_EXPECT(atleast(1).of(n2, a1, n1)); 
     207 
     208    TEST_EXPECT(wrong(atleast(2).of(a1, n1, n2))); 
     209    TEST_EXPECT(wrong(atleast(2).of(a1, n1))); 
     210    TEST_EXPECT(wrong(atleast(2).of(a1))); // impossible 
     211 
     212    TEST_EXPECT(atmost(2).of(a1)); 
     213    TEST_EXPECT(atmost(2).of(a1, a2)); 
     214    TEST_EXPECT(atmost(2).of(a1, a2, n1)); 
     215    TEST_EXPECT(atmost(2).of(a1, n1, n2)); 
     216    TEST_EXPECT(atmost(2).of(n1, n2)); 
     217    TEST_EXPECT(wrong(atmost(2).of(a1, a2, a3))); 
     218 
     219    TEST_EXPECT(exacly(1).of(ff1, nf1, nf2)); 
     220    TEST_EXPECT(wrong(exacly(1).of(nf1, nf2))); 
     221    TEST_EXPECT(wrong(exacly(1).of(nf1, nf2, nf3))); 
     222    TEST_EXPECT(wrong(exacly(1).of(ff1, ff2, nf2))); 
     223    TEST_EXPECT(wrong(exacly(1).of(ff1, ff2, ff3))); 
     224 
     225} 
     226 
     227void TEST_replace_old_TEST_ASSERTS_by_expectations() { 
     228    // test various string-types are matchable (w/o casts) 
     229    { 
     230        const char *car_ccp = "Alfa"; 
     231        char       *car_cp  = strdup("Alfa"); 
     232        string      car_str("Alfa"); 
     233 
     234        TEST_ASSERT_EQUAL(car_ccp, "Alfa"); 
     235        TEST_ASSERT_EQUAL(car_cp, "Alfa"); 
     236        TEST_ASSERT_EQUAL(car_str, "Alfa"); 
     237 
     238        TEST_ASSERT_EQUAL("Alfa", car_ccp); 
     239        TEST_ASSERT_EQUAL("Alfa", car_cp); 
     240        TEST_ASSERT_EQUAL("Alfa", car_str); 
     241 
     242        TEST_ASSERT_EQUAL(car_cp, car_ccp); 
     243        TEST_ASSERT_EQUAL(car_cp, car_str); 
     244        TEST_ASSERT_EQUAL(car_ccp, car_cp); 
     245        TEST_ASSERT_EQUAL(car_ccp, car_str); 
     246        TEST_ASSERT_EQUAL(car_str, car_cp); 
     247        TEST_ASSERT_EQUAL(car_str, car_ccp); 
     248 
     249        char *null = NULL; 
     250        TEST_ASSERT_NULL(NULL); 
     251        TEST_ASSERT_NULL(null); 
     252 
     253        TEST_ASSERT_CONTAINS(car_ccp, "lf"); 
     254        TEST_ASSERT_CONTAINS(car_cp, "fa"); 
     255        TEST_ASSERT_CONTAINS(car_str, "Al"); 
     256 
     257        free(car_cp); 
     258    } 
     259 
     260    // test various numeric types are matchable 
     261 
     262    { 
     263        short unsigned su = 7; 
     264        short          s  = -su; 
     265 
     266        unsigned iu = su; 
     267        int      i  = -iu; 
     268 
     269        long unsigned lu = (long unsigned)INT_MAX+3; 
     270        long          l  = -lu; 
     271 
     272        float  f = s; 
     273        double d = i; 
     274 
     275        TEST_ASSERT_EQUAL(s, -7); 
     276        TEST_ASSERT_EQUAL(i, -7); 
     277 
     278        TEST_ASSERT_EQUAL(su, 7);  TEST_ASSERT_EQUAL(iu, 7); 
     279        TEST_ASSERT_EQUAL(su, 7U); TEST_ASSERT_EQUAL(iu, 7U); 
     280        TEST_ASSERT_EQUAL(su, 7L); TEST_ASSERT_EQUAL(iu, 7L); 
     281 
     282        TEST_ASSERT_EQUAL(s, -su); TEST_ASSERT_EQUAL(s, -iu); 
     283        TEST_ASSERT_EQUAL(i, -iu); TEST_ASSERT_EQUAL(i, -su); 
     284        TEST_ASSERT_EQUAL(l, -lu); 
     285 
     286        TEST_ASSERT_EQUAL(f, d); 
     287        TEST_ASSERT_EQUAL(d, f); 
     288    } 
     289 
     290    TEST_ASSERT_ZERO(7-7); 
     291} 
     292 
     293// --- simulate user_type (which may be defined anywhere) --- 
     294class user_type { 
     295    int x, y; 
     296public: 
     297    user_type(int X, int Y) : x(X), y(Y) {} 
     298 
     299    int get_x() const { return x; } 
     300    int get_y() const { return y; } 
     301 
     302    user_type flipped() const { return user_type(y,x); } 
     303 
     304    int quadrant() const { 
     305        if (x == 0 || y == 0) return 0; // on axis 
     306        if (y>0) return x<0 ? 2 : 1; 
     307        return x<0 ? 3 : 4; 
     308    } 
     309}; 
     310// --- end of user_type --- 
     311 
     312// helpers needed for tests: 
     313inline bool operator == (const user_type& u1, const user_type& u2) { return u1.get_x() == u2.get_x() && u1.get_y() == u2.get_y(); } 
     314inline char *val2readable(const user_type& u) { return arb_test::StaticCode::strf("user_type(%i,%i)", u.get_x(), u.get_y()); } 
     315inline bool in_same_quadrant(const user_type& u1, const user_type& u2) { return u1.quadrant() == u2.quadrant(); } 
     316 
     317void TEST_user_type_with_expectations() { 
     318    user_type ut1(3, 4); 
     319    user_type ut12(4, 4); 
     320    user_type ut2(-4, 4); 
     321    user_type ut3(-4, -8); 
     322    user_type ut4(4, -8); 
     323 
     324    TEST_EXPECT(that(ut1).differs(ut12)); 
     325    TEST_EXPECT(that(ut12).equals(ut12.flipped())); 
     326    TEST_EXPECT(that(ut1).differs(ut1.flipped())); 
     327 
     328    TEST_EXPECT(that(ut1).is(in_same_quadrant, ut12)); 
     329    TEST_EXPECT(none().of(that(ut1).is(in_same_quadrant, ut2), 
     330                          that(ut2).is(in_same_quadrant, ut3), 
     331                          that(ut3).is(in_same_quadrant, ut4))); 
     332} 
     333 
     334void TEST_similarity() { 
     335    double d1      = 0.7531; 
     336    double epsilon = 0.00001; 
     337    double d2      = d1-epsilon*0.6; 
     338    double d3      = d1+epsilon*0.6; 
     339 
     340    TEST_EXPECT(that(d1).is(epsilon_similar(epsilon), d2)); 
     341    TEST_EXPECT(that(d1).is(epsilon_similar(epsilon), d3)); 
     342    TEST_EXPECT(that(d2).is_not(epsilon_similar(epsilon), d3)); 
     343 
     344    TEST_ASSERT_SIMILAR(d1, d2, epsilon); 
     345    TEST_ASSERT_SIMILAR(d1, d3, epsilon); 
     346} 
     347 
     348void TEST_less_equal() { 
     349    int x = 7; 
     350    int y = 8; 
     351    int z = 9; 
     352 
     353    // less/more etc 
     354 
     355    TEST_EXPECT(that(x).less_than(y)); 
     356    TEST_EXPECT(that(x).less_or_equal(y)); 
     357    TEST_EXPECT(that(x).less_or_equal(x)); 
     358     
     359    TEST_EXPECT(that(y).more_than(x)); 
     360    TEST_EXPECT(that(y).more_or_equal(x)); 
     361    TEST_EXPECT(that(y).more_or_equal(y)); 
     362 
     363    TEST_ASSERT_LOWER_EQUAL(x, y); 
     364    TEST_ASSERT_LOWER_EQUAL(x, x); 
     365    TEST_ASSERT_LOWER(x, y); 
     366    TEST_ASSERT_IN_RANGE(y, x, z); 
     367} 
     368 
     369#endif // UNIT_TESTS 
     370 
     371// -------------------------------------------------------------------------------- 
     372 
     373 
  • branches/e4fix/SL/PRONUC/Makefile

    r7423 r8223  
    7979iupac.o: $(ARBHOME)/INCLUDE/arb_core.h 
    8080iupac.o: $(ARBHOME)/INCLUDE/arbdb_base.h 
     81iupac.o: $(ARBHOME)/INCLUDE/arbtools.h 
    8182iupac.o: $(ARBHOME)/INCLUDE/dupstr.h 
    8283iupac.o: $(ARBHOME)/INCLUDE/test_global.h 
  • branches/e4fix/UNIT_TESTER/TestEnvironment.cxx

    r8177 r8223  
    183183        if (!fp) { 
    184184            GB_ERROR error = GB_IO_error("creating flag", flagfile); 
    185             StaticCode::errorf(__FILE__, __LINE__, "%s\n", error); 
     185            HERE.errorf(true, "%s\n", error); 
    186186        } 
    187187        fclose(fp); 
     
    197197        if (res != 0) { 
    198198            GB_ERROR error = GB_IO_error("unlinking", flagfile); 
    199             StaticCode::errorf(__FILE__, __LINE__, "%s\n", error); 
     199            HERE.errorf(true, "%s\n", error); 
    200200        } 
    201201        env_assert(!flagFileExists()); 
  • branches/e4fix/UNIT_TESTER/test_unit.h

    r8104 r8223  
    1616#include <arb_assert.h> 
    1717#endif 
     18#ifndef ARBTOOLS_H 
     19#include <arbtools.h> 
     20#endif 
    1821#ifndef _GLIBCXX_CSTDARG 
    1922#include <cstdarg> 
     
    2528#include <errno.h> 
    2629#endif 
     30#ifndef DUPSTR_H 
     31#include <dupstr.h> 
     32#endif 
     33 
     34#if defined(_GLIBCXX_STRING) 
     35#define TESTS_KNOW_STRING 
     36#endif 
     37 
    2738 
    2839#define ENABLE_CRASH_TESTS // comment out this line to get rid of provoked SEGVs (e.g. while debugging test-code) 
    29 // #define TRACE_IS_EQUAL // print calls to numerical is_equal() 
    3040 
    3141/* Note: 
     
    3646 * test is known to fail, but cannot be fixed atm for some reason 
    3747 * 
     48 * Recommended test-assertion is TEST_EXPECT(that(..).xxx()) 
     49 * see examples in test-unit-tests in ../CORE/arb_string.cxx@UNIT_TESTS 
    3850 */ 
    3951 
     
    4456namespace arb_test { 
    4557 
    46     class StaticCode { 
    47         static void vcompiler_msg(const char *filename, int lineno, const char *message_type, const char *format, va_list parg) __attribute__((format(__printf__, 4, 0))) { 
    48             fprintf(stderr, "%s:%i: ", filename, lineno); 
     58    // ------------- 
     59    //      str 
     60 
     61    class str { 
     62        char *s; 
     63    public: 
     64        str() : s(0) {} 
     65        str(const str& other) : s(nulldup(other.s)) {} 
     66        explicit str(char *S) : s(S) {} 
     67        str& operator = (const str& other) { 
     68            freedup(s, other.s); 
     69            return *this; 
     70        } 
     71        str& operator = (char *S) { 
     72            freeset(s, S); 
     73            return *this; 
     74        } 
     75        ~str() { free(s); } 
     76 
     77        bool exists() const { return s; } 
     78        void assign(char *S) { s = S; } 
     79        const char *value() const { return s; } 
     80    }; 
     81 
     82    // ----------------------- 
     83    //      location info 
     84 
     85#define WITHVALISTFROM(format,CODE)  do { va_list parg; va_start(parg, format); CODE; va_end(parg); } while(0) 
     86#define VPRINTFORMAT(format)         WITHVALISTFROM(format, vfprintf(stderr, format, parg)) 
     87#define VCOMPILERMSG(msgtype,format) WITHVALISTFROM(format, vcompiler_msg(msgtype, format, parg)) 
     88 
     89    class locinfo //! stores source code location 
     90    { 
     91        const char *file; 
     92        int         line; 
     93 
     94        __attribute__((format(__printf__, 2, 0))) void vcompiler_msg(const char *message_type, const char *format, va_list parg) const { 
     95            fprintf(stderr, "%s:%i: ", file, line); 
    4996            if (message_type) fprintf(stderr, "%s: ", message_type); 
    5097            vfprintf(stderr, format, parg); 
    5198        } 
    52  
    53 #define WITHVALISTFROM(format,CODE)             do { va_list parg; va_start(parg, format); CODE; va_end(parg); } while(0) 
    54 #define VPRINTFORMAT(format)                    WITHVALISTFROM(format, vfprintf(stderr, format, parg)) 
    55 #define VCOMPILERMSG(file,line,msgtype,format)  WITHVALISTFROM(format, vcompiler_msg(file, line, msgtype, format, parg)) 
    5699         
    57100    public: 
    58  
     101        locinfo() : file(0), line(0) {} 
     102        locinfo(const char *file_, int line_) : file(file_), line(line_) {} 
     103 
     104        bool exists() const { return file; } 
     105 
     106        const char *get_file() const { return file; } 
     107        int get_line() const { return line; } 
     108 
     109        __attribute__((format(printf, 2, 3))) void warningf(const char *format, ...) const { 
     110            GlobalTestData& global = test_data(); 
     111            if (global.show_warnings) { 
     112                FlushedOutput yes; 
     113                VCOMPILERMSG("Warning", format); 
     114                GlobalTestData::print_annotation(); 
     115                global.warnings++; 
     116            } 
     117        } 
     118 
     119        __attribute__((format(printf, 3, 4))) void errorf(bool fail, const char *format, ...) const { 
     120            { 
     121                FlushedOutput yes; 
     122                VCOMPILERMSG("Error", format); 
     123                GlobalTestData::print_annotation(); 
     124            } 
     125            if (fail) TRIGGER_ASSERTION(false); // fake an assertion failure 
     126        } 
     127        __attribute__((format(printf, 3, 4))) void ioerrorf(bool fail, const char *format, ...) const { 
     128            { 
     129                FlushedOutput yes; 
     130                VCOMPILERMSG("Error", format); 
     131                fprintf(stderr, " (errno=%i='%s')", errno, strerror(errno)); 
     132                GlobalTestData::print_annotation(); 
     133            } 
     134            if (fail) TRIGGER_ASSERTION(false); // fake an assertion failure 
     135        } 
     136    }; 
     137 
     138    // -------------------- 
     139    //      StaticCode 
     140 
     141    struct StaticCode { 
    59142        static void printf(const char *format, ...) __attribute__((format(printf, 1, 2))) { 
    60143            FlushedOutputNoLF yes; 
    61144            VPRINTFORMAT(format); 
    62145        } 
    63         static void warningf(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) { 
    64             GlobalTestData& global = test_data(); 
    65             if (global.show_warnings) { 
    66                 FlushedOutput yes; 
    67                 VCOMPILERMSG(filename, lineno, "Warning", format); 
    68                 GlobalTestData::print_annotation(); 
    69                 global.warnings++; 
    70             } 
    71         } 
    72         static void errorf(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) { 
    73             { 
    74                 FlushedOutput yes; 
    75                 VCOMPILERMSG(filename, lineno, "Error", format); 
    76                 GlobalTestData::print_annotation(); 
    77             } 
    78             TRIGGER_ASSERTION(false); // fake an assertion failure 
    79         } 
    80         static void ioerrorf(const char *filename, int lineno, const char *format, ...) __attribute__((format(printf, 3, 4))) { 
    81             { 
    82                 FlushedOutput yes; 
    83                 VCOMPILERMSG(filename, lineno, "Error", format); 
    84                 fprintf(stderr, " (errno=%i='%s')", errno, strerror(errno)); 
    85                 GlobalTestData::print_annotation(); 
    86             } 
    87             TRIGGER_ASSERTION(false); // fake an assertion failure 
    88         } 
    89146#undef VPRINTFORMAT 
    90147#undef VCOMPILERMSG 
    91148#undef WITHVALISTFROM 
    92149 
    93         static void print_readable_string(const char *s, FILE *out) { 
     150        static char *readable_string(const char *s) { 
    94151            // quote like C does! 
    95152            if (s) { 
    96                 fputc('\"', out); 
    97                 for (int i_ = 0; s[i_]; ++i_) { 
    98                     switch (s[i_]) { 
    99                         case '\n': fputs("\\n", out); break; 
    100                         case '\t': fputs("\\t", out); break; 
    101                         case '\"': fputs("\\\"", out); break; 
    102                         case '\\': fputs("\\\\", out); break; 
    103                         default: fputc(s[i_], out); break; 
     153                size_t  len    = strlen(s)*4; 
     154                char   *res = (char*)malloc(len+2+1); 
     155 
     156                int j     = 0; 
     157                res[j++] = '\"'; 
     158                for (int i = 0; s[i]; ++i) { 
     159                    unsigned char c = static_cast<unsigned char>(s[i]); 
     160                    char esc = 0; 
     161                    switch (c) { 
     162                        case '\n': esc = 'n'; break; 
     163                        case '\t': esc = 't'; break; 
     164                        case '\"': esc = '\"'; break; 
     165                        case '\\': esc = '\\'; break; 
     166                        default: if (c<10) esc = c-1+'1'; break; 
     167                    } 
     168                    if (esc) { 
     169                        res[j++] = '\\'; 
     170                        res[j++] = esc; 
     171                    } 
     172                    else { 
     173                        if (c >= 32 && c<127) { 
     174                            res[j++] = c; 
     175                        } 
     176                        else { 
     177                            j += sprintf(res+j, "\\x%02x", int(c)); 
     178                        } 
    104179                    } 
    105180                } 
    106                 fputc('\"', out); 
     181                res[j++] = '\"'; 
     182                res[j++] = 0; 
     183                return res; 
    107184            } 
    108185            else { 
    109                 fputs("(null)", out); 
    110             } 
    111         } 
    112     }; 
    113  
    114     inline void print(int i)                 { fprintf(stderr, "%i", i); } 
    115     inline void print_hex(int i)             { fprintf(stderr, "0x%x", i); } 
    116  
    117     inline void print(long L)                { fprintf(stderr, "%li", L); } 
    118     inline void print_hex(long L)            { fprintf(stderr, "0x%lx", L); } 
    119  
    120     inline void print(const char *s)         { StaticCode::print_readable_string(s, stderr); } 
    121     // no print_hex for strings 
    122  
    123     inline void print(size_t z)              { fprintf(stderr, "%zu", z); } 
    124     inline void print_hex(size_t z)          { fprintf(stderr, "0x%zx", z); } 
    125  
    126     inline void print(unsigned char c)       { fprintf(stderr, "'%c'", c); } 
    127     inline void print_hex(unsigned char c)   { print_hex(size_t(c)); } 
    128  
    129     inline void print(char c)                { print((unsigned char)c); } 
    130     inline void print_hex(char c)            { print_hex((unsigned char)c); } 
     186                return strdup("(null)"); 
     187            } 
     188        } 
     189        static void print_readable_string(const char *s, FILE *out) { 
     190            fputs(str(readable_string(s)).value(), out); 
     191        } 
     192 
     193        static char *vstrf(const char *format, va_list& parg) __attribute__((format(__printf__, 1, 0))) { 
     194            static const size_t max_vstrf_size = 10000; 
     195            static char         vstrf_buf[max_vstrf_size]; 
     196 
     197            int printed = vsnprintf(vstrf_buf, max_vstrf_size, format, parg); 
     198            arb_assert(printed >= 0 && size_t(printed)<max_vstrf_size); 
     199 
     200            char *result    = (char*)malloc(printed+1); 
     201            memcpy(result, vstrf_buf, printed); 
     202            result[printed] = 0; 
     203            return result; 
     204        } 
     205 
     206        static char *strf(const char *format, ...) __attribute__((format(__printf__, 1, 2))) { 
     207            va_list  parg; 
     208            va_start(parg, format); 
     209            char *result = vstrf(format, parg); 
     210            va_end(parg); 
     211            return result; 
     212        } 
     213 
     214    }; 
     215 
     216    inline char *val2readable(bool b) { return strdup(b ? "true" : "false"); } 
     217     
     218    inline char *val2readable(int i) { return StaticCode::strf("%i", i); } 
     219    inline char *val2hex(int i) { return StaticCode::strf("0x%x", i); } 
     220 
     221    inline char *val2readable(long L) { return StaticCode::strf("%li", L); } 
     222    inline char *val2hex(long L) { return StaticCode::strf("0x%lx", L); } 
     223 
     224    inline char *val2readable(size_t z) { return StaticCode::strf("%zu", z); } 
     225    inline char *val2hex(size_t z) { return StaticCode::strf("0x%zx", z); } 
    131226 
    132227    // dont dup size_t: 
    133228#ifdef ARB_64 
    134     inline void print(unsigned u)            { fprintf(stderr, "%u", u); } 
    135     inline void print_hex(unsigned u)        { fprintf(stderr, "0x%x", u); } 
     229    inline char *val2readable(unsigned u) { return StaticCode::strf("%u", u); } 
     230    inline char *val2hex(unsigned u) { return StaticCode::strf("0x%x", u); } 
    136231#else 
    137     inline void print(long unsigned u)       { fprintf(stderr, "%lu", u); } 
    138     inline void print_hex(long unsigned u)   { fprintf(stderr, "0x%lx", u); } 
     232    inline char *val2readable(long unsigned u) { return StaticCode::strf("%lu", u); } 
     233    inline char *val2hex(long unsigned u) { return StaticCode::strf("0x%lx", u); } 
    139234#endif 
     235 
     236    inline char *val2readable(double d) { return StaticCode::strf("%f", d); } 
     237 
     238    inline char *val2readable(unsigned char c) { arb_assert(c); return StaticCode::strf("'%c'", c); } 
     239    inline char *val2readable(const char *s) { return StaticCode::readable_string(s); } 
     240 
     241#ifdef TESTS_KNOW_STRING 
     242    inline char *val2readable(const std::string& s) { return StaticCode::readable_string(s.c_str()); } 
     243#endif 
     244 
     245    template <typename T> inline void print(const T& t) { fputs(val2readable(make_copy(t)), stderr); } 
     246    template <typename T> inline void print_hex(const T& t) { fputs(val2hex(make_copy(t)), stderr); } 
    140247 
    141248    template <typename T1, typename T2> inline void print_pair(T1 t1, T2 t2) { 
    142249        print(t1); 
    143         fputs(", ", stderr); 
     250        fputs(",", stderr); 
    144251        print(t2); 
    145252    } 
     
    150257    } 
    151258 
    152     template <typename T> inline const char *nameoftype(T unspecialized) { 
    153         return specialized_nameoftype(unspecialized);  // define instanciating type below! 
    154     } 
    155  
    156 #define NAMEOFTYPE(type) template <> inline const char * nameoftype<>(type) { return #type; } 
    157     NAMEOFTYPE(bool); 
    158     NAMEOFTYPE(char); 
    159     NAMEOFTYPE(unsigned char); 
    160     NAMEOFTYPE(const char*); 
    161     NAMEOFTYPE(int); 
    162     NAMEOFTYPE(unsigned int); 
    163     NAMEOFTYPE(long int); 
    164     NAMEOFTYPE(long unsigned int); 
    165 #undef NAMEOFTYPE 
    166  
    167  
    168  
    169 #ifdef TRACE_IS_EQUAL 
    170     template <typename T1, typename T2> inline bool bool_traced(const char *name, bool equal, T1 t1, T2 t2) { 
    171         fprintf(stderr, "%-5s = %s(%s ", (equal ? "true" : "false"), name, nameoftype(t1)); 
    172         print(t1); 
    173         fprintf(stderr, ",%s ", nameoftype(t2)); 
    174         print(t2); 
    175         fprintf(stderr, ")\n"); 
    176         return equal; 
    177     } 
    178 #else 
    179     template <typename T1, typename T2> inline bool bool_traced(const char *, bool equal, T1 , T2 ) { 
    180         return equal; 
    181     } 
     259    class epsilon_similar { 
     260        double epsilon; 
     261    public: 
     262        epsilon_similar(double epsilon_) : epsilon(epsilon_) {} 
     263        bool operator()(const double& d1, const double& d2) const { 
     264            double diff = d1-d2; 
     265            if (diff<0.0) diff = -diff; // do not use fabs() here 
     266            return diff <= epsilon; 
     267        } 
     268    }; 
     269 
     270    struct containing { 
     271        bool operator()(const char *str, const char *part) const { return strstr(str, part); } 
     272#if defined(TESTS_KNOW_STRING) 
     273        bool operator()(const std::string& str, const std::string& part) const { return strstr(str.c_str(), part.c_str()); } 
    182274#endif 
    183  
    184     template <typename T1, typename T2> inline bool is_equal(T1 t1, T2 t2) { 
    185         return bool_traced("is_equal", t1 == t2, t1, t2); 
    186     } 
    187     template<> inline bool is_equal<>(const char *s1, const char *s2) { 
    188         return bool_traced("is_equal", (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0), s1, s2); 
    189     } 
    190     template <typename T1, typename T2> inline bool is_less(T1 t1, T2 t2) { 
    191         return bool_traced("is_less", t1 < t2, t1, t2); 
    192     } 
    193  
    194  
    195     template <typename T1, typename T2> inline void print_failed_compare(T1 t1, T2 t2, const char *prefix, const char *infix, const char *suffix) { 
    196         FlushedOutput yes; 
    197         fputs(prefix, stderr); 
    198         print_pair(t1, t2); 
    199         fputs(infix, stderr); 
    200         print_hex_pair(t1, t2); 
    201         fputs(suffix, stderr); 
    202     } 
    203     template <typename T1, typename T2> inline void print_failed_equal(T1 t1, T2 t2) { 
    204         print_failed_compare(t1, t2, "test_equal(", ") (", ") returns false"); 
    205     } 
    206     template <typename T1, typename T2> inline void print_failed_less_equal(T1 t1, T2 t2) { 
    207         print_failed_compare(t1, t2, "test_less_equal(", ") (", ") returns false"); 
    208     } 
    209     template <typename T1, typename T2> inline void print_failed_different(T1 t1, T2 t2) { 
    210         print_failed_compare(t1, t2, "test_different(", ") (", ") returns false"); 
    211     } 
    212  
    213     template<> inline void print_failed_equal<>(const char *s1, const char *s2) { 
    214         FlushedOutput yes; 
    215         fputs("test_equal(", stderr); 
    216         print(s1); 
    217         fputs(",\n           ", stderr); 
    218         print(s2); 
    219         fputs(") returns false", stderr); 
    220     } 
    221     template<> inline void print_failed_different<>(const char *s1, const char *) { 
    222         FlushedOutput yes; 
    223         fputs("test_different(", stderr); 
    224         print(s1); 
    225         fputs(", <same>", stderr); 
    226         fputs(") returns false", stderr); 
    227     } 
    228  
    229     template <typename T1, typename T2> inline bool test_equal(T1 t1, T2 t2) { 
    230         bool equal = is_equal(t1, t2); 
    231         if (!equal) print_failed_equal(t1, t2); 
    232         return equal; 
    233     } 
    234     template <typename T1, typename T2> inline bool test_less_equal(T1 lower, T2 upper) { 
    235         bool less_equal = is_equal(lower, upper) || is_less(lower, upper); 
    236         if (!less_equal) print_failed_less_equal(lower, upper); 
    237         return less_equal; 
    238     } 
    239     template <typename T1, typename T2> inline bool test_different(T1 t1, T2 t2) { 
    240         bool different = !is_equal(t1, t2); 
    241         if (!different) print_failed_different(t1, t2); 
    242         return different; 
    243     } 
    244  
    245 #define ACCEPT_NON_CONST_ARGUMENTS(FUN,TYPE) \ 
    246     template<> inline bool FUN<>(TYPE p1, TYPE p2) { return FUN((const TYPE)p1, (const TYPE)p2); } \ 
    247         template<> inline bool FUN<>(TYPE p1, const TYPE p2) { return FUN((const TYPE)p1, p2); } \ 
    248         template<> inline bool FUN<>(const TYPE p1, TYPE p2) { return FUN(p1, (const TYPE)p2); } 
    249  
    250     ACCEPT_NON_CONST_ARGUMENTS(test_equal, char*); 
    251     ACCEPT_NON_CONST_ARGUMENTS(test_different, char*); 
    252  
    253 #ifdef ARB_64 
    254     typedef long int NULLPTR; 
    255 #else 
    256     typedef int      NULLPTR; 
    257 #endif 
    258      
    259 #define ACCEPT_NULLPTR_ARGUMENTS(FUN,TYPE)         \ 
    260     template<> inline bool FUN<>(TYPE p1, NULLPTR p2) { TEST_ASSERT(!p2); return FUN((const TYPE)p1, (const TYPE)p2); } \ 
    261         template<> inline bool FUN<>(const TYPE p1, NULLPTR p2) { TEST_ASSERT(!p2); return FUN((const TYPE)p1, (const TYPE)p2); } \ 
    262         template<> inline bool FUN<>(NULLPTR p1, TYPE p2) { TEST_ASSERT(!p1); return FUN((const TYPE)p1, (const TYPE)p2); } \ 
    263         template<> inline bool FUN<>(NULLPTR p1, const TYPE p2) { TEST_ASSERT(!p1); return FUN((const TYPE)p1, (const TYPE)p2); } 
    264  
    265     ACCEPT_NULLPTR_ARGUMENTS(test_equal, char*); 
    266     ACCEPT_NULLPTR_ARGUMENTS(test_different, char*); 
    267  
    268     inline bool test_similar(double d1, double d2, double epsilon) { 
    269         double diff = d1-d2; 
    270         if (diff<0.0) diff = -diff; // do not use fabs() here 
    271  
    272         bool in_epsilon_range = diff < epsilon; 
    273         if (!in_epsilon_range) { 
    274             StaticCode::printf("test_similar(%f,%f,%f) returns false\n", d1, d2, epsilon); 
    275         } 
    276         return in_epsilon_range; 
    277     } 
    278  
    279     inline bool test_equal(double d1, double d2) { return test_similar(d1, d2, 0.000001); } 
    280  
    281     inline bool test_strcontains(const char *str, const char *part)  { 
    282         const char *found = strstr(str, part); 
    283         if (!found) StaticCode::printf("string '%s'\ndoes not contain '%s'\n", str, part); 
    284         return found; 
    285     } 
    286      
    287     // inline bool is_equal(double d1, double d2) { 
    288         // return is_similar(d1, d2, 0.000001); 
    289     // } 
     275    }; 
    290276 
    291277    inline bool files_are_equal(const char *file1, const char *file2) { 
     
    364350        return !error; 
    365351    } 
     352 
     353 
     354    // ------------------ 
     355    //      copy 
     356 
     357 
     358    template <typename T> 
     359    class copy //! makes char* copyable, so it can be handled like most other types 
     360    { 
     361        T t; 
     362    public: 
     363        copy(const T& t_) : t(t_) {} 
     364        operator const T&() const { return t; } 
     365    }; 
     366 
     367    template <> 
     368    class copy<const char *> { 
     369        str t; 
     370    public: 
     371        copy(const char *t_) : t(str(t_ ? strdup(t_) : NULL)) {} 
     372        operator const char *() const { return t.value(); } 
     373    }; 
     374 
     375    template <typename T> class copy< copy<T> > { copy(const copy<T>& t_); }; // avoid copies of copies 
     376 
     377    template <typename T> inline copy<T> make_copy(const T& t) { return copy<T>(t); } 
     378 
     379    inline copy<const char *> make_copy(const char *p) { return copy<const char *>(p); } 
     380    inline copy<const char *> make_copy(char *p) { return copy<const char *>(p); } 
     381    inline copy<const char *> make_copy(const unsigned char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } 
     382    inline copy<const char *> make_copy(unsigned char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } 
     383    inline copy<const char *> make_copy(const signed char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } 
     384    inline copy<const char *> make_copy(signed char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } 
     385 
     386    inline copy<unsigned char> make_copy(char p) { return copy<unsigned char>(p); } 
     387    inline copy<unsigned char> make_copy(unsigned char p) { return copy<unsigned char>(p); } 
     388    inline copy<unsigned char> make_copy(signed char p) { return copy<unsigned char>(p); } 
     389 
     390    template <typename T> str readable(const copy<T>& v) { return str(val2readable(v)); } 
     391    template <typename T> str readableHex(const copy<T>& v) { return str(val2readableHex(v)); } 
     392 
     393    template <typename T> bool operator == (const copy<T>& v1, const copy<T>& v2) { return static_cast<const T&>(v1) == static_cast<const T&>(v2); } 
     394    template <typename T> bool operator != (const copy<T>& v1, const copy<T>& v2) { return !(v1 == v2); } 
     395 
     396    template <> inline bool operator == <const char *>(const copy<const char *>& v1, const copy<const char *>& v2) { 
     397        const char *val1 = v1; 
     398        const char *val2 = v2; 
     399 
     400        return (val1 == val2) || (val1 && val2 && (strcmp(val1, val2) == 0)); 
     401    } 
     402 
     403 
     404 
     405    // ------------------------------- 
     406    //      some output functions 
     407 
     408    inline void print(const char *s) { fputs(s, stderr); } 
     409    inline void print(char c) { fputc(c, stderr); } 
     410    inline void print(int i) { fprintf(stderr, "%i", i); } 
     411 
     412    inline void space() { print(' '); } 
     413    inline void nl() { print('\n'); } 
     414     
     415    inline void print_indent(int indent) { while (indent--) space(); } 
     416 
     417    inline void spaced(const char *word) { space(); print(word); space(); } 
     418    inline void select_spaced(bool first, const char *singular, const char *plural) { spaced(first ? singular : plural); } 
     419     
     420 
     421#define HASTOBE_CLONABLE(type) virtual type *clone() const = 0 
     422#define MAKE_CLONABLE(type)    type *clone() const { return new type(*this); } 
     423 
     424    // ------------------------------ 
     425    //      abstract expectation 
     426 
     427    struct expectation //! something expected. can be fulfilled or not (and can explain why/not) 
     428    { 
     429        virtual ~expectation() {} 
     430        HASTOBE_CLONABLE(expectation); 
     431 
     432        virtual bool fulfilled() const              = 0; 
     433        virtual void explain(int indent) const      = 0; 
     434        virtual void dump_brief_description() const = 0; 
     435    }; 
     436 
     437    // ------------------- 
     438    //      asserters 
     439 
     440    class asserter : virtual Noncopyable { 
     441        expectation *expected; 
     442        locinfo      loc; 
     443        const char  *code; 
     444 
     445        virtual void announce_failure() const { TRIGGER_ASSERTION(false); } 
     446 
     447        void err(const char *format) const { loc.errorf(false, format, code); } 
     448        void warn(const char *format) const { loc.warningf(format, code); } 
     449         
     450    public: 
     451        asserter(const expectation& e, const char *nontmp_code, const char *file, int line) 
     452            : expected(e.clone()), 
     453              loc(file, line), 
     454              code(nontmp_code) 
     455        {} 
     456        virtual ~asserter() { delete expected; } 
     457 
     458        const char *get_code() const { return code; } 
     459 
     460        void expect_that() const { 
     461            if (!expected->fulfilled()) { 
     462                err("Failed expectation '%s'"); 
     463                print("expectation fails because\n"); 
     464                expected->explain(2); print('\n'); 
     465                announce_failure(); 
     466            } 
     467        } 
     468        void expect_broken() const { 
     469            if (expected->fulfilled()) { 
     470                err("Previously broken expectation '%s' succeeds"); 
     471                announce_failure(); 
     472            } 
     473            else { 
     474                warn("Expectation '%s' known as broken (accepted until fixed)"); 
     475                print("Broken because\n"); 
     476                expected->explain(2); print('\n'); 
     477            } 
     478        } 
     479        void expect_wanted_behavior() const { 
     480            if (expected->fulfilled()) { 
     481                err("Wanted behavior '%s' reached"); 
     482                announce_failure(); 
     483            } 
     484            else { 
     485                warn("Wanted behavior: '%s'"); 
     486                print("Unsatisfied because\n"); 
     487                expected->explain(2); print('\n'); 
     488            } 
     489        } 
     490 
     491    }; 
     492 
     493    class debug_asserter : public asserter { 
     494        virtual void announce_failure() const { 
     495            print("<<< would trigger assertion now! >>>\n"); 
     496        } 
     497    public: 
     498        debug_asserter(const expectation& e, const char *code_, const char *file, int line) 
     499            : asserter(e, code_, file, line) 
     500        {} 
     501 
     502        void debug_expectations() { 
     503            fprintf(stderr, "-------------------- [Debugging expectations for '%s']\n", get_code()); 
     504            expect_that(); 
     505            expect_broken(); 
     506            expect_wanted_behavior(); 
     507        } 
     508    }; 
     509 
     510    // ---------------------------------------- 
     511    //      matchable + matcher (abstract) 
     512 
     513    struct matchable //! can be matched with corresponding matcher. 
     514    { 
     515        virtual ~matchable() {} 
     516        HASTOBE_CLONABLE(matchable); 
     517 
     518        virtual const char *name() const           = 0; 
     519        virtual const char *readable_value() const = 0; 
     520    }; 
     521 
     522    struct matcher //! can match things. 
     523    { 
     524        virtual ~matcher() {} 
     525        HASTOBE_CLONABLE(matcher); 
     526 
     527        virtual bool matches(const matchable& thing) const                      = 0; 
     528        virtual void dump_expectation(const matchable& thing, int indent) const = 0; 
     529        virtual void dump_brief_description(const matchable& thing) const       = 0; 
     530    }; 
     531 
     532    // ---------------------------------------------- 
     533    //      expectation from matchable + matcher 
     534 
     535 
     536    class match_expectation : public expectation //! expectation composed from matcher and corresponding matchable. 
     537    { 
     538        matchable *thing; 
     539        matcher   *condition; 
     540    public: 
     541        match_expectation(const matchable& thing_, const matcher& condition_) 
     542            : thing(thing_.clone()), 
     543              condition(condition_.clone()) 
     544        {} 
     545        match_expectation(const match_expectation& other) 
     546            : thing(other.thing->clone()), 
     547              condition(other.condition->clone()) 
     548        {} 
     549        DECLARE_ASSIGNMENT_OPERATOR(match_expectation); 
     550        MAKE_CLONABLE(match_expectation); 
     551        ~match_expectation() { 
     552            delete thing; 
     553            delete condition; 
     554        } 
     555 
     556        bool fulfilled() const { return condition->matches(*thing); } 
     557        void explain(int indent) const { condition->dump_expectation(*thing, indent); } 
     558        void dump_brief_description() const { condition->dump_brief_description(*thing); } 
     559    }; 
     560 
     561    // ------------------- 
     562    //      predicate 
     563 
     564 
     565    class predicate_description { 
     566        const char  *primary; 
     567        const char  *inverse; 
     568        mutable str  tmp; 
     569 
     570        void erase_last_from_tmp() const { 
     571            char *t   = const_cast<char*>(tmp.value()); 
     572            int   len = strlen(t); 
     573            t[len-1]  = 0; 
     574        } 
     575 
     576        static bool ends_with_s(const char *s) { 
     577            int len          = strlen(s); 
     578            return s[len-1] == 's'; 
     579        } 
     580 
     581        const char *make(const char *desc, bool got) const { 
     582            if (ends_with_s(desc)) { 
     583                if (got) return desc; 
     584                tmp = StaticCode::strf("doesnt %s", desc); 
     585                erase_last_from_tmp(); 
     586            } 
     587            else { 
     588                tmp = StaticCode::strf("%s %s", got ? "is" : "isnt", desc); 
     589            } 
     590            return tmp.value(); 
     591        } 
     592 
     593    public: 
     594        predicate_description(const char *primary_) : primary(primary_), inverse(NULL) {} 
     595        predicate_description(const char *primary_, const char *inverse_) : primary(primary_), inverse(inverse_) {} 
     596        predicate_description(const predicate_description& other) : primary(other.primary), inverse(other.inverse) {} 
     597        DECLARE_ASSIGNMENT_OPERATOR(predicate_description); 
     598 
     599        const char *make(bool expected, bool got) const { 
     600            if (expected) return make(primary, got); 
     601            if (inverse) return make(inverse, !got); 
     602            return make(primary, !got); 
     603        } 
     604    }; 
     605 
     606    template <typename FUNC> 
     607    class predicate { 
     608        FUNC                  pred; 
     609        predicate_description description; 
     610    public: 
     611        predicate(FUNC pred_, const char *name) : pred(pred_), description(name) {} 
     612        predicate(FUNC pred_, const char *name, const char *inverse) : pred(pred_), description(name, inverse) {} 
     613 
     614        template <typename T> bool matches(const copy<T>& v1, const copy<T>& v2) const { return pred(v1, v2); } 
     615        const char *describe(bool expected, bool got) const { return description.make(expected, got); } 
     616    }; 
     617 
     618    template <typename FUNC> predicate<FUNC> make_predicate(FUNC func, const char *primary, const char *inverse) { 
     619        return predicate<FUNC>(func, primary, inverse); 
     620    } 
     621 
     622    // ------------------------------------------ 
     623    //      matchable + matcher (for values) 
     624 
     625    template <typename T> inline bool equals(const copy<T>& t1, const copy<T>& t2) { return t1 == t2; } 
     626    template <typename T> inline bool less(const copy<T>& t1, const copy<T>& t2) { return t1 < t2; } 
     627    template <typename T> inline bool more(const copy<T>& t1, const copy<T>& t2) { return t1 > t2; } 
     628 
     629    template <typename T> 
     630    class matchable_value : public matchable //! matchable for values 
     631    { 
     632        copy<T>      val; 
     633        mutable str  readable; 
     634        const char * code; 
     635    public: 
     636        matchable_value(copy<T> val_, const char *nontemp_code) : val(val_), code(nontemp_code) {} 
     637        matchable_value(const matchable_value<T>& other) : val(other.val), readable(other.readable), code(other.code) {} 
     638        DECLARE_ASSIGNMENT_OPERATOR(matchable_value); 
     639        MAKE_CLONABLE(matchable_value<T>); 
     640 
     641        const copy<T>& value() const { return val; } 
     642        char *gen_description() const { return StaticCode::strf("%s (=%s)", code, val.readable()); } 
     643 
     644        const char *name() const { return code; } 
     645        const char *readable_value() const { 
     646            if (!readable.exists()) readable = arb_test::readable(val); 
     647            return readable.value(); 
     648        } 
     649 
     650        template <typename U> inline match_expectation equals_expectation(bool invert, const U& other, const char *code) const; 
     651        template <typename U> inline match_expectation lessThan_expectation(bool invert, const U& other, const char *code) const; 
     652        template <typename U> inline match_expectation moreThan_expectation(bool invert, const U& other, const char *code) const; 
     653         
     654        template <typename FUNC> inline match_expectation predicate_expectation(bool wanted, predicate<FUNC> pred, matchable_value<T> arg) const; 
     655        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; 
     656    }; 
     657 
     658    template <typename T, typename U> 
     659    inline const matchable_value<T> make_matchable_value(const U& other, const char *code_) { 
     660        return matchable_value<T>(T(other), code_); 
     661    } 
     662#if defined(TESTS_KNOW_STRING) 
     663    template<> 
     664    inline const matchable_value<const char*> make_matchable_value<const char *, std::string>(const std::string& other, const char *code_) { 
     665        return matchable_value<const char *>(other.c_str(), code_); 
     666    } 
     667#endif 
     668     
     669    template <typename T> template <typename U> 
     670    inline match_expectation matchable_value<T>::equals_expectation(bool wanted, const U& other, const char *code_) const { 
     671        return predicate_expectation(wanted, make_predicate(equals<T>, "equals", "differs"), make_matchable_value<T,U>(other, code_)); 
     672    } 
     673    template <typename T> template <typename U> 
     674    inline match_expectation matchable_value<T>::lessThan_expectation(bool wanted, const U& other, const char *code_) const { 
     675        return predicate_expectation(wanted, make_predicate(less<T>, "less than", "more or equal"), make_matchable_value<T,U>(other, code_)); 
     676    } 
     677    template <typename T> template <typename U> 
     678    inline match_expectation matchable_value<T>::moreThan_expectation(bool wanted, const U& other, const char *code_) const { 
     679        return predicate_expectation(wanted, make_predicate(more<T>, "more than", "less or equal"), make_matchable_value<T,U>(other, code_)); 
     680    } 
     681     
     682    template <typename T> 
     683    class value_matcher : public matcher //! matcher for values 
     684    { 
     685        matchable_value<T> expected; 
     686    public: 
     687        value_matcher(const matchable_value<T>& expected_) : expected(expected_) {} 
     688        virtual ~value_matcher() {} 
     689 
     690        virtual bool matches(const copy<T>& v1, const copy<T>& v2) const       = 0; 
     691        virtual const char *relation(bool isMatch) const                       = 0; 
     692 
     693        const matchable_value<T>& get_expected() const { return expected; } 
     694 
     695        bool matches(const matchable& thing) const { 
     696            const matchable_value<T>& value_thing = dynamic_cast<const matchable_value<T>&>(thing); 
     697            return matches(value_thing.value(), expected.value()); 
     698        } 
     699 
     700        void dump_expectation(const matchable& thing, int indent) const { 
     701            bool isMatch = matches(thing); 
     702            print_indent(indent); 
     703            fprintf(stderr, "'%s' %s '%s'", thing.name(), relation(isMatch), expected.name()); 
     704 
     705            const matchable_value<T>& value_thing = dynamic_cast<const matchable_value<T>&>(thing); 
     706            if (equals<T>(value_thing.value(), expected.value())) { 
     707                fprintf(stderr, " (both are %s)", value_thing.readable_value()); 
     708            } 
     709            else { 
     710                int diff = strlen(thing.name())-strlen(expected.name()); 
     711 
     712                print(", where\n"); 
     713                indent += 2;; 
     714                print_indent(indent); fprintf(stderr, "'%s'%*s is %s, and\n", thing.name(),    (diff>0 ? 0 : -diff), "", thing.readable_value()); 
     715                print_indent(indent); fprintf(stderr, "'%s'%*s is %s",        expected.name(), (diff<0 ? 0 : diff),  "", expected.readable_value()); 
     716            } 
     717        } 
     718        void dump_brief_description(const matchable& thing) const { 
     719            print(thing.name()); 
     720            print('.'); 
     721            print(relation(true)); 
     722            print('('); print(expected.name()); print(')'); 
     723        } 
     724 
     725    }; 
     726 
     727    // --------------------------- 
     728    //      predicate_matcher 
     729 
     730 
     731    template <typename T, typename FUNC> 
     732    class predicate_matcher : public value_matcher<T> { 
     733        predicate<FUNC> pred; 
     734        bool            expected_result; 
     735 
     736    public: 
     737        predicate_matcher(bool wanted, predicate<FUNC> pred_, const matchable_value<T>& arg) 
     738            : value_matcher<T>(arg), 
     739              pred(pred_), 
     740              expected_result(wanted) 
     741        {} 
     742        MAKE_CLONABLE(predicate_matcher); 
     743 
     744        bool matches(const copy<T>& v1, const copy<T>& v2) const { return correlated(pred.matches(v1, v2), expected_result); } 
     745        const char *relation(bool isMatch) const { return pred.describe(expected_result, correlated(isMatch, expected_result)); } 
     746    }; 
     747 
     748    template <typename T> template <typename FUNC> 
     749    inline match_expectation matchable_value<T>::predicate_expectation(bool wanted, predicate<FUNC> pred, matchable_value<T> arg) const { 
     750        return match_expectation(*this, predicate_matcher<T,FUNC>(wanted, pred, arg)); 
     751    } 
     752    template <typename T> template <typename U, typename FUNC> 
     753    inline match_expectation matchable_value<T>::predicate_expectation(bool wanted, FUNC pred, const char *pred_code, const U& arg, const char *arg_code) const { 
     754        return match_expectation(*this, predicate_matcher<T,FUNC>(wanted, predicate<FUNC>(pred, pred_code), make_matchable_value<T,U>(arg, arg_code))); 
     755    } 
     756 
     757    // ------------------------------------------------ 
     758    //      matchable + matcher (for expectations) 
     759 
     760    const int MAX_GROUP_SIZE = 3; 
     761    class expectation_group : public matchable //! group of expectation. matchable with group_matcher 
     762    { 
     763        int          count; 
     764        expectation *depend_on[MAX_GROUP_SIZE]; 
     765 
     766        expectation_group& operator = (const expectation_group&); // forbidden 
     767    protected: 
     768 
     769    public: 
     770        expectation_group(const expectation& e) : count(1) { 
     771            depend_on[0] = e.clone(); 
     772        } 
     773        expectation_group(const expectation& e1, const expectation& e2) : count(2) { 
     774            depend_on[0] = e1.clone(); 
     775            depend_on[1] = e2.clone(); 
     776        } 
     777        expectation_group(const expectation_group& other) : count(other.count) { 
     778            for (int i = 0; i<count; ++i) { 
     779                depend_on[i] = other.depend_on[i]->clone(); 
     780            } 
     781        } 
     782        virtual ~expectation_group() { 
     783            for (int i = 0; i<count; ++i) { 
     784                delete depend_on[i]; 
     785            } 
     786        } 
     787        MAKE_CLONABLE(expectation_group); 
     788 
     789        expectation_group& add(const expectation& e) { depend_on[count++] = e.clone(); return *this; } 
     790 
     791        const char *name() const { 
     792            return "<expectation_group>"; 
     793        } 
     794        const char *readable_value() const { 
     795            return "<value of expectation_group>"; 
     796        } 
     797 
     798        const expectation& dependent(int i) const { arb_assert(i<count); return *depend_on[i]; } 
     799        int size() const { return count; } 
     800        int count_fulfilled() const { 
     801            int ff = 0; 
     802            for (int i = 0; i<count; ++i) { 
     803                ff += dependent(i).fulfilled(); 
     804            } 
     805            return ff; 
     806        } 
     807        void dump_some_expectations(int indent, bool fulfilled, bool unfulfilled) const { 
     808            if (fulfilled||unfulfilled) { 
     809                bool all    = fulfilled && unfulfilled; 
     810                bool wanted = fulfilled; 
     811 
     812                bool printed = false; 
     813                for (int i = 0; i<size(); ++i) { 
     814                    const expectation& e = dependent(i); 
     815 
     816                    bool is_fulfilled = e.fulfilled(); 
     817                    if (all || is_fulfilled == wanted) { 
     818                        if (printed) print('\n'); 
     819                        e.explain(indent); 
     820                        printed = true; 
     821                    } 
     822                } 
     823            } 
     824        } 
     825        void dump_brief_description() const { 
     826            print("of("); 
     827            bool printed = false; 
     828            for (int i = 0; i<size(); ++i) { 
     829                if (printed) print(", "); 
     830                const expectation& e = dependent(i); 
     831                e.dump_brief_description(); 
     832                printed = true; 
     833            } 
     834            print(')'); 
     835        } 
     836    }; 
     837 
     838    struct group_match //! result of matching an expectation_group with a group_matcher 
     839    { 
     840        const int count; 
     841        const int fulfilled; 
     842        const int min_req; 
     843        const int max_req; 
     844        const int diff; 
     845 
     846        int required(int what) const { return what == -1 ? count : what; } 
     847        group_match(const expectation_group& group, int min, int max) 
     848            : count(group.size()), 
     849              fulfilled(group.count_fulfilled()), 
     850              min_req(required(min)), 
     851              max_req(required(max)), 
     852              diff(fulfilled<min_req 
     853                   ? fulfilled-min_req 
     854                   : (fulfilled>max_req ? fulfilled-max_req : 0)) 
     855        {} 
     856 
     857 
     858        inline static void is(int a) { select_spaced(a == 1, "is", "are"); } 
     859        inline static void was(int a) { select_spaced(a < 2, "was", "were"); } 
     860        inline static void amountzero(int a, const char *zero) { a ? print(a) : print(zero); } 
     861 
     862        void dump_num_of(int amount, const char *thing) const { 
     863            amountzero(amount, "no"); 
     864            space(); 
     865            print(thing); 
     866            if (amount != 1) print('s'); 
     867        } 
     868 
     869        void dump(const expectation_group& group, int indent) const { 
     870            print_indent(indent); 
     871            if (count == 1) { 
     872                print("expectation "); 
     873                print("'"); 
     874                group.dependent(0).dump_brief_description(); 
     875                print("' "); 
     876                print(fulfilled ? "fulfilled" : "fails"); 
     877                print(diff ? " unexpectedly" : " as expected"); 
     878            } 
     879            else { 
     880                print("expected "); 
     881                int that_many; 
     882                if (min_req == max_req) { 
     883                    if (diff>0 && min_req>0) print("only "); 
     884                    that_many = min_req; 
     885                } 
     886                else { 
     887                    if (diff) { 
     888                        print("at"); select_spaced(diff<0, "least", "most"); 
     889                        that_many = diff<0 ? min_req : max_req; 
     890                    } 
     891                    else { 
     892                        fprintf(stderr, "%i-", min_req); 
     893                        that_many = max_req; 
     894                    } 
     895                } 
     896                dump_num_of(that_many, "fulfilled expectation"); 
     897                space(); 
     898                group.dump_brief_description(); 
     899                nl(); 
     900 
     901                indent += 2; 
     902                print_indent(indent); 
     903                if (diff == 0) print("and "); else print("but "); 
     904 
     905                if (diff<0 && fulfilled>0) print("only "); 
     906                amountzero(fulfilled, "none"); is(fulfilled); print("fulfilled"); 
     907            } 
     908 
     909            print(", because\n"); 
     910            bool show_fulfilled   = diff >= 0; 
     911            bool show_unfulfilled = diff <= 0; 
     912            group.dump_some_expectations(indent+2, show_fulfilled, show_unfulfilled); 
     913        } 
     914    }; 
     915 
     916    class group_matcher : public matcher //! matches expectation_group for degree of fulfilledness 
     917    { 
     918        int min, max; 
     919        group_matcher(int min_, int max_) : min(min_), max(max_) {} 
     920    public: 
     921        MAKE_CLONABLE(group_matcher); 
     922 
     923        bool matches(const matchable& thing) const { 
     924            return group_match(dynamic_cast<const expectation_group&>(thing), min, max).diff == 0; 
     925        } 
     926 
     927        void dump_expectation(const matchable& thing, int indent) const { 
     928            const expectation_group& group = dynamic_cast<const expectation_group&>(thing); 
     929            group_match matching(group, min, max); 
     930            matching.dump(group, indent); 
     931        } 
     932 
     933        // factories 
     934        static group_matcher all() { return group_matcher(-1, -1); } 
     935        static group_matcher none() { return group_matcher(0, 0); } 
     936        static group_matcher atleast(int min_) { return group_matcher(min_, -1); } 
     937        static group_matcher atmost(int max_) { return group_matcher(0, max_); } 
     938        static group_matcher exacly(int amount) { return group_matcher(amount, amount); } 
     939 
     940        // match_expectation factories 
     941        match_expectation of(const expectation& e) const { 
     942            return match_expectation(expectation_group(e), *this); 
     943        } 
     944        match_expectation of(const expectation& e1, const expectation& e2) const { 
     945            return match_expectation(expectation_group(e1, e2), *this); 
     946        } 
     947        match_expectation of(const expectation& e1, const expectation& e2, const expectation& e3) const { 
     948            return match_expectation(expectation_group(e1, e2).add(e3), *this); 
     949        } 
     950 
     951        void dump_brief_description(const matchable& thing) const { 
     952            if (max == -1) { 
     953                if (min == -1) { 
     954                    print("all"); 
     955                } 
     956                else { 
     957                    fprintf(stderr, "atleast(%i)", min); 
     958                } 
     959            } 
     960            else if (max == 0) { 
     961                print("none"); 
     962            } 
     963            else if (min == max) { 
     964                fprintf(stderr, "exactly(%i)", min); 
     965            } 
     966            else { 
     967                fprintf(stderr, "[%i-%i]", min, max); 
     968            } 
     969 
     970            print('.'); 
     971 
     972            const expectation_group& group = dynamic_cast<const expectation_group&>(thing); 
     973            group.dump_brief_description(); 
     974        } 
     975    }; 
     976 
     977    // -------------------------- 
     978    //      helper functions 
     979 
     980     
     981    template <typename T> const matchable_value<T> CREATE_matchable(const copy<T>& val, const char *code) { return matchable_value<T>(val, code); } 
     982 
     983    inline group_matcher all() { return group_matcher::all(); } 
     984    inline group_matcher none() { return group_matcher::none(); } 
     985    inline group_matcher atleast(int min) { return group_matcher::atleast(min); } 
     986    inline group_matcher atmost(int max) { return group_matcher::atmost(max); } 
     987    inline group_matcher exacly(int amount) { return group_matcher::exacly(amount); } 
     988 
     989    inline match_expectation wrong(const expectation& e) { return none().of(e); } 
    366990}; 
    367991 
    368992// -------------------------------------------------------------------------------- 
    369993 
    370 #define TEST_WARNING(format,strarg)           arb_test::StaticCode::warningf(__FILE__, __LINE__, format, (strarg)) 
    371 #define TEST_WARNING2(format,strarg1,strarg2) arb_test::StaticCode::warningf(__FILE__, __LINE__, format, (strarg1), (strarg2)) 
    372  
    373 #define TEST_ERROR(format,strarg)           arb_test::StaticCode::errorf(__FILE__, __LINE__, format, (strarg)) 
    374 #define TEST_ERROR2(format,strarg1,strarg2) arb_test::StaticCode::errorf(__FILE__, __LINE__, format, (strarg1), (strarg2)) 
    375 #define TEST_IOERROR(format,strarg)         arb_test::StaticCode::ioerrorf(__FILE__, __LINE__, format, (strarg)) 
     994#define MATCHABLE_ARGS_UNTYPED(val) val, #val 
     995#define MATCHABLE_ARGS_TYPED(val)   make_copy(val), #val 
     996 
     997#define equals(val)  equals_expectation(true, MATCHABLE_ARGS_UNTYPED(val)) 
     998#define differs(val) equals_expectation(false, MATCHABLE_ARGS_UNTYPED(val)) 
     999 
     1000#define less_than(val) lessThan_expectation(true, MATCHABLE_ARGS_UNTYPED(val)) 
     1001#define more_than(val) moreThan_expectation(true, MATCHABLE_ARGS_UNTYPED(val)) 
     1002 
     1003#define less_or_equal(val) moreThan_expectation(false, MATCHABLE_ARGS_UNTYPED(val)) 
     1004#define more_or_equal(val) lessThan_expectation(false, MATCHABLE_ARGS_UNTYPED(val)) 
     1005 
     1006#define is(pred,arg)     predicate_expectation(true, MATCHABLE_ARGS_UNTYPED(pred), MATCHABLE_ARGS_UNTYPED(arg)) 
     1007#define is_not(pred,arg) predicate_expectation(false, MATCHABLE_ARGS_UNTYPED(pred), MATCHABLE_ARGS_UNTYPED(arg)) 
     1008 
     1009#define that(thing) CREATE_matchable(MATCHABLE_ARGS_TYPED(thing)) 
     1010 
     1011#define TEST_EXPECT(EXPCTN) do { using namespace arb_test; asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).expect_that(); } while(0) 
     1012#define TEST_EXPECT__BROKEN(EXPCTN) do { using namespace arb_test; asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).expect_broken(); } while(0) 
     1013#define TEST_EXPECT__WANTED(EXPCTN) do { using namespace arb_test; asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).expect_wanted_behavior(); } while(0) 
     1014 
     1015#define DEBUG_TEST_EXPECT(EXPCTN) do {                                                  \ 
     1016        using namespace arb_test;                                                       \ 
     1017        debug_asserter(EXPCTN, #EXPCTN, __FILE__, __LINE__).                            \ 
     1018            debug_expectations();                                                       \ 
     1019        debug_asserter(wrong(EXPCTN), "wrong(" #EXPCTN ")", __FILE__, __LINE__).        \ 
     1020            debug_expectations();                                                       \ 
     1021    } while(0) 
     1022 
     1023// -------------------------------------------------------------------------------- 
     1024 
     1025#define HERE arb_test::locinfo(__FILE__, __LINE__) 
     1026 
     1027#define TEST_WARNING(format,strarg)           HERE.warningf(format, (strarg)) 
     1028#define TEST_WARNING2(format,strarg1,strarg2) HERE.warningf(format, (strarg1), (strarg2)) 
     1029#define TEST_ERROR(format,strarg)             HERE.errorf(true, format, (strarg)) 
     1030#define TEST_ERROR2(format,strarg1,strarg2)   HERE.errorf(true, format, (strarg1), (strarg2)) 
     1031#define TEST_IOERROR(format,strarg)           HERE.ioerrorf(true, format, (strarg)) 
    3761032 
    3771033// -------------------------------------------------------------------------------- 
     
    3941050    } while (0) 
    3951051 
    396  
    397 #define TEST_ASSERT_ZERO(cond)         TEST_ASSERT((cond)         == 0) 
    398 #define TEST_ASSERT_ZERO__BROKEN(cond) TEST_ASSERT__BROKEN((cond) == 0) 
     1052#define TEST_ASSERT_ZERO(cond)         TEST_EXPECT(that(cond).equals(0)) 
     1053#define TEST_ASSERT_ZERO__BROKEN(cond) TEST_EXPECT__BROKEN(that(cond).equals(0)) 
    3991054 
    4001055#define TEST_ASSERT_ZERO_OR_SHOW_ERRNO(iocond)                  \ 
     
    5461201// -------------------------------------------------------------------------------- 
    5471202 
    548 #define TEST_ASSERT_NULL(n)         TEST_ASSERT(arb_test::test_equal(n, (typeof(n))NULL)) 
    549 #define TEST_ASSERT_NULL__BROKEN(n) TEST_ASSERT__BROKEN(arb_test::test_equal(n, (typeof(n))NULL)) 
    550  
    551 #define TEST_ASSERT_EQUAL(e1,t2)         TEST_ASSERT(arb_test::test_equal(e1, t2)) 
    552 #define TEST_ASSERT_EQUAL__BROKEN(e1,t2) TEST_ASSERT__BROKEN(arb_test::test_equal(e1, t2)) 
    553  
    554 #define TEST_ASSERT_SIMILAR(e1,t2,epsilon)         TEST_ASSERT(arb_test::test_similar(e1, t2, epsilon)) 
    555 #define TEST_ASSERT_SIMILAR__BROKEN(e1,t2,epsilon) TEST_ASSERT__BROKEN(arb_test::test_similar(e1, t2, epsilon)) 
    556  
    557 #define TEST_ASSERT_DIFFERENT(e1,t2)         TEST_ASSERT(arb_test::test_different(e1, t2)) 
    558 #define TEST_ASSERT_DIFFERENT__BROKEN(e1,t2) TEST_ASSERT__BROKEN(arb_test::test_different(e1, t2)) 
    559  
    560 #define TEST_ASSERT_LOWER_EQUAL(lower,upper)  TEST_ASSERT(arb_test::test_less_equal(lower, upper)) 
    561 #define TEST_ASSERT_LOWER(lower,upper) do { TEST_ASSERT_LOWER_EQUAL(lower, upper); TEST_ASSERT_DIFFERENT(lower, upper); } while(0) 
    562 #define TEST_ASSERT_IN_RANGE(val,lower,upper) do { TEST_ASSERT_LOWER_EQUAL(lower, val); TEST_ASSERT_LOWER_EQUAL(val, upper); } while(0) 
    563  
    564  
    565 #define TEST_ASSERT_CONTAINS(str, part) TEST_ASSERT(arb_test::test_strcontains(str, part)) 
     1203#define TEST_ASSERT_EQUAL(e1,t2)         TEST_EXPECT(that(e1).equals(t2)) 
     1204#define TEST_ASSERT_EQUAL__BROKEN(e1,t2) TEST_EXPECT__BROKEN(that(e1).equals(t2)) 
     1205 
     1206#define TEST_ASSERT_NULL(n)         TEST_ASSERT_EQUAL(n, NULL) 
     1207#define TEST_ASSERT_NULL__BROKEN(n) TEST_ASSERT_EQUAL__BROKEN(n, NULL) 
     1208 
     1209#define TEST_ASSERT_SIMILAR(e1,t2,epsilon)         TEST_EXPECT(that(e1).is(epsilon_similar(epsilon), t2)) 
     1210#define TEST_ASSERT_SIMILAR__BROKEN(e1,t2,epsilon) TEST_EXPECT__BROKEN(that(e1).is(epsilon_similar(epsilon), t2)) 
     1211 
     1212#define TEST_ASSERT_DIFFERENT(e1,t2)         TEST_EXPECT(that(e1).differs(t2)); 
     1213#define TEST_ASSERT_DIFFERENT__BROKEN(e1,t2) TEST_EXPECT__BROKEN(that(e1).differs(t2)); 
     1214 
     1215#define TEST_ASSERT_LOWER_EQUAL(lower,upper)  TEST_EXPECT(that(lower).less_or_equal(upper)) 
     1216#define TEST_ASSERT_LOWER(lower,upper)        TEST_EXPECT(that(lower).less_than(upper)) 
     1217#define TEST_ASSERT_IN_RANGE(val,lower,upper) TEST_EXPECT(all().of(that(val).more_or_equal(lower), that(val).less_or_equal(upper))) 
     1218 
     1219#define TEST_ASSERT_CONTAINS(str, part) TEST_EXPECT(that(str).is(containing(), part)) 
    5661220 
    5671221// --------------------------------------------------------------------------------