1 module ut.exception;
2 
3 
4 import ut;
5 import nogc.exception;
6 
7 
8 @("enforce.derived")
9 @safe unittest {
10     import std.array: array;
11 
12     string msg, file;
13     size_t line, expectedLine;
14     () @safe {
15         try {
16             expectedLine = __LINE__ + 1;
17             () @nogc { enforce(false, "foo", 5, "bar"); }();
18         } catch(NoGcException ex) {
19             msg = ex.msg.array;
20             file = ex.file.idup;
21             line = ex.line;
22         }
23     }();
24 
25     msg.should == "foo5bar";
26     file.should == __FILE__;
27     line.should == expectedLine;
28 }
29 
30 
31 @("enforce.base")
32 @safe unittest {
33     import std.array: array;
34 
35     string msg, file;
36     size_t line, expectedLine;
37     () @safe {
38         try {
39             expectedLine = __LINE__ + 1;
40             () @nogc { enforce(false, "foo", 5, "bar"); }();
41         } catch(Exception ex) {
42             // not copying here on purpose - the compiler can't help
43             msg = ex.msg;
44             file = ex.file;
45             line = ex.line;
46         }
47     }();
48 
49     // no way of getting msg from the base class
50     msg.should == "";
51     file.should == __FILE__;
52     line.should == expectedLine;
53 }
54 
55 
56 version(FIXME) {
57     @("TestAllocator")
58         @safe @nogc unittest {
59 
60         import test_allocator;
61         static TestAllocator allocator;
62 
63         alias MyException = NoGcExceptionImpl!(TestAllocator*);
64 
65         // just to make sure it compiles
66         void func() {
67             throw new MyException(&allocator, 42, " foobar ", 33.3);
68         }
69     }
70 }
71 
72 
73 @("malloc")
74 @safe @nogc unittest {
75 
76     import std.algorithm: equal;
77 
78     try
79         throw new NoGcException(42, " foobar ", 33.3);
80     catch(NoGcException e) {
81         assert(equal(e.msg, "42 foobar 33.300000"), "msg not what expected");
82         assert(e.file == __FILE__);
83         assert(e.line == __LINE__ - 4);
84     }
85 }
86 
87 
88 @("derived exception")
89 @safe @nogc unittest {
90 
91     static class MyException: NoGcException {
92 
93         static int numInstances;
94 
95         this(A...)(auto ref A args) {
96             import std.functional: forward;
97             super(forward!args);
98             ++numInstances;
99         }
100 
101         ~this() {
102             --numInstances;
103         }
104     }
105 
106     try {
107         assert(MyException.numInstances == 0);
108         throw new MyException(42, " foobar ", 33.3);
109     } catch(MyException e) {
110         assert(MyException.numInstances == 1);
111     }
112 
113     static if(__VERSION__ > 2086)
114         assert(MyException.numInstances == 0);
115 }
116 
117 
118 @("throw.base")
119 @safe @nogc unittest {
120     try
121         NoGcException.throw_(File("foo.d"), Line(42),
122                              "this is the message ", 33, " or ", 77.7, " hah");
123     catch(Exception e) {
124         assert(e.line == 42);
125         debug {
126             e.file.should == "foo.d";
127             e.line.should == 42;
128             // msg not available via Exception
129             e.msg.should == "";
130         }
131         return;
132     }
133 
134     assert(false, "Didn't catch the exception");
135 }
136 
137 
138 @("throw.child")
139 @safe @nogc unittest {
140 
141     import std.array: array;
142 
143     static class MyException: NoGcException {
144         mixin NoGcExceptionCtors;
145     }
146 
147     try
148         MyException.throw_(File("foo.d"), Line(42),
149                            "this is the message ", 33, " or ", 77.7, " hah");
150     catch(MyException e) {
151         assert(e.line == 42);
152         debug {
153             e.file.should == "foo.d";
154             e.line.should == 42;
155             e.msg.array.should == "this is the message 33 or 77.700000 hah";
156         }
157         return;
158     }
159 
160     assert(false, "Didn't catch the exception");
161 }