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 class AssertionError : Error {
28     // this(string file = __FILE__, size_t line = __LINE__,
29     //      Throwable next = null) @nogc @safe pure nothrow
30     // {
31     //     super("", file, line, next);
32     // }
33 
34     mixin basicExceptionCtors;
35 }
36 
37 class Matchers {
38     static T[] contains(T)(T[] items...) {
39         T[] r;
40         foreach (T item; items)
41             r ~= item;
42         return r;
43     }
44 
45     // bool containsString(string source, string item)
46     // {
47 
48     // }
49 
50 }
51 
52 /**
53  * A set of assertion methods useful for writing tests. Only failed assertions
54  * are recorded. These methods can be used directly:
55  * <code>Assert.assertEquals(...)</code>, however, they read better if they
56  * are referenced through static import:
57  *
58  * <pre>
59  * import org.junit.Assert.*;
60  *    ...
61  *    assertEquals(...);
62  * </pre>
63  *
64  * @see AssertionError
65  * @since 4.0
66  */
67 class Assert {
68     /**
69      * Protect constructor since it is a static only class
70      */
71     protected this() {
72     }
73 
74     /**
75      * Asserts that a condition is true. If it isn't it throws an
76      * {@link AssertionError} with the given message.
77      *
78      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
79      * okay)
80      * @param condition condition to be checked
81      */
82     static void assertTrue(string message, bool condition) {
83         if (!condition) {
84             fail(message);
85         }
86     }
87 
88     /**
89      * Asserts that a condition is true. If it isn't it throws an
90      * {@link AssertionError} without a message.
91      *
92      * @param condition condition to be checked
93      */
94     static void assertTrue(bool condition) {
95         assertTrue(null, condition);
96     }
97 
98     /**
99      * Asserts that a condition is false. If it isn't it throws an
100      * {@link AssertionError} with the given message.
101      *
102      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
103      * okay)
104      * @param condition condition to be checked
105      */
106     static void assertFalse(
107             string message, bool condition) {
108         assertTrue(message, !condition);
109     }
110 
111     /**
112      * Asserts that a condition is false. If it isn't it throws an
113      * {@link AssertionError} without a message.
114      *
115      * @param condition condition to be checked
116      */
117     static void assertFalse(bool condition) {
118         assertFalse(null, condition);
119     }
120 
121     /**
122      * Fails a test with the given message.
123      *
124      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
125      * okay)
126      * @see AssertionError
127      */
128     static void fail(string message) {
129 
130         // if (message.empty)
131         //     message = std.format.format("raised in %s:%s", file, line);
132         // else
133         //     message = std.format.format("raised in %s:%s, message: %s", file, line, message);
134 
135         throw new AssertionError(message, cast(Throwable) null);
136     }
137 
138     /**
139      * Fails a test with no message.
140      */
141     static void fail() {
142         fail(null);
143     }
144 
145     /**
146      * Asserts that two objects are equal. If they are not, an
147      * {@link AssertionError} is thrown with the given message. If
148      * <code>expected</code> and <code>actual</code> are <code>null</code>,
149      * they are considered equal.
150      *
151      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
152      * okay)
153      * @param expected expected value
154      * @param actual actual value
155      */
156     static void assertEquals(T, size_t line = __LINE__, string file = __FILE__)(
157             string message, T expected, T actual) {
158         // if (!message.empty)
159         //     message = std.format.format("raised in %s:%s, message: %s", file, line, message);
160         // else
161         //     message = std.format.format("raised in %s:%s", file, line);
162 
163         version (HUNT_DEBUG) {
164             trace("expected: ", expected);
165             trace("actual: ", actual);
166         }
167 
168         static if (is(T == class)) {
169             assert(expected == actual, message);
170         } else {
171             assert(expected == actual, message);
172         }
173     }
174 
175     private static bool equalsRegardingNull(Object expected, Object actual) {
176         if (expected is null) {
177             return actual is null;
178         }
179 
180         return isEquals(expected, actual);
181     }
182 
183     private static bool isEquals(Object expected, Object actual) {
184         return expected.opEquals(actual);
185     }
186 
187     /**
188      * Asserts that two objects are equal. If they are not, an
189      * {@link AssertionError} without a message is thrown. If
190      * <code>expected</code> and <code>actual</code> are <code>null</code>,
191      * they are considered equal.
192      *
193      * @param expected expected value
194      * @param actual the value to check against <code>expected</code>
195      */
196     static void assertEquals(T, size_t line = __LINE__, string file = __FILE__)(T expected, T actual) {
197         assertEquals!(T, line, file)(null, expected, actual);
198     }
199 
200     /**
201      * Asserts that two objects are <b>not</b> equals. If they are, an
202      * {@link AssertionError} is thrown with the given message. If
203      * <code>unexpected</code> and <code>actual</code> are <code>null</code>,
204      * they are considered equal.
205      *
206      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
207      * okay)
208      * @param unexpected unexpected value to check
209      * @param actual the value to check against <code>unexpected</code>
210      */
211     static void assertNotEquals(string message, Object unexpected, Object actual) {
212         if (equalsRegardingNull(unexpected, actual)) {
213             failEquals(message, actual);
214         }
215     }
216 
217     /**
218      * Asserts that two objects are <b>not</b> equals. If they are, an
219      * {@link AssertionError} without a message is thrown. If
220      * <code>unexpected</code> and <code>actual</code> are <code>null</code>,
221      * they are considered equal.
222      *
223      * @param unexpected unexpected value to check
224      * @param actual the value to check against <code>unexpected</code>
225      */
226     static void assertNotEquals(Object unexpected, Object actual) {
227         assertNotEquals(null, unexpected, actual);
228     }
229 
230     private static void failEquals(string message, Object actual) {
231         string formatted = "Values should be different. ";
232         if (message !is null) {
233             formatted = message ~ ". ";
234         }
235 
236         formatted ~= "Actual: " ~ actual.toString();
237         fail(formatted);
238     }
239 
240     private static void failEquals(T)(string message, T actual) if (isNumeric!T) {
241         string formatted = "Values should be different. ";
242         if (message !is null) {
243             formatted = message ~ ". ";
244         }
245 
246         formatted ~= "Actual: " ~ to!string(actual);
247         fail(formatted);
248     }
249 
250     /**
251      * Asserts that two longs are <b>not</b> equals. If they are, an
252      * {@link AssertionError} is thrown with the given message.
253      *
254      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
255      * okay)
256      * @param unexpected unexpected value to check
257      * @param actual the value to check against <code>unexpected</code>
258      */
259     static void assertNotEquals(string message, long unexpected, long actual) {
260         if (unexpected == actual) {
261             failEquals(message, actual);
262         }
263     }
264 
265     /**
266      * Asserts that two longs are <b>not</b> equals. If they are, an
267      * {@link AssertionError} without a message is thrown.
268      *
269      * @param unexpected unexpected value to check
270      * @param actual the value to check against <code>unexpected</code>
271      */
272     static void assertNotEquals(long unexpected, long actual) {
273         assertNotEquals(null, unexpected, actual);
274     }
275 
276     /**
277      * Asserts that two doubles are <b>not</b> equal to within a positive delta.
278      * If they are, an {@link AssertionError} is thrown with the given
279      * message. If the unexpected value is infinity then the delta value is
280      * ignored. NaNs are considered equal:
281      * <code>assertNotEquals(Double.NaN, Double.NaN, *)</code> fails
282      *
283      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
284      * okay)
285      * @param unexpected unexpected value
286      * @param actual the value to check against <code>unexpected</code>
287      * @param delta the maximum delta between <code>unexpected</code> and
288      * <code>actual</code> for which both numbers are still
289      * considered equal.
290      */
291     static void assertNotEquals(string message, double unexpected, double actual, double delta) {
292         if (!doubleIsDifferent(unexpected, actual, delta)) {
293             failEquals(message, actual);
294         }
295     }
296 
297     /**
298      * Asserts that two doubles are <b>not</b> equal to within a positive delta.
299      * If they are, an {@link AssertionError} is thrown. If the unexpected
300      * value is infinity then the delta value is ignored.NaNs are considered
301      * equal: <code>assertNotEquals(Double.NaN, Double.NaN, *)</code> fails
302      *
303      * @param unexpected unexpected value
304      * @param actual the value to check against <code>unexpected</code>
305      * @param delta the maximum delta between <code>unexpected</code> and
306      * <code>actual</code> for which both numbers are still
307      * considered equal.
308      */
309     static void assertNotEquals(double unexpected, double actual, double delta) {
310         assertNotEquals(null, unexpected, actual, delta);
311     }
312 
313     /**
314      * Asserts that two floats are <b>not</b> equal to within a positive delta.
315      * If they are, an {@link AssertionError} is thrown. If the unexpected
316      * value is infinity then the delta value is ignored.NaNs are considered
317      * equal: <code>assertNotEquals(Float.NaN, Float.NaN, *)</code> fails
318      *
319      * @param unexpected unexpected value
320      * @param actual the value to check against <code>unexpected</code>
321      * @param delta the maximum delta between <code>unexpected</code> and
322      * <code>actual</code> for which both numbers are still
323      * considered equal.
324      */
325     static void assertNotEquals(float unexpected, float actual, float delta) {
326         assertNotEquals(null, unexpected, actual, delta);
327     }
328 
329     /**
330      * Asserts that two object arrays are equal. If they are not, an
331      * {@link AssertionError} is thrown with the given message. If
332      * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
333      * they are considered equal.
334      *
335      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
336      * okay)
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(string message, Object[] expecteds, Object[] actuals) {
343         internalArrayEquals(message, expecteds, actuals);
344     }
345 
346     /**
347      * Asserts that two object arrays are equal. If they are not, an
348      * {@link AssertionError} is thrown. If <code>expected</code> and
349      * <code>actual</code> are <code>null</code>, they are considered
350      * equal.
351      *
352      * @param expecteds Object array or array of arrays (multi-dimensional array) with
353      * expected values
354      * @param actuals Object array or array of arrays (multi-dimensional array) with
355      * actual values
356      */
357     static void assertArrayEquals(Object[] expecteds, Object[] actuals) {
358         assertArrayEquals(null, expecteds, actuals);
359     }
360 
361     /**
362      * Asserts that two bool arrays are equal. If they are not, an
363      * {@link AssertionError} is thrown with the given message. If
364      * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
365      * they are considered equal.
366      *
367      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
368      * okay)
369      * @param expecteds bool array with expected values.
370      * @param actuals bool array with expected values.
371      */
372     static void assertArrayEquals(string message, bool[] expecteds, bool[] actuals) {
373         internalArrayEquals(message, expecteds, actuals);
374     }
375 
376     /**
377      * Asserts that two bool arrays are equal. If they are not, an
378      * {@link AssertionError} is thrown. If <code>expected</code> and
379      * <code>actual</code> are <code>null</code>, they are considered
380      * equal.
381      *
382      * @param expecteds bool array with expected values.
383      * @param actuals bool array with expected values.
384      */
385     static void assertArrayEquals(bool[] expecteds, bool[] actuals) {
386         assertArrayEquals(null, expecteds, actuals);
387     }
388 
389     /**
390      * Asserts that two byte arrays are equal. If they are not, an
391      * {@link AssertionError} is thrown with the given message.
392      *
393      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
394      * okay)
395      * @param expecteds byte array with expected values.
396      * @param actuals byte array with actual values
397      */
398     static void assertArrayEquals(string message, byte[] expecteds, byte[] actuals) {
399         internalArrayEquals(message, expecteds, actuals);
400     }
401 
402     /**
403      * Asserts that two byte arrays are equal. If they are not, an
404      * {@link AssertionError} is thrown.
405      *
406      * @param expecteds byte array with expected values.
407      * @param actuals byte array with actual values
408      */
409     static void assertArrayEquals(byte[] expecteds, byte[] actuals) {
410         assertArrayEquals(null, expecteds, actuals);
411     }
412 
413     /**
414      * Asserts that two char arrays are equal. If they are not, an
415      * {@link AssertionError} is thrown with the given message.
416      *
417      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
418      * okay)
419      * @param expecteds char array with expected values.
420      * @param actuals char array with actual values
421      */
422     static void assertArrayEquals(string message, char[] expecteds, char[] actuals) {
423         internalArrayEquals(message, expecteds, actuals);
424     }
425 
426     /**
427      * Asserts that two char arrays are equal. If they are not, an
428      * {@link AssertionError} is thrown.
429      *
430      * @param expecteds char array with expected values.
431      * @param actuals char array with actual values
432      */
433     static void assertArrayEquals(char[] expecteds, char[] actuals) {
434         assertArrayEquals(null, expecteds, actuals);
435     }
436 
437     /**
438      * Asserts that two short arrays are equal. If they are not, an
439      * {@link AssertionError} is thrown with the given message.
440      *
441      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
442      * okay)
443      * @param expecteds short array with expected values.
444      * @param actuals short array with actual values
445      */
446     static void assertArrayEquals(string message, short[] expecteds, short[] actuals) {
447         internalArrayEquals(message, expecteds, actuals);
448     }
449 
450     /**
451      * Asserts that two short arrays are equal. If they are not, an
452      * {@link AssertionError} is thrown.
453      *
454      * @param expecteds short array with expected values.
455      * @param actuals short array with actual values
456      */
457     static void assertArrayEquals(short[] expecteds, short[] actuals) {
458         assertArrayEquals(null, expecteds, actuals);
459     }
460 
461     /**
462      * Asserts that two int arrays are equal. If they are not, an
463      * {@link AssertionError} is thrown with the given message.
464      *
465      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
466      * okay)
467      * @param expecteds int array with expected values.
468      * @param actuals int array with actual values
469      */
470     static void assertArrayEquals(string message, int[] expecteds, int[] actuals) {
471         internalArrayEquals(message, expecteds, actuals);
472     }
473 
474     /**
475      * Asserts that two int arrays are equal. If they are not, an
476      * {@link AssertionError} is thrown.
477      *
478      * @param expecteds int array with expected values.
479      * @param actuals int array with actual values
480      */
481     static void assertArrayEquals(int[] expecteds, int[] actuals) {
482         assertArrayEquals(null, expecteds, actuals);
483     }
484 
485     /**
486      * Asserts that two long arrays are equal. If they are not, an
487      * {@link AssertionError} is thrown with the given message.
488      *
489      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
490      * okay)
491      * @param expecteds long array with expected values.
492      * @param actuals long array with actual values
493      */
494     static void assertArrayEquals(string message, long[] expecteds, long[] actuals) {
495         internalArrayEquals(message, expecteds, actuals);
496     }
497 
498     /**
499      * Asserts that two long arrays are equal. If they are not, an
500      * {@link AssertionError} is thrown.
501      *
502      * @param expecteds long array with expected values.
503      * @param actuals long array with actual values
504      */
505     static void assertArrayEquals(long[] expecteds, long[] actuals) {
506         assertArrayEquals(null, expecteds, actuals);
507     }
508 
509     /**
510      * Asserts that two double arrays are equal. If they are not, an
511      * {@link AssertionError} is thrown with the given message.
512      *
513      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
514      * okay)
515      * @param expecteds double array with expected values.
516      * @param actuals double array with actual values
517      * @param delta the maximum delta between <code>expecteds[i]</code> and
518      * <code>actuals[i]</code> for which both numbers are still
519      * considered equal.
520      */
521     // static void assertArrayEquals(string message, double[] expecteds,
522     //         double[] actuals, double delta){
523     //     // new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals);
524     // }
525 
526     /**
527      * Asserts that two double arrays are equal. If they are not, an
528      * {@link AssertionError} is thrown.
529      *
530      * @param expecteds double array with expected values.
531      * @param actuals double array with actual values
532      * @param delta the maximum delta between <code>expecteds[i]</code> and
533      * <code>actuals[i]</code> for which both numbers are still
534      * considered equal.
535      */
536     // static void assertArrayEquals(double[] expecteds, double[] actuals, double delta) {
537     //     assertArrayEquals(null, expecteds, actuals, delta);
538     // }
539 
540     /**
541      * Asserts that two float arrays are equal. If they are not, an
542      * {@link AssertionError} is thrown with the given message.
543      *
544      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
545      * okay)
546      * @param expecteds float array with expected values.
547      * @param actuals float array with actual values
548      * @param delta the maximum delta between <code>expecteds[i]</code> and
549      * <code>actuals[i]</code> for which both numbers are still
550      * considered equal.
551      */
552     // static void assertArrayEquals(string message, float[] expecteds,
553     //         float[] actuals, float delta){
554     //     new InexactComparisonCriteria(delta).arrayEquals(message, expecteds, actuals);
555     // }
556 
557     /**
558      * Asserts that two float arrays are equal. If they are not, an
559      * {@link AssertionError} is thrown.
560      *
561      * @param expecteds float array with expected values.
562      * @param actuals float array with actual values
563      * @param delta the maximum delta between <code>expecteds[i]</code> and
564      * <code>actuals[i]</code> for which both numbers are still
565      * considered equal.
566      */
567     // static void assertArrayEquals(float[] expecteds, float[] actuals, float delta) {
568     //     assertArrayEquals(null, expecteds, actuals, delta);
569     // }
570 
571     /**
572      * Asserts that two object arrays are equal. If they are not, an
573      * {@link AssertionError} is thrown with the given message. If
574      * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
575      * they are considered equal.
576      *
577      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
578      * okay)
579      * @param expecteds Object array or array of arrays (multi-dimensional array) with
580      * expected values.
581      * @param actuals Object array or array of arrays (multi-dimensional array) with
582      * actual values
583      */
584     private static void internalArrayEquals(T)(string message, T[] expecteds, T[] actuals) {
585         // new ExactComparisonCriteria().arrayEquals(message, expecteds, actuals);
586         assert(expecteds.length == actuals.length, message);
587         for (int i = 0; i < expecteds.length; i++) {
588             assertEquals(message, expecteds[i], actuals[i]);
589         }
590     }
591 
592     /**
593      * Asserts that two doubles are equal to within a positive delta.
594      * If they are not, an {@link AssertionError} is thrown with the given
595      * message. If the expected value is infinity then the delta value is
596      * ignored. NaNs are considered equal:
597      * <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes
598      *
599      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
600      * okay)
601      * @param expected expected value
602      * @param actual the value to check against <code>expected</code>
603      * @param delta the maximum delta between <code>expected</code> and
604      * <code>actual</code> for which both numbers are still
605      * considered equal.
606      */
607     static void assertEquals(
608             string message, double expected, double actual, double delta) {
609         if (doubleIsDifferent(expected, actual, delta)) {
610             failNotEquals!(double)(message, expected, actual);
611         }
612     }
613 
614     /**
615      * Asserts that two floats are equal to within a positive delta.
616      * If they are not, an {@link AssertionError} is thrown with the given
617      * message. If the expected value is infinity then the delta value is
618      * ignored. NaNs are considered equal:
619      * <code>assertEquals(Float.NaN, Float.NaN, *)</code> passes
620      *
621      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
622      * okay)
623      * @param expected expected value
624      * @param actual the value to check against <code>expected</code>
625      * @param delta the maximum delta between <code>expected</code> and
626      * <code>actual</code> for which both numbers are still
627      * considered equal.
628      */
629     static void assertEquals(string message, float expected, float actual, float delta) {
630         if (floatIsDifferent(expected, actual, delta)) {
631             failNotEquals(message, expected, actual);
632         }
633     }
634 
635     /**
636      * Asserts that two floats are <b>not</b> equal to within a positive delta.
637      * If they are, an {@link AssertionError} is thrown with the given
638      * message. If the unexpected value is infinity then the delta value is
639      * ignored. NaNs are considered equal:
640      * <code>assertNotEquals(Float.NaN, Float.NaN, *)</code> fails
641      *
642      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
643      * okay)
644      * @param unexpected unexpected value
645      * @param actual the value to check against <code>unexpected</code>
646      * @param delta the maximum delta between <code>unexpected</code> and
647      * <code>actual</code> for which both numbers are still
648      * considered equal.
649      */
650     static void assertNotEquals(string message, float unexpected, float actual, float delta) {
651         if (!floatIsDifferent(unexpected, actual, delta)) {
652             failEquals(message, actual);
653         }
654     }
655 
656     static private bool doubleIsDifferent(double d1, double d2, double delta) {
657         if (d1 == d2) {
658             return false;
659         }
660         if ((std.math.abs(d1 - d2) <= delta)) {
661             return false;
662         }
663 
664         return true;
665     }
666 
667     static private bool floatIsDifferent(float f1, float f2, float delta) {
668         if (f1 == f2) {
669             return false;
670         }
671         if ((std.math.abs(f1 - f2) <= delta)) {
672             return false;
673         }
674 
675         return true;
676     }
677 
678     /**
679      * Asserts that two longs are equal. If they are not, an
680      * {@link AssertionError} is thrown.
681      *
682      * @param expected expected long value.
683      * @param actual actual long value
684      */
685     static void assertEquals(long expected, long actual) {
686         assertEquals(null, expected, actual);
687     }
688 
689     /**
690      * Asserts that two longs are equal. If they are not, an
691      * {@link AssertionError} is thrown with the given message.
692      *
693      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
694      * okay)
695      * @param expected long expected value.
696      * @param actual long actual value
697      */
698     static void assertEquals(string message, long expected, long actual) {
699         if (expected != actual) {
700             failNotEquals(message, expected, actual);
701         }
702     }
703 
704     /**
705      * @deprecated Use
706      *             <code>assertEquals(double expected, double actual, double delta)</code>
707      *             instead
708      */
709     // deprecated("")
710     // static void assertEquals(double expected, double actual) {
711     //     assertEquals(null, expected, actual);
712     // }
713 
714     /**
715      * @deprecated Use
716      *             <code>assertEquals(string message, double expected, double actual, double delta)</code>
717      *             instead
718      */
719     // deprecated("")
720     // static void assertEquals(string message, double expected,
721     //         double actual) {
722     //     fail("Use assertEquals(expected, actual, delta) to compare floating-point numbers");
723     // }
724 
725     /**
726      * Asserts that two doubles are equal to within a positive delta.
727      * If they are not, an {@link AssertionError} is thrown. If the expected
728      * value is infinity then the delta value is ignored.NaNs are considered
729      * equal: <code>assertEquals(Double.NaN, Double.NaN, *)</code> passes
730      *
731      * @param expected expected value
732      * @param actual the value to check against <code>expected</code>
733      * @param delta the maximum delta between <code>expected</code> and
734      * <code>actual</code> for which both numbers are still
735      * considered equal.
736      */
737     static void assertEquals(double expected, double actual, double delta) {
738         assertEquals(null, expected, actual, delta);
739     }
740 
741     /**
742      * Asserts that two floats are equal to within a positive delta.
743      * If they are not, an {@link AssertionError} is thrown. If the expected
744      * value is infinity then the delta value is ignored. NaNs are considered
745      * equal: <code>assertEquals(Float.NaN, Float.NaN, *)</code> passes
746      *
747      * @param expected expected value
748      * @param actual the value to check against <code>expected</code>
749      * @param delta the maximum delta between <code>expected</code> and
750      * <code>actual</code> for which both numbers are still
751      * considered equal.
752      */
753 
754     static void assertEquals(float expected, float actual, float delta) {
755         assertEquals(null, expected, actual, delta);
756     }
757 
758     /**
759      * Asserts that an object isn't null. If it is an {@link AssertionError} is
760      * thrown with the given message.
761      *
762      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
763      * okay)
764      * @param object Object to check or <code>null</code>
765      */
766     static void assertNotNull(T)(string message, T object) {
767         assertTrue(message, object !is null);
768     }
769 
770     /**
771      * Asserts that an object isn't null. If it is an {@link AssertionError} is
772      * thrown.
773      *
774      * @param object Object to check or <code>null</code>
775      */
776     static void assertNotNull(T)(T object) {
777         assertNotNull!(T)(null, object);
778     }
779 
780     /**
781      * Asserts that an object is null. If it is not, an {@link AssertionError}
782      * is thrown with the given message.
783      *
784      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
785      * okay)
786      * @param object Object to check or <code>null</code>
787      */
788     static void assertNull(T, size_t line = __LINE__, string file = __FILE__)(
789             string message, T object) {
790         static if (is(T == class) || is(T == interface)) {
791             if (object is null)
792                 return;
793         } else static if (is(T == struct)) {
794             if (object == T.init)
795                 return;
796         } else {
797             if (object.empty)
798                 return;
799         }
800         failNotNull!(T, line, file)(message, object);
801     }
802 
803     /**
804      * Asserts that an object is null. If it isn't an {@link AssertionError} is
805      * thrown.
806      *
807      * @param object Object to check or <code>null</code>
808      */
809     static void assertNull(T, size_t line = __LINE__, string file = __FILE__)(T object) {
810         assertNull!(T, line, file)(null, object);
811     }
812 
813     static private void failNotNull(T, size_t line = __LINE__, string file = __FILE__)(
814             string message, T actual) {
815         string formatted = "";
816         if (message !is null) {
817             formatted = message ~ " ";
818         }
819         static if (is(T == class)) {
820             fail(formatted ~ "expected null, but was:<" ~ actual.toString() ~ ">");
821         } else {
822             fail(formatted ~ "expected null, but was:<" ~ to!string(actual) ~ ">");
823         }
824     }
825 
826     /**
827      * Asserts that two objects refer to the same object. If they are not, an
828      * {@link AssertionError} is thrown with the given message.
829      *
830      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
831      * okay)
832      * @param expected the expected object
833      * @param actual the object to compare to <code>expected</code>
834      */
835     static void assertSame(T, size_t line = __LINE__, string file = __FILE__)(
836             string message, T expected, T actual) {
837         if (expected == actual) {
838             return;
839         }
840         failNotSame!(T, line, file)(message, expected, actual);
841     }
842 
843     /**
844      * Asserts that two objects refer to the same object. If they are not the
845      * same, an {@link AssertionError} without a message is thrown.
846      *
847      * @param expected the expected object
848      * @param actual the object to compare to <code>expected</code>
849      */
850     static void assertSame(T, size_t line = __LINE__, string file = __FILE__)(T expected, T actual) {
851         assertSame!(T, line, file)(null, expected, actual);
852     }
853 
854     /**
855      * Asserts that two objects do not refer to the same object. If they do
856      * refer to the same object, an {@link AssertionError} is thrown with the
857      * given message.
858      *
859      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
860      * okay)
861      * @param unexpected the object you don't expect
862      * @param actual the object to compare to <code>unexpected</code>
863      */
864     static void assertNotSame(T, size_t line = __LINE__, string file = __FILE__)(
865             string message, T unexpected, T actual) {
866         if (unexpected == actual) {
867             failSame(message);
868         }
869     }
870 
871     /**
872      * Asserts that two objects do not refer to the same object. If they do
873      * refer to the same object, an {@link AssertionError} without a message is
874      * thrown.
875      *
876      * @param unexpected the object you don't expect
877      * @param actual the object to compare to <code>unexpected</code>
878      */
879     static void assertNotSame(T, size_t line = __LINE__, string file = __FILE__)(
880             T unexpected, T actual) {
881         assertNotSame!(T, line, file)("", unexpected, actual);
882     }
883 
884     static private void failSame(string message) {
885         string formatted = "";
886         if (!message.empty) {
887             formatted = message ~ " ";
888         }
889         fail(formatted ~ "expected not same");
890     }
891 
892     static private void failNotSame(T, size_t line = __LINE__, string file = __FILE__)(
893             string message, T expected, T actual) {
894         string formatted = "";
895         if (!message.empty) {
896             formatted = message ~ " ";
897         }
898         fail(formatted ~ "expected same:<" ~ typeid(expected)
899                 .toString() ~ "> was not:<" ~ typeid(actual).toString() ~ ">");
900     }
901 
902     static private void failNotEquals(T)(
903             string message, T expected, T actual) {
904         fail(format(message, expected, actual));
905     }
906 
907     static string format(T)(string message, T expected, T actual)
908             if (is(T == class) || is(T == struct) || is(T == interface)) {
909         string formatted = "";
910         if (!message.empty) {
911             formatted = message ~ " ";
912         }
913         string expectedString = expected.toString();
914         string actualString = actual.toString();
915         if (expectedString == actualString) {
916             return formatted ~ "expected: " ~ formatClassAndValue(expected,
917                     expectedString) ~ " but was: " ~ formatClassAndValue(actual, actualString);
918         } else {
919             return formatted ~ "expected:<" ~ expectedString ~ "> but was:<" ~ actualString ~ ">";
920         }
921     }
922 
923     // static private void failNotEquals(T, size_t line = __LINE__, string file = __FILE__)
924     //     (string message, T expected, T actual)
925     //         if (isNumeric!T) {
926     //     fail(format(message, expected, actual));
927     // }
928 
929     static string format(T)(string message, T expected, T actual) if (isNumeric!T) {
930         string formatted = "";
931         if (!message.empty) {
932             formatted = message ~ " ";
933         }
934         string expectedString = to!string(expected);
935         string actualString = to!string(actual);
936         if (expected != actual) {
937             return formatted ~ "expected: " ~ expectedString ~ " but was: " ~ actualString;
938         } else {
939             return formatted;
940         }
941     }
942 
943     private static string formatClassAndValue(Object value, string valueString) {
944         string className = value is null ? "null" : typeof(value).stringof;
945         return className ~ "<" ~ valueString ~ ">";
946     }
947 
948     /**
949      * Asserts that two object arrays are equal. If they are not, an
950      * {@link AssertionError} is thrown with the given message. If
951      * <code>expecteds</code> and <code>actuals</code> are <code>null</code>,
952      * they are considered equal.
953      *
954      * @param message the identifying message for the {@link AssertionError} (<code>null</code>
955      * okay)
956      * @param expecteds Object array or array of arrays (multi-dimensional array) with
957      * expected values.
958      * @param actuals Object array or array of arrays (multi-dimensional array) with
959      * actual values
960      * @deprecated use assertArrayEquals
961      */
962     // deprecated("")
963     // static void assertEquals(string message, Object[] expecteds,
964     //         Object[] actuals) {
965     //     assertArrayEquals(message, expecteds, actuals);
966     // }
967 
968     /**
969      * Asserts that two object arrays are equal. If they are not, an
970      * {@link AssertionError} is thrown. If <code>expected</code> and
971      * <code>actual</code> are <code>null</code>, they are considered
972      * equal.
973      *
974      * @param expecteds Object array or array of arrays (multi-dimensional array) with
975      * expected values
976      * @param actuals Object array or array of arrays (multi-dimensional array) with
977      * actual values
978      * @deprecated use assertArrayEquals
979      */
980     // deprecated("")
981     // static void assertEquals(Object[] expecteds, Object[] actuals) {
982     //     assertArrayEquals(expecteds, actuals);
983     // }
984 
985     /**
986      * Asserts that <code>actual</code> satisfies the condition specified by
987      * <code>matcher</code>. If not, an {@link AssertionError} is thrown with
988      * information about the matcher and failing value. Example:
989      *
990      * <pre>
991      *   assertThat(0, is(1)); // fails:
992      *     // failure message:
993      *     // expected: is &lt;1&gt;
994      *     // got value: &lt;0&gt;
995      *   assertThat(0, is(not(1))) // passes
996      * </pre>
997      *
998      * <code>org.hamcrest.Matcher</code> does not currently document the meaning
999      * of its type parameter <code>T</code>.  This method assumes that a matcher
1000      * typed as <code>Matcher&lt;T&gt;</code> can be meaningfully applied only
1001      * to values that could be assigned to a variable of type <code>T</code>.
1002      *
1003      * @param (T) the static type accepted by the matcher (this can flag obvious
1004      * compile-time problems such as {@code assertThat(1, is("a"))}
1005      * @param actual the computed value being compared
1006      * @param matcher an expression, built of {@link Matcher}s, specifying allowed
1007      * values
1008      * @see org.hamcrest.CoreMatchers
1009      * @see org.hamcrest.MatcherAssert
1010      */
1011     static void assertThat(T, size_t line = __LINE__, string file = __FILE__)(T actual, T matcher) {
1012         assertThat!(T, line, file)("", actual, matcher);
1013     }
1014 
1015     /**
1016      * Asserts that <code>actual</code> satisfies the condition specified by
1017      * <code>matcher</code>. If not, an {@link AssertionError} is thrown with
1018      * the reason and information about the matcher and failing value. Example:
1019      *
1020      * <pre>
1021      *   assertThat(&quot;Help! Integers don't work&quot;, 0, is(1)); // fails:
1022      *     // failure message:
1023      *     // Help! Integers don't work
1024      *     // expected: is &lt;1&gt;
1025      *     // got value: &lt;0&gt;
1026      *   assertThat(&quot;Zero is one&quot;, 0, is(not(1))) // passes
1027      * </pre>
1028      *
1029      * <code>org.hamcrest.Matcher</code> does not currently document the meaning
1030      * of its type parameter <code>T</code>.  This method assumes that a matcher
1031      * typed as <code>Matcher&lt;T&gt;</code> can be meaningfully applied only
1032      * to values that could be assigned to a variable of type <code>T</code>.
1033      *
1034      * @param reason additional information about the error
1035      * @param (T) the static type accepted by the matcher (this can flag obvious
1036      * compile-time problems such as {@code assertThat(1, is("a"))}
1037      * @param actual the computed value being compared
1038      * @param matcher an expression, built of {@link Matcher}s, specifying allowed
1039      * values
1040      * @see org.hamcrest.CoreMatchers
1041      * @see org.hamcrest.MatcherAssert
1042      */
1043     static void assertThat(T, size_t line = __LINE__, string file = __FILE__)(
1044             string message, T actual, T matcher) {
1045         // trace("actual=>", actual);
1046         // trace("matcher=>", matcher);
1047         // if (message.empty)
1048         //     message = std.format.format("raised in %s:%s", file, line);
1049         // else
1050         //     message = std.format.format("raised in %s:%s, reason: %s", file, line, message);
1051         assert(actual == matcher, message);
1052     }
1053 
1054     static void assertContain(T)(T source, T substring) {
1055         assert(source.canFind(substring), source);
1056     }
1057 
1058     static void assertStartsWith(T)(T source, T substring) {
1059         assert(source.startsWith(substring));
1060     }
1061 
1062     /**
1063 	 * Assert a bool expression, throwing {@code IllegalStateException} if
1064 	 * the test result is {@code false}. Call isTrue if you wish to throw
1065 	 * IllegalArgumentException on an assertion failure.
1066 	 * 
1067 	 * <pre class="code">
1068 	 * Assert.state(id is null, "The id property must not already be initialized");
1069 	 * </pre>
1070 	 * 
1071 	 * @param expression
1072 	 *            a bool expression
1073 	 * @param message
1074 	 *            the exception message to use if the assertion fails
1075 	 * @throws IllegalStateException
1076 	 *             if expression is {@code false}
1077 	 */
1078     static void state(bool expression, string message) {
1079         if (!expression) {
1080             throw new IllegalStateException(message);
1081         }
1082     }
1083 }