1 module oops;
2 
3 
4 import unit_threaded;
5 import std.exception: assertThrown, assertNotThrown;
6 
7 class CustomException : Exception {
8     this(string msg = "") {
9             super(msg);
10         }
11 }
12 
13 class ChildException : CustomException {
14     this(string msg = "") {
15             super(msg);
16         }
17 }
18 
19 
20 @("shouldThrow works with non-throwing expression")
21 unittest {
22     assertThrown((2 + 2).shouldThrow);
23 }
24 
25 
26 @("shouldThrow works with throwing expression")
27 unittest {
28     void funcThrows() {
29         throw new Exception("oops");
30     }
31     assertNotThrown(funcThrows.shouldThrow);
32 }
33 
34 @("shouldThrowExactly works with non-throwing expression")
35 unittest {
36     assertThrown((2 + 2).shouldThrowExactly!ChildException);
37 }
38 
39 
40 @("shouldThrowWithMessage works with non-throwing expression")
41 unittest {
42     assertThrown((2 + 2).shouldThrowWithMessage("oops"));
43 }
44 
45 
46 @("shouldThrowWithMessage works with throwing expression")
47 unittest {
48     void funcThrows() {
49         throw new Exception("oops");
50     }
51     assertNotThrown(funcThrows.shouldThrowWithMessage("oops"));
52     assertThrown(funcThrows.shouldThrowWithMessage("foobar"));
53 }
54 
55 @("shouldThrowExactly works with throwing expression")
56 unittest {
57 
58     void throwCustom() {
59         throw new CustomException("custom");
60     }
61 
62     assertNotThrown(throwCustom.shouldThrow);
63     assertNotThrown(throwCustom.shouldThrow!CustomException);
64     assertNotThrown(throwCustom.shouldThrowExactly!CustomException);
65 
66 
67     void throwChild() {
68         throw new ChildException("child");
69     }
70 
71     assertNotThrown(throwChild.shouldThrow);
72     assertNotThrown(throwChild.shouldThrow!CustomException);
73     assertNotThrown(throwChild.shouldThrow!ChildException);
74 
75     assertThrown(throwChild.shouldThrowExactly!Exception);
76     assertThrown(throwChild.shouldThrowExactly!CustomException);
77 }