vendor: update all dependencies to latest versions
This commit is contained in:
+62
-24
@@ -1,6 +1,7 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
@@ -48,10 +49,15 @@ type Call struct {
|
||||
// Amount of times this call has been called
|
||||
totalCalls int
|
||||
|
||||
// Call to this method can be optional
|
||||
optional bool
|
||||
|
||||
// Holds a channel that will be used to block the Return until it either
|
||||
// receives a message or is closed. nil means it returns immediately.
|
||||
WaitFor <-chan time.Time
|
||||
|
||||
waitTime time.Duration
|
||||
|
||||
// Holds a handler used to manipulate arguments content that are passed by
|
||||
// reference. It's useful when mocking methods such as unmarshalers or
|
||||
// decoders.
|
||||
@@ -130,7 +136,10 @@ func (c *Call) WaitUntil(w <-chan time.Time) *Call {
|
||||
//
|
||||
// Mock.On("MyMethod", arg1, arg2).After(time.Second)
|
||||
func (c *Call) After(d time.Duration) *Call {
|
||||
return c.WaitUntil(time.After(d))
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
c.waitTime = d
|
||||
return c
|
||||
}
|
||||
|
||||
// Run sets a handler to be called before returning. It can be used when
|
||||
@@ -148,6 +157,15 @@ func (c *Call) Run(fn func(args Arguments)) *Call {
|
||||
return c
|
||||
}
|
||||
|
||||
// Maybe allows the method call to be optional. Not calling an optional method
|
||||
// will not cause an error while asserting expectations
|
||||
func (c *Call) Maybe() *Call {
|
||||
c.lock()
|
||||
defer c.unlock()
|
||||
c.optional = true
|
||||
return c
|
||||
}
|
||||
|
||||
// On chains a new expectation description onto the mocked interface. This
|
||||
// allows syntax like.
|
||||
//
|
||||
@@ -308,24 +326,18 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen
|
||||
m.mutex.Unlock()
|
||||
|
||||
if closestFound {
|
||||
panic(fmt.Sprintf("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\n", callString(methodName, arguments, true), callString(methodName, closestCall.Arguments, true), diffArguments(arguments, closestCall.Arguments)))
|
||||
panic(fmt.Sprintf("\n\nmock: Unexpected Method Call\n-----------------------------\n\n%s\n\nThe closest call I have is: \n\n%s\n\n%s\n", callString(methodName, arguments, true), callString(methodName, closestCall.Arguments, true), diffArguments(closestCall.Arguments, arguments)))
|
||||
} else {
|
||||
panic(fmt.Sprintf("\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()))
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case call.Repeatability == 1:
|
||||
if call.Repeatability == 1 {
|
||||
call.Repeatability = -1
|
||||
call.totalCalls++
|
||||
|
||||
case call.Repeatability > 1:
|
||||
} else if call.Repeatability > 1 {
|
||||
call.Repeatability--
|
||||
call.totalCalls++
|
||||
|
||||
case call.Repeatability == 0:
|
||||
call.totalCalls++
|
||||
}
|
||||
call.totalCalls++
|
||||
|
||||
// add the call
|
||||
m.Calls = append(m.Calls, *newCall(m, methodName, arguments...))
|
||||
@@ -334,13 +346,23 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen
|
||||
// block if specified
|
||||
if call.WaitFor != nil {
|
||||
<-call.WaitFor
|
||||
} else {
|
||||
time.Sleep(call.waitTime)
|
||||
}
|
||||
|
||||
if call.RunFn != nil {
|
||||
call.RunFn(arguments)
|
||||
m.mutex.Lock()
|
||||
runFn := call.RunFn
|
||||
m.mutex.Unlock()
|
||||
|
||||
if runFn != nil {
|
||||
runFn(arguments)
|
||||
}
|
||||
|
||||
return call.ReturnArguments
|
||||
m.mutex.Lock()
|
||||
returnArgs := call.ReturnArguments
|
||||
m.mutex.Unlock()
|
||||
|
||||
return returnArgs
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -380,16 +402,16 @@ func (m *Mock) AssertExpectations(t TestingT) bool {
|
||||
// iterate through each expectation
|
||||
expectedCalls := m.expectedCalls()
|
||||
for _, expectedCall := range expectedCalls {
|
||||
if !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) && expectedCall.totalCalls == 0 {
|
||||
if !expectedCall.optional && !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) && expectedCall.totalCalls == 0 {
|
||||
somethingMissing = true
|
||||
failedExpectations++
|
||||
t.Logf("\u274C\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
|
||||
t.Logf("FAIL:\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
|
||||
} else {
|
||||
if expectedCall.Repeatability > 0 {
|
||||
somethingMissing = true
|
||||
failedExpectations++
|
||||
} else {
|
||||
t.Logf("\u2705\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
|
||||
t.Logf("PASS:\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -498,9 +520,25 @@ type argumentMatcher struct {
|
||||
|
||||
func (f argumentMatcher) Matches(argument interface{}) bool {
|
||||
expectType := f.fn.Type().In(0)
|
||||
expectTypeNilSupported := false
|
||||
switch expectType.Kind() {
|
||||
case reflect.Interface, reflect.Chan, reflect.Func, reflect.Map, reflect.Slice, reflect.Ptr:
|
||||
expectTypeNilSupported = true
|
||||
}
|
||||
|
||||
if reflect.TypeOf(argument).AssignableTo(expectType) {
|
||||
result := f.fn.Call([]reflect.Value{reflect.ValueOf(argument)})
|
||||
argType := reflect.TypeOf(argument)
|
||||
var arg reflect.Value
|
||||
if argType == nil {
|
||||
arg = reflect.New(expectType).Elem()
|
||||
} else {
|
||||
arg = reflect.ValueOf(argument)
|
||||
}
|
||||
|
||||
if argType == nil && !expectTypeNilSupported {
|
||||
panic(errors.New("attempting to call matcher with nil for non-nil expected type"))
|
||||
}
|
||||
if argType == nil || argType.AssignableTo(expectType) {
|
||||
result := f.fn.Call([]reflect.Value{arg})
|
||||
return result[0].Bool()
|
||||
}
|
||||
return false
|
||||
@@ -586,10 +624,10 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
|
||||
|
||||
if matcher, ok := expected.(argumentMatcher); ok {
|
||||
if matcher.Matches(actual) {
|
||||
output = fmt.Sprintf("%s\t%d: \u2705 %s matched by %s\n", output, i, actual, matcher)
|
||||
output = fmt.Sprintf("%s\t%d: PASS: %s matched by %s\n", output, i, actual, matcher)
|
||||
} else {
|
||||
differences++
|
||||
output = fmt.Sprintf("%s\t%d: \u2705 %s not matched by %s\n", output, i, actual, matcher)
|
||||
output = fmt.Sprintf("%s\t%d: PASS: %s not matched by %s\n", output, i, actual, matcher)
|
||||
}
|
||||
} else if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() {
|
||||
|
||||
@@ -597,7 +635,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
|
||||
if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) {
|
||||
// not match
|
||||
differences++
|
||||
output = fmt.Sprintf("%s\t%d: \u274C type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actual)
|
||||
output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actual)
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -606,11 +644,11 @@ func (args Arguments) Diff(objects []interface{}) (string, int) {
|
||||
|
||||
if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
|
||||
// match
|
||||
output = fmt.Sprintf("%s\t%d: \u2705 %s == %s\n", output, i, actual, expected)
|
||||
output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, actual, expected)
|
||||
} else {
|
||||
// not match
|
||||
differences++
|
||||
output = fmt.Sprintf("%s\t%d: \u274C %s != %s\n", output, i, actual, expected)
|
||||
output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+159
-4
@@ -2,6 +2,8 @@ package mock
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -41,6 +43,26 @@ func (i *TestExampleImplementation) TheExampleMethod3(et *ExampleType) error {
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethod4(v ExampleInterface) error {
|
||||
args := i.Called(v)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethod5(ch chan struct{}) error {
|
||||
args := i.Called(ch)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethod6(m map[string]bool) error {
|
||||
args := i.Called(m)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethod7(slice []bool) error {
|
||||
args := i.Called(slice)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (i *TestExampleImplementation) TheExampleMethodFunc(fn func(string) error) error {
|
||||
args := i.Called(fn)
|
||||
return args.Error(0)
|
||||
@@ -180,15 +202,20 @@ func Test_Mock_On_WithPtrArgMatcher(t *testing.T) {
|
||||
var mockedService TestExampleImplementation
|
||||
|
||||
mockedService.On("TheExampleMethod3",
|
||||
MatchedBy(func(a *ExampleType) bool { return a.ran == true }),
|
||||
MatchedBy(func(a *ExampleType) bool { return a != nil && a.ran == true }),
|
||||
).Return(nil)
|
||||
|
||||
mockedService.On("TheExampleMethod3",
|
||||
MatchedBy(func(a *ExampleType) bool { return a.ran == false }),
|
||||
MatchedBy(func(a *ExampleType) bool { return a != nil && a.ran == false }),
|
||||
).Return(errors.New("error"))
|
||||
|
||||
mockedService.On("TheExampleMethod3",
|
||||
MatchedBy(func(a *ExampleType) bool { return a == nil }),
|
||||
).Return(errors.New("error2"))
|
||||
|
||||
assert.Equal(t, mockedService.TheExampleMethod3(&ExampleType{true}), nil)
|
||||
assert.EqualError(t, mockedService.TheExampleMethod3(&ExampleType{false}), "error")
|
||||
assert.EqualError(t, mockedService.TheExampleMethod3(nil), "error2")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithFuncArgMatcher(t *testing.T) {
|
||||
@@ -197,17 +224,62 @@ func Test_Mock_On_WithFuncArgMatcher(t *testing.T) {
|
||||
fixture1, fixture2 := errors.New("fixture1"), errors.New("fixture2")
|
||||
|
||||
mockedService.On("TheExampleMethodFunc",
|
||||
MatchedBy(func(a func(string) error) bool { return a("string") == fixture1 }),
|
||||
MatchedBy(func(a func(string) error) bool { return a != nil && a("string") == fixture1 }),
|
||||
).Return(errors.New("fixture1"))
|
||||
|
||||
mockedService.On("TheExampleMethodFunc",
|
||||
MatchedBy(func(a func(string) error) bool { return a("string") == fixture2 }),
|
||||
MatchedBy(func(a func(string) error) bool { return a != nil && a("string") == fixture2 }),
|
||||
).Return(errors.New("fixture2"))
|
||||
|
||||
mockedService.On("TheExampleMethodFunc",
|
||||
MatchedBy(func(a func(string) error) bool { return a == nil }),
|
||||
).Return(errors.New("fixture3"))
|
||||
|
||||
assert.EqualError(t, mockedService.TheExampleMethodFunc(
|
||||
func(string) error { return fixture1 }), "fixture1")
|
||||
assert.EqualError(t, mockedService.TheExampleMethodFunc(
|
||||
func(string) error { return fixture2 }), "fixture2")
|
||||
assert.EqualError(t, mockedService.TheExampleMethodFunc(nil), "fixture3")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithInterfaceArgMatcher(t *testing.T) {
|
||||
var mockedService TestExampleImplementation
|
||||
|
||||
mockedService.On("TheExampleMethod4",
|
||||
MatchedBy(func(a ExampleInterface) bool { return a == nil }),
|
||||
).Return(errors.New("fixture1"))
|
||||
|
||||
assert.EqualError(t, mockedService.TheExampleMethod4(nil), "fixture1")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithChannelArgMatcher(t *testing.T) {
|
||||
var mockedService TestExampleImplementation
|
||||
|
||||
mockedService.On("TheExampleMethod5",
|
||||
MatchedBy(func(ch chan struct{}) bool { return ch == nil }),
|
||||
).Return(errors.New("fixture1"))
|
||||
|
||||
assert.EqualError(t, mockedService.TheExampleMethod5(nil), "fixture1")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithMapArgMatcher(t *testing.T) {
|
||||
var mockedService TestExampleImplementation
|
||||
|
||||
mockedService.On("TheExampleMethod6",
|
||||
MatchedBy(func(m map[string]bool) bool { return m == nil }),
|
||||
).Return(errors.New("fixture1"))
|
||||
|
||||
assert.EqualError(t, mockedService.TheExampleMethod6(nil), "fixture1")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithSliceArgMatcher(t *testing.T) {
|
||||
var mockedService TestExampleImplementation
|
||||
|
||||
mockedService.On("TheExampleMethod7",
|
||||
MatchedBy(func(slice []bool) bool { return slice == nil }),
|
||||
).Return(errors.New("fixture1"))
|
||||
|
||||
assert.EqualError(t, mockedService.TheExampleMethod7(nil), "fixture1")
|
||||
}
|
||||
|
||||
func Test_Mock_On_WithVariadicFunc(t *testing.T) {
|
||||
@@ -998,6 +1070,31 @@ func Test_Mock_AssertNotCalled(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func Test_Mock_AssertOptional(t *testing.T) {
|
||||
// Optional called
|
||||
var ms1 = new(TestExampleImplementation)
|
||||
ms1.On("TheExampleMethod", 1, 2, 3).Maybe().Return(4, nil)
|
||||
ms1.TheExampleMethod(1, 2, 3)
|
||||
|
||||
tt1 := new(testing.T)
|
||||
assert.Equal(t, true, ms1.AssertExpectations(tt1))
|
||||
|
||||
// Optional not called
|
||||
var ms2 = new(TestExampleImplementation)
|
||||
ms2.On("TheExampleMethod", 1, 2, 3).Maybe().Return(4, nil)
|
||||
|
||||
tt2 := new(testing.T)
|
||||
assert.Equal(t, true, ms2.AssertExpectations(tt2))
|
||||
|
||||
// Non-optional called
|
||||
var ms3 = new(TestExampleImplementation)
|
||||
ms3.On("TheExampleMethod", 1, 2, 3).Return(4, nil)
|
||||
ms3.TheExampleMethod(1, 2, 3)
|
||||
|
||||
tt3 := new(testing.T)
|
||||
assert.Equal(t, true, ms3.AssertExpectations(tt3))
|
||||
}
|
||||
|
||||
/*
|
||||
Arguments helper methods
|
||||
*/
|
||||
@@ -1195,3 +1292,61 @@ func Test_MockMethodCalled(t *testing.T) {
|
||||
require.Equal(t, "world", retArgs[0])
|
||||
m.AssertExpectations(t)
|
||||
}
|
||||
|
||||
// Test to validate fix for racy concurrent call access in MethodCalled()
|
||||
func Test_MockReturnAndCalledConcurrent(t *testing.T) {
|
||||
iterations := 1000
|
||||
m := &Mock{}
|
||||
call := m.On("ConcurrencyTestMethod")
|
||||
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
go func() {
|
||||
for i := 0; i < iterations; i++ {
|
||||
call.Return(10)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
for i := 0; i < iterations; i++ {
|
||||
ConcurrencyTestMethod(m)
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
type timer struct{ Mock }
|
||||
|
||||
func (s *timer) GetTime(i int) string {
|
||||
return s.Called(i).Get(0).(string)
|
||||
}
|
||||
|
||||
func TestAfterTotalWaitTimeWhileExecution(t *testing.T) {
|
||||
waitDuration := 1
|
||||
total, waitMs := 5, time.Millisecond*time.Duration(waitDuration)
|
||||
aTimer := new(timer)
|
||||
for i := 0; i < total; i++ {
|
||||
aTimer.On("GetTime", i).After(waitMs).Return(fmt.Sprintf("Time%d", i)).Once()
|
||||
}
|
||||
time.Sleep(waitMs)
|
||||
start := time.Now()
|
||||
var results []string
|
||||
|
||||
for i := 0; i < total; i++ {
|
||||
results = append(results, aTimer.GetTime(i))
|
||||
}
|
||||
|
||||
end := time.Now()
|
||||
elapsedTime := end.Sub(start)
|
||||
assert.True(t, elapsedTime > waitMs, fmt.Sprintf("Total elapsed time:%v should be atleast greater than %v", elapsedTime, waitMs))
|
||||
assert.Equal(t, total, len(results))
|
||||
for i, _ := range results {
|
||||
assert.Equal(t, fmt.Sprintf("Time%d", i), results[i], "Return value of method should be same")
|
||||
}
|
||||
}
|
||||
|
||||
func ConcurrencyTestMethod(m *Mock) {
|
||||
m.Called()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user