pax_global_header00006660000000000000000000000064131346623710014520gustar00rootroot0000000000000052 comment=13f360950a79f5864a972c786a10a50e44b69541 mock-1.0.0/000077500000000000000000000000001313466237100124475ustar00rootroot00000000000000mock-1.0.0/.gitignore000066400000000000000000000003501313466237100144350ustar00rootroot00000000000000# Object files and binaries from go. *.[568] # Library files. *.a # Any file prefixed by an underscore. */_* # Vim temporary files. .*.swp # The mockgen binary. mockgen/mockgen # A binary produced by gotest. #gomock/[568]\.out mock-1.0.0/.travis.yml000066400000000000000000000004061313466237100145600ustar00rootroot00000000000000language: go go: # we intend to support only the latest version and perhaps the previous one - 1.7 - 1.8 script: - go build ./... - go install github.com/golang/mock/mockgen - ./ci/check_go_fmt.sh - ./ci/check_go_generate.sh - go test -v ./... mock-1.0.0/AUTHORS000066400000000000000000000005631313466237100135230ustar00rootroot00000000000000# This is the official list of GoMock authors for copyright purposes. # This file is distinct from the CONTRIBUTORS files. # See the latter for an explanation. # Names should be added to this file as # Name or Organization # The email address is not required for organizations. # Please keep the list sorted. Alex Reece Google Inc. mock-1.0.0/CONTRIBUTORS000066400000000000000000000027271313466237100143370ustar00rootroot00000000000000# This is the official list of people who can contribute (and typically # have contributed) code to the gomock repository. # The AUTHORS file lists the copyright holders; this file # lists people. For example, Google employees are listed here # but not in AUTHORS, because Google holds the copyright. # # The submission process automatically checks to make sure # that people submitting code are listed in this file (by email address). # # Names should be added to this file only after verifying that # the individual or the individual's organization has agreed to # the appropriate Contributor License Agreement, found here: # # http://code.google.com/legal/individual-cla-v1.0.html # http://code.google.com/legal/corporate-cla-v1.0.html # # The agreement for individuals can be filled out on the web. # # When adding J Random Contributor's name to this file, # either J's name or J's organization's name should be # added to the AUTHORS file, depending on whether the # individual or corporate CLA was used. # Names should be added to this file like so: # Name # # An entry with two email addresses specifies that the # first address should be used in the submit logs and # that the second address should be recognized as the # same person when interacting with Rietveld. # Please keep the list sorted. Aaron Jacobs Alex Reece David Symonds Ryan Barrett mock-1.0.0/LICENSE000066400000000000000000000261361313466237100134640ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. mock-1.0.0/README.md000066400000000000000000000056571313466237100137430ustar00rootroot00000000000000gomock [![Build Status](https://travis-ci.org/golang/mock.svg?branch=master)](https://travis-ci.org/golang/mock) ====== GoMock is a mocking framework for the [Go programming language][golang]. It integrates well with Go's built-in `testing` package, but can be used in other contexts too. Installation ------------ Once you have [installed Go][golang-install], run these commands to install the `gomock` package and the `mockgen` tool: go get github.com/golang/mock/gomock go get github.com/golang/mock/mockgen Documentation ------------- After installing, you can use `go doc` to get documentation: go doc github.com/golang/mock/gomock Alternatively, there is an online reference for the package hosted on GoPkgDoc [here][gomock-ref]. Running mockgen --------------- `mockgen` has two modes of operation: source and reflect. Source mode generates mock interfaces from a source file. It is enabled by using the -source flag. Other flags that may be useful in this mode are -imports and -aux_files. Example: mockgen -source=foo.go [other options] Reflect mode generates mock interfaces by building a program that uses reflection to understand interfaces. It is enabled by passing two non-flag arguments: an import path, and a comma-separated list of symbols. Example: mockgen database/sql/driver Conn,Driver The `mockgen` command is used to generate source code for a mock class given a Go source file containing interfaces to be mocked. It supports the following flags: * `-source`: A file containing interfaces to be mocked. * `-destination`: A file to which to write the resulting source code. If you don't set this, the code is printed to standard output. * `-package`: The package to use for the resulting mock class source code. If you don't set this, the package name is `mock_` concatenated with the package of the input file. * `-imports`: A list of explicit imports that should be used in the resulting source code, specified as a comma-separated list of elements of the form `foo=bar/baz`, where `bar/baz` is the package being imported and `foo` is the identifier to use for the package in the generated source code. * `-aux_files`: A list of additional files that should be consulted to resolve e.g. embedded interfaces defined in a different file. This is specified as a comma-separated list of elements of the form `foo=bar/baz.go`, where `bar/baz.go` is the source file and `foo` is the package name of that file used by the -source file. * `-build_flags`: (reflect mode only) Flags passed verbatim to `go build`. For an example of the use of `mockgen`, see the `sample/` directory. In simple cases, you will need only the `-source` flag. TODO: Brief overview of how to create mock objects and set up expectations, and an example. [golang]: http://golang.org/ [golang-install]: http://golang.org/doc/install.html#releases [gomock-ref]: http://godoc.org/github.com/golang/mock/gomock mock-1.0.0/ci/000077500000000000000000000000001313466237100130425ustar00rootroot00000000000000mock-1.0.0/ci/check_go_fmt.sh000077500000000000000000000004661313466237100160170ustar00rootroot00000000000000#!/bin/bash # This script is used by the CI to check if the code is gofmt formatted. set -euo pipefail GOFMT_DIFF=$(IFS=$'\n'; gofmt -d $( find . -type f -name '*.go' ) ) if [[ -n "${GOFMT_DIFF}" ]]; then echo "${GOFMT_DIFF}" echo echo "The go source files aren't gofmt formatted." exit 1 fi mock-1.0.0/ci/check_go_generate.sh000077500000000000000000000013641313466237100170210ustar00rootroot00000000000000#!/bin/bash # This script is used by the CI to check if 'go generate ./...' is up to date. # # Note: If the generated files aren't up to date then this script updates # them despite printing an error message so running it the second time # might not print any errors. This isn't very useful locally during development # but it works well with the CI that downloads a fresh version of the repo # each time before executing this script. set -euo pipefail TEMP_DIR=$( mktemp -d ) function cleanup() { rm -rf "${TEMP_DIR}" } trap cleanup EXIT cp -r . "${TEMP_DIR}/" go generate ./... if ! diff -r . "${TEMP_DIR}"; then echo echo "The generated files aren't up to date." echo "Update them with the 'go generate ./...' command." exit 1 fi mock-1.0.0/gomock/000077500000000000000000000000001313466237100137265ustar00rootroot00000000000000mock-1.0.0/gomock/call.go000066400000000000000000000157461313466237100152050ustar00rootroot00000000000000// Copyright 2010 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package gomock import ( "fmt" "reflect" "strings" ) // Call represents an expected call to a mock. type Call struct { t TestReporter // for triggering test failures on invalid call setup receiver interface{} // the receiver of the method call method string // the name of the method methodType reflect.Type // the type of the method args []Matcher // the args rets []interface{} // the return values (if any) preReqs []*Call // prerequisite calls // Expectations minCalls, maxCalls int numCalls int // actual number made // Actions doFunc reflect.Value setArgs map[int]reflect.Value } // AnyTimes allows the expectation to be called 0 or more times func (c *Call) AnyTimes() *Call { c.minCalls, c.maxCalls = 0, 1e8 // close enough to infinity return c } // MinTimes requires the call to occur at least n times. If AnyTimes or MaxTimes have not been called, MinTimes also // sets the maximum number of calls to infinity. func (c *Call) MinTimes(n int) *Call { c.minCalls = n if c.maxCalls == 1 { c.maxCalls = 1e8 } return c } // MaxTimes limits the number of calls to n times. If AnyTimes or MinTimes have not been called, MaxTimes also // sets the minimum number of calls to 0. func (c *Call) MaxTimes(n int) *Call { c.maxCalls = n if c.minCalls == 1 { c.minCalls = 0 } return c } // Do declares the action to run when the call is matched. // It takes an interface{} argument to support n-arity functions. func (c *Call) Do(f interface{}) *Call { // TODO: Check arity and types here, rather than dying badly elsewhere. c.doFunc = reflect.ValueOf(f) return c } func (c *Call) Return(rets ...interface{}) *Call { mt := c.methodType if len(rets) != mt.NumOut() { c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d", c.receiver, c.method, len(rets), mt.NumOut()) } for i, ret := range rets { if got, want := reflect.TypeOf(ret), mt.Out(i); got == want { // Identical types; nothing to do. } else if got == nil { // Nil needs special handling. switch want.Kind() { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: // ok default: c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable", i, c.receiver, c.method, want) } } else if got.AssignableTo(want) { // Assignable type relation. Make the assignment now so that the generated code // can return the values with a type assertion. v := reflect.New(want).Elem() v.Set(reflect.ValueOf(ret)) rets[i] = v.Interface() } else { c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v", i, c.receiver, c.method, got, want) } } c.rets = rets return c } func (c *Call) Times(n int) *Call { c.minCalls, c.maxCalls = n, n return c } // SetArg declares an action that will set the nth argument's value, // indirected through a pointer. func (c *Call) SetArg(n int, value interface{}) *Call { if c.setArgs == nil { c.setArgs = make(map[int]reflect.Value) } mt := c.methodType // TODO: This will break on variadic methods. // We will need to check those at invocation time. if n < 0 || n >= mt.NumIn() { c.t.Fatalf("SetArg(%d, ...) called for a method with %d args", n, mt.NumIn()) } // Permit setting argument through an interface. // In the interface case, we don't (nay, can't) check the type here. at := mt.In(n) switch at.Kind() { case reflect.Ptr: dt := at.Elem() if vt := reflect.TypeOf(value); !vt.AssignableTo(dt) { c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v", n, vt, dt) } case reflect.Interface: // nothing to do default: c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface type %v", n, at) } c.setArgs[n] = reflect.ValueOf(value) return c } // isPreReq returns true if other is a direct or indirect prerequisite to c. func (c *Call) isPreReq(other *Call) bool { for _, preReq := range c.preReqs { if other == preReq || preReq.isPreReq(other) { return true } } return false } // After declares that the call may only match after preReq has been exhausted. func (c *Call) After(preReq *Call) *Call { if c == preReq { c.t.Fatalf("A call isn't allowed to be it's own prerequisite") } if preReq.isPreReq(c) { c.t.Fatalf("Loop in call order: %v is a prerequisite to %v (possibly indirectly).", c, preReq) } c.preReqs = append(c.preReqs, preReq) return c } // Returns true iff the minimum number of calls have been made. func (c *Call) satisfied() bool { return c.numCalls >= c.minCalls } // Returns true iff the maximum number of calls have been made. func (c *Call) exhausted() bool { return c.numCalls >= c.maxCalls } func (c *Call) String() string { args := make([]string, len(c.args)) for i, arg := range c.args { args[i] = arg.String() } arguments := strings.Join(args, ", ") return fmt.Sprintf("%T.%v(%s)", c.receiver, c.method, arguments) } // Tests if the given call matches the expected call. func (c *Call) matches(args []interface{}) bool { if len(args) != len(c.args) { return false } for i, m := range c.args { if !m.Matches(args[i]) { return false } } // Check that all prerequisite calls have been satisfied. for _, preReqCall := range c.preReqs { if !preReqCall.satisfied() { return false } } return true } // dropPrereqs tells the expected Call to not re-check prerequite calls any // longer, and to return its current set. func (c *Call) dropPrereqs() (preReqs []*Call) { preReqs = c.preReqs c.preReqs = nil return } func (c *Call) call(args []interface{}) (rets []interface{}, action func()) { c.numCalls++ // Actions if c.doFunc.IsValid() { doArgs := make([]reflect.Value, len(args)) ft := c.doFunc.Type() for i := 0; i < len(args); i++ { if args[i] != nil { doArgs[i] = reflect.ValueOf(args[i]) } else { // Use the zero value for the arg. doArgs[i] = reflect.Zero(ft.In(i)) } } action = func() { c.doFunc.Call(doArgs) } } for n, v := range c.setArgs { reflect.ValueOf(args[n]).Elem().Set(v) } rets = c.rets if rets == nil { // Synthesize the zero value for each of the return args' types. mt := c.methodType rets = make([]interface{}, mt.NumOut()) for i := 0; i < mt.NumOut(); i++ { rets[i] = reflect.Zero(mt.Out(i)).Interface() } } return } // InOrder declares that the given calls should occur in order. func InOrder(calls ...*Call) { for i := 1; i < len(calls); i++ { calls[i].After(calls[i-1]) } } mock-1.0.0/gomock/call_test.go000066400000000000000000000016321313466237100162310ustar00rootroot00000000000000package gomock import "testing" type mockTestReporter struct { errorCalls int fatalCalls int } func (o *mockTestReporter) Errorf(format string, args ...interface{}) { o.errorCalls++ } func (o *mockTestReporter) Fatalf(format string, args ...interface{}) { o.fatalCalls++ } func TestCall_After(t *testing.T) { t.Run("SelfPrereqCallsFatalf", func(t *testing.T) { tr1 := &mockTestReporter{} c := &Call{t: tr1} c.After(c) if tr1.fatalCalls != 1 { t.Errorf("number of fatal calls == %v, want 1", tr1.fatalCalls) } }) t.Run("LoopInCallOrderCallsFatalf", func(t *testing.T) { tr1 := &mockTestReporter{} tr2 := &mockTestReporter{} c1 := &Call{t: tr1} c2 := &Call{t: tr2} c1.After(c2) c2.After(c1) if tr1.errorCalls != 0 || tr1.fatalCalls != 0 { t.Error("unexpected errors") } if tr2.fatalCalls != 1 { t.Errorf("number of fatal calls == %v, want 1", tr2.fatalCalls) } }) } mock-1.0.0/gomock/callset.go000066400000000000000000000037601313466237100157120ustar00rootroot00000000000000// Copyright 2011 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package gomock // callSet represents a set of expected calls, indexed by receiver and method // name. type callSet map[interface{}]map[string][]*Call // Add adds a new expected call. func (cs callSet) Add(call *Call) { methodMap, ok := cs[call.receiver] if !ok { methodMap = make(map[string][]*Call) cs[call.receiver] = methodMap } methodMap[call.method] = append(methodMap[call.method], call) } // Remove removes an expected call. func (cs callSet) Remove(call *Call) { methodMap, ok := cs[call.receiver] if !ok { return } sl := methodMap[call.method] for i, c := range sl { if c == call { // quick removal; we don't need to maintain call order if len(sl) > 1 { sl[i] = sl[len(sl)-1] } methodMap[call.method] = sl[:len(sl)-1] break } } } // FindMatch searches for a matching call. Returns nil if no call matched. func (cs callSet) FindMatch(receiver interface{}, method string, args []interface{}) *Call { methodMap, ok := cs[receiver] if !ok { return nil } calls, ok := methodMap[method] if !ok { return nil } // Search through the unordered set of calls expected on a method on a // receiver. for _, call := range calls { // A call should not normally still be here if exhausted, // but it can happen if, for instance, .Times(0) was used. // Pretend the call doesn't match. if call.exhausted() { continue } if call.matches(args) { return call } } return nil } mock-1.0.0/gomock/controller.go000066400000000000000000000132441313466237100164440ustar00rootroot00000000000000// Copyright 2010 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // GoMock - a mock framework for Go. // // Standard usage: // (1) Define an interface that you wish to mock. // type MyInterface interface { // SomeMethod(x int64, y string) // } // (2) Use mockgen to generate a mock from the interface. // (3) Use the mock in a test: // func TestMyThing(t *testing.T) { // mockCtrl := gomock.NewController(t) // defer mockCtrl.Finish() // // mockObj := something.NewMockMyInterface(mockCtrl) // mockObj.EXPECT().SomeMethod(4, "blah") // // pass mockObj to a real object and play with it. // } // // By default, expected calls are not enforced to run in any particular order. // Call order dependency can be enforced by use of InOrder and/or Call.After. // Call.After can create more varied call order dependencies, but InOrder is // often more convenient. // // The following examples create equivalent call order dependencies. // // Example of using Call.After to chain expected call order: // // firstCall := mockObj.EXPECT().SomeMethod(1, "first") // secondCall := mockObj.EXPECT().SomeMethod(2, "second").After(firstCall) // mockObj.EXPECT().SomeMethod(3, "third").After(secondCall) // // Example of using InOrder to declare expected call order: // // gomock.InOrder( // mockObj.EXPECT().SomeMethod(1, "first"), // mockObj.EXPECT().SomeMethod(2, "second"), // mockObj.EXPECT().SomeMethod(3, "third"), // ) // // TODO: // - Handle different argument/return types (e.g. ..., chan, map, interface). package gomock import ( "fmt" "reflect" "sync" ) // 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. type Controller struct { mu sync.Mutex t TestReporter expectedCalls callSet } func NewController(t TestReporter) *Controller { return &Controller{ t: t, expectedCalls: make(callSet), } } func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call { recv := reflect.ValueOf(receiver) for i := 0; i < recv.Type().NumMethod(); i++ { if recv.Type().Method(i).Name == method { return ctrl.RecordCallWithMethodType(receiver, method, recv.Method(i).Type(), args...) } } ctrl.t.Fatalf("gomock: failed finding method %s on %T", method, receiver) // In case t.Fatalf does not panic. panic(fmt.Sprintf("gomock: failed finding method %s on %T", method, receiver)) } func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call { // TODO: check arity, types. margs := make([]Matcher, len(args)) for i, arg := range args { if m, ok := arg.(Matcher); ok { margs[i] = m } else if arg == nil { // Handle nil specially so that passing a nil interface value // will match the typed nils of concrete args. margs[i] = Nil() } else { margs[i] = Eq(arg) } } ctrl.mu.Lock() defer ctrl.mu.Unlock() call := &Call{t: ctrl.t, receiver: receiver, method: method, methodType: methodType, args: margs, minCalls: 1, maxCalls: 1} ctrl.expectedCalls.Add(call) return call } func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} { ctrl.mu.Lock() defer ctrl.mu.Unlock() expected := ctrl.expectedCalls.FindMatch(receiver, method, args) if expected == nil { ctrl.t.Fatalf("no matching expected call: %T.%v(%v)", receiver, method, args) } // Two things happen here: // * the matching call no longer needs to check prerequite calls, // * and the prerequite calls are no longer expected, so remove them. preReqCalls := expected.dropPrereqs() for _, preReqCall := range preReqCalls { ctrl.expectedCalls.Remove(preReqCall) } rets, action := expected.call(args) if expected.exhausted() { ctrl.expectedCalls.Remove(expected) } // Don't hold the lock while doing the call's action (if any) // so that actions may execute concurrently. // We use the deferred Unlock to capture any panics that happen above; // here we add a deferred Lock to balance it. ctrl.mu.Unlock() defer ctrl.mu.Lock() if action != nil { action() } return rets } func (ctrl *Controller) Finish() { ctrl.mu.Lock() defer ctrl.mu.Unlock() // If we're currently panicking, probably because this is a deferred call, // pass through the panic. if err := recover(); err != nil { panic(err) } // Check that all remaining expected calls are satisfied. failures := false for _, methodMap := range ctrl.expectedCalls { for _, calls := range methodMap { for _, call := range calls { if !call.satisfied() { ctrl.t.Errorf("missing call(s) to %v", call) failures = true } } } } if failures { ctrl.t.Fatalf("aborting test due to missing call(s)") } } mock-1.0.0/gomock/controller_test.go000066400000000000000000000302301313466237100174750ustar00rootroot00000000000000// Copyright 2011 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package gomock_test import ( "fmt" "reflect" "testing" "github.com/golang/mock/gomock" ) type ErrorReporter struct { t *testing.T log []string failed bool fatalToken struct{} } func NewErrorReporter(t *testing.T) *ErrorReporter { return &ErrorReporter{t: t} } func (e *ErrorReporter) reportLog() { for _, entry := range e.log { e.t.Log(entry) } } func (e *ErrorReporter) assertPass(msg string) { if e.failed { e.t.Errorf("Expected pass, but got failure(s): %s", msg) e.reportLog() } } func (e *ErrorReporter) assertFail(msg string) { if !e.failed { e.t.Errorf("Expected failure, but got pass: %s", msg) } } // Use to check that code triggers a fatal test failure. func (e *ErrorReporter) assertFatal(fn func()) { defer func() { err := recover() if err == nil { var actual string if e.failed { actual = "non-fatal failure" } else { actual = "pass" } e.t.Error("Expected fatal failure, but got a", actual) } else if token, ok := err.(*struct{}); ok && token == &e.fatalToken { // This is okay - the panic is from Fatalf(). return } else { // Some other panic. panic(err) } }() fn() } // recoverUnexpectedFatal can be used as a deferred call in test cases to // recover from and display a call to ErrorReporter.Fatalf(). func (e *ErrorReporter) recoverUnexpectedFatal() { err := recover() if err == nil { // No panic. } else if token, ok := err.(*struct{}); ok && token == &e.fatalToken { // Unexpected fatal error happened. e.t.Error("Got unexpected fatal error(s). All errors up to this point:") e.reportLog() return } else { // Some other panic. panic(err) } } func (e *ErrorReporter) Logf(format string, args ...interface{}) { e.log = append(e.log, fmt.Sprintf(format, args...)) } func (e *ErrorReporter) Errorf(format string, args ...interface{}) { e.Logf(format, args...) e.failed = true } func (e *ErrorReporter) Fatalf(format string, args ...interface{}) { e.Logf(format, args...) e.failed = true panic(&e.fatalToken) } // A type purely for use as a receiver in testing the Controller. type Subject struct{} func (s *Subject) FooMethod(arg string) int { return 0 } func (s *Subject) BarMethod(arg string) int { return 0 } func assertEqual(t *testing.T, expected interface{}, actual interface{}) { if !reflect.DeepEqual(expected, actual) { t.Errorf("Expected %+v, but got %+v", expected, actual) } } func createFixtures(t *testing.T) (reporter *ErrorReporter, ctrl *gomock.Controller) { // reporter acts as a testing.T-like object that we pass to the // Controller. We use it to test that the mock considered tests // successful or failed. reporter = NewErrorReporter(t) ctrl = gomock.NewController(reporter) return } func TestNoCalls(t *testing.T) { reporter, ctrl := createFixtures(t) ctrl.Finish() reporter.assertPass("No calls expected or made.") } func TestExpectedMethodCall(t *testing.T) { reporter, ctrl := createFixtures(t) subject := new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument") ctrl.Call(subject, "FooMethod", "argument") ctrl.Finish() reporter.assertPass("Expected method call made.") } func TestUnexpectedMethodCall(t *testing.T) { reporter, ctrl := createFixtures(t) subject := new(Subject) reporter.assertFatal(func() { ctrl.Call(subject, "FooMethod", "argument") }) ctrl.Finish() } func TestRepeatedCall(t *testing.T) { reporter, ctrl := createFixtures(t) subject := new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").Times(3) ctrl.Call(subject, "FooMethod", "argument") ctrl.Call(subject, "FooMethod", "argument") ctrl.Call(subject, "FooMethod", "argument") reporter.assertPass("After expected repeated method calls.") reporter.assertFatal(func() { ctrl.Call(subject, "FooMethod", "argument") }) ctrl.Finish() reporter.assertFail("After calling one too many times.") } func TestUnexpectedArgCount(t *testing.T) { reporter, ctrl := createFixtures(t) defer reporter.recoverUnexpectedFatal() subject := new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument") reporter.assertFatal(func() { // This call is made with the wrong number of arguments... ctrl.Call(subject, "FooMethod", "argument", "extra_argument") }) reporter.assertFatal(func() { // ... so is this. ctrl.Call(subject, "FooMethod") }) reporter.assertFatal(func() { // The expected call wasn't made. ctrl.Finish() }) } func TestAnyTimes(t *testing.T) { reporter, ctrl := createFixtures(t) subject := new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").AnyTimes() for i := 0; i < 100; i++ { ctrl.Call(subject, "FooMethod", "argument") } reporter.assertPass("After 100 method calls.") ctrl.Finish() } func TestMinTimes1(t *testing.T) { // It fails if there are no calls reporter, ctrl := createFixtures(t) subject := new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1) reporter.assertFatal(func() { ctrl.Finish() }) // It succeeds if there is one call reporter, ctrl = createFixtures(t) subject = new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1) ctrl.Call(subject, "FooMethod", "argument") ctrl.Finish() // It succeeds if there are many calls reporter, ctrl = createFixtures(t) subject = new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(1) for i := 0; i < 100; i++ { ctrl.Call(subject, "FooMethod", "argument") } ctrl.Finish() } func TestMaxTimes1(t *testing.T) { // It succeeds if there are no calls _, ctrl := createFixtures(t) subject := new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1) ctrl.Finish() // It succeeds if there is one call _, ctrl = createFixtures(t) subject = new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1) ctrl.Call(subject, "FooMethod", "argument") ctrl.Finish() //It fails if there are more reporter, ctrl := createFixtures(t) subject = new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(1) ctrl.Call(subject, "FooMethod", "argument") reporter.assertFatal(func() { ctrl.Call(subject, "FooMethod", "argument") }) ctrl.Finish() } func TestMinMaxTimes(t *testing.T) { // It fails if there are less calls than specified reporter, ctrl := createFixtures(t) subject := new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(2).MaxTimes(2) ctrl.Call(subject, "FooMethod", "argument") reporter.assertFatal(func() { ctrl.Finish() }) // It fails if there are more calls than specified reporter, ctrl = createFixtures(t) subject = new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").MinTimes(2).MaxTimes(2) ctrl.Call(subject, "FooMethod", "argument") ctrl.Call(subject, "FooMethod", "argument") reporter.assertFatal(func() { ctrl.Call(subject, "FooMethod", "argument") }) // It succeeds if there is just the right number of calls reporter, ctrl = createFixtures(t) subject = new(Subject) ctrl.RecordCall(subject, "FooMethod", "argument").MaxTimes(2).MinTimes(2) ctrl.Call(subject, "FooMethod", "argument") ctrl.Call(subject, "FooMethod", "argument") ctrl.Finish() } func TestDo(t *testing.T) { _, ctrl := createFixtures(t) subject := new(Subject) doCalled := false var argument string ctrl.RecordCall(subject, "FooMethod", "argument").Do( func(arg string) { doCalled = true argument = arg }) if doCalled { t.Error("Do() callback called too early.") } ctrl.Call(subject, "FooMethod", "argument") if !doCalled { t.Error("Do() callback not called.") } if "argument" != argument { t.Error("Do callback received wrong argument.") } ctrl.Finish() } func TestReturn(t *testing.T) { _, ctrl := createFixtures(t) subject := new(Subject) // Unspecified return should produce "zero" result. ctrl.RecordCall(subject, "FooMethod", "zero") ctrl.RecordCall(subject, "FooMethod", "five").Return(5) assertEqual( t, []interface{}{0}, ctrl.Call(subject, "FooMethod", "zero")) assertEqual( t, []interface{}{5}, ctrl.Call(subject, "FooMethod", "five")) ctrl.Finish() } func TestUnorderedCalls(t *testing.T) { reporter, ctrl := createFixtures(t) defer reporter.recoverUnexpectedFatal() subjectTwo := new(Subject) subjectOne := new(Subject) ctrl.RecordCall(subjectOne, "FooMethod", "1") ctrl.RecordCall(subjectOne, "BarMethod", "2") ctrl.RecordCall(subjectTwo, "FooMethod", "3") ctrl.RecordCall(subjectTwo, "BarMethod", "4") // Make the calls in a different order, which should be fine. ctrl.Call(subjectOne, "BarMethod", "2") ctrl.Call(subjectTwo, "FooMethod", "3") ctrl.Call(subjectTwo, "BarMethod", "4") ctrl.Call(subjectOne, "FooMethod", "1") reporter.assertPass("After making all calls in different order") ctrl.Finish() reporter.assertPass("After finish") } func commonTestOrderedCalls(t *testing.T) (reporter *ErrorReporter, ctrl *gomock.Controller, subjectOne, subjectTwo *Subject) { reporter, ctrl = createFixtures(t) subjectOne = new(Subject) subjectTwo = new(Subject) gomock.InOrder( ctrl.RecordCall(subjectOne, "FooMethod", "1").AnyTimes(), ctrl.RecordCall(subjectTwo, "FooMethod", "2"), ctrl.RecordCall(subjectTwo, "BarMethod", "3"), ) return } func TestOrderedCallsCorrect(t *testing.T) { reporter, ctrl, subjectOne, subjectTwo := commonTestOrderedCalls(t) ctrl.Call(subjectOne, "FooMethod", "1") ctrl.Call(subjectTwo, "FooMethod", "2") ctrl.Call(subjectTwo, "BarMethod", "3") ctrl.Finish() reporter.assertPass("After finish") } func TestOrderedCallsInCorrect(t *testing.T) { reporter, ctrl, subjectOne, subjectTwo := commonTestOrderedCalls(t) ctrl.Call(subjectOne, "FooMethod", "1") reporter.assertFatal(func() { ctrl.Call(subjectTwo, "BarMethod", "3") }) } // Test that calls that are prerequites to other calls but have maxCalls > // minCalls are removed from the expected call set. func TestOrderedCallsWithPreReqMaxUnbounded(t *testing.T) { reporter, ctrl, subjectOne, subjectTwo := commonTestOrderedCalls(t) // Initially we should be able to call FooMethod("1") as many times as we // want. ctrl.Call(subjectOne, "FooMethod", "1") ctrl.Call(subjectOne, "FooMethod", "1") // But calling something that has it as a prerequite should remove it from // the expected call set. This allows tests to ensure that FooMethod("1") is // *not* called after FooMethod("2"). ctrl.Call(subjectTwo, "FooMethod", "2") // Therefore this call should fail: reporter.assertFatal(func() { ctrl.Call(subjectOne, "FooMethod", "1") }) } func TestCallAfterLoopPanic(t *testing.T) { _, ctrl := createFixtures(t) subject := new(Subject) firstCall := ctrl.RecordCall(subject, "FooMethod", "1") secondCall := ctrl.RecordCall(subject, "FooMethod", "2") thirdCall := ctrl.RecordCall(subject, "FooMethod", "3") gomock.InOrder(firstCall, secondCall, thirdCall) defer func() { err := recover() if err == nil { t.Error("Call.After creation of dependency loop did not panic.") } }() // This should panic due to dependency loop. firstCall.After(thirdCall) } func TestPanicOverridesExpectationChecks(t *testing.T) { ctrl := gomock.NewController(t) reporter := NewErrorReporter(t) reporter.assertFatal(func() { ctrl.RecordCall(new(Subject), "FooMethod", "1") defer ctrl.Finish() reporter.Fatalf("Intentional panic") }) } func TestSetArgWithBadType(t *testing.T) { rep, ctrl := createFixtures(t) defer ctrl.Finish() s := new(Subject) // This should catch a type error: rep.assertFatal(func() { ctrl.RecordCall(s, "FooMethod", "1").SetArg(0, "blah") }) ctrl.Call(s, "FooMethod", "1") } func TestTimes0(t *testing.T) { rep, ctrl := createFixtures(t) defer ctrl.Finish() s := new(Subject) ctrl.RecordCall(s, "FooMethod", "arg").Times(0) rep.assertFatal(func() { ctrl.Call(s, "FooMethod", "arg") }) } mock-1.0.0/gomock/matchers.go000066400000000000000000000044101313466237100160620ustar00rootroot00000000000000//go:generate mockgen -destination mock_matcher/mock_matcher.go github.com/golang/mock/gomock Matcher // Copyright 2010 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package gomock import ( "fmt" "reflect" ) // A Matcher is a representation of a class of values. // It is used to represent the valid or expected arguments to a mocked method. type Matcher interface { // Matches returns whether x is a match. Matches(x interface{}) bool // String describes what the matcher matches. String() string } type anyMatcher struct{} func (anyMatcher) Matches(x interface{}) bool { return true } func (anyMatcher) String() string { return "is anything" } type eqMatcher struct { x interface{} } func (e eqMatcher) Matches(x interface{}) bool { return reflect.DeepEqual(e.x, x) } func (e eqMatcher) String() string { return fmt.Sprintf("is equal to %v", e.x) } type nilMatcher struct{} func (nilMatcher) Matches(x interface{}) bool { if x == nil { return true } v := reflect.ValueOf(x) switch v.Kind() { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: return v.IsNil() } return false } func (nilMatcher) String() string { return "is nil" } type notMatcher struct { m Matcher } func (n notMatcher) Matches(x interface{}) bool { return !n.m.Matches(x) } func (n notMatcher) String() string { // TODO: Improve this if we add a NotString method to the Matcher interface. return "not(" + n.m.String() + ")" } // Constructors func Any() Matcher { return anyMatcher{} } func Eq(x interface{}) Matcher { return eqMatcher{x} } func Nil() Matcher { return nilMatcher{} } func Not(x interface{}) Matcher { if m, ok := x.(Matcher); ok { return notMatcher{m} } return notMatcher{Eq(x)} } mock-1.0.0/gomock/matchers_test.go000066400000000000000000000037601313466237100171300ustar00rootroot00000000000000// Copyright 2010 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package gomock_test import ( "errors" "testing" "github.com/golang/mock/gomock" mock_matcher "github.com/golang/mock/gomock/mock_matcher" ) func TestMatchers(t *testing.T) { type e interface{} type testCase struct { matcher gomock.Matcher yes, no []e } tests := []testCase{ testCase{gomock.Any(), []e{3, nil, "foo"}, nil}, testCase{gomock.Eq(4), []e{4}, []e{3, "blah", nil, int64(4)}}, testCase{gomock.Nil(), []e{nil, (error)(nil), (chan bool)(nil), (*int)(nil)}, []e{"", 0, make(chan bool), errors.New("err"), new(int)}}, testCase{gomock.Not(gomock.Eq(4)), []e{3, "blah", nil, int64(4)}, []e{4}}, } for i, test := range tests { for _, x := range test.yes { if !test.matcher.Matches(x) { t.Errorf(`test %d: "%v %s" should be true.`, i, x, test.matcher) } } for _, x := range test.no { if test.matcher.Matches(x) { t.Errorf(`test %d: "%v %s" should be false.`, i, x, test.matcher) } } } } // A more thorough test of notMatcher func TestNotMatcher(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockMatcher := mock_matcher.NewMockMatcher(ctrl) notMatcher := gomock.Not(mockMatcher) mockMatcher.EXPECT().Matches(4).Return(true) if match := notMatcher.Matches(4); match { t.Errorf("notMatcher should not match 4") } mockMatcher.EXPECT().Matches(5).Return(false) if match := notMatcher.Matches(5); !match { t.Errorf("notMatcher should match 5") } } mock-1.0.0/gomock/mock_matcher/000077500000000000000000000000001313466237100163625ustar00rootroot00000000000000mock-1.0.0/gomock/mock_matcher/mock_matcher.go000066400000000000000000000031171313466237100213470ustar00rootroot00000000000000// Code generated by MockGen. DO NOT EDIT. // Source: github.com/golang/mock/gomock (interfaces: Matcher) package mock_gomock import ( gomock "github.com/golang/mock/gomock" reflect "reflect" ) // MockMatcher is a mock of Matcher interface type MockMatcher struct { ctrl *gomock.Controller recorder *MockMatcherMockRecorder } // MockMatcherMockRecorder is the mock recorder for MockMatcher type MockMatcherMockRecorder struct { mock *MockMatcher } // NewMockMatcher creates a new mock instance func NewMockMatcher(ctrl *gomock.Controller) *MockMatcher { mock := &MockMatcher{ctrl: ctrl} mock.recorder = &MockMatcherMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use func (_m *MockMatcher) EXPECT() *MockMatcherMockRecorder { return _m.recorder } // Matches mocks base method func (_m *MockMatcher) Matches(_param0 interface{}) bool { ret := _m.ctrl.Call(_m, "Matches", _param0) ret0, _ := ret[0].(bool) return ret0 } // Matches indicates an expected call of Matches func (_mr *MockMatcherMockRecorder) Matches(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Matches", reflect.TypeOf((*MockMatcher)(nil).Matches), arg0) } // String mocks base method func (_m *MockMatcher) String() string { ret := _m.ctrl.Call(_m, "String") ret0, _ := ret[0].(string) return ret0 } // String indicates an expected call of String func (_mr *MockMatcherMockRecorder) String() *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "String", reflect.TypeOf((*MockMatcher)(nil).String)) } mock-1.0.0/mockgen/000077500000000000000000000000001313466237100140725ustar00rootroot00000000000000mock-1.0.0/mockgen/mockgen.go000066400000000000000000000264711313466237100160560ustar00rootroot00000000000000// Copyright 2010 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // MockGen generates mock implementations of Go interfaces. package main // TODO: This does not support recursive embedded interfaces. // TODO: This does not support embedding package-local interfaces in a separate file. import ( "bytes" "flag" "fmt" "go/format" "go/token" "io" "log" "os" "path" "sort" "strconv" "strings" "unicode" "github.com/golang/mock/mockgen/model" ) const ( gomockImportPath = "github.com/golang/mock/gomock" ) var ( source = flag.String("source", "", "(source mode) Input Go source file; enables source mode.") destination = flag.String("destination", "", "Output file; defaults to stdout.") packageOut = flag.String("package", "", "Package of the generated code; defaults to the package of the input with a 'mock_' prefix.") selfPackage = flag.String("self_package", "", "If set, the package this mock will be part of.") debugParser = flag.Bool("debug_parser", false, "Print out parser results only.") ) func main() { flag.Usage = usage flag.Parse() var pkg *model.Package var err error if *source != "" { pkg, err = ParseFile(*source) } else { if flag.NArg() != 2 { usage() log.Fatal("Expected exactly two arguments") } pkg, err = Reflect(flag.Arg(0), strings.Split(flag.Arg(1), ",")) } if err != nil { log.Fatalf("Loading input failed: %v", err) } if *debugParser { pkg.Print(os.Stdout) return } dst := os.Stdout if len(*destination) > 0 { f, err := os.Create(*destination) if err != nil { log.Fatalf("Failed opening destination file: %v", err) } defer f.Close() dst = f } packageName := *packageOut if packageName == "" { // pkg.Name in reflect mode is the base name of the import path, // which might have characters that are illegal to have in package names. packageName = "mock_" + sanitize(pkg.Name) } g := new(generator) if *source != "" { g.filename = *source } else { g.srcPackage = flag.Arg(0) g.srcInterfaces = flag.Arg(1) } if err := g.Generate(pkg, packageName); err != nil { log.Fatalf("Failed generating mock: %v", err) } if _, err := dst.Write(g.Output()); err != nil { log.Fatalf("Failed writing to destination: %v", err) } } func usage() { io.WriteString(os.Stderr, usageText) flag.PrintDefaults() } const usageText = `mockgen has two modes of operation: source and reflect. Source mode generates mock interfaces from a source file. It is enabled by using the -source flag. Other flags that may be useful in this mode are -imports and -aux_files. Example: mockgen -source=foo.go [other options] Reflect mode generates mock interfaces by building a program that uses reflection to understand interfaces. It is enabled by passing two non-flag arguments: an import path, and a comma-separated list of symbols. Example: mockgen database/sql/driver Conn,Driver ` type generator struct { buf bytes.Buffer indent string filename string // may be empty srcPackage, srcInterfaces string // may be empty packageMap map[string]string // map from import path to package name } func (g *generator) p(format string, args ...interface{}) { fmt.Fprintf(&g.buf, g.indent+format+"\n", args...) } func (g *generator) in() { g.indent += "\t" } func (g *generator) out() { if len(g.indent) > 0 { g.indent = g.indent[0 : len(g.indent)-1] } } func removeDot(s string) string { if len(s) > 0 && s[len(s)-1] == '.' { return s[0 : len(s)-1] } return s } // sanitize cleans up a string to make a suitable package name. func sanitize(s string) string { t := "" for _, r := range s { if t == "" { if unicode.IsLetter(r) || r == '_' { t += string(r) continue } } else { if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' { t += string(r) continue } } t += "_" } if t == "_" { t = "x" } return t } func (g *generator) Generate(pkg *model.Package, pkgName string) error { g.p("// Code generated by MockGen. DO NOT EDIT.") if g.filename != "" { g.p("// Source: %v", g.filename) } else { g.p("// Source: %v (interfaces: %v)", g.srcPackage, g.srcInterfaces) } g.p("") // Get all required imports, and generate unique names for them all. im := pkg.Imports() im[gomockImportPath] = true im["reflect"] = true // Sort keys to make import alias generation predictable sorted_paths := make([]string, len(im), len(im)) x := 0 for pth := range im { sorted_paths[x] = pth x++ } sort.Strings(sorted_paths) g.packageMap = make(map[string]string, len(im)) localNames := make(map[string]bool, len(im)) for _, pth := range sorted_paths { base := sanitize(path.Base(pth)) // Local names for an imported package can usually be the basename of the import path. // A couple of situations don't permit that, such as duplicate local names // (e.g. importing "html/template" and "text/template"), or where the basename is // a keyword (e.g. "foo/case"). // try base0, base1, ... pkgName := base i := 0 for localNames[pkgName] || token.Lookup(pkgName).IsKeyword() { pkgName = base + strconv.Itoa(i) i++ } g.packageMap[pth] = pkgName localNames[pkgName] = true } g.p("package %v", pkgName) g.p("") g.p("import (") g.in() for path, pkg := range g.packageMap { if path == *selfPackage { continue } g.p("%v %q", pkg, path) } for _, path := range pkg.DotImports { g.p(". %q", path) } g.out() g.p(")") for _, intf := range pkg.Interfaces { if err := g.GenerateMockInterface(intf); err != nil { return err } } return nil } // The name of the mock type to use for the given interface identifier. func mockName(typeName string) string { return "Mock" + typeName } func (g *generator) GenerateMockInterface(intf *model.Interface) error { mockType := mockName(intf.Name) g.p("") g.p("// %v is a mock of %v interface", mockType, intf.Name) g.p("type %v struct {", mockType) g.in() g.p("ctrl *gomock.Controller") g.p("recorder *%vMockRecorder", mockType) g.out() g.p("}") g.p("") g.p("// %vMockRecorder is the mock recorder for %v", mockType, mockType) g.p("type %vMockRecorder struct {", mockType) g.in() g.p("mock *%v", mockType) g.out() g.p("}") g.p("") // TODO: Re-enable this if we can import the interface reliably. //g.p("// Verify that the mock satisfies the interface at compile time.") //g.p("var _ %v = (*%v)(nil)", typeName, mockType) //g.p("") g.p("// New%v creates a new mock instance", mockType) g.p("func New%v(ctrl *gomock.Controller) *%v {", mockType, mockType) g.in() g.p("mock := &%v{ctrl: ctrl}", mockType) g.p("mock.recorder = &%vMockRecorder{mock}", mockType) g.p("return mock") g.out() g.p("}") g.p("") // XXX: possible name collision here if someone has EXPECT in their interface. g.p("// EXPECT returns an object that allows the caller to indicate expected use") g.p("func (_m *%v) EXPECT() *%vMockRecorder {", mockType, mockType) g.in() g.p("return _m.recorder") g.out() g.p("}") g.GenerateMockMethods(mockType, intf, *selfPackage) return nil } func (g *generator) GenerateMockMethods(mockType string, intf *model.Interface, pkgOverride string) { for _, m := range intf.Methods { g.p("") g.GenerateMockMethod(mockType, m, pkgOverride) g.p("") g.GenerateMockRecorderMethod(mockType, m) } } // GenerateMockMethod generates a mock method implementation. // If non-empty, pkgOverride is the package in which unqualified types reside. func (g *generator) GenerateMockMethod(mockType string, m *model.Method, pkgOverride string) error { args := make([]string, len(m.In)) argNames := make([]string, len(m.In)) for i, p := range m.In { name := p.Name if name == "" { name = fmt.Sprintf("_param%d", i) } ts := p.Type.String(g.packageMap, pkgOverride) args[i] = name + " " + ts argNames[i] = name } if m.Variadic != nil { name := m.Variadic.Name if name == "" { name = fmt.Sprintf("_param%d", len(m.In)) } ts := m.Variadic.Type.String(g.packageMap, pkgOverride) args = append(args, name+" ..."+ts) argNames = append(argNames, name) } argString := strings.Join(args, ", ") rets := make([]string, len(m.Out)) for i, p := range m.Out { rets[i] = p.Type.String(g.packageMap, pkgOverride) } retString := strings.Join(rets, ", ") if len(rets) > 1 { retString = "(" + retString + ")" } if retString != "" { retString = " " + retString } g.p("// %v mocks base method", m.Name) g.p("func (_m *%v) %v(%v)%v {", mockType, m.Name, argString, retString) g.in() callArgs := strings.Join(argNames, ", ") if callArgs != "" { callArgs = ", " + callArgs } if m.Variadic != nil { // Non-trivial. The generated code must build a []interface{}, // but the variadic argument may be any type. g.p("_s := []interface{}{%s}", strings.Join(argNames[:len(argNames)-1], ", ")) g.p("for _, _x := range %s {", argNames[len(argNames)-1]) g.in() g.p("_s = append(_s, _x)") g.out() g.p("}") callArgs = ", _s..." } if len(m.Out) == 0 { g.p(`_m.ctrl.Call(_m, "%v"%v)`, m.Name, callArgs) } else { g.p(`ret := _m.ctrl.Call(_m, "%v"%v)`, m.Name, callArgs) // Go does not allow "naked" type assertions on nil values, so we use the two-value form here. // The value of that is either (x.(T), true) or (Z, false), where Z is the zero value for T. // Happily, this coincides with the semantics we want here. retNames := make([]string, len(rets)) for i, t := range rets { retNames[i] = fmt.Sprintf("ret%d", i) g.p("%s, _ := ret[%d].(%s)", retNames[i], i, t) } g.p("return " + strings.Join(retNames, ", ")) } g.out() g.p("}") return nil } func (g *generator) GenerateMockRecorderMethod(mockType string, m *model.Method) error { nargs := len(m.In) args := make([]string, nargs) for i := 0; i < nargs; i++ { args[i] = "arg" + strconv.Itoa(i) } argString := strings.Join(args, ", ") if nargs > 0 { argString += " interface{}" } if m.Variadic != nil { if nargs > 0 { argString += ", " } argString += fmt.Sprintf("arg%d ...interface{}", nargs) } g.p("// %v indicates an expected call of %v", m.Name, m.Name) g.p("func (_mr *%vMockRecorder) %v(%v) *gomock.Call {", mockType, m.Name, argString) g.in() callArgs := strings.Join(args, ", ") if nargs > 0 { callArgs = ", " + callArgs } if m.Variadic != nil { if nargs == 0 { // Easy: just use ... to push the arguments through. callArgs = ", arg0..." } else { // Hard: create a temporary slice. g.p("_s := append([]interface{}{%s}, arg%d...)", strings.Join(args, ", "), nargs) callArgs = ", _s..." } } g.p(`return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "%s", reflect.TypeOf((*%s)(nil).%s)%s)`, m.Name, mockType, m.Name, callArgs) g.out() g.p("}") return nil } // Output returns the generator's output, formatted in the standard Go style. func (g *generator) Output() []byte { src, err := format.Source(g.buf.Bytes()) if err != nil { log.Fatalf("Failed to format generated source code: %s\n%s", err, g.buf.String()) } return src } mock-1.0.0/mockgen/model/000077500000000000000000000000001313466237100151725ustar00rootroot00000000000000mock-1.0.0/mockgen/model/model.go000066400000000000000000000233531313466237100166270ustar00rootroot00000000000000// Copyright 2012 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package model contains the data model necessary for generating mock implementations. package model import ( "encoding/gob" "fmt" "io" "reflect" "strings" ) // Package is a Go package. It may be a subset. type Package struct { Name string Interfaces []*Interface DotImports []string } func (pkg *Package) Print(w io.Writer) { fmt.Fprintf(w, "package %s\n", pkg.Name) for _, intf := range pkg.Interfaces { intf.Print(w) } } // Imports returns the imports needed by the Package as a set of import paths. func (pkg *Package) Imports() map[string]bool { im := make(map[string]bool) for _, intf := range pkg.Interfaces { intf.addImports(im) } return im } // Interface is a Go interface. type Interface struct { Name string Methods []*Method } func (intf *Interface) Print(w io.Writer) { fmt.Fprintf(w, "interface %s\n", intf.Name) for _, m := range intf.Methods { m.Print(w) } } func (intf *Interface) addImports(im map[string]bool) { for _, m := range intf.Methods { m.addImports(im) } } // Method is a single method of an interface. type Method struct { Name string In, Out []*Parameter Variadic *Parameter // may be nil } func (m *Method) Print(w io.Writer) { fmt.Fprintf(w, " - method %s\n", m.Name) if len(m.In) > 0 { fmt.Fprintf(w, " in:\n") for _, p := range m.In { p.Print(w) } } if m.Variadic != nil { fmt.Fprintf(w, " ...:\n") m.Variadic.Print(w) } if len(m.Out) > 0 { fmt.Fprintf(w, " out:\n") for _, p := range m.Out { p.Print(w) } } } func (m *Method) addImports(im map[string]bool) { for _, p := range m.In { p.Type.addImports(im) } if m.Variadic != nil { m.Variadic.Type.addImports(im) } for _, p := range m.Out { p.Type.addImports(im) } } // Parameter is an argument or return parameter of a method. type Parameter struct { Name string // may be empty Type Type } func (p *Parameter) Print(w io.Writer) { n := p.Name if n == "" { n = `""` } fmt.Fprintf(w, " - %v: %v\n", n, p.Type.String(nil, "")) } // Type is a Go type. type Type interface { String(pm map[string]string, pkgOverride string) string addImports(im map[string]bool) } func init() { gob.Register(&ArrayType{}) gob.Register(&ChanType{}) gob.Register(&FuncType{}) gob.Register(&MapType{}) gob.Register(&NamedType{}) gob.Register(&PointerType{}) gob.Register(PredeclaredType("")) } // ArrayType is an array or slice type. type ArrayType struct { Len int // -1 for slices, >= 0 for arrays Type Type } func (at *ArrayType) String(pm map[string]string, pkgOverride string) string { s := "[]" if at.Len > -1 { s = fmt.Sprintf("[%d]", at.Len) } return s + at.Type.String(pm, pkgOverride) } func (at *ArrayType) addImports(im map[string]bool) { at.Type.addImports(im) } // ChanType is a channel type. type ChanType struct { Dir ChanDir // 0, 1 or 2 Type Type } func (ct *ChanType) String(pm map[string]string, pkgOverride string) string { s := ct.Type.String(pm, pkgOverride) if ct.Dir == RecvDir { return "<-chan " + s } if ct.Dir == SendDir { return "chan<- " + s } return "chan " + s } func (ct *ChanType) addImports(im map[string]bool) { ct.Type.addImports(im) } // ChanDir is a channel direction. type ChanDir int const ( RecvDir ChanDir = 1 SendDir ChanDir = 2 ) // FuncType is a function type. type FuncType struct { In, Out []*Parameter Variadic *Parameter // may be nil } func (ft *FuncType) String(pm map[string]string, pkgOverride string) string { args := make([]string, len(ft.In)) for i, p := range ft.In { args[i] = p.Type.String(pm, pkgOverride) } if ft.Variadic != nil { args = append(args, "..."+ft.Variadic.Type.String(pm, pkgOverride)) } rets := make([]string, len(ft.Out)) for i, p := range ft.Out { rets[i] = p.Type.String(pm, pkgOverride) } retString := strings.Join(rets, ", ") if nOut := len(ft.Out); nOut == 1 { retString = " " + retString } else if nOut > 1 { retString = " (" + retString + ")" } return "func(" + strings.Join(args, ", ") + ")" + retString } func (ft *FuncType) addImports(im map[string]bool) { for _, p := range ft.In { p.Type.addImports(im) } if ft.Variadic != nil { ft.Variadic.Type.addImports(im) } for _, p := range ft.Out { p.Type.addImports(im) } } // MapType is a map type. type MapType struct { Key, Value Type } func (mt *MapType) String(pm map[string]string, pkgOverride string) string { return "map[" + mt.Key.String(pm, pkgOverride) + "]" + mt.Value.String(pm, pkgOverride) } func (mt *MapType) addImports(im map[string]bool) { mt.Key.addImports(im) mt.Value.addImports(im) } // NamedType is an exported type in a package. type NamedType struct { Package string // may be empty Type string // TODO: should this be typed Type? } func (nt *NamedType) String(pm map[string]string, pkgOverride string) string { // TODO: is this right? if pkgOverride == nt.Package { return nt.Type } return pm[nt.Package] + "." + nt.Type } func (nt *NamedType) addImports(im map[string]bool) { if nt.Package != "" { im[nt.Package] = true } } // PointerType is a pointer to another type. type PointerType struct { Type Type } func (pt *PointerType) String(pm map[string]string, pkgOverride string) string { return "*" + pt.Type.String(pm, pkgOverride) } func (pt *PointerType) addImports(im map[string]bool) { pt.Type.addImports(im) } // PredeclaredType is a predeclared type such as "int". type PredeclaredType string func (pt PredeclaredType) String(pm map[string]string, pkgOverride string) string { return string(pt) } func (pt PredeclaredType) addImports(im map[string]bool) {} // The following code is intended to be called by the program generated by ../reflect.go. func InterfaceFromInterfaceType(it reflect.Type) (*Interface, error) { if it.Kind() != reflect.Interface { return nil, fmt.Errorf("%v is not an interface", it) } intf := &Interface{} for i := 0; i < it.NumMethod(); i++ { mt := it.Method(i) // TODO: need to skip unexported methods? or just raise an error? m := &Method{ Name: mt.Name, } var err error m.In, m.Variadic, m.Out, err = funcArgsFromType(mt.Type) if err != nil { return nil, err } intf.Methods = append(intf.Methods, m) } return intf, nil } // t's Kind must be a reflect.Func. func funcArgsFromType(t reflect.Type) (in []*Parameter, variadic *Parameter, out []*Parameter, err error) { nin := t.NumIn() if t.IsVariadic() { nin-- } var p *Parameter for i := 0; i < nin; i++ { p, err = parameterFromType(t.In(i)) if err != nil { return } in = append(in, p) } if t.IsVariadic() { p, err = parameterFromType(t.In(nin).Elem()) if err != nil { return } variadic = p } for i := 0; i < t.NumOut(); i++ { p, err = parameterFromType(t.Out(i)) if err != nil { return } out = append(out, p) } return } func parameterFromType(t reflect.Type) (*Parameter, error) { tt, err := typeFromType(t) if err != nil { return nil, err } return &Parameter{Type: tt}, nil } var errorType = reflect.TypeOf((*error)(nil)).Elem() var byteType = reflect.TypeOf(byte(0)) func typeFromType(t reflect.Type) (Type, error) { // Hack workaround for https://golang.org/issue/3853. // This explicit check should not be necessary. if t == byteType { return PredeclaredType("byte"), nil } if imp := t.PkgPath(); imp != "" { return &NamedType{ Package: imp, Type: t.Name(), }, nil } // only unnamed or predeclared types after here // Lots of types have element types. Let's do the parsing and error checking for all of them. var elemType Type switch t.Kind() { case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice: var err error elemType, err = typeFromType(t.Elem()) if err != nil { return nil, err } } switch t.Kind() { case reflect.Array: return &ArrayType{ Len: t.Len(), Type: elemType, }, nil case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String: return PredeclaredType(t.Kind().String()), nil case reflect.Chan: var dir ChanDir switch t.ChanDir() { case reflect.RecvDir: dir = RecvDir case reflect.SendDir: dir = SendDir } return &ChanType{ Dir: dir, Type: elemType, }, nil case reflect.Func: in, variadic, out, err := funcArgsFromType(t) if err != nil { return nil, err } return &FuncType{ In: in, Out: out, Variadic: variadic, }, nil case reflect.Interface: // Two special interfaces. if t.NumMethod() == 0 { return PredeclaredType("interface{}"), nil } if t == errorType { return PredeclaredType("error"), nil } case reflect.Map: kt, err := typeFromType(t.Key()) if err != nil { return nil, err } return &MapType{ Key: kt, Value: elemType, }, nil case reflect.Ptr: return &PointerType{ Type: elemType, }, nil case reflect.Slice: return &ArrayType{ Len: -1, Type: elemType, }, nil case reflect.Struct: if t.NumField() == 0 { return PredeclaredType("struct{}"), nil } } // TODO: Struct, UnsafePointer return nil, fmt.Errorf("can't yet turn %v (%v) into a model.Type", t, t.Kind()) } mock-1.0.0/mockgen/parse.go000066400000000000000000000271621313466237100155430ustar00rootroot00000000000000// Copyright 2012 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main // This file contains the model construction by parsing source files. import ( "flag" "fmt" "go/ast" "go/parser" "go/token" "log" "path" "strconv" "strings" "github.com/golang/mock/mockgen/model" ) var ( imports = flag.String("imports", "", "(source mode) Comma-separated name=path pairs of explicit imports to use.") auxFiles = flag.String("aux_files", "", "(source mode) Comma-separated pkg=path pairs of auxiliary Go source files.") ) // TODO: simplify error reporting func ParseFile(source string) (*model.Package, error) { fs := token.NewFileSet() file, err := parser.ParseFile(fs, source, nil, 0) if err != nil { return nil, fmt.Errorf("failed parsing source file %v: %v", source, err) } p := &fileParser{ fileSet: fs, imports: make(map[string]string), auxInterfaces: make(map[string]map[string]*ast.InterfaceType), } // Handle -imports. dotImports := make(map[string]bool) if *imports != "" { for _, kv := range strings.Split(*imports, ",") { eq := strings.Index(kv, "=") k, v := kv[:eq], kv[eq+1:] if k == "." { // TODO: Catch dupes? dotImports[v] = true } else { // TODO: Catch dupes? p.imports[k] = v } } } // Handle -aux_files. if err := p.parseAuxFiles(*auxFiles); err != nil { return nil, err } p.addAuxInterfacesFromFile("", file) // this file pkg, err := p.parseFile(file) if err != nil { return nil, err } pkg.DotImports = make([]string, 0, len(dotImports)) for path := range dotImports { pkg.DotImports = append(pkg.DotImports, path) } return pkg, nil } type fileParser struct { fileSet *token.FileSet imports map[string]string // package name => import path auxFiles []*ast.File auxInterfaces map[string]map[string]*ast.InterfaceType // package (or "") => name => interface } func (p *fileParser) errorf(pos token.Pos, format string, args ...interface{}) error { ps := p.fileSet.Position(pos) format = "%s:%d:%d: " + format args = append([]interface{}{ps.Filename, ps.Line, ps.Column}, args...) return fmt.Errorf(format, args...) } func (p *fileParser) parseAuxFiles(auxFiles string) error { auxFiles = strings.TrimSpace(auxFiles) if auxFiles == "" { return nil } for _, kv := range strings.Split(auxFiles, ",") { parts := strings.SplitN(kv, "=", 2) if len(parts) != 2 { return fmt.Errorf("bad aux file spec: %v", kv) } file, err := parser.ParseFile(p.fileSet, parts[1], nil, 0) if err != nil { return err } p.auxFiles = append(p.auxFiles, file) p.addAuxInterfacesFromFile(parts[0], file) } return nil } func (p *fileParser) addAuxInterfacesFromFile(pkg string, file *ast.File) { if _, ok := p.auxInterfaces[pkg]; !ok { p.auxInterfaces[pkg] = make(map[string]*ast.InterfaceType) } for ni := range iterInterfaces(file) { p.auxInterfaces[pkg][ni.name.Name] = ni.it } } func (p *fileParser) parseFile(file *ast.File) (*model.Package, error) { allImports := importsOfFile(file) // Don't stomp imports provided by -imports. Those should take precedence. for pkg, path := range allImports { if _, ok := p.imports[pkg]; !ok { p.imports[pkg] = path } } // Add imports from auxiliary files, which might be needed for embedded interfaces. // Don't stomp any other imports. for _, f := range p.auxFiles { for pkg, path := range importsOfFile(f) { if _, ok := p.imports[pkg]; !ok { p.imports[pkg] = path } } } var is []*model.Interface for ni := range iterInterfaces(file) { i, err := p.parseInterface(ni.name.String(), "", ni.it) if err != nil { return nil, err } is = append(is, i) } return &model.Package{ Name: file.Name.String(), Interfaces: is, }, nil } func (p *fileParser) parseInterface(name, pkg string, it *ast.InterfaceType) (*model.Interface, error) { intf := &model.Interface{Name: name} for _, field := range it.Methods.List { switch v := field.Type.(type) { case *ast.FuncType: if nn := len(field.Names); nn != 1 { return nil, fmt.Errorf("expected one name for interface %v, got %d", intf.Name, nn) } m := &model.Method{ Name: field.Names[0].String(), } var err error m.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v) if err != nil { return nil, err } intf.Methods = append(intf.Methods, m) case *ast.Ident: // Embedded interface in this package. ei := p.auxInterfaces[""][v.String()] if ei == nil { return nil, p.errorf(v.Pos(), "unknown embedded interface %s", v.String()) } eintf, err := p.parseInterface(v.String(), pkg, ei) if err != nil { return nil, err } // Copy the methods. // TODO: apply shadowing rules. for _, m := range eintf.Methods { intf.Methods = append(intf.Methods, m) } case *ast.SelectorExpr: // Embedded interface in another package. fpkg, sel := v.X.(*ast.Ident).String(), v.Sel.String() ei := p.auxInterfaces[fpkg][sel] if ei == nil { return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", fpkg, sel) } epkg, ok := p.imports[fpkg] if !ok { return nil, p.errorf(v.X.Pos(), "unknown package %s", fpkg) } eintf, err := p.parseInterface(sel, epkg, ei) if err != nil { return nil, err } // Copy the methods. // TODO: apply shadowing rules. for _, m := range eintf.Methods { intf.Methods = append(intf.Methods, m) } default: return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type) } } return intf, nil } func (p *fileParser) parseFunc(pkg string, f *ast.FuncType) (in []*model.Parameter, variadic *model.Parameter, out []*model.Parameter, err error) { if f.Params != nil { regParams := f.Params.List if isVariadic(f) { n := len(regParams) varParams := regParams[n-1:] regParams = regParams[:n-1] vp, err := p.parseFieldList(pkg, varParams) if err != nil { return nil, nil, nil, p.errorf(varParams[0].Pos(), "failed parsing variadic argument: %v", err) } variadic = vp[0] } in, err = p.parseFieldList(pkg, regParams) if err != nil { return nil, nil, nil, p.errorf(f.Pos(), "failed parsing arguments: %v", err) } } if f.Results != nil { out, err = p.parseFieldList(pkg, f.Results.List) if err != nil { return nil, nil, nil, p.errorf(f.Pos(), "failed parsing returns: %v", err) } } return } func (p *fileParser) parseFieldList(pkg string, fields []*ast.Field) ([]*model.Parameter, error) { nf := 0 for _, f := range fields { nn := len(f.Names) if nn == 0 { nn = 1 // anonymous parameter } nf += nn } if nf == 0 { return nil, nil } ps := make([]*model.Parameter, nf) i := 0 // destination index for _, f := range fields { t, err := p.parseType(pkg, f.Type) if err != nil { return nil, err } if len(f.Names) == 0 { // anonymous arg ps[i] = &model.Parameter{Type: t} i++ continue } for _, name := range f.Names { ps[i] = &model.Parameter{Name: name.Name, Type: t} i++ } } return ps, nil } func (p *fileParser) parseType(pkg string, typ ast.Expr) (model.Type, error) { switch v := typ.(type) { case *ast.ArrayType: ln := -1 if v.Len != nil { x, err := strconv.Atoi(v.Len.(*ast.BasicLit).Value) if err != nil { return nil, p.errorf(v.Len.Pos(), "bad array size: %v", err) } ln = x } t, err := p.parseType(pkg, v.Elt) if err != nil { return nil, err } return &model.ArrayType{Len: ln, Type: t}, nil case *ast.ChanType: t, err := p.parseType(pkg, v.Value) if err != nil { return nil, err } var dir model.ChanDir if v.Dir == ast.SEND { dir = model.SendDir } if v.Dir == ast.RECV { dir = model.RecvDir } return &model.ChanType{Dir: dir, Type: t}, nil case *ast.Ellipsis: // assume we're parsing a variadic argument return p.parseType(pkg, v.Elt) case *ast.FuncType: in, variadic, out, err := p.parseFunc(pkg, v) if err != nil { return nil, err } return &model.FuncType{In: in, Out: out, Variadic: variadic}, nil case *ast.Ident: if v.IsExported() { // assume type in this package return &model.NamedType{Package: pkg, Type: v.Name}, nil } else { // assume predeclared type return model.PredeclaredType(v.Name), nil } case *ast.InterfaceType: if v.Methods != nil && len(v.Methods.List) > 0 { return nil, p.errorf(v.Pos(), "can't handle non-empty unnamed interface types") } return model.PredeclaredType("interface{}"), nil case *ast.MapType: key, err := p.parseType(pkg, v.Key) if err != nil { return nil, err } value, err := p.parseType(pkg, v.Value) if err != nil { return nil, err } return &model.MapType{Key: key, Value: value}, nil case *ast.SelectorExpr: pkgName := v.X.(*ast.Ident).String() pkg, ok := p.imports[pkgName] if !ok { return nil, p.errorf(v.Pos(), "unknown package %q", pkgName) } return &model.NamedType{Package: pkg, Type: v.Sel.String()}, nil case *ast.StarExpr: t, err := p.parseType(pkg, v.X) if err != nil { return nil, err } return &model.PointerType{Type: t}, nil case *ast.StructType: if v.Fields != nil && len(v.Fields.List) > 0 { return nil, p.errorf(v.Pos(), "can't handle non-empty unnamed struct types") } return model.PredeclaredType("struct{}"), nil } return nil, fmt.Errorf("don't know how to parse type %T", typ) } // importsOfFile returns a map of package name to import path // of the imports in file. func importsOfFile(file *ast.File) map[string]string { /* We have to make guesses about some imports, because imports are not required * to have names. Named imports are always certain. Unnamed imports are guessed * to have a name of the last path component; if the last path component has dots, * the first dot-delimited field is used as the name. */ m := make(map[string]string) for _, decl := range file.Decls { gd, ok := decl.(*ast.GenDecl) if !ok || gd.Tok != token.IMPORT { continue } for _, spec := range gd.Specs { is, ok := spec.(*ast.ImportSpec) if !ok { continue } pkg, importPath := "", string(is.Path.Value) importPath = importPath[1 : len(importPath)-1] // remove quotes if is.Name != nil { if is.Name.Name == "_" { continue } pkg = removeDot(is.Name.Name) } else { _, last := path.Split(importPath) pkg = strings.SplitN(last, ".", 2)[0] } if _, ok := m[pkg]; ok { log.Fatalf("imported package collision: %q imported twice", pkg) } m[pkg] = importPath } } return m } type namedInterface struct { name *ast.Ident it *ast.InterfaceType } // Create an iterator over all interfaces in file. func iterInterfaces(file *ast.File) <-chan namedInterface { ch := make(chan namedInterface) go func() { for _, decl := range file.Decls { gd, ok := decl.(*ast.GenDecl) if !ok || gd.Tok != token.TYPE { continue } for _, spec := range gd.Specs { ts, ok := spec.(*ast.TypeSpec) if !ok { continue } it, ok := ts.Type.(*ast.InterfaceType) if !ok { continue } ch <- namedInterface{ts.Name, it} } } close(ch) }() return ch } // isVariadic returns whether the function is variadic. func isVariadic(f *ast.FuncType) bool { nargs := len(f.Params.List) if nargs == 0 { return false } _, ok := f.Params.List[nargs-1].Type.(*ast.Ellipsis) return ok } mock-1.0.0/mockgen/reflect.go000066400000000000000000000100701313466237100160430ustar00rootroot00000000000000// Copyright 2012 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main // This file contains the model construction by reflection. import ( "bytes" "encoding/gob" "flag" "io" "io/ioutil" "os" "os/exec" "path/filepath" "runtime" "text/template" "github.com/golang/mock/mockgen/model" ) var ( progOnly = flag.Bool("prog_only", false, "(reflect mode) Only generate the reflection program; write it to stdout.") execOnly = flag.String("exec_only", "", "(reflect mode) If set, execute this reflection program.") buildFlags = flag.String("build_flags", "", "(reflect mode) Additional flags for go build.") ) func Reflect(importPath string, symbols []string) (*model.Package, error) { // TODO: sanity check arguments progPath := *execOnly if *execOnly == "" { // We use TempDir instead of TempFile so we can control the filename. tmpDir, err := ioutil.TempDir("", "gomock_reflect_") if err != nil { return nil, err } defer func() { os.RemoveAll(tmpDir) }() const progSource = "prog.go" var progBinary = "prog.bin" if runtime.GOOS == "windows" { // Windows won't execute a program unless it has a ".exe" suffix. progBinary += ".exe" } // Generate program. var program bytes.Buffer data := reflectData{ ImportPath: importPath, Symbols: symbols, } if err := reflectProgram.Execute(&program, &data); err != nil { return nil, err } if *progOnly { io.Copy(os.Stdout, &program) os.Exit(0) } if err := ioutil.WriteFile(filepath.Join(tmpDir, progSource), program.Bytes(), 0600); err != nil { return nil, err } cmdArgs := []string{} cmdArgs = append(cmdArgs, "build") if *buildFlags != "" { cmdArgs = append(cmdArgs, *buildFlags) } cmdArgs = append(cmdArgs, "-o", progBinary, progSource) // Build the program. cmd := exec.Command("go", cmdArgs...) cmd.Dir = tmpDir cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return nil, err } progPath = filepath.Join(tmpDir, progBinary) } // Run it. cmd := exec.Command(progPath) var stdout bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return nil, err } // Process output. var pkg model.Package if err := gob.NewDecoder(&stdout).Decode(&pkg); err != nil { return nil, err } return &pkg, nil } type reflectData struct { ImportPath string Symbols []string } // This program reflects on an interface value, and prints the // gob encoding of a model.Package to standard output. // JSON doesn't work because of the model.Type interface. var reflectProgram = template.Must(template.New("program").Parse(` package main import ( "encoding/gob" "fmt" "os" "path" "reflect" "github.com/golang/mock/mockgen/model" pkg_ {{printf "%q" .ImportPath}} ) func main() { its := []struct{ sym string typ reflect.Type }{ {{range .Symbols}} { {{printf "%q" .}}, reflect.TypeOf((*pkg_.{{.}})(nil)).Elem()}, {{end}} } pkg := &model.Package{ // NOTE: This behaves contrary to documented behaviour if the // package name is not the final component of the import path. // The reflect package doesn't expose the package name, though. Name: path.Base({{printf "%q" .ImportPath}}), } for _, it := range its { intf, err := model.InterfaceFromInterfaceType(it.typ) if err != nil { fmt.Fprintf(os.Stderr, "Reflection: %v\n", err) os.Exit(1) } intf.Name = it.sym pkg.Interfaces = append(pkg.Interfaces, intf) } if err := gob.NewEncoder(os.Stdout).Encode(pkg); err != nil { fmt.Fprintf(os.Stderr, "gob encode: %v\n", err) os.Exit(1) } } `)) mock-1.0.0/mockgen/tests/000077500000000000000000000000001313466237100152345ustar00rootroot00000000000000mock-1.0.0/mockgen/tests/unexported_method/000077500000000000000000000000001313466237100207715ustar00rootroot00000000000000mock-1.0.0/mockgen/tests/unexported_method/README.md000066400000000000000000000001031313466237100222420ustar00rootroot00000000000000From #52, this tests an unexported method in the mocked interface. mock-1.0.0/mockgen/tests/unexported_method/bugreport.go000066400000000000000000000005631313466237100233350ustar00rootroot00000000000000//go:generate mockgen -destination bugreport_mock.go -package bugreport -source=bugreport.go Example package bugreport import "fmt" // Example is an interface with a non exported method type Example interface { someMethod(string) string } // CallExample is a simple function that uses the interface func CallExample(e Example) { fmt.Println(e.someMethod("test")) } mock-1.0.0/mockgen/tests/unexported_method/bugreport_mock.go000066400000000000000000000023141313466237100243420ustar00rootroot00000000000000// Code generated by MockGen. DO NOT EDIT. // Source: bugreport.go package bugreport import ( gomock "github.com/golang/mock/gomock" reflect "reflect" ) // MockExample is a mock of Example interface type MockExample struct { ctrl *gomock.Controller recorder *MockExampleMockRecorder } // MockExampleMockRecorder is the mock recorder for MockExample type MockExampleMockRecorder struct { mock *MockExample } // NewMockExample creates a new mock instance func NewMockExample(ctrl *gomock.Controller) *MockExample { mock := &MockExample{ctrl: ctrl} mock.recorder = &MockExampleMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use func (_m *MockExample) EXPECT() *MockExampleMockRecorder { return _m.recorder } // someMethod mocks base method func (_m *MockExample) someMethod(_param0 string) string { ret := _m.ctrl.Call(_m, "someMethod", _param0) ret0, _ := ret[0].(string) return ret0 } // someMethod indicates an expected call of someMethod func (_mr *MockExampleMockRecorder) someMethod(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "someMethod", reflect.TypeOf((*MockExample)(nil).someMethod), arg0) } mock-1.0.0/mockgen/tests/unexported_method/bugreport_test.go000066400000000000000000000004171313466237100243720ustar00rootroot00000000000000package bugreport import ( "testing" "github.com/golang/mock/gomock" ) func TestCallExample(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() e := NewMockExample(ctrl) e.EXPECT().someMethod(gomock.Any()).Return("it works!") CallExample(e) } mock-1.0.0/sample/000077500000000000000000000000001313466237100137305ustar00rootroot00000000000000mock-1.0.0/sample/README.md000066400000000000000000000012501313466237100152050ustar00rootroot00000000000000This directory contains an example of a package containing a non-trivial interface that can be mocked with GoMock. The interesting files are: * `user.go`: Source code for the sample package, containing interfaces to be mocked. This file depends on the packages named imp[1-4] for various things. * `user_test.go`: A test for the sample package, in which mocks of the interfaces from `user.go` are used. This demonstrates how to create mock objects, set up expectations, and so on. * `mock_user/mock_user.go`: The generated mock code. See ../update_mocks.sh for the command used to generate it. To run the test, go test github.com/golang/mock/sample mock-1.0.0/sample/imp1/000077500000000000000000000000001313466237100145765ustar00rootroot00000000000000mock-1.0.0/sample/imp1/imp1.go000066400000000000000000000006411313466237100157740ustar00rootroot00000000000000package imp1 import "bufio" type Imp1 struct{} type ImpT int type ForeignEmbedded interface { // The return value here also makes sure that // the generated mock picks up the "bufio" import. ForeignEmbeddedMethod() *bufio.Reader // This method uses a type in this package, // which should be qualified when this interface is embedded. ImplicitPackage(s string, t ImpT, st []ImpT, pt *ImpT, ct chan ImpT) } mock-1.0.0/sample/imp2/000077500000000000000000000000001313466237100145775ustar00rootroot00000000000000mock-1.0.0/sample/imp2/imp2.go000066400000000000000000000000411313466237100157700ustar00rootroot00000000000000package imp2 type Imp2 struct{} mock-1.0.0/sample/imp3/000077500000000000000000000000001313466237100146005ustar00rootroot00000000000000mock-1.0.0/sample/imp3/imp3.go000066400000000000000000000000411313466237100157720ustar00rootroot00000000000000package imp3 type Imp3 struct{} mock-1.0.0/sample/imp4/000077500000000000000000000000001313466237100146015ustar00rootroot00000000000000mock-1.0.0/sample/imp4/imp4.go000066400000000000000000000000451313466237100160000ustar00rootroot00000000000000package imp_four type Imp4 struct{} mock-1.0.0/sample/mock_user/000077500000000000000000000000001313466237100157175ustar00rootroot00000000000000mock-1.0.0/sample/mock_user/mock_user.go000066400000000000000000000320101313466237100202310ustar00rootroot00000000000000// Code generated by MockGen. DO NOT EDIT. // Source: github.com/golang/mock/sample (interfaces: Index,Embed,Embedded) package mock_sample import ( bufio "bufio" bytes "bytes" gomock "github.com/golang/mock/gomock" imp1 "github.com/golang/mock/sample/imp1" imp2 "github.com/golang/mock/sample/imp2" imp3 "github.com/golang/mock/sample/imp3" imp4 "github.com/golang/mock/sample/imp4" hash "hash" template "html/template" io "io" http "net/http" reflect "reflect" template0 "text/template" ) // MockIndex is a mock of Index interface type MockIndex struct { ctrl *gomock.Controller recorder *MockIndexMockRecorder } // MockIndexMockRecorder is the mock recorder for MockIndex type MockIndexMockRecorder struct { mock *MockIndex } // NewMockIndex creates a new mock instance func NewMockIndex(ctrl *gomock.Controller) *MockIndex { mock := &MockIndex{ctrl: ctrl} mock.recorder = &MockIndexMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use func (_m *MockIndex) EXPECT() *MockIndexMockRecorder { return _m.recorder } // Anon mocks base method func (_m *MockIndex) Anon(_param0 string) { _m.ctrl.Call(_m, "Anon", _param0) } // Anon indicates an expected call of Anon func (_mr *MockIndexMockRecorder) Anon(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Anon", reflect.TypeOf((*MockIndex)(nil).Anon), arg0) } // Chan mocks base method func (_m *MockIndex) Chan(_param0 chan int, _param1 chan<- hash.Hash) { _m.ctrl.Call(_m, "Chan", _param0, _param1) } // Chan indicates an expected call of Chan func (_mr *MockIndexMockRecorder) Chan(arg0, arg1 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Chan", reflect.TypeOf((*MockIndex)(nil).Chan), arg0, arg1) } // ConcreteRet mocks base method func (_m *MockIndex) ConcreteRet() chan<- bool { ret := _m.ctrl.Call(_m, "ConcreteRet") ret0, _ := ret[0].(chan<- bool) return ret0 } // ConcreteRet indicates an expected call of ConcreteRet func (_mr *MockIndexMockRecorder) ConcreteRet() *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ConcreteRet", reflect.TypeOf((*MockIndex)(nil).ConcreteRet)) } // Ellip mocks base method func (_m *MockIndex) Ellip(_param0 string, _param1 ...interface{}) { _s := []interface{}{_param0} for _, _x := range _param1 { _s = append(_s, _x) } _m.ctrl.Call(_m, "Ellip", _s...) } // Ellip indicates an expected call of Ellip func (_mr *MockIndexMockRecorder) Ellip(arg0 interface{}, arg1 ...interface{}) *gomock.Call { _s := append([]interface{}{arg0}, arg1...) return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Ellip", reflect.TypeOf((*MockIndex)(nil).Ellip), _s...) } // EllipOnly mocks base method func (_m *MockIndex) EllipOnly(_param0 ...string) { _s := []interface{}{} for _, _x := range _param0 { _s = append(_s, _x) } _m.ctrl.Call(_m, "EllipOnly", _s...) } // EllipOnly indicates an expected call of EllipOnly func (_mr *MockIndexMockRecorder) EllipOnly(arg0 ...interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "EllipOnly", reflect.TypeOf((*MockIndex)(nil).EllipOnly), arg0...) } // ForeignFour mocks base method func (_m *MockIndex) ForeignFour(_param0 imp4.Imp4) { _m.ctrl.Call(_m, "ForeignFour", _param0) } // ForeignFour indicates an expected call of ForeignFour func (_mr *MockIndexMockRecorder) ForeignFour(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ForeignFour", reflect.TypeOf((*MockIndex)(nil).ForeignFour), arg0) } // ForeignOne mocks base method func (_m *MockIndex) ForeignOne(_param0 imp1.Imp1) { _m.ctrl.Call(_m, "ForeignOne", _param0) } // ForeignOne indicates an expected call of ForeignOne func (_mr *MockIndexMockRecorder) ForeignOne(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ForeignOne", reflect.TypeOf((*MockIndex)(nil).ForeignOne), arg0) } // ForeignThree mocks base method func (_m *MockIndex) ForeignThree(_param0 imp3.Imp3) { _m.ctrl.Call(_m, "ForeignThree", _param0) } // ForeignThree indicates an expected call of ForeignThree func (_mr *MockIndexMockRecorder) ForeignThree(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ForeignThree", reflect.TypeOf((*MockIndex)(nil).ForeignThree), arg0) } // ForeignTwo mocks base method func (_m *MockIndex) ForeignTwo(_param0 imp2.Imp2) { _m.ctrl.Call(_m, "ForeignTwo", _param0) } // ForeignTwo indicates an expected call of ForeignTwo func (_mr *MockIndexMockRecorder) ForeignTwo(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ForeignTwo", reflect.TypeOf((*MockIndex)(nil).ForeignTwo), arg0) } // Func mocks base method func (_m *MockIndex) Func(_param0 func(http.Request) (int, bool)) { _m.ctrl.Call(_m, "Func", _param0) } // Func indicates an expected call of Func func (_mr *MockIndexMockRecorder) Func(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Func", reflect.TypeOf((*MockIndex)(nil).Func), arg0) } // Get mocks base method func (_m *MockIndex) Get(_param0 string) interface{} { ret := _m.ctrl.Call(_m, "Get", _param0) ret0, _ := ret[0].(interface{}) return ret0 } // Get indicates an expected call of Get func (_mr *MockIndexMockRecorder) Get(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Get", reflect.TypeOf((*MockIndex)(nil).Get), arg0) } // GetTwo mocks base method func (_m *MockIndex) GetTwo(_param0 string, _param1 string) (interface{}, interface{}) { ret := _m.ctrl.Call(_m, "GetTwo", _param0, _param1) ret0, _ := ret[0].(interface{}) ret1, _ := ret[1].(interface{}) return ret0, ret1 } // GetTwo indicates an expected call of GetTwo func (_mr *MockIndexMockRecorder) GetTwo(arg0, arg1 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "GetTwo", reflect.TypeOf((*MockIndex)(nil).GetTwo), arg0, arg1) } // Map mocks base method func (_m *MockIndex) Map(_param0 map[int]hash.Hash) { _m.ctrl.Call(_m, "Map", _param0) } // Map indicates an expected call of Map func (_mr *MockIndexMockRecorder) Map(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Map", reflect.TypeOf((*MockIndex)(nil).Map), arg0) } // NillableRet mocks base method func (_m *MockIndex) NillableRet() error { ret := _m.ctrl.Call(_m, "NillableRet") ret0, _ := ret[0].(error) return ret0 } // NillableRet indicates an expected call of NillableRet func (_mr *MockIndexMockRecorder) NillableRet() *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "NillableRet", reflect.TypeOf((*MockIndex)(nil).NillableRet)) } // Other mocks base method func (_m *MockIndex) Other() hash.Hash { ret := _m.ctrl.Call(_m, "Other") ret0, _ := ret[0].(hash.Hash) return ret0 } // Other indicates an expected call of Other func (_mr *MockIndexMockRecorder) Other() *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Other", reflect.TypeOf((*MockIndex)(nil).Other)) } // Ptr mocks base method func (_m *MockIndex) Ptr(_param0 *int) { _m.ctrl.Call(_m, "Ptr", _param0) } // Ptr indicates an expected call of Ptr func (_mr *MockIndexMockRecorder) Ptr(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Ptr", reflect.TypeOf((*MockIndex)(nil).Ptr), arg0) } // Put mocks base method func (_m *MockIndex) Put(_param0 string, _param1 interface{}) { _m.ctrl.Call(_m, "Put", _param0, _param1) } // Put indicates an expected call of Put func (_mr *MockIndexMockRecorder) Put(arg0, arg1 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Put", reflect.TypeOf((*MockIndex)(nil).Put), arg0, arg1) } // Slice mocks base method func (_m *MockIndex) Slice(_param0 []int, _param1 []byte) [3]int { ret := _m.ctrl.Call(_m, "Slice", _param0, _param1) ret0, _ := ret[0].([3]int) return ret0 } // Slice indicates an expected call of Slice func (_mr *MockIndexMockRecorder) Slice(arg0, arg1 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Slice", reflect.TypeOf((*MockIndex)(nil).Slice), arg0, arg1) } // Struct mocks base method func (_m *MockIndex) Struct(_param0 struct{}) { _m.ctrl.Call(_m, "Struct", _param0) } // Struct indicates an expected call of Struct func (_mr *MockIndexMockRecorder) Struct(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Struct", reflect.TypeOf((*MockIndex)(nil).Struct), arg0) } // StructChan mocks base method func (_m *MockIndex) StructChan(_param0 chan struct{}) { _m.ctrl.Call(_m, "StructChan", _param0) } // StructChan indicates an expected call of StructChan func (_mr *MockIndexMockRecorder) StructChan(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "StructChan", reflect.TypeOf((*MockIndex)(nil).StructChan), arg0) } // Summary mocks base method func (_m *MockIndex) Summary(_param0 *bytes.Buffer, _param1 io.Writer) { _m.ctrl.Call(_m, "Summary", _param0, _param1) } // Summary indicates an expected call of Summary func (_mr *MockIndexMockRecorder) Summary(arg0, arg1 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Summary", reflect.TypeOf((*MockIndex)(nil).Summary), arg0, arg1) } // Templates mocks base method func (_m *MockIndex) Templates(_param0 template.CSS, _param1 template0.FuncMap) { _m.ctrl.Call(_m, "Templates", _param0, _param1) } // Templates indicates an expected call of Templates func (_mr *MockIndexMockRecorder) Templates(arg0, arg1 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "Templates", reflect.TypeOf((*MockIndex)(nil).Templates), arg0, arg1) } // MockEmbed is a mock of Embed interface type MockEmbed struct { ctrl *gomock.Controller recorder *MockEmbedMockRecorder } // MockEmbedMockRecorder is the mock recorder for MockEmbed type MockEmbedMockRecorder struct { mock *MockEmbed } // NewMockEmbed creates a new mock instance func NewMockEmbed(ctrl *gomock.Controller) *MockEmbed { mock := &MockEmbed{ctrl: ctrl} mock.recorder = &MockEmbedMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use func (_m *MockEmbed) EXPECT() *MockEmbedMockRecorder { return _m.recorder } // EmbeddedMethod mocks base method func (_m *MockEmbed) EmbeddedMethod() { _m.ctrl.Call(_m, "EmbeddedMethod") } // EmbeddedMethod indicates an expected call of EmbeddedMethod func (_mr *MockEmbedMockRecorder) EmbeddedMethod() *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "EmbeddedMethod", reflect.TypeOf((*MockEmbed)(nil).EmbeddedMethod)) } // ForeignEmbeddedMethod mocks base method func (_m *MockEmbed) ForeignEmbeddedMethod() *bufio.Reader { ret := _m.ctrl.Call(_m, "ForeignEmbeddedMethod") ret0, _ := ret[0].(*bufio.Reader) return ret0 } // ForeignEmbeddedMethod indicates an expected call of ForeignEmbeddedMethod func (_mr *MockEmbedMockRecorder) ForeignEmbeddedMethod() *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ForeignEmbeddedMethod", reflect.TypeOf((*MockEmbed)(nil).ForeignEmbeddedMethod)) } // ImplicitPackage mocks base method func (_m *MockEmbed) ImplicitPackage(_param0 string, _param1 imp1.ImpT, _param2 []imp1.ImpT, _param3 *imp1.ImpT, _param4 chan imp1.ImpT) { _m.ctrl.Call(_m, "ImplicitPackage", _param0, _param1, _param2, _param3, _param4) } // ImplicitPackage indicates an expected call of ImplicitPackage func (_mr *MockEmbedMockRecorder) ImplicitPackage(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "ImplicitPackage", reflect.TypeOf((*MockEmbed)(nil).ImplicitPackage), arg0, arg1, arg2, arg3, arg4) } // RegularMethod mocks base method func (_m *MockEmbed) RegularMethod() { _m.ctrl.Call(_m, "RegularMethod") } // RegularMethod indicates an expected call of RegularMethod func (_mr *MockEmbedMockRecorder) RegularMethod() *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "RegularMethod", reflect.TypeOf((*MockEmbed)(nil).RegularMethod)) } // MockEmbedded is a mock of Embedded interface type MockEmbedded struct { ctrl *gomock.Controller recorder *MockEmbeddedMockRecorder } // MockEmbeddedMockRecorder is the mock recorder for MockEmbedded type MockEmbeddedMockRecorder struct { mock *MockEmbedded } // NewMockEmbedded creates a new mock instance func NewMockEmbedded(ctrl *gomock.Controller) *MockEmbedded { mock := &MockEmbedded{ctrl: ctrl} mock.recorder = &MockEmbeddedMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use func (_m *MockEmbedded) EXPECT() *MockEmbeddedMockRecorder { return _m.recorder } // EmbeddedMethod mocks base method func (_m *MockEmbedded) EmbeddedMethod() { _m.ctrl.Call(_m, "EmbeddedMethod") } // EmbeddedMethod indicates an expected call of EmbeddedMethod func (_mr *MockEmbeddedMockRecorder) EmbeddedMethod() *gomock.Call { return _mr.mock.ctrl.RecordCallWithMethodType(_mr.mock, "EmbeddedMethod", reflect.TypeOf((*MockEmbedded)(nil).EmbeddedMethod)) } mock-1.0.0/sample/user.go000066400000000000000000000054221313466237100152400ustar00rootroot00000000000000//go:generate mockgen -destination mock_user/mock_user.go github.com/golang/mock/sample Index,Embed,Embedded // An example package with an interface. package user // Random bunch of imports to test mockgen. import "io" import ( btz "bytes" "hash" "log" "net" "net/http" // Two imports with the same base name. t1 "html/template" t2 "text/template" ) // Dependencies outside the standard library. import ( "github.com/golang/mock/sample/imp1" renamed2 "github.com/golang/mock/sample/imp2" . "github.com/golang/mock/sample/imp3" "github.com/golang/mock/sample/imp4" // calls itself "imp_four" ) // A bizarre interface to test corner cases in mockgen. // This would normally be in its own file or package, // separate from the user of it (e.g. io.Reader). type Index interface { Get(key string) interface{} GetTwo(key1, key2 string) (v1, v2 interface{}) Put(key string, value interface{}) // Check that imports are handled correctly. Summary(buf *btz.Buffer, w io.Writer) Other() hash.Hash Templates(a t1.CSS, b t2.FuncMap) // A method with an anonymous argument. Anon(string) // Methods using foreign types outside the standard library. ForeignOne(imp1.Imp1) ForeignTwo(renamed2.Imp2) ForeignThree(Imp3) ForeignFour(imp_four.Imp4) // A method that returns a nillable type. NillableRet() error // A method that returns a non-interface type. ConcreteRet() chan<- bool // Methods with an ellipsis argument. Ellip(fmt string, args ...interface{}) EllipOnly(...string) // A method with a pointer argument that we will set. Ptr(arg *int) // A method with a slice argument and an array return. Slice(a []int, b []byte) [3]int // A method with channel arguments. Chan(a chan int, b chan<- hash.Hash) // A method with a function argument. Func(f func(http.Request) (int, bool)) // A method with a map argument. Map(a map[int]hash.Hash) // Methods with an unnamed empty struct argument. Struct(a struct{}) // not so likely StructChan(a chan struct{}) // a bit more common } // An interface with an embedded interface. type Embed interface { RegularMethod() Embedded imp1.ForeignEmbedded } type Embedded interface { EmbeddedMethod() } // some random use of another package that isn't needed by the interface. var _ net.Addr // A function that we will test that uses the above interface. // It takes a list of keys and values, and puts them in the index. func Remember(index Index, keys []string, values []interface{}) { for i, k := range keys { index.Put(k, values[i]) } err := index.NillableRet() if err != nil { log.Fatalf("Woah! %v", err) } if len(keys) > 0 && keys[0] == "a" { index.Ellip("%d", 0, 1, 1, 2, 3) index.Ellip("%d", 1, 3, 6, 10, 15) index.EllipOnly("arg") } } func GrabPointer(index Index) int { var a int index.Ptr(&a) return a } mock-1.0.0/sample/user_test.go000066400000000000000000000070361313466237100163020ustar00rootroot00000000000000// A test that uses a mock. package user_test import ( "testing" "github.com/golang/mock/gomock" "github.com/golang/mock/sample" "github.com/golang/mock/sample/imp1" mock_user "github.com/golang/mock/sample/mock_user" ) func TestRemember(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockIndex := mock_user.NewMockIndex(ctrl) mockIndex.EXPECT().Put("a", 1) // literals work mockIndex.EXPECT().Put("b", gomock.Eq(2)) // matchers work too // NillableRet returns error. Not declaring it should result in a nil return. mockIndex.EXPECT().NillableRet() // Calls that returns something assignable to the return type. boolc := make(chan bool) // In this case, "chan bool" is assignable to "chan<- bool". mockIndex.EXPECT().ConcreteRet().Return(boolc) // In this case, nil is assignable to "chan<- bool". mockIndex.EXPECT().ConcreteRet().Return(nil) // Should be able to place expectations on variadic methods. mockIndex.EXPECT().Ellip("%d", 0, 1, 1, 2, 3) // direct args tri := []interface{}{1, 3, 6, 10, 15} mockIndex.EXPECT().Ellip("%d", tri...) // args from slice mockIndex.EXPECT().EllipOnly(gomock.Eq("arg")) user.Remember(mockIndex, []string{"a", "b"}, []interface{}{1, 2}) // Check the ConcreteRet calls. if c := mockIndex.ConcreteRet(); c != boolc { t.Errorf("ConcreteRet: got %v, want %v", c, boolc) } if c := mockIndex.ConcreteRet(); c != nil { t.Errorf("ConcreteRet: got %v, want nil", c) } // Try one with an action. calledString := "" mockIndex.EXPECT().Put(gomock.Any(), gomock.Any()).Do(func(key string, _ interface{}) { calledString = key }) mockIndex.EXPECT().NillableRet() user.Remember(mockIndex, []string{"blah"}, []interface{}{7}) if calledString != "blah" { t.Fatalf(`Uh oh. %q != "blah"`, calledString) } // Use Do with a nil arg. mockIndex.EXPECT().Put("nil-key", gomock.Any()).Do(func(key string, value interface{}) { if value != nil { t.Errorf("Put did not pass through nil; got %v", value) } }) mockIndex.EXPECT().NillableRet() user.Remember(mockIndex, []string{"nil-key"}, []interface{}{nil}) } func TestVariadicFunction(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockIndex := mock_user.NewMockIndex(ctrl) m := mockIndex.EXPECT().Ellip("%d", 0, 1, 1, 2, 3) m.Do(func(format string, nums ...int) { sum := 0 for _, value := range nums { sum += value } if sum != 7 { t.Errorf("Expected 7, got %d", sum) } }) mockIndex.Ellip("%d", 0, 1, 1, 2, 3) } func TestGrabPointer(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockIndex := mock_user.NewMockIndex(ctrl) mockIndex.EXPECT().Ptr(gomock.Any()).SetArg(0, 7) // set first argument to 7 i := user.GrabPointer(mockIndex) if i != 7 { t.Errorf("Expected 7, got %d", i) } } func TestEmbeddedInterface(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() mockEmbed := mock_user.NewMockEmbed(ctrl) mockEmbed.EXPECT().RegularMethod() mockEmbed.EXPECT().EmbeddedMethod() mockEmbed.EXPECT().ForeignEmbeddedMethod() mockEmbed.RegularMethod() mockEmbed.EmbeddedMethod() var emb imp1.ForeignEmbedded = mockEmbed // also does interface check emb.ForeignEmbeddedMethod() } func TestExpectTrueNil(t *testing.T) { // Make sure that passing "nil" to EXPECT (thus as a nil interface value), // will correctly match a nil concrete type. ctrl := gomock.NewController(t) defer ctrl.Finish() mockIndex := mock_user.NewMockIndex(ctrl) mockIndex.EXPECT().Ptr(nil) // this nil is a nil interface{} mockIndex.Ptr(nil) // this nil is a nil *int }