1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.Assert;
13 
14 import std.algorithm;
15 import std.array;
16 import std.conv;
17 import std.exception;
18 import std.format;
19 import std.math;
20 import std.range;
21 import std.range;
22 import std.traits;
23 
24 import hunt.logging;
25 import hunt.Exceptions;
26 
27 
28 class Matchers {
29     static T[] contains(T)(T[] items...) {
30         T[] r;
31         foreach (T item; items)
32             r ~= item;
33         return r;
34     }
35 
36     // bool containsString(string source, string item)
37     // {
38 
39     // }
40 
41 }
42 
43 /**
44  * A set of assertion methods useful for writing tests. Only failed assertions
45  * are recorded. These methods can be used directly:
46  * <code>Assert.assertEquals(...)</code>, however, they read better if they
47  * are referenced through static import:
48  *
49  * <pre>
50  * import org.junit.Assert.*;
51  *    ...
52  *    assertEquals(...);
53  * </pre>
54  *
55  * @see AssertionError
56  */
57 class Assert {
58     /**
59      * Protect constructor since it is a static only class
60      */
61     protected this() {
62     }
63 
64     /**
65      * Asserts that a condition is true. If it isn't it throws an
66      * {@link AssertionError} with the given message.
67      *
68      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
69      * okay)
70      * @param condition condition to be checked
71      */
72     static void assertTrue(string message, bool condition) {
73         if (!condition) {
74             fail(message);
75         }
76     }
77 
78     /**
79      * Asserts that a condition is true. If it isn't it throws an
80      * {@link AssertionError} without a message.
81      *
82      * @param condition condition to be checked
83      */
84     static void assertTrue(bool condition) {
85         assertTrue(null, condition);
86     }
87 
88     /**
89      * Asserts that a condition is false. If it isn't it throws an
90      * {@link AssertionError} with the given message.
91      *
92      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
93      * okay)
94      * @param condition condition to be checked
95      */
96     static void assertFalse(
97             string message, bool condition) {
98         assertTrue(message, !condition);
99     }
100 
101     /**
102      * Asserts that a condition is false. If it isn't it throws an
103      * {@link AssertionError} without a message.
104      *
105      * @param condition condition to be checked
106      */
107     static void assertFalse(bool condition) {
108         assertFalse(null, condition);
109     }
110 
111     /**
112      * Fails a test with the given message.
113      *
114      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
115      * okay)
116      * @see AssertionError
117      */
118     static void fail(string message) {
119 
120         // if (message.empty)
121         //     message = std.format.format("raised in %s:%s", file, line);
122         // else
123         //     message = std.format.format("raised in %s:%s, message: %s", file, line, message);
124 
125         throw new AssertionError(message, cast(Throwable) null);
126     }
127 
128     /**
129      * Fails a test with no message.
130      */
131     static void fail() {
132         fail(null);
133     }
134 
135     /**
136      * Asserts that two objects are equal. If they are not, an
137      * {@link AssertionError} is thrown with the given message. If
138      * <code>expected</code> and <code>actual</code> are <code>null</code>,
139      * they are considered equal.
140      *
141      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
142      * okay)
143      * @param expected expected value
144      * @param actual actual value
145      */
146     static void assertEquals(T, size_t line = __LINE__, string file = __FILE__)(
147             string message, T expected, T actual) {
148         version (HUNT_DEBUG_MORE) {
149             trace("expected: ", expected);
150             trace("actual: ", actual);
151         }
152 
153         static if (is(T == class)) {
154             assert(expected == actual, message);
155         } else {
156             assert(expected == actual, message);
157         }
158     }
159 
160     private static bool equalsRegardingNull(Object expected, Object actual) {
161         if (expected is null) {
162             return actual is null;
163         }
164 
165         return isEquals(expected, actual);
166     }
167 
168     private static bool isEquals(Object expected, Object actual) {
169         return expected.opEquals(actual);
170     }
171 
172     /**
173      * Asserts that two objects are equal. If they are not, an
174      * {@link AssertionError} without a message is thrown. If
175      * <code>expected</code> and <code>actual</code> are <code>null</code>,
176      * they are considered equal.
177      *
178      * @param expected expected value
179      * @param actual the value to check against <code>expected</code>
180      */
181     static void assertEquals(T, size_t line = __LINE__, string file = __FILE__)(T expected, T actual) {
182         assertEquals!(T, line, file)(null, expected, actual);
183     }
184 
185     /**
186      * Asserts that two objects are <b>not</b> equals. If they are, an
187      * {@link AssertionError} is thrown with the given message. If
188      * <code>unexpected</code> and <code>actual</code> are <code>null</code>,
189      * they are considered equal.
190      *
191      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
192      * okay)
193      * @param unexpected unexpected value to check
194      * @param actual the value to check against <code>unexpected</code>
195      */
196     static void assertNotEquals(string message, Object unexpected, Object actual) {
197         if (equalsRegardingNull(unexpected, actual)) {
198             failEquals(message, actual);
199         }
200     }
201 
202     /**
203      * Asserts that two objects are <b>not</b> equals. If they are, an
204      * {@link AssertionError} without a message is thrown. If
205      * <code>unexpected</code> and <code>actual</code> are <code>null</code>,
206      * they are considered equal.
207      *
208      * @param unexpected unexpected value to check
209      * @param actual the value to check against <code>unexpected</code>
210      */
211     static void assertNotEquals(Object unexpected, Object actual) {
212         assertNotEquals(null, unexpected, actual);
213     }
214 
215     private static void failEquals(string message, Object actual) {
216         string formatted = "Values should be different. ";
217         if (message !is null) {
218             formatted = message ~ ". ";
219         }
220 
221         formatted ~= "Actual: " ~ actual.toString();
222         fail(formatted);
223     }
224 
225     private static void failEquals(T)(string message, T actual) if (isNumeric!T) {
226         string formatted = "Values should be different. ";
227         if (message !is null) {
228             formatted = message ~ ". ";
229         }
230 
231         formatted ~= "Actual: " ~ to!string(actual);
232         fail(formatted);
233     }
234 
235     /**
236      * Asserts that two longs are <b>not</b> equals. If they are, an
237      * {@link AssertionError} is thrown with the given message.
238      *
239      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
240      * okay)
241      * @param unexpected unexpected value to check
242      * @param actual the value to check against <code>unexpected</code>
243      */
244     static void assertNotEquals(string message, long unexpected, long actual) {
245         if (unexpected == actual) {
246             failEquals(message, actual);
247         }
248     }
249 
250     /**
251      * Asserts that two longs are <b>not</b> equals. If they are, an
252      * {@link AssertionError} without a message is thrown.
253      *
254      * @param unexpected unexpected value to check
255      * @param actual the value to check against <code>unexpected</code>
256      */
257     static void assertNotEquals(long unexpected, long actual) {
258         assertNotEquals(null, unexpected, actual);
259     }
260 
261     /**
262      * Asserts that two doubles are <b>not</b> equal to within a positive delta.
263      * If they are, an {@link AssertionError} is thrown with the given
264      * message. If the unexpected value is infinity then the delta value is
265      * ignored. NaNs are considered equal:
266      * <code>assertNotEquals(Double.NaN, Double.NaN, *)</code> fails
267      *
268      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
269      * okay)
270      * @param unexpected unexpected value
271      * @param actual the value to check against <code>unexpected</code>
272      * @param delta the maximum delta between <code>unexpected</code> and
273      * <code>actual</code> for which both numbers are still
274      * considered equal.
275      */
276     static void assertNotEquals(string message, double unexpected, double actual, double delta) {
277         if (!doubleIsDifferent(unexpected, actual, delta)) {
278             failEquals(message, actual);
279         }
280     }
281 
282     /**
283      * Asserts that two doubles are <b>not</b> equal to within a positive delta.
284      * If they are, an {@link AssertionError} is thrown. If the unexpected
285      * value is infinity then the delta value is ignored.NaNs are considered
286      * equal: <code>assertNotEquals(Double.NaN, Double.NaN, *)</code> fails
287      *
288      * @param unexpected unexpected value
289      * @param actual the value to check against <code>unexpected</code>
290      * @param delta the maximum delta between <code>unexpected</code> and
291      * <code>actual</code> for which both numbers are still
292      * considered equal.
293      */
294     static void assertNotEquals(double unexpected, double actual, double delta) {
295         assertNotEquals(null, unexpected, actual, delta);
296     }
297 
298     /**
299      * Asserts that two floats are <b>not</b> equal to within a positive delta.
300      * If they are, an {@link AssertionError} is thrown. If the unexpected
301      * value is infinity then the delta value is ignored.NaNs are considered
302      * equal: <code>assertNotEquals(Float.NaN, Float.NaN, *)</code> fails
303      *
304      * @param unexpected unexpected value
305      * @param actual the value to check against <code>unexpected</code>
306      * @param delta the maximum delta between <code>unexpected</code> and
307      * <code>actual</code> for which both numbers are still
308      * considered equal.
309      */
310     static void assertNotEquals(float unexpected, float actual, float delta) {
311         assertNotEquals(null, unexpected, actual, delta);
312     }
313 
314     /**
315      * Asserts that two object arrays are equal. If they are not, an
316      * {@link AssertionError} is thrown with the given message. If
317      * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
318      * they are considered equal.
319      *
320      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
321      * okay)
322      * @param expecteds Object array or array of arrays (multi-dimensional array) with
323      * expected values.
324      * @param actuals Object array or array of arrays (multi-dimensional array) with
325      * actual values
326      */
327     static void assertArrayEquals(T)(string message, T[] expecteds, T[] actuals) {
328         internalArrayEquals(message, expecteds, actuals);
329     }
330 
331     /**
332      * Asserts that two object arrays are equal. If they are not, an
333      * {@link AssertionError} is thrown. If <code>expected</code> and
334      * <code>actual</code> are <code>null</code>, they are considered
335      * equal.
336      *
337      * @param expecteds Object array or array of arrays (multi-dimensional array) with
338      * expected values
339      * @param actuals Object array or array of arrays (multi-dimensional array) with
340      * actual values
341      */
342     static void assertArrayEquals(T)(T[] expecteds, T[] actuals) {
343         assertArrayEquals(null, expecteds, actuals);
344     }
345 
346     /**
347      * Asserts that two object arrays are equal. If they are not, an
348      * {@link AssertionError} is thrown with the given message. If
349      * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
350      * they are considered equal.
351      *
352      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
353      * okay)
354      * @param expecteds Object array or array of arrays (multi-dimensional array) with
355      * expected values.
356      * @param actuals Object array or array of arrays (multi-dimensional array) with
357      * actual values
358      */
359     private static void internalArrayEquals(T)(string message, T[] expecteds, T[] actuals) {
360         // new ExactComparisonCriteria().arrayEquals(message, expecteds, actuals);
361         assert(expecteds.length == actuals.length, message);
362         for (int i = 0; i < expecteds.length; i++) {
363             assertEquals(message, expecteds[i], actuals[i]);
364         }
365     }
366 
367     /**
368      * Asserts that two doubles are equal to within a positive delta.
369      * If they are not, an {@link AssertionError} is thrown with the given
370      * message. If the expected value is infinity then the delta value is
371      * ignored. NaNs are considered equal:
372      * <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes
373      *
374      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
375      * okay)
376      * @param expected expected value
377      * @param actual the value to check against <code>expected</code>
378      * @param delta the maximum delta between <code>expected</code> and
379      * <code>actual</code> for which both numbers are still
380      * considered equal.
381      */
382     static void assertEquals(
383             string message, double expected, double actual, double delta) {
384         if (doubleIsDifferent(expected, actual, delta)) {
385             failNotEquals!(double)(message, expected, actual);
386         }
387     }
388 
389     /**
390      * Asserts that two floats are equal to within a positive delta.
391      * If they are not, an {@link AssertionError} is thrown with the given
392      * message. If the expected value is infinity then the delta value is
393      * ignored. NaNs are considered equal:
394      * <code>assertEquals(Float.NaN, Float.NaN, *)</code> passes
395      *
396      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
397      * okay)
398      * @param expected expected value
399      * @param actual the value to check against <code>expected</code>
400      * @param delta the maximum delta between <code>expected</code> and
401      * <code>actual</code> for which both numbers are still
402      * considered equal.
403      */
404     static void assertEquals(string message, float expected, float actual, float delta) {
405         if (floatIsDifferent(expected, actual, delta)) {
406             failNotEquals(message, expected, actual);
407         }
408     }
409 
410     /**
411      * Asserts that two floats are <b>not</b> equal to within a positive delta.
412      * If they are, an {@link AssertionError} is thrown with the given
413      * message. If the unexpected value is infinity then the delta value is
414      * ignored. NaNs are considered equal:
415      * <code>assertNotEquals(Float.NaN, Float.NaN, *)</code> fails
416      *
417      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
418      * okay)
419      * @param unexpected unexpected value
420      * @param actual the value to check against <code>unexpected</code>
421      * @param delta the maximum delta between <code>unexpected</code> and
422      * <code>actual</code> for which both numbers are still
423      * considered equal.
424      */
425     static void assertNotEquals(string message, float unexpected, float actual, float delta) {
426         if (!floatIsDifferent(unexpected, actual, delta)) {
427             failEquals(message, actual);
428         }
429     }
430 
431     static private bool doubleIsDifferent(double d1, double d2, double delta) {
432         if (d1 == d2) {
433             return false;
434         }
435         if ((std.math.abs(d1 - d2) <= delta)) {
436             return false;
437         }
438 
439         return true;
440     }
441 
442     static private bool floatIsDifferent(float f1, float f2, float delta) {
443         if (f1 == f2) {
444             return false;
445         }
446         if ((std.math.abs(f1 - f2) <= delta)) {
447             return false;
448         }
449 
450         return true;
451     }
452 
453     /**
454      * Asserts that two longs are equal. If they are not, an
455      * {@link AssertionError} is thrown.
456      *
457      * @param expected expected long value.
458      * @param actual actual long value
459      */
460     static void assertEquals(long expected, long actual) {
461         assertEquals(null, expected, actual);
462     }
463 
464     /**
465      * Asserts that two longs are equal. If they are not, an
466      * {@link AssertionError} is thrown with the given message.
467      *
468      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
469      * okay)
470      * @param expected long expected value.
471      * @param actual long actual value
472      */
473     static void assertEquals(string message, long expected, long actual) {
474         if (expected != actual) {
475             failNotEquals(message, expected, actual);
476         }
477     }
478 
479     /**
480      * @deprecated Use
481      *             <code>assertEquals(double expected, double actual, double delta)</code>
482      *             instead
483      */
484     // deprecated("")
485     // static void assertEquals(double expected, double actual) {
486     //     assertEquals(null, expected, actual);
487     // }
488 
489     /**
490      * @deprecated Use
491      *             <code>assertEquals(string message, double expected, double actual, double delta)</code>
492      *             instead
493      */
494     // deprecated("")
495     // static void assertEquals(string message, double expected,
496     //         double actual) {
497     //     fail("Use assertEquals(expected, actual, delta) to compare floating-point numbers");
498     // }
499 
500     /**
501      * Asserts that two doubles are equal to within a positive delta.
502      * If they are not, an {@link AssertionError} is thrown. If the expected
503      * value is infinity then the delta value is ignored.NaNs are considered
504      * equal: <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes
505      *
506      * @param expected expected value
507      * @param actual the value to check against <code>expected</code>
508      * @param delta the maximum delta between <code>expected</code> and
509      * <code>actual</code> for which both numbers are still
510      * considered equal.
511      */
512     static void assertEquals(double expected, double actual, double delta) {
513         assertEquals(null, expected, actual, delta);
514     }
515 
516     /**
517      * Asserts that two floats are equal to within a positive delta.
518      * If they are not, an {@link AssertionError} is thrown. If the expected
519      * value is infinity then the delta value is ignored. NaNs are considered
520      * equal: <code>assertEquals(Float.NaN, Float.NaN, *)</code> passes
521      *
522      * @param expected expected value
523      * @param actual the value to check against <code>expected</code>
524      * @param delta the maximum delta between <code>expected</code> and
525      * <code>actual</code> for which both numbers are still
526      * considered equal.
527      */
528 
529     static void assertEquals(float expected, float actual, float delta) {
530         assertEquals(null, expected, actual, delta);
531     }
532 
533     /**
534      * Asserts that an object isn't null. If it is an {@link AssertionError} is
535      * thrown with the given message.
536      *
537      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
538      * okay)
539      * @param object Object to check or <code>null</code>
540      */
541     static void assertNotNull(T)(string message, T object) {
542         assertTrue(message, object !is null);
543     }
544 
545     /**
546      * Asserts that an object isn't null. If it is an {@link AssertionError} is
547      * thrown.
548      *
549      * @param object Object to check or <code>null</code>
550      */
551     static void assertNotNull(T)(T object) {
552         assertNotNull!(T)(null, object);
553     }
554 
555     /**
556      * Asserts that an object is null. If it is not, an {@link AssertionError}
557      * is thrown with the given message.
558      *
559      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
560      * okay)
561      * @param object Object to check or <code>null</code>
562      */
563     static void assertNull(T, size_t line = __LINE__, string file = __FILE__)(
564             string message, T object) {
565         static if (is(T == class) || is(T == interface)) {
566             if (object is null)
567                 return;
568         } else static if (is(T == struct)) {
569             if (object == T.init)
570                 return;
571         } else {
572             if (object.empty)
573                 return;
574         }
575         failNotNull!(T, line, file)(message, object);
576     }
577 
578     /**
579      * Asserts that an object is null. If it isn't an {@link AssertionError} is
580      * thrown.
581      *
582      * @param object Object to check or <code>null</code>
583      */
584     static void assertNull(T, size_t line = __LINE__, string file = __FILE__)(T object) {
585         assertNull!(T, line, file)(null, object);
586     }
587 
588     static private void failNotNull(T, size_t line = __LINE__, string file = __FILE__)(
589             string message, T actual) {
590         string formatted = "";
591         if (message !is null) {
592             formatted = message ~ " ";
593         }
594         static if (is(T == class)) {
595             fail(formatted ~ "expected null, but was:<" ~ actual.toString() ~ ">");
596         } else {
597             fail(formatted ~ "expected null, but was:<" ~ to!string(actual) ~ ">");
598         }
599     }
600 
601     /**
602      * Asserts that two objects refer to the same object. If they are not, an
603      * {@link AssertionError} is thrown with the given message.
604      *
605      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
606      * okay)
607      * @param expected the expected object
608      * @param actual the object to compare to <code>expected</code>
609      */
610     static void assertSame(T, size_t line = __LINE__, string file = __FILE__)(
611             string message, T expected, T actual) {
612         if (expected is actual) {
613             return;
614         }
615         failNotSame!(T, line, file)(message, expected, actual);
616     }
617 
618     /**
619      * Asserts that two objects refer to the same object. If they are not the
620      * same, an {@link AssertionError} without a message is thrown.
621      *
622      * @param expected the expected object
623      * @param actual the object to compare to <code>expected</code>
624      */
625     static void assertSame(T, size_t line = __LINE__, string file = __FILE__)(T expected, T actual) {
626         assertSame!(T, line, file)(null, expected, actual);
627     }
628 
629     /**
630      * Asserts that two objects do not refer to the same object. If they do
631      * refer to the same object, an {@link AssertionError} is thrown with the
632      * given message.
633      *
634      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
635      * okay)
636      * @param unexpected the object you don't expect
637      * @param actual the object to compare to <code>unexpected</code>
638      */
639     static void assertNotSame(T, size_t line = __LINE__, string file = __FILE__)(
640             string message, T unexpected, T actual) {
641         if (unexpected == actual) {
642             failSame(message);
643         }
644     }
645 
646     /**
647      * Asserts that two objects do not refer to the same object. If they do
648      * refer to the same object, an {@link AssertionError} without a message is
649      * thrown.
650      *
651      * @param unexpected the object you don't expect
652      * @param actual the object to compare to <code>unexpected</code>
653      */
654     static void assertNotSame(T, size_t line = __LINE__, string file = __FILE__)(
655             T unexpected, T actual) {
656         assertNotSame!(T, line, file)("", unexpected, actual);
657     }
658 
659     static private void failSame(string message) {
660         string formatted = "";
661         if (!message.empty) {
662             formatted = message ~ " ";
663         }
664         fail(formatted ~ "expected not same");
665     }
666 
667     static private void failNotSame(T, size_t line = __LINE__, string file = __FILE__)(
668             string message, T expected, T actual) {
669         string formatted = "";
670         if (!message.empty) {
671             formatted = message ~ " ";
672         }
673         fail(formatted ~ "expected same:<" ~ typeid(expected)
674                 .toString() ~ "> was not:<" ~ typeid(actual).toString() ~ ">");
675     }
676 
677     static private void failNotEquals(T)(
678             string message, T expected, T actual) {
679         fail(format(message, expected, actual));
680     }
681 
682     static string format(T)(string message, T expected, T actual)
683             if (is(T == class) || is(T == struct) || is(T == interface)) {
684         string formatted = "";
685         if (!message.empty) {
686             formatted = message ~ " ";
687         }
688         string expectedString = expected.toString();
689         string actualString = actual.toString();
690         if (expectedString == actualString) {
691             return formatted ~ "expected: " ~ formatClassAndValue(expected,
692                     expectedString) ~ " but was: " ~ formatClassAndValue(actual, actualString);
693         } else {
694             return formatted ~ "expected:<" ~ expectedString ~ "> but was:<" ~ actualString ~ ">";
695         }
696     }
697 
698     // static private void failNotEquals(T, size_t line = __LINE__, string file = __FILE__)
699     //     (string message, T expected, T actual)
700     //         if (isNumeric!T) {
701     //     fail(format(message, expected, actual));
702     // }
703 
704     static string format(T)(string message, T expected, T actual) if (isNumeric!T) {
705         string formatted = "";
706         if (!message.empty) {
707             formatted = message ~ " ";
708         }
709         string expectedString = to!string(expected);
710         string actualString = to!string(actual);
711         if (expected != actual) {
712             return formatted ~ "expected: " ~ expectedString ~ " but was: " ~ actualString;
713         } else {
714             return formatted;
715         }
716     }
717 
718     private static string formatClassAndValue(Object value, string valueString) {
719         string className = value is null ? "null" : typeof(value).stringof;
720         return className ~ "<" ~ valueString ~ ">";
721     }
722 
723     /**
724      * Asserts that two object arrays are equal. If they are not, an
725      * {@link AssertionError} is thrown with the given message. If
726      * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
727      * they are considered equal.
728      *
729      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
730      * okay)
731      * @param expecteds Object array or array of arrays (multi-dimensional array) with
732      * expected values.
733      * @param actuals Object array or array of arrays (multi-dimensional array) with
734      * actual values
735      * @deprecated use assertArrayEquals
736      */
737     // deprecated("")
738     // static void assertEquals(string message, Object[] expecteds,
739     //         Object[] actuals) {
740     //     assertArrayEquals(message, expecteds, actuals);
741     // }
742 
743     /**
744      * Asserts that two object arrays are equal. If they are not, an
745      * {@link AssertionError} is thrown. If <code>expected</code> and
746      * <code>actual</code> are <code>null</code>, they are considered
747      * equal.
748      *
749      * @param expecteds Object array or array of arrays (multi-dimensional array) with
750      * expected values
751      * @param actuals Object array or array of arrays (multi-dimensional array) with
752      * actual values
753      * @deprecated use assertArrayEquals
754      */
755     // deprecated("")
756     // static void assertEquals(Object[] expecteds, Object[] actuals) {
757     //     assertArrayEquals(expecteds, actuals);
758     // }
759 
760     /**
761      * Asserts that <code>actual</code> satisfies the condition specified by
762      * <code>matcher</code>. If not, an {@link AssertionError} is thrown with
763      * information about the matcher and failing value. Example:
764      *
765      * <pre>
766      *   assertThat(0, is(1)); // fails:
767      *     // failure message:
768      *     // expected: is &lt;1&gt;
769      *     // got value: &lt;0&gt;
770      *   assertThat(0, is(not(1))) // passes
771      * </pre>
772      *
773      * <code>org.hamcrest.Matcher</code> does not currently document the meaning
774      * of its type parameter <code>T</code>.  This method assumes that a matcher
775      * typed as <code>Matcher&lt;T&gt;</code> can be meaningfully applied only
776      * to values that could be assigned to a variable of type <code>T</code>.
777      *
778      * @param (T) the static type accepted by the matcher (this can flag obvious
779      * compile-time problems such as {@code assertThat(1, is("a"))}
780      * @param actual the computed value being compared
781      * @param matcher an expression, built of {@link Matcher}s, specifying allowed
782      * values
783      * @see org.hamcrest.CoreMatchers
784      * @see org.hamcrest.MatcherAssert
785      */
786     static void assertThat(T, size_t line = __LINE__, string file = __FILE__)(T actual, T matcher) {
787         assertThat!(T, line, file)("", actual, matcher);
788     }
789 
790     /**
791      * Asserts that <code>actual</code> satisfies the condition specified by
792      * <code>matcher</code>. If not, an {@link AssertionError} is thrown with
793      * the reason and information about the matcher and failing value. Example:
794      *
795      * <pre>
796      *   assertThat(&quot;Help! Integers don't work&quot;, 0, is(1)); // fails:
797      *     // failure message:
798      *     // Help! Integers don't work
799      *     // expected: is &lt;1&gt;
800      *     // got value: &lt;0&gt;
801      *   assertThat(&quot;Zero is one&quot;, 0, is(not(1))) // passes
802      * </pre>
803      *
804      * <code>org.hamcrest.Matcher</code> does not currently document the meaning
805      * of its type parameter <code>T</code>.  This method assumes that a matcher
806      * typed as <code>Matcher&lt;T&gt;</code> can be meaningfully applied only
807      * to values that could be assigned to a variable of type <code>T</code>.
808      *
809      * @param reason additional information about the error
810      * @param (T) the static type accepted by the matcher (this can flag obvious
811      * compile-time problems such as {@code assertThat(1, is("a"))}
812      * @param actual the computed value being compared
813      * @param matcher an expression, built of {@link Matcher}s, specifying allowed
814      * values
815      * @see org.hamcrest.CoreMatchers
816      * @see org.hamcrest.MatcherAssert
817      */
818     static void assertThat(T, size_t line = __LINE__, string file = __FILE__)(
819             string message, T actual, T matcher) {
820         // trace("actual=>", actual);
821         // trace("matcher=>", matcher);
822         // if (message.empty)
823         //     message = std.format.format("raised in %s:%s", file, line);
824         // else
825         //     message = std.format.format("raised in %s:%s, reason: %s", file, line, message);
826         assert(actual == matcher, message);
827     }
828 
829     static void assertContain(T)(T source, T substring) {
830         assert(source.canFind(substring), source);
831     }
832 
833     static void assertStartsWith(T)(T source, T substring) {
834         assert(source.startsWith(substring));
835     }
836 
837     /**
838 	 * Assert a bool expression, throwing {@code IllegalStateException} if
839 	 * the test result is {@code false}. Call isTrue if you wish to throw
840 	 * IllegalArgumentException on an assertion failure.
841 	 * 
842 	 * <pre class="code">
843 	 * Assert.state(id is null, "The id property must not already be initialized");
844 	 * </pre>
845 	 * 
846 	 * @param expression
847 	 *            a bool expression
848 	 * @param message
849 	 *            the exception message to use if the assertion fails
850 	 * @throws IllegalStateException
851 	 *             if expression is {@code false}
852 	 */
853     static void state(bool expression, string message) {
854         if (!expression) {
855             throw new IllegalStateException(message);
856         }
857     }
858 }
859 
860 
861 
862 alias assertArrayEquals = Assert.assertArrayEquals;
863 alias assertTrue = Assert.assertTrue;
864 alias assertFalse = Assert.assertFalse;
865 alias assertThat = Assert.assertThat;
866 alias assertEquals = Assert.assertEquals;
867 alias assertNotNull = Assert.assertNotNull;
868 alias assertNull = Assert.assertNull;
869 alias assertSame = Assert.assertSame;
870 alias fail = Assert.fail;