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 }