Differences From Artifact [73906cba073bce6c]:
- File
polemy/tricks.d
- 2010-11-08 12:26:39 - part of checkin [80ff567c75] on branch trunk - Testing easyAST. (user: kinaba) [annotate]
To Artifact [3f689d3451f8c1cc]:
- File
tricks/tricks.d
- 2010-11-09 05:19:20 - part of checkin [8de5b49cdf] on branch trunk - split tricks module into a separate package. (user: kinaba) [annotate]
1 /** | 1 /**
2 * Authors: k.inaba 2 * Authors: k.inaba
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 tricks.tricks;
> 8 import tricks.test;
8 import std.array : appender; 9 import std.array : appender;
9 import std.format : formattedWrite; 10 import std.format : formattedWrite;
10 import core.exception : onAssertErrorMsg, AssertError; | 11 import core.exception : AssertError;
11 12
12 /// Simple Wrapper for std.format.doFormat 13 /// Simple Wrapper for std.format.doFormat
13 14
14 string sprintf(string fmt, T...)(T params) 15 string sprintf(string fmt, T...)(T params)
15 { 16 {
16 auto writer = appender!string(); 17 auto writer = appender!string();
17 formattedWrite(writer, fmt, params); 18 formattedWrite(writer, fmt, params);
................................................................................................................................................................................
20 21
21 unittest 22 unittest
22 { 23 {
23 assert( sprintf!"%s == %d"("1+2", 3) == "1+2 == 3" ); 24 assert( sprintf!"%s == %d"("1+2", 3) == "1+2 == 3" );
24 assert( sprintf!"%s == %04d"("1+2", 3) == "1+2 == 0003" ); 25 assert( sprintf!"%s == %04d"("1+2", 3) == "1+2 == 0003" );
25 } 26 }
26 27
27 /// Unittest helper that asserts an expression must throw something | 28 /// Create an exception with automatically completed filename and lineno informa
28 29
29 void assert_throw(ExceptionType, T, string fn=__FILE__, int ln=__LINE__)(lazy T | 30 auto genex(ExceptionType, string fn=__FILE__, int ln=__LINE__, T...)(T params)
30 { 31 {
31 try { | 32 static if( T.length > 0 && is(T[$-1] : Throwable) )
32 t(); | 33 return new ExceptionType(params[0..$-1], fn, ln, params[$-1]);
> 34 else
33 } catch(ExceptionType) { | 35 return new ExceptionType(params, fn, ln);
34 return; <
35 } catch(Throwable e) { <
36 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exception [ <
37 } <
38 onAssertErrorMsg(fn, ln, msg.length ? msg : "no execption"); <
39 } <
40 <
41 /// Unittest helper that asserts an expression must not throw anything <
42 <
43 void assert_nothrow(T, string fn=__FILE__, int ln=__LINE__)(lazy T t, string msg <
44 { <
45 try { <
46 t(); <
47 } catch(Throwable e) { <
48 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exception [ <
49 } <
50 } 36 }
51 37
52 unittest 38 unittest
53 { 39 {
54 auto error = {throw new Error("hello");}; | 40 assert_ne( genex!Exception("msg").file, "" );
55 auto nothing = (){}; | 41 assert_ne( genex!Exception("msg").line, 0 );
56 auto assertError = {assert(0);}; | 42 assert_ne( genex!Exception("msg",new Exception("bar")).next, Exception.i
57 <
58 assert_nothrow ( assert_nothrow(nothing()) ); <
59 assert_throw!AssertError( assert_nothrow(error()) ); <
60 assert_throw!AssertError( assert_nothrow(assertError()) ); <
61 <
62 assert_nothrow ( assert_throw!Error(error()) ); <
63 assert_throw!AssertError( assert_throw!Error(nothing()) ); <
64 assert_nothrow ( assert_throw!Error(assertError()) ); <
65 assert_throw!AssertError( assert_throw!AssertError(error()) ); <
66 } 43 }
67 44
68 /// Unittest helpers asserting two values are in some relation ==, !=, <, <=, >, <
69 <
70 template assertOp(string op) <
71 { <
72 void assertOp(A, B, string fn=__FILE__, int ln=__LINE__)(A a, B b, strin <
73 { <
74 try { <
75 if( mixin("a"~op~"b") ) return; <
76 } catch(Throwable e) { <
77 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"exc <
78 } <
79 onAssertErrorMsg(fn, ln, msg.length ? msg : sprintf!"%s !%s %s"( <
80 } <
81 } <
82 <
83 alias assertOp!(`==`) assert_eq; <
84 alias assertOp!(`!=`) assert_ne; <
85 alias assertOp!(`<`) assert_lt; <
86 alias assertOp!(`<=`) assert_le; <
87 alias assertOp!(`>`) assert_gt; <
88 alias assertOp!(`>=`) assert_ge; <
89 <
90 unittest <
91 { <
92 assert_nothrow( assert_eq(1, 1) ); <
93 assert_nothrow( assert_ne(1, 0) ); <
94 assert_nothrow( assert_lt(0, 1) ); <
95 assert_nothrow( assert_le(0, 1) ); <
96 assert_nothrow( assert_le(0, 0) ); <
97 assert_nothrow( assert_gt(1, 0) ); <
98 assert_nothrow( assert_ge(1, 0) ); <
99 assert_nothrow( assert_ge(0, 0) ); <
100 <
101 assert_throw!AssertError( assert_eq(1, 0) ); <
102 assert_throw!AssertError( assert_ne(1, 1) ); <
103 assert_throw!AssertError( assert_lt(1, 1) ); <
104 assert_throw!AssertError( assert_lt(1, 0) ); <
105 assert_throw!AssertError( assert_le(1, 0) ); <
106 assert_throw!AssertError( assert_gt(0, 0) ); <
107 assert_throw!AssertError( assert_gt(0, 1) ); <
108 assert_throw!AssertError( assert_ge(0, 1) ); <
109 <
110 class Temp { bool opEquals(int x){return x/x==x;} } <
111 assert_throw!AssertError( assert_eq(new Temp, 0) ); <
112 assert_nothrow ( assert_eq(new Temp, 1) ); <
113 assert_throw!AssertError( assert_eq(new Temp, 2) ); <
114 } <
115 <
116 /* [Todo] is there any way to clearnly implement "assert_compiles" and "assert_n <
117 <
118 /// Mixing-in the bean constructor for a class 45 /// Mixing-in the bean constructor for a class
119 46
120 /*mixin*/ 47 /*mixin*/
121 template SimpleConstructor() 48 template SimpleConstructor()
122 { 49 {
123 static if( is(typeof(super) == Object) || super.tupleof.length==0 ) 50 static if( is(typeof(super) == Object) || super.tupleof.length==0 )
124 this( typeof(this.tupleof) params ) 51 this( typeof(this.tupleof) params )