github.com/bananabytelabs/wazero@v0.0.0-20240105073314-54b22a776da8/internal/testing/require/require_test.go (about) 1 package require 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "testing" 8 ) 9 10 func TestCapturePanic(t *testing.T) { 11 tests := []struct { 12 name string 13 panics func() 14 expectedErr string 15 }{ 16 { 17 name: "doesn't panic", 18 panics: func() {}, 19 expectedErr: "", 20 }, 21 { 22 name: "panics with error", 23 panics: func() { panic(errors.New("error")) }, 24 expectedErr: "error", 25 }, 26 { 27 name: "panics with string", 28 panics: func() { panic("crash") }, 29 expectedErr: "crash", 30 }, 31 { 32 name: "panics with object", 33 panics: func() { panic(struct{}{}) }, 34 expectedErr: "{}", 35 }, 36 } 37 38 for _, tt := range tests { 39 tc := tt 40 41 t.Run(tc.name, func(t *testing.T) { 42 captured := CapturePanic(tc.panics) 43 if tc.expectedErr == "" { 44 if captured != nil { 45 t.Fatalf("expected no error, but found %v", captured) 46 } 47 } else { 48 if captured.Error() != tc.expectedErr { 49 t.Fatalf("expected %s, but found %s", tc.expectedErr, captured.Error()) 50 } 51 } 52 }) 53 } 54 } 55 56 func TestFail(t *testing.T) { 57 tests := []struct { 58 name string 59 formatWithArgs []interface{} 60 expectedLog string 61 }{ 62 { 63 name: "message no formatWithArgs", 64 expectedLog: "failed", 65 }, 66 { 67 name: "message formatWithArgs =: string", 68 formatWithArgs: []interface{}{"because"}, 69 expectedLog: "failed: because", 70 }, 71 { 72 name: "message formatWithArgs = [number]", 73 formatWithArgs: []interface{}{1}, 74 expectedLog: "failed: 1", 75 }, 76 { 77 name: "message formatWithArgs = [struct]", 78 formatWithArgs: []interface{}{struct{}{}}, 79 expectedLog: "failed: {}", 80 }, 81 { 82 name: "message formatWithArgs = [string, string]", 83 formatWithArgs: []interface{}{"because", "this"}, 84 expectedLog: "failed: because this", 85 }, 86 { 87 name: "message formatWithArgs = [format, string]", 88 formatWithArgs: []interface{}{"because %s", "this"}, 89 expectedLog: "failed: because this", 90 }, 91 { 92 name: "message formatWithArgs = [format, struct]", 93 formatWithArgs: []interface{}{"because %s", struct{}{}}, 94 expectedLog: "failed: because {}", 95 }, 96 } 97 98 for _, tt := range tests { 99 tc := tt 100 101 t.Run(tc.name, func(t *testing.T) { 102 m := &mockT{t: t} 103 fail(m, "failed", "", tc.formatWithArgs...) 104 m.require(tc.expectedLog) 105 }) 106 } 107 } 108 109 type testStruct struct { 110 name string 111 } 112 113 func TestRequire(t *testing.T) { 114 zero := uint64(0) 115 struct1 := &testStruct{"hello"} 116 struct2 := &testStruct{"hello"} 117 118 tests := []struct { 119 name string 120 require func(TestingT) 121 expectedLog string 122 }{ 123 { 124 name: "Contains passes on contains", 125 require: func(t TestingT) { 126 Contains(t, "hello cat", "cat") 127 }, 128 }, 129 { 130 name: "Contains fails on empty", 131 require: func(t TestingT) { 132 Contains(t, "", "dog") 133 }, 134 expectedLog: `expected "" to contain "dog"`, 135 }, 136 { 137 name: "Contains fails on not contains", 138 require: func(t TestingT) { 139 Contains(t, "hello cat", "dog") 140 }, 141 expectedLog: `expected "hello cat" to contain "dog"`, 142 }, 143 { 144 name: "Contains fails on not contains with format", 145 require: func(t TestingT) { 146 Contains(t, "hello cat", "dog", "pay me %d", 5) 147 }, 148 expectedLog: `expected "hello cat" to contain "dog": pay me 5`, 149 }, 150 { 151 name: "Equal passes on equal: string", 152 require: func(t TestingT) { 153 Equal(t, "wazero", "wazero") 154 }, 155 }, 156 { 157 name: "Equal passes on equal: []byte", 158 require: func(t TestingT) { 159 Equal(t, []byte{1, 2, 3, 4}, []byte{1, 2, 3, 4}) 160 }, 161 }, 162 { 163 name: "Equal passes on equal: struct", 164 require: func(t TestingT) { 165 Equal(t, &testStruct{name: "takeshi"}, &testStruct{name: "takeshi"}) 166 }, 167 }, 168 { 169 name: "Equal fails on nil: string", 170 require: func(t TestingT) { 171 Equal(t, "wazero", nil) 172 }, 173 expectedLog: `expected "wazero", but was nil`, 174 }, 175 { 176 name: "Equal fails on nil: []byte", 177 require: func(t TestingT) { 178 Equal(t, []byte{1, 2, 3, 4}, nil) 179 }, 180 expectedLog: `expected []byte{0x1, 0x2, 0x3, 0x4}, but was nil`, 181 }, 182 { 183 name: "Equal fails on nil: struct", 184 require: func(t TestingT) { 185 Equal(t, &testStruct{name: "takeshi"}, nil) 186 }, 187 expectedLog: `expected &require.testStruct{name:"takeshi"}, but was nil`, 188 }, 189 190 { 191 name: "Equal fails on not same type: string", 192 require: func(t TestingT) { 193 Equal(t, "wazero", uint32(1)) 194 }, 195 expectedLog: `expected "wazero", but was uint32(1)`, 196 }, 197 { 198 name: "Equal fails on not same type: []byte", 199 require: func(t TestingT) { 200 Equal(t, []byte{1, 2, 3, 4}, "wazero") 201 }, 202 expectedLog: `expected []uint8([1 2 3 4]), but was string(wazero)`, 203 }, 204 { 205 name: "Equal fails on not same type: struct", 206 require: func(t TestingT) { 207 Equal(t, &testStruct{name: "takeshi"}, "wazero") 208 }, 209 expectedLog: `expected *require.testStruct(&{takeshi}), but was string(wazero)`, 210 }, 211 { 212 name: "Equal fails on not equal: string", 213 require: func(t TestingT) { 214 Equal(t, "wazero", "walero") 215 }, 216 expectedLog: `expected "wazero", but was "walero"`, 217 }, 218 { 219 name: "Equal fails on not equal: uint64", // ensure we don't use multi-line output! 220 require: func(t TestingT) { 221 Equal(t, uint64(12), uint64(13)) 222 }, 223 expectedLog: `expected 12, but was 13`, 224 }, 225 { 226 name: "Equal fails on not equal: []byte", 227 require: func(t TestingT) { 228 Equal(t, []byte{1, 2, 3, 4}, []byte{1, 2, 4}) 229 }, 230 expectedLog: `unexpected value 231 expected: 232 []byte{0x1, 0x2, 0x3, 0x4} 233 was: 234 []byte{0x1, 0x2, 0x4} 235 `, 236 }, 237 { 238 name: "Equal fails on not equal: struct", 239 require: func(t TestingT) { 240 Equal(t, &testStruct{name: "takeshi"}, &testStruct{name: "adrian"}) 241 }, 242 expectedLog: `unexpected value 243 expected: 244 &require.testStruct{name:"takeshi"} 245 was: 246 &require.testStruct{name:"adrian"} 247 `, 248 }, 249 { 250 name: "Equal fails on not equal: struct with format", 251 require: func(t TestingT) { 252 Equal(t, &testStruct{name: "takeshi"}, &testStruct{name: "adrian"}, "pay me %d", 5) 253 }, 254 expectedLog: `unexpected value: pay me 5 255 expected: 256 &require.testStruct{name:"takeshi"} 257 was: 258 &require.testStruct{name:"adrian"} 259 `, 260 }, 261 { 262 name: "EqualError passes on equal", 263 require: func(t TestingT) { 264 EqualError(t, io.EOF, io.EOF.Error()) 265 }, 266 }, 267 { 268 name: "EqualError fails on nil", 269 require: func(t TestingT) { 270 EqualError(t, nil, "crash") 271 }, 272 expectedLog: "expected an error, but was nil", 273 }, 274 { 275 name: "EqualError fails on not equal", 276 require: func(t TestingT) { 277 EqualError(t, io.EOF, "crash") 278 }, 279 expectedLog: `expected error "crash", but was "EOF"`, 280 }, 281 { 282 name: "EqualError fails on not equal with format", 283 require: func(t TestingT) { 284 EqualError(t, io.EOF, "crash", "pay me %d", 5) 285 }, 286 expectedLog: `expected error "crash", but was "EOF": pay me 5`, 287 }, 288 { 289 name: "Error passes on not nil", 290 require: func(t TestingT) { 291 Error(t, io.EOF) 292 }, 293 }, 294 { 295 name: "Error fails on nil", 296 require: func(t TestingT) { 297 Error(t, nil) 298 }, 299 expectedLog: "expected an error, but was nil", 300 }, 301 { 302 name: "Error fails on nil with format", 303 require: func(t TestingT) { 304 Error(t, nil, "pay me %d", 5) 305 }, 306 expectedLog: `expected an error, but was nil: pay me 5`, 307 }, 308 { 309 name: "ErrorIs passes on same", 310 require: func(t TestingT) { 311 ErrorIs(t, io.EOF, io.EOF) 312 }, 313 }, 314 { 315 name: "ErrorIs passes on wrapped", 316 require: func(t TestingT) { 317 ErrorIs(t, fmt.Errorf("cause: %w", io.EOF), io.EOF) 318 }, 319 }, 320 { 321 name: "ErrorIs fails on not equal", 322 require: func(t TestingT) { 323 ErrorIs(t, io.EOF, io.ErrUnexpectedEOF) 324 }, 325 expectedLog: "expected errors.Is(EOF, unexpected EOF), but it wasn't", 326 }, 327 { 328 name: "ErrorIs fails on not equal with format", 329 require: func(t TestingT) { 330 ErrorIs(t, io.EOF, io.ErrUnexpectedEOF, "pay me %d", 5) 331 }, 332 expectedLog: `expected errors.Is(EOF, unexpected EOF), but it wasn't: pay me 5`, 333 }, 334 { 335 name: "Nil passes on nil", 336 require: func(t TestingT) { 337 Nil(t, nil) 338 }, 339 }, 340 { 341 name: "Nil fails on not nil", 342 require: func(t TestingT) { 343 Nil(t, io.EOF) 344 }, 345 expectedLog: "expected nil, but was EOF", 346 }, 347 { 348 name: "Nil fails on not nil with format", 349 require: func(t TestingT) { 350 Nil(t, io.EOF, "pay me %d", 5) 351 }, 352 expectedLog: `expected nil, but was EOF: pay me 5`, 353 }, 354 { 355 name: "NoError passes on nil", 356 require: func(t TestingT) { 357 NoError(t, nil) 358 }, 359 }, 360 { 361 name: "NoError fails on not nil", 362 require: func(t TestingT) { 363 NoError(t, io.EOF) 364 }, 365 expectedLog: "expected no error, but was EOF", 366 }, 367 { 368 name: "NoError fails on not nil with format", 369 require: func(t TestingT) { 370 NoError(t, io.EOF, "pay me %d", 5) 371 }, 372 expectedLog: `expected no error, but was EOF: pay me 5`, 373 }, 374 { 375 name: "NotNil passes on not nil", 376 require: func(t TestingT) { 377 NotNil(t, io.EOF) 378 }, 379 }, 380 { 381 name: "NotNil fails on nil", 382 require: func(t TestingT) { 383 NotNil(t, nil) 384 }, 385 expectedLog: "expected to not be nil", 386 }, 387 { 388 name: "NotNil fails on nil with format", 389 require: func(t TestingT) { 390 NotNil(t, nil, "pay me %d", 5) 391 }, 392 expectedLog: `expected to not be nil: pay me 5`, 393 }, 394 { 395 name: "False passes on false", 396 require: func(t TestingT) { 397 False(t, false) 398 }, 399 }, 400 { 401 name: "False fails on true", 402 require: func(t TestingT) { 403 False(t, true) 404 }, 405 expectedLog: "expected false, but was true", 406 }, 407 { 408 name: "False fails on true with format", 409 require: func(t TestingT) { 410 False(t, true, "pay me %d", 5) 411 }, 412 expectedLog: "expected false, but was true: pay me 5", 413 }, 414 { 415 name: "Equal passes on equal: string", 416 require: func(t TestingT) { 417 Equal(t, "wazero", "wazero") 418 }, 419 }, 420 { 421 name: "Equal passes on equal: []byte", 422 require: func(t TestingT) { 423 Equal(t, []byte{1, 2, 3, 4}, []byte{1, 2, 3, 4}) 424 }, 425 }, 426 { 427 name: "Equal passes on equal: struct", 428 require: func(t TestingT) { 429 Equal(t, &testStruct{name: "takeshi"}, &testStruct{name: "takeshi"}) 430 }, 431 }, 432 { 433 name: "Equal fails on nil: string", 434 require: func(t TestingT) { 435 Equal(t, "wazero", nil) 436 }, 437 expectedLog: `expected "wazero", but was nil`, 438 }, 439 { 440 name: "Equal fails on nil: []byte", 441 require: func(t TestingT) { 442 Equal(t, []byte{1, 2, 3, 4}, nil) 443 }, 444 expectedLog: `expected []byte{0x1, 0x2, 0x3, 0x4}, but was nil`, 445 }, 446 { 447 name: "Equal fails on nil: struct", 448 require: func(t TestingT) { 449 Equal(t, &testStruct{name: "takeshi"}, nil) 450 }, 451 expectedLog: `expected &require.testStruct{name:"takeshi"}, but was nil`, 452 }, 453 { 454 name: "NotEqual passes on not equal", 455 require: func(t TestingT) { 456 NotEqual(t, uint32(1), uint32(2)) 457 }, 458 }, 459 { 460 name: "NotEqual fails on equal: nil", 461 require: func(t TestingT) { 462 NotEqual(t, nil, nil) 463 }, 464 expectedLog: `expected to not equal <nil>`, 465 }, 466 { 467 name: "NotEqual fails on equal: string", 468 require: func(t TestingT) { 469 NotEqual(t, "wazero", "wazero") 470 }, 471 expectedLog: `expected to not equal "wazero"`, 472 }, 473 { 474 name: "NotEqual fails on equal: []byte", 475 require: func(t TestingT) { 476 NotEqual(t, []byte{1, 2, 3, 4}, []byte{1, 2, 3, 4}) 477 }, 478 expectedLog: `expected to not equal []byte{0x1, 0x2, 0x3, 0x4}`, 479 }, 480 { 481 name: "NotEqual fails on equal: struct", 482 require: func(t TestingT) { 483 NotEqual(t, &testStruct{name: "takeshi"}, &testStruct{name: "takeshi"}) 484 }, 485 expectedLog: `expected to not equal &require.testStruct{name:"takeshi"}`, 486 }, 487 { 488 name: "NotEqual fails on equal: struct with format", 489 require: func(t TestingT) { 490 NotEqual(t, &testStruct{name: "takeshi"}, &testStruct{name: "takeshi"}, "pay me %d", 5) 491 }, 492 expectedLog: `expected to not equal &require.testStruct{name:"takeshi"}: pay me 5`, 493 }, 494 { 495 name: "NotSame passes on not same", 496 require: func(t TestingT) { 497 NotSame(t, struct1, struct2) 498 }, 499 }, 500 { 501 name: "NotSame passes on different types", 502 require: func(t TestingT) { 503 NotSame(t, struct1, &zero) 504 }, 505 }, 506 { 507 name: "NotSame fails on same pointers", 508 require: func(t TestingT) { 509 NotSame(t, struct1, struct1) 510 }, 511 expectedLog: "expected &{hello} to point to a different object", 512 }, 513 { 514 name: "NotSame fails on same pointers with format", 515 require: func(t TestingT) { 516 NotSame(t, struct1, struct1, "pay me %d", 5) 517 }, 518 expectedLog: "expected &{hello} to point to a different object: pay me 5", 519 }, 520 { 521 name: "Same passes on same", 522 require: func(t TestingT) { 523 Same(t, struct1, struct1) 524 }, 525 }, 526 { 527 name: "Same fails on different types", 528 require: func(t TestingT) { 529 Same(t, struct1, &zero) 530 }, 531 expectedLog: fmt.Sprintf("expected %v to point to the same object as &{hello}", &zero), 532 }, 533 { 534 name: "Same fails on different pointers", 535 require: func(t TestingT) { 536 Same(t, struct1, struct2) 537 }, 538 expectedLog: "expected &{hello} to point to the same object as &{hello}", 539 }, 540 { 541 name: "Same fails on different pointers with format", 542 require: func(t TestingT) { 543 Same(t, struct1, struct2, "pay me %d", 5) 544 }, 545 expectedLog: "expected &{hello} to point to the same object as &{hello}: pay me 5", 546 }, 547 { 548 name: "True passes on true", 549 require: func(t TestingT) { 550 True(t, true) 551 }, 552 }, 553 { 554 name: "True fails on false", 555 require: func(t TestingT) { 556 True(t, false) 557 }, 558 expectedLog: "expected true, but was false", 559 }, 560 { 561 name: "True fails on false with format", 562 require: func(t TestingT) { 563 True(t, false, "pay me %d", 5) 564 }, 565 expectedLog: "expected true, but was false: pay me 5", 566 }, 567 { 568 name: "Zero passes on float32(0)", 569 require: func(t TestingT) { 570 Zero(t, float32(0)) 571 }, 572 }, 573 { 574 name: "Zero passes on float64(0)", 575 require: func(t TestingT) { 576 Zero(t, float64(0)) 577 }, 578 }, 579 { 580 name: "Zero passes on int(0)", 581 require: func(t TestingT) { 582 Zero(t, int(0)) 583 }, 584 }, 585 { 586 name: "Zero passes on uint32(0)", 587 require: func(t TestingT) { 588 Zero(t, uint32(0)) 589 }, 590 }, 591 { 592 name: "Zero passes on uint64(0)", 593 require: func(t TestingT) { 594 Zero(t, uint64(0)) 595 }, 596 }, 597 { 598 name: "Zero fails on float32(1)", 599 require: func(t TestingT) { 600 Zero(t, float32(1)) 601 }, 602 expectedLog: "expected zero, but was 1", 603 }, 604 { 605 name: "Zero fails on float64(1)", 606 require: func(t TestingT) { 607 Zero(t, float64(1)) 608 }, 609 expectedLog: "expected zero, but was 1", 610 }, 611 { 612 name: "Zero fails on int(1)", 613 require: func(t TestingT) { 614 Zero(t, int(1)) 615 }, 616 expectedLog: "expected zero, but was 1", 617 }, 618 { 619 name: "Zero fails on uint32(1)", 620 require: func(t TestingT) { 621 Zero(t, uint32(1)) 622 }, 623 expectedLog: "expected zero, but was 1", 624 }, 625 { 626 name: "Zero fails on uint64(1)", 627 require: func(t TestingT) { 628 Zero(t, uint64(1)) 629 }, 630 expectedLog: "expected zero, but was 1", 631 }, 632 { 633 name: "Zero fails on uint64(1) with format", 634 require: func(t TestingT) { 635 Zero(t, uint64(1), "pay me %d", 5) 636 }, 637 expectedLog: "expected zero, but was 1: pay me 5", 638 }, 639 } 640 641 for _, tt := range tests { 642 tc := tt 643 t.Run(tc.name, func(t *testing.T) { 644 m := &mockT{t: t} 645 tc.require(m) 646 m.require(tc.expectedLog) 647 }) 648 } 649 } 650 651 // compile-time check to ensure mockT implements TestingT 652 var _ TestingT = &mockT{} 653 654 type mockT struct { 655 t *testing.T 656 log string 657 } 658 659 // Fatal implements TestingT.Fatal 660 func (t *mockT) Fatal(args ...interface{}) { 661 if t.log != "" { 662 t.t.Fatal("already called Fatal(") 663 } 664 t.log = fmt.Sprint(args...) 665 } 666 667 func (t *mockT) require(expectedLog string) { 668 if expectedLog != t.log { 669 t.t.Fatalf("expected log=%q, but found %q", expectedLog, t.log) 670 } 671 }