1 /** 2 Exception classes 3 */ 4 module unit_threaded.exception; 5 6 void fail(const string output, const string file, size_t line) @safe pure 7 { 8 throw new UnitTestException([output], file, line); 9 } 10 11 void fail(const string[] lines, const string file, size_t line) @safe pure 12 { 13 throw new UnitTestException(lines, file, line); 14 } 15 16 /** 17 * An exception to signal that a test case has failed. 18 */ 19 public class UnitTestException : Exception 20 { 21 mixin UnitTestFailureImpl; 22 } 23 24 public class UnitTestError : Error 25 { 26 mixin UnitTestFailureImpl; 27 } 28 29 private template UnitTestFailureImpl() 30 { 31 this(const string msg, string file = __FILE__, 32 size_t line = __LINE__, Throwable next = null) @safe pure nothrow 33 { 34 this([msg], file, line, next); 35 } 36 37 this(const string[] msgLines, string file = __FILE__, 38 size_t line = __LINE__, Throwable next = null) @safe pure nothrow 39 { 40 import std.string: join; 41 static if (is(typeof(this) : Exception)) 42 { 43 super(msgLines.join("\n"), next, file.dup, line); 44 } 45 else 46 { 47 super(msgLines.join("\n"), file.dup, line, next); 48 } 49 this.msgLines = msgLines.dup; 50 } 51 52 override string toString() @safe const pure scope 53 { 54 import std.algorithm: map; 55 import std.array: join; 56 return msgLines.map!(a => getOutputPrefix(file, line) ~ a).join("\n"); 57 } 58 59 private: 60 61 const string[] msgLines; 62 63 string getOutputPrefix(in string file, in size_t line) @safe const pure scope 64 { 65 import std.conv: text; 66 return text(" ", file, ":", line, " - "); 67 } 68 }