summaryrefslogtreecommitdiff
path: root/vendor/github.com/golang/mock/gomock/controller.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/golang/mock/gomock/controller.go')
-rw-r--r--vendor/github.com/golang/mock/gomock/controller.go119
1 files changed, 83 insertions, 36 deletions
diff --git a/vendor/github.com/golang/mock/gomock/controller.go b/vendor/github.com/golang/mock/gomock/controller.go
index a7b7918..0651c91 100644
--- a/vendor/github.com/golang/mock/gomock/controller.go
+++ b/vendor/github.com/golang/mock/gomock/controller.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// GoMock - a mock framework for Go.
+// Package gomock is a mock framework for Go.
//
// Standard usage:
// (1) Define an interface that you wish to mock.
@@ -56,59 +56,111 @@
package gomock
import (
+ "context"
"fmt"
- "golang.org/x/net/context"
"reflect"
"runtime"
"sync"
)
-// A TestReporter is something that can be used to report test failures.
-// It is satisfied by the standard library's *testing.T.
+// A TestReporter is something that can be used to report test failures. It
+// is satisfied by the standard library's *testing.T.
type TestReporter interface {
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
}
-// A Controller represents the top-level control of a mock ecosystem.
-// It defines the scope and lifetime of mock objects, as well as their expectations.
-// It is safe to call Controller's methods from multiple goroutines.
+// TestHelper is a TestReporter that has the Helper method. It is satisfied
+// by the standard library's *testing.T.
+type TestHelper interface {
+ TestReporter
+ Helper()
+}
+
+// A Controller represents the top-level control of a mock ecosystem. It
+// defines the scope and lifetime of mock objects, as well as their
+// expectations. It is safe to call Controller's methods from multiple
+// goroutines. Each test should create a new Controller and invoke Finish via
+// defer.
+//
+// func TestFoo(t *testing.T) {
+// ctrl := gomock.NewController(st)
+// defer ctrl.Finish()
+// // ..
+// }
+//
+// func TestBar(t *testing.T) {
+// t.Run("Sub-Test-1", st) {
+// ctrl := gomock.NewController(st)
+// defer ctrl.Finish()
+// // ..
+// })
+// t.Run("Sub-Test-2", st) {
+// ctrl := gomock.NewController(st)
+// defer ctrl.Finish()
+// // ..
+// })
+// })
type Controller struct {
+ // T should only be called within a generated mock. It is not intended to
+ // be used in user code and may be changed in future versions. T is the
+ // TestReporter passed in when creating the Controller via NewController.
+ // If the TestReporter does not implement a TestHelper it will be wrapped
+ // with a nopTestHelper.
+ T TestHelper
mu sync.Mutex
- t TestReporter
expectedCalls *callSet
finished bool
}
+// NewController returns a new Controller. It is the preferred way to create a
+// Controller.
func NewController(t TestReporter) *Controller {
+ h, ok := t.(TestHelper)
+ if !ok {
+ h = nopTestHelper{t}
+ }
+
return &Controller{
- t: t,
+ T: h,
expectedCalls: newCallSet(),
}
}
type cancelReporter struct {
- t TestReporter
+ TestHelper
cancel func()
}
-func (r *cancelReporter) Errorf(format string, args ...interface{}) { r.t.Errorf(format, args...) }
+func (r *cancelReporter) Errorf(format string, args ...interface{}) {
+ r.TestHelper.Errorf(format, args...)
+}
func (r *cancelReporter) Fatalf(format string, args ...interface{}) {
defer r.cancel()
- r.t.Fatalf(format, args...)
+ r.TestHelper.Fatalf(format, args...)
}
// WithContext returns a new Controller and a Context, which is cancelled on any
// fatal failure.
func WithContext(ctx context.Context, t TestReporter) (*Controller, context.Context) {
+ h, ok := t.(TestHelper)
+ if !ok {
+ h = nopTestHelper{t}
+ }
+
ctx, cancel := context.WithCancel(ctx)
- return NewController(&cancelReporter{t, cancel}), ctx
+ return NewController(&cancelReporter{h, cancel}), ctx
}
+type nopTestHelper struct {
+ TestReporter
+}
+
+func (h nopTestHelper) Helper() {}
+
+// RecordCall is called by a mock. It should not be called by user code.
func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call {
- if h, ok := ctrl.t.(testHelper); ok {
- h.Helper()
- }
+ ctrl.T.Helper()
recv := reflect.ValueOf(receiver)
for i := 0; i < recv.Type().NumMethod(); i++ {
@@ -116,16 +168,15 @@ func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...
return ctrl.RecordCallWithMethodType(receiver, method, recv.Method(i).Type(), args...)
}
}
- ctrl.t.Fatalf("gomock: failed finding method %s on %T", method, receiver)
+ ctrl.T.Fatalf("gomock: failed finding method %s on %T", method, receiver)
panic("unreachable")
}
+// RecordCallWithMethodType is called by a mock. It should not be called by user code.
func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call {
- if h, ok := ctrl.t.(testHelper); ok {
- h.Helper()
- }
+ ctrl.T.Helper()
- call := newCall(ctrl.t, receiver, method, methodType, args...)
+ call := newCall(ctrl.T, receiver, method, methodType, args...)
ctrl.mu.Lock()
defer ctrl.mu.Unlock()
@@ -134,20 +185,20 @@ func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method st
return call
}
+// Call is called by a mock. It should not be called by user code.
func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} {
- if h, ok := ctrl.t.(testHelper); ok {
- h.Helper()
- }
+ ctrl.T.Helper()
// Nest this code so we can use defer to make sure the lock is released.
actions := func() []func([]interface{}) []interface{} {
+ ctrl.T.Helper()
ctrl.mu.Lock()
defer ctrl.mu.Unlock()
expected, err := ctrl.expectedCalls.FindMatch(receiver, method, args)
if err != nil {
origin := callerInfo(2)
- ctrl.t.Fatalf("Unexpected call to %T.%v(%v) at %s because: %s", receiver, method, args, origin, err)
+ ctrl.T.Fatalf("Unexpected call to %T.%v(%v) at %s because: %s", receiver, method, args, origin, err)
}
// Two things happen here:
@@ -175,16 +226,17 @@ func (ctrl *Controller) Call(receiver interface{}, method string, args ...interf
return rets
}
+// Finish checks to see if all the methods that were expected to be called
+// were called. It should be invoked for each Controller. It is not idempotent
+// and therefore can only be invoked once.
func (ctrl *Controller) Finish() {
- if h, ok := ctrl.t.(testHelper); ok {
- h.Helper()
- }
+ ctrl.T.Helper()
ctrl.mu.Lock()
defer ctrl.mu.Unlock()
if ctrl.finished {
- ctrl.t.Fatalf("Controller.Finish was called more than once. It has to be called exactly once.")
+ ctrl.T.Fatalf("Controller.Finish was called more than once. It has to be called exactly once.")
}
ctrl.finished = true
@@ -197,10 +249,10 @@ func (ctrl *Controller) Finish() {
// Check that all remaining expected calls are satisfied.
failures := ctrl.expectedCalls.Failures()
for _, call := range failures {
- ctrl.t.Errorf("missing call(s) to %v", call)
+ ctrl.T.Errorf("missing call(s) to %v", call)
}
if len(failures) != 0 {
- ctrl.t.Fatalf("aborting test due to missing call(s)")
+ ctrl.T.Fatalf("aborting test due to missing call(s)")
}
}
@@ -210,8 +262,3 @@ func callerInfo(skip int) string {
}
return "unknown file"
}
-
-type testHelper interface {
- TestReporter
- Helper()
-}