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 }