8de5b49cdf 2010-11-09 kinaba: /** 8de5b49cdf 2010-11-09 kinaba: * Authors: k.inaba 8de5b49cdf 2010-11-09 kinaba: * License: NYSL 0.9982 http://www.kmonos.net/nysl/ 8de5b49cdf 2010-11-09 kinaba: * 515502e8d1 2010-11-20 kinaba: * Hepler routines for unittesting. 515502e8d1 2010-11-20 kinaba: * TODO: Is there any clean way to implement "assert_compiles" and "assert_not_compile"? 8de5b49cdf 2010-11-09 kinaba: */ 8de5b49cdf 2010-11-09 kinaba: module tricks.test; 515502e8d1 2010-11-20 kinaba: import std.conv : text; 8de5b49cdf 2010-11-09 kinaba: import core.exception; 8de5b49cdf 2010-11-09 kinaba: 6f0ec5b7c9 2010-11-11 kinaba: version(unittest) 6f0ec5b7c9 2010-11-11 kinaba: { 515502e8d1 2010-11-20 kinaba: import std.cstream; 6f0ec5b7c9 2010-11-11 kinaba: import core.runtime; 6f0ec5b7c9 2010-11-11 kinaba: 6f0ec5b7c9 2010-11-11 kinaba: static this() 515502e8d1 2010-11-20 kinaba: { 515502e8d1 2010-11-20 kinaba: installCustomTestRunner(); 515502e8d1 2010-11-20 kinaba: } 515502e8d1 2010-11-20 kinaba: 515502e8d1 2010-11-20 kinaba: private void installCustomTestRunner() 6f0ec5b7c9 2010-11-11 kinaba: { 6f0ec5b7c9 2010-11-11 kinaba: Runtime.moduleUnitTester = function() 6f0ec5b7c9 2010-11-11 kinaba: { 515502e8d1 2010-11-20 kinaba: Throwable firstError = null; 515502e8d1 2010-11-20 kinaba: 515502e8d1 2010-11-20 kinaba: void logError(Throwable e) 515502e8d1 2010-11-20 kinaba: { 515502e8d1 2010-11-20 kinaba: if(firstError is null) 515502e8d1 2010-11-20 kinaba: firstError = e; 515502e8d1 2010-11-20 kinaba: derr.writefln(" !! %s(%d): %s", e.file, e.line, e.msg); 515502e8d1 2010-11-20 kinaba: } 515502e8d1 2010-11-20 kinaba: 515502e8d1 2010-11-20 kinaba: void testModule(ModuleInfo* m, void function() test) 6f0ec5b7c9 2010-11-11 kinaba: { 515502e8d1 2010-11-20 kinaba: derr.writefln("[TEST] %s", m.name); 515502e8d1 2010-11-20 kinaba: try { test(); } catch( Throwable e ) { logError(e); } 6f0ec5b7c9 2010-11-11 kinaba: } 515502e8d1 2010-11-20 kinaba: 515502e8d1 2010-11-20 kinaba: bool report() 6f0ec5b7c9 2010-11-11 kinaba: { 515502e8d1 2010-11-20 kinaba: if(firstError is null) 515502e8d1 2010-11-20 kinaba: return true; 515502e8d1 2010-11-20 kinaba: derr.writefln("[TEST] The first error was:\n%s", firstError); 515502e8d1 2010-11-20 kinaba: derr.writeString("[TEST] press enter to exit."); 515502e8d1 2010-11-20 kinaba: din.readLine(); 6f0ec5b7c9 2010-11-11 kinaba: return false; 6f0ec5b7c9 2010-11-11 kinaba: } 515502e8d1 2010-11-20 kinaba: 515502e8d1 2010-11-20 kinaba: foreach(m; ModuleInfo) 515502e8d1 2010-11-20 kinaba: if(m && m.unitTest) 515502e8d1 2010-11-20 kinaba: testModule(m, m.unitTest); 515502e8d1 2010-11-20 kinaba: return report(); 6f0ec5b7c9 2010-11-11 kinaba: }; 6f0ec5b7c9 2010-11-11 kinaba: } 6f0ec5b7c9 2010-11-11 kinaba: } 6f0ec5b7c9 2010-11-11 kinaba: 8de5b49cdf 2010-11-09 kinaba: /// Unittest helper that asserts an expression must throw something 8de5b49cdf 2010-11-09 kinaba: 6f0ec5b7c9 2010-11-11 kinaba: void assert_throw(ExcT=Throwable, T, string fn=__FILE__, size_t ln=__LINE__)(lazy T t, string msg="") 8de5b49cdf 2010-11-09 kinaba: { 6f0ec5b7c9 2010-11-11 kinaba: static if( is(ExcT == Throwable) ) 7465fcdd7f 2010-11-09 kinaba: try 7465fcdd7f 2010-11-09 kinaba: { t(); } 6f0ec5b7c9 2010-11-11 kinaba: catch(ExcT) 7465fcdd7f 2010-11-09 kinaba: { return; } 7465fcdd7f 2010-11-09 kinaba: else 7465fcdd7f 2010-11-09 kinaba: try 7465fcdd7f 2010-11-09 kinaba: { t(); } 6f0ec5b7c9 2010-11-11 kinaba: catch(ExcT) 7465fcdd7f 2010-11-09 kinaba: { return; } 7465fcdd7f 2010-11-09 kinaba: catch(Throwable e) 6f0ec5b7c9 2010-11-11 kinaba: { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad exception \n >> "~e.toString()); } 2459e9a821 2010-11-09 kinaba: onAssertErrorMsg(fn, ln, msg.length ? msg : "not thrown"); 8de5b49cdf 2010-11-09 kinaba: } 8de5b49cdf 2010-11-09 kinaba: 8de5b49cdf 2010-11-09 kinaba: /// Unittest helper that asserts an expression must not throw anything 8de5b49cdf 2010-11-09 kinaba: 38fcc662be 2010-11-10 kinaba: T assert_nothrow(T, string fn=__FILE__, size_t ln=__LINE__)(lazy T t, string msg="") 8de5b49cdf 2010-11-09 kinaba: { 8de5b49cdf 2010-11-09 kinaba: try 8de5b49cdf 2010-11-09 kinaba: { return t(); } 8de5b49cdf 2010-11-09 kinaba: catch(Throwable e) 6f0ec5b7c9 2010-11-11 kinaba: { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad exception \n >> "~e.toString()); } 8de5b49cdf 2010-11-09 kinaba: assert(false); 8de5b49cdf 2010-11-09 kinaba: } 8de5b49cdf 2010-11-09 kinaba: 8de5b49cdf 2010-11-09 kinaba: unittest 8de5b49cdf 2010-11-09 kinaba: { 8de5b49cdf 2010-11-09 kinaba: auto error = {throw new Error("hello");}; 8de5b49cdf 2010-11-09 kinaba: auto nothing = (){}; 8de5b49cdf 2010-11-09 kinaba: auto assertError = {assert(0);}; 8de5b49cdf 2010-11-09 kinaba: 8de5b49cdf 2010-11-09 kinaba: assert_nothrow ( assert_nothrow(nothing()) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_nothrow(error()) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_nothrow(assertError()) ); 8de5b49cdf 2010-11-09 kinaba: 8de5b49cdf 2010-11-09 kinaba: assert_nothrow ( assert_throw!Error(error()) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_throw!Error(nothing()) ); 8de5b49cdf 2010-11-09 kinaba: assert_nothrow ( assert_throw!Error(assertError()) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_throw!AssertError(error()) ); 8de5b49cdf 2010-11-09 kinaba: } 8de5b49cdf 2010-11-09 kinaba: 8de5b49cdf 2010-11-09 kinaba: template assertOp(string op) 8de5b49cdf 2010-11-09 kinaba: { 6ecc7046fc 2010-11-21 kinaba: void assertOp(A, B, string fn=__FILE__, size_t ln=__LINE__)(lazy A a_, lazy B b_, string msg="") 8de5b49cdf 2010-11-09 kinaba: { 8de5b49cdf 2010-11-09 kinaba: try 6ecc7046fc 2010-11-21 kinaba: { A a=a_(); B b=b_(); if( mixin("a"~op~"b") ) return; 6ecc7046fc 2010-11-21 kinaba: onAssertErrorMsg(fn, ln, msg.length ? msg : text(a, " !", op, " ", b)); } 8de5b49cdf 2010-11-09 kinaba: catch(Throwable e) 6f0ec5b7c9 2010-11-11 kinaba: { onAssertErrorMsg(fn, ln, msg.length ? msg : "bad exception \n >> "~e.toString()); } 6ecc7046fc 2010-11-21 kinaba: assert(false); 8de5b49cdf 2010-11-09 kinaba: } 8de5b49cdf 2010-11-09 kinaba: } 8de5b49cdf 2010-11-09 kinaba: 38fcc662be 2010-11-10 kinaba: alias assertOp!(`==`) assert_eq; /// asserts two operands are == 38fcc662be 2010-11-10 kinaba: alias assertOp!(`!=`) assert_ne; /// asserts two operands are != 38fcc662be 2010-11-10 kinaba: alias assertOp!(`<`) assert_lt; /// asserts two operands are < 38fcc662be 2010-11-10 kinaba: alias assertOp!(`<=`) assert_le; /// asserts two operands are <= 38fcc662be 2010-11-10 kinaba: alias assertOp!(`>`) assert_gt; /// asserts two operands are > 38fcc662be 2010-11-10 kinaba: alias assertOp!(`>=`) assert_ge; /// asserts two operands are >= 8de5b49cdf 2010-11-09 kinaba: 8de5b49cdf 2010-11-09 kinaba: unittest 8de5b49cdf 2010-11-09 kinaba: { 8de5b49cdf 2010-11-09 kinaba: assert_nothrow( assert_eq(1, 1) ); 8de5b49cdf 2010-11-09 kinaba: assert_nothrow( assert_ne(1, 0) ); 8de5b49cdf 2010-11-09 kinaba: assert_nothrow( assert_lt(0, 1) ); 8de5b49cdf 2010-11-09 kinaba: assert_nothrow( assert_le(0, 1) ); 8de5b49cdf 2010-11-09 kinaba: assert_nothrow( assert_le(0, 0) ); 8de5b49cdf 2010-11-09 kinaba: assert_nothrow( assert_gt(1, 0) ); 8de5b49cdf 2010-11-09 kinaba: assert_nothrow( assert_ge(1, 0) ); 8de5b49cdf 2010-11-09 kinaba: assert_nothrow( assert_ge(0, 0) ); 8de5b49cdf 2010-11-09 kinaba: 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_eq(1, 0) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_ne(1, 1) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_lt(1, 1) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_lt(1, 0) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_le(1, 0) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_gt(0, 0) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_gt(0, 1) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_ge(0, 1) ); 8de5b49cdf 2010-11-09 kinaba: 8de5b49cdf 2010-11-09 kinaba: class Temp { bool opEquals(int x){return x/x==x;} } 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_eq(new Temp, 0) ); 8de5b49cdf 2010-11-09 kinaba: assert_nothrow ( assert_eq(new Temp, 1) ); 8de5b49cdf 2010-11-09 kinaba: assert_throw!AssertError( assert_eq(new Temp, 2) ); 8de5b49cdf 2010-11-09 kinaba: }