Differences From Artifact [b521ec130c690547]:
- File        
polemy/tricks.d
- 2010-11-07 15:03:38 - part of checkin [820e7198cc] on branch trunk - Made helloworld work. (user: kinaba) [annotate]
 
To Artifact [63ca5d91a9064dd8]:
- File        
polemy/tricks.d
- 2010-11-08 06:19:57 - part of checkin [61998c472a] on branch trunk - Introduced unittest helpers (assert_eq, assert_throw, etc). Mmigration to it is not done yet. (user: kinaba) [annotate]
 
     3      3    * License: NYSL 0.9982 http://www.kmonos.net/nysl/
     4      4    *
     5      5    * Common tricks and utilities for programming in D.
     6      6    */
     7      7   module polemy.tricks;
     8      8   static import std.array;
     9      9   static import std.format;
           10  +static import core.exception;
    10     11   
    11     12   /// Simple Wrapper for std.format.doFormat
    12     13   
    13     14   string sprintf(string fmt, T...)(T params)
    14     15   {
    15     16    auto writer = std.array.appender!string();
    16     17    std.format.formattedWrite(writer, fmt, params);
................................................................................
    19     20   
    20     21   unittest
    21     22   {
    22     23    assert( sprintf!"%s == %d"("1+2", 3) == "1+2 == 3" );
    23     24    assert( sprintf!"%s == %04d"("1+2", 3) == "1+2 == 0003" );
    24     25   }
    25     26   
           27  +/// Unittest helpers asserting two values are in some relation ==, !=, <, <=, >, >=
           28  +
           29  +template assertOp(string op)
           30  +{
           31  + void assertOp(A, B, string fn=__FILE__, int ln=__LINE__)(A a, B b, string msg="")
           32  + {
           33  +  try {
           34  +   if( mixin("a"~op~"b") ) return;
           35  +  } catch(Throwable e) {
           36  +   core.exception.onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exception [%s]"(e));
           37  +  }
           38  +  core.exception.onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"%s !%s %s"(a,op,b));
           39  + }
           40  +}
           41  +
           42  +alias assertOp!(`==`) assert_eq;
           43  +alias assertOp!(`!=`) assert_ne;
           44  +alias assertOp!(`<`)  assert_lt;
           45  +alias assertOp!(`<=`) assert_le;
           46  +alias assertOp!(`>`)  assert_gt;
           47  +alias assertOp!(`>=`) assert_ge;
           48  +
           49  +/// Unittest helper that asserts an expression must throw something
           50  +
           51  +void assert_throw(ExceptionType, T, string fn=__FILE__, int ln=__LINE__)(lazy T t, string msg="")
           52  +{
           53  + try {
           54  +  t();
           55  + } catch(ExceptionType) {
           56  +  return;
           57  + } catch(Throwable e) {
           58  +  core.exception.onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exception [%s]"(e));
           59  + }
           60  + core.exception.onAssertErrorMsg(fn, ln, msg.length ? msg : "no execption");
           61  +}
           62  +
           63  +/// Unittest helper that asserts an expression must not throw anything
           64  +
           65  +void assert_nothrow(ExceptionType, T, string fn=__FILE__, int ln=__LINE__)(lazy T t, string msg="")
           66  +{
           67  + try {
           68  +  t();
           69  + } catch(Throwable e) {
           70  +  core.exception.onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exception [%s]"(e));
           71  + }
           72  +}
           73  +
           74  +/* [Todo] is there any way to clearnly implement "assert_compiles" and "assert_not_compile"? */
           75  +
    26     76   /// Mixing-in the bean constructor for a class
    27     77   
    28         -/*mixin*/ template SimpleConstructor()
           78  +template SimpleConstructor()
    29     79   {
    30     80    static if( is(typeof(super) == Object) || super.tupleof.length==0 )
    31     81     this( typeof(this.tupleof) params )
    32     82     {
    33     83      static if(this.tupleof.length>0)
    34     84       this.tupleof = params;
    35     85     }
    36     86    else
    37         -  // this parameter list is not always desirable but should work for many cases
    38     87     this( typeof(super.tupleof) ps, typeof(this.tupleof) params )
    39     88     {
           89  +   // including (only) the direct super class members
           90  +   // may not always be a desirable choice, but should work for many cases
    40     91      super(ps);
    41     92      static if(this.tupleof.length>0)
    42     93       this.tupleof = params;
    43     94     }
    44     95   }
           96  +
           97  +unittest
           98  +{
           99  + class Temp
          100  + {
          101  +  int x;
          102  +  string y;
          103  +  mixin SimpleConstructor;
          104  + }
          105  + assert_eq( (new Temp(1,"foo")).x, 1 );
          106  + assert_eq( (new Temp(1,"foo")).y, "foo" );
          107  + assert( !__traits(compiles, new Temp) );
          108  + assert( !__traits(compiles, new Temp(1)) );
          109  + assert( !__traits(compiles, new Temp("foo",1)) );
          110  +}
    45    111   
    46    112   /// Mixing-in the MOST-DERIVED-member-wise comparator for a class
    47    113   
    48         -/*mixin*/ template SimpleCompare()
          114  +template SimpleCompare()
    49    115   {
    50    116    override bool opEquals(Object rhs_) const
    51    117    {
    52    118     if( auto rhs = cast(typeof(this))rhs_ )
    53    119     {
    54    120      foreach(i,_; this.tupleof)
    55    121       if( this.tupleof[i] != rhs.tupleof[i] )
................................................................................
    85    151    class Temp
    86    152    {
    87    153     int x;
    88    154     string y;
    89    155     mixin SimpleConstructor;
    90    156     mixin SimpleCompare;
    91    157    }
    92         - assert( (new Temp(1,"foo")).x == 1 );
    93         - assert( (new Temp(1,"foo")).y == "foo" );
    94         - assert( !__traits(compiles, new Temp) );
    95         - assert( !__traits(compiles, new Temp(1)) );
    96         - assert( !__traits(compiles, new Temp("foo",1)) );
    97         - assert( new Temp(1,"foo") == new Temp(1,"foo") );
    98         - assert( (new Temp(1,"foo")).toHash == (new Temp(1,"foo")).toHash );
    99         - assert( new Temp(1,"foo") != new Temp(2,"foo") );
   100         - assert( new Temp(1,"foo") != new Temp(1,"bar") );
   101         - assert( new Temp(1,"foo") > new Temp(1,"bar") );
   102         - assert( new Temp(1,"foo") < new Temp(2,"bar") );
          158  + assert_eq( new Temp(1,"foo"), new Temp(1,"foo") );
          159  + assert_eq( (new Temp(1,"foo")).toHash, (new Temp(1,"foo")).toHash );
          160  + assert_ne( new Temp(1,"foo"), new Temp(2,"foo") );
          161  + assert_ne( new Temp(1,"foo"), new Temp(1,"bar") );
          162  + assert_gt( new Temp(1,"foo"), new Temp(1,"bar") );
          163  + assert_lt( new Temp(1,"foo"), new Temp(2,"bar") );
   103    164   }