Differences From Artifact [fc21831342965670]:
- File
tricks/test.d
- 2010-11-11 15:22:55 - part of checkin [6f0ec5b7c9] on branch trunk - Custom Test Runner (user: kinaba) [annotate]
To Artifact [b9b84a35fccc5116]:
- File
tricks/test.d
- 2010-11-20 09:20:03 - part of checkin [515502e8d1] on branch trunk - table get, init, ask expressions addded (user: kinaba) [annotate]
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 <=