Skip to content
This repository has been archived by the owner on Jun 27, 2023. It is now read-only.

Commit

Permalink
gomock: documents exported functions
Browse files Browse the repository at this point in the history
fixes #222
  • Loading branch information
poy committed Dec 21, 2018
1 parent c2e99c4 commit 7c85401
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 24 deletions.
40 changes: 34 additions & 6 deletions gomock/controller.go
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// GoMock - a mock framework for Go.
// Package gomock is a mock framework for Go.
//
// Standard usage:
// (1) Define an interface that you wish to mock.
Expand Down Expand Up @@ -63,8 +63,8 @@ import (
"sync"
)

// A TestReporter is something that can be used to report test failures.
// It is satisfied by the standard library's *testing.T.
// A TestReporter is something that can be used to report test failures. It
// is satisfied by the standard library's *testing.T.
type TestReporter interface {
Errorf(format string, args ...interface{})
Fatalf(format string, args ...interface{})
Expand All @@ -77,9 +77,30 @@ type TestHelper interface {
Helper()
}

// A Controller represents the top-level control of a mock ecosystem.
// It defines the scope and lifetime of mock objects, as well as their expectations.
// It is safe to call Controller's methods from multiple goroutines.
// A Controller represents the top-level control of a mock ecosystem. It
// defines the scope and lifetime of mock objects, as well as their
// expectations. It is safe to call Controller's methods from multiple
// goroutines. Each test should create a new Controller and invoke Finish via
// defer.
//
// func TestFoo(t *testing.T) {
// ctrl := gomock.NewController(st)
// defer ctrl.Finish()
// // ..
// }
//
// func TestBar(t *testing.T) {
// t.Run("Sub-Test-1", st) {
// ctrl := gomock.NewController(st)
// defer ctrl.Finish()
// // ..
// })
// t.Run("Sub-Test-2", st) {
// ctrl := gomock.NewController(st)
// defer ctrl.Finish()
// // ..
// })
// })
type Controller struct {
// T should only be called within a generated mock. It is not intended to
// be used in user code and may be changed in future versions. T is the
Expand All @@ -92,6 +113,8 @@ type Controller struct {
finished bool
}

// NewController returns a new Controller. It is the preferred way to create a
// Controller.
func NewController(t TestReporter) *Controller {
h, ok := t.(TestHelper)
if !ok {
Expand Down Expand Up @@ -135,6 +158,7 @@ type nopTestHelper struct {

func (h nopTestHelper) Helper() {}

// RecordCall is called by a mock. It should not be called by user code.
func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call {
ctrl.T.Helper()

Expand All @@ -148,6 +172,7 @@ func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...
panic("unreachable")
}

// RecordCallWithMethodType is called by a mock. It should not be called by user code.
func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method string, methodType reflect.Type, args ...interface{}) *Call {
ctrl.T.Helper()

Expand All @@ -160,6 +185,7 @@ func (ctrl *Controller) RecordCallWithMethodType(receiver interface{}, method st
return call
}

// Call is called by a mock. It should not be called by user code.
func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} {
ctrl.T.Helper()

Expand Down Expand Up @@ -200,6 +226,8 @@ func (ctrl *Controller) Call(receiver interface{}, method string, args ...interf
return rets
}

// Finish checks to see if all the methods that were expected to be called
// were called. It should be invoked for each Controller.
func (ctrl *Controller) Finish() {
ctrl.T.Helper()

Expand Down
33 changes: 26 additions & 7 deletions gomock/matchers.go
Expand Up @@ -98,9 +98,30 @@ func (m assignableToTypeOfMatcher) String() string {
}

// Constructors
func Any() Matcher { return anyMatcher{} }
// Any returns a matcher that always matches.
func Any() Matcher { return anyMatcher{} }

// Eq returns a matcher that matches on equality.
//
// Example usage:
// Eq(5).Matches(5) // returns true
// Eq(5).Matches(4) // returns false
func Eq(x interface{}) Matcher { return eqMatcher{x} }
func Nil() Matcher { return nilMatcher{} }

// Nil returns a matcher that matches if the received value is nil.
//
// Example usage:
// var x *bytes.Buffer
// Nil().Matches(x) // returns true
// x = &bytes.Buffer{}
// Nil().Matches(x) // returns false
func Nil() Matcher { return nilMatcher{} }

// Not reverses the results of its given child matcher.
//
// Example usage:
// Not(Eq(5)).Matches(4) // returns true
// Not(Eq(5)).Matches(5) // returns false
func Not(x interface{}) Matcher {
if m, ok := x.(Matcher); ok {
return notMatcher{m}
Expand All @@ -112,11 +133,9 @@ func Not(x interface{}) Matcher {
// function is assignable to the type of the parameter to this function.
//
// Example usage:
//
// dbMock.EXPECT().
// Insert(gomock.AssignableToTypeOf(&EmployeeRecord{})).
// Return(errors.New("DB error"))
//
// var s fmt.Stringer = &bytes.Buffer{}
// AssignableToTypeOf(s).Matches(time.Second) // returns true
// AssignableToTypeOf(s).Matches(99) // returns false
func AssignableToTypeOf(x interface{}) Matcher {
return assignableToTypeOfMatcher{reflect.TypeOf(x)}
}
12 changes: 6 additions & 6 deletions mockgen/mockgen.go
Expand Up @@ -60,13 +60,13 @@ func main() {
var pkg *model.Package
var err error
if *source != "" {
pkg, err = ParseFile(*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), ","))
pkg, err = reflect(flag.Arg(0), strings.Split(flag.Arg(1), ","))
}
if err != nil {
log.Fatalf("Loading input failed: %v", err)
Expand Down Expand Up @@ -250,17 +250,17 @@ func (g *generator) Generate(pkg *model.Package, pkgName string, outputPackagePa
}

// Sort keys to make import alias generation predictable
sorted_paths := make([]string, len(im), len(im))
sortedPaths := make([]string, len(im), len(im))
x := 0
for pth := range im {
sorted_paths[x] = pth
sortedPaths[x] = pth
x++
}
sort.Strings(sorted_paths)
sort.Strings(sortedPaths)

g.packageMap = make(map[string]string, len(im))
localNames := make(map[string]bool, len(im))
for _, pth := range sorted_paths {
for _, pth := range sortedPaths {
base := sanitize(path.Base(pth))

// Local names for an imported package can usually be the basename of the import path.
Expand Down
8 changes: 4 additions & 4 deletions mockgen/parse.go
Expand Up @@ -39,7 +39,7 @@ var (

// TODO: simplify error reporting

func ParseFile(source string) (*model.Package, error) {
func parseFile(source string) (*model.Package, error) {
srcDir, err := filepath.Abs(filepath.Dir(source))
if err != nil {
return nil, fmt.Errorf("failed getting source directory: %v", err)
Expand Down Expand Up @@ -386,10 +386,10 @@ func (p *fileParser) parseType(pkg string, typ ast.Expr) (model.Type, error) {
}
// assume type in this package
return &model.NamedType{Package: pkg, Type: v.Name}, nil
} else {
// assume predeclared type
return model.PredeclaredType(v.Name), nil
}

// 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")
Expand Down
6 changes: 5 additions & 1 deletion mockgen/reflect.go
Expand Up @@ -52,6 +52,10 @@ func writeProgram(importPath string, symbols []string) ([]byte, error) {
// run the given program and parse the output as a model.Package.
func run(program string) (*model.Package, error) {
f, err := ioutil.TempFile("", "")
if err != nil {
return nil, err
}

filename := f.Name()
defer os.Remove(filename)
if err := f.Close(); err != nil {
Expand Down Expand Up @@ -122,7 +126,7 @@ func runInDir(program []byte, dir string) (*model.Package, error) {
return run(filepath.Join(tmpDir, progBinary))
}

func Reflect(importPath string, symbols []string) (*model.Package, error) {
func reflect(importPath string, symbols []string) (*model.Package, error) {
// TODO: sanity check arguments

if *execOnly != "" {
Expand Down

0 comments on commit 7c85401

Please sign in to comment.