Diff
Not logged in

Differences From Artifact [1483c10390a22fc3]:

To Artifact [fc21831342965670]:


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 * Unittest helpers. 5 * Unittest helpers. > 6 * TODO: use stderr instead of stdout. the problem is that std.cstream is xxxx.. > 7 * TODO: is there any way to clearnly implement "assert_compiles" and "assert_no 6 */ 8 */ 7 module tricks.test; 9 module tricks.test; 8 import std.conv : to; 10 import std.conv : to; 9 import core.exception; 11 import core.exception; > 12 > 13 version(unittest) > 14 { > 15 import std.stdio; > 16 import core.runtime; > 17 > 18 // Install custom test runner > 19 static this() > 20 { > 21 Runtime.moduleUnitTester = function() > 22 { > 23 Throwable ee = null; > 24 size_t failed=0; > 25 foreach(m; ModuleInfo) if(m) if(auto fp=m.unitTest) > 26 { > 27 writeln("[TEST] ", m.name); > 28 try { > 29 fp(); > 30 } catch( Throwable e ) { > 31 if(ee is null) > 32 ee = e; > 33 failed++; > 34 writeln(" !! ",e.file,"(",e.line,"): ", > 35 } > 36 } > 37 if(ee !is null) > 38 { > 39 writeln("[TEST] ",failed," modules failed. The f > 40 writeln(ee); > 41 write("[TEST] press enter to exit."); > 42 readln(); > 43 return false; > 44 } > 45 return true; > 46 }; > 47 } > 48 } 10 49 11 /// Unittest helper that asserts an expression must throw something 50 /// Unittest helper that asserts an expression must throw something 12 51 13 void assert_throw(ExceptionType=Throwable, < 14 T, string fn=__FILE__, size_t ln=__LINE__)(lazy T t, string msg="") | 52 void assert_throw(ExcT=Throwable, T, string fn=__FILE__, size_t ln=__LINE__)(laz 15 { 53 { 16 static if( is(ExceptionType == Throwable) ) | 54 static if( is(ExcT == Throwable) ) 17 try 55 try 18 { t(); } 56 { t(); } 19 catch(ExceptionType) | 57 catch(ExcT) 20 { return; } 58 { return; } 21 else 59 else 22 try 60 try 23 { t(); } 61 { t(); } 24 catch(ExceptionType) | 62 catch(ExcT) 25 { return; } 63 { return; } 26 catch(Throwable e) 64 catch(Throwable e) 27 { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad excep | 65 { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad excep 28 onAssertErrorMsg(fn, ln, msg.length ? msg : "not thrown"); 66 onAssertErrorMsg(fn, ln, msg.length ? msg : "not thrown"); 29 } 67 } 30 68 31 /// Unittest helper that asserts an expression must not throw anything 69 /// Unittest helper that asserts an expression must not throw anything 32 70 33 T assert_nothrow(T, string fn=__FILE__, size_t ln=__LINE__)(lazy T t, string msg 71 T assert_nothrow(T, string fn=__FILE__, size_t ln=__LINE__)(lazy T t, string msg 34 { 72 { 35 try 73 try 36 { return t(); } 74 { return t(); } 37 catch(Throwable e) 75 catch(Throwable e) 38 { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad exception\n > | 76 { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad exception \n 39 assert(false); 77 assert(false); 40 } 78 } 41 79 42 unittest 80 unittest 43 { 81 { 44 auto error = {throw new Error("hello");}; 82 auto error = {throw new Error("hello");}; 45 auto nothing = (){}; 83 auto nothing = (){}; ................................................................................................................................................................................ 58 template assertOp(string op) 96 template assertOp(string op) 59 { 97 { 60 void assertOp(A, B, string fn=__FILE__, size_t ln=__LINE__)(A a, B b, st 98 void assertOp(A, B, string fn=__FILE__, size_t ln=__LINE__)(A a, B b, st 61 { 99 { 62 try 100 try 63 { if( mixin("a"~op~"b") ) return; } 101 { if( mixin("a"~op~"b") ) return; } 64 catch(Throwable e) 102 catch(Throwable e) 65 { onAssertErrorMsg(fn, ln, msg.length ? msg : "exception | 103 { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad excep 66 onAssertErrorMsg(fn, ln, msg.length ? msg : to!string(a)~" !"~op 104 onAssertErrorMsg(fn, ln, msg.length ? msg : to!string(a)~" !"~op 67 } 105 } 68 } 106 } 69 107 70 alias assertOp!(`==`) assert_eq; /// asserts two operands are == 108 alias assertOp!(`==`) assert_eq; /// asserts two operands are == 71 alias assertOp!(`!=`) assert_ne; /// asserts two operands are != 109 alias assertOp!(`!=`) assert_ne; /// asserts two operands are != 72 alias assertOp!(`<`) assert_lt; /// asserts two operands are < 110 alias assertOp!(`<`) assert_lt; /// asserts two operands are < ................................................................................................................................................................................ 95 assert_throw!AssertError( assert_ge(0, 1) ); 133 assert_throw!AssertError( assert_ge(0, 1) ); 96 134 97 class Temp { bool opEquals(int x){return x/x==x;} } 135 class Temp { bool opEquals(int x){return x/x==x;} } 98 assert_throw!AssertError( assert_eq(new Temp, 0) ); 136 assert_throw!AssertError( assert_eq(new Temp, 0) ); 99 assert_nothrow ( assert_eq(new Temp, 1) ); 137 assert_nothrow ( assert_eq(new Temp, 1) ); 100 assert_throw!AssertError( assert_eq(new Temp, 2) ); 138 assert_throw!AssertError( assert_eq(new Temp, 2) ); 101 } 139 } 102 < 103 /* [Todo] is there any way to clearnly implement "assert_compiles" and "assert_n <