Diff
Not logged in

Differences From Artifact [b521ec130c690547]:

To Artifact [63ca5d91a9064dd8]:


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 }