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 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/
4 * 4 *
5 * Common tricks and utilities for programming in D. 5 * Common tricks and utilities for programming in D.
6 */ 6 */
7 module polemy.tricks; 7 module polemy.tricks;
8 static import std.array; 8 static import std.array;
9 static import std.format; 9 static import std.format;
> 10 static import core.exception;
10 11
11 /// Simple Wrapper for std.format.doFormat 12 /// Simple Wrapper for std.format.doFormat
12 13
13 string sprintf(string fmt, T...)(T params) 14 string sprintf(string fmt, T...)(T params)
14 { 15 {
15 auto writer = std.array.appender!string(); 16 auto writer = std.array.appender!string();
16 std.format.formattedWrite(writer, fmt, params); 17 std.format.formattedWrite(writer, fmt, params);
................................................................................................................................................................................
19 20
20 unittest 21 unittest
21 { 22 {
22 assert( sprintf!"%s == %d"("1+2", 3) == "1+2 == 3" ); 23 assert( sprintf!"%s == %d"("1+2", 3) == "1+2 == 3" );
23 assert( sprintf!"%s == %04d"("1+2", 3) == "1+2 == 0003" ); 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, strin
> 32 {
> 33 try {
> 34 if( mixin("a"~op~"b") ) return;
> 35 } catch(Throwable e) {
> 36 core.exception.onAssertErrorMsg(fn, ln, msg.length ? msg
> 37 }
> 38 core.exception.onAssertErrorMsg(fn, ln, msg.length ? msg : sprin
> 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
> 52 {
> 53 try {
> 54 t();
> 55 } catch(ExceptionType) {
> 56 return;
> 57 } catch(Throwable e) {
> 58 core.exception.onAssertErrorMsg(fn, ln, msg.length ? msg : sprin
> 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
> 66 {
> 67 try {
> 68 t();
> 69 } catch(Throwable e) {
> 70 core.exception.onAssertErrorMsg(fn, ln, msg.length ? msg : sprin
> 71 }
> 72 }
> 73
> 74 /* [Todo] is there any way to clearnly implement "assert_compiles" and "assert_n
> 75
26 /// Mixing-in the bean constructor for a class 76 /// Mixing-in the bean constructor for a class
27 77
28 /*mixin*/ template SimpleConstructor() | 78 template SimpleConstructor()
29 { 79 {
30 static if( is(typeof(super) == Object) || super.tupleof.length==0 ) 80 static if( is(typeof(super) == Object) || super.tupleof.length==0 )
31 this( typeof(this.tupleof) params ) 81 this( typeof(this.tupleof) params )
32 { 82 {
33 static if(this.tupleof.length>0) 83 static if(this.tupleof.length>0)
34 this.tupleof = params; 84 this.tupleof = params;
35 } 85 }
36 else 86 else
37 // this parameter list is not always desirable but should work f <
38 this( typeof(super.tupleof) ps, typeof(this.tupleof) params ) 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
40 super(ps); 91 super(ps);
41 static if(this.tupleof.length>0) 92 static if(this.tupleof.length>0)
42 this.tupleof = params; 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 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class 112 /// Mixing-in the MOST-DERIVED-member-wise comparator for a class
47 113
48 /*mixin*/ template SimpleCompare() | 114 template SimpleCompare()
49 { 115 {
50 override bool opEquals(Object rhs_) const 116 override bool opEquals(Object rhs_) const
51 { 117 {
52 if( auto rhs = cast(typeof(this))rhs_ ) 118 if( auto rhs = cast(typeof(this))rhs_ )
53 { 119 {
54 foreach(i,_; this.tupleof) 120 foreach(i,_; this.tupleof)
55 if( this.tupleof[i] != rhs.tupleof[i] ) 121 if( this.tupleof[i] != rhs.tupleof[i] )
................................................................................................................................................................................
85 class Temp 151 class Temp
86 { 152 {
87 int x; 153 int x;
88 string y; 154 string y;
89 mixin SimpleConstructor; 155 mixin SimpleConstructor;
90 mixin SimpleCompare; 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") ); | 158 assert_eq( new Temp(1,"foo"), new Temp(1,"foo") );
98 assert( (new Temp(1,"foo")).toHash == (new Temp(1,"foo")).toHash ); | 159 assert_eq( (new Temp(1,"foo")).toHash, (new Temp(1,"foo")).toHash );
99 assert( new Temp(1,"foo") != new Temp(2,"foo") ); | 160 assert_ne( new Temp(1,"foo"), new Temp(2,"foo") );
100 assert( new Temp(1,"foo") != new Temp(1,"bar") ); | 161 assert_ne( new Temp(1,"foo"), new Temp(1,"bar") );
101 assert( new Temp(1,"foo") > new Temp(1,"bar") ); | 162 assert_gt( new Temp(1,"foo"), new Temp(1,"bar") );
102 assert( new Temp(1,"foo") < new Temp(2,"bar") ); | 163 assert_lt( new Temp(1,"foo"), new Temp(2,"bar") );
103 } 164 }