callset.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // Copyright 2011 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. "bytes"
  17. "errors"
  18. "fmt"
  19. )
  20. // callSet represents a set of expected calls, indexed by receiver and method
  21. // name.
  22. type callSet struct {
  23. // Calls that are still expected.
  24. expected map[callSetKey][]*Call
  25. // Calls that have been exhausted.
  26. exhausted map[callSetKey][]*Call
  27. }
  28. // callSetKey is the key in the maps in callSet
  29. type callSetKey struct {
  30. receiver interface{}
  31. fname string
  32. }
  33. func newCallSet() *callSet {
  34. return &callSet{make(map[callSetKey][]*Call), make(map[callSetKey][]*Call)}
  35. }
  36. // Add adds a new expected call.
  37. func (cs callSet) Add(call *Call) {
  38. key := callSetKey{call.receiver, call.method}
  39. m := cs.expected
  40. if call.exhausted() {
  41. m = cs.exhausted
  42. }
  43. m[key] = append(m[key], call)
  44. }
  45. // Remove removes an expected call.
  46. func (cs callSet) Remove(call *Call) {
  47. key := callSetKey{call.receiver, call.method}
  48. calls := cs.expected[key]
  49. for i, c := range calls {
  50. if c == call {
  51. // maintain order for remaining calls
  52. cs.expected[key] = append(calls[:i], calls[i+1:]...)
  53. cs.exhausted[key] = append(cs.exhausted[key], call)
  54. break
  55. }
  56. }
  57. }
  58. // FindMatch searches for a matching call. Returns error with explanation message if no call matched.
  59. func (cs callSet) FindMatch(receiver interface{}, method string, args []interface{}) (*Call, error) {
  60. key := callSetKey{receiver, method}
  61. // Search through the expected calls.
  62. expected := cs.expected[key]
  63. var callsErrors bytes.Buffer
  64. for _, call := range expected {
  65. err := call.matches(args)
  66. if err != nil {
  67. _, _ = fmt.Fprintf(&callsErrors, "\n%v", err)
  68. } else {
  69. return call, nil
  70. }
  71. }
  72. // If we haven't found a match then search through the exhausted calls so we
  73. // get useful error messages.
  74. exhausted := cs.exhausted[key]
  75. for _, call := range exhausted {
  76. if err := call.matches(args); err != nil {
  77. _, _ = fmt.Fprintf(&callsErrors, "\n%v", err)
  78. continue
  79. }
  80. _, _ = fmt.Fprintf(
  81. &callsErrors, "all expected calls for method %q have been exhausted", method,
  82. )
  83. }
  84. if len(expected)+len(exhausted) == 0 {
  85. _, _ = fmt.Fprintf(&callsErrors, "there are no expected calls of the method %q for that receiver", method)
  86. }
  87. return nil, errors.New(callsErrors.String())
  88. }
  89. // Failures returns the calls that are not satisfied.
  90. func (cs callSet) Failures() []*Call {
  91. failures := make([]*Call, 0, len(cs.expected))
  92. for _, calls := range cs.expected {
  93. for _, call := range calls {
  94. if !call.satisfied() {
  95. failures = append(failures, call)
  96. }
  97. }
  98. }
  99. return failures
  100. }