mock.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. package mock
  2. import (
  3. "errors"
  4. "fmt"
  5. "reflect"
  6. "regexp"
  7. "runtime"
  8. "strings"
  9. "sync"
  10. "time"
  11. "github.com/davecgh/go-spew/spew"
  12. "github.com/pmezard/go-difflib/difflib"
  13. "github.com/stretchr/objx"
  14. "github.com/stretchr/testify/assert"
  15. )
  16. // TestingT is an interface wrapper around *testing.T
  17. type TestingT interface {
  18. Logf(format string, args ...interface{})
  19. Errorf(format string, args ...interface{})
  20. FailNow()
  21. }
  22. /*
  23. Call
  24. */
  25. // Call represents a method call and is used for setting expectations,
  26. // as well as recording activity.
  27. type Call struct {
  28. Parent *Mock
  29. // The name of the method that was or will be called.
  30. Method string
  31. // Holds the arguments of the method.
  32. Arguments Arguments
  33. // Holds the arguments that should be returned when
  34. // this method is called.
  35. ReturnArguments Arguments
  36. // The number of times to return the return arguments when setting
  37. // expectations. 0 means to always return the value.
  38. Repeatability int
  39. // Amount of times this call has been called
  40. totalCalls int
  41. // Call to this method can be optional
  42. optional bool
  43. // Holds a channel that will be used to block the Return until it either
  44. // receives a message or is closed. nil means it returns immediately.
  45. WaitFor <-chan time.Time
  46. waitTime time.Duration
  47. // Holds a handler used to manipulate arguments content that are passed by
  48. // reference. It's useful when mocking methods such as unmarshalers or
  49. // decoders.
  50. RunFn func(Arguments)
  51. }
  52. func newCall(parent *Mock, methodName string, methodArguments ...interface{}) *Call {
  53. return &Call{
  54. Parent: parent,
  55. Method: methodName,
  56. Arguments: methodArguments,
  57. ReturnArguments: make([]interface{}, 0),
  58. Repeatability: 0,
  59. WaitFor: nil,
  60. RunFn: nil,
  61. }
  62. }
  63. func (c *Call) lock() {
  64. c.Parent.mutex.Lock()
  65. }
  66. func (c *Call) unlock() {
  67. c.Parent.mutex.Unlock()
  68. }
  69. // Return specifies the return arguments for the expectation.
  70. //
  71. // Mock.On("DoSomething").Return(errors.New("failed"))
  72. func (c *Call) Return(returnArguments ...interface{}) *Call {
  73. c.lock()
  74. defer c.unlock()
  75. c.ReturnArguments = returnArguments
  76. return c
  77. }
  78. // Once indicates that that the mock should only return the value once.
  79. //
  80. // Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Once()
  81. func (c *Call) Once() *Call {
  82. return c.Times(1)
  83. }
  84. // Twice indicates that that the mock should only return the value twice.
  85. //
  86. // Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Twice()
  87. func (c *Call) Twice() *Call {
  88. return c.Times(2)
  89. }
  90. // Times indicates that that the mock should only return the indicated number
  91. // of times.
  92. //
  93. // Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2).Times(5)
  94. func (c *Call) Times(i int) *Call {
  95. c.lock()
  96. defer c.unlock()
  97. c.Repeatability = i
  98. return c
  99. }
  100. // WaitUntil sets the channel that will block the mock's return until its closed
  101. // or a message is received.
  102. //
  103. // Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second))
  104. func (c *Call) WaitUntil(w <-chan time.Time) *Call {
  105. c.lock()
  106. defer c.unlock()
  107. c.WaitFor = w
  108. return c
  109. }
  110. // After sets how long to block until the call returns
  111. //
  112. // Mock.On("MyMethod", arg1, arg2).After(time.Second)
  113. func (c *Call) After(d time.Duration) *Call {
  114. c.lock()
  115. defer c.unlock()
  116. c.waitTime = d
  117. return c
  118. }
  119. // Run sets a handler to be called before returning. It can be used when
  120. // mocking a method such as unmarshalers that takes a pointer to a struct and
  121. // sets properties in such struct
  122. //
  123. // Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}").Return().Run(func(args Arguments) {
  124. // arg := args.Get(0).(*map[string]interface{})
  125. // arg["foo"] = "bar"
  126. // })
  127. func (c *Call) Run(fn func(args Arguments)) *Call {
  128. c.lock()
  129. defer c.unlock()
  130. c.RunFn = fn
  131. return c
  132. }
  133. // Maybe allows the method call to be optional. Not calling an optional method
  134. // will not cause an error while asserting expectations
  135. func (c *Call) Maybe() *Call {
  136. c.lock()
  137. defer c.unlock()
  138. c.optional = true
  139. return c
  140. }
  141. // On chains a new expectation description onto the mocked interface. This
  142. // allows syntax like.
  143. //
  144. // Mock.
  145. // On("MyMethod", 1).Return(nil).
  146. // On("MyOtherMethod", 'a', 'b', 'c').Return(errors.New("Some Error"))
  147. func (c *Call) On(methodName string, arguments ...interface{}) *Call {
  148. return c.Parent.On(methodName, arguments...)
  149. }
  150. // Mock is the workhorse used to track activity on another object.
  151. // For an example of its usage, refer to the "Example Usage" section at the top
  152. // of this document.
  153. type Mock struct {
  154. // Represents the calls that are expected of
  155. // an object.
  156. ExpectedCalls []*Call
  157. // Holds the calls that were made to this mocked object.
  158. Calls []Call
  159. // TestData holds any data that might be useful for testing. Testify ignores
  160. // this data completely allowing you to do whatever you like with it.
  161. testData objx.Map
  162. mutex sync.Mutex
  163. }
  164. // TestData holds any data that might be useful for testing. Testify ignores
  165. // this data completely allowing you to do whatever you like with it.
  166. func (m *Mock) TestData() objx.Map {
  167. if m.testData == nil {
  168. m.testData = make(objx.Map)
  169. }
  170. return m.testData
  171. }
  172. /*
  173. Setting expectations
  174. */
  175. // On starts a description of an expectation of the specified method
  176. // being called.
  177. //
  178. // Mock.On("MyMethod", arg1, arg2)
  179. func (m *Mock) On(methodName string, arguments ...interface{}) *Call {
  180. for _, arg := range arguments {
  181. if v := reflect.ValueOf(arg); v.Kind() == reflect.Func {
  182. panic(fmt.Sprintf("cannot use Func in expectations. Use mock.AnythingOfType(\"%T\")", arg))
  183. }
  184. }
  185. m.mutex.Lock()
  186. defer m.mutex.Unlock()
  187. c := newCall(m, methodName, arguments...)
  188. m.ExpectedCalls = append(m.ExpectedCalls, c)
  189. return c
  190. }
  191. // /*
  192. // Recording and responding to activity
  193. // */
  194. func (m *Mock) findExpectedCall(method string, arguments ...interface{}) (int, *Call) {
  195. for i, call := range m.ExpectedCalls {
  196. if call.Method == method && call.Repeatability > -1 {
  197. _, diffCount := call.Arguments.Diff(arguments)
  198. if diffCount == 0 {
  199. return i, call
  200. }
  201. }
  202. }
  203. return -1, nil
  204. }
  205. func (m *Mock) findClosestCall(method string, arguments ...interface{}) (bool, *Call) {
  206. diffCount := 0
  207. var closestCall *Call
  208. for _, call := range m.expectedCalls() {
  209. if call.Method == method {
  210. _, tempDiffCount := call.Arguments.Diff(arguments)
  211. if tempDiffCount < diffCount || diffCount == 0 {
  212. diffCount = tempDiffCount
  213. closestCall = call
  214. }
  215. }
  216. }
  217. if closestCall == nil {
  218. return false, nil
  219. }
  220. return true, closestCall
  221. }
  222. func callString(method string, arguments Arguments, includeArgumentValues bool) string {
  223. var argValsString string
  224. if includeArgumentValues {
  225. var argVals []string
  226. for argIndex, arg := range arguments {
  227. argVals = append(argVals, fmt.Sprintf("%d: %#v", argIndex, arg))
  228. }
  229. argValsString = fmt.Sprintf("\n\t\t%s", strings.Join(argVals, "\n\t\t"))
  230. }
  231. return fmt.Sprintf("%s(%s)%s", method, arguments.String(), argValsString)
  232. }
  233. // Called tells the mock object that a method has been called, and gets an array
  234. // of arguments to return. Panics if the call is unexpected (i.e. not preceded by
  235. // appropriate .On .Return() calls)
  236. // If Call.WaitFor is set, blocks until the channel is closed or receives a message.
  237. func (m *Mock) Called(arguments ...interface{}) Arguments {
  238. // get the calling function's name
  239. pc, _, _, ok := runtime.Caller(1)
  240. if !ok {
  241. panic("Couldn't get the caller information")
  242. }
  243. functionPath := runtime.FuncForPC(pc).Name()
  244. //Next four lines are required to use GCCGO function naming conventions.
  245. //For Ex: github_com_docker_libkv_store_mock.WatchTree.pN39_github_com_docker_libkv_store_mock.Mock
  246. //uses interface information unlike golang github.com/docker/libkv/store/mock.(*Mock).WatchTree
  247. //With GCCGO we need to remove interface information starting from pN<dd>.
  248. re := regexp.MustCompile("\\.pN\\d+_")
  249. if re.MatchString(functionPath) {
  250. functionPath = re.Split(functionPath, -1)[0]
  251. }
  252. parts := strings.Split(functionPath, ".")
  253. functionName := parts[len(parts)-1]
  254. return m.MethodCalled(functionName, arguments...)
  255. }
  256. // MethodCalled tells the mock object that the given method has been called, and gets
  257. // an array of arguments to return. Panics if the call is unexpected (i.e. not preceded
  258. // by appropriate .On .Return() calls)
  259. // If Call.WaitFor is set, blocks until the channel is closed or receives a message.
  260. func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments {
  261. m.mutex.Lock()
  262. found, call := m.findExpectedCall(methodName, arguments...)
  263. if found < 0 {
  264. // we have to fail here - because we don't know what to do
  265. // as the return arguments. This is because:
  266. //
  267. // a) this is a totally unexpected call to this method,
  268. // b) the arguments are not what was expected, or
  269. // c) the developer has forgotten to add an accompanying On...Return pair.
  270. closestFound, closestCall := m.findClosestCall(methodName, arguments...)
  271. m.mutex.Unlock()
  272. if closestFound {
  273. 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)))
  274. } else {
  275. 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()))
  276. }
  277. }
  278. if call.Repeatability == 1 {
  279. call.Repeatability = -1
  280. } else if call.Repeatability > 1 {
  281. call.Repeatability--
  282. }
  283. call.totalCalls++
  284. // add the call
  285. m.Calls = append(m.Calls, *newCall(m, methodName, arguments...))
  286. m.mutex.Unlock()
  287. // block if specified
  288. if call.WaitFor != nil {
  289. <-call.WaitFor
  290. } else {
  291. time.Sleep(call.waitTime)
  292. }
  293. m.mutex.Lock()
  294. runFn := call.RunFn
  295. m.mutex.Unlock()
  296. if runFn != nil {
  297. runFn(arguments)
  298. }
  299. m.mutex.Lock()
  300. returnArgs := call.ReturnArguments
  301. m.mutex.Unlock()
  302. return returnArgs
  303. }
  304. /*
  305. Assertions
  306. */
  307. type assertExpectationser interface {
  308. AssertExpectations(TestingT) bool
  309. }
  310. // AssertExpectationsForObjects asserts that everything specified with On and Return
  311. // of the specified objects was in fact called as expected.
  312. //
  313. // Calls may have occurred in any order.
  314. func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool {
  315. for _, obj := range testObjects {
  316. if m, ok := obj.(Mock); ok {
  317. t.Logf("Deprecated mock.AssertExpectationsForObjects(myMock.Mock) use mock.AssertExpectationsForObjects(myMock)")
  318. obj = &m
  319. }
  320. m := obj.(assertExpectationser)
  321. if !m.AssertExpectations(t) {
  322. return false
  323. }
  324. }
  325. return true
  326. }
  327. // AssertExpectations asserts that everything specified with On and Return was
  328. // in fact called as expected. Calls may have occurred in any order.
  329. func (m *Mock) AssertExpectations(t TestingT) bool {
  330. m.mutex.Lock()
  331. defer m.mutex.Unlock()
  332. var somethingMissing bool
  333. var failedExpectations int
  334. // iterate through each expectation
  335. expectedCalls := m.expectedCalls()
  336. for _, expectedCall := range expectedCalls {
  337. if !expectedCall.optional && !m.methodWasCalled(expectedCall.Method, expectedCall.Arguments) && expectedCall.totalCalls == 0 {
  338. somethingMissing = true
  339. failedExpectations++
  340. t.Logf("FAIL:\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
  341. } else {
  342. if expectedCall.Repeatability > 0 {
  343. somethingMissing = true
  344. failedExpectations++
  345. t.Logf("FAIL:\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
  346. } else {
  347. t.Logf("PASS:\t%s(%s)", expectedCall.Method, expectedCall.Arguments.String())
  348. }
  349. }
  350. }
  351. if somethingMissing {
  352. 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())
  353. }
  354. return !somethingMissing
  355. }
  356. // AssertNumberOfCalls asserts that the method was called expectedCalls times.
  357. func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls int) bool {
  358. m.mutex.Lock()
  359. defer m.mutex.Unlock()
  360. var actualCalls int
  361. for _, call := range m.calls() {
  362. if call.Method == methodName {
  363. actualCalls++
  364. }
  365. }
  366. return assert.Equal(t, expectedCalls, actualCalls, fmt.Sprintf("Expected number of calls (%d) does not match the actual number of calls (%d).", expectedCalls, actualCalls))
  367. }
  368. // AssertCalled asserts that the method was called.
  369. // It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.
  370. func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool {
  371. m.mutex.Lock()
  372. defer m.mutex.Unlock()
  373. 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))) {
  374. t.Logf("%v", m.expectedCalls())
  375. return false
  376. }
  377. return true
  378. }
  379. // AssertNotCalled asserts that the method was not called.
  380. // It can produce a false result when an argument is a pointer type and the underlying value changed after calling the mocked method.
  381. func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool {
  382. m.mutex.Lock()
  383. defer m.mutex.Unlock()
  384. 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))) {
  385. t.Logf("%v", m.expectedCalls())
  386. return false
  387. }
  388. return true
  389. }
  390. func (m *Mock) methodWasCalled(methodName string, expected []interface{}) bool {
  391. for _, call := range m.calls() {
  392. if call.Method == methodName {
  393. _, differences := Arguments(expected).Diff(call.Arguments)
  394. if differences == 0 {
  395. // found the expected call
  396. return true
  397. }
  398. }
  399. }
  400. // we didn't find the expected call
  401. return false
  402. }
  403. func (m *Mock) expectedCalls() []*Call {
  404. return append([]*Call{}, m.ExpectedCalls...)
  405. }
  406. func (m *Mock) calls() []Call {
  407. return append([]Call{}, m.Calls...)
  408. }
  409. /*
  410. Arguments
  411. */
  412. // Arguments holds an array of method arguments or return values.
  413. type Arguments []interface{}
  414. const (
  415. // Anything is used in Diff and Assert when the argument being tested
  416. // shouldn't be taken into consideration.
  417. Anything string = "mock.Anything"
  418. )
  419. // AnythingOfTypeArgument is a string that contains the type of an argument
  420. // for use when type checking. Used in Diff and Assert.
  421. type AnythingOfTypeArgument string
  422. // AnythingOfType returns an AnythingOfTypeArgument object containing the
  423. // name of the type to check for. Used in Diff and Assert.
  424. //
  425. // For example:
  426. // Assert(t, AnythingOfType("string"), AnythingOfType("int"))
  427. func AnythingOfType(t string) AnythingOfTypeArgument {
  428. return AnythingOfTypeArgument(t)
  429. }
  430. // argumentMatcher performs custom argument matching, returning whether or
  431. // not the argument is matched by the expectation fixture function.
  432. type argumentMatcher struct {
  433. // fn is a function which accepts one argument, and returns a bool.
  434. fn reflect.Value
  435. }
  436. func (f argumentMatcher) Matches(argument interface{}) bool {
  437. expectType := f.fn.Type().In(0)
  438. expectTypeNilSupported := false
  439. switch expectType.Kind() {
  440. case reflect.Interface, reflect.Chan, reflect.Func, reflect.Map, reflect.Slice, reflect.Ptr:
  441. expectTypeNilSupported = true
  442. }
  443. argType := reflect.TypeOf(argument)
  444. var arg reflect.Value
  445. if argType == nil {
  446. arg = reflect.New(expectType).Elem()
  447. } else {
  448. arg = reflect.ValueOf(argument)
  449. }
  450. if argType == nil && !expectTypeNilSupported {
  451. panic(errors.New("attempting to call matcher with nil for non-nil expected type"))
  452. }
  453. if argType == nil || argType.AssignableTo(expectType) {
  454. result := f.fn.Call([]reflect.Value{arg})
  455. return result[0].Bool()
  456. }
  457. return false
  458. }
  459. func (f argumentMatcher) String() string {
  460. return fmt.Sprintf("func(%s) bool", f.fn.Type().In(0).Name())
  461. }
  462. // MatchedBy can be used to match a mock call based on only certain properties
  463. // from a complex struct or some calculation. It takes a function that will be
  464. // evaluated with the called argument and will return true when there's a match
  465. // and false otherwise.
  466. //
  467. // Example:
  468. // m.On("Do", MatchedBy(func(req *http.Request) bool { return req.Host == "example.com" }))
  469. //
  470. // |fn|, must be a function accepting a single argument (of the expected type)
  471. // which returns a bool. If |fn| doesn't match the required signature,
  472. // MatchedBy() panics.
  473. func MatchedBy(fn interface{}) argumentMatcher {
  474. fnType := reflect.TypeOf(fn)
  475. if fnType.Kind() != reflect.Func {
  476. panic(fmt.Sprintf("assert: arguments: %s is not a func", fn))
  477. }
  478. if fnType.NumIn() != 1 {
  479. panic(fmt.Sprintf("assert: arguments: %s does not take exactly one argument", fn))
  480. }
  481. if fnType.NumOut() != 1 || fnType.Out(0).Kind() != reflect.Bool {
  482. panic(fmt.Sprintf("assert: arguments: %s does not return a bool", fn))
  483. }
  484. return argumentMatcher{fn: reflect.ValueOf(fn)}
  485. }
  486. // Get Returns the argument at the specified index.
  487. func (args Arguments) Get(index int) interface{} {
  488. if index+1 > len(args) {
  489. panic(fmt.Sprintf("assert: arguments: Cannot call Get(%d) because there are %d argument(s).", index, len(args)))
  490. }
  491. return args[index]
  492. }
  493. // Is gets whether the objects match the arguments specified.
  494. func (args Arguments) Is(objects ...interface{}) bool {
  495. for i, obj := range args {
  496. if obj != objects[i] {
  497. return false
  498. }
  499. }
  500. return true
  501. }
  502. // Diff gets a string describing the differences between the arguments
  503. // and the specified objects.
  504. //
  505. // Returns the diff string and number of differences found.
  506. func (args Arguments) Diff(objects []interface{}) (string, int) {
  507. var output = "\n"
  508. var differences int
  509. var maxArgCount = len(args)
  510. if len(objects) > maxArgCount {
  511. maxArgCount = len(objects)
  512. }
  513. for i := 0; i < maxArgCount; i++ {
  514. var actual, expected interface{}
  515. if len(objects) <= i {
  516. actual = "(Missing)"
  517. } else {
  518. actual = objects[i]
  519. }
  520. if len(args) <= i {
  521. expected = "(Missing)"
  522. } else {
  523. expected = args[i]
  524. }
  525. if matcher, ok := expected.(argumentMatcher); ok {
  526. if matcher.Matches(actual) {
  527. output = fmt.Sprintf("%s\t%d: PASS: %s matched by %s\n", output, i, actual, matcher)
  528. } else {
  529. differences++
  530. output = fmt.Sprintf("%s\t%d: PASS: %s not matched by %s\n", output, i, actual, matcher)
  531. }
  532. } else if reflect.TypeOf(expected) == reflect.TypeOf((*AnythingOfTypeArgument)(nil)).Elem() {
  533. // type checking
  534. if reflect.TypeOf(actual).Name() != string(expected.(AnythingOfTypeArgument)) && reflect.TypeOf(actual).String() != string(expected.(AnythingOfTypeArgument)) {
  535. // not match
  536. differences++
  537. output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected, reflect.TypeOf(actual).Name(), actual)
  538. }
  539. } else {
  540. // normal checking
  541. if assert.ObjectsAreEqual(expected, Anything) || assert.ObjectsAreEqual(actual, Anything) || assert.ObjectsAreEqual(actual, expected) {
  542. // match
  543. output = fmt.Sprintf("%s\t%d: PASS: %s == %s\n", output, i, actual, expected)
  544. } else {
  545. // not match
  546. differences++
  547. output = fmt.Sprintf("%s\t%d: FAIL: %s != %s\n", output, i, actual, expected)
  548. }
  549. }
  550. }
  551. if differences == 0 {
  552. return "No differences.", differences
  553. }
  554. return output, differences
  555. }
  556. // Assert compares the arguments with the specified objects and fails if
  557. // they do not exactly match.
  558. func (args Arguments) Assert(t TestingT, objects ...interface{}) bool {
  559. // get the differences
  560. diff, diffCount := args.Diff(objects)
  561. if diffCount == 0 {
  562. return true
  563. }
  564. // there are differences... report them...
  565. t.Logf(diff)
  566. t.Errorf("%sArguments do not match.", assert.CallerInfo())
  567. return false
  568. }
  569. // String gets the argument at the specified index. Panics if there is no argument, or
  570. // if the argument is of the wrong type.
  571. //
  572. // If no index is provided, String() returns a complete string representation
  573. // of the arguments.
  574. func (args Arguments) String(indexOrNil ...int) string {
  575. if len(indexOrNil) == 0 {
  576. // normal String() method - return a string representation of the args
  577. var argsStr []string
  578. for _, arg := range args {
  579. argsStr = append(argsStr, fmt.Sprintf("%s", reflect.TypeOf(arg)))
  580. }
  581. return strings.Join(argsStr, ",")
  582. } else if len(indexOrNil) == 1 {
  583. // Index has been specified - get the argument at that index
  584. var index = indexOrNil[0]
  585. var s string
  586. var ok bool
  587. if s, ok = args.Get(index).(string); !ok {
  588. panic(fmt.Sprintf("assert: arguments: String(%d) failed because object wasn't correct type: %s", index, args.Get(index)))
  589. }
  590. return s
  591. }
  592. panic(fmt.Sprintf("assert: arguments: Wrong number of arguments passed to String. Must be 0 or 1, not %d", len(indexOrNil)))
  593. }
  594. // Int gets the argument at the specified index. Panics if there is no argument, or
  595. // if the argument is of the wrong type.
  596. func (args Arguments) Int(index int) int {
  597. var s int
  598. var ok bool
  599. if s, ok = args.Get(index).(int); !ok {
  600. panic(fmt.Sprintf("assert: arguments: Int(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
  601. }
  602. return s
  603. }
  604. // Error gets the argument at the specified index. Panics if there is no argument, or
  605. // if the argument is of the wrong type.
  606. func (args Arguments) Error(index int) error {
  607. obj := args.Get(index)
  608. var s error
  609. var ok bool
  610. if obj == nil {
  611. return nil
  612. }
  613. if s, ok = obj.(error); !ok {
  614. panic(fmt.Sprintf("assert: arguments: Error(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
  615. }
  616. return s
  617. }
  618. // Bool gets the argument at the specified index. Panics if there is no argument, or
  619. // if the argument is of the wrong type.
  620. func (args Arguments) Bool(index int) bool {
  621. var s bool
  622. var ok bool
  623. if s, ok = args.Get(index).(bool); !ok {
  624. panic(fmt.Sprintf("assert: arguments: Bool(%d) failed because object wasn't correct type: %v", index, args.Get(index)))
  625. }
  626. return s
  627. }
  628. func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {
  629. t := reflect.TypeOf(v)
  630. k := t.Kind()
  631. if k == reflect.Ptr {
  632. t = t.Elem()
  633. k = t.Kind()
  634. }
  635. return t, k
  636. }
  637. func diffArguments(expected Arguments, actual Arguments) string {
  638. if len(expected) != len(actual) {
  639. return fmt.Sprintf("Provided %v arguments, mocked for %v arguments", len(expected), len(actual))
  640. }
  641. for x := range expected {
  642. if diffString := diff(expected[x], actual[x]); diffString != "" {
  643. return fmt.Sprintf("Difference found in argument %v:\n\n%s", x, diffString)
  644. }
  645. }
  646. return ""
  647. }
  648. // diff returns a diff of both values as long as both are of the same type and
  649. // are a struct, map, slice or array. Otherwise it returns an empty string.
  650. func diff(expected interface{}, actual interface{}) string {
  651. if expected == nil || actual == nil {
  652. return ""
  653. }
  654. et, ek := typeAndKind(expected)
  655. at, _ := typeAndKind(actual)
  656. if et != at {
  657. return ""
  658. }
  659. if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array {
  660. return ""
  661. }
  662. e := spewConfig.Sdump(expected)
  663. a := spewConfig.Sdump(actual)
  664. diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
  665. A: difflib.SplitLines(e),
  666. B: difflib.SplitLines(a),
  667. FromFile: "Expected",
  668. FromDate: "",
  669. ToFile: "Actual",
  670. ToDate: "",
  671. Context: 1,
  672. })
  673. return diff
  674. }
  675. var spewConfig = spew.ConfigState{
  676. Indent: " ",
  677. DisablePointerAddresses: true,
  678. DisableCapacities: true,
  679. SortKeys: true,
  680. }