Artifact bb5afea9b7b1423db6e9b85852bbbbca8a2e495a
1 /**
2 * Authors: k.inaba
3 * License: NYSL 0.9982 http://www.kmonos.net/nysl/
4 *
5 * Unittest helpers.
6 */
7 module tricks.test;
8 import std.conv : to;
9 import core.exception;
10
11 /// Unittest helper that asserts an expression must throw something
12
13 void assert_throw(ExceptionType, T, string fn=__FILE__, int ln=__LINE__)(lazy T t, string msg="")
14 {
15 try
16 { t(); }
17 catch(ExceptionType)
18 { return; }
19 catch(Throwable e)
20 { onAssertErrorMsg(fn, ln, msg.length ? msg : "exception ["~e.toString()~"]"); }
21 onAssertErrorMsg(fn, ln, msg.length ? msg : "no execption");
22 }
23
24 /// Unittest helper that asserts an expression must not throw anything
25
26 auto assert_nothrow(T, string fn=__FILE__, int ln=__LINE__)(lazy T t, string msg="")
27 {
28 try
29 { return t(); }
30 catch(Throwable e)
31 { onAssertErrorMsg(fn, ln, msg.length ? msg : "exception ["~e.toString()~"]"); }
32 assert(false);
33 }
34
35 unittest
36 {
37 auto error = {throw new Error("hello");};
38 auto nothing = (){};
39 auto assertError = {assert(0);};
40
41 assert_nothrow ( assert_nothrow(nothing()) );
42 assert_throw!AssertError( assert_nothrow(error()) );
43 assert_throw!AssertError( assert_nothrow(assertError()) );
44
45 assert_nothrow ( assert_throw!Error(error()) );
46 assert_throw!AssertError( assert_throw!Error(nothing()) );
47 assert_nothrow ( assert_throw!Error(assertError()) );
48 assert_throw!AssertError( assert_throw!AssertError(error()) );
49 }
50
51 /// Unittest helpers asserting two values are in some relation ==, !=, <, <=, >, >=
52
53 template assertOp(string op)
54 {
55 void assertOp(A, B, string fn=__FILE__, int ln=__LINE__)(A a, B b, string msg="")
56 {
57 try
58 { if( mixin("a"~op~"b") ) return; }
59 catch(Throwable e)
60 { onAssertErrorMsg(fn, ln, msg.length ? msg : "exception ["~e.toString()~"]"); }
61 onAssertErrorMsg(fn, ln, msg.length ? msg : to!string(a)~" !"~op~to!string(b));
62 }
63 }
64
65 alias assertOp!(`==`) assert_eq;
66 alias assertOp!(`!=`) assert_ne;
67 alias assertOp!(`<`) assert_lt;
68 alias assertOp!(`<=`) assert_le;
69 alias assertOp!(`>`) assert_gt;
70 alias assertOp!(`>=`) assert_ge;
71
72 unittest
73 {
74 assert_nothrow( assert_eq(1, 1) );
75 assert_nothrow( assert_ne(1, 0) );
76 assert_nothrow( assert_lt(0, 1) );
77 assert_nothrow( assert_le(0, 1) );
78 assert_nothrow( assert_le(0, 0) );
79 assert_nothrow( assert_gt(1, 0) );
80 assert_nothrow( assert_ge(1, 0) );
81 assert_nothrow( assert_ge(0, 0) );
82
83 assert_throw!AssertError( assert_eq(1, 0) );
84 assert_throw!AssertError( assert_ne(1, 1) );
85 assert_throw!AssertError( assert_lt(1, 1) );
86 assert_throw!AssertError( assert_lt(1, 0) );
87 assert_throw!AssertError( assert_le(1, 0) );
88 assert_throw!AssertError( assert_gt(0, 0) );
89 assert_throw!AssertError( assert_gt(0, 1) );
90 assert_throw!AssertError( assert_ge(0, 1) );
91
92 class Temp { bool opEquals(int x){return x/x==x;} }
93 assert_throw!AssertError( assert_eq(new Temp, 0) );
94 assert_nothrow ( assert_eq(new Temp, 1) );
95 assert_throw!AssertError( assert_eq(new Temp, 2) );
96 }
97
98 /* [Todo] is there any way to clearnly implement "assert_compiles" and "assert_not_compile"? */