1package assert 2 3import ( 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.v2" 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 28type 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. 34type 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. 38type 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. 42type 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. 46type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool 47 48// Comparison a custom function that returns true on success and false on failure 49type 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. 58func 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// ObjectsAreEqualValues gets whether two objects are equal, or if their 79// values are equal. 80func ObjectsAreEqualValues(expected, actual interface{}) bool { 81 if ObjectsAreEqual(expected, actual) { 82 return true 83 } 84 85 actualType := reflect.TypeOf(actual) 86 if actualType == nil { 87 return false 88 } 89 expectedValue := reflect.ValueOf(expected) 90 if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) { 91 // Attempt comparison after type conversion 92 return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual) 93 } 94 95 return false 96} 97 98/* CallerInfo is necessary because the assert functions use the testing object 99internally, causing it to print the file:line of the assert method, rather than where 100the problem actually occurred in calling code.*/ 101 102// CallerInfo returns an array of strings containing the file and line number 103// of each stack frame leading from the current test to the assert call that 104// failed. 105func CallerInfo() []string { 106 107 pc := uintptr(0) 108 file := "" 109 line := 0 110 ok := false 111 name := "" 112 113 callers := []string{} 114 for i := 0; ; i++ { 115 pc, file, line, ok = runtime.Caller(i) 116 if !ok { 117 // The breaks below failed to terminate the loop, and we ran off the 118 // end of the call stack. 119 break 120 } 121 122 // This is a huge edge case, but it will panic if this is the case, see #180 123 if file == "<autogenerated>" { 124 break 125 } 126 127 f := runtime.FuncForPC(pc) 128 if f == nil { 129 break 130 } 131 name = f.Name() 132 133 // testing.tRunner is the standard library function that calls 134 // tests. Subtests are called directly by tRunner, without going through 135 // the Test/Benchmark/Example function that contains the t.Run calls, so 136 // with subtests we should break when we hit tRunner, without adding it 137 // to the list of callers. 138 if name == "testing.tRunner" { 139 break 140 } 141 142 parts := strings.Split(file, "/") 143 file = parts[len(parts)-1] 144 if len(parts) > 1 { 145 dir := parts[len(parts)-2] 146 if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { 147 callers = append(callers, fmt.Sprintf("%s:%d", file, line)) 148 } 149 } 150 151 // Drop the package 152 segments := strings.Split(name, ".") 153 name = segments[len(segments)-1] 154 if isTest(name, "Test") || 155 isTest(name, "Benchmark") || 156 isTest(name, "Example") { 157 break 158 } 159 } 160 161 return callers 162} 163 164// Stolen from the `go test` tool. 165// isTest tells whether name looks like a test (or benchmark, according to prefix). 166// It is a Test (say) if there is a character after Test that is not a lower-case letter. 167// We don't want TesticularCancer. 168func isTest(name, prefix string) bool { 169 if !strings.HasPrefix(name, prefix) { 170 return false 171 } 172 if len(name) == len(prefix) { // "Test" is ok 173 return true 174 } 175 rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) 176 return !unicode.IsLower(rune) 177} 178 179func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { 180 if len(msgAndArgs) == 0 || msgAndArgs == nil { 181 return "" 182 } 183 if len(msgAndArgs) == 1 { 184 msg := msgAndArgs[0] 185 if msgAsStr, ok := msg.(string); ok { 186 return msgAsStr 187 } 188 return fmt.Sprintf("%+v", msg) 189 } 190 if len(msgAndArgs) > 1 { 191 return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) 192 } 193 return "" 194} 195 196// Aligns the provided message so that all lines after the first line start at the same location as the first line. 197// Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab). 198// The longestLabelLen parameter specifies the length of the longest label in the output (required becaues this is the 199// basis on which the alignment occurs). 200func indentMessageLines(message string, longestLabelLen int) string { 201 outBuf := new(bytes.Buffer) 202 203 for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { 204 // no need to align first line because it starts at the correct location (after the label) 205 if i != 0 { 206 // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab 207 outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") 208 } 209 outBuf.WriteString(scanner.Text()) 210 } 211 212 return outBuf.String() 213} 214 215type failNower interface { 216 FailNow() 217} 218 219// FailNow fails test 220func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { 221 if h, ok := t.(tHelper); ok { 222 h.Helper() 223 } 224 Fail(t, failureMessage, msgAndArgs...) 225 226 // We cannot extend TestingT with FailNow() and 227 // maintain backwards compatibility, so we fallback 228 // to panicking when FailNow is not available in 229 // TestingT. 230 // See issue #263 231 232 if t, ok := t.(failNower); ok { 233 t.FailNow() 234 } else { 235 panic("test failed and t is missing `FailNow()`") 236 } 237 return false 238} 239 240// Fail reports a failure through 241func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { 242 if h, ok := t.(tHelper); ok { 243 h.Helper() 244 } 245 content := []labeledContent{ 246 {"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")}, 247 {"Error", failureMessage}, 248 } 249 250 // Add test name if the Go version supports it 251 if n, ok := t.(interface { 252 Name() string 253 }); ok { 254 content = append(content, labeledContent{"Test", n.Name()}) 255 } 256 257 message := messageFromMsgAndArgs(msgAndArgs...) 258 if len(message) > 0 { 259 content = append(content, labeledContent{"Messages", message}) 260 } 261 262 t.Errorf("\n%s", ""+labeledOutput(content...)) 263 264 return false 265} 266 267type labeledContent struct { 268 label string 269 content string 270} 271 272// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: 273// 274// \t{{label}}:{{align_spaces}}\t{{content}}\n 275// 276// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. 277// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this 278// alignment is achieved, "\t{{content}}\n" is added for the output. 279// 280// 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. 281func labeledOutput(content ...labeledContent) string { 282 longestLabel := 0 283 for _, v := range content { 284 if len(v.label) > longestLabel { 285 longestLabel = len(v.label) 286 } 287 } 288 var output string 289 for _, v := range content { 290 output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n" 291 } 292 return output 293} 294 295// Implements asserts that an object is implemented by the specified interface. 296// 297// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) 298func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { 299 if h, ok := t.(tHelper); ok { 300 h.Helper() 301 } 302 interfaceType := reflect.TypeOf(interfaceObject).Elem() 303 304 if object == nil { 305 return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...) 306 } 307 if !reflect.TypeOf(object).Implements(interfaceType) { 308 return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...) 309 } 310 311 return true 312} 313 314// IsType asserts that the specified objects are of the same type. 315func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { 316 if h, ok := t.(tHelper); ok { 317 h.Helper() 318 } 319 320 if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { 321 return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) 322 } 323 324 return true 325} 326 327// Equal asserts that two objects are equal. 328// 329// assert.Equal(t, 123, 123) 330// 331// Pointer variable equality is determined based on the equality of the 332// referenced values (as opposed to the memory addresses). Function equality 333// cannot be determined and will always fail. 334func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 335 if h, ok := t.(tHelper); ok { 336 h.Helper() 337 } 338 if err := validateEqualArgs(expected, actual); err != nil { 339 return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)", 340 expected, actual, err), msgAndArgs...) 341 } 342 343 if !ObjectsAreEqual(expected, actual) { 344 diff := diff(expected, actual) 345 expected, actual = formatUnequalValues(expected, actual) 346 return Fail(t, fmt.Sprintf("Not equal: \n"+ 347 "expected: %s\n"+ 348 "actual : %s%s", expected, actual, diff), msgAndArgs...) 349 } 350 351 return true 352 353} 354 355// validateEqualArgs checks whether provided arguments can be safely used in the 356// Equal/NotEqual functions. 357func validateEqualArgs(expected, actual interface{}) error { 358 if expected == nil && actual == nil { 359 return nil 360 } 361 362 if isFunction(expected) || isFunction(actual) { 363 return errors.New("cannot take func type as argument") 364 } 365 return nil 366} 367 368// Same asserts that two pointers reference the same object. 369// 370// assert.Same(t, ptr1, ptr2) 371// 372// Both arguments must be pointer variables. Pointer variable sameness is 373// determined based on the equality of both type and value. 374func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 375 if h, ok := t.(tHelper); ok { 376 h.Helper() 377 } 378 379 if !samePointers(expected, actual) { 380 return Fail(t, fmt.Sprintf("Not same: \n"+ 381 "expected: %p %#v\n"+ 382 "actual : %p %#v", expected, expected, actual, actual), msgAndArgs...) 383 } 384 385 return true 386} 387 388// NotSame asserts that two pointers do not reference the same object. 389// 390// assert.NotSame(t, ptr1, ptr2) 391// 392// Both arguments must be pointer variables. Pointer variable sameness is 393// determined based on the equality of both type and value. 394func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 395 if h, ok := t.(tHelper); ok { 396 h.Helper() 397 } 398 399 if samePointers(expected, actual) { 400 return Fail(t, fmt.Sprintf( 401 "Expected and actual point to the same object: %p %#v", 402 expected, expected), msgAndArgs...) 403 } 404 return true 405} 406 407// samePointers compares two generic interface objects and returns whether 408// they point to the same object 409func samePointers(first, second interface{}) bool { 410 firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second) 411 if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr { 412 return false 413 } 414 415 firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second) 416 if firstType != secondType { 417 return false 418 } 419 420 // compare pointer addresses 421 return first == second 422} 423 424// formatUnequalValues takes two values of arbitrary types and returns string 425// representations appropriate to be presented to the user. 426// 427// If the values are not of like type, the returned strings will be prefixed 428// with the type name, and the value will be enclosed in parenthesis similar 429// to a type conversion in the Go grammar. 430func formatUnequalValues(expected, actual interface{}) (e string, a string) { 431 if reflect.TypeOf(expected) != reflect.TypeOf(actual) { 432 return fmt.Sprintf("%T(%#v)", expected, expected), 433 fmt.Sprintf("%T(%#v)", actual, actual) 434 } 435 switch expected.(type) { 436 case time.Duration: 437 return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual) 438 } 439 return fmt.Sprintf("%#v", expected), fmt.Sprintf("%#v", actual) 440} 441 442// EqualValues asserts that two objects are equal or convertable to the same types 443// and equal. 444// 445// assert.EqualValues(t, uint32(123), int32(123)) 446func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 447 if h, ok := t.(tHelper); ok { 448 h.Helper() 449 } 450 451 if !ObjectsAreEqualValues(expected, actual) { 452 diff := diff(expected, actual) 453 expected, actual = formatUnequalValues(expected, actual) 454 return Fail(t, fmt.Sprintf("Not equal: \n"+ 455 "expected: %s\n"+ 456 "actual : %s%s", expected, actual, diff), msgAndArgs...) 457 } 458 459 return true 460 461} 462 463// Exactly asserts that two objects are equal in value and type. 464// 465// assert.Exactly(t, int32(123), int64(123)) 466func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 467 if h, ok := t.(tHelper); ok { 468 h.Helper() 469 } 470 471 aType := reflect.TypeOf(expected) 472 bType := reflect.TypeOf(actual) 473 474 if aType != bType { 475 return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) 476 } 477 478 return Equal(t, expected, actual, msgAndArgs...) 479 480} 481 482// NotNil asserts that the specified object is not nil. 483// 484// assert.NotNil(t, err) 485func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 486 if h, ok := t.(tHelper); ok { 487 h.Helper() 488 } 489 if !isNil(object) { 490 return true 491 } 492 return Fail(t, "Expected value not to be nil.", msgAndArgs...) 493} 494 495// containsKind checks if a specified kind in the slice of kinds. 496func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool { 497 for i := 0; i < len(kinds); i++ { 498 if kind == kinds[i] { 499 return true 500 } 501 } 502 503 return false 504} 505 506// isNil checks if a specified object is nil or not, without Failing. 507func isNil(object interface{}) bool { 508 if object == nil { 509 return true 510 } 511 512 value := reflect.ValueOf(object) 513 kind := value.Kind() 514 isNilableKind := containsKind( 515 []reflect.Kind{ 516 reflect.Chan, reflect.Func, 517 reflect.Interface, reflect.Map, 518 reflect.Ptr, reflect.Slice}, 519 kind) 520 521 if isNilableKind && value.IsNil() { 522 return true 523 } 524 525 return false 526} 527 528// Nil asserts that the specified object is nil. 529// 530// assert.Nil(t, err) 531func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 532 if h, ok := t.(tHelper); ok { 533 h.Helper() 534 } 535 if isNil(object) { 536 return true 537 } 538 return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) 539} 540 541// isEmpty gets whether the specified object is considered empty or not. 542func isEmpty(object interface{}) bool { 543 544 // get nil case out of the way 545 if object == nil { 546 return true 547 } 548 549 objValue := reflect.ValueOf(object) 550 551 switch objValue.Kind() { 552 // collection types are empty when they have no element 553 case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: 554 return objValue.Len() == 0 555 // pointers are empty if nil or if the value they point to is empty 556 case reflect.Ptr: 557 if objValue.IsNil() { 558 return true 559 } 560 deref := objValue.Elem().Interface() 561 return isEmpty(deref) 562 // for all other types, compare against the zero value 563 default: 564 zero := reflect.Zero(objValue.Type()) 565 return reflect.DeepEqual(object, zero.Interface()) 566 } 567} 568 569// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either 570// a slice or a channel with len == 0. 571// 572// assert.Empty(t, obj) 573func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 574 if h, ok := t.(tHelper); ok { 575 h.Helper() 576 } 577 578 pass := isEmpty(object) 579 if !pass { 580 Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) 581 } 582 583 return pass 584 585} 586 587// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either 588// a slice or a channel with len == 0. 589// 590// if assert.NotEmpty(t, obj) { 591// assert.Equal(t, "two", obj[1]) 592// } 593func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { 594 if h, ok := t.(tHelper); ok { 595 h.Helper() 596 } 597 598 pass := !isEmpty(object) 599 if !pass { 600 Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...) 601 } 602 603 return pass 604 605} 606 607// getLen try to get length of object. 608// return (false, 0) if impossible. 609func getLen(x interface{}) (ok bool, length int) { 610 v := reflect.ValueOf(x) 611 defer func() { 612 if e := recover(); e != nil { 613 ok = false 614 } 615 }() 616 return true, v.Len() 617} 618 619// Len asserts that the specified object has specific length. 620// Len also fails if the object has a type that len() not accept. 621// 622// assert.Len(t, mySlice, 3) 623func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { 624 if h, ok := t.(tHelper); ok { 625 h.Helper() 626 } 627 ok, l := getLen(object) 628 if !ok { 629 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) 630 } 631 632 if l != length { 633 return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) 634 } 635 return true 636} 637 638// True asserts that the specified value is true. 639// 640// assert.True(t, myBool) 641func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { 642 if h, ok := t.(tHelper); ok { 643 h.Helper() 644 } 645 if h, ok := t.(interface { 646 Helper() 647 }); ok { 648 h.Helper() 649 } 650 651 if value != true { 652 return Fail(t, "Should be true", msgAndArgs...) 653 } 654 655 return true 656 657} 658 659// False asserts that the specified value is false. 660// 661// assert.False(t, myBool) 662func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { 663 if h, ok := t.(tHelper); ok { 664 h.Helper() 665 } 666 667 if value != false { 668 return Fail(t, "Should be false", msgAndArgs...) 669 } 670 671 return true 672 673} 674 675// NotEqual asserts that the specified values are NOT equal. 676// 677// assert.NotEqual(t, obj1, obj2) 678// 679// Pointer variable equality is determined based on the equality of the 680// referenced values (as opposed to the memory addresses). 681func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { 682 if h, ok := t.(tHelper); ok { 683 h.Helper() 684 } 685 if err := validateEqualArgs(expected, actual); err != nil { 686 return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)", 687 expected, actual, err), msgAndArgs...) 688 } 689 690 if ObjectsAreEqual(expected, actual) { 691 return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) 692 } 693 694 return true 695 696} 697 698// containsElement try loop over the list check if the list includes the element. 699// return (false, false) if impossible. 700// return (true, false) if element was not found. 701// return (true, true) if element was found. 702func includeElement(list interface{}, element interface{}) (ok, found bool) { 703 704 listValue := reflect.ValueOf(list) 705 listKind := reflect.TypeOf(list).Kind() 706 defer func() { 707 if e := recover(); e != nil { 708 ok = false 709 found = false 710 } 711 }() 712 713 if listKind == reflect.String { 714 elementValue := reflect.ValueOf(element) 715 return true, strings.Contains(listValue.String(), elementValue.String()) 716 } 717 718 if listKind == reflect.Map { 719 mapKeys := listValue.MapKeys() 720 for i := 0; i < len(mapKeys); i++ { 721 if ObjectsAreEqual(mapKeys[i].Interface(), element) { 722 return true, true 723 } 724 } 725 return true, false 726 } 727 728 for i := 0; i < listValue.Len(); i++ { 729 if ObjectsAreEqual(listValue.Index(i).Interface(), element) { 730 return true, true 731 } 732 } 733 return true, false 734 735} 736 737// Contains asserts that the specified string, list(array, slice...) or map contains the 738// specified substring or element. 739// 740// assert.Contains(t, "Hello World", "World") 741// assert.Contains(t, ["Hello", "World"], "World") 742// assert.Contains(t, {"Hello": "World"}, "Hello") 743func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { 744 if h, ok := t.(tHelper); ok { 745 h.Helper() 746 } 747 748 ok, found := includeElement(s, contains) 749 if !ok { 750 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) 751 } 752 if !found { 753 return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", s, contains), msgAndArgs...) 754 } 755 756 return true 757 758} 759 760// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the 761// specified substring or element. 762// 763// assert.NotContains(t, "Hello World", "Earth") 764// assert.NotContains(t, ["Hello", "World"], "Earth") 765// assert.NotContains(t, {"Hello": "World"}, "Earth") 766func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { 767 if h, ok := t.(tHelper); ok { 768 h.Helper() 769 } 770 771 ok, found := includeElement(s, contains) 772 if !ok { 773 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) 774 } 775 if found { 776 return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...) 777 } 778 779 return true 780 781} 782 783// Subset asserts that the specified list(array, slice...) contains all 784// elements given in the specified subset(array, slice...). 785// 786// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") 787func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { 788 if h, ok := t.(tHelper); ok { 789 h.Helper() 790 } 791 if subset == nil { 792 return true // we consider nil to be equal to the nil set 793 } 794 795 subsetValue := reflect.ValueOf(subset) 796 defer func() { 797 if e := recover(); e != nil { 798 ok = false 799 } 800 }() 801 802 listKind := reflect.TypeOf(list).Kind() 803 subsetKind := reflect.TypeOf(subset).Kind() 804 805 if listKind != reflect.Array && listKind != reflect.Slice { 806 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) 807 } 808 809 if subsetKind != reflect.Array && subsetKind != reflect.Slice { 810 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) 811 } 812 813 for i := 0; i < subsetValue.Len(); i++ { 814 element := subsetValue.Index(i).Interface() 815 ok, found := includeElement(list, element) 816 if !ok { 817 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) 818 } 819 if !found { 820 return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, element), msgAndArgs...) 821 } 822 } 823 824 return true 825} 826 827// NotSubset asserts that the specified list(array, slice...) contains not all 828// elements given in the specified subset(array, slice...). 829// 830// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") 831func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { 832 if h, ok := t.(tHelper); ok { 833 h.Helper() 834 } 835 if subset == nil { 836 return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...) 837 } 838 839 subsetValue := reflect.ValueOf(subset) 840 defer func() { 841 if e := recover(); e != nil { 842 ok = false 843 } 844 }() 845 846 listKind := reflect.TypeOf(list).Kind() 847 subsetKind := reflect.TypeOf(subset).Kind() 848 849 if listKind != reflect.Array && listKind != reflect.Slice { 850 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) 851 } 852 853 if subsetKind != reflect.Array && subsetKind != reflect.Slice { 854 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) 855 } 856 857 for i := 0; i < subsetValue.Len(); i++ { 858 element := subsetValue.Index(i).Interface() 859 ok, found := includeElement(list, element) 860 if !ok { 861 return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) 862 } 863 if !found { 864 return true 865 } 866 } 867 868 return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) 869} 870 871// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified 872// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, 873// the number of appearances of each of them in both lists should match. 874// 875// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) 876func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { 877 if h, ok := t.(tHelper); ok { 878 h.Helper() 879 } 880 if isEmpty(listA) && isEmpty(listB) { 881 return true 882 } 883 884 aKind := reflect.TypeOf(listA).Kind() 885 bKind := reflect.TypeOf(listB).Kind() 886 887 if aKind != reflect.Array && aKind != reflect.Slice { 888 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listA, aKind), msgAndArgs...) 889 } 890 891 if bKind != reflect.Array && bKind != reflect.Slice { 892 return Fail(t, fmt.Sprintf("%q has an unsupported type %s", listB, bKind), msgAndArgs...) 893 } 894 895 aValue := reflect.ValueOf(listA) 896 bValue := reflect.ValueOf(listB) 897 898 aLen := aValue.Len() 899 bLen := bValue.Len() 900 901 if aLen != bLen { 902 return Fail(t, fmt.Sprintf("lengths don't match: %d != %d", aLen, bLen), msgAndArgs...) 903 } 904 905 // Mark indexes in bValue that we already used 906 visited := make([]bool, bLen) 907 for i := 0; i < aLen; i++ { 908 element := aValue.Index(i).Interface() 909 found := false 910 for j := 0; j < bLen; j++ { 911 if visited[j] { 912 continue 913 } 914 if ObjectsAreEqual(bValue.Index(j).Interface(), element) { 915 visited[j] = true 916 found = true 917 break 918 } 919 } 920 if !found { 921 return Fail(t, fmt.Sprintf("element %s appears more times in %s than in %s", element, aValue, bValue), msgAndArgs...) 922 } 923 } 924 925 return true 926} 927 928// Condition uses a Comparison to assert a complex condition. 929func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { 930 if h, ok := t.(tHelper); ok { 931 h.Helper() 932 } 933 result := comp() 934 if !result { 935 Fail(t, "Condition failed!", msgAndArgs...) 936 } 937 return result 938} 939 940// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics 941// methods, and represents a simple func that takes no arguments, and returns nothing. 942type PanicTestFunc func() 943 944// didPanic returns true if the function passed to it panics. Otherwise, it returns false. 945func didPanic(f PanicTestFunc) (bool, interface{}, string) { 946 947 didPanic := false 948 var message interface{} 949 var stack string 950 func() { 951 952 defer func() { 953 if message = recover(); message != nil { 954 didPanic = true 955 stack = string(debug.Stack()) 956 } 957 }() 958 959 // call the target function 960 f() 961 962 }() 963 964 return didPanic, message, stack 965 966} 967 968// Panics asserts that the code inside the specified PanicTestFunc panics. 969// 970// assert.Panics(t, func(){ GoCrazy() }) 971func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { 972 if h, ok := t.(tHelper); ok { 973 h.Helper() 974 } 975 976 if funcDidPanic, panicValue, _ := didPanic(f); !funcDidPanic { 977 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) 978 } 979 980 return true 981} 982 983// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that 984// the recovered panic value equals the expected panic value. 985// 986// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) 987func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { 988 if h, ok := t.(tHelper); ok { 989 h.Helper() 990 } 991 992 funcDidPanic, panicValue, panickedStack := didPanic(f) 993 if !funcDidPanic { 994 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) 995 } 996 if panicValue != expected { 997 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...) 998 } 999 1000 return true 1001} 1002 1003// PanicsWithError asserts that the code inside the specified PanicTestFunc 1004// panics, and that the recovered panic value is an error that satisfies the 1005// EqualError comparison. 1006// 1007// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) 1008func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool { 1009 if h, ok := t.(tHelper); ok { 1010 h.Helper() 1011 } 1012 1013 funcDidPanic, panicValue, panickedStack := didPanic(f) 1014 if !funcDidPanic { 1015 return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) 1016 } 1017 panicErr, ok := panicValue.(error) 1018 if !ok || panicErr.Error() != errString { 1019 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...) 1020 } 1021 1022 return true 1023} 1024 1025// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. 1026// 1027// assert.NotPanics(t, func(){ RemainCalm() }) 1028func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { 1029 if h, ok := t.(tHelper); ok { 1030 h.Helper() 1031 } 1032 1033 if funcDidPanic, panicValue, panickedStack := didPanic(f); funcDidPanic { 1034 return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v\n\tPanic stack:\t%s", f, panicValue, panickedStack), msgAndArgs...) 1035 } 1036 1037 return true 1038} 1039 1040// WithinDuration asserts that the two times are within duration delta of each other. 1041// 1042// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) 1043func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { 1044 if h, ok := t.(tHelper); ok { 1045 h.Helper() 1046 } 1047 1048 dt := expected.Sub(actual) 1049 if dt < -delta || dt > delta { 1050 return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) 1051 } 1052 1053 return true 1054} 1055 1056func toFloat(x interface{}) (float64, bool) { 1057 var xf float64 1058 xok := true 1059 1060 switch xn := x.(type) { 1061 case uint8: 1062 xf = float64(xn) 1063 case uint16: 1064 xf = float64(xn) 1065 case uint32: 1066 xf = float64(xn) 1067 case uint64: 1068 xf = float64(xn) 1069 case int: 1070 xf = float64(xn) 1071 case int8: 1072 xf = float64(xn) 1073 case int16: 1074 xf = float64(xn) 1075 case int32: 1076 xf = float64(xn) 1077 case int64: 1078 xf = float64(xn) 1079 case float32: 1080 xf = float64(xn) 1081 case float64: 1082 xf = float64(xn) 1083 case time.Duration: 1084 xf = float64(xn) 1085 default: 1086 xok = false 1087 } 1088 1089 return xf, xok 1090} 1091 1092// InDelta asserts that the two numerals are within delta of each other. 1093// 1094// assert.InDelta(t, math.Pi, 22/7.0, 0.01) 1095func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { 1096 if h, ok := t.(tHelper); ok { 1097 h.Helper() 1098 } 1099 1100 af, aok := toFloat(expected) 1101 bf, bok := toFloat(actual) 1102 1103 if !aok || !bok { 1104 return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...) 1105 } 1106 1107 if math.IsNaN(af) { 1108 return Fail(t, fmt.Sprintf("Expected must not be NaN"), msgAndArgs...) 1109 } 1110 1111 if math.IsNaN(bf) { 1112 return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...) 1113 } 1114 1115 dt := af - bf 1116 if dt < -delta || dt > delta { 1117 return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) 1118 } 1119 1120 return true 1121} 1122 1123// InDeltaSlice is the same as InDelta, except it compares two slices. 1124func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { 1125 if h, ok := t.(tHelper); ok { 1126 h.Helper() 1127 } 1128 if expected == nil || actual == nil || 1129 reflect.TypeOf(actual).Kind() != reflect.Slice || 1130 reflect.TypeOf(expected).Kind() != reflect.Slice { 1131 return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) 1132 } 1133 1134 actualSlice := reflect.ValueOf(actual) 1135 expectedSlice := reflect.ValueOf(expected) 1136 1137 for i := 0; i < actualSlice.Len(); i++ { 1138 result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...) 1139 if !result { 1140 return result 1141 } 1142 } 1143 1144 return true 1145} 1146 1147// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. 1148func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { 1149 if h, ok := t.(tHelper); ok { 1150 h.Helper() 1151 } 1152 if expected == nil || actual == nil || 1153 reflect.TypeOf(actual).Kind() != reflect.Map || 1154 reflect.TypeOf(expected).Kind() != reflect.Map { 1155 return Fail(t, "Arguments must be maps", msgAndArgs...) 1156 } 1157 1158 expectedMap := reflect.ValueOf(expected) 1159 actualMap := reflect.ValueOf(actual) 1160 1161 if expectedMap.Len() != actualMap.Len() { 1162 return Fail(t, "Arguments must have the same number of keys", msgAndArgs...) 1163 } 1164 1165 for _, k := range expectedMap.MapKeys() { 1166 ev := expectedMap.MapIndex(k) 1167 av := actualMap.MapIndex(k) 1168 1169 if !ev.IsValid() { 1170 return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...) 1171 } 1172 1173 if !av.IsValid() { 1174 return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...) 1175 } 1176 1177 if !InDelta( 1178 t, 1179 ev.Interface(), 1180 av.Interface(), 1181 delta, 1182 msgAndArgs..., 1183 ) { 1184 return false 1185 } 1186 } 1187 1188 return true 1189} 1190 1191func calcRelativeError(expected, actual interface{}) (float64, error) { 1192 af, aok := toFloat(expected) 1193 if !aok { 1194 return 0, fmt.Errorf("expected value %q cannot be converted to float", expected) 1195 } 1196 if af == 0 { 1197 return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error") 1198 } 1199 bf, bok := toFloat(actual) 1200 if !bok { 1201 return 0, fmt.Errorf("actual value %q cannot be converted to float", actual) 1202 } 1203 1204 return math.Abs(af-bf) / math.Abs(af), nil 1205} 1206 1207// InEpsilon asserts that expected and actual have a relative error less than epsilon 1208func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { 1209 if h, ok := t.(tHelper); ok { 1210 h.Helper() 1211 } 1212 actualEpsilon, err := calcRelativeError(expected, actual) 1213 if err != nil { 1214 return Fail(t, err.Error(), msgAndArgs...) 1215 } 1216 if actualEpsilon > epsilon { 1217 return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ 1218 " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) 1219 } 1220 1221 return true 1222} 1223 1224// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. 1225func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { 1226 if h, ok := t.(tHelper); ok { 1227 h.Helper() 1228 } 1229 if expected == nil || actual == nil || 1230 reflect.TypeOf(actual).Kind() != reflect.Slice || 1231 reflect.TypeOf(expected).Kind() != reflect.Slice { 1232 return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) 1233 } 1234 1235 actualSlice := reflect.ValueOf(actual) 1236 expectedSlice := reflect.ValueOf(expected) 1237 1238 for i := 0; i < actualSlice.Len(); i++ { 1239 result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon) 1240 if !result { 1241 return result 1242 } 1243 } 1244 1245 return true 1246} 1247 1248/* 1249 Errors 1250*/ 1251 1252// NoError asserts that a function returned no error (i.e. `nil`). 1253// 1254// actualObj, err := SomeFunction() 1255// if assert.NoError(t, err) { 1256// assert.Equal(t, expectedObj, actualObj) 1257// } 1258func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { 1259 if h, ok := t.(tHelper); ok { 1260 h.Helper() 1261 } 1262 if err != nil { 1263 return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) 1264 } 1265 1266 return true 1267} 1268 1269// Error asserts that a function returned an error (i.e. not `nil`). 1270// 1271// actualObj, err := SomeFunction() 1272// if assert.Error(t, err) { 1273// assert.Equal(t, expectedError, err) 1274// } 1275func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { 1276 if h, ok := t.(tHelper); ok { 1277 h.Helper() 1278 } 1279 1280 if err == nil { 1281 return Fail(t, "An error is expected but got nil.", msgAndArgs...) 1282 } 1283 1284 return true 1285} 1286 1287// EqualError asserts that a function returned an error (i.e. not `nil`) 1288// and that it is equal to the provided error. 1289// 1290// actualObj, err := SomeFunction() 1291// assert.EqualError(t, err, expectedErrorString) 1292func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { 1293 if h, ok := t.(tHelper); ok { 1294 h.Helper() 1295 } 1296 if !Error(t, theError, msgAndArgs...) { 1297 return false 1298 } 1299 expected := errString 1300 actual := theError.Error() 1301 // don't need to use deep equals here, we know they are both strings 1302 if expected != actual { 1303 return Fail(t, fmt.Sprintf("Error message not equal:\n"+ 1304 "expected: %q\n"+ 1305 "actual : %q", expected, actual), msgAndArgs...) 1306 } 1307 return true 1308} 1309 1310// matchRegexp return true if a specified regexp matches a string. 1311func matchRegexp(rx interface{}, str interface{}) bool { 1312 1313 var r *regexp.Regexp 1314 if rr, ok := rx.(*regexp.Regexp); ok { 1315 r = rr 1316 } else { 1317 r = regexp.MustCompile(fmt.Sprint(rx)) 1318 } 1319 1320 return (r.FindStringIndex(fmt.Sprint(str)) != nil) 1321 1322} 1323 1324// Regexp asserts that a specified regexp matches a string. 1325// 1326// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") 1327// assert.Regexp(t, "start...$", "it's not starting") 1328func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { 1329 if h, ok := t.(tHelper); ok { 1330 h.Helper() 1331 } 1332 1333 match := matchRegexp(rx, str) 1334 1335 if !match { 1336 Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) 1337 } 1338 1339 return match 1340} 1341 1342// NotRegexp asserts that a specified regexp does not match a string. 1343// 1344// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") 1345// assert.NotRegexp(t, "^start", "it's not starting") 1346func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { 1347 if h, ok := t.(tHelper); ok { 1348 h.Helper() 1349 } 1350 match := matchRegexp(rx, str) 1351 1352 if match { 1353 Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) 1354 } 1355 1356 return !match 1357 1358} 1359 1360// Zero asserts that i is the zero value for its type. 1361func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { 1362 if h, ok := t.(tHelper); ok { 1363 h.Helper() 1364 } 1365 if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { 1366 return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) 1367 } 1368 return true 1369} 1370 1371// NotZero asserts that i is not the zero value for its type. 1372func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { 1373 if h, ok := t.(tHelper); ok { 1374 h.Helper() 1375 } 1376 if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { 1377 return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) 1378 } 1379 return true 1380} 1381 1382// FileExists checks whether a file exists in the given path. It also fails if 1383// the path points to a directory or there is an error when trying to check the file. 1384func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { 1385 if h, ok := t.(tHelper); ok { 1386 h.Helper() 1387 } 1388 info, err := os.Lstat(path) 1389 if err != nil { 1390 if os.IsNotExist(err) { 1391 return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) 1392 } 1393 return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) 1394 } 1395 if info.IsDir() { 1396 return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...) 1397 } 1398 return true 1399} 1400 1401// NoFileExists checks whether a file does not exist in a given path. It fails 1402// if the path points to an existing _file_ only. 1403func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { 1404 if h, ok := t.(tHelper); ok { 1405 h.Helper() 1406 } 1407 info, err := os.Lstat(path) 1408 if err != nil { 1409 return true 1410 } 1411 if info.IsDir() { 1412 return true 1413 } 1414 return Fail(t, fmt.Sprintf("file %q exists", path), msgAndArgs...) 1415} 1416 1417// DirExists checks whether a directory exists in the given path. It also fails 1418// if the path is a file rather a directory or there is an error checking whether it exists. 1419func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { 1420 if h, ok := t.(tHelper); ok { 1421 h.Helper() 1422 } 1423 info, err := os.Lstat(path) 1424 if err != nil { 1425 if os.IsNotExist(err) { 1426 return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) 1427 } 1428 return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) 1429 } 1430 if !info.IsDir() { 1431 return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...) 1432 } 1433 return true 1434} 1435 1436// NoDirExists checks whether a directory does not exist in the given path. 1437// It fails if the path points to an existing _directory_ only. 1438func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { 1439 if h, ok := t.(tHelper); ok { 1440 h.Helper() 1441 } 1442 info, err := os.Lstat(path) 1443 if err != nil { 1444 if os.IsNotExist(err) { 1445 return true 1446 } 1447 return true 1448 } 1449 if !info.IsDir() { 1450 return true 1451 } 1452 return Fail(t, fmt.Sprintf("directory %q exists", path), msgAndArgs...) 1453} 1454 1455// JSONEq asserts that two JSON strings are equivalent. 1456// 1457// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) 1458func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { 1459 if h, ok := t.(tHelper); ok { 1460 h.Helper() 1461 } 1462 var expectedJSONAsInterface, actualJSONAsInterface interface{} 1463 1464 if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil { 1465 return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...) 1466 } 1467 1468 if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil { 1469 return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...) 1470 } 1471 1472 return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) 1473} 1474 1475// YAMLEq asserts that two YAML strings are equivalent. 1476func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { 1477 if h, ok := t.(tHelper); ok { 1478 h.Helper() 1479 } 1480 var expectedYAMLAsInterface, actualYAMLAsInterface interface{} 1481 1482 if err := yaml.Unmarshal([]byte(expected), &expectedYAMLAsInterface); err != nil { 1483 return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid yaml.\nYAML parsing error: '%s'", expected, err.Error()), msgAndArgs...) 1484 } 1485 1486 if err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil { 1487 return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid yaml.\nYAML error: '%s'", actual, err.Error()), msgAndArgs...) 1488 } 1489 1490 return Equal(t, expectedYAMLAsInterface, actualYAMLAsInterface, msgAndArgs...) 1491} 1492 1493func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { 1494 t := reflect.TypeOf(v) 1495 k := t.Kind() 1496 1497 if k == reflect.Ptr { 1498 t = t.Elem() 1499 k = t.Kind() 1500 } 1501 return t, k 1502} 1503 1504// diff returns a diff of both values as long as both are of the same type and 1505// are a struct, map, slice, array or string. Otherwise it returns an empty string. 1506func diff(expected interface{}, actual interface{}) string { 1507 if expected == nil || actual == nil { 1508 return "" 1509 } 1510 1511 et, ek := typeAndKind(expected) 1512 at, _ := typeAndKind(actual) 1513 1514 if et != at { 1515 return "" 1516 } 1517 1518 if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String { 1519 return "" 1520 } 1521 1522 var e, a string 1523 if et != reflect.TypeOf("") { 1524 e = spewConfig.Sdump(expected) 1525 a = spewConfig.Sdump(actual) 1526 } else { 1527 e = reflect.ValueOf(expected).String() 1528 a = reflect.ValueOf(actual).String() 1529 } 1530 1531 diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ 1532 A: difflib.SplitLines(e), 1533 B: difflib.SplitLines(a), 1534 FromFile: "Expected", 1535 FromDate: "", 1536 ToFile: "Actual", 1537 ToDate: "", 1538 Context: 1, 1539 }) 1540 1541 return "\n\nDiff:\n" + diff 1542} 1543 1544func isFunction(arg interface{}) bool { 1545 if arg == nil { 1546 return false 1547 } 1548 return reflect.TypeOf(arg).Kind() == reflect.Func 1549} 1550 1551var spewConfig = spew.ConfigState{ 1552 Indent: " ", 1553 DisablePointerAddresses: true, 1554 DisableCapacities: true, 1555 SortKeys: true, 1556} 1557 1558type tHelper interface { 1559 Helper() 1560} 1561 1562// Eventually asserts that given condition will be met in waitFor time, 1563// periodically checking target function each tick. 1564// 1565// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) 1566func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { 1567 if h, ok := t.(tHelper); ok { 1568 h.Helper() 1569 } 1570 1571 ch := make(chan bool, 1) 1572 1573 timer := time.NewTimer(waitFor) 1574 defer timer.Stop() 1575 1576 ticker := time.NewTicker(tick) 1577 defer ticker.Stop() 1578 1579 for tick := ticker.C; ; { 1580 select { 1581 case <-timer.C: 1582 return Fail(t, "Condition never satisfied", msgAndArgs...) 1583 case <-tick: 1584 tick = nil 1585 go func() { ch <- condition() }() 1586 case v := <-ch: 1587 if v { 1588 return true 1589 } 1590 tick = ticker.C 1591 } 1592 } 1593} 1594 1595// Never asserts that the given condition doesn't satisfy in waitFor time, 1596// periodically checking the target function each tick. 1597// 1598// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) 1599func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { 1600 if h, ok := t.(tHelper); ok { 1601 h.Helper() 1602 } 1603 1604 ch := make(chan bool, 1) 1605 1606 timer := time.NewTimer(waitFor) 1607 defer timer.Stop() 1608 1609 ticker := time.NewTicker(tick) 1610 defer ticker.Stop() 1611 1612 for tick := ticker.C; ; { 1613 select { 1614 case <-timer.C: 1615 return true 1616 case <-tick: 1617 tick = nil 1618 go func() { ch <- condition() }() 1619 case v := <-ch: 1620 if v { 1621 return Fail(t, "Condition satisfied", msgAndArgs...) 1622 } 1623 tick = ticker.C 1624 } 1625 } 1626} 1627