File Annotation
Not logged in
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.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: }