Diff
Not logged in

Differences From Artifact [73906cba073bce6c]:

To Artifact [3f689d3451f8c1cc]:


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 )