1 /** A Better assert. 2 3 Copyright: Per Nordlöw 2022-. 4 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 5 Authors: $(WEB Per Nordlöw) 6 7 TODO: make these pure nothrow @safe @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 try { 29 std.exception.assertThrown!T(expression, msg, file, line); 30 return true; 31 } catch (Throwable exc) { 32 // FIXTHIS: unhelpful error message 33 writeln("failed at ", baseName(file), "(", line, "):", 34 " Did not throw \"", msg, "\"."); 35 return false; 36 } 37 } 38 39 nothrow: 40 41 /** A Better assert. 42 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 43 TODO: Can we convert args to strings like GCC's __STRING(expression)? 44 TODO: Make these be able to be called in unittest placed in struct scopes 45 */ 46 void assertTrue(T, 47 string file = __FILE__, uint line = __LINE__, 48 Args...) (T test, lazy Args args) { 49 version (assert) if (!test) { 50 throw new AssertError("at \n" ~file~ ":" ~to!string(line)~ ":\n test: " ~to!string(test)); 51 } 52 } 53 alias assertT = assertTrue; 54 55 void assertEqual(T, U, 56 string file = __FILE__, uint line = __LINE__, 57 Args...)(T lhs, U rhs, 58 lazy Args args) /+ TODO: use args +/ 59 { 60 version (assert) if (lhs != rhs) { 61 throw new AssertError("at \n" ~file~ ":" ~to!string(line)~ ":\n lhs: " ~to!string(lhs)~ " !=\n rhs: " ~to!string(rhs)); 62 } 63 } 64 alias assertE = assertEqual; 65 66 void assertLessThanOrEqual(T, U, 67 string file = __FILE__, 68 uint line = __LINE__, 69 Args...) (T lhs, U rhs, 70 lazy Args args) /+ TODO: use args +/ 71 { 72 version (assert) if (lhs > rhs) { 73 throw new AssertError("at \n" ~file~ ":" ~to!string(line)~ ":\n lhs: " ~to!string(lhs)~ " >\n rhs: " ~to!string(rhs)); 74 } 75 } 76 alias assertLTE = assertLessThanOrEqual; 77 78 void assertLessThan(T, U, 79 string file = __FILE__, uint line = __LINE__, 80 Args...) (T lhs, U rhs, 81 lazy Args args) /+ TODO: use args +/ 82 { 83 version (assert) if (lhs >= rhs) { 84 throw new AssertError("at \n" ~file~ ":" ~to!string(line)~ ":\n lhs: " ~to!string(lhs)~ " >=\n rhs: " ~to!string(rhs)); 85 } 86 } 87 alias assertLT = assertLessThan; 88 89 void assertNotEqual(T, U, 90 string file = __FILE__, uint line = __LINE__, 91 Args...) (T lhs, U rhs, 92 lazy Args args) /+ TODO: use args +/ 93 { 94 version (assert) if (lhs == rhs) { 95 throw new AssertError("at \n" ~file~ ":" ~to!string(line)~ ":\n lhs: " ~to!string(lhs)~ " ==\n rhs: " ~to!string(rhs)); 96 } 97 } 98 alias assertNE = assertNotEqual;