1 module unit_threaded.ut.should; 2 3 import unit_threaded.should; 4 import unit_threaded.asserts; 5 6 private void assertFail(E)(lazy E expression, in string file = __FILE__, in size_t line = __LINE__) 7 { 8 import std.exception: assertThrown; 9 assertThrown!UnitTestException(expression, null, file, line); 10 } 11 12 13 @safe pure unittest { 14 static struct Foo { 15 bool opCast(T: bool)() { 16 return true; 17 } 18 } 19 shouldBeTrue(Foo()); 20 } 21 22 23 @safe pure unittest { 24 static struct Foo { 25 bool opCast(T: bool)() { 26 return false; 27 } 28 } 29 shouldBeFalse(Foo()); 30 } 31 32 @safe unittest { 33 //impure comparisons 34 shouldEqual(1.0, 1.0) ; 35 } 36 37 @safe pure unittest { 38 import unit_threaded.asserts; 39 40 assertExceptionMsg(3.shouldEqual(5), 41 " tests/unit_threaded/ut/should.d:123 - Expected: 5\n" ~ 42 " tests/unit_threaded/ut/should.d:123 - Got: 3"); 43 44 assertExceptionMsg("foo".shouldEqual("bar"), 45 " tests/unit_threaded/ut/should.d:123 - Expected: \"bar\"\n" ~ 46 " tests/unit_threaded/ut/should.d:123 - Got: \"foo\""); 47 48 assertExceptionMsg([1, 2, 4].shouldEqual([1, 2, 3]), 49 " tests/unit_threaded/ut/should.d:123 - Expected: [1, 2, 3]\n" ~ 50 " tests/unit_threaded/ut/should.d:123 - Got: [1, 2, 4]"); 51 52 assertExceptionMsg([[0, 1, 2, 3, 4], [1], [2], [3], [4], [5]].shouldEqual([[0], [1], [2]]), 53 " tests/unit_threaded/ut/should.d:123 - Expected: [[0], [1], [2]]\n" ~ 54 " tests/unit_threaded/ut/should.d:123 - Got: [[0, 1, 2, 3, 4], [1], [2], [3], [4], [5]]"); 55 56 assertExceptionMsg([[0, 1, 2, 3, 4, 5], [1], [2], [3]].shouldEqual([[0], [1], [2]]), 57 " tests/unit_threaded/ut/should.d:123 - Expected: [[0], [1], [2]]\n" ~ 58 " tests/unit_threaded/ut/should.d:123 - Got: [[0, 1, 2, 3, 4, 5], [1], [2], [3]]"); 59 60 61 assertExceptionMsg([[0, 1, 2, 3, 4, 5], [1], [2], [3], [4], [5]].shouldEqual([[0]]), 62 " tests/unit_threaded/ut/should.d:123 - Expected: [[0]]\n" ~ 63 " tests/unit_threaded/ut/should.d:123 - Got: [\n" ~ 64 " tests/unit_threaded/ut/should.d:123 - [0, 1, 2, 3, 4, 5],\n" ~ 65 " tests/unit_threaded/ut/should.d:123 - [1],\n" ~ 66 " tests/unit_threaded/ut/should.d:123 - [2],\n" ~ 67 " tests/unit_threaded/ut/should.d:123 - [3],\n" ~ 68 " tests/unit_threaded/ut/should.d:123 - [4],\n" ~ 69 " tests/unit_threaded/ut/should.d:123 - [5],\n" ~ 70 " tests/unit_threaded/ut/should.d:123 - ]"); 71 72 assertExceptionMsg(1.shouldNotEqual(1), 73 " tests/unit_threaded/ut/should.d:123 - Value:\n" ~ 74 " tests/unit_threaded/ut/should.d:123 - 1\n" ~ 75 " tests/unit_threaded/ut/should.d:123 - is not expected to be equal to:\n" ~ 76 " tests/unit_threaded/ut/should.d:123 - 1"); 77 } 78 79 @safe pure unittest 80 { 81 ubyte[] arr; 82 arr.shouldEqual([]); 83 } 84 85 86 @safe pure unittest 87 { 88 int[] ints = [1, 2, 3]; 89 byte[] bytes = [1, 2, 3]; 90 byte[] bytes2 = [1, 2, 4]; 91 shouldEqual(ints, bytes); 92 shouldEqual(bytes, ints) ; 93 shouldNotEqual(ints, bytes2) ; 94 95 const constIntToInts = [1 : 2, 3 : 7, 9 : 345]; 96 auto intToInts = [1 : 2, 3 : 7, 9 : 345]; 97 shouldEqual(intToInts, constIntToInts) ; 98 shouldEqual(constIntToInts, intToInts) ; 99 } 100 101 @safe unittest { 102 shouldEqual([1 : 2.0, 2 : 4.0], [1 : 2.0, 2 : 4.0]) ; 103 shouldNotEqual([1 : 2.0, 2 : 4.0], [1 : 2.2, 2 : 4.0]) ; 104 } 105 106 107 @safe pure unittest 108 { 109 class Foo 110 { 111 this(int i) { this.i = i; } 112 override string toString() const 113 { 114 import std.conv: to; 115 return i.to!string; 116 } 117 int i; 118 } 119 120 shouldNotBeNull(new Foo(4)); 121 assertFail(shouldNotBeNull(null)); 122 shouldEqual(new Foo(5), new Foo(5)); 123 assertFail(shouldEqual(new Foo(5), new Foo(4))); 124 shouldNotEqual(new Foo(5), new Foo(4)) ; 125 assertFail(shouldNotEqual(new Foo(5), new Foo(5))); 126 } 127 128 @safe pure unittest 129 { 130 shouldBeNull(null); 131 assertFail(shouldBeNull(new int)); 132 } 133 134 135 @safe pure unittest { 136 5.shouldBeIn([5: "foo"]); 137 138 struct AA { 139 int onlyKey; 140 bool opBinaryRight(string op)(in int key) const { 141 return key == onlyKey; 142 } 143 } 144 145 5.shouldBeIn(AA(5)); 146 assertFail(5.shouldBeIn(AA(4))); 147 } 148 149 @safe pure unittest 150 { 151 shouldBeIn(4, [1, 2, 4]); 152 shouldBeIn("foo", ["foo" : 1]); 153 assertFail("foo".shouldBeIn(["bar"])); 154 } 155 156 @safe pure unittest { 157 assertExceptionMsg("foo".shouldBeIn(["quux": "toto"]), 158 ` tests/unit_threaded/ut/should.d:123 - Value "foo"` ~ "\n" ~ 159 ` tests/unit_threaded/ut/should.d:123 - not in ["quux":"toto"]`); 160 } 161 162 @safe pure unittest { 163 assertExceptionMsg("foo".shouldBeIn("quux"), 164 ` tests/unit_threaded/ut/should.d:123 - Value "foo"` ~ "\n" ~ 165 ` tests/unit_threaded/ut/should.d:123 - not in "quux"`); 166 167 } 168 169 @safe pure unittest { 170 5.shouldNotBeIn([4: "foo"]); 171 172 struct AA { 173 int onlyKey; 174 bool opBinaryRight(string op)(in int key) const { 175 return key == onlyKey; 176 } 177 } 178 179 5.shouldNotBeIn(AA(4)); 180 assertFail(5.shouldNotBeIn(AA(5))); 181 } 182 183 @safe pure unittest { 184 assertExceptionMsg("quux".shouldNotBeIn(["quux": "toto"]), 185 ` tests/unit_threaded/ut/should.d:123 - Value "quux"` ~ "\n" ~ 186 ` tests/unit_threaded/ut/should.d:123 - is in ["quux":"toto"]`); 187 } 188 189 @safe pure unittest { 190 assertExceptionMsg("foo".shouldNotBeIn("foobar"), 191 ` tests/unit_threaded/ut/should.d:123 - Value "foo"` ~ "\n" ~ 192 ` tests/unit_threaded/ut/should.d:123 - is in "foobar"`); 193 194 } 195 196 197 @safe unittest 198 { 199 auto arrayRangeWithoutLength(T)(T[] array) 200 { 201 struct ArrayRangeWithoutLength(T) 202 { 203 private: 204 T[] array; 205 public: 206 T front() const @property 207 { 208 return array[0]; 209 } 210 211 void popFront() 212 { 213 array = array[1 .. $]; 214 } 215 216 bool empty() const @property 217 { 218 import std.array; 219 return array.empty; 220 } 221 } 222 return ArrayRangeWithoutLength!T(array); 223 } 224 shouldNotBeIn(3.5, [1.1, 2.2, 4.4]); 225 shouldNotBeIn(1.0, [2.0 : 1, 3.0 : 2]); 226 shouldNotBeIn(1, arrayRangeWithoutLength([2, 3, 4])); 227 assertFail(1.shouldNotBeIn(arrayRangeWithoutLength([1, 2, 3]))); 228 assertFail("foo".shouldNotBeIn(["foo"])); 229 } 230 231 @safe pure unittest { 232 import unit_threaded.asserts; 233 void funcThrows(string msg) { throw new Exception(msg); } 234 try { 235 auto exception = funcThrows("foo bar").shouldThrow; 236 assertEqual(exception.msg, "foo bar"); 237 } catch(Exception e) { 238 assert(false, "should not have thrown anything and threw: " ~ e.msg); 239 } 240 } 241 242 @safe pure unittest { 243 import unit_threaded.asserts; 244 void func() {} 245 try { 246 func.shouldThrow; 247 assert(false, "Should never get here"); 248 } catch(Exception e) 249 assertEqual(e.msg, "Expression did not throw"); 250 } 251 252 @safe pure unittest { 253 import unit_threaded.asserts; 254 void funcAsserts() { assert(false, "Oh noes"); } 255 try { 256 funcAsserts.shouldThrow; 257 assert(false, "Should never get here"); 258 } catch(Exception e) 259 assertEqual(e.msg, 260 "Expression threw core.exception.AssertError instead of the expected Exception:\nOh noes"); 261 } 262 263 unittest { 264 void func() {} 265 func.shouldNotThrow; 266 void funcThrows() { throw new Exception("oops"); } 267 assertFail(shouldNotThrow(funcThrows)); 268 } 269 270 @safe pure unittest { 271 void funcThrows(string msg) { throw new Exception(msg); } 272 funcThrows("foo bar").shouldThrowWithMessage!Exception("foo bar"); 273 funcThrows("foo bar").shouldThrowWithMessage("foo bar"); 274 assertFail(funcThrows("boo boo").shouldThrowWithMessage("foo bar")); 275 void func() {} 276 assertFail(func.shouldThrowWithMessage("oops")); 277 } 278 279 // can't be made pure because of throwExactly, which in turn 280 // can't be pure because of Object.opEquals 281 @safe unittest 282 { 283 class CustomException : Exception 284 { 285 this(string msg = "") 286 { 287 super(msg); 288 } 289 } 290 291 class ChildException : CustomException 292 { 293 this(string msg = "") 294 { 295 super(msg); 296 } 297 } 298 299 void throwCustom() 300 { 301 throw new CustomException(); 302 } 303 304 throwCustom.shouldThrow; 305 throwCustom.shouldThrow!CustomException; 306 307 void throwChild() 308 { 309 throw new ChildException(); 310 } 311 312 throwChild.shouldThrow; 313 throwChild.shouldThrow!CustomException; 314 throwChild.shouldThrow!ChildException; 315 throwChild.shouldThrowExactly!ChildException; 316 try 317 { 318 throwChild.shouldThrowExactly!CustomException; //should not succeed 319 assert(0, "shouldThrowExactly failed"); 320 } 321 catch (Exception ex) 322 { 323 } 324 325 void doesntThrow() {} 326 assertFail(doesntThrow.shouldThrowExactly!Exception); 327 } 328 329 @safe pure unittest 330 { 331 void throwRangeError() 332 { 333 ubyte[] bytes; 334 bytes = bytes[1 .. $]; 335 } 336 337 import core.exception : RangeError; 338 339 throwRangeError.shouldThrow!RangeError; 340 } 341 342 @safe pure unittest { 343 import std.stdio; 344 345 import core.exception: OutOfMemoryError; 346 347 class CustomException : Exception { 348 this(string msg = "", in string file = __FILE__, in size_t line = __LINE__) { super(msg, file, line); } 349 } 350 351 void func() { throw new CustomException("oh noes"); } 352 353 func.shouldThrow!CustomException; 354 assertFail(func.shouldThrow!OutOfMemoryError); 355 } 356 357 358 unittest { 359 import unit_threaded.asserts; 360 class Foo { 361 override string toString() @safe pure nothrow const { 362 return "Foo"; 363 } 364 } 365 366 auto foo = new const Foo; 367 assertEqual(foo.convertToString, "Foo"); 368 } 369 370 @safe pure unittest { 371 assert(isEqual(1.0, 1.0)); 372 assert(!isEqual(1.0, 1.0001)); 373 } 374 375 @safe unittest { 376 assert(isApproxEqual(1.0, 1.0)); 377 assert(isApproxEqual(1.0, 1.0001)); 378 } 379 380 @safe unittest { 381 1.0.shouldApproxEqual(1.0001); 382 assertFail(2.0.shouldApproxEqual(1.0)); 383 } 384 385 @safe pure unittest { 386 import std.conv: to; 387 import std.range: iota; 388 389 assert(isEqual(2, 2)); 390 assert(!isEqual(2, 3)); 391 392 assert(isEqual(2.1, 2.1)); 393 assert(!isEqual(2.1, 2.2)); 394 395 assert(isEqual("foo", "foo")); 396 assert(!isEqual("foo", "fooo")); 397 398 assert(isEqual([1, 2], [1, 2])); 399 assert(!isEqual([1, 2], [1, 2, 3])); 400 401 assert(isEqual(iota(2), [0, 1])); 402 assert(!isEqual(iota(2), [1, 2, 3])); 403 404 assert(isEqual([[0, 1], [0, 1, 2]], [iota(2), iota(3)])); 405 assert(isEqual([[0, 1], [0, 1, 2]], [[0, 1], [0, 1, 2]])); 406 assert(!isEqual([[0, 1], [0, 1, 4]], [iota(2), iota(3)])); 407 assert(!isEqual([[0, 1], [0]], [iota(2), iota(3)])); 408 409 assert(isEqual([0: 1], [0: 1])); 410 411 const constIntToInts = [1 : 2, 3 : 7, 9 : 345]; 412 auto intToInts = [1 : 2, 3 : 7, 9 : 345]; 413 414 assert(isEqual(intToInts, constIntToInts)); 415 assert(isEqual(constIntToInts, intToInts)); 416 417 class Foo 418 { 419 this(int i) { this.i = i; } 420 override string toString() const { return i.to!string; } 421 int i; 422 } 423 424 assert(isEqual(new Foo(5), new Foo(5))); 425 assert(!isEqual(new Foo(5), new Foo(4))); 426 427 ubyte[] arr; 428 assert(isEqual(arr, [])); 429 } 430 431 @safe pure unittest 432 { 433 int[] ints; 434 string[] strings; 435 string[string] aa; 436 437 shouldBeEmpty(ints); 438 shouldBeEmpty(strings); 439 shouldBeEmpty(aa); 440 441 ints ~= 1; 442 strings ~= "foo"; 443 aa["foo"] = "bar"; 444 445 assertFail(shouldBeEmpty(ints)); 446 assertFail(shouldBeEmpty(strings)); 447 assertFail(shouldBeEmpty(aa)); 448 } 449 450 451 @safe pure unittest 452 { 453 int[] ints; 454 string[] strings; 455 string[string] aa; 456 457 assertFail(shouldNotBeEmpty(ints)); 458 assertFail(shouldNotBeEmpty(strings)); 459 assertFail(shouldNotBeEmpty(aa)); 460 461 ints ~= 1; 462 strings ~= "foo"; 463 aa["foo"] = "bar"; 464 465 shouldNotBeEmpty(ints); 466 shouldNotBeEmpty(strings); 467 shouldNotBeEmpty(aa); 468 } 469 470 @safe pure unittest 471 { 472 shouldBeGreaterThan(7, 5); 473 } 474 475 476 @safe pure unittest 477 { 478 shouldBeSmallerThan(5, 7); 479 assertFail(shouldBeSmallerThan(7, 5)); 480 assertFail(shouldBeSmallerThan(7, 7)); 481 } 482 483 @safe pure unittest { 484 "foo"w.shouldEqual("foo"); 485 } 486 487 @("Non-copyable types can be asserted on") 488 @safe pure unittest { 489 490 struct Move { 491 int i; 492 @disable this(this); 493 } 494 495 Move(5).shouldEqual(Move(5)); 496 } 497 498 @("issue 88") 499 @safe pure unittest { 500 501 class C { 502 int foo; 503 override string toString() @safe pure nothrow const { return null; } 504 } 505 506 C c = null; 507 c.shouldEqual(c); 508 C null_; 509 assertFail((new C).shouldEqual(null_)); 510 } 511 512 @("issue 89") 513 unittest { 514 class C { 515 override string toString() @safe pure nothrow const { return null; } 516 } 517 518 auto actual = new C; 519 auto expected = new C; 520 521 // these should both pass 522 actual.shouldEqual(expected); // passes: actual.tupleof == expected.tupleof 523 [actual].shouldEqual([expected]); // fails: actual != expected 524 } 525 526 @("non-const toString should compile") 527 @safe pure unittest { 528 class C { 529 override string toString() @safe pure nothrow { return null; } 530 } 531 (new C).shouldEqual(new C); 532 } 533 534 @safe pure unittest { 535 ['\xff'].shouldEqual(['\xff']); 536 } 537 538 @safe unittest { 539 shouldEqual(new Object, new Object); 540 } 541 542 543 @("should ==") 544 @safe pure unittest { 545 1.should == 1; 546 2.should == 2; 547 assertFail(1.should == 2); 548 assertExceptionMsg(1.should == 2, 549 ` tests/unit_threaded/ut/should.d:123 - Expected: 2` ~ "\n" ~ 550 ` tests/unit_threaded/ut/should.d:123 - Got: 1`); 551 } 552 553 @("should.be ==") 554 @safe pure unittest { 555 1.should.be == 1; 556 2.should.be == 2; 557 assertFail(1.should.be == 2); 558 assertExceptionMsg(1.should.be == 2, 559 ` tests/unit_threaded/ut/should.d:123 - Expected: 2` ~ "\n" ~ 560 ` tests/unit_threaded/ut/should.d:123 - Got: 1`); 561 } 562 563 @("should.not ==") 564 @safe pure unittest { 565 1.should.not == 2; 566 assertFail(2.should.not == 2); 567 } 568 569 @("should.not.be ==") 570 @safe pure unittest { 571 1.should.not.be == 2; 572 assertFail(2.should.not.be == 2); 573 } 574 575 @("should.throw") 576 @safe pure unittest { 577 578 void funcOk() {} 579 580 void funcThrows() { 581 throw new Exception("oops"); 582 } 583 584 assertFail(funcOk.should.throw_); 585 funcThrows.should.throw_; 586 } 587 588 @("should.be in") 589 @safe pure unittest { 590 1.should.be in [1, 2, 3]; 591 2.should.be in [1, 2, 3]; 592 3.should.be in [1, 2, 3]; 593 assertFail(4.should.be in [1, 2, 3]); 594 } 595 596 @("should.not.be in") 597 @safe pure unittest { 598 4.should.not.be in [1, 2, 3]; 599 assertFail(1.should.not.be in [1, 2, 3]); 600 } 601 602 @("should ~ for range") 603 @safe pure unittest { 604 [1, 2, 3].should ~ [3, 2, 1]; 605 [1, 2, 3].should.not ~ [1, 2, 2]; 606 assertFail([1, 2, 3].should ~ [1, 2, 2]); 607 } 608 609 @("should ~ for float") 610 @safe unittest { 611 1.0.should ~ 1.0001; 612 1.0.should.not ~ 2.0; 613 assertFail(2.0.should ~ 1.0001); 614 }