mirror of https://github.com/stretchr/testify.git
Merge branch 'master' into fix/suite-test-failures
commit
f2227519d6
|
@ -29,6 +29,7 @@ jobs:
|
||||||
- "1.19"
|
- "1.19"
|
||||||
- "1.20"
|
- "1.20"
|
||||||
- "1.21"
|
- "1.21"
|
||||||
|
- "1.22"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
|
|
|
@ -223,6 +223,8 @@ You can use the [mockery tool](https://vektra.github.io/mockery/latest/) to auto
|
||||||
|
|
||||||
[`suite`](https://pkg.go.dev/github.com/stretchr/testify/suite "API documentation") package
|
[`suite`](https://pkg.go.dev/github.com/stretchr/testify/suite "API documentation") package
|
||||||
-----------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------
|
||||||
|
> [!WARNING]
|
||||||
|
> The suite package does not support parallel tests. See [#934](https://github.com/stretchr/testify/issues/934).
|
||||||
|
|
||||||
The `suite` package provides functionality that you might be used to from more common object-oriented languages. With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal.
|
The `suite` package provides functionality that you might be used to from more common object-oriented languages. With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal.
|
||||||
|
|
||||||
|
|
|
@ -621,6 +621,15 @@ func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg s
|
||||||
return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
|
return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotErrorAsf asserts that none of the errors in err's chain matches target,
|
||||||
|
// but if so, sets target to that error value.
|
||||||
|
func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return NotErrorAs(t, err, target, append([]interface{}{msg}, args...)...)
|
||||||
|
}
|
||||||
|
|
||||||
// NotErrorIsf asserts that none of the errors in err's chain matches target.
|
// NotErrorIsf asserts that none of the errors in err's chain matches target.
|
||||||
// This is a wrapper for errors.Is.
|
// This is a wrapper for errors.Is.
|
||||||
func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {
|
func NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {
|
||||||
|
|
|
@ -1234,6 +1234,24 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str
|
||||||
return NotEqualf(a.t, expected, actual, msg, args...)
|
return NotEqualf(a.t, expected, actual, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotErrorAs asserts that none of the errors in err's chain matches target,
|
||||||
|
// but if so, sets target to that error value.
|
||||||
|
func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return NotErrorAs(a.t, err, target, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotErrorAsf asserts that none of the errors in err's chain matches target,
|
||||||
|
// but if so, sets target to that error value.
|
||||||
|
func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
return NotErrorAsf(a.t, err, target, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
// NotErrorIs asserts that none of the errors in err's chain matches target.
|
// NotErrorIs asserts that none of the errors in err's chain matches target.
|
||||||
// This is a wrapper for errors.Is.
|
// This is a wrapper for errors.Is.
|
||||||
func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool {
|
func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool {
|
||||||
|
|
|
@ -2149,6 +2149,24 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{
|
||||||
), msgAndArgs...)
|
), msgAndArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotErrorAs asserts that none of the errors in err's chain matches target,
|
||||||
|
// but if so, sets target to that error value.
|
||||||
|
func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
if !errors.As(err, target) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
chain := buildErrorChainString(err)
|
||||||
|
|
||||||
|
return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+
|
||||||
|
"found: %q\n"+
|
||||||
|
"in chain: %s", target, chain,
|
||||||
|
), msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
func buildErrorChainString(err error) string {
|
func buildErrorChainString(err error) string {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -1327,7 +1327,7 @@ func TestNotElementsMatch(t *testing.T) {
|
||||||
actual interface{}
|
actual interface{}
|
||||||
result bool
|
result bool
|
||||||
}{
|
}{
|
||||||
// not mathing
|
// not matching
|
||||||
{[]int{1}, []int{}, true},
|
{[]int{1}, []int{}, true},
|
||||||
{[]int{}, []int{2}, true},
|
{[]int{}, []int{2}, true},
|
||||||
{[]int{1}, []int{2}, true},
|
{[]int{1}, []int{2}, true},
|
||||||
|
@ -3269,7 +3269,6 @@ func TestNotErrorIs(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestErrorAs(t *testing.T) {
|
func TestErrorAs(t *testing.T) {
|
||||||
mockT := new(testing.T)
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
err error
|
err error
|
||||||
result bool
|
result bool
|
||||||
|
@ -3282,9 +3281,38 @@ func TestErrorAs(t *testing.T) {
|
||||||
tt := tt
|
tt := tt
|
||||||
var target *customError
|
var target *customError
|
||||||
t.Run(fmt.Sprintf("ErrorAs(%#v,%#v)", tt.err, target), func(t *testing.T) {
|
t.Run(fmt.Sprintf("ErrorAs(%#v,%#v)", tt.err, target), func(t *testing.T) {
|
||||||
|
mockT := new(testing.T)
|
||||||
res := ErrorAs(mockT, tt.err, &target)
|
res := ErrorAs(mockT, tt.err, &target)
|
||||||
if res != tt.result {
|
if res != tt.result {
|
||||||
t.Errorf("ErrorAs(%#v,%#v) should return %t)", tt.err, target, tt.result)
|
t.Errorf("ErrorAs(%#v,%#v) should return %t", tt.err, target, tt.result)
|
||||||
|
}
|
||||||
|
if res == mockT.Failed() {
|
||||||
|
t.Errorf("The test result (%t) should be reflected in the testing.T type (%t)", res, !mockT.Failed())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNotErrorAs(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
err error
|
||||||
|
result bool
|
||||||
|
}{
|
||||||
|
{fmt.Errorf("wrap: %w", &customError{}), false},
|
||||||
|
{io.EOF, true},
|
||||||
|
{nil, true},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
tt := tt
|
||||||
|
var target *customError
|
||||||
|
t.Run(fmt.Sprintf("NotErrorAs(%#v,%#v)", tt.err, target), func(t *testing.T) {
|
||||||
|
mockT := new(testing.T)
|
||||||
|
res := NotErrorAs(mockT, tt.err, &target)
|
||||||
|
if res != tt.result {
|
||||||
|
t.Errorf("NotErrorAs(%#v,%#v) should not return %t", tt.err, target, tt.result)
|
||||||
|
}
|
||||||
|
if res == mockT.Failed() {
|
||||||
|
t.Errorf("The test result (%t) should be reflected in the testing.T type (%t)", res, !mockT.Failed())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
// import assertYaml "github.com/stretchr/testify/assert/yaml"
|
// import assertYaml "github.com/stretchr/testify/assert/yaml"
|
||||||
//
|
//
|
||||||
// func init() {
|
// func init() {
|
||||||
// assertYaml.Unmarshall = func (in []byte, out interface{}) error {
|
// assertYaml.Unmarshal = func (in []byte, out interface{}) error {
|
||||||
// // ...
|
// // ...
|
||||||
// return nil
|
// return nil
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
//
|
//
|
||||||
// This package is just an indirection that allows the builder to override the
|
// This package is just an indirection that allows the builder to override the
|
||||||
// indirection with an alternative implementation of this package that uses
|
// indirection with an alternative implementation of this package that uses
|
||||||
// another implemantation of YAML deserialization. This allows to not either not
|
// another implementation of YAML deserialization. This allows to not either not
|
||||||
// use YAML deserialization at all, or to use another implementation than
|
// use YAML deserialization at all, or to use another implementation than
|
||||||
// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]).
|
// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]).
|
||||||
//
|
//
|
||||||
|
|
51
mock/mock.go
51
mock/mock.go
|
@ -256,7 +256,7 @@ func (c *Call) Unset() *Call {
|
||||||
// calls have been called as expected. The referenced calls may be from the
|
// calls have been called as expected. The referenced calls may be from the
|
||||||
// same mock instance and/or other mock instances.
|
// same mock instance and/or other mock instances.
|
||||||
//
|
//
|
||||||
// Mock.On("Do").Return(nil).Notbefore(
|
// Mock.On("Do").Return(nil).NotBefore(
|
||||||
// Mock.On("Init").Return(nil)
|
// Mock.On("Init").Return(nil)
|
||||||
// )
|
// )
|
||||||
func (c *Call) NotBefore(calls ...*Call) *Call {
|
func (c *Call) NotBefore(calls ...*Call) *Call {
|
||||||
|
@ -273,6 +273,20 @@ func (c *Call) NotBefore(calls ...*Call) *Call {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InOrder defines the order in which the calls should be made
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// InOrder(
|
||||||
|
// Mock.On("init").Return(nil),
|
||||||
|
// Mock.On("Do").Return(nil),
|
||||||
|
// )
|
||||||
|
func InOrder(calls ...*Call) {
|
||||||
|
for i := 1; i < len(calls); i++ {
|
||||||
|
calls[i].NotBefore(calls[i-1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mock is the workhorse used to track activity on another object.
|
// Mock is the workhorse used to track activity on another object.
|
||||||
// For an example of its usage, refer to the "Example Usage" section at the top
|
// For an example of its usage, refer to the "Example Usage" section at the top
|
||||||
// of this document.
|
// of this document.
|
||||||
|
@ -491,11 +505,12 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen
|
||||||
m.mutex.Unlock()
|
m.mutex.Unlock()
|
||||||
|
|
||||||
if closestCall != nil {
|
if closestCall != nil {
|
||||||
m.fail("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s",
|
m.fail("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\nDiff: %s\nat: %s\n",
|
||||||
callString(methodName, arguments, true),
|
callString(methodName, arguments, true),
|
||||||
callString(methodName, closestCall.Arguments, true),
|
callString(methodName, closestCall.Arguments, true),
|
||||||
diffArguments(closestCall.Arguments, arguments),
|
diffArguments(closestCall.Arguments, arguments),
|
||||||
strings.TrimSpace(mismatch),
|
strings.TrimSpace(mismatch),
|
||||||
|
assert.CallerInfo(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo())
|
m.fail("\nassert: mock: I don't know what to return because the method call was unexpected.\n\tEither do Mock.On(\"%s\").Return(...) first, or remove the %s() call.\n\tThis method was unexpected:\n\t\t%s\n\tat: %s", methodName, methodName, callString(methodName, arguments, true), assert.CallerInfo())
|
||||||
|
@ -811,21 +826,20 @@ func IsType(t interface{}) *IsTypeArgument {
|
||||||
return &IsTypeArgument{t: reflect.TypeOf(t)}
|
return &IsTypeArgument{t: reflect.TypeOf(t)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FunctionalOptionsArgument is a struct that contains the type and value of an functional option argument
|
// FunctionalOptionsArgument contains a list of functional options arguments
|
||||||
// for use when type checking.
|
// expected for use when matching a list of arguments.
|
||||||
type FunctionalOptionsArgument struct {
|
type FunctionalOptionsArgument struct {
|
||||||
value interface{}
|
values []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the string representation of FunctionalOptionsArgument
|
// String returns the string representation of FunctionalOptionsArgument
|
||||||
func (f *FunctionalOptionsArgument) String() string {
|
func (f *FunctionalOptionsArgument) String() string {
|
||||||
var name string
|
var name string
|
||||||
tValue := reflect.ValueOf(f.value)
|
if len(f.values) > 0 {
|
||||||
if tValue.Len() > 0 {
|
name = "[]" + reflect.TypeOf(f.values[0]).String()
|
||||||
name = "[]" + reflect.TypeOf(tValue.Index(0).Interface()).String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Replace(fmt.Sprintf("%#v", f.value), "[]interface {}", name, 1)
|
return strings.Replace(fmt.Sprintf("%#v", f.values), "[]interface {}", name, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FunctionalOptions returns an [FunctionalOptionsArgument] object containing
|
// FunctionalOptions returns an [FunctionalOptionsArgument] object containing
|
||||||
|
@ -833,10 +847,10 @@ func (f *FunctionalOptionsArgument) String() string {
|
||||||
//
|
//
|
||||||
// For example:
|
// For example:
|
||||||
//
|
//
|
||||||
// Assert(t, FunctionalOptions(foo.Opt1("strValue"), foo.Opt2(613)))
|
// args.Assert(t, FunctionalOptions(foo.Opt1("strValue"), foo.Opt2(613)))
|
||||||
func FunctionalOptions(value ...interface{}) *FunctionalOptionsArgument {
|
func FunctionalOptions(values ...interface{}) *FunctionalOptionsArgument {
|
||||||
return &FunctionalOptionsArgument{
|
return &FunctionalOptionsArgument{
|
||||||
value: value,
|
values: values,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -990,20 +1004,17 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
|
||||||
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected.t.Name(), actualT.Name(), actualFmt)
|
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected.t.Name(), actualT.Name(), actualFmt)
|
||||||
}
|
}
|
||||||
case *FunctionalOptionsArgument:
|
case *FunctionalOptionsArgument:
|
||||||
t := expected.value
|
|
||||||
|
|
||||||
var name string
|
var name string
|
||||||
tValue := reflect.ValueOf(t)
|
if len(expected.values) > 0 {
|
||||||
if tValue.Len() > 0 {
|
name = "[]" + reflect.TypeOf(expected.values[0]).String()
|
||||||
name = "[]" + reflect.TypeOf(tValue.Index(0).Interface()).String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tName := reflect.TypeOf(t).Name()
|
const tName = "[]interface{}"
|
||||||
if name != reflect.TypeOf(actual).String() && tValue.Len() != 0 {
|
if name != reflect.TypeOf(actual).String() && len(expected.values) != 0 {
|
||||||
differences++
|
differences++
|
||||||
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt)
|
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, tName, reflect.TypeOf(actual).Name(), actualFmt)
|
||||||
} else {
|
} else {
|
||||||
if ef, af := assertOpts(t, actual); ef == "" && af == "" {
|
if ef, af := assertOpts(expected.values, actual); ef == "" && af == "" {
|
||||||
// match
|
// match
|
||||||
output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, tName, tName)
|
output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, tName, tName)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -937,6 +937,26 @@ func Test_Mock_Return_NotBefore_In_Order(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Mock_Return_InOrder_Uses_NotBefore(t *testing.T) {
|
||||||
|
var mockedService = new(TestExampleImplementation)
|
||||||
|
|
||||||
|
InOrder(
|
||||||
|
mockedService.
|
||||||
|
On("TheExampleMethod", 1, 2, 3).
|
||||||
|
Return(4, nil),
|
||||||
|
mockedService.
|
||||||
|
On("TheExampleMethod2", true).
|
||||||
|
Return(),
|
||||||
|
)
|
||||||
|
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
mockedService.TheExampleMethod(1, 2, 3)
|
||||||
|
})
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
mockedService.TheExampleMethod2(true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func Test_Mock_Return_NotBefore_Out_Of_Order(t *testing.T) {
|
func Test_Mock_Return_NotBefore_Out_Of_Order(t *testing.T) {
|
||||||
var mockedService = new(TestExampleImplementation)
|
var mockedService = new(TestExampleImplementation)
|
||||||
|
|
||||||
|
@ -967,6 +987,35 @@ TheExampleMethod(int,int,int)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_Mock_Return_InOrder_Uses_NotBefore_Out_Of_Order(t *testing.T) {
|
||||||
|
var mockedService = new(TestExampleImplementation)
|
||||||
|
|
||||||
|
InOrder(
|
||||||
|
mockedService.
|
||||||
|
On("TheExampleMethod", 1, 2, 3).
|
||||||
|
Return(4, nil).Twice(),
|
||||||
|
mockedService.
|
||||||
|
On("TheExampleMethod2", true).
|
||||||
|
Return(),
|
||||||
|
)
|
||||||
|
|
||||||
|
expectedPanicString := `mock: Unexpected Method Call
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
TheExampleMethod2(bool)
|
||||||
|
0: true
|
||||||
|
|
||||||
|
Must not be called before:
|
||||||
|
|
||||||
|
TheExampleMethod(int,int,int)
|
||||||
|
0: 1
|
||||||
|
1: 2
|
||||||
|
2: 3`
|
||||||
|
require.PanicsWithValue(t, expectedPanicString, func() {
|
||||||
|
mockedService.TheExampleMethod2(true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func Test_Mock_Return_NotBefore_Not_Enough_Times(t *testing.T) {
|
func Test_Mock_Return_NotBefore_Not_Enough_Times(t *testing.T) {
|
||||||
var mockedService = new(TestExampleImplementation)
|
var mockedService = new(TestExampleImplementation)
|
||||||
|
|
||||||
|
@ -1022,6 +1071,7 @@ func Test_Mock_Return_NotBefore_Different_Mock_In_Order(t *testing.T) {
|
||||||
mockedService2.TheExampleMethod2(true)
|
mockedService2.TheExampleMethod2(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_Mock_Return_NotBefore_Different_Mock_Out_Of_Order(t *testing.T) {
|
func Test_Mock_Return_NotBefore_Different_Mock_Out_Of_Order(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
mockedService1 = new(TestExampleImplementation)
|
mockedService1 = new(TestExampleImplementation)
|
||||||
|
@ -1980,7 +2030,7 @@ func TestArgumentMatcherToPrintMismatch(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
matchingExp := regexp.MustCompile(
|
matchingExp := regexp.MustCompile(
|
||||||
`\s+mock: Unexpected Method Call\s+-*\s+GetTime\(int\)\s+0: 1\s+The closest call I have is:\s+GetTime\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(int=1\) not matched by func\(int\) bool`)
|
`\s+mock: Unexpected Method Call\s+-*\s+GetTime\(int\)\s+0: 1\s+The closest call I have is:\s+GetTime\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(int=1\) not matched by func\(int\) bool\nat: \[[^\]]+mock\/mock_test.go`)
|
||||||
assert.Regexp(t, matchingExp, r)
|
assert.Regexp(t, matchingExp, r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -1997,7 +2047,7 @@ func TestArgumentMatcherToPrintMismatchWithReferenceType(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
matchingExp := regexp.MustCompile(
|
matchingExp := regexp.MustCompile(
|
||||||
`\s+mock: Unexpected Method Call\s+-*\s+GetTimes\(\[\]int\)\s+0: \[\]int\{1\}\s+The closest call I have is:\s+GetTimes\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(\[\]int=\[1\]\) not matched by func\(\[\]int\) bool`)
|
`\s+mock: Unexpected Method Call\s+-*\s+GetTimes\(\[\]int\)\s+0: \[\]int\{1\}\s+The closest call I have is:\s+GetTimes\(mock.argumentMatcher\)\s+0: mock.argumentMatcher\{.*?\}\s+Diff:.*\(\[\]int=\[1\]\) not matched by func\(\[\]int\) bool\nat: \[[^\]]+mock\/mock_test.go`)
|
||||||
assert.Regexp(t, matchingExp, r)
|
assert.Regexp(t, matchingExp, r)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -2028,7 +2078,7 @@ func TestClosestCallMismatchedArgumentInformationShowsTheClosest(t *testing.T) {
|
||||||
func TestClosestCallFavorsFirstMock(t *testing.T) {
|
func TestClosestCallFavorsFirstMock(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -2,4 \+2,4 @@\s+\(bool\) true,\s+- \(bool\) true,\s+- \(bool\) true\s+\+ \(bool\) false,\s+\+ \(bool\) false\s+}\s+`
|
diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -2,4 \+2,4 @@\s+\(bool\) true,\s+- \(bool\) true,\s+- \(bool\) true\s+\+ \(bool\) false,\s+\+ \(bool\) false\s+}\s+Diff: 0: FAIL: \(\[\]bool=\[(true\s?|false\s?){3}]\) != \(\[\]bool=\[(true\s?|false\s?){3}\]\)`
|
||||||
matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod7([]bool)`, `0: \[\]bool{true, false, false}`, `0: \[\]bool{true, true, true}`, diffRegExp))
|
matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod7([]bool)`, `0: \[\]bool{true, false, false}`, `0: \[\]bool{true, true, true}`, diffRegExp))
|
||||||
assert.Regexp(t, matchingExp, r)
|
assert.Regexp(t, matchingExp, r)
|
||||||
}
|
}
|
||||||
|
@ -2044,7 +2094,7 @@ func TestClosestCallFavorsFirstMock(t *testing.T) {
|
||||||
func TestClosestCallUsesRepeatabilityToFindClosest(t *testing.T) {
|
func TestClosestCallUsesRepeatabilityToFindClosest(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -1,4 \+1,4 @@\s+\(\[\]bool\) \(len=3\) {\s+- \(bool\) false,\s+- \(bool\) false,\s+\+ \(bool\) true,\s+\+ \(bool\) true,\s+\(bool\) false\s+`
|
diffRegExp := `Difference found in argument 0:\s+--- Expected\s+\+\+\+ Actual\s+@@ -1,4 \+1,4 @@\s+\(\[\]bool\) \(len=3\) {\s+- \(bool\) false,\s+- \(bool\) false,\s+\+ \(bool\) true,\s+\+ \(bool\) true,\s+\(bool\) false\s+Diff: 0: FAIL: \(\[\]bool=\[(true\s?|false\s?){3}]\) != \(\[\]bool=\[(true\s?|false\s?){3}\]\)`
|
||||||
matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod7([]bool)`, `0: \[\]bool{true, true, false}`, `0: \[\]bool{false, false, false}`, diffRegExp))
|
matchingExp := regexp.MustCompile(unexpectedCallRegex(`TheExampleMethod7([]bool)`, `0: \[\]bool{true, true, false}`, `0: \[\]bool{false, false, false}`, diffRegExp))
|
||||||
assert.Regexp(t, matchingExp, r)
|
assert.Regexp(t, matchingExp, r)
|
||||||
}
|
}
|
||||||
|
@ -2101,7 +2151,7 @@ func Test_isBetterMatchThanReturnsFalseIfRepeatabilityIsLessThanOrEqualToOther(t
|
||||||
|
|
||||||
func unexpectedCallRegex(method, calledArg, expectedArg, diff string) string {
|
func unexpectedCallRegex(method, calledArg, expectedArg, diff string) string {
|
||||||
rMethod := regexp.QuoteMeta(method)
|
rMethod := regexp.QuoteMeta(method)
|
||||||
return fmt.Sprintf(`\s+mock: Unexpected Method Call\s+-*\s+%s\s+%s\s+The closest call I have is:\s+%s\s+%s\s+%s`,
|
return fmt.Sprintf(`\s+mock: Unexpected Method Call\s+-*\s+%s\s+%s\s+The closest call I have is:\s+%s\s+%s\s+%s\nat: \[[^\]]+mock\/mock_test.go`,
|
||||||
rMethod, calledArg, rMethod, expectedArg, diff)
|
rMethod, calledArg, rMethod, expectedArg, diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1559,6 +1559,30 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string,
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotErrorAs asserts that none of the errors in err's chain matches target,
|
||||||
|
// but if so, sets target to that error value.
|
||||||
|
func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
if assert.NotErrorAs(t, err, target, msgAndArgs...) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotErrorAsf asserts that none of the errors in err's chain matches target,
|
||||||
|
// but if so, sets target to that error value.
|
||||||
|
func NotErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) {
|
||||||
|
if h, ok := t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
if assert.NotErrorAsf(t, err, target, msg, args...) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
// NotErrorIs asserts that none of the errors in err's chain matches target.
|
// NotErrorIs asserts that none of the errors in err's chain matches target.
|
||||||
// This is a wrapper for errors.Is.
|
// This is a wrapper for errors.Is.
|
||||||
func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) {
|
func NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) {
|
||||||
|
|
|
@ -1235,6 +1235,24 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str
|
||||||
NotEqualf(a.t, expected, actual, msg, args...)
|
NotEqualf(a.t, expected, actual, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NotErrorAs asserts that none of the errors in err's chain matches target,
|
||||||
|
// but if so, sets target to that error value.
|
||||||
|
func (a *Assertions) NotErrorAs(err error, target interface{}, msgAndArgs ...interface{}) {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
NotErrorAs(a.t, err, target, msgAndArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NotErrorAsf asserts that none of the errors in err's chain matches target,
|
||||||
|
// but if so, sets target to that error value.
|
||||||
|
func (a *Assertions) NotErrorAsf(err error, target interface{}, msg string, args ...interface{}) {
|
||||||
|
if h, ok := a.t.(tHelper); ok {
|
||||||
|
h.Helper()
|
||||||
|
}
|
||||||
|
NotErrorAsf(a.t, err, target, msg, args...)
|
||||||
|
}
|
||||||
|
|
||||||
// NotErrorIs asserts that none of the errors in err's chain matches target.
|
// NotErrorIs asserts that none of the errors in err's chain matches target.
|
||||||
// This is a wrapper for errors.Is.
|
// This is a wrapper for errors.Is.
|
||||||
func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) {
|
func (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) {
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
// or individual tests (depending on which interface(s) you
|
// or individual tests (depending on which interface(s) you
|
||||||
// implement).
|
// implement).
|
||||||
//
|
//
|
||||||
|
// The suite package does not support parallel tests. See [issue 934].
|
||||||
|
//
|
||||||
// A testing suite is usually built by first extending the built-in
|
// A testing suite is usually built by first extending the built-in
|
||||||
// suite functionality from suite.Suite in testify. Alternatively,
|
// suite functionality from suite.Suite in testify. Alternatively,
|
||||||
// you could reproduce that logic on your own if you wanted (you
|
// you could reproduce that logic on your own if you wanted (you
|
||||||
|
@ -63,4 +65,6 @@
|
||||||
// func TestExampleTestSuite(t *testing.T) {
|
// func TestExampleTestSuite(t *testing.T) {
|
||||||
// suite.Run(t, new(ExampleTestSuite))
|
// suite.Run(t, new(ExampleTestSuite))
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
|
// [issue 934]: https://github.com/stretchr/testify/issues/934
|
||||||
package suite
|
package suite
|
||||||
|
|
Loading…
Reference in New Issue