call.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. // Copyright 2010 Google Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package gomock
  15. import (
  16. "fmt"
  17. "reflect"
  18. "strings"
  19. )
  20. // Call represents an expected call to a mock.
  21. type Call struct {
  22. t TestReporter // for triggering test failures on invalid call setup
  23. receiver interface{} // the receiver of the method call
  24. method string // the name of the method
  25. args []Matcher // the args
  26. rets []interface{} // the return values (if any)
  27. preReqs []*Call // prerequisite calls
  28. // Expectations
  29. minCalls, maxCalls int
  30. numCalls int // actual number made
  31. // Actions
  32. doFunc reflect.Value
  33. setArgs map[int]reflect.Value
  34. }
  35. // AnyTimes allows the expectation to be called 0 or more times
  36. func (c *Call) AnyTimes() *Call {
  37. c.minCalls, c.maxCalls = 0, 1e8 // close enough to infinity
  38. return c
  39. }
  40. // MinTimes requires the call to occur at least n times. If AnyTimes or MaxTimes have not been called, MinTimes also
  41. // sets the maximum number of calls to infinity.
  42. func (c *Call) MinTimes(n int) *Call {
  43. c.minCalls = n
  44. if c.maxCalls == 1 {
  45. c.maxCalls = 1e8
  46. }
  47. return c
  48. }
  49. // MaxTimes limits the number of calls to n times. If AnyTimes or MinTimes have not been called, MaxTimes also
  50. // sets the minimum number of calls to 0.
  51. func (c *Call) MaxTimes(n int) *Call {
  52. c.maxCalls = n
  53. if c.minCalls == 1 {
  54. c.minCalls = 0
  55. }
  56. return c
  57. }
  58. // Do declares the action to run when the call is matched.
  59. // It takes an interface{} argument to support n-arity functions.
  60. func (c *Call) Do(f interface{}) *Call {
  61. // TODO: Check arity and types here, rather than dying badly elsewhere.
  62. c.doFunc = reflect.ValueOf(f)
  63. return c
  64. }
  65. func (c *Call) Return(rets ...interface{}) *Call {
  66. mt := c.methodType()
  67. if len(rets) != mt.NumOut() {
  68. c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d",
  69. c.receiver, c.method, len(rets), mt.NumOut())
  70. }
  71. for i, ret := range rets {
  72. if got, want := reflect.TypeOf(ret), mt.Out(i); got == want {
  73. // Identical types; nothing to do.
  74. } else if got == nil {
  75. // Nil needs special handling.
  76. switch want.Kind() {
  77. case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
  78. // ok
  79. default:
  80. c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable",
  81. i, c.receiver, c.method, want)
  82. }
  83. } else if got.AssignableTo(want) {
  84. // Assignable type relation. Make the assignment now so that the generated code
  85. // can return the values with a type assertion.
  86. v := reflect.New(want).Elem()
  87. v.Set(reflect.ValueOf(ret))
  88. rets[i] = v.Interface()
  89. } else {
  90. c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v",
  91. i, c.receiver, c.method, got, want)
  92. }
  93. }
  94. c.rets = rets
  95. return c
  96. }
  97. func (c *Call) Times(n int) *Call {
  98. c.minCalls, c.maxCalls = n, n
  99. return c
  100. }
  101. // SetArg declares an action that will set the nth argument's value,
  102. // indirected through a pointer.
  103. func (c *Call) SetArg(n int, value interface{}) *Call {
  104. if c.setArgs == nil {
  105. c.setArgs = make(map[int]reflect.Value)
  106. }
  107. mt := c.methodType()
  108. // TODO: This will break on variadic methods.
  109. // We will need to check those at invocation time.
  110. if n < 0 || n >= mt.NumIn() {
  111. c.t.Fatalf("SetArg(%d, ...) called for a method with %d args", n, mt.NumIn())
  112. }
  113. // Permit setting argument through an interface.
  114. // In the interface case, we don't (nay, can't) check the type here.
  115. at := mt.In(n)
  116. switch at.Kind() {
  117. case reflect.Ptr:
  118. dt := at.Elem()
  119. if vt := reflect.TypeOf(value); !vt.AssignableTo(dt) {
  120. c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v", n, vt, dt)
  121. }
  122. case reflect.Interface:
  123. // nothing to do
  124. default:
  125. c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface type %v", n, at)
  126. }
  127. c.setArgs[n] = reflect.ValueOf(value)
  128. return c
  129. }
  130. // isPreReq returns true if other is a direct or indirect prerequisite to c.
  131. func (c *Call) isPreReq(other *Call) bool {
  132. for _, preReq := range c.preReqs {
  133. if other == preReq || preReq.isPreReq(other) {
  134. return true
  135. }
  136. }
  137. return false
  138. }
  139. // After declares that the call may only match after preReq has been exhausted.
  140. func (c *Call) After(preReq *Call) *Call {
  141. if preReq.isPreReq(c) {
  142. msg := fmt.Sprintf(
  143. "Loop in call order: %v is a prerequisite to %v (possibly indirectly).",
  144. c, preReq,
  145. )
  146. panic(msg)
  147. }
  148. c.preReqs = append(c.preReqs, preReq)
  149. return c
  150. }
  151. // Returns true iff the minimum number of calls have been made.
  152. func (c *Call) satisfied() bool {
  153. return c.numCalls >= c.minCalls
  154. }
  155. // Returns true iff the maximum number of calls have been made.
  156. func (c *Call) exhausted() bool {
  157. return c.numCalls >= c.maxCalls
  158. }
  159. func (c *Call) String() string {
  160. args := make([]string, len(c.args))
  161. for i, arg := range c.args {
  162. args[i] = arg.String()
  163. }
  164. arguments := strings.Join(args, ", ")
  165. return fmt.Sprintf("%T.%v(%s)", c.receiver, c.method, arguments)
  166. }
  167. // Tests if the given call matches the expected call.
  168. func (c *Call) matches(args []interface{}) bool {
  169. if len(args) != len(c.args) {
  170. return false
  171. }
  172. for i, m := range c.args {
  173. if !m.Matches(args[i]) {
  174. return false
  175. }
  176. }
  177. // Check that all prerequisite calls have been satisfied.
  178. for _, preReqCall := range c.preReqs {
  179. if !preReqCall.satisfied() {
  180. return false
  181. }
  182. }
  183. return true
  184. }
  185. // dropPrereqs tells the expected Call to not re-check prerequite calls any
  186. // longer, and to return its current set.
  187. func (c *Call) dropPrereqs() (preReqs []*Call) {
  188. preReqs = c.preReqs
  189. c.preReqs = nil
  190. return
  191. }
  192. func (c *Call) call(args []interface{}) (rets []interface{}, action func()) {
  193. c.numCalls++
  194. // Actions
  195. if c.doFunc.IsValid() {
  196. doArgs := make([]reflect.Value, len(args))
  197. ft := c.doFunc.Type()
  198. for i := 0; i < ft.NumIn(); i++ {
  199. if args[i] != nil {
  200. doArgs[i] = reflect.ValueOf(args[i])
  201. } else {
  202. // Use the zero value for the arg.
  203. doArgs[i] = reflect.Zero(ft.In(i))
  204. }
  205. }
  206. action = func() { c.doFunc.Call(doArgs) }
  207. }
  208. for n, v := range c.setArgs {
  209. reflect.ValueOf(args[n]).Elem().Set(v)
  210. }
  211. rets = c.rets
  212. if rets == nil {
  213. // Synthesize the zero value for each of the return args' types.
  214. mt := c.methodType()
  215. rets = make([]interface{}, mt.NumOut())
  216. for i := 0; i < mt.NumOut(); i++ {
  217. rets[i] = reflect.Zero(mt.Out(i)).Interface()
  218. }
  219. }
  220. return
  221. }
  222. func (c *Call) methodType() reflect.Type {
  223. recv := reflect.ValueOf(c.receiver)
  224. for i := 0; i < recv.Type().NumMethod(); i++ {
  225. if recv.Type().Method(i).Name == c.method {
  226. return recv.Method(i).Type()
  227. }
  228. }
  229. panic(fmt.Sprintf("gomock: failed finding method %s on %T", c.method, c.receiver))
  230. }
  231. // InOrder declares that the given calls should occur in order.
  232. func InOrder(calls ...*Call) {
  233. for i := 1; i < len(calls); i++ {
  234. calls[i].After(calls[i-1])
  235. }
  236. }