assertions.go (58691B)
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 "runtime/debug" 15 "strings" 16 "time" 17 "unicode" 18 "unicode/utf8" 19 20 "github.com/davecgh/go-spew/spew" 21 "github.com/pmezard/go-difflib/difflib" 22 yaml "gopkg.in/yaml.v3" 23 ) 24 25 //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" 26 27 // TestingT is an interface wrapper around *testing.T 28 type TestingT interface { 29 Errorf(format string, args ...interface{}) 30 } 31 32 // ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful 33 // for table driven tests. 34 type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool 35 36 // ValueAssertionFunc is a common function prototype when validating a single value. Can be useful 37 // for table driven tests. 38 type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool 39 40 // BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful 41 // for table driven tests. 42 type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool 43 44 // ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful 45 // for table driven tests. 46 type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool 47 48 // Comparison is a custom function that returns true on success and false on failure 49 type Comparison func() (success bool) 50 51 /* 52 Helper functions 53 */ 54 55 // ObjectsAreEqual determines if two objects are considered equal. 56 // 57 // This function does no assertion of any kind. 58 func ObjectsAreEqual(expected, actual interface{}) bool { 59 if expected == nil || actual == nil { 60 return expected == actual 61 } 62 63 exp, ok := expected.([]byte) 64 if !ok { 65 return reflect.DeepEqual(expected, actual) 66 } 67 68 act, ok := actual.([]byte) 69 if !ok { 70 return false 71 } 72 if exp == nil || act == nil { 73 return exp == nil && act == nil 74 } 75 return bytes.Equal(exp, act) 76 } 77 78 // copyExportedFields iterates downward through nested data structures and creates a copy 79 // that only contains the exported struct fields. 80 func copyExportedFields(expected interface{}) interface{} { 81 if isNil(expected) { 82 return expected 83 } 84 85 expectedType := reflect.TypeOf(expected) 86 expectedKind := expectedType.Kind() 87 expectedValue := reflect.ValueOf(expected) 88 89 switch expectedKind { 90 case reflect.Struct: 91 result := reflect.New(expectedType).Elem() 92 for i := 0; i < expectedType.NumField(); i++ { 93 field := expectedType.Field(i) 94 isExported := field.IsExported() 95 if isExported { 96 fieldValue := expectedValue.Field(i) 97 if isNil(fieldValue) || isNil(fieldValue.Interface()) { 98 continue 99 } 100 newValue := copyExportedFields(fieldValue.Interface()) 101 result.Field(i).Set(reflect.ValueOf(newValue)) 102 } 103 } 104 return result.Interface() 105 106 case reflect.Ptr: 107 result := reflect.New(expectedType.Elem()) 108 unexportedRemoved := copyExportedFields(expectedValue.Elem().Interface()) 109 result.Elem().Set(reflect.ValueOf(unexportedRemoved)) 110 return result.Interface() 111 112 case reflect.Array, reflect.Slice: 113 result := reflect.MakeSlice(expectedType, expectedValue.Len(), expectedValue.Len()) 114 for i := 0; i < expectedValue.Len(); i++ { 115 index := expectedValue.Index(i) 116 if isNil(index) { 117 continue 118 } 119 unexportedRemoved := copyExportedFields(index.Interface()) 120 result.Index(i).Set(reflect.ValueOf(unexportedRemoved)) 121 } 122 return result.Interface() 123 124 case reflect.Map: 125 result := reflect.MakeMap(expectedType) 126 for _, k := range expectedValue.MapKeys() { 127 index := expectedValue.MapIndex(k) 128 unexportedRemoved := copyExportedFields(index.Interface()) 129 result.SetMapIndex(k, reflect.ValueOf(unexportedRemoved)) 130 } 131 return result.Interface() 132 133 default: 134 return expected 135 } 136 } 137 138 // ObjectsExportedFieldsAreEqual determines if the exported (public) fields of two objects are 139 // considered equal. This comparison of only exported fields is applied recursively to nested data 140 // structures. 141 // 142 // This function does no assertion of any kind. 143 func ObjectsExportedFieldsAreEqual(expected, actual interface{}) bool { 144 expectedCleaned := copyExportedFields(expected) 145 actualCleaned := copyExportedFields(actual) 146 return ObjectsAreEqualValues(expectedCleaned, actualCleaned) 147 } 148 149 // ObjectsAreEqualValues gets whether two objects are equal, or if their 150 // values are equal. 151 func ObjectsAreEqualValues(expected, actual interface{}) bool { 152 if ObjectsAreEqual(expected, actual) { 153 return true 154 } 155 156 actualType := reflect.TypeOf(actual) 157 if actualType == nil { 158 return false 159 } 160 expectedValue := reflect.ValueOf(expected) 161 if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) { 162 // Attempt comparison after type conversion 163 return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual) 164 } 165 166 return false 167 } 168 169 /* CallerInfo is necessary because the assert functions use the testing object 170 internally, causing it to print the file:line of the assert method, rather than where 171 the problem actually occurred in calling code.*/ 172 173 // CallerInfo returns an array of strings containing the file and line number 174 // of each stack frame leading from the current test to the assert call that 175 // failed. 176 func CallerInfo() []string { 177 178 var pc uintptr 179 var ok bool 180 var file string 181 var line int 182 var name string 183 184 callers := []string{} 185 for i := 0; ; i++ { 186 pc, file, line, ok = runtime.Caller(i) 187 if !ok { 188 // The breaks below failed to terminate the loop, and we ran off the 189 // end of the call stack. 190 break 191 } 192 193 // This is a huge edge case, but it will panic if this is the case, see #180 194 if file == "<autogenerated>" { 195 break 196 } 197 198 f := runtime.FuncForPC(pc) 199 if f == nil { 200 break 201 } 202 name = f.Name() 203 204 // testing.tRunner is the standard library function that calls 205 // tests. Subtests are called directly by tRunner, without going through 206 // the Test/Benchmark/Example function that contains the t.Run calls, so 207 // with subtests we should break when we hit tRunner, without adding it 208 // to the list of callers. 209 if name == "testing.tRunner" { 210 break 211 } 212 213 parts := strings.Split(file, "/") 214 if len(parts) > 1 { 215 filename := parts[len(parts)-1] 216 dir := parts[len(parts)-2] 217 if (dir != "assert" && dir != "mock" && dir != "require") || filename == "mock_test.go" { 218 callers = append(callers, fmt.Sprintf("%s:%d", file, line)) 219 } 220 } 221 222 // Drop the package 223 segments := strings.Split(name, ".") 224 name = segments[len(segments)-1] 225 if isTest(name, "Test") || 226 isTest(name, "Benchmark") || 227 isTest(name, "Example") { 228 break 229 } 230 } 231 232 return callers 233 } 234 235 // Stolen from the `go test` tool. 236 // isTest tells whether name looks like a test (or benchmark, according to prefix). 237 // It is a Test (say) if there is a character after Test that is not a lower-case letter. 238 // We don't want TesticularCancer. 239 func isTest(name, prefix string) bool { 240 if !strings.HasPrefix(name, prefix) { 241 return false 242 } 243 if len(name) == len(prefix) { // "Test" is ok 244 return true 245 } 246 r, _ := utf8.DecodeRuneInString(name[len(prefix):]) 247 return !unicode.IsLower(r) 248 } 249 250 func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { 251 if len(msgAndArgs) == 0 || msgAndArgs == nil { 252 return "" 253 } 254 if len(msgAndArgs) == 1 { 255 msg := msgAndArgs[0] 256 if msgAsStr, ok := msg.(string); ok { 257 return msgAsStr 258 } 259 return fmt.Sprintf("%+v", msg) 260 } 261 if len(msgAndArgs) > 1 { 262 return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) 263 } 264 return "" 265 } 266 267 // Aligns the provided message so that all lines after the first line start at the same location as the first line. 268 // Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab). 269 // The longestLabelLen parameter specifies the length of the longest label in the output (required becaues this is the 270 // basis on which the alignment occurs). 271 func indentMessageLines(message string, longestLabelLen int) string { 272 outBuf := new(bytes.Buffer) 273 274 for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { 275 // no need to align first line because it starts at the correct location (after the label) 276 if i != 0 { 277 // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab 278 outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") 279 } 280 outBuf.WriteString(scanner.Text()) 281 } 282 283 return outBuf.String() 284 } 285 286 type failNower interface { 287 FailNow() 288 } 289 290 // FailNow fails test 291 func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { 292 if h, ok := t.(tHelper); ok { 293 h.Helper() 294 } 295 Fail(t, failureMessage, msgAndArgs...) 296 297 // We cannot extend TestingT with FailNow() and 298 // maintain backwards compatibility, so we fallback 299 // to panicking when FailNow is not available in 300 // TestingT. 301 // See issue #263 302 303 if t, ok := t.(failNower); ok { 304 t.FailNow() 305 } else { 306 panic("test failed and t is missing `FailNow()`") 307 } 308 return false 309 } 310 311 // Fail reports a failure through 312 func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { 313 if h, ok := t.(tHelper); ok { 314 h.Helper() 315 } 316 content := []labeledContent{ 317 {"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")}, 318 {"Error", failureMessage}, 319 } 320 321 // Add test name if the Go version supports it 322 if n, ok := t.(interface { 323 Name() string 324 }); ok { 325 content = append(content, labeledContent{"Test", n.Name()}) 326 } 327 328 message := messageFromMsgAndArgs(msgAndArgs...) 329 if len(message) > 0 { 330 content = append(content, labeledContent{"Messages", message}) 331 } 332 333 t.Errorf("\n%s", ""+labeledOutput(content...)) 334 335 return false 336 } 337 338 type labeledContent struct { 339 label string 340 content string 341 } 342 343 // labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: 344 // 345 // \t{{label}}:{{align_spaces}}\t{{content}}\n 346 // 347 // The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. 348 // If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this 349 // alignment is achieved, "\t{{content}}\n" is added for the output. 350 // 351 // 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. 352 func labeledOutput(content ...labeledContent) string { 353 longestLabel := 0 354 for _, v := range content { 355 if len(v.label) > longestLabel { 356 longestLabel = len(v.label) 357 } 358 } 359 var output string 360 for _, v := range content { 361 output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n" 362 } 363 return output 364 } 365 366 // Implements asserts that an object is implemented by the specified interface. 367 // 368 // assert.Implements(t, (*MyInterface)(nil), new(MyObject)) 369 func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { 370 if h, ok := t.(tHelper); ok { 371 h.Helper() 372 } 373 interfaceType := reflect.TypeOf(interfaceObject).Elem() 374 375 if object == nil { 376 return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...) 377 } 378 if !reflect.TypeOf(object).Implements(interfaceType) { 379 return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...) 380 } 381 382 return true 383 } 384 385 // IsType asserts that the specified objects are of the same type. 386 func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { 387 if h, ok := t.(tHelper); ok { 388 h.Helper() 389 } 390 391 if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { 392 return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) 393 } 394 395 return true 396 } 397 398 // Equal asserts that two objects are equal. 399 // 400 // assert.Equal(t, 123, 123) 401 // 402 // Pointer variable equality is determined based on the equality of the 403 // referenced values (as opposed to the memory addresses). Function equality 404 // cannot be determined and will always fail. 405 func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 406 if h, ok := t.(tHelper); ok { 407 h.Helper() 408 } 409 if err := validateEqualArgs(expected, actual); err != nil { 410 return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)", 411 expected, actual, err), msgAndArgs...) 412 } 413 414 if !ObjectsAreEqual(expected, actual) { 415 diff := diff(expected, actual) 416 expected, actual = formatUnequalValues(expected, actual) 417 return Fail(t, fmt.Sprintf("Not equal: \n"+ 418 "expected: %s\n"+ 419 "actual : %s%s", expected, actual, diff), msgAndArgs...) 420 } 421 422 return true 423 424 } 425 426 // validateEqualArgs checks whether provided arguments can be safely used in the 427 // Equal/NotEqual functions. 428 func validateEqualArgs(expected, actual interface{}) error { 429 if expected == nil && actual == nil { 430 return nil 431 } 432 433 if isFunction(expected) || isFunction(actual) { 434 return errors.New("cannot take func type as argument") 435 } 436 return nil 437 } 438 439 // Same asserts that two pointers reference the same object. 440 // 441 // assert.Same(t, ptr1, ptr2) 442 // 443 // Both arguments must be pointer variables. Pointer variable sameness is 444 // determined based on the equality of both type and value. 445 func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 446 if h, ok := t.(tHelper); ok { 447 h.Helper() 448 } 449 450 if !samePointers(expected, actual) { 451 return Fail(t, fmt.Sprintf("Not same: \n"+ 452 "expected: %p %#v\n"+ 453 "actual : %p %#v", expected, expected, actual, actual), msgAndArgs...) 454 } 455 456 return true 457 } 458 459 // NotSame asserts that two pointers do not reference the same object. 460 // 461 // assert.NotSame(t, ptr1, ptr2) 462 // 463 // Both arguments must be pointer variables. Pointer variable sameness is 464 // determined based on the equality of both type and value. 465 func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 466 if h, ok := t.(tHelper); ok { 467 h.Helper() 468 } 469 470 if samePointers(expected, actual) { 471 return Fail(t, fmt.Sprintf( 472 "Expected and actual point to the same object: %p %#v", 473 expected, expected), msgAndArgs...) 474 } 475 return true 476 } 477 478 // samePointers compares two generic interface objects and returns whether 479 // they point to the same object 480 func samePointers(first, second interface{}) bool { 481 firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second) 482 if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr { 483 return false 484 } 485 486 firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second) 487 if firstType != secondType { 488 return false 489 } 490 491 // compare pointer addresses 492 return first == second 493 } 494 495 // formatUnequalValues takes two values of arbitrary types and returns string 496 // representations appropriate to be presented to the user. 497 // 498 // If the values are not of like type, the returned strings will be prefixed 499 // with the type name, and the value will be enclosed in parenthesis similar 500 // to a type conversion in the Go grammar. 501 func formatUnequalValues(expected, actual interface{}) (e string, a string) { 502 if reflect.TypeOf(expected) != reflect.TypeOf(actual) { 503 return fmt.Sprintf("%T(%s)", expected, truncatingFormat(expected)), 504 fmt.Sprintf("%T(%s)", actual, truncatingFormat(actual)) 505 } 506 switch expected.(type) { 507 case time.Duration: 508 return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual) 509 } 510 return truncatingFormat(expected), truncatingFormat(actual) 511 } 512 513 // truncatingFormat formats the data and truncates it if it's too long. 514 // 515 // This helps keep formatted error messages lines from exceeding the 516 // bufio.MaxScanTokenSize max line length that the go testing framework imposes. 517 func truncatingFormat(data interface{}) string { 518 value := fmt.Sprintf("%#v", data) 519 max := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed. 520 if len(value) > max { 521 value = value[0:max] + "<... truncated>" 522 } 523 return value 524 } 525 526 // EqualValues asserts that two objects are equal or convertable to the same types 527 // and equal. 528 // 529 // assert.EqualValues(t, uint32(123), int32(123)) 530 func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 531 if h, ok := t.(tHelper); ok { 532 h.Helper() 533 } 534 535 if !ObjectsAreEqualValues(expected, actual) { 536 diff := diff(expected, actual) 537 expected, actual = formatUnequalValues(expected, actual) 538 return Fail(t, fmt.Sprintf("Not equal: \n"+ 539 "expected: %s\n"+ 540 "actual : %s%s", expected, actual, diff), msgAndArgs...) 541 } 542 543 return true 544 545 } 546 547 // EqualExportedValues asserts that the types of two objects are equal and their public 548 // fields are also equal. This is useful for comparing structs that have private fields 549 // that could potentially differ. 550 // 551 // type S struct { 552 // Exported int 553 // notExported int 554 // } 555 // assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true 556 // assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false 557 func EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 558 if h, ok := t.(tHelper); ok { 559 h.Helper() 560 } 561 562 aType := reflect.TypeOf(expected) 563 bType := reflect.TypeOf(actual) 564 565 if aType != bType { 566 return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) 567 } 568 569 if aType.Kind() != reflect.Struct { 570 return Fail(t, fmt.Sprintf("Types expected to both be struct \n\t%v != %v", aType.Kind(), reflect.Struct), msgAndArgs...) 571 } 572 573 if bType.Kind() != reflect.Struct { 574 return Fail(t, fmt.Sprintf("Types expected to both be struct \n\t%v != %v", bType.Kind(), reflect.Struct), msgAndArgs...) 575 } 576 577 expected = copyExportedFields(expected) 578 actual = copyExportedFields(actual) 579 580 if !ObjectsAreEqualValues(expected, actual) { 581 diff := diff(expected, actual) 582 expected, actual = formatUnequalValues(expected, actual) 583 return Fail(t, fmt.Sprintf("Not equal (comparing only exported fields): \n"+ 584 "expected: %s\n"+ 585 "actual : %s%s", expected, actual, diff), msgAndArgs...) 586 } 587 588 return true 589 } 590 591 // Exactly asserts that two objects are equal in value and type. 592 // 593 // assert.Exactly(t, int32(123), int64(123)) 594 func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 595 if h, ok := t.(tHelper); ok { 596 h.Helper() 597 } 598 599 aType := reflect.TypeOf(expected) 600 bType := reflect.TypeOf(actual) 601 602 if aType != bType { 603 return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) 604 } 605 606 return Equal(t, expected, actual, msgAndArgs...) 607 608 } 609 610 // NotNil asserts that the specified object is not nil. 611 // 612 // assert.NotNil(t, err) 613 func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 614 if !isNil(object) { 615 return true 616 } 617 if h, ok := t.(tHelper); ok { 618 h.Helper() 619 } 620 return Fail(t, "Expected value not to be nil.", msgAndArgs...) 621 } 622 623 // containsKind checks if a specified kind in the slice of kinds. 624 func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool { 625 for i := 0; i < len(kinds); i++ { 626 if kind == kinds[i] { 627 return true 628 } 629 } 630 631 return false 632 } 633 634 // isNil checks if a specified object is nil or not, without Failing. 635 func isNil(object interface{}) bool { 636 if object == nil { 637 return true 638 } 639 640 value := reflect.ValueOf(object) 641 kind := value.Kind() 642 isNilableKind := containsKind( 643 []reflect.Kind{ 644 reflect.Chan, reflect.Func, 645 reflect.Interface, reflect.Map, 646 reflect.Ptr, reflect.Slice, reflect.UnsafePointer}, 647 kind) 648 649 if isNilableKind && value.IsNil() { 650 return true 651 } 652 653 return false 654 } 655 656 // Nil asserts that the specified object is nil. 657 // 658 // assert.Nil(t, err) 659 func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 660 if isNil(object) { 661 return true 662 } 663 if h, ok := t.(tHelper); ok { 664 h.Helper() 665 } 666 return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) 667 } 668 669 // isEmpty gets whether the specified object is considered empty or not. 670 func isEmpty(object interface{}) bool { 671 672 // get nil case out of the way 673 if object == nil { 674 return true 675 } 676 677 objValue := reflect.ValueOf(object) 678 679 switch objValue.Kind() { 680 // collection types are empty when they have no element 681 case reflect.Chan, reflect.Map, reflect.Slice: 682 return objValue.Len() == 0 683 // pointers are empty if nil or if the value they point to is empty 684 case reflect.Ptr: 685 if objValue.IsNil() { 686 return true 687 } 688 deref := objValue.Elem().Interface() 689 return isEmpty(deref) 690 // for all other types, compare against the zero value 691 // array types are empty when they match their zero-initialized state 692 default: 693 zero := reflect.Zero(objValue.Type()) 694 return reflect.DeepEqual(object, zero.Interface()) 695 } 696 } 697 698 // Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either 699 // a slice or a channel with len == 0. 700 // 701 // assert.Empty(t, obj) 702 func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 703 pass := isEmpty(object) 704 if !pass { 705 if h, ok := t.(tHelper); ok { 706 h.Helper() 707 } 708 Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) 709 } 710 711 return pass 712 713 } 714 715 // NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either 716 // a slice or a channel with len == 0. 717 // 718 // if assert.NotEmpty(t, obj) { 719 // assert.Equal(t, "two", obj[1]) 720 // } 721 func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 722 pass := !isEmpty(object) 723 if !pass { 724 if h, ok := t.(tHelper); ok { 725 h.Helper() 726 } 727 Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...) 728 } 729 730 return pass 731 732 } 733 734 // getLen try to get length of object. 735 // return (false, 0) if impossible. 736 func getLen(x interface{}) (ok bool, length int) { 737 v := reflect.ValueOf(x) 738 defer func() { 739 if e := recover(); e != nil { 740 ok = false 741 } 742 }() 743 return true, v.Len() 744 } 745 746 // Len asserts that the specified object has specific length. 747 // Len also fails if the object has a type that len() not accept. 748 // 749 // assert.Len(t, mySlice, 3) 750 func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { 751 if h, ok := t.(tHelper); ok { 752 h.Helper() 753 } 754 ok, l := getLen(object) 755 if !ok { 756 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) 757 } 758 759 if l != length { 760 return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) 761 } 762 return true 763 } 764 765 // True asserts that the specified value is true. 766 // 767 // assert.True(t, myBool) 768 func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { 769 if !value { 770 if h, ok := t.(tHelper); ok { 771 h.Helper() 772 } 773 return Fail(t, "Should be true", msgAndArgs...) 774 } 775 776 return true 777 778 } 779 780 // False asserts that the specified value is false. 781 // 782 // assert.False(t, myBool) 783 func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { 784 if value { 785 if h, ok := t.(tHelper); ok { 786 h.Helper() 787 } 788 return Fail(t, "Should be false", msgAndArgs...) 789 } 790 791 return true 792 793 } 794 795 // NotEqual asserts that the specified values are NOT equal. 796 // 797 // assert.NotEqual(t, obj1, obj2) 798 // 799 // Pointer variable equality is determined based on the equality of the 800 // referenced values (as opposed to the memory addresses). 801 func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 802 if h, ok := t.(tHelper); ok { 803 h.Helper() 804 } 805 if err := validateEqualArgs(expected, actual); err != nil { 806 return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)", 807 expected, actual, err), msgAndArgs...) 808 } 809 810 if ObjectsAreEqual(expected, actual) { 811 return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) 812 } 813 814 return true 815 816 } 817 818 // NotEqualValues asserts that two objects are not equal even when converted to the same type 819 // 820 // assert.NotEqualValues(t, obj1, obj2) 821 func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 822 if h, ok := t.(tHelper); ok { 823 h.Helper() 824 } 825 826 if ObjectsAreEqualValues(expected, actual) { 827 return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) 828 } 829 830 return true 831 } 832 833 // containsElement try loop over the list check if the list includes the element. 834 // return (false, false) if impossible. 835 // return (true, false) if element was not found. 836 // return (true, true) if element was found. 837 func containsElement(list interface{}, element interface{}) (ok, found bool) { 838 839 listValue := reflect.ValueOf(list) 840 listType := reflect.TypeOf(list) 841 if listType == nil { 842 return false, false 843 } 844 listKind := listType.Kind() 845 defer func() { 846 if e := recover(); e != nil { 847 ok = false 848 found = false 849 } 850 }() 851 852 if listKind == reflect.String { 853 elementValue := reflect.ValueOf(element) 854 return true, strings.Contains(listValue.String(), elementValue.String()) 855 } 856 857 if listKind == reflect.Map { 858 mapKeys := listValue.MapKeys() 859 for i := 0; i < len(mapKeys); i++ { 860 if ObjectsAreEqual(mapKeys[i].Interface(), element) { 861 return true, true 862 } 863 } 864 return true, false 865 } 866 867 for i := 0; i < listValue.Len(); i++ { 868 if ObjectsAreEqual(listValue.Index(i).Interface(), element) { 869 return true, true 870 } 871 } 872 return true, false 873 874 } 875 876 // Contains asserts that the specified string, list(array, slice...) or map contains the 877 // specified substring or element. 878 // 879 // assert.Contains(t, "Hello World", "World") 880 // assert.Contains(t, ["Hello", "World"], "World") 881 // assert.Contains(t, {"Hello": "World"}, "Hello") 882 func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { 883 if h, ok := t.(tHelper); ok { 884 h.Helper() 885 } 886 887 ok, found := containsElement(s, contains) 888 if !ok { 889 return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) 890 } 891 if !found { 892 return Fail(t, fmt.Sprintf("%#v does not contain %#v", s, contains), msgAndArgs...) 893 } 894 895 return true 896 897 } 898 899 // NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the 900 // specified substring or element. 901 // 902 // assert.NotContains(t, "Hello World", "Earth") 903 // assert.NotContains(t, ["Hello", "World"], "Earth") 904 // assert.NotContains(t, {"Hello": "World"}, "Earth") 905 func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { 906 if h, ok := t.(tHelper); ok { 907 h.Helper() 908 } 909 910 ok, found := containsElement(s, contains) 911 if !ok { 912 return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) 913 } 914 if found { 915 return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...) 916 } 917 918 return true 919 920 } 921 922 // Subset asserts that the specified list(array, slice...) contains all 923 // elements given in the specified subset(array, slice...). 924 // 925 // assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") 926 func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { 927 if h, ok := t.(tHelper); ok { 928 h.Helper() 929 } 930 if subset == nil { 931 return true // we consider nil to be equal to the nil set 932 } 933 934 listKind := reflect.TypeOf(list).Kind() 935 if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { 936 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) 937 } 938 939 subsetKind := reflect.TypeOf(subset).Kind() 940 if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map { 941 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) 942 } 943 944 if subsetKind == reflect.Map && listKind == reflect.Map { 945 subsetMap := reflect.ValueOf(subset) 946 actualMap := reflect.ValueOf(list) 947 948 for _, k := range subsetMap.MapKeys() { 949 ev := subsetMap.MapIndex(k) 950 av := actualMap.MapIndex(k) 951 952 if !av.IsValid() { 953 return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) 954 } 955 if !ObjectsAreEqual(ev.Interface(), av.Interface()) { 956 return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) 957 } 958 } 959 960 return true 961 } 962 963 subsetList := reflect.ValueOf(subset) 964 for i := 0; i < subsetList.Len(); i++ { 965 element := subsetList.Index(i).Interface() 966 ok, found := containsElement(list, element) 967 if !ok { 968 return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) 969 } 970 if !found { 971 return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, element), msgAndArgs...) 972 } 973 } 974 975 return true 976 } 977 978 // NotSubset asserts that the specified list(array, slice...) contains not all 979 // elements given in the specified subset(array, slice...). 980 // 981 // assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") 982 func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { 983 if h, ok := t.(tHelper); ok { 984 h.Helper() 985 } 986 if subset == nil { 987 return Fail(t, "nil is the empty set which is a subset of every set", msgAndArgs...) 988 } 989 990 listKind := reflect.TypeOf(list).Kind() 991 if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { 992 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) 993 } 994 995 subsetKind := reflect.TypeOf(subset).Kind() 996 if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map { 997 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) 998 } 999 1000 if subsetKind == reflect.Map && listKind == reflect.Map { 1001 subsetMap := reflect.ValueOf(subset) 1002 actualMap := reflect.ValueOf(list) 1003 1004 for _, k := range subsetMap.MapKeys() { 1005 ev := subsetMap.MapIndex(k) 1006 av := actualMap.MapIndex(k) 1007 1008 if !av.IsValid() { 1009 return true 1010 } 1011 if !ObjectsAreEqual(ev.Interface(), av.Interface()) { 1012 return true 1013 } 1014 } 1015 1016 return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) 1017 } 1018 1019 subsetList := reflect.ValueOf(subset) 1020 for i := 0; i < subsetList.Len(); i++ { 1021 element := subsetList.Index(i).Interface() 1022 ok, found := containsElement(list, element) 1023 if !ok { 1024 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) 1025 } 1026 if !found { 1027 return true 1028 } 1029 } 1030 1031 return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) 1032 } 1033 1034 // ElementsMatch asserts that the specified listA(array, slice...) is equal to specified 1035 // listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, 1036 // the number of appearances of each of them in both lists should match. 1037 // 1038 // assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) 1039 func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { 1040 if h, ok := t.(tHelper); ok { 1041 h.Helper() 1042 } 1043 if isEmpty(listA) && isEmpty(listB) { 1044 return true 1045 } 1046 1047 if !isList(t, listA, msgAndArgs...) || !isList(t, listB, msgAndArgs...) { 1048 return false 1049 } 1050 1051 extraA, extraB := diffLists(listA, listB) 1052 1053 if len(extraA) == 0 && len(extraB) == 0 { 1054 return true 1055 } 1056 1057 return Fail(t, formatListDiff(listA, listB, extraA, extraB), msgAndArgs...) 1058 } 1059 1060 // isList checks that the provided value is array or slice. 1061 func isList(t TestingT, list interface{}, msgAndArgs ...interface{}) (ok bool) { 1062 kind := reflect.TypeOf(list).Kind() 1063 if kind != reflect.Array && kind != reflect.Slice { 1064 return Fail(t, fmt.Sprintf("%q has an unsupported type %s, expecting array or slice", list, kind), 1065 msgAndArgs...) 1066 } 1067 return true 1068 } 1069 1070 // diffLists diffs two arrays/slices and returns slices of elements that are only in A and only in B. 1071 // If some element is present multiple times, each instance is counted separately (e.g. if something is 2x in A and 1072 // 5x in B, it will be 0x in extraA and 3x in extraB). The order of items in both lists is ignored. 1073 func diffLists(listA, listB interface{}) (extraA, extraB []interface{}) { 1074 aValue := reflect.ValueOf(listA) 1075 bValue := reflect.ValueOf(listB) 1076 1077 aLen := aValue.Len() 1078 bLen := bValue.Len() 1079 1080 // Mark indexes in bValue that we already used 1081 visited := make([]bool, bLen) 1082 for i := 0; i < aLen; i++ { 1083 element := aValue.Index(i).Interface() 1084 found := false 1085 for j := 0; j < bLen; j++ { 1086 if visited[j] { 1087 continue 1088 } 1089 if ObjectsAreEqual(bValue.Index(j).Interface(), element) { 1090 visited[j] = true 1091 found = true 1092 break 1093 } 1094 } 1095 if !found { 1096 extraA = append(extraA, element) 1097 } 1098 } 1099 1100 for j := 0; j < bLen; j++ { 1101 if visited[j] { 1102 continue 1103 } 1104 extraB = append(extraB, bValue.Index(j).Interface()) 1105 } 1106 1107 return 1108 } 1109 1110 func formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) string { 1111 var msg bytes.Buffer 1112 1113 msg.WriteString("elements differ") 1114 if len(extraA) > 0 { 1115 msg.WriteString("\n\nextra elements in list A:\n") 1116 msg.WriteString(spewConfig.Sdump(extraA)) 1117 } 1118 if len(extraB) > 0 { 1119 msg.WriteString("\n\nextra elements in list B:\n") 1120 msg.WriteString(spewConfig.Sdump(extraB)) 1121 } 1122 msg.WriteString("\n\nlistA:\n") 1123 msg.WriteString(spewConfig.Sdump(listA)) 1124 msg.WriteString("\n\nlistB:\n") 1125 msg.WriteString(spewConfig.Sdump(listB)) 1126 1127 return msg.String() 1128 } 1129 1130 // Condition uses a Comparison to assert a complex condition. 1131 func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { 1132 if h, ok := t.(tHelper); ok { 1133 h.Helper() 1134 } 1135 result := comp() 1136 if !result { 1137 Fail(t, "Condition failed!", msgAndArgs...) 1138 } 1139 return result 1140 } 1141 1142 // PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics 1143 // methods, and represents a simple func that takes no arguments, and returns nothing. 1144 type PanicTestFunc func() 1145 1146 // didPanic returns true if the function passed to it panics. Otherwise, it returns false. 1147 func didPanic(f PanicTestFunc) (didPanic bool, message interface{}, stack string) { 1148 didPanic = true 1149 1150 defer func() { 1151 message = recover() 1152 if didPanic { 1153 stack = string(debug.Stack()) 1154 } 1155 }() 1156 1157 // call the target function 1158 f() 1159 didPanic = false 1160 1161 return 1162 } 1163 1164 // Panics asserts that the code inside the specified PanicTestFunc panics. 1165 // 1166 // assert.Panics(t, func(){ GoCrazy() }) 1167 func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { 1168 if h, ok := t.(tHelper); ok { 1169 h.Helper() 1170 } 1171 1172 if funcDidPanic, panicValue, _ := didPanic(f); !funcDidPanic { 1173 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) 1174 } 1175 1176 return true 1177 } 1178 1179 // PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that 1180 // the recovered panic value equals the expected panic value. 1181 // 1182 // assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) 1183 func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { 1184 if h, ok := t.(tHelper); ok { 1185 h.Helper() 1186 } 1187 1188 funcDidPanic, panicValue, panickedStack := didPanic(f) 1189 if !funcDidPanic { 1190 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) 1191 } 1192 if panicValue != expected { 1193 return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, expected, panicValue, panickedStack), msgAndArgs...) 1194 } 1195 1196 return true 1197 } 1198 1199 // PanicsWithError asserts that the code inside the specified PanicTestFunc 1200 // panics, and that the recovered panic value is an error that satisfies the 1201 // EqualError comparison. 1202 // 1203 // assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) 1204 func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool { 1205 if h, ok := t.(tHelper); ok { 1206 h.Helper() 1207 } 1208 1209 funcDidPanic, panicValue, panickedStack := didPanic(f) 1210 if !funcDidPanic { 1211 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) 1212 } 1213 panicErr, ok := panicValue.(error) 1214 if !ok || panicErr.Error() != errString { 1215 return Fail(t, fmt.Sprintf("func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, errString, panicValue, panickedStack), msgAndArgs...) 1216 } 1217 1218 return true 1219 } 1220 1221 // NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. 1222 // 1223 // assert.NotPanics(t, func(){ RemainCalm() }) 1224 func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { 1225 if h, ok := t.(tHelper); ok { 1226 h.Helper() 1227 } 1228 1229 if funcDidPanic, panicValue, panickedStack := didPanic(f); funcDidPanic { 1230 return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v\n\tPanic stack:\t%s", f, panicValue, panickedStack), msgAndArgs...) 1231 } 1232 1233 return true 1234 } 1235 1236 // WithinDuration asserts that the two times are within duration delta of each other. 1237 // 1238 // assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) 1239 func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { 1240 if h, ok := t.(tHelper); ok { 1241 h.Helper() 1242 } 1243 1244 dt := expected.Sub(actual) 1245 if dt < -delta || dt > delta { 1246 return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) 1247 } 1248 1249 return true 1250 } 1251 1252 // WithinRange asserts that a time is within a time range (inclusive). 1253 // 1254 // assert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second)) 1255 func WithinRange(t TestingT, actual, start, end time.Time, msgAndArgs ...interface{}) bool { 1256 if h, ok := t.(tHelper); ok { 1257 h.Helper() 1258 } 1259 1260 if end.Before(start) { 1261 return Fail(t, "Start should be before end", msgAndArgs...) 1262 } 1263 1264 if actual.Before(start) { 1265 return Fail(t, fmt.Sprintf("Time %v expected to be in time range %v to %v, but is before the range", actual, start, end), msgAndArgs...) 1266 } else if actual.After(end) { 1267 return Fail(t, fmt.Sprintf("Time %v expected to be in time range %v to %v, but is after the range", actual, start, end), msgAndArgs...) 1268 } 1269 1270 return true 1271 } 1272 1273 func toFloat(x interface{}) (float64, bool) { 1274 var xf float64 1275 xok := true 1276 1277 switch xn := x.(type) { 1278 case uint: 1279 xf = float64(xn) 1280 case uint8: 1281 xf = float64(xn) 1282 case uint16: 1283 xf = float64(xn) 1284 case uint32: 1285 xf = float64(xn) 1286 case uint64: 1287 xf = float64(xn) 1288 case int: 1289 xf = float64(xn) 1290 case int8: 1291 xf = float64(xn) 1292 case int16: 1293 xf = float64(xn) 1294 case int32: 1295 xf = float64(xn) 1296 case int64: 1297 xf = float64(xn) 1298 case float32: 1299 xf = float64(xn) 1300 case float64: 1301 xf = xn 1302 case time.Duration: 1303 xf = float64(xn) 1304 default: 1305 xok = false 1306 } 1307 1308 return xf, xok 1309 } 1310 1311 // InDelta asserts that the two numerals are within delta of each other. 1312 // 1313 // assert.InDelta(t, math.Pi, 22/7.0, 0.01) 1314 func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { 1315 if h, ok := t.(tHelper); ok { 1316 h.Helper() 1317 } 1318 1319 af, aok := toFloat(expected) 1320 bf, bok := toFloat(actual) 1321 1322 if !aok || !bok { 1323 return Fail(t, "Parameters must be numerical", msgAndArgs...) 1324 } 1325 1326 if math.IsNaN(af) && math.IsNaN(bf) { 1327 return true 1328 } 1329 1330 if math.IsNaN(af) { 1331 return Fail(t, "Expected must not be NaN", msgAndArgs...) 1332 } 1333 1334 if math.IsNaN(bf) { 1335 return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...) 1336 } 1337 1338 dt := af - bf 1339 if dt < -delta || dt > delta { 1340 return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) 1341 } 1342 1343 return true 1344 } 1345 1346 // InDeltaSlice is the same as InDelta, except it compares two slices. 1347 func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { 1348 if h, ok := t.(tHelper); ok { 1349 h.Helper() 1350 } 1351 if expected == nil || actual == nil || 1352 reflect.TypeOf(actual).Kind() != reflect.Slice || 1353 reflect.TypeOf(expected).Kind() != reflect.Slice { 1354 return Fail(t, "Parameters must be slice", msgAndArgs...) 1355 } 1356 1357 actualSlice := reflect.ValueOf(actual) 1358 expectedSlice := reflect.ValueOf(expected) 1359 1360 for i := 0; i < actualSlice.Len(); i++ { 1361 result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...) 1362 if !result { 1363 return result 1364 } 1365 } 1366 1367 return true 1368 } 1369 1370 // InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. 1371 func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { 1372 if h, ok := t.(tHelper); ok { 1373 h.Helper() 1374 } 1375 if expected == nil || actual == nil || 1376 reflect.TypeOf(actual).Kind() != reflect.Map || 1377 reflect.TypeOf(expected).Kind() != reflect.Map { 1378 return Fail(t, "Arguments must be maps", msgAndArgs...) 1379 } 1380 1381 expectedMap := reflect.ValueOf(expected) 1382 actualMap := reflect.ValueOf(actual) 1383 1384 if expectedMap.Len() != actualMap.Len() { 1385 return Fail(t, "Arguments must have the same number of keys", msgAndArgs...) 1386 } 1387 1388 for _, k := range expectedMap.MapKeys() { 1389 ev := expectedMap.MapIndex(k) 1390 av := actualMap.MapIndex(k) 1391 1392 if !ev.IsValid() { 1393 return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...) 1394 } 1395 1396 if !av.IsValid() { 1397 return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...) 1398 } 1399 1400 if !InDelta( 1401 t, 1402 ev.Interface(), 1403 av.Interface(), 1404 delta, 1405 msgAndArgs..., 1406 ) { 1407 return false 1408 } 1409 } 1410 1411 return true 1412 } 1413 1414 func calcRelativeError(expected, actual interface{}) (float64, error) { 1415 af, aok := toFloat(expected) 1416 bf, bok := toFloat(actual) 1417 if !aok || !bok { 1418 return 0, fmt.Errorf("Parameters must be numerical") 1419 } 1420 if math.IsNaN(af) && math.IsNaN(bf) { 1421 return 0, nil 1422 } 1423 if math.IsNaN(af) { 1424 return 0, errors.New("expected value must not be NaN") 1425 } 1426 if af == 0 { 1427 return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error") 1428 } 1429 if math.IsNaN(bf) { 1430 return 0, errors.New("actual value must not be NaN") 1431 } 1432 1433 return math.Abs(af-bf) / math.Abs(af), nil 1434 } 1435 1436 // InEpsilon asserts that expected and actual have a relative error less than epsilon 1437 func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { 1438 if h, ok := t.(tHelper); ok { 1439 h.Helper() 1440 } 1441 if math.IsNaN(epsilon) { 1442 return Fail(t, "epsilon must not be NaN") 1443 } 1444 actualEpsilon, err := calcRelativeError(expected, actual) 1445 if err != nil { 1446 return Fail(t, err.Error(), msgAndArgs...) 1447 } 1448 if actualEpsilon > epsilon { 1449 return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ 1450 " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) 1451 } 1452 1453 return true 1454 } 1455 1456 // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. 1457 func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { 1458 if h, ok := t.(tHelper); ok { 1459 h.Helper() 1460 } 1461 if expected == nil || actual == nil || 1462 reflect.TypeOf(actual).Kind() != reflect.Slice || 1463 reflect.TypeOf(expected).Kind() != reflect.Slice { 1464 return Fail(t, "Parameters must be slice", msgAndArgs...) 1465 } 1466 1467 actualSlice := reflect.ValueOf(actual) 1468 expectedSlice := reflect.ValueOf(expected) 1469 1470 for i := 0; i < actualSlice.Len(); i++ { 1471 result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon) 1472 if !result { 1473 return result 1474 } 1475 } 1476 1477 return true 1478 } 1479 1480 /* 1481 Errors 1482 */ 1483 1484 // NoError asserts that a function returned no error (i.e. `nil`). 1485 // 1486 // actualObj, err := SomeFunction() 1487 // if assert.NoError(t, err) { 1488 // assert.Equal(t, expectedObj, actualObj) 1489 // } 1490 func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { 1491 if err != nil { 1492 if h, ok := t.(tHelper); ok { 1493 h.Helper() 1494 } 1495 return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) 1496 } 1497 1498 return true 1499 } 1500 1501 // Error asserts that a function returned an error (i.e. not `nil`). 1502 // 1503 // actualObj, err := SomeFunction() 1504 // if assert.Error(t, err) { 1505 // assert.Equal(t, expectedError, err) 1506 // } 1507 func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { 1508 if err == nil { 1509 if h, ok := t.(tHelper); ok { 1510 h.Helper() 1511 } 1512 return Fail(t, "An error is expected but got nil.", msgAndArgs...) 1513 } 1514 1515 return true 1516 } 1517 1518 // EqualError asserts that a function returned an error (i.e. not `nil`) 1519 // and that it is equal to the provided error. 1520 // 1521 // actualObj, err := SomeFunction() 1522 // assert.EqualError(t, err, expectedErrorString) 1523 func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { 1524 if h, ok := t.(tHelper); ok { 1525 h.Helper() 1526 } 1527 if !Error(t, theError, msgAndArgs...) { 1528 return false 1529 } 1530 expected := errString 1531 actual := theError.Error() 1532 // don't need to use deep equals here, we know they are both strings 1533 if expected != actual { 1534 return Fail(t, fmt.Sprintf("Error message not equal:\n"+ 1535 "expected: %q\n"+ 1536 "actual : %q", expected, actual), msgAndArgs...) 1537 } 1538 return true 1539 } 1540 1541 // ErrorContains asserts that a function returned an error (i.e. not `nil`) 1542 // and that the error contains the specified substring. 1543 // 1544 // actualObj, err := SomeFunction() 1545 // assert.ErrorContains(t, err, expectedErrorSubString) 1546 func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) bool { 1547 if h, ok := t.(tHelper); ok { 1548 h.Helper() 1549 } 1550 if !Error(t, theError, msgAndArgs...) { 1551 return false 1552 } 1553 1554 actual := theError.Error() 1555 if !strings.Contains(actual, contains) { 1556 return Fail(t, fmt.Sprintf("Error %#v does not contain %#v", actual, contains), msgAndArgs...) 1557 } 1558 1559 return true 1560 } 1561 1562 // matchRegexp return true if a specified regexp matches a string. 1563 func matchRegexp(rx interface{}, str interface{}) bool { 1564 1565 var r *regexp.Regexp 1566 if rr, ok := rx.(*regexp.Regexp); ok { 1567 r = rr 1568 } else { 1569 r = regexp.MustCompile(fmt.Sprint(rx)) 1570 } 1571 1572 return (r.FindStringIndex(fmt.Sprint(str)) != nil) 1573 1574 } 1575 1576 // Regexp asserts that a specified regexp matches a string. 1577 // 1578 // assert.Regexp(t, regexp.MustCompile("start"), "it's starting") 1579 // assert.Regexp(t, "start...$", "it's not starting") 1580 func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { 1581 if h, ok := t.(tHelper); ok { 1582 h.Helper() 1583 } 1584 1585 match := matchRegexp(rx, str) 1586 1587 if !match { 1588 Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) 1589 } 1590 1591 return match 1592 } 1593 1594 // NotRegexp asserts that a specified regexp does not match a string. 1595 // 1596 // assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") 1597 // assert.NotRegexp(t, "^start", "it's not starting") 1598 func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { 1599 if h, ok := t.(tHelper); ok { 1600 h.Helper() 1601 } 1602 match := matchRegexp(rx, str) 1603 1604 if match { 1605 Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) 1606 } 1607 1608 return !match 1609 1610 } 1611 1612 // Zero asserts that i is the zero value for its type. 1613 func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { 1614 if h, ok := t.(tHelper); ok { 1615 h.Helper() 1616 } 1617 if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { 1618 return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) 1619 } 1620 return true 1621 } 1622 1623 // NotZero asserts that i is not the zero value for its type. 1624 func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { 1625 if h, ok := t.(tHelper); ok { 1626 h.Helper() 1627 } 1628 if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { 1629 return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) 1630 } 1631 return true 1632 } 1633 1634 // FileExists checks whether a file exists in the given path. It also fails if 1635 // the path points to a directory or there is an error when trying to check the file. 1636 func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { 1637 if h, ok := t.(tHelper); ok { 1638 h.Helper() 1639 } 1640 info, err := os.Lstat(path) 1641 if err != nil { 1642 if os.IsNotExist(err) { 1643 return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) 1644 } 1645 return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) 1646 } 1647 if info.IsDir() { 1648 return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...) 1649 } 1650 return true 1651 } 1652 1653 // NoFileExists checks whether a file does not exist in a given path. It fails 1654 // if the path points to an existing _file_ only. 1655 func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { 1656 if h, ok := t.(tHelper); ok { 1657 h.Helper() 1658 } 1659 info, err := os.Lstat(path) 1660 if err != nil { 1661 return true 1662 } 1663 if info.IsDir() { 1664 return true 1665 } 1666 return Fail(t, fmt.Sprintf("file %q exists", path), msgAndArgs...) 1667 } 1668 1669 // DirExists checks whether a directory exists in the given path. It also fails 1670 // if the path is a file rather a directory or there is an error checking whether it exists. 1671 func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { 1672 if h, ok := t.(tHelper); ok { 1673 h.Helper() 1674 } 1675 info, err := os.Lstat(path) 1676 if err != nil { 1677 if os.IsNotExist(err) { 1678 return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) 1679 } 1680 return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) 1681 } 1682 if !info.IsDir() { 1683 return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...) 1684 } 1685 return true 1686 } 1687 1688 // NoDirExists checks whether a directory does not exist in the given path. 1689 // It fails if the path points to an existing _directory_ only. 1690 func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { 1691 if h, ok := t.(tHelper); ok { 1692 h.Helper() 1693 } 1694 info, err := os.Lstat(path) 1695 if err != nil { 1696 if os.IsNotExist(err) { 1697 return true 1698 } 1699 return true 1700 } 1701 if !info.IsDir() { 1702 return true 1703 } 1704 return Fail(t, fmt.Sprintf("directory %q exists", path), msgAndArgs...) 1705 } 1706 1707 // JSONEq asserts that two JSON strings are equivalent. 1708 // 1709 // assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) 1710 func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { 1711 if h, ok := t.(tHelper); ok { 1712 h.Helper() 1713 } 1714 var expectedJSONAsInterface, actualJSONAsInterface interface{} 1715 1716 if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil { 1717 return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...) 1718 } 1719 1720 if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil { 1721 return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...) 1722 } 1723 1724 return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) 1725 } 1726 1727 // YAMLEq asserts that two YAML strings are equivalent. 1728 func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { 1729 if h, ok := t.(tHelper); ok { 1730 h.Helper() 1731 } 1732 var expectedYAMLAsInterface, actualYAMLAsInterface interface{} 1733 1734 if err := yaml.Unmarshal([]byte(expected), &expectedYAMLAsInterface); err != nil { 1735 return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid yaml.\nYAML parsing error: '%s'", expected, err.Error()), msgAndArgs...) 1736 } 1737 1738 if err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil { 1739 return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid yaml.\nYAML error: '%s'", actual, err.Error()), msgAndArgs...) 1740 } 1741 1742 return Equal(t, expectedYAMLAsInterface, actualYAMLAsInterface, msgAndArgs...) 1743 } 1744 1745 func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { 1746 t := reflect.TypeOf(v) 1747 k := t.Kind() 1748 1749 if k == reflect.Ptr { 1750 t = t.Elem() 1751 k = t.Kind() 1752 } 1753 return t, k 1754 } 1755 1756 // diff returns a diff of both values as long as both are of the same type and 1757 // are a struct, map, slice, array or string. Otherwise it returns an empty string. 1758 func diff(expected interface{}, actual interface{}) string { 1759 if expected == nil || actual == nil { 1760 return "" 1761 } 1762 1763 et, ek := typeAndKind(expected) 1764 at, _ := typeAndKind(actual) 1765 1766 if et != at { 1767 return "" 1768 } 1769 1770 if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String { 1771 return "" 1772 } 1773 1774 var e, a string 1775 1776 switch et { 1777 case reflect.TypeOf(""): 1778 e = reflect.ValueOf(expected).String() 1779 a = reflect.ValueOf(actual).String() 1780 case reflect.TypeOf(time.Time{}): 1781 e = spewConfigStringerEnabled.Sdump(expected) 1782 a = spewConfigStringerEnabled.Sdump(actual) 1783 default: 1784 e = spewConfig.Sdump(expected) 1785 a = spewConfig.Sdump(actual) 1786 } 1787 1788 diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ 1789 A: difflib.SplitLines(e), 1790 B: difflib.SplitLines(a), 1791 FromFile: "Expected", 1792 FromDate: "", 1793 ToFile: "Actual", 1794 ToDate: "", 1795 Context: 1, 1796 }) 1797 1798 return "\n\nDiff:\n" + diff 1799 } 1800 1801 func isFunction(arg interface{}) bool { 1802 if arg == nil { 1803 return false 1804 } 1805 return reflect.TypeOf(arg).Kind() == reflect.Func 1806 } 1807 1808 var spewConfig = spew.ConfigState{ 1809 Indent: " ", 1810 DisablePointerAddresses: true, 1811 DisableCapacities: true, 1812 SortKeys: true, 1813 DisableMethods: true, 1814 MaxDepth: 10, 1815 } 1816 1817 var spewConfigStringerEnabled = spew.ConfigState{ 1818 Indent: " ", 1819 DisablePointerAddresses: true, 1820 DisableCapacities: true, 1821 SortKeys: true, 1822 MaxDepth: 10, 1823 } 1824 1825 type tHelper interface { 1826 Helper() 1827 } 1828 1829 // Eventually asserts that given condition will be met in waitFor time, 1830 // periodically checking target function each tick. 1831 // 1832 // assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) 1833 func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { 1834 if h, ok := t.(tHelper); ok { 1835 h.Helper() 1836 } 1837 1838 ch := make(chan bool, 1) 1839 1840 timer := time.NewTimer(waitFor) 1841 defer timer.Stop() 1842 1843 ticker := time.NewTicker(tick) 1844 defer ticker.Stop() 1845 1846 for tick := ticker.C; ; { 1847 select { 1848 case <-timer.C: 1849 return Fail(t, "Condition never satisfied", msgAndArgs...) 1850 case <-tick: 1851 tick = nil 1852 go func() { ch <- condition() }() 1853 case v := <-ch: 1854 if v { 1855 return true 1856 } 1857 tick = ticker.C 1858 } 1859 } 1860 } 1861 1862 // CollectT implements the TestingT interface and collects all errors. 1863 type CollectT struct { 1864 errors []error 1865 } 1866 1867 // Errorf collects the error. 1868 func (c *CollectT) Errorf(format string, args ...interface{}) { 1869 c.errors = append(c.errors, fmt.Errorf(format, args...)) 1870 } 1871 1872 // FailNow panics. 1873 func (c *CollectT) FailNow() { 1874 panic("Assertion failed") 1875 } 1876 1877 // Reset clears the collected errors. 1878 func (c *CollectT) Reset() { 1879 c.errors = nil 1880 } 1881 1882 // Copy copies the collected errors to the supplied t. 1883 func (c *CollectT) Copy(t TestingT) { 1884 if tt, ok := t.(tHelper); ok { 1885 tt.Helper() 1886 } 1887 for _, err := range c.errors { 1888 t.Errorf("%v", err) 1889 } 1890 } 1891 1892 // EventuallyWithT asserts that given condition will be met in waitFor time, 1893 // periodically checking target function each tick. In contrast to Eventually, 1894 // it supplies a CollectT to the condition function, so that the condition 1895 // function can use the CollectT to call other assertions. 1896 // The condition is considered "met" if no errors are raised in a tick. 1897 // The supplied CollectT collects all errors from one tick (if there are any). 1898 // If the condition is not met before waitFor, the collected errors of 1899 // the last tick are copied to t. 1900 // 1901 // externalValue := false 1902 // go func() { 1903 // time.Sleep(8*time.Second) 1904 // externalValue = true 1905 // }() 1906 // assert.EventuallyWithT(t, func(c *assert.CollectT) { 1907 // // add assertions as needed; any assertion failure will fail the current tick 1908 // assert.True(c, externalValue, "expected 'externalValue' to be true") 1909 // }, 1*time.Second, 10*time.Second, "external state has not changed to 'true'; still false") 1910 func EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { 1911 if h, ok := t.(tHelper); ok { 1912 h.Helper() 1913 } 1914 1915 collect := new(CollectT) 1916 ch := make(chan bool, 1) 1917 1918 timer := time.NewTimer(waitFor) 1919 defer timer.Stop() 1920 1921 ticker := time.NewTicker(tick) 1922 defer ticker.Stop() 1923 1924 for tick := ticker.C; ; { 1925 select { 1926 case <-timer.C: 1927 collect.Copy(t) 1928 return Fail(t, "Condition never satisfied", msgAndArgs...) 1929 case <-tick: 1930 tick = nil 1931 collect.Reset() 1932 go func() { 1933 condition(collect) 1934 ch <- len(collect.errors) == 0 1935 }() 1936 case v := <-ch: 1937 if v { 1938 return true 1939 } 1940 tick = ticker.C 1941 } 1942 } 1943 } 1944 1945 // Never asserts that the given condition doesn't satisfy in waitFor time, 1946 // periodically checking the target function each tick. 1947 // 1948 // assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) 1949 func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { 1950 if h, ok := t.(tHelper); ok { 1951 h.Helper() 1952 } 1953 1954 ch := make(chan bool, 1) 1955 1956 timer := time.NewTimer(waitFor) 1957 defer timer.Stop() 1958 1959 ticker := time.NewTicker(tick) 1960 defer ticker.Stop() 1961 1962 for tick := ticker.C; ; { 1963 select { 1964 case <-timer.C: 1965 return true 1966 case <-tick: 1967 tick = nil 1968 go func() { ch <- condition() }() 1969 case v := <-ch: 1970 if v { 1971 return Fail(t, "Condition satisfied", msgAndArgs...) 1972 } 1973 tick = ticker.C 1974 } 1975 } 1976 } 1977 1978 // ErrorIs asserts that at least one of the errors in err's chain matches target. 1979 // This is a wrapper for errors.Is. 1980 func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { 1981 if h, ok := t.(tHelper); ok { 1982 h.Helper() 1983 } 1984 if errors.Is(err, target) { 1985 return true 1986 } 1987 1988 var expectedText string 1989 if target != nil { 1990 expectedText = target.Error() 1991 } 1992 1993 chain := buildErrorChainString(err) 1994 1995 return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+ 1996 "expected: %q\n"+ 1997 "in chain: %s", expectedText, chain, 1998 ), msgAndArgs...) 1999 } 2000 2001 // NotErrorIs asserts that at none of the errors in err's chain matches target. 2002 // This is a wrapper for errors.Is. 2003 func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { 2004 if h, ok := t.(tHelper); ok { 2005 h.Helper() 2006 } 2007 if !errors.Is(err, target) { 2008 return true 2009 } 2010 2011 var expectedText string 2012 if target != nil { 2013 expectedText = target.Error() 2014 } 2015 2016 chain := buildErrorChainString(err) 2017 2018 return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ 2019 "found: %q\n"+ 2020 "in chain: %s", expectedText, chain, 2021 ), msgAndArgs...) 2022 } 2023 2024 // ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value. 2025 // This is a wrapper for errors.As. 2026 func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool { 2027 if h, ok := t.(tHelper); ok { 2028 h.Helper() 2029 } 2030 if errors.As(err, target) { 2031 return true 2032 } 2033 2034 chain := buildErrorChainString(err) 2035 2036 return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ 2037 "expected: %q\n"+ 2038 "in chain: %s", target, chain, 2039 ), msgAndArgs...) 2040 } 2041 2042 func buildErrorChainString(err error) string { 2043 if err == nil { 2044 return "" 2045 } 2046 2047 e := errors.Unwrap(err) 2048 chain := fmt.Sprintf("%q", err.Error()) 2049 for e != nil { 2050 chain += fmt.Sprintf("\n\t%q", e.Error()) 2051 e = errors.Unwrap(e) 2052 } 2053 return chain 2054 }