Diff
Not logged in

Differences From Artifact [fc21831342965670]:

To Artifact [b9b84a35fccc5116]:


1 1 /** 2 2 * Authors: k.inaba 3 3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 4 4 * 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_not_compile"? 5 + * Hepler routines for unittesting. 6 + * TODO: Is there any clean way to implement "assert_compiles" and "assert_not_compile"? 8 7 */ 9 8 module tricks.test; 10 -import std.conv : to; 9 +import std.conv : text; 11 10 import core.exception; 12 11 13 12 version(unittest) 14 13 { 15 - import std.stdio; 14 + import std.cstream; 16 15 import core.runtime; 17 16 18 - // Install custom test runner 19 17 static this() 20 18 { 19 + installCustomTestRunner(); 20 + } 21 + 22 + private void installCustomTestRunner() 23 + { 21 24 Runtime.moduleUnitTester = function() 22 25 { 23 - Throwable ee = null; 24 - size_t failed=0; 25 - foreach(m; ModuleInfo) if(m) if(auto fp=m.unitTest) 26 + Throwable firstError = null; 27 + 28 + void logError(Throwable e) 29 + { 30 + if(firstError is null) 31 + firstError = e; 32 + derr.writefln(" !! %s(%d): %s", e.file, e.line, e.msg); 33 + } 34 + 35 + void testModule(ModuleInfo* m, void function() test) 26 36 { 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,"): ",e.msg); 35 - } 37 + derr.writefln("[TEST] %s", m.name); 38 + try { test(); } catch( Throwable e ) { logError(e); } 36 39 } 37 - if(ee !is null) 40 + 41 + bool report() 38 42 { 39 - writeln("[TEST] ",failed," modules failed. The first error was:"); 40 - writeln(ee); 41 - write("[TEST] press enter to exit."); 42 - readln(); 43 + if(firstError is null) 44 + return true; 45 + derr.writefln("[TEST] The first error was:\n%s", firstError); 46 + derr.writeString("[TEST] press enter to exit."); 47 + din.readLine(); 43 48 return false; 44 49 } 45 - return true; 50 + 51 + foreach(m; ModuleInfo) 52 + if(m && m.unitTest) 53 + testModule(m, m.unitTest); 54 + return report(); 46 55 }; 47 56 } 48 57 } 49 58 50 59 /// Unittest helper that asserts an expression must throw something 51 60 52 61 void assert_throw(ExcT=Throwable, T, string fn=__FILE__, size_t ln=__LINE__)(lazy T t, string msg="") ................................................................................ 97 106 { 98 107 void assertOp(A, B, string fn=__FILE__, size_t ln=__LINE__)(A a, B b, string msg="") 99 108 { 100 109 try 101 110 { if( mixin("a"~op~"b") ) return; } 102 111 catch(Throwable e) 103 112 { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad exception \n >> "~e.toString()); } 104 - onAssertErrorMsg(fn, ln, msg.length ? msg : to!string(a)~" !"~op~" "~to!string(b)); 113 + onAssertErrorMsg(fn, ln, msg.length ? msg : text(a, " !", op, " ", b)); 105 114 } 106 115 } 107 116 108 117 alias assertOp!(`==`) assert_eq; /// asserts two operands are == 109 118 alias assertOp!(`!=`) assert_ne; /// asserts two operands are != 110 119 alias assertOp!(`<`) assert_lt; /// asserts two operands are < 111 120 alias assertOp!(`<=`) assert_le; /// asserts two operands are <=