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 <1> 994 * // got value: <0> 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<T></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("Help! Integers don't work", 0, is(1)); // fails: 1022 * // failure message: 1023 * // Help! Integers don't work 1024 * // expected: is <1> 1025 * // got value: <0> 1026 * assertThat("Zero is one", 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<T></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 }