github.com/v2pro/plz@v0.0.0-20221028024117-e5f9aec5b631/test/testify/assert/assertions.go (about) 1 package assert 2 3 import ( 4 "bufio" 5 "bytes" 6 "encoding/json" 7 "errors" 8 "fmt" 9 "math" 10 "os" 11 "reflect" 12 "regexp" 13 "runtime" 14 "strings" 15 "time" 16 "unicode" 17 "unicode/utf8" 18 "github.com/v2pro/plz/test/go-difflib/difflib" 19 "github.com/v2pro/plz/test/go-spew/spew" 20 ) 21 22 //go:generate go run ../_codegen/main.go -output-package=assert -template=assertion_format.go.tmpl 23 24 // TestingT is an interface wrapper around *testing.T 25 type TestingT interface { 26 Errorf(format string, args ...interface{}) 27 } 28 29 // Comparison a custom function that returns true on success and false on failure 30 type Comparison func() (success bool) 31 32 /* 33 Helper functions 34 */ 35 36 // ObjectsAreEqual determines if two objects are considered equal. 37 // 38 // This function does no assertion of any kind. 39 func ObjectsAreEqual(expected, actual interface{}) bool { 40 41 if expected == nil || actual == nil { 42 return expected == actual 43 } 44 if exp, ok := expected.([]byte); ok { 45 act, ok := actual.([]byte) 46 if !ok { 47 return false 48 } else if exp == nil || act == nil { 49 return exp == nil && act == nil 50 } 51 return bytes.Equal(exp, act) 52 } 53 return reflect.DeepEqual(expected, actual) 54 55 } 56 57 // ObjectsAreEqualValues gets whether two objects are equal, or if their 58 // values are equal. 59 func ObjectsAreEqualValues(expected, actual interface{}) bool { 60 if ObjectsAreEqual(expected, actual) { 61 return true 62 } 63 64 actualType := reflect.TypeOf(actual) 65 if actualType == nil { 66 return false 67 } 68 expectedValue := reflect.ValueOf(expected) 69 if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) { 70 // Attempt comparison after type conversion 71 return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual) 72 } 73 74 return false 75 } 76 77 /* CallerInfo is necessary because the assert functions use the testing object 78 internally, causing it to print the file:line of the assert method, rather than where 79 the problem actually occurred in calling code.*/ 80 81 // CallerInfo returns an array of strings containing the file and line number 82 // of each stack frame leading from the current test to the assert call that 83 // failed. 84 func CallerInfo() []string { 85 86 pc := uintptr(0) 87 file := "" 88 line := 0 89 ok := false 90 name := "" 91 92 callers := []string{} 93 for i := 0; ; i++ { 94 pc, file, line, ok = runtime.Caller(i) 95 if !ok { 96 // The breaks below failed to terminate the loop, and we ran off the 97 // end of the call stack. 98 break 99 } 100 101 // This is a huge edge case, but it will panic if this is the case, see #180 102 if file == "<autogenerated>" { 103 break 104 } 105 106 f := runtime.FuncForPC(pc) 107 if f == nil { 108 break 109 } 110 name = f.Name() 111 112 // testing.tRunner is the standard library function that calls 113 // tests. Subtests are called directly by tRunner, without going through 114 // the Test/Benchmark/Example function that contains the t.Run calls, so 115 // with subtests we should break when we hit tRunner, without adding it 116 // to the list of callers. 117 if name == "testing.tRunner" { 118 break 119 } 120 121 parts := strings.Split(file, "/") 122 file = parts[len(parts)-1] 123 if len(parts) > 1 { 124 dir := parts[len(parts)-2] 125 if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { 126 callers = append(callers, fmt.Sprintf("%s:%d", file, line)) 127 } 128 } 129 130 // Drop the package 131 segments := strings.Split(name, ".") 132 name = segments[len(segments)-1] 133 if isTest(name, "Test") || 134 isTest(name, "Benchmark") || 135 isTest(name, "Example") { 136 break 137 } 138 } 139 140 return callers 141 } 142 143 // Stolen from the `go test` tool. 144 // isTest tells whether name looks like a test (or benchmark, according to prefix). 145 // It is a Test (say) if there is a character after Test that is not a lower-case letter. 146 // We don't want TesticularCancer. 147 func isTest(name, prefix string) bool { 148 if !strings.HasPrefix(name, prefix) { 149 return false 150 } 151 if len(name) == len(prefix) { // "Test" is ok 152 return true 153 } 154 rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) 155 return !unicode.IsLower(rune) 156 } 157 158 // getWhitespaceString returns a string that is long enough to overwrite the default 159 // output from the go testing framework. 160 func getWhitespaceString() string { 161 162 _, file, line, ok := runtime.Caller(1) 163 if !ok { 164 return "" 165 } 166 parts := strings.Split(file, "/") 167 file = parts[len(parts)-1] 168 169 return strings.Repeat(" ", len(fmt.Sprintf("%s:%d: ", file, line))) 170 171 } 172 173 func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { 174 if len(msgAndArgs) == 0 || msgAndArgs == nil { 175 return "" 176 } 177 if len(msgAndArgs) == 1 { 178 return msgAndArgs[0].(string) 179 } 180 if len(msgAndArgs) > 1 { 181 return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) 182 } 183 return "" 184 } 185 186 // Aligns the provided message so that all lines after the first line start at the same location as the first line. 187 // Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab). 188 // The longestLabelLen parameter specifies the length of the longest label in the output (required becaues this is the 189 // basis on which the alignment occurs). 190 func indentMessageLines(message string, longestLabelLen int) string { 191 outBuf := new(bytes.Buffer) 192 193 for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { 194 // no need to align first line because it starts at the correct location (after the label) 195 if i != 0 { 196 // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab 197 outBuf.WriteString("\n\r\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") 198 } 199 outBuf.WriteString(scanner.Text()) 200 } 201 202 return outBuf.String() 203 } 204 205 type failNower interface { 206 FailNow() 207 } 208 209 // FailNow fails test 210 func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { 211 Fail(t, failureMessage, msgAndArgs...) 212 213 // We cannot extend TestingT with FailNow() and 214 // maintain backwards compatibility, so we fallback 215 // to panicking when FailNow is not available in 216 // TestingT. 217 // See issue #263 218 219 if t, ok := t.(failNower); ok { 220 t.FailNow() 221 } else { 222 panic("test failed and t is missing `FailNow()`") 223 } 224 return false 225 } 226 227 // Fail reports a failure through 228 func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { 229 content := []labeledContent{ 230 {"Error", failureMessage}, 231 } 232 233 message := messageFromMsgAndArgs(msgAndArgs...) 234 if len(message) > 0 { 235 content = append(content, labeledContent{"Messages", message}) 236 } 237 238 t.Errorf("%s", "\r"+getWhitespaceString()+labeledOutput(content...)) 239 240 return false 241 } 242 243 type labeledContent struct { 244 label string 245 content string 246 } 247 248 // labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: 249 // 250 // \r\t{{label}}:{{align_spaces}}\t{{content}}\n 251 // 252 // The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. 253 // If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this 254 // alignment is achieved, "\t{{content}}\n" is added for the output. 255 // 256 // If the content of the labeledOutput contains line breaks, the subsequent lines are aligned so that they start at the same location as the first line. 257 func labeledOutput(content ...labeledContent) string { 258 longestLabel := 0 259 for _, v := range content { 260 if len(v.label) > longestLabel { 261 longestLabel = len(v.label) 262 } 263 } 264 var output string 265 for _, v := range content { 266 output += "\r\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n" 267 } 268 return output 269 } 270 271 // Implements asserts that an object is implemented by the specified interface. 272 // 273 // assert.Implements(t, (*MyInterface)(nil), new(MyObject)) 274 func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { 275 interfaceType := reflect.TypeOf(interfaceObject).Elem() 276 277 if object == nil { 278 return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...) 279 } 280 if !reflect.TypeOf(object).Implements(interfaceType) { 281 return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...) 282 } 283 284 return true 285 } 286 287 // IsType asserts that the specified objects are of the same type. 288 func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { 289 290 if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { 291 return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) 292 } 293 294 return true 295 } 296 297 // Equal asserts that two objects are equal. 298 // 299 // assert.Equal(t, 123, 123) 300 // 301 // Pointer variable equality is determined based on the equality of the 302 // referenced values (as opposed to the memory addresses). Function equality 303 // cannot be determined and will always fail. 304 func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 305 if err := validateEqualArgs(expected, actual); err != nil { 306 return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)", 307 expected, actual, err), msgAndArgs...) 308 } 309 310 if !ObjectsAreEqual(expected, actual) { 311 diff := diff(expected, actual) 312 expected, actual = formatUnequalValues(expected, actual) 313 return Fail(t, fmt.Sprintf("Not equal: \n"+ 314 "expected: %s\n"+ 315 "actual : %s%s", expected, actual, diff), msgAndArgs...) 316 } 317 318 return true 319 320 } 321 322 // formatUnequalValues takes two values of arbitrary types and returns string 323 // representations appropriate to be presented to the user. 324 // 325 // If the values are not of like type, the returned strings will be prefixed 326 // with the type name, and the value will be enclosed in parenthesis similar 327 // to a type conversion in the Go grammar. 328 func formatUnequalValues(expected, actual interface{}) (e string, a string) { 329 if reflect.TypeOf(expected) != reflect.TypeOf(actual) { 330 return fmt.Sprintf("%T(%#v)", expected, expected), 331 fmt.Sprintf("%T(%#v)", actual, actual) 332 } 333 334 return fmt.Sprintf("%#v", expected), 335 fmt.Sprintf("%#v", actual) 336 } 337 338 // EqualValues asserts that two objects are equal or convertable to the same types 339 // and equal. 340 // 341 // assert.EqualValues(t, uint32(123), int32(123)) 342 func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 343 344 if !ObjectsAreEqualValues(expected, actual) { 345 diff := diff(expected, actual) 346 expected, actual = formatUnequalValues(expected, actual) 347 return Fail(t, fmt.Sprintf("Not equal: \n"+ 348 "expected: %s\n"+ 349 "actual : %s%s", expected, actual, diff), msgAndArgs...) 350 } 351 352 return true 353 354 } 355 356 // Exactly asserts that two objects are equal in value and type. 357 // 358 // assert.Exactly(t, int32(123), int64(123)) 359 func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 360 361 aType := reflect.TypeOf(expected) 362 bType := reflect.TypeOf(actual) 363 364 if aType != bType { 365 return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...) 366 } 367 368 return Equal(t, expected, actual, msgAndArgs...) 369 370 } 371 372 // NotNil asserts that the specified object is not nil. 373 // 374 // assert.NotNil(t, err) 375 func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 376 if !isNil(object) { 377 return true 378 } 379 return Fail(t, "Expected value not to be nil.", msgAndArgs...) 380 } 381 382 // isNil checks if a specified object is nil or not, without Failing. 383 func isNil(object interface{}) bool { 384 if object == nil { 385 return true 386 } 387 388 value := reflect.ValueOf(object) 389 kind := value.Kind() 390 if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() { 391 return true 392 } 393 394 return false 395 } 396 397 // Nil asserts that the specified object is nil. 398 // 399 // assert.Nil(t, err) 400 func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 401 if isNil(object) { 402 return true 403 } 404 return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) 405 } 406 407 // isEmpty gets whether the specified object is considered empty or not. 408 func isEmpty(object interface{}) bool { 409 410 // get nil case out of the way 411 if object == nil { 412 return true 413 } 414 415 objValue := reflect.ValueOf(object) 416 417 switch objValue.Kind() { 418 // collection types are empty when they have no element 419 case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: 420 return objValue.Len() == 0 421 // pointers are empty if nil or if the value they point to is empty 422 case reflect.Ptr: 423 if objValue.IsNil() { 424 return true 425 } 426 deref := objValue.Elem().Interface() 427 return isEmpty(deref) 428 // for all other types, compare against the zero value 429 default: 430 zero := reflect.Zero(objValue.Type()) 431 return reflect.DeepEqual(object, zero.Interface()) 432 } 433 } 434 435 // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either 436 // a slice or a channel with len == 0. 437 // 438 // assert.Empty(t, obj) 439 func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 440 441 pass := isEmpty(object) 442 if !pass { 443 Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) 444 } 445 446 return pass 447 448 } 449 450 // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either 451 // a slice or a channel with len == 0. 452 // 453 // if assert.NotEmpty(t, obj) { 454 // assert.Equal(t, "two", obj[1]) 455 // } 456 func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 457 458 pass := !isEmpty(object) 459 if !pass { 460 Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...) 461 } 462 463 return pass 464 465 } 466 467 // getLen try to get length of object. 468 // return (false, 0) if impossible. 469 func getLen(x interface{}) (ok bool, length int) { 470 v := reflect.ValueOf(x) 471 defer func() { 472 if e := recover(); e != nil { 473 ok = false 474 } 475 }() 476 return true, v.Len() 477 } 478 479 // Len asserts that the specified object has specific length. 480 // Len also fails if the object has a type that len() not accept. 481 // 482 // assert.Len(t, mySlice, 3) 483 func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { 484 ok, l := getLen(object) 485 if !ok { 486 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) 487 } 488 489 if l != length { 490 return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) 491 } 492 return true 493 } 494 495 // True asserts that the specified value is true. 496 // 497 // assert.True(t, myBool) 498 func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { 499 500 if value != true { 501 return Fail(t, "Should be true", msgAndArgs...) 502 } 503 504 return true 505 506 } 507 508 // False asserts that the specified value is false. 509 // 510 // assert.False(t, myBool) 511 func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { 512 513 if value != false { 514 return Fail(t, "Should be false", msgAndArgs...) 515 } 516 517 return true 518 519 } 520 521 // NotEqual asserts that the specified values are NOT equal. 522 // 523 // assert.NotEqual(t, obj1, obj2) 524 // 525 // Pointer variable equality is determined based on the equality of the 526 // referenced values (as opposed to the memory addresses). 527 func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 528 if err := validateEqualArgs(expected, actual); err != nil { 529 return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)", 530 expected, actual, err), msgAndArgs...) 531 } 532 533 if ObjectsAreEqual(expected, actual) { 534 return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) 535 } 536 537 return true 538 539 } 540 541 // containsElement try loop over the list check if the list includes the element. 542 // return (false, false) if impossible. 543 // return (true, false) if element was not found. 544 // return (true, true) if element was found. 545 func includeElement(list interface{}, element interface{}) (ok, found bool) { 546 547 listValue := reflect.ValueOf(list) 548 elementValue := reflect.ValueOf(element) 549 defer func() { 550 if e := recover(); e != nil { 551 ok = false 552 found = false 553 } 554 }() 555 556 if reflect.TypeOf(list).Kind() == reflect.String { 557 return true, strings.Contains(listValue.String(), elementValue.String()) 558 } 559 560 if reflect.TypeOf(list).Kind() == reflect.Map { 561 mapKeys := listValue.MapKeys() 562 for i := 0; i < len(mapKeys); i++ { 563 if ObjectsAreEqual(mapKeys[i].Interface(), element) { 564 return true, true 565 } 566 } 567 return true, false 568 } 569 570 for i := 0; i < listValue.Len(); i++ { 571 if ObjectsAreEqual(listValue.Index(i).Interface(), element) { 572 return true, true 573 } 574 } 575 return true, false 576 577 } 578 579 // Contains asserts that the specified string, list(array, slice...) or map contains the 580 // specified substring or element. 581 // 582 // assert.Contains(t, "Hello World", "World") 583 // assert.Contains(t, ["Hello", "World"], "World") 584 // assert.Contains(t, {"Hello": "World"}, "Hello") 585 func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { 586 587 ok, found := includeElement(s, contains) 588 if !ok { 589 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) 590 } 591 if !found { 592 return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...) 593 } 594 595 return true 596 597 } 598 599 // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the 600 // specified substring or element. 601 // 602 // assert.NotContains(t, "Hello World", "Earth") 603 // assert.NotContains(t, ["Hello", "World"], "Earth") 604 // assert.NotContains(t, {"Hello": "World"}, "Earth") 605 func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { 606 607 ok, found := includeElement(s, contains) 608 if !ok { 609 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) 610 } 611 if found { 612 return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...) 613 } 614 615 return true 616 617 } 618 619 // Subset asserts that the specified list(array, slice...) contains all 620 // elements given in the specified subset(array, slice...). 621 // 622 // assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") 623 func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { 624 if subset == nil { 625 return true // we consider nil to be equal to the nil set 626 } 627 628 subsetValue := reflect.ValueOf(subset) 629 defer func() { 630 if e := recover(); e != nil { 631 ok = false 632 } 633 }() 634 635 listKind := reflect.TypeOf(list).Kind() 636 subsetKind := reflect.TypeOf(subset).Kind() 637 638 if listKind != reflect.Array && listKind != reflect.Slice { 639 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) 640 } 641 642 if subsetKind != reflect.Array && subsetKind != reflect.Slice { 643 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) 644 } 645 646 for i := 0; i < subsetValue.Len(); i++ { 647 element := subsetValue.Index(i).Interface() 648 ok, found := includeElement(list, element) 649 if !ok { 650 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) 651 } 652 if !found { 653 return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, element), msgAndArgs...) 654 } 655 } 656 657 return true 658 } 659 660 // NotSubset asserts that the specified list(array, slice...) contains not all 661 // elements given in the specified subset(array, slice...). 662 // 663 // assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") 664 func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { 665 if subset == nil { 666 return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...) 667 } 668 669 subsetValue := reflect.ValueOf(subset) 670 defer func() { 671 if e := recover(); e != nil { 672 ok = false 673 } 674 }() 675 676 listKind := reflect.TypeOf(list).Kind() 677 subsetKind := reflect.TypeOf(subset).Kind() 678 679 if listKind != reflect.Array && listKind != reflect.Slice { 680 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) 681 } 682 683 if subsetKind != reflect.Array && subsetKind != reflect.Slice { 684 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) 685 } 686 687 for i := 0; i < subsetValue.Len(); i++ { 688 element := subsetValue.Index(i).Interface() 689 ok, found := includeElement(list, element) 690 if !ok { 691 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) 692 } 693 if !found { 694 return true 695 } 696 } 697 698 return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) 699 } 700 701 // ElementsMatch asserts that the specified listA(array, slice...) is equal to specified 702 // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, 703 // the number of appearances of each of them in both lists should match. 704 // 705 // assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])) 706 func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { 707 if isEmpty(listA) && isEmpty(listB) { 708 return true 709 } 710 711 aKind := reflect.TypeOf(listA).Kind() 712 bKind := reflect.TypeOf(listB).Kind() 713 714 if aKind != reflect.Array && aKind != reflect.Slice { 715 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listA, aKind), msgAndArgs...) 716 } 717 718 if bKind != reflect.Array && bKind != reflect.Slice { 719 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listB, bKind), msgAndArgs...) 720 } 721 722 aValue := reflect.ValueOf(listA) 723 bValue := reflect.ValueOf(listB) 724 725 aLen := aValue.Len() 726 bLen := bValue.Len() 727 728 if aLen != bLen { 729 return Fail(t, fmt.Sprintf("lengths don't match: %d != %d", aLen, bLen), msgAndArgs...) 730 } 731 732 // Mark indexes in bValue that we already used 733 visited := make([]bool, bLen) 734 for i := 0; i < aLen; i++ { 735 element := aValue.Index(i).Interface() 736 found := false 737 for j := 0; j < bLen; j++ { 738 if visited[j] { 739 continue 740 } 741 if ObjectsAreEqual(bValue.Index(j).Interface(), element) { 742 visited[j] = true 743 found = true 744 break 745 } 746 } 747 if !found { 748 return Fail(t, fmt.Sprintf("element %s appears more times in %s than in %s", element, aValue, bValue), msgAndArgs...) 749 } 750 } 751 752 return true 753 } 754 755 // Condition uses a Comparison to assert a complex condition. 756 func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { 757 result := comp() 758 if !result { 759 Fail(t, "Condition failed!", msgAndArgs...) 760 } 761 return result 762 } 763 764 // PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics 765 // methods, and represents a simple func that takes no arguments, and returns nothing. 766 type PanicTestFunc func() 767 768 // didPanic returns true if the function passed to it panics. Otherwise, it returns false. 769 func didPanic(f PanicTestFunc) (bool, interface{}) { 770 771 didPanic := false 772 var message interface{} 773 func() { 774 775 defer func() { 776 if message = recover(); message != nil { 777 didPanic = true 778 } 779 }() 780 781 // call the target function 782 f() 783 784 }() 785 786 return didPanic, message 787 788 } 789 790 // Panics asserts that the code inside the specified PanicTestFunc panics. 791 // 792 // assert.Panics(t, func(){ GoCrazy() }) 793 func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { 794 795 if funcDidPanic, panicValue := didPanic(f); !funcDidPanic { 796 return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) 797 } 798 799 return true 800 } 801 802 // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that 803 // the recovered panic value equals the expected panic value. 804 // 805 // assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) 806 func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { 807 808 funcDidPanic, panicValue := didPanic(f) 809 if !funcDidPanic { 810 return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) 811 } 812 if panicValue != expected { 813 return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%v\n\r\tPanic value:\t%v", f, expected, panicValue), msgAndArgs...) 814 } 815 816 return true 817 } 818 819 // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. 820 // 821 // assert.NotPanics(t, func(){ RemainCalm() }) 822 func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { 823 824 if funcDidPanic, panicValue := didPanic(f); funcDidPanic { 825 return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...) 826 } 827 828 return true 829 } 830 831 // WithinDuration asserts that the two times are within duration delta of each other. 832 // 833 // assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) 834 func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { 835 836 dt := expected.Sub(actual) 837 if dt < -delta || dt > delta { 838 return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) 839 } 840 841 return true 842 } 843 844 func toFloat(x interface{}) (float64, bool) { 845 var xf float64 846 xok := true 847 848 switch xn := x.(type) { 849 case uint8: 850 xf = float64(xn) 851 case uint16: 852 xf = float64(xn) 853 case uint32: 854 xf = float64(xn) 855 case uint64: 856 xf = float64(xn) 857 case int: 858 xf = float64(xn) 859 case int8: 860 xf = float64(xn) 861 case int16: 862 xf = float64(xn) 863 case int32: 864 xf = float64(xn) 865 case int64: 866 xf = float64(xn) 867 case float32: 868 xf = float64(xn) 869 case float64: 870 xf = float64(xn) 871 case time.Duration: 872 xf = float64(xn) 873 default: 874 xok = false 875 } 876 877 return xf, xok 878 } 879 880 // InDelta asserts that the two numerals are within delta of each other. 881 // 882 // assert.InDelta(t, math.Pi, (22 / 7.0), 0.01) 883 func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { 884 885 af, aok := toFloat(expected) 886 bf, bok := toFloat(actual) 887 888 if !aok || !bok { 889 return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...) 890 } 891 892 if math.IsNaN(af) { 893 return Fail(t, fmt.Sprintf("Expected must not be NaN"), msgAndArgs...) 894 } 895 896 if math.IsNaN(bf) { 897 return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...) 898 } 899 900 dt := af - bf 901 if dt < -delta || dt > delta { 902 return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) 903 } 904 905 return true 906 } 907 908 // InDeltaSlice is the same as InDelta, except it compares two slices. 909 func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { 910 if expected == nil || actual == nil || 911 reflect.TypeOf(actual).Kind() != reflect.Slice || 912 reflect.TypeOf(expected).Kind() != reflect.Slice { 913 return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) 914 } 915 916 actualSlice := reflect.ValueOf(actual) 917 expectedSlice := reflect.ValueOf(expected) 918 919 for i := 0; i < actualSlice.Len(); i++ { 920 result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...) 921 if !result { 922 return result 923 } 924 } 925 926 return true 927 } 928 929 // InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. 930 func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { 931 if expected == nil || actual == nil || 932 reflect.TypeOf(actual).Kind() != reflect.Map || 933 reflect.TypeOf(expected).Kind() != reflect.Map { 934 return Fail(t, "Arguments must be maps", msgAndArgs...) 935 } 936 937 expectedMap := reflect.ValueOf(expected) 938 actualMap := reflect.ValueOf(actual) 939 940 if expectedMap.Len() != actualMap.Len() { 941 return Fail(t, "Arguments must have the same numbe of keys", msgAndArgs...) 942 } 943 944 for _, k := range expectedMap.MapKeys() { 945 ev := expectedMap.MapIndex(k) 946 av := actualMap.MapIndex(k) 947 948 if !ev.IsValid() { 949 return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...) 950 } 951 952 if !av.IsValid() { 953 return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...) 954 } 955 956 if !InDelta( 957 t, 958 ev.Interface(), 959 av.Interface(), 960 delta, 961 msgAndArgs..., 962 ) { 963 return false 964 } 965 } 966 967 return true 968 } 969 970 func calcRelativeError(expected, actual interface{}) (float64, error) { 971 af, aok := toFloat(expected) 972 if !aok { 973 return 0, fmt.Errorf("expected value %q cannot be converted to float", expected) 974 } 975 if af == 0 { 976 return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error") 977 } 978 bf, bok := toFloat(actual) 979 if !bok { 980 return 0, fmt.Errorf("actual value %q cannot be converted to float", actual) 981 } 982 983 return math.Abs(af-bf) / math.Abs(af), nil 984 } 985 986 // InEpsilon asserts that expected and actual have a relative error less than epsilon 987 func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { 988 actualEpsilon, err := calcRelativeError(expected, actual) 989 if err != nil { 990 return Fail(t, err.Error(), msgAndArgs...) 991 } 992 if actualEpsilon > epsilon { 993 return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ 994 " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) 995 } 996 997 return true 998 } 999 1000 // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. 1001 func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { 1002 if expected == nil || actual == nil || 1003 reflect.TypeOf(actual).Kind() != reflect.Slice || 1004 reflect.TypeOf(expected).Kind() != reflect.Slice { 1005 return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) 1006 } 1007 1008 actualSlice := reflect.ValueOf(actual) 1009 expectedSlice := reflect.ValueOf(expected) 1010 1011 for i := 0; i < actualSlice.Len(); i++ { 1012 result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon) 1013 if !result { 1014 return result 1015 } 1016 } 1017 1018 return true 1019 } 1020 1021 /* 1022 Errors 1023 */ 1024 1025 // NoError asserts that a function returned no error (i.e. `nil`). 1026 // 1027 // actualObj, err := SomeFunction() 1028 // if assert.NoError(t, err) { 1029 // assert.Equal(t, expectedObj, actualObj) 1030 // } 1031 func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { 1032 if err != nil { 1033 return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) 1034 } 1035 1036 return true 1037 } 1038 1039 // Error asserts that a function returned an error (i.e. not `nil`). 1040 // 1041 // actualObj, err := SomeFunction() 1042 // if assert.Error(t, err) { 1043 // assert.Equal(t, expectedError, err) 1044 // } 1045 func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { 1046 1047 if err == nil { 1048 return Fail(t, "An error is expected but got nil.", msgAndArgs...) 1049 } 1050 1051 return true 1052 } 1053 1054 // EqualError asserts that a function returned an error (i.e. not `nil`) 1055 // and that it is equal to the provided error. 1056 // 1057 // actualObj, err := SomeFunction() 1058 // assert.EqualError(t, err, expectedErrorString) 1059 func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { 1060 if !Error(t, theError, msgAndArgs...) { 1061 return false 1062 } 1063 expected := errString 1064 actual := theError.Error() 1065 // don't need to use deep equals here, we know they are both strings 1066 if expected != actual { 1067 return Fail(t, fmt.Sprintf("Error message not equal:\n"+ 1068 "expected: %q\n"+ 1069 "actual : %q", expected, actual), msgAndArgs...) 1070 } 1071 return true 1072 } 1073 1074 // matchRegexp return true if a specified regexp matches a string. 1075 func matchRegexp(rx interface{}, str interface{}) bool { 1076 1077 var r *regexp.Regexp 1078 if rr, ok := rx.(*regexp.Regexp); ok { 1079 r = rr 1080 } else { 1081 r = regexp.MustCompile(fmt.Sprint(rx)) 1082 } 1083 1084 return (r.FindStringIndex(fmt.Sprint(str)) != nil) 1085 1086 } 1087 1088 // Regexp asserts that a specified regexp matches a string. 1089 // 1090 // assert.Regexp(t, regexp.MustCompile("start"), "it's starting") 1091 // assert.Regexp(t, "start...$", "it's not starting") 1092 func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { 1093 1094 match := matchRegexp(rx, str) 1095 1096 if !match { 1097 Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) 1098 } 1099 1100 return match 1101 } 1102 1103 // NotRegexp asserts that a specified regexp does not match a string. 1104 // 1105 // assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") 1106 // assert.NotRegexp(t, "^start", "it's not starting") 1107 func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { 1108 match := matchRegexp(rx, str) 1109 1110 if match { 1111 Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) 1112 } 1113 1114 return !match 1115 1116 } 1117 1118 // Zero asserts that i is the zero value for its type. 1119 func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { 1120 if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { 1121 return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) 1122 } 1123 return true 1124 } 1125 1126 // NotZero asserts that i is not the zero value for its type. 1127 func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { 1128 if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { 1129 return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) 1130 } 1131 return true 1132 } 1133 1134 // FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file. 1135 func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { 1136 info, err := os.Lstat(path) 1137 if err != nil { 1138 if os.IsNotExist(err) { 1139 return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) 1140 } 1141 return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) 1142 } 1143 if info.IsDir() { 1144 return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...) 1145 } 1146 return true 1147 } 1148 1149 // DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists. 1150 func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { 1151 info, err := os.Lstat(path) 1152 if err != nil { 1153 if os.IsNotExist(err) { 1154 return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) 1155 } 1156 return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) 1157 } 1158 if !info.IsDir() { 1159 return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...) 1160 } 1161 return true 1162 } 1163 1164 // JSONEq asserts that two JSON strings are equivalent. 1165 // 1166 // assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) 1167 func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { 1168 var expectedJSONAsInterface, actualJSONAsInterface interface{} 1169 1170 if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil { 1171 return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...) 1172 } 1173 1174 if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil { 1175 return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...) 1176 } 1177 1178 return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) 1179 } 1180 1181 func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { 1182 t := reflect.TypeOf(v) 1183 k := t.Kind() 1184 1185 if k == reflect.Ptr { 1186 t = t.Elem() 1187 k = t.Kind() 1188 } 1189 return t, k 1190 } 1191 1192 // diff returns a diff of both values as long as both are of the same type and 1193 // are a struct, map, slice or array. Otherwise it returns an empty string. 1194 func diff(expected interface{}, actual interface{}) string { 1195 if expected == nil || actual == nil { 1196 return "" 1197 } 1198 1199 et, ek := typeAndKind(expected) 1200 at, _ := typeAndKind(actual) 1201 1202 if et != at { 1203 return "" 1204 } 1205 1206 if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array { 1207 return "" 1208 } 1209 1210 e := spewConfig.Sdump(expected) 1211 a := spewConfig.Sdump(actual) 1212 1213 diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ 1214 A: difflib.SplitLines(e), 1215 B: difflib.SplitLines(a), 1216 FromFile: "Expected", 1217 FromDate: "", 1218 ToFile: "Actual", 1219 ToDate: "", 1220 Context: 1, 1221 }) 1222 1223 return "\n\nDiff:\n" + diff 1224 } 1225 1226 // validateEqualArgs checks whether provided arguments can be safely used in the 1227 // Equal/NotEqual functions. 1228 func validateEqualArgs(expected, actual interface{}) error { 1229 if isFunction(expected) || isFunction(actual) { 1230 return errors.New("cannot take func type as argument") 1231 } 1232 return nil 1233 } 1234 1235 func isFunction(arg interface{}) bool { 1236 if arg == nil { 1237 return false 1238 } 1239 return reflect.TypeOf(arg).Kind() == reflect.Func 1240 } 1241 1242 var spewConfig = spew.ConfigState{ 1243 Indent: " ", 1244 DisablePointerAddresses: true, 1245 DisableCapacities: true, 1246 SortKeys: true, 1247 }