summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go')
-rw-r--r--Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go280
1 files changed, 169 insertions, 111 deletions
diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go b/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go
index fa8747e29..36de9e659 100644
--- a/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go
+++ b/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go
@@ -2,13 +2,15 @@ package mock
import (
"fmt"
- "github.com/stretchr/objx"
- "github.com/stretchr/testify/assert"
"reflect"
+ "regexp"
"runtime"
"strings"
"sync"
"time"
+
+ "github.com/mattermost/platform/Godeps/_workspace/src/github.com/stretchr/objx"
+ "github.com/mattermost/platform/Godeps/_workspace/src/github.com/stretchr/testify/assert"
)
// TestingT is an interface wrapper around *testing.T
@@ -24,6 +26,7 @@ type TestingT interface {
// Call represents a method call and is used for setting expectations,
// as well as recording activity.
type Call struct {
+ Parent *Mock
// The name of the method that was or will be called.
Method string
@@ -46,112 +49,79 @@ type Call struct {
// Holds a handler used to manipulate arguments content that are passed by
// reference. It's useful when mocking methods such as unmarshalers or
// decoders.
- Run func(Arguments)
+ RunFn func(Arguments)
}
-// 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 of this document.
-type Mock struct {
-
- // The method name that is currently
- // being referred to by the On method.
- onMethodName string
-
- // An array of the arguments that are
- // currently being referred to by the On method.
- onMethodArguments Arguments
-
- // Represents the calls that are expected of
- // an object.
- ExpectedCalls []Call
-
- // Holds the calls that were made to this mocked object.
- Calls []Call
-
- // TestData holds any data that might be useful for testing. Testify ignores
- // this data completely allowing you to do whatever you like with it.
- testData objx.Map
-
- mutex sync.Mutex
-}
-
-// TestData holds any data that might be useful for testing. Testify ignores
-// this data completely allowing you to do whatever you like with it.
-func (m *Mock) TestData() objx.Map {
-
- if m.testData == nil {
- m.testData = make(objx.Map)
+func newCall(parent *Mock, methodName string, methodArguments ...interface{}) *Call {
+ return &Call{
+ Parent: parent,
+ Method: methodName,
+ Arguments: methodArguments,
+ ReturnArguments: make([]interface{}, 0),
+ Repeatability: 0,
+ WaitFor: nil,
+ RunFn: nil,
}
-
- return m.testData
}
-/*
- Setting expectations
-*/
+func (self *Call) lock() {
+ self.Parent.mutex.Lock()
+}
-// On starts a description of an expectation of the specified method
-// being called.
-//
-// Mock.On("MyMethod", arg1, arg2)
-func (m *Mock) On(methodName string, arguments ...interface{}) *Mock {
- m.onMethodName = methodName
- m.onMethodArguments = arguments
+func (self *Call) unlock() {
+ self.Parent.mutex.Unlock()
+}
- for _, arg := range arguments {
- if v := reflect.ValueOf(arg); v.Kind() == reflect.Func {
- panic(fmt.Sprintf("cannot use Func in expectations. Use mock.AnythingOfType(\"%T\")", arg))
- }
- }
+func (self *Call) Return(returnArguments ...interface{}) *Call {
+ self.lock()
+ defer self.unlock()
- return m
-}
+ self.ReturnArguments = returnArguments
-// Return finishes a description of an expectation of the method (and arguments)
-// specified in the most recent On method call.
-//
-// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2)
-func (m *Mock) Return(returnArguments ...interface{}) *Mock {
- m.ExpectedCalls = append(m.ExpectedCalls, Call{m.onMethodName, m.onMethodArguments, returnArguments, 0, nil, nil})
- return m
+ return self
}
// Once indicates that that the mock should only return the value once.
//
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once()
-func (m *Mock) Once() {
- m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = 1
+func (self *Call) Once() *Call {
+ return self.Times(1)
}
// Twice indicates that that the mock should only return the value twice.
//
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice()
-func (m *Mock) Twice() {
- m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = 2
+func (self *Call) Twice() *Call {
+ return self.Times(2)
}
// Times indicates that that the mock should only return the indicated number
// of times.
//
// Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5)
-func (m *Mock) Times(i int) {
- m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = i
+func (self *Call) Times(i int) *Call {
+ self.lock()
+ defer self.unlock()
+ self.Repeatability = i
+ return self
}
// WaitUntil sets the channel that will block the mock's return until its closed
// or a message is received.
//
// Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second))
-func (m *Mock) WaitUntil(w <-chan time.Time) *Mock {
- m.ExpectedCalls[len(m.ExpectedCalls)-1].WaitFor = w
- return m
+func (self *Call) WaitUntil(w <-chan time.Time) *Call {
+ self.lock()
+ defer self.unlock()
+ self.WaitFor = w
+ return self
}
// After sets how long to block until the call returns
//
// Mock.On("MyMethod", arg1, arg2).After(time.Second)
-func (m *Mock) After(d time.Duration) *Mock {
- return m.WaitUntil(time.After(d))
+func (self *Call) After(d time.Duration) *Call {
+ return self.WaitUntil(time.After(d))
}
// Run sets a handler to be called before returning. It can be used when
@@ -162,22 +132,87 @@ func (m *Mock) After(d time.Duration) *Mock {
// arg := args.Get(0).(*map[string]interface{})
// arg["foo"] = "bar"
// })
-func (m *Mock) Run(fn func(Arguments)) *Mock {
- m.ExpectedCalls[len(m.ExpectedCalls)-1].Run = fn
- return m
+func (self *Call) Run(fn func(Arguments)) *Call {
+ self.lock()
+ defer self.unlock()
+ self.RunFn = fn
+ return self
+}
+
+// On chains a new expectation description onto the mocked interface. This
+// allows syntax like.
+//
+// Mock.
+// On("MyMethod", 1).Return(nil).
+// On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error"))
+func (self *Call) On(methodName string, arguments ...interface{}) *Call {
+ return self.Parent.On(methodName, arguments...)
+}
+
+// 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
+// of this document.
+type Mock struct {
+ // Represents the calls that are expected of
+ // an object.
+ ExpectedCalls []*Call
+
+ // Holds the calls that were made to this mocked object.
+ Calls []Call
+
+ // TestData holds any data that might be useful for testing. Testify ignores
+ // this data completely allowing you to do whatever you like with it.
+ testData objx.Map
+
+ mutex sync.Mutex
+}
+
+// TestData holds any data that might be useful for testing. Testify ignores
+// this data completely allowing you to do whatever you like with it.
+func (m *Mock) TestData() objx.Map {
+
+ if m.testData == nil {
+ m.testData = make(objx.Map)
+ }
+
+ return m.testData
}
/*
- Recording and responding to activity
+ Setting expectations
*/
+// On starts a description of an expectation of the specified method
+// being called.
+//
+// Mock.On("MyMethod", arg1, arg2)
+func (self *Mock) On(methodName string, arguments ...interface{}) *Call {
+ for _, arg := range arguments {
+ if v := reflect.ValueOf(arg); v.Kind() == reflect.Func {
+ panic(fmt.Sprintf("cannot use Func in expectations. Use mock.AnythingOfType(\"%T\")", arg))
+ }
+ }
+
+ self.mutex.Lock()
+ defer self.mutex.Unlock()
+ c := newCall(self, methodName, arguments...)
+ self.ExpectedCalls = append(self.ExpectedCalls, c)
+ return c
+}
+
+// /*
+// Recording and responding to activity
+// */
+
func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *Call) {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
for i, call := range m.ExpectedCalls {
if call.Method == method && call.Repeatability > -1 {
_, diffCount := call.Arguments.Diff(arguments)
if diffCount == 0 {
- return i, &call
+ return i, call
}
}
@@ -186,17 +221,16 @@ func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *
}
func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) {
-
diffCount := 0
var closestCall *Call = nil
- for _, call := range m.ExpectedCalls {
+ for _, call := range m.expectedCalls() {
if call.Method == method {
_, tempDiffCount := call.Arguments.Diff(arguments)
if tempDiffCount < diffCount || diffCount == 0 {
diffCount = tempDiffCount
- closestCall = &call
+ closestCall = call
}
}
@@ -215,7 +249,7 @@ func callString(method string, arguments Arguments, includeArgumentValues bool)
if includeArgumentValues {
var argVals []string
for argIndex, arg := range arguments {
- argVals = append(argVals, fmt.Sprintf("%d: %v", argIndex, arg))
+ argVals = append(argVals, fmt.Sprintf("%d: %#v", argIndex, arg))
}
argValsString = fmt.Sprintf("\n\t\t%s", strings.Join(argVals, "\n\t\t"))
}
@@ -228,22 +262,26 @@ func callString(method string, arguments Arguments, includeArgumentValues bool)
// appropriate .On .Return() calls)
// If Call.WaitFor is set, blocks until the channel is closed or receives a message.
func (m *Mock) Called(arguments ...interface{}) Arguments {
- defer m.mutex.Unlock()
- m.mutex.Lock()
-
// get the calling function's name
pc, _, _, ok := runtime.Caller(1)
if !ok {
panic("Couldn't get the caller information")
}
functionPath := runtime.FuncForPC(pc).Name()
+ //Next four lines are required to use GCCGO function naming conventions.
+ //For Ex: github_com_docker_libkv_store_mock.WatchTree.pN39_github_com_docker_libkv_store_mock.Mock
+ //uses inteface information unlike golang github.com/docker/libkv/store/mock.(*Mock).WatchTree
+ //With GCCGO we need to remove interface information starting from pN<dd>.
+ re := regexp.MustCompile("\\.pN\\d+_")
+ if re.MatchString(functionPath) {
+ functionPath = re.Split(functionPath, -1)[0]
+ }
parts := strings.Split(functionPath, ".")
functionName := parts[len(parts)-1]
found, call := m.findExpectedCall(functionName, arguments...)
- switch {
- case found < 0:
+ if found < 0 {
// we have to fail here - because we don't know what to do
// as the return arguments. This is because:
//
@@ -258,28 +296,33 @@ func (m *Mock) Called(arguments ...interface{}) 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", functionName, functionName, callString(functionName, arguments, true), assert.CallerInfo()))
}
- case call.Repeatability == 1:
- call.Repeatability = -1
- m.ExpectedCalls[found] = *call
- case call.Repeatability > 1:
- call.Repeatability -= 1
- m.ExpectedCalls[found] = *call
+ } else {
+ m.mutex.Lock()
+ switch {
+ case call.Repeatability == 1:
+ call.Repeatability = -1
+
+ case call.Repeatability > 1:
+ call.Repeatability -= 1
+ }
+ m.mutex.Unlock()
}
// add the call
- m.Calls = append(m.Calls, Call{functionName, arguments, make([]interface{}, 0), 0, nil, nil})
+ m.mutex.Lock()
+ m.Calls = append(m.Calls, *newCall(m, functionName, arguments...))
+ m.mutex.Unlock()
// block if specified
if call.WaitFor != nil {
<-call.WaitFor
}
- if call.Run != nil {
- call.Run(arguments)
+ if call.RunFn != nil {
+ call.RunFn(arguments)
}
return call.ReturnArguments
-
}
/*
@@ -302,27 +345,30 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
// AssertExpectations asserts that everything specified with On and Return was
// in fact called as expected. Calls may have occurred in any order.
func (m *Mock) AssertExpectations(t TestingT) bool {
-
var somethingMissing bool = false
var failedExpectations int = 0
// iterate through each expectation
- for _, expectedCall := range m.ExpectedCalls {
- switch {
- case !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments):
+ expectedCalls := m.expectedCalls()
+ for _, expectedCall := range expectedCalls {
+ if !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) {
somethingMissing = true
failedExpectations++
t.Logf("\u274C\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
- case expectedCall.Repeatability > 0:
- somethingMissing = true
- failedExpectations++
- default:
- t.Logf("\u2705\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
+ } else {
+ m.mutex.Lock()
+ if expectedCall.Repeatability > 0 {
+ somethingMissing = true
+ failedExpectations++
+ } else {
+ t.Logf("\u2705\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
+ }
+ m.mutex.Unlock()
}
}
if somethingMissing {
- t.Errorf("FAIL: %d out of %d expectation(s) were met.\n\tThe code you are testing needs to make %d more call(s).\n\tat: %s", len(m.ExpectedCalls)-failedExpectations, len(m.ExpectedCalls), failedExpectations, assert.CallerInfo())
+ t.Errorf("FAIL: %d out of %d expectation(s) were met.\n\tThe code you are testing needs to make %d more call(s).\n\tat: %s", len(expectedCalls)-failedExpectations, len(expectedCalls), failedExpectations, assert.CallerInfo())
}
return !somethingMissing
@@ -331,18 +377,18 @@ func (m *Mock) AssertExpectations(t TestingT) bool {
// AssertNumberOfCalls asserts that the method was called expectedCalls times.
func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls int) bool {
var actualCalls int = 0
- for _, call := range m.Calls {
+ for _, call := range m.calls() {
if call.Method == methodName {
actualCalls++
}
}
- return assert.Equal(t, actualCalls, expectedCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls))
+ return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls))
}
// AssertCalled asserts that the method was called.
func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool {
if !assert.True(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method should have been called with %d argument(s), but was not.", methodName, len(arguments))) {
- t.Logf("%v", m.ExpectedCalls)
+ t.Logf("%v", m.expectedCalls())
return false
}
return true
@@ -351,14 +397,14 @@ func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interfac
// AssertNotCalled asserts that the method was not called.
func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool {
if !assert.False(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method was called with %d argument(s), but should NOT have been.", methodName, len(arguments))) {
- t.Logf("%v", m.ExpectedCalls)
+ t.Logf("%v", m.expectedCalls())
return false
}
return true
}
func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool {
- for _, call := range m.Calls {
+ for _, call := range m.calls() {
if call.Method == methodName {
_, differences := Arguments(expected).Diff(call.Arguments)
@@ -374,6 +420,18 @@ func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool {
return false
}
+func (m *Mock) expectedCalls() []*Call {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ return append([]*Call{}, m.ExpectedCalls...)
+}
+
+func (m *Mock) calls() []Call {
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ return append([]Call{}, m.Calls...)
+}
+
/*
Arguments
*/