1package require 2 3import ( 4 "encoding/json" 5 "errors" 6 "testing" 7 "time" 8) 9 10// AssertionTesterInterface defines an interface to be used for testing assertion methods 11type AssertionTesterInterface interface { 12 TestMethod() 13} 14 15// AssertionTesterConformingObject is an object that conforms to the AssertionTesterInterface interface 16type AssertionTesterConformingObject struct { 17} 18 19func (a *AssertionTesterConformingObject) TestMethod() { 20} 21 22// AssertionTesterNonConformingObject is an object that does not conform to the AssertionTesterInterface interface 23type AssertionTesterNonConformingObject struct { 24} 25 26type MockT struct { 27 Failed bool 28} 29 30func (t *MockT) FailNow() { 31 t.Failed = true 32} 33 34func (t *MockT) Errorf(format string, args ...interface{}) { 35 _, _ = format, args 36} 37 38func TestImplements(t *testing.T) { 39 40 Implements(t, (*AssertionTesterInterface)(nil), new(AssertionTesterConformingObject)) 41 42 mockT := new(MockT) 43 Implements(mockT, (*AssertionTesterInterface)(nil), new(AssertionTesterNonConformingObject)) 44 if !mockT.Failed { 45 t.Error("Check should fail") 46 } 47} 48 49func TestIsType(t *testing.T) { 50 51 IsType(t, new(AssertionTesterConformingObject), new(AssertionTesterConformingObject)) 52 53 mockT := new(MockT) 54 IsType(mockT, new(AssertionTesterConformingObject), new(AssertionTesterNonConformingObject)) 55 if !mockT.Failed { 56 t.Error("Check should fail") 57 } 58} 59 60func TestEqual(t *testing.T) { 61 62 Equal(t, 1, 1) 63 64 mockT := new(MockT) 65 Equal(mockT, 1, 2) 66 if !mockT.Failed { 67 t.Error("Check should fail") 68 } 69 70} 71 72func TestNotEqual(t *testing.T) { 73 74 NotEqual(t, 1, 2) 75 mockT := new(MockT) 76 NotEqual(mockT, 2, 2) 77 if !mockT.Failed { 78 t.Error("Check should fail") 79 } 80} 81 82func TestExactly(t *testing.T) { 83 84 a := float32(1) 85 b := float32(1) 86 c := float64(1) 87 88 Exactly(t, a, b) 89 90 mockT := new(MockT) 91 Exactly(mockT, a, c) 92 if !mockT.Failed { 93 t.Error("Check should fail") 94 } 95} 96 97func TestNotNil(t *testing.T) { 98 99 NotNil(t, new(AssertionTesterConformingObject)) 100 101 mockT := new(MockT) 102 NotNil(mockT, nil) 103 if !mockT.Failed { 104 t.Error("Check should fail") 105 } 106} 107 108func TestNil(t *testing.T) { 109 110 Nil(t, nil) 111 112 mockT := new(MockT) 113 Nil(mockT, new(AssertionTesterConformingObject)) 114 if !mockT.Failed { 115 t.Error("Check should fail") 116 } 117} 118 119func TestTrue(t *testing.T) { 120 121 True(t, true) 122 123 mockT := new(MockT) 124 True(mockT, false) 125 if !mockT.Failed { 126 t.Error("Check should fail") 127 } 128} 129 130func TestFalse(t *testing.T) { 131 132 False(t, false) 133 134 mockT := new(MockT) 135 False(mockT, true) 136 if !mockT.Failed { 137 t.Error("Check should fail") 138 } 139} 140 141func TestContains(t *testing.T) { 142 143 Contains(t, "Hello World", "Hello") 144 145 mockT := new(MockT) 146 Contains(mockT, "Hello World", "Salut") 147 if !mockT.Failed { 148 t.Error("Check should fail") 149 } 150} 151 152func TestNotContains(t *testing.T) { 153 154 NotContains(t, "Hello World", "Hello!") 155 156 mockT := new(MockT) 157 NotContains(mockT, "Hello World", "Hello") 158 if !mockT.Failed { 159 t.Error("Check should fail") 160 } 161} 162 163func TestPanics(t *testing.T) { 164 165 Panics(t, func() { 166 panic("Panic!") 167 }) 168 169 mockT := new(MockT) 170 Panics(mockT, func() {}) 171 if !mockT.Failed { 172 t.Error("Check should fail") 173 } 174} 175 176func TestNotPanics(t *testing.T) { 177 178 NotPanics(t, func() {}) 179 180 mockT := new(MockT) 181 NotPanics(mockT, func() { 182 panic("Panic!") 183 }) 184 if !mockT.Failed { 185 t.Error("Check should fail") 186 } 187} 188 189func TestNoError(t *testing.T) { 190 191 NoError(t, nil) 192 193 mockT := new(MockT) 194 NoError(mockT, errors.New("some error")) 195 if !mockT.Failed { 196 t.Error("Check should fail") 197 } 198} 199 200func TestError(t *testing.T) { 201 202 Error(t, errors.New("some error")) 203 204 mockT := new(MockT) 205 Error(mockT, nil) 206 if !mockT.Failed { 207 t.Error("Check should fail") 208 } 209} 210 211func TestEqualError(t *testing.T) { 212 213 EqualError(t, errors.New("some error"), "some error") 214 215 mockT := new(MockT) 216 EqualError(mockT, errors.New("some error"), "Not some error") 217 if !mockT.Failed { 218 t.Error("Check should fail") 219 } 220} 221 222func TestEmpty(t *testing.T) { 223 224 Empty(t, "") 225 226 mockT := new(MockT) 227 Empty(mockT, "x") 228 if !mockT.Failed { 229 t.Error("Check should fail") 230 } 231} 232 233func TestNotEmpty(t *testing.T) { 234 235 NotEmpty(t, "x") 236 237 mockT := new(MockT) 238 NotEmpty(mockT, "") 239 if !mockT.Failed { 240 t.Error("Check should fail") 241 } 242} 243 244func TestWithinDuration(t *testing.T) { 245 246 a := time.Now() 247 b := a.Add(10 * time.Second) 248 249 WithinDuration(t, a, b, 15*time.Second) 250 251 mockT := new(MockT) 252 WithinDuration(mockT, a, b, 5*time.Second) 253 if !mockT.Failed { 254 t.Error("Check should fail") 255 } 256} 257 258func TestInDelta(t *testing.T) { 259 260 InDelta(t, 1.001, 1, 0.01) 261 262 mockT := new(MockT) 263 InDelta(mockT, 1, 2, 0.5) 264 if !mockT.Failed { 265 t.Error("Check should fail") 266 } 267} 268 269func TestZero(t *testing.T) { 270 271 Zero(t, "") 272 273 mockT := new(MockT) 274 Zero(mockT, "x") 275 if !mockT.Failed { 276 t.Error("Check should fail") 277 } 278} 279 280func TestNotZero(t *testing.T) { 281 282 NotZero(t, "x") 283 284 mockT := new(MockT) 285 NotZero(mockT, "") 286 if !mockT.Failed { 287 t.Error("Check should fail") 288 } 289} 290 291func TestJSONEq_EqualSONString(t *testing.T) { 292 mockT := new(MockT) 293 JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) 294 if mockT.Failed { 295 t.Error("Check should pass") 296 } 297} 298 299func TestJSONEq_EquivalentButNotEqual(t *testing.T) { 300 mockT := new(MockT) 301 JSONEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) 302 if mockT.Failed { 303 t.Error("Check should pass") 304 } 305} 306 307func TestJSONEq_HashOfArraysAndHashes(t *testing.T) { 308 mockT := new(MockT) 309 JSONEq(mockT, "{\r\n\t\"numeric\": 1.5,\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]],\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\"\r\n}", 310 "{\r\n\t\"numeric\": 1.5,\r\n\t\"hash\": {\"nested\": \"hash\", \"nested_slice\": [\"this\", \"is\", \"nested\"]},\r\n\t\"string\": \"foo\",\r\n\t\"array\": [{\"foo\": \"bar\"}, 1, \"string\", [\"nested\", \"array\", 5.5]]\r\n}") 311 if mockT.Failed { 312 t.Error("Check should pass") 313 } 314} 315 316func TestJSONEq_Array(t *testing.T) { 317 mockT := new(MockT) 318 JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) 319 if mockT.Failed { 320 t.Error("Check should pass") 321 } 322} 323 324func TestJSONEq_HashAndArrayNotEquivalent(t *testing.T) { 325 mockT := new(MockT) 326 JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) 327 if !mockT.Failed { 328 t.Error("Check should fail") 329 } 330} 331 332func TestJSONEq_HashesNotEquivalent(t *testing.T) { 333 mockT := new(MockT) 334 JSONEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) 335 if !mockT.Failed { 336 t.Error("Check should fail") 337 } 338} 339 340func TestJSONEq_ActualIsNotJSON(t *testing.T) { 341 mockT := new(MockT) 342 JSONEq(mockT, `{"foo": "bar"}`, "Not JSON") 343 if !mockT.Failed { 344 t.Error("Check should fail") 345 } 346} 347 348func TestJSONEq_ExpectedIsNotJSON(t *testing.T) { 349 mockT := new(MockT) 350 JSONEq(mockT, "Not JSON", `{"foo": "bar", "hello": "world"}`) 351 if !mockT.Failed { 352 t.Error("Check should fail") 353 } 354} 355 356func TestJSONEq_ExpectedAndActualNotJSON(t *testing.T) { 357 mockT := new(MockT) 358 JSONEq(mockT, "Not JSON", "Not JSON") 359 if !mockT.Failed { 360 t.Error("Check should fail") 361 } 362} 363 364func TestJSONEq_ArraysOfDifferentOrder(t *testing.T) { 365 mockT := new(MockT) 366 JSONEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) 367 if !mockT.Failed { 368 t.Error("Check should fail") 369 } 370} 371 372func TestYAMLEq_EqualYAMLString(t *testing.T) { 373 mockT := new(MockT) 374 YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) 375 if mockT.Failed { 376 t.Error("Check should pass") 377 } 378} 379 380func TestYAMLEq_EquivalentButNotEqual(t *testing.T) { 381 mockT := new(MockT) 382 YAMLEq(mockT, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) 383 if mockT.Failed { 384 t.Error("Check should pass") 385 } 386} 387 388func TestYAMLEq_HashOfArraysAndHashes(t *testing.T) { 389 mockT := new(MockT) 390 expected := ` 391numeric: 1.5 392array: 393 - foo: bar 394 - 1 395 - "string" 396 - ["nested", "array", 5.5] 397hash: 398 nested: hash 399 nested_slice: [this, is, nested] 400string: "foo" 401` 402 403 actual := ` 404numeric: 1.5 405hash: 406 nested: hash 407 nested_slice: [this, is, nested] 408string: "foo" 409array: 410 - foo: bar 411 - 1 412 - "string" 413 - ["nested", "array", 5.5] 414` 415 YAMLEq(mockT, expected, actual) 416 if mockT.Failed { 417 t.Error("Check should pass") 418 } 419} 420 421func TestYAMLEq_Array(t *testing.T) { 422 mockT := new(MockT) 423 YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `["foo", {"nested": "hash", "hello": "world"}]`) 424 if mockT.Failed { 425 t.Error("Check should pass") 426 } 427} 428 429func TestYAMLEq_HashAndArrayNotEquivalent(t *testing.T) { 430 mockT := new(MockT) 431 YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `{"foo": "bar", {"nested": "hash", "hello": "world"}}`) 432 if !mockT.Failed { 433 t.Error("Check should fail") 434 } 435} 436 437func TestYAMLEq_HashesNotEquivalent(t *testing.T) { 438 mockT := new(MockT) 439 YAMLEq(mockT, `{"foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) 440 if !mockT.Failed { 441 t.Error("Check should fail") 442 } 443} 444 445func TestYAMLEq_ActualIsSimpleString(t *testing.T) { 446 mockT := new(MockT) 447 YAMLEq(mockT, `{"foo": "bar"}`, "Simple String") 448 if !mockT.Failed { 449 t.Error("Check should fail") 450 } 451} 452 453func TestYAMLEq_ExpectedIsSimpleString(t *testing.T) { 454 mockT := new(MockT) 455 YAMLEq(mockT, "Simple String", `{"foo": "bar", "hello": "world"}`) 456 if !mockT.Failed { 457 t.Error("Check should fail") 458 } 459} 460 461func TestYAMLEq_ExpectedAndActualSimpleString(t *testing.T) { 462 mockT := new(MockT) 463 YAMLEq(mockT, "Simple String", "Simple String") 464 if mockT.Failed { 465 t.Error("Check should pass") 466 } 467} 468 469func TestYAMLEq_ArraysOfDifferentOrder(t *testing.T) { 470 mockT := new(MockT) 471 YAMLEq(mockT, `["foo", {"hello": "world", "nested": "hash"}]`, `[{ "hello": "world", "nested": "hash"}, "foo"]`) 472 if !mockT.Failed { 473 t.Error("Check should fail") 474 } 475} 476 477func ExampleComparisonAssertionFunc() { 478 t := &testing.T{} // provided by test 479 480 adder := func(x, y int) int { 481 return x + y 482 } 483 484 type args struct { 485 x int 486 y int 487 } 488 489 tests := []struct { 490 name string 491 args args 492 expect int 493 assertion ComparisonAssertionFunc 494 }{ 495 {"2+2=4", args{2, 2}, 4, Equal}, 496 {"2+2!=5", args{2, 2}, 5, NotEqual}, 497 {"2+3==5", args{2, 3}, 5, Exactly}, 498 } 499 500 for _, tt := range tests { 501 t.Run(tt.name, func(t *testing.T) { 502 tt.assertion(t, tt.expect, adder(tt.args.x, tt.args.y)) 503 }) 504 } 505} 506 507func TestComparisonAssertionFunc(t *testing.T) { 508 type iface interface { 509 Name() string 510 } 511 512 tests := []struct { 513 name string 514 expect interface{} 515 got interface{} 516 assertion ComparisonAssertionFunc 517 }{ 518 {"implements", (*iface)(nil), t, Implements}, 519 {"isType", (*testing.T)(nil), t, IsType}, 520 {"equal", t, t, Equal}, 521 {"equalValues", t, t, EqualValues}, 522 {"exactly", t, t, Exactly}, 523 {"notEqual", t, nil, NotEqual}, 524 {"NotEqualValues", t, nil, NotEqualValues}, 525 {"notContains", []int{1, 2, 3}, 4, NotContains}, 526 {"subset", []int{1, 2, 3, 4}, []int{2, 3}, Subset}, 527 {"notSubset", []int{1, 2, 3, 4}, []int{0, 3}, NotSubset}, 528 {"elementsMatch", []byte("abc"), []byte("bac"), ElementsMatch}, 529 {"regexp", "^t.*y$", "testify", Regexp}, 530 {"notRegexp", "^t.*y$", "Testify", NotRegexp}, 531 } 532 533 for _, tt := range tests { 534 t.Run(tt.name, func(t *testing.T) { 535 tt.assertion(t, tt.expect, tt.got) 536 }) 537 } 538} 539 540func ExampleValueAssertionFunc() { 541 t := &testing.T{} // provided by test 542 543 dumbParse := func(input string) interface{} { 544 var x interface{} 545 json.Unmarshal([]byte(input), &x) 546 return x 547 } 548 549 tests := []struct { 550 name string 551 arg string 552 assertion ValueAssertionFunc 553 }{ 554 {"true is not nil", "true", NotNil}, 555 {"empty string is nil", "", Nil}, 556 {"zero is not nil", "0", NotNil}, 557 {"zero is zero", "0", Zero}, 558 {"false is zero", "false", Zero}, 559 } 560 561 for _, tt := range tests { 562 t.Run(tt.name, func(t *testing.T) { 563 tt.assertion(t, dumbParse(tt.arg)) 564 }) 565 } 566} 567 568func TestValueAssertionFunc(t *testing.T) { 569 tests := []struct { 570 name string 571 value interface{} 572 assertion ValueAssertionFunc 573 }{ 574 {"notNil", true, NotNil}, 575 {"nil", nil, Nil}, 576 {"empty", []int{}, Empty}, 577 {"notEmpty", []int{1}, NotEmpty}, 578 {"zero", false, Zero}, 579 {"notZero", 42, NotZero}, 580 } 581 582 for _, tt := range tests { 583 t.Run(tt.name, func(t *testing.T) { 584 tt.assertion(t, tt.value) 585 }) 586 } 587} 588 589func ExampleBoolAssertionFunc() { 590 t := &testing.T{} // provided by test 591 592 isOkay := func(x int) bool { 593 return x >= 42 594 } 595 596 tests := []struct { 597 name string 598 arg int 599 assertion BoolAssertionFunc 600 }{ 601 {"-1 is bad", -1, False}, 602 {"42 is good", 42, True}, 603 {"41 is bad", 41, False}, 604 {"45 is cool", 45, True}, 605 } 606 607 for _, tt := range tests { 608 t.Run(tt.name, func(t *testing.T) { 609 tt.assertion(t, isOkay(tt.arg)) 610 }) 611 } 612} 613 614func TestBoolAssertionFunc(t *testing.T) { 615 tests := []struct { 616 name string 617 value bool 618 assertion BoolAssertionFunc 619 }{ 620 {"true", true, True}, 621 {"false", false, False}, 622 } 623 624 for _, tt := range tests { 625 t.Run(tt.name, func(t *testing.T) { 626 tt.assertion(t, tt.value) 627 }) 628 } 629} 630 631func ExampleErrorAssertionFunc() { 632 t := &testing.T{} // provided by test 633 634 dumbParseNum := func(input string, v interface{}) error { 635 return json.Unmarshal([]byte(input), v) 636 } 637 638 tests := []struct { 639 name string 640 arg string 641 assertion ErrorAssertionFunc 642 }{ 643 {"1.2 is number", "1.2", NoError}, 644 {"1.2.3 not number", "1.2.3", Error}, 645 {"true is not number", "true", Error}, 646 {"3 is number", "3", NoError}, 647 } 648 649 for _, tt := range tests { 650 t.Run(tt.name, func(t *testing.T) { 651 var x float64 652 tt.assertion(t, dumbParseNum(tt.arg, &x)) 653 }) 654 } 655} 656 657func TestErrorAssertionFunc(t *testing.T) { 658 tests := []struct { 659 name string 660 err error 661 assertion ErrorAssertionFunc 662 }{ 663 {"noError", nil, NoError}, 664 {"error", errors.New("whoops"), Error}, 665 } 666 667 for _, tt := range tests { 668 t.Run(tt.name, func(t *testing.T) { 669 tt.assertion(t, tt.err) 670 }) 671 } 672} 673