matchers.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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. // A Matcher is a representation of a class of values.
  21. // It is used to represent the valid or expected arguments to a mocked method.
  22. type Matcher interface {
  23. // Matches returns whether x is a match.
  24. Matches(x interface{}) bool
  25. // String describes what the matcher matches.
  26. String() string
  27. }
  28. // WantFormatter modifies the given Matcher's String() method to the given
  29. // Stringer. This allows for control on how the "Want" is formatted when
  30. // printing .
  31. func WantFormatter(s fmt.Stringer, m Matcher) Matcher {
  32. type matcher interface {
  33. Matches(x interface{}) bool
  34. }
  35. return struct {
  36. matcher
  37. fmt.Stringer
  38. }{
  39. matcher: m,
  40. Stringer: s,
  41. }
  42. }
  43. // StringerFunc type is an adapter to allow the use of ordinary functions as
  44. // a Stringer. If f is a function with the appropriate signature,
  45. // StringerFunc(f) is a Stringer that calls f.
  46. type StringerFunc func() string
  47. // String implements fmt.Stringer.
  48. func (f StringerFunc) String() string {
  49. return f()
  50. }
  51. // GotFormatter is used to better print failure messages. If a matcher
  52. // implements GotFormatter, it will use the result from Got when printing
  53. // the failure message.
  54. type GotFormatter interface {
  55. // Got is invoked with the received value. The result is used when
  56. // printing the failure message.
  57. Got(got interface{}) string
  58. }
  59. // GotFormatterFunc type is an adapter to allow the use of ordinary
  60. // functions as a GotFormatter. If f is a function with the appropriate
  61. // signature, GotFormatterFunc(f) is a GotFormatter that calls f.
  62. type GotFormatterFunc func(got interface{}) string
  63. // Got implements GotFormatter.
  64. func (f GotFormatterFunc) Got(got interface{}) string {
  65. return f(got)
  66. }
  67. // GotFormatterAdapter attaches a GotFormatter to a Matcher.
  68. func GotFormatterAdapter(s GotFormatter, m Matcher) Matcher {
  69. return struct {
  70. GotFormatter
  71. Matcher
  72. }{
  73. GotFormatter: s,
  74. Matcher: m,
  75. }
  76. }
  77. type anyMatcher struct{}
  78. func (anyMatcher) Matches(interface{}) bool {
  79. return true
  80. }
  81. func (anyMatcher) String() string {
  82. return "is anything"
  83. }
  84. type eqMatcher struct {
  85. x interface{}
  86. }
  87. func (e eqMatcher) Matches(x interface{}) bool {
  88. // In case, some value is nil
  89. if e.x == nil || x == nil {
  90. return reflect.DeepEqual(e.x, x)
  91. }
  92. // Check if types assignable and convert them to common type
  93. x1Val := reflect.ValueOf(e.x)
  94. x2Val := reflect.ValueOf(x)
  95. if x1Val.Type().AssignableTo(x2Val.Type()) {
  96. x1ValConverted := x1Val.Convert(x2Val.Type())
  97. return reflect.DeepEqual(x1ValConverted.Interface(), x2Val.Interface())
  98. }
  99. return false
  100. }
  101. func (e eqMatcher) String() string {
  102. return fmt.Sprintf("is equal to %v (%T)", e.x, e.x)
  103. }
  104. type nilMatcher struct{}
  105. func (nilMatcher) Matches(x interface{}) bool {
  106. if x == nil {
  107. return true
  108. }
  109. v := reflect.ValueOf(x)
  110. switch v.Kind() {
  111. case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map,
  112. reflect.Ptr, reflect.Slice:
  113. return v.IsNil()
  114. }
  115. return false
  116. }
  117. func (nilMatcher) String() string {
  118. return "is nil"
  119. }
  120. type notMatcher struct {
  121. m Matcher
  122. }
  123. func (n notMatcher) Matches(x interface{}) bool {
  124. return !n.m.Matches(x)
  125. }
  126. func (n notMatcher) String() string {
  127. return "not(" + n.m.String() + ")"
  128. }
  129. type assignableToTypeOfMatcher struct {
  130. targetType reflect.Type
  131. }
  132. func (m assignableToTypeOfMatcher) Matches(x interface{}) bool {
  133. return reflect.TypeOf(x).AssignableTo(m.targetType)
  134. }
  135. func (m assignableToTypeOfMatcher) String() string {
  136. return "is assignable to " + m.targetType.Name()
  137. }
  138. type allMatcher struct {
  139. matchers []Matcher
  140. }
  141. func (am allMatcher) Matches(x interface{}) bool {
  142. for _, m := range am.matchers {
  143. if !m.Matches(x) {
  144. return false
  145. }
  146. }
  147. return true
  148. }
  149. func (am allMatcher) String() string {
  150. ss := make([]string, 0, len(am.matchers))
  151. for _, matcher := range am.matchers {
  152. ss = append(ss, matcher.String())
  153. }
  154. return strings.Join(ss, "; ")
  155. }
  156. type lenMatcher struct {
  157. i int
  158. }
  159. func (m lenMatcher) Matches(x interface{}) bool {
  160. v := reflect.ValueOf(x)
  161. switch v.Kind() {
  162. case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
  163. return v.Len() == m.i
  164. default:
  165. return false
  166. }
  167. }
  168. func (m lenMatcher) String() string {
  169. return fmt.Sprintf("has length %d", m.i)
  170. }
  171. type inAnyOrderMatcher struct {
  172. x interface{}
  173. }
  174. func (m inAnyOrderMatcher) Matches(x interface{}) bool {
  175. given, ok := m.prepareValue(x)
  176. if !ok {
  177. return false
  178. }
  179. wanted, ok := m.prepareValue(m.x)
  180. if !ok {
  181. return false
  182. }
  183. if given.Len() != wanted.Len() {
  184. return false
  185. }
  186. usedFromGiven := make([]bool, given.Len())
  187. foundFromWanted := make([]bool, wanted.Len())
  188. for i := 0; i < wanted.Len(); i++ {
  189. wantedMatcher := Eq(wanted.Index(i).Interface())
  190. for j := 0; j < given.Len(); j++ {
  191. if usedFromGiven[j] {
  192. continue
  193. }
  194. if wantedMatcher.Matches(given.Index(j).Interface()) {
  195. foundFromWanted[i] = true
  196. usedFromGiven[j] = true
  197. break
  198. }
  199. }
  200. }
  201. missingFromWanted := 0
  202. for _, found := range foundFromWanted {
  203. if !found {
  204. missingFromWanted++
  205. }
  206. }
  207. extraInGiven := 0
  208. for _, used := range usedFromGiven {
  209. if !used {
  210. extraInGiven++
  211. }
  212. }
  213. return extraInGiven == 0 && missingFromWanted == 0
  214. }
  215. func (m inAnyOrderMatcher) prepareValue(x interface{}) (reflect.Value, bool) {
  216. xValue := reflect.ValueOf(x)
  217. switch xValue.Kind() {
  218. case reflect.Slice, reflect.Array:
  219. return xValue, true
  220. default:
  221. return reflect.Value{}, false
  222. }
  223. }
  224. func (m inAnyOrderMatcher) String() string {
  225. return fmt.Sprintf("has the same elements as %v", m.x)
  226. }
  227. // Constructors
  228. // All returns a composite Matcher that returns true if and only all of the
  229. // matchers return true.
  230. func All(ms ...Matcher) Matcher { return allMatcher{ms} }
  231. // Any returns a matcher that always matches.
  232. func Any() Matcher { return anyMatcher{} }
  233. // Eq returns a matcher that matches on equality.
  234. //
  235. // Example usage:
  236. // Eq(5).Matches(5) // returns true
  237. // Eq(5).Matches(4) // returns false
  238. func Eq(x interface{}) Matcher { return eqMatcher{x} }
  239. // Len returns a matcher that matches on length. This matcher returns false if
  240. // is compared to a type that is not an array, chan, map, slice, or string.
  241. func Len(i int) Matcher {
  242. return lenMatcher{i}
  243. }
  244. // Nil returns a matcher that matches if the received value is nil.
  245. //
  246. // Example usage:
  247. // var x *bytes.Buffer
  248. // Nil().Matches(x) // returns true
  249. // x = &bytes.Buffer{}
  250. // Nil().Matches(x) // returns false
  251. func Nil() Matcher { return nilMatcher{} }
  252. // Not reverses the results of its given child matcher.
  253. //
  254. // Example usage:
  255. // Not(Eq(5)).Matches(4) // returns true
  256. // Not(Eq(5)).Matches(5) // returns false
  257. func Not(x interface{}) Matcher {
  258. if m, ok := x.(Matcher); ok {
  259. return notMatcher{m}
  260. }
  261. return notMatcher{Eq(x)}
  262. }
  263. // AssignableToTypeOf is a Matcher that matches if the parameter to the mock
  264. // function is assignable to the type of the parameter to this function.
  265. //
  266. // Example usage:
  267. // var s fmt.Stringer = &bytes.Buffer{}
  268. // AssignableToTypeOf(s).Matches(time.Second) // returns true
  269. // AssignableToTypeOf(s).Matches(99) // returns false
  270. //
  271. // var ctx = reflect.TypeOf((*context.Context)(nil)).Elem()
  272. // AssignableToTypeOf(ctx).Matches(context.Background()) // returns true
  273. func AssignableToTypeOf(x interface{}) Matcher {
  274. if xt, ok := x.(reflect.Type); ok {
  275. return assignableToTypeOfMatcher{xt}
  276. }
  277. return assignableToTypeOfMatcher{reflect.TypeOf(x)}
  278. }
  279. // InAnyOrder is a Matcher that returns true for collections of the same elements ignoring the order.
  280. //
  281. // Example usage:
  282. // InAnyOrder([]int{1, 2, 3}).Matches([]int{1, 3, 2}) // returns true
  283. // InAnyOrder([]int{1, 2, 3}).Matches([]int{1, 2}) // returns false
  284. func InAnyOrder(x interface{}) Matcher {
  285. return inAnyOrderMatcher{x}
  286. }