1 /** 2 * Tests/Examples of Pijamas 3 * 4 * Authors: Pedro Tacla Yamada, Luis Panadero Guardeño 5 * License: Licensed under the MIT license. See LICENSE for more information. 6 */ 7 module pijamas_spec; 8 9 import std.exception; 10 11 import pijamas; 12 import pijamas.exception : AssertException; 13 14 version (Debug_Failing_Tests) { 15 @("Failing test") 16 unittest { 17 10.should.be.equal(0); 18 } 19 20 @("Failing test with native assert") 21 unittest { 22 assert(10 == 0); 23 } 24 25 @("Error test") 26 unittest { 27 throw new Exception("Some exception"); 28 } 29 } 30 31 @("Should Assertion.exist") 32 @trusted unittest { 33 // it("existence of string", 34 { 35 // String 36 string str; 37 str.should.not.exist; 38 assertNotThrown!AssertException(str.should.not.exist); 39 assertThrown!AssertException(str.should.exist); 40 41 string str2 = null; 42 str2.should.not.exist; 43 44 } 45 46 // it("With not nullable, must do nothing 47 { 48 int i = 10; 49 i.should.exist; 50 i.should.not.exist; 51 52 struct S { 53 int x; 54 } 55 56 S s; 57 assertNotThrown!AssertException(s.should.exist); 58 assertNotThrown!AssertException(s.should.not.exist); 59 } 60 61 // it("Pointer not being a null pointer" 62 { 63 // Ptr 64 int* ptr = null; 65 ptr.should.not.exist; 66 assertThrown!AssertException(ptr.should.exist); 67 68 int value; 69 ptr = &value; 70 ptr.should.exist; 71 } 72 73 // it("Class reference" 74 { 75 // Class 76 class C { 77 int x; 78 this() { 79 } 80 } 81 82 C c; 83 c.should.not.exist; 84 assertThrown!AssertException(c.should.exist); 85 86 c = new C(); 87 c.should.exist; 88 } 89 } 90 91 @("Asserting a field of a no copiable Struct") 92 @safe unittest { 93 struct S { 94 this(this) @disable; 95 96 int x; 97 size_t length; 98 } 99 100 auto s = S(123, 10); 101 s.x.should.be.equal(123); 102 //s.should.have.length(10); // Error is not copyable because it is annotated with @disable 103 } 104 105 @("Should Assertion.True") 106 @trusted unittest { 107 // it("returns and asserts for true", 108 { 109 true.should.be.True; 110 (1 == 1).should.be.True; 111 } 112 113 // it("throws for false", 114 { 115 (1 != 1).should.not.be.True; 116 assertThrown!AssertException(false.should.be.True); 117 } 118 } 119 120 @("Should Assertion.False") 121 @trusted unittest { 122 // it("returns and asserts for false", 123 { 124 false.should.be.False; 125 (1 != 1).should.be.False; 126 } 127 128 // it("throws for true", 129 { 130 true.should.not.be.False; 131 assertThrown!AssertException((1 == 1).should.be.False); 132 } 133 } 134 135 @("Should Assertion.equal") 136 @trusted unittest { 137 // it("asserts whether two values are equal", 138 { 139 10.should.be.equal(10); 140 10.expect.to.be.equal(10); 141 10.should.not.be.equal(5); 142 10.should.not; 143 assertThrown!AssertException(10.should.be.equal(2)); 144 } 145 146 // it("works for arrays", 147 { 148 [1, 2, 3, 4].should.be.equal([1, 2, 3, 4]); 149 150 byte[] a2 = [0, 2, 1]; 151 a2.should.not.be.equal([1, 2, 3, 5]); 152 assertThrown!AssertException(a2.should.be.equal([100, 200, 4])); 153 } 154 155 // it("works for ranges", 156 /* 157 // FIX Fix for ranges ... if "other" is an array, should convert the range to an array and compare. 158 // also, must be careful with infinite ranges 159 { 160 import std.range : iota; 161 auto r = iota(1, 4); 162 r.should.be.equal([1, 2, 3, 4]); 163 } 164 */ 165 166 // it("works for structs", 167 { 168 struct ExampleS { 169 bool a = false; 170 string f = "something"; 171 } 172 173 auto e = ExampleS(true, "here"); 174 e.should.be.equal(ExampleS(true, "here")); 175 e.should.be.not.equal(ExampleS(true, "asdf")); 176 assertThrown!AssertException(e.should.be.equal(ExampleS(true, "asdf"))); 177 } 178 179 // it("works for classes", 180 { 181 class ExampleC { 182 int x; 183 this(int x) { 184 this.x = x; 185 } 186 187 override bool opEquals(Object o) const // @trusted 188 { 189 if (ExampleC rhs = cast(ExampleC) o) { 190 return this.x == rhs.x; 191 } 192 return false; 193 } 194 } 195 196 class OtherClass { 197 int x; 198 this(int x) { 199 this.x = x; 200 } 201 } 202 203 auto e = new ExampleC(33); 204 e.should.be.equal(new ExampleC(33)); 205 e.should.be.not.equal(new ExampleC(1)); 206 assertThrown!AssertException(e.should.be.equal(new ExampleC(1))); 207 208 e.should.be.not.equal(new OtherClass(33)); 209 assertThrown!AssertException(e.should.be.equal(new OtherClass(33))); 210 211 } 212 } 213 214 @("Should Assertion.approxEqual") 215 @trusted unittest { 216 // it("asserts that the identical value are identical") 217 { 218 float f = 0.01; 219 f.should.be.approxEqual(f); 220 f.should.be.close(f); 221 222 double d = 0.01; 223 d.should.be.approxEqual(d); 224 225 real r = 0.01; 226 r.should.be.approxEqual(r); 227 } 228 229 // it("handles comparing diferent float types") 230 { 231 float f = 0.01; 232 double d = 0.01; 233 real r = 0.01; 234 f.should.be.approxEqual(d); 235 f.should.be.approxEqual(r); 236 237 d.should.be.approxEqual(f); 238 d.should.be.approxEqual(r); 239 240 r.should.be.approxEqual(f); 241 r.should.be.approxEqual(d); 242 } 243 244 // it("asserts that two nearly identical float values are approximated equal") 245 { 246 float one = 1_000_000_000.0; 247 one.should.be.close(999_999_999.0); 248 249 double d = 0.1; 250 double d2 = d + 1e-10; 251 d.should.not.be.equal(d2); 252 d.should.be.approxEqual(d2); 253 254 // and("when increase the difference, it must not be approximated equals") 255 d2 += 1e-5; 256 d.should.not.be.equal(d2); 257 d.should.not.be.approxEqual(d2); 258 assertThrown!AssertException(d.should.be.approxEqual(d2)); 259 260 // and("Different default limits for different floating point types") 261 float oneFloat = 1.0f; 262 double oneDouble = 1.0; 263 oneFloat.should.be.close(0.999_99f); 264 oneDouble.should.not.be.close(0.999_99); 265 } 266 } 267 268 version (MirNoGCException) { 269 } else { 270 @("Should Assertion.match") 271 @trusted unittest { 272 // it("returns whether a string type matches a Regex", 273 { 274 import std.regex : regex; 275 276 string str = "Something weird"; 277 str.should.match(regex(`[a-z]+`)); 278 assertThrown!AssertException(str.should.match(regex(`[0-9]+`))); 279 } 280 281 // it("returns whether a string type matches a StaticRegex", 282 { 283 import std.regex : ctRegex; 284 285 string str = "something 2 weird"; 286 str.should.match(ctRegex!`[a-z0-9]+`); 287 assertThrown!AssertException(str.should.match(ctRegex!`^[a-z]+$`)); 288 } 289 290 // it("returns whether a string type matches a string regex", 291 { 292 string str = "1234numbers"; 293 str.should.match(`[0-9]+[a-z]+`); 294 str.should.not.match(`^[a-z]+`); 295 assertThrown!AssertException(str.should.match(`^[a-z]+`)); 296 } 297 } 298 } 299 300 @("Should Assertion.include") 301 @trusted unittest { 302 // it("asserts for arrays containing elements", 303 { 304 int[] a = [1, 2, 3, 4, 5, 6]; 305 a.should.include!int(4); 306 a.should.not.include!int(7); 307 assertThrown!AssertException(a.should.include(7)); 308 } 309 310 // it("asserts for associative arrays containing values", 311 { 312 int[string] aa = ["something": 2, "else": 3]; 313 aa.should.have.value(2); 314 aa.should.not.have.value(4); 315 assertThrown!AssertException(aa.should.have.value(42)); 316 } 317 318 // it("asserts for strings containing characters", 319 { 320 string str = "asdf1"; 321 str.should.include('a'); 322 version (MirNoGCException) { 323 } else { 324 str.should.include("sd"); 325 } 326 str.should.not.include(2); 327 str.should.not.include('u'); 328 assertThrown!AssertException(str.should.include('z')); 329 } 330 } 331 332 @("Should Assertion.length") 333 @trusted unittest { 334 // it("asserts for length equality for strings", 335 { 336 auto str = "1234567"; 337 str.should.have.length(7); 338 assertThrown!AssertException(str.should.have.length(17)); 339 } 340 341 // it("asserts for length equality for arrays", 342 { 343 auto a = [1, 2, 3, 4, 5, 6]; 344 a.should.have.length(6); 345 assertThrown!AssertException(a.should.have.length(16)); 346 } 347 348 // it("asserts for length equality for associative arrays", 349 { 350 string[string] aa = [ 351 "something": "here", "what": "is", "this": "stuff", "we're": "doing" 352 ]; 353 aa.should.have.length(4); 354 assertThrown!AssertException(aa.should.have.length(24)); 355 } 356 } 357 358 @("Should Assertion.empty") 359 @trusted unittest { 360 // it("asserts that a string is empty" 361 { 362 auto str = "1234567"; 363 str.should.not.be.empty; 364 assertThrown!AssertException(str.should.be.empty); 365 "".should.be.empty; 366 } 367 368 // it("asserts that an array is empty" 369 { 370 auto a = [1, 2, 3, 4, 5, 6]; 371 a.should.not.be.empty; 372 assertThrown!AssertException(a.should.be.empty); 373 int[] emptyArr; 374 emptyArr.should.be.empty; 375 376 int[10] emptySArr; 377 emptySArr.should.not.be.empty; 378 // A static array contains N values of T.init, so never can be empty 379 } 380 381 // it("asserts that an associative array is empty", 382 { 383 string[string] aa = [ 384 "something": "here", "what": "is", "this": "stuff", "we're": "doing" 385 ]; 386 aa.should.not.be.empty; 387 assertThrown!AssertException(aa.should.be.empty); 388 int[string] emptyAa; 389 emptyAa.should.be.empty; 390 } 391 } 392 393 @("Should Assertion.Throw") 394 @trusted unittest { 395 // it("asserts whether an expressions throws", 396 { 397 void throwing() { 398 throw new Exception("I throw with 0!"); 399 } 400 401 assertThrown!Exception(throwing()); 402 should(&throwing).Throw!Exception; 403 404 void notThrowing() { 405 return; 406 } 407 408 should(¬Throwing).not.Throw; 409 } 410 } 411 412 @("Should Assertion.key") 413 @trusted unittest { 414 // it("asserts for `key` existence in types with `opIndex` defined", 415 { 416 auto aArr = ["something": "here",]; 417 418 aArr.should.have.key("something"); 419 aArr.should.not.have.key("else"); 420 assertThrown!AssertException(aArr.should.have.key("another")); 421 } 422 } 423 424 @("Should Assertion.sorted") 425 @trusted unittest { 426 // it("asserts whether a range is sorted", 427 { 428 auto unsorted = [4, 3, 2, 1]; 429 unsorted.should.not.be.sorted; 430 assertThrown!AssertException(unsorted.should.be.sorted); 431 auto sortedAr = [1, 2, 3, 4, 8]; 432 sortedAr.should.be.sorted; 433 assertThrown!AssertException(sortedAr.should.not.be.sorted); 434 } 435 } 436 437 @("Should Assertion.biggerThan") 438 @trusted unittest { 439 //it("asserts whether a value is bigger than other", 440 { 441 auto a1 = true; 442 a1.should.be.biggerThan(0); 443 a1.should.be.biggerThan(false); 444 445 auto a2 = "aab"; 446 a2.should.be.biggerThan("aaa"); 447 a2.should.not.be.biggerThan("zz"); 448 assertThrown!AssertException(a2.should.be.biggerThan("zz")); 449 450 10.should.be.biggerOrEqualThan(10); 451 50.should.be.biggerOrEqualThan(10); 452 } 453 } 454 455 @("Should Assertion.smallerThan") 456 @trusted unittest { 457 // it("asserts whether a value is smaller than other", 458 { 459 auto a1 = false; 460 a1.should.be.smallerThan(1); 461 a1.should.be.smallerThan(true); 462 463 auto a2 = 1000; 464 a2.should.be.smallerThan(2000); 465 a2.should.be.not.smallerThan(99); 466 assertThrown!AssertException(a2.should.be.smallerThan(99)); 467 468 10.should.be.smallerOrEqualThan(10); 469 10.should.be.smallerOrEqualThan(50); 470 } 471 } 472