...

Source file src/github.com/stretchr/testify/assert/assertions.go

Documentation: github.com/stretchr/testify/assert

     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  }
  2106  

View as plain text