func (m *Mock) Called(arguments ...interface{}) Arguments {
	pc, _, _, ok := runtime.Caller(1)
	if !ok {
		panic("Couldn't get the caller information")
	}
	functionPath := runtime.FuncForPC(pc).Name()
	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...)
	if found < 0 {
		closestFound, closestCall := m.findClosestCall(functionName, arguments...)
		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", callString(functionName, arguments, true), callString(functionName, closestCall.Arguments, true)))
		} 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()))
		}
	} else {
		m.mutex.Lock()
		switch {
		case call.Repeatability == 1:
			call.Repeatability = -1
		case call.Repeatability > 1:
			call.Repeatability--
		}
		m.mutex.Unlock()
	}
	m.mutex.Lock()
	m.Calls = append(m.Calls, *newCall(m, functionName, arguments...))
	m.mutex.Unlock()
	if call.WaitFor != nil {
		<-call.WaitFor
	}
	if call.RunFn != nil {
		call.RunFn(arguments)
	}
	return call.ReturnArguments
}
Called tells the mock object that a method has been called, and gets an array
of arguments to return.  Panics if the call is unexpected (i.e. not preceeded by
appropriate .On .Return() calls)
If Call.WaitFor is set, blocks until the channel is closed or receives a message.
package mock
import (
	"fmt"
	"reflect"
	"regexp"
	"runtime"
	"strings"
	"sync"
	"time"
	"github.com/stretchr/objx"
	"github.com/stretchr/testify/assert"
)
type TestingT interface {
	Logf(format string, args ...interface{})
	Errorf(format string, args ...interface{})
	FailNow()
}
type Call struct {
	Parent *Mock
	Method string
	Arguments Arguments
	ReturnArguments Arguments
	Repeatability int
	WaitFor <-chan time.Time
	RunFn func(Arguments)
}
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,
	}
}
func (c *Call) lock() {
	c.Parent.mutex.Lock()
}
func (c *Call) unlock() {
	c.Parent.mutex.Unlock()
}
func (c *Call) Return(returnArguments ...interface{}) *Call {
	c.lock()
	defer c.unlock()
	c.ReturnArguments = returnArguments
	return c
}
func (c *Call) Once() *Call {
	return c.Times(1)
}
func (c *Call) Twice() *Call {
	return c.Times(2)
}
func (c *Call) Times(i int) *Call {
	c.lock()
	defer c.unlock()
	c.Repeatability = i
	return c
}
func (c *Call) WaitUntil(w <-chan time.Time) *Call {
	c.lock()
	defer c.unlock()
	c.WaitFor = w
	return c
}
func (c *Call) After(d time.Duration) *Call {
	return c.WaitUntil(time.After(d))
}
func (c *Call) Run(fn func(Arguments)) *Call {
	c.lock()
	defer c.unlock()
	c.RunFn = fn
	return c
}
func (c *Call) On(methodName string, arguments ...interface{}) *Call {
	return c.Parent.On(methodName, arguments...)
}
type Mock struct {
	ExpectedCalls []*Call
	Calls []Call
	testData objx.Map
	mutex sync.Mutex
}
func (m *Mock) TestData() objx.Map {
	if m.testData == nil {
		m.testData = make(objx.Map)
	}
	return m.testData
}
func (m *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))
		}
	}
	m.mutex.Lock()
	defer m.mutex.Unlock()
	c := newCall(m, methodName, arguments...)
	m.ExpectedCalls = append(m.ExpectedCalls, c)
	return c
}
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 -1, nil
}
func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) {
	diffCount := 0
	var closestCall *Call
	for _, call := range m.expectedCalls() {
		if call.Method == method {
			_, tempDiffCount := call.Arguments.Diff(arguments)
			if tempDiffCount < diffCount || diffCount == 0 {
				diffCount = tempDiffCount
				closestCall = call
			}
		}
	}
	if closestCall == nil {
		return false, nil
	}
	return true, closestCall
}
func callString(method string, arguments Arguments, includeArgumentValues bool) string {
	var argValsString string
	if includeArgumentValues {
		var argVals []string
		for argIndex, arg := range arguments {
			argVals = append(argVals, fmt.Sprintf("%d: %#v", argIndex, arg))
		}
		argValsString = fmt.Sprintf("\n\t\t%s", strings.Join(argVals, "\n\t\t"))
	}
	return fmt.Sprintf("%s(%s)%s", method, arguments.String(), argValsString)
}