1 /** A Better assert. 2 3 Copyright: Per Nordlöw 2018-. 4 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 5 Authors: $(WEB Per Nordlöw) 6 7 TODO: make these @safe pure nothrow @nogc by utilizing dynamic_array and printf 8 9 extend to something like: 10 11 - must!"a == b"(x, y); 12 - check!"a == b"(x, y); 13 - require!"a == b"(x, y); 14 */ 15 module nxt.assert_ex; 16 17 // import std.string : format; 18 import core.exception : AssertError; 19 import std.conv: to; 20 21 @trusted: 22 23 /// Returns: true if the expression throws. 24 bool assertThrows(T:Throwable = Exception, E)(lazy E expression, 25 string msg = T.stringof, 26 string file = __FILE__, 27 int line = __LINE__ ) 28 { 29 try 30 { 31 std.exception.assertThrown!T(expression, msg, file, line); 32 return true; 33 } 34 catch (Throwable exc) 35 { 36 // FIXTHIS: unhelpful error message 37 writeln("failed at ", baseName(file), "(", line, "):", 38 " Did not throw \"", msg, "\"."); 39 return false; 40 } 41 } 42 43 nothrow: 44 45 /** A Better assert. 46 See_Also: http://poita.org/2012/09/02/a-better-assert-for-d.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+poita+%28poita.org%29 47 TODO: Can we convert args to strings like GCC's __STRING(expression)? 48 TODO: Make these be able to be called in unittest placed in struct scopes 49 */ 50 void assertTrue(T, 51 string file = __FILE__, uint line = __LINE__, 52 Args...) (T test, lazy Args args) 53 { 54 version(assert) if (!test) 55 { 56 throw new AssertError("at \n" ~file~ ":" ~to!string(line)~ ":\n test: " ~to!string(test)); 57 } 58 } 59 alias assertT = assertTrue; 60 61 void assertEqual(T, U, 62 string file = __FILE__, uint line = __LINE__, 63 Args...)(T lhs, U rhs, 64 lazy Args args) // TODO: use args 65 { 66 version(assert) if (lhs != rhs) 67 { 68 throw new AssertError("at \n" ~file~ ":" ~to!string(line)~ ":\n lhs: " ~to!string(lhs)~ " !=\n rhs: " ~to!string(rhs)); 69 } 70 } 71 alias assertE = assertEqual; 72 73 // @safe pure unittest 74 // { 75 // assertEqual([1], [2, 3]); 76 // } 77 78 void assertLessThanOrEqual(T, U, 79 string file = __FILE__, 80 uint line = __LINE__, 81 Args...) (T lhs, U rhs, 82 lazy Args args) // TODO: use args 83 { 84 version(assert) if (lhs > rhs) 85 { 86 throw new AssertError("at \n" ~file~ ":" ~to!string(line)~ ":\n lhs: " ~to!string(lhs)~ " >\n rhs: " ~to!string(rhs)); 87 } 88 } 89 alias assertLTE = assertLessThanOrEqual; 90 91 void assertLessThan(T, U, 92 string file = __FILE__, uint line = __LINE__, 93 Args...) (T lhs, U rhs, 94 lazy Args args) // TODO: use args 95 { 96 version(assert) if (lhs >= rhs) 97 { 98 throw new AssertError("at \n" ~file~ ":" ~to!string(line)~ ":\n lhs: " ~to!string(lhs)~ " >=\n rhs: " ~to!string(rhs)); 99 } 100 } 101 alias assertLT = assertLessThan; 102 103 void assertNotEqual(T, U, 104 string file = __FILE__, uint line = __LINE__, 105 Args...) (T lhs, U rhs, 106 lazy Args args) // TODO: use args 107 { 108 version(assert) if (lhs == rhs) 109 { 110 throw new AssertError("at \n" ~file~ ":" ~to!string(line)~ ":\n lhs: " ~to!string(lhs)~ " ==\n rhs: " ~to!string(rhs)); 111 } 112 } 113 alias assertNE = assertNotEqual;