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