You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

109 lines
2.9 KiB

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