mirror

Mirror free and open-source projects you like with minimal effort
git clone git://git.server.ky/slackcoder/mirror
Log | Files | Refs | README

assertions.go (60730B)


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