add prune and remove unused packages

This commit is contained in:
Michelle Au
2019-03-08 14:54:43 -08:00
parent f59b58d164
commit 8c0accad66
17240 changed files with 27 additions and 4750030 deletions

View File

@@ -1,559 +0,0 @@
// 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/build"
"go/format"
"go/token"
"io"
"log"
"os"
"path"
"path/filepath"
"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.")
mockNames = flag.String("mock_names", "", "Comma-separated interfaceName=mockName pairs of explicit mock names to use. Mock names default to 'Mock'+ interfaceName suffix.")
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", "", "The full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. This can happen if the mock's package is set to one of its inputs (usually the main one) and the output is stdio so mockgen cannot detect the final output package. Setting this flag will then tell mockgen which import to exclude.")
writePkgComment = flag.Bool("write_package_comment", true, "Writes package documentation comment (godoc) if true.")
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)
}
// outputPackagePath represents the fully qualified name of the package of
// the generated code. Its purposes are to prevent the module from importing
// itself and to prevent qualifying type names that come from its own
// package (i.e. if there is a type called X then we want to print "X" not
// "package.X" since "package" is this package). This can happen if the mock
// is output into an already existing package.
outputPackagePath := *selfPackage
if len(outputPackagePath) == 0 && len(*destination) > 0 {
dst, _ := filepath.Abs(filepath.Dir(*destination))
for _, prefix := range build.Default.SrcDirs() {
if strings.HasPrefix(dst, prefix) {
if rel, err := filepath.Rel(prefix, dst); err == nil {
outputPackagePath = rel
break
}
}
}
}
g := new(generator)
if *source != "" {
g.filename = *source
} else {
g.srcPackage = flag.Arg(0)
g.srcInterfaces = flag.Arg(1)
}
if *mockNames != "" {
g.mockNames = parseMockNames(*mockNames)
}
if err := g.Generate(pkg, packageName, outputPackagePath); 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 parseMockNames(names string) map[string]string {
mocksMap := make(map[string]string)
for _, kv := range strings.Split(names, ",") {
parts := strings.SplitN(kv, "=", 2)
if len(parts) != 2 || parts[1] == "" {
log.Fatalf("bad mock names spec: %v", kv)
}
mocksMap[parts[0]] = parts[1]
}
return mocksMap
}
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
mockNames map[string]string //may be empty
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, outputPackagePath 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
// Only import reflect if it's used. We only use reflect in mocked methods
// so only import if any of the mocked interfaces have methods.
for _, intf := range pkg.Interfaces {
if len(intf.Methods) > 0 {
im["reflect"] = true
break
}
}
// 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
}
if *writePkgComment {
g.p("// Package %v is a generated GoMock package.", pkgName)
}
g.p("package %v", pkgName)
g.p("")
g.p("import (")
g.in()
for path, pkg := range g.packageMap {
if path == outputPackagePath {
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, outputPackagePath); err != nil {
return err
}
}
return nil
}
// The name of the mock type to use for the given interface identifier.
func (g *generator) mockName(typeName string) string {
if mockName, ok := g.mockNames[typeName]; ok {
return mockName
}
return "Mock" + typeName
}
func (g *generator) GenerateMockInterface(intf *model.Interface, outputPackagePath string) error {
mockType := g.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, outputPackagePath)
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)
}
}
func makeArgString(argNames, argTypes []string) string {
args := make([]string, len(argNames))
for i, name := range argNames {
// specify the type only once for consecutive args of the same type
if i+1 < len(argTypes) && argTypes[i] == argTypes[i+1] {
args[i] = name
} else {
args[i] = name + " " + argTypes[i]
}
}
return strings.Join(args, ", ")
}
// 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 {
argNames := g.getArgNames(m)
argTypes := g.getArgTypes(m, pkgOverride)
argString := makeArgString(argNames, argTypes)
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
}
ia := newIdentifierAllocator(argNames)
idRecv := ia.allocateIdentifier("m")
g.p("// %v mocks base method", m.Name)
g.p("func (%v *%v) %v(%v)%v {", idRecv, mockType, m.Name, argString, retString)
g.in()
var callArgs string
if m.Variadic == nil {
if len(argNames) > 0 {
callArgs = ", " + strings.Join(argNames, ", ")
}
} else {
// Non-trivial. The generated code must build a []interface{},
// but the variadic argument may be any type.
idVarArgs := ia.allocateIdentifier("varargs")
idVArg := ia.allocateIdentifier("a")
g.p("%s := []interface{}{%s}", idVarArgs, strings.Join(argNames[:len(argNames)-1], ", "))
g.p("for _, %s := range %s {", idVArg, argNames[len(argNames)-1])
g.in()
g.p("%s = append(%s, %s)", idVarArgs, idVarArgs, idVArg)
g.out()
g.p("}")
callArgs = ", " + idVarArgs + "..."
}
if len(m.Out) == 0 {
g.p(`%v.ctrl.Call(%v, %q%v)`, idRecv, idRecv, m.Name, callArgs)
} else {
idRet := ia.allocateIdentifier("ret")
g.p(`%v := %v.ctrl.Call(%v, %q%v)`, idRet, idRecv, idRecv, 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] = ia.allocateIdentifier(fmt.Sprintf("ret%d", i))
g.p("%s, _ := %s[%d].(%s)", retNames[i], idRet, i, t)
}
g.p("return " + strings.Join(retNames, ", "))
}
g.out()
g.p("}")
return nil
}
func (g *generator) GenerateMockRecorderMethod(mockType string, m *model.Method) error {
argNames := g.getArgNames(m)
var argString string
if m.Variadic == nil {
argString = strings.Join(argNames, ", ")
} else {
argString = strings.Join(argNames[:len(argNames)-1], ", ")
}
if argString != "" {
argString += " interface{}"
}
if m.Variadic != nil {
if argString != "" {
argString += ", "
}
argString += fmt.Sprintf("%s ...interface{}", argNames[len(argNames)-1])
}
ia := newIdentifierAllocator(argNames)
idRecv := ia.allocateIdentifier("mr")
g.p("// %v indicates an expected call of %v", m.Name, m.Name)
g.p("func (%s *%vMockRecorder) %v(%v) *gomock.Call {", idRecv, mockType, m.Name, argString)
g.in()
var callArgs string
if m.Variadic == nil {
if len(argNames) > 0 {
callArgs = ", " + strings.Join(argNames, ", ")
}
} else {
if len(argNames) == 1 {
// Easy: just use ... to push the arguments through.
callArgs = ", " + argNames[0] + "..."
} else {
// Hard: create a temporary slice.
idVarArgs := ia.allocateIdentifier("varargs")
g.p("%s := append([]interface{}{%s}, %s...)",
idVarArgs,
strings.Join(argNames[:len(argNames)-1], ", "),
argNames[len(argNames)-1])
callArgs = ", " + idVarArgs + "..."
}
}
g.p(`return %s.mock.ctrl.RecordCallWithMethodType(%s.mock, "%s", reflect.TypeOf((*%s)(nil).%s)%s)`, idRecv, idRecv, m.Name, mockType, m.Name, callArgs)
g.out()
g.p("}")
return nil
}
func (g *generator) getArgNames(m *model.Method) []string {
argNames := make([]string, len(m.In))
for i, p := range m.In {
name := p.Name
if name == "" {
name = fmt.Sprintf("arg%d", i)
}
argNames[i] = name
}
if m.Variadic != nil {
name := m.Variadic.Name
if name == "" {
name = fmt.Sprintf("arg%d", len(m.In))
}
argNames = append(argNames, name)
}
return argNames
}
func (g *generator) getArgTypes(m *model.Method, pkgOverride string) []string {
argTypes := make([]string, len(m.In))
for i, p := range m.In {
argTypes[i] = p.Type.String(g.packageMap, pkgOverride)
}
if m.Variadic != nil {
argTypes = append(argTypes, "..."+m.Variadic.Type.String(g.packageMap, pkgOverride))
}
return argTypes
}
type identifierAllocator map[string]struct{}
func newIdentifierAllocator(taken []string) identifierAllocator {
a := make(identifierAllocator, len(taken))
for _, s := range taken {
a[s] = struct{}{}
}
return a
}
func (o identifierAllocator) allocateIdentifier(want string) string {
id := want
for i := 2; ; i++ {
if _, ok := o[id]; !ok {
o[id] = struct{}{}
return id
}
id = want + "_" + strconv.Itoa(i)
}
}
// 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
}

View File

@@ -1,181 +0,0 @@
package main
import (
"fmt"
"testing"
)
func TestMakeArgString(t *testing.T) {
testCases := []struct {
argNames []string
argTypes []string
argString string
}{
{
argNames: nil,
argTypes: nil,
argString: "",
},
{
argNames: []string{"arg0"},
argTypes: []string{"int"},
argString: "arg0 int",
},
{
argNames: []string{"arg0", "arg1"},
argTypes: []string{"int", "bool"},
argString: "arg0 int, arg1 bool",
},
{
argNames: []string{"arg0", "arg1"},
argTypes: []string{"int", "int"},
argString: "arg0, arg1 int",
},
{
argNames: []string{"arg0", "arg1", "arg2"},
argTypes: []string{"bool", "int", "int"},
argString: "arg0 bool, arg1, arg2 int",
},
{
argNames: []string{"arg0", "arg1", "arg2"},
argTypes: []string{"int", "bool", "int"},
argString: "arg0 int, arg1 bool, arg2 int",
},
{
argNames: []string{"arg0", "arg1", "arg2"},
argTypes: []string{"int", "int", "bool"},
argString: "arg0, arg1 int, arg2 bool",
},
{
argNames: []string{"arg0", "arg1", "arg2"},
argTypes: []string{"int", "int", "int"},
argString: "arg0, arg1, arg2 int",
},
{
argNames: []string{"arg0", "arg1", "arg2", "arg3"},
argTypes: []string{"bool", "int", "int", "int"},
argString: "arg0 bool, arg1, arg2, arg3 int",
},
{
argNames: []string{"arg0", "arg1", "arg2", "arg3"},
argTypes: []string{"int", "bool", "int", "int"},
argString: "arg0 int, arg1 bool, arg2, arg3 int",
},
{
argNames: []string{"arg0", "arg1", "arg2", "arg3"},
argTypes: []string{"int", "int", "bool", "int"},
argString: "arg0, arg1 int, arg2 bool, arg3 int",
},
{
argNames: []string{"arg0", "arg1", "arg2", "arg3"},
argTypes: []string{"int", "int", "int", "bool"},
argString: "arg0, arg1, arg2 int, arg3 bool",
},
{
argNames: []string{"arg0", "arg1", "arg2", "arg3", "arg4"},
argTypes: []string{"bool", "int", "int", "int", "bool"},
argString: "arg0 bool, arg1, arg2, arg3 int, arg4 bool",
},
{
argNames: []string{"arg0", "arg1", "arg2", "arg3", "arg4"},
argTypes: []string{"int", "bool", "int", "int", "bool"},
argString: "arg0 int, arg1 bool, arg2, arg3 int, arg4 bool",
},
{
argNames: []string{"arg0", "arg1", "arg2", "arg3", "arg4"},
argTypes: []string{"int", "int", "bool", "int", "bool"},
argString: "arg0, arg1 int, arg2 bool, arg3 int, arg4 bool",
},
{
argNames: []string{"arg0", "arg1", "arg2", "arg3", "arg4"},
argTypes: []string{"int", "int", "int", "bool", "bool"},
argString: "arg0, arg1, arg2 int, arg3, arg4 bool",
},
{
argNames: []string{"arg0", "arg1", "arg2", "arg3", "arg4"},
argTypes: []string{"int", "int", "bool", "bool", "int"},
argString: "arg0, arg1 int, arg2, arg3 bool, arg4 int",
},
}
for i, tc := range testCases {
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
s := makeArgString(tc.argNames, tc.argTypes)
if s != tc.argString {
t.Errorf("result == %q, want %q", s, tc.argString)
}
})
}
}
func TestNewIdentifierAllocator(t *testing.T) {
a := newIdentifierAllocator([]string{"taken1", "taken2"})
if len(a) != 2 {
t.Fatalf("expected 2 items, got %v", len(a))
}
_, ok := a["taken1"]
if !ok {
t.Errorf("allocator doesn't contain 'taken1': %#v", a)
}
_, ok = a["taken2"]
if !ok {
t.Errorf("allocator doesn't contain 'taken2': %#v", a)
}
}
func allocatorContainsIdentifiers(a identifierAllocator, ids []string) bool {
if len(a) != len(ids) {
return false
}
for _, id := range ids {
_, ok := a[id]
if !ok {
return false
}
}
return true
}
func TestIdentifierAllocator_allocateIdentifier(t *testing.T) {
a := newIdentifierAllocator([]string{"taken"})
t2 := a.allocateIdentifier("taken_2")
if t2 != "taken_2" {
t.Fatalf("expected 'taken_2', got %q", t2)
}
expected := []string{"taken", "taken_2"}
if !allocatorContainsIdentifiers(a, expected) {
t.Fatalf("allocator doesn't contain the expected items - allocator: %#v, expected items: %#v", a, expected)
}
t3 := a.allocateIdentifier("taken")
if t3 != "taken_3" {
t.Fatalf("expected 'taken_3', got %q", t3)
}
expected = []string{"taken", "taken_2", "taken_3"}
if !allocatorContainsIdentifiers(a, expected) {
t.Fatalf("allocator doesn't contain the expected items - allocator: %#v, expected items: %#v", a, expected)
}
t4 := a.allocateIdentifier("taken")
if t4 != "taken_4" {
t.Fatalf("expected 'taken_4', got %q", t4)
}
expected = []string{"taken", "taken_2", "taken_3", "taken_4"}
if !allocatorContainsIdentifiers(a, expected) {
t.Fatalf("allocator doesn't contain the expected items - allocator: %#v, expected items: %#v", a, expected)
}
id := a.allocateIdentifier("id")
if id != "id" {
t.Fatalf("expected 'id', got %q", id)
}
expected = []string{"taken", "taken_2", "taken_3", "taken_4", "id"}
if !allocatorContainsIdentifiers(a, expected) {
t.Fatalf("allocator doesn't contain the expected items - allocator: %#v, expected items: %#v", a, expected)
}
}

View File

@@ -1,449 +0,0 @@
// 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"
)
// pkgPath is the importable path for package model
const pkgPath = "github.com/golang/mock/mockgen/model"
// 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{})
// Call gob.RegisterName to make sure it has the consistent name registered
// for both gob decoder and encoder.
//
// For a non-pointer type, gob.Register will try to get package full path by
// calling rt.PkgPath() for a name to register. If your project has vendor
// directory, it is possible that PkgPath will get a path like this:
// ../../../vendor/github.com/golang/mock/mockgen/model
gob.RegisterName(pkgPath+".PredeclaredType", 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 != "" {
// PkgPath might return a path that includes "vendor"
// These paths do not compile, so we need to remove everything
// up to and including "/vendor/"
// see https://github.com/golang/go/issues/12019
if i := strings.LastIndex(imp, "/vendor/"); i != -1 {
imp = imp[i+len("/vendor/"):]
}
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())
}

View File

@@ -1,504 +0,0 @@
// 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/build"
"go/parser"
"go/token"
"log"
"path"
"path/filepath"
"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) {
srcDir, err := filepath.Abs(filepath.Dir(source))
if err != nil {
return nil, fmt.Errorf("failed getting source directory: %v", err)
}
var packageImport string
if p, err := build.ImportDir(srcDir, 0); err == nil {
packageImport = p.ImportPath
} // TODO: should we fail if this returns an 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),
importedInterfaces: make(map[string]map[string]*ast.InterfaceType),
auxInterfaces: make(map[string]map[string]*ast.InterfaceType),
srcDir: srcDir,
}
// 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(packageImport, file) // this file
pkg, err := p.parseFile(packageImport, 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
importedInterfaces map[string]map[string]*ast.InterfaceType // package (or "") => name => interface
auxFiles []*ast.File
auxInterfaces map[string]map[string]*ast.InterfaceType // package (or "") => name => interface
srcDir string
}
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)
}
pkg, fpath := parts[0], parts[1]
file, err := parser.ParseFile(p.fileSet, fpath, nil, 0)
if err != nil {
return err
}
p.auxFiles = append(p.auxFiles, file)
p.addAuxInterfacesFromFile(pkg, 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
}
}
// parseFile loads all file imports and auxiliary files import into the
// fileParser, parses all file interfaces and returns package model.
func (p *fileParser) parseFile(importPath string, 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(), importPath, ni.it)
if err != nil {
return nil, err
}
is = append(is, i)
}
return &model.Package{
Name: file.Name.String(),
Interfaces: is,
}, nil
}
// parsePackage loads package specified by path, parses it and populates
// corresponding imports and importedInterfaces into the fileParser.
func (p *fileParser) parsePackage(path string) error {
var pkgs map[string]*ast.Package
if imp, err := build.Import(path, p.srcDir, build.FindOnly); err != nil {
return err
} else if pkgs, err = parser.ParseDir(p.fileSet, imp.Dir, nil, 0); err != nil {
return err
}
for _, pkg := range pkgs {
file := ast.MergePackageFiles(pkg, ast.FilterFuncDuplicates|ast.FilterUnassociatedComments|ast.FilterImportDuplicates)
if _, ok := p.importedInterfaces[path]; !ok {
p.importedInterfaces[path] = make(map[string]*ast.InterfaceType)
}
for ni := range iterInterfaces(file) {
p.importedInterfaces[path][ni.name.Name] = ni.it
}
for pkgName, pkgPath := range importsOfFile(file) {
if _, ok := p.imports[pkgName]; !ok {
p.imports[pkgName] = pkgPath
}
}
}
return 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[pkg][v.String()]
if ei == nil {
if ei = p.importedInterfaces[pkg][v.String()]; 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()
epkg, ok := p.imports[fpkg]
if !ok {
return nil, p.errorf(v.X.Pos(), "unknown package %s", fpkg)
}
ei := p.auxInterfaces[fpkg][sel]
if ei == nil {
fpkg = epkg
if _, ok = p.importedInterfaces[epkg]; !ok {
if err := p.parsePackage(epkg); err != nil {
return nil, p.errorf(v.Pos(), "could not parse package %s: %v", fpkg, err)
}
}
if ei = p.importedInterfaces[epkg][sel]; ei == nil {
return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", fpkg, sel)
}
}
eintf, err := p.parseInterface(sel, fpkg, 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() {
// `pkg` may be an aliased imported pkg
// if so, patch the import w/ the fully qualified import
maybeImportedPkg, ok := p.imports[pkg]
if ok {
pkg = maybeImportedPkg
}
// 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 {
m := make(map[string]string)
for _, is := range file.Imports {
var pkgName string
importPath := is.Path.Value[1 : len(is.Path.Value)-1] // remove quotes
if is.Name != nil {
// Named imports are always certain.
if is.Name.Name == "_" {
continue
}
pkgName = removeDot(is.Name.Name)
} else {
pkg, err := build.Import(importPath, "", 0)
if err != nil {
// Fallback to import path suffix. Note that this is uncertain.
_, last := path.Split(importPath)
// If the last path component has dots, the first dot-delimited
// field is used as the name.
pkgName = strings.SplitN(last, ".", 2)[0]
} else {
pkgName = pkg.Name
}
}
if _, ok := m[pkgName]; ok {
log.Fatalf("imported package collision: %q imported twice", pkgName)
}
m[pkgName] = 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
}

View File

@@ -1,108 +0,0 @@
package main
import (
"go/ast"
"go/parser"
"go/token"
"testing"
)
func TestFileParser_ParseFile(t *testing.T) {
fs := token.NewFileSet()
file, err := parser.ParseFile(fs, "tests/custom_package_name/greeter/greeter.go", nil, 0)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
p := fileParser{
fileSet: fs,
imports: make(map[string]string),
importedInterfaces: make(map[string]map[string]*ast.InterfaceType),
}
pkg, err := p.parseFile("", file)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
checkGreeterImports(t, p.imports)
expectedName := "greeter"
if pkg.Name != expectedName {
t.Fatalf("Expected name to be %v but got %v", expectedName, pkg.Name)
}
expectedInterfaceName := "InputMaker"
if pkg.Interfaces[0].Name != expectedInterfaceName {
t.Fatalf("Expected interface name to be %v but got %v", expectedInterfaceName, pkg.Interfaces[0].Name)
}
}
func TestFileParser_ParsePackage(t *testing.T) {
fs := token.NewFileSet()
_, err := parser.ParseFile(fs, "tests/custom_package_name/greeter/greeter.go", nil, 0)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
p := fileParser{
fileSet: fs,
imports: make(map[string]string),
importedInterfaces: make(map[string]map[string]*ast.InterfaceType),
}
err = p.parsePackage("github.com/golang/mock/mockgen/tests/custom_package_name/greeter")
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
checkGreeterImports(t, p.imports)
}
func TestImportsOfFile(t *testing.T) {
fs := token.NewFileSet()
file, err := parser.ParseFile(fs, "tests/custom_package_name/greeter/greeter.go", nil, 0)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
imports := importsOfFile(file)
checkGreeterImports(t, imports)
}
func checkGreeterImports(t *testing.T, imports map[string]string) {
// check that imports have stdlib package "fmt"
if fmtPackage, ok := imports["fmt"]; !ok {
t.Errorf("Expected imports to have key \"fmt\"")
} else {
expectedFmtPackage := "fmt"
if fmtPackage != expectedFmtPackage {
t.Errorf("Expected fmt key to have value %s but got %s", expectedFmtPackage, fmtPackage)
}
}
// check that imports have package named "validator"
if validatorPackage, ok := imports["validator"]; !ok {
t.Errorf("Expected imports to have key \"fmt\"")
} else {
expectedValidatorPackage := "github.com/golang/mock/mockgen/tests/custom_package_name/validator"
if validatorPackage != expectedValidatorPackage {
t.Errorf("Expected validator key to have value %s but got %s", expectedValidatorPackage, validatorPackage)
}
}
// check that imports have package named "client"
if clientPackage, ok := imports["client"]; !ok {
t.Errorf("Expected imports to have key \"client\"")
} else {
expectedClientPackage := "github.com/golang/mock/mockgen/tests/custom_package_name/client/v1"
if clientPackage != expectedClientPackage {
t.Errorf("Expected client key to have value %s but got %s", expectedClientPackage, clientPackage)
}
}
// check that imports don't have package named "v1"
if _, ok := imports["v1"]; ok {
t.Errorf("Expected import not to have key \"v1\"")
}
}

View File

@@ -1,197 +0,0 @@
// 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"
"go/build"
"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 and exit.")
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 writeProgram(importPath string, symbols []string) ([]byte, error) {
var program bytes.Buffer
data := reflectData{
ImportPath: importPath,
Symbols: symbols,
}
if err := reflectProgram.Execute(&program, &data); err != nil {
return nil, err
}
return program.Bytes(), nil
}
// run the given command and parse the output as a model.Package.
func run(command string) (*model.Package, error) {
// Run the program.
cmd := exec.Command(command)
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
}
// runInDir writes the given program into the given dir, runs it there, and
// parses the output as a model.Package.
func runInDir(program []byte, dir string) (*model.Package, error) {
// We use TempDir instead of TempFile so we can control the filename.
tmpDir, err := ioutil.TempDir(dir, "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"
}
if err := ioutil.WriteFile(filepath.Join(tmpDir, progSource), program, 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
}
return run(filepath.Join(tmpDir, progBinary))
}
func Reflect(importPath string, symbols []string) (*model.Package, error) {
// TODO: sanity check arguments
if *execOnly != "" {
return run(*execOnly)
}
program, err := writeProgram(importPath, symbols)
if err != nil {
return nil, err
}
if *progOnly {
os.Stdout.Write(program)
os.Exit(0)
}
wd, _ := os.Getwd()
// Try to run the program in the same directory as the input package.
if p, err := build.Import(importPath, wd, build.FindOnly); err == nil {
dir := p.Dir
if p, err := runInDir(program, dir); err == nil {
return p, nil
}
}
// Since that didn't work, try to run it in the current working directory.
if p, err := runInDir(program, wd); err == nil {
return p, nil
}
// Since that didn't work, try to run it in a standard temp directory.
return runInDir(program, "")
}
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)
}
}
`))

View File

@@ -1,36 +0,0 @@
Embedded interfaces in `aux_files` generate `unknown embedded interface XXX` errors.
See below for example of the problem:
```
// source
import (
alias "some.org/package/imported"
)
type Source interface {
alias.Foreign
}
```
```
// some.org/package/imported
type Foreign interface {
Embedded
}
type Embedded interface {}
```
Attempting to generate a mock will result in an `unknown embedded interface Embedded`.
The issue is that the `fileParser` stores `auxInterfaces` underneath the package name
explicitly specified in the `aux_files` flag.
In the `parseInterface` method, there is an incorrect assumption about an embedded interface
always being in the source file.
```
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())
}
```

View File

@@ -1,18 +0,0 @@
//go:generate mockgen -aux_files faux=faux/faux.go -destination bugreport_mock.go -package bugreport -source=bugreport.go Example
package bugreport
import (
"log"
"github.com/golang/mock/mockgen/tests/aux_imports_embedded_interface/faux"
)
// Source is an interface w/ an embedded foreign interface
type Source interface {
faux.Foreign
}
func CallForeignMethod(s Source) {
log.Println(s.Method())
}

View File

@@ -1,46 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: bugreport.go
// Package bugreport is a generated GoMock package.
package bugreport
import (
gomock "github.com/golang/mock/gomock"
faux "github.com/golang/mock/mockgen/tests/aux_imports_embedded_interface/faux"
reflect "reflect"
)
// MockSource is a mock of Source interface
type MockSource struct {
ctrl *gomock.Controller
recorder *MockSourceMockRecorder
}
// MockSourceMockRecorder is the mock recorder for MockSource
type MockSourceMockRecorder struct {
mock *MockSource
}
// NewMockSource creates a new mock instance
func NewMockSource(ctrl *gomock.Controller) *MockSource {
mock := &MockSource{ctrl: ctrl}
mock.recorder = &MockSourceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockSource) EXPECT() *MockSourceMockRecorder {
return m.recorder
}
// Method mocks base method
func (m *MockSource) Method() faux.Return {
ret := m.ctrl.Call(m, "Method")
ret0, _ := ret[0].(faux.Return)
return ret0
}
// Method indicates an expected call of Method
func (mr *MockSourceMockRecorder) Method() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Method", reflect.TypeOf((*MockSource)(nil).Method))
}

View File

@@ -1,18 +0,0 @@
package bugreport
import (
"testing"
"github.com/golang/mock/gomock"
)
// TestValidInterface assesses whether or not the generated mock is valid
func TestValidInterface(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
s := NewMockSource(ctrl)
s.EXPECT().Method().Return("")
CallForeignMethod(s)
}

View File

@@ -1,10 +0,0 @@
package faux
type Foreign interface {
Method() Return
Embedded
}
type Embedded interface{}
type Return interface{}

View File

@@ -1,22 +0,0 @@
# Tests for custom package names
This directory contains test for mockgen generating mocks when imported package
name does not match import path suffix. For example, package with name "client"
is located under import path "github.com/golang/mock/mockgen/tests/custom_package_name/client/v1".
Prior to this patch:
$ go generate greeter/greeter.go
2018/03/05 22:44:52 Loading input failed: greeter.go:17:11: failed parsing returns: greeter.go:17:14: unknown package "client"
greeter/greeter.go:1: running "mockgen": exit status 1
This can be fixed by manually providing `-imports` flag, like `-imports client=github.com/golang/mock/mockgen/tests/custom_package_name/client/v1`.
But, mockgen should be able to automatically resolve package names in such situations.
With this patch applied:
$ go generate greeter/greeter.go
$ echo $?
0
Mockgen runs successfully, produced output is equal to [greeter_mock_test.go](greeter/greeter_mock_test.go) content.

View File

@@ -1,13 +0,0 @@
package client
import "fmt"
type Client struct{}
func (c *Client) Greet(in GreetInput) string {
return fmt.Sprintf("Hello, %s!", in.Name)
}
type GreetInput struct {
Name string
}

View File

@@ -1,31 +0,0 @@
//go:generate mockgen -source greeter.go -destination greeter_mock_test.go -package greeter
package greeter
import (
// stdlib import
"fmt"
// non-matching import suffix and package name
"github.com/golang/mock/mockgen/tests/custom_package_name/client/v1"
// matching import suffix and package name
"github.com/golang/mock/mockgen/tests/custom_package_name/validator"
)
type InputMaker interface {
MakeInput() client.GreetInput
}
type Greeter struct {
InputMaker InputMaker
Client *client.Client
}
func (g *Greeter) Greet() (string, error) {
in := g.InputMaker.MakeInput()
if err := validator.Validate(in.Name); err != nil {
return "", fmt.Errorf("validation failed: %v", err)
}
return g.Client.Greet(in), nil
}

View File

@@ -1,46 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: greeter.go
// Package greeter is a generated GoMock package.
package greeter
import (
gomock "github.com/golang/mock/gomock"
v1 "github.com/golang/mock/mockgen/tests/custom_package_name/client/v1"
reflect "reflect"
)
// MockInputMaker is a mock of InputMaker interface
type MockInputMaker struct {
ctrl *gomock.Controller
recorder *MockInputMakerMockRecorder
}
// MockInputMakerMockRecorder is the mock recorder for MockInputMaker
type MockInputMakerMockRecorder struct {
mock *MockInputMaker
}
// NewMockInputMaker creates a new mock instance
func NewMockInputMaker(ctrl *gomock.Controller) *MockInputMaker {
mock := &MockInputMaker{ctrl: ctrl}
mock.recorder = &MockInputMakerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockInputMaker) EXPECT() *MockInputMakerMockRecorder {
return m.recorder
}
// MakeInput mocks base method
func (m *MockInputMaker) MakeInput() v1.GreetInput {
ret := m.ctrl.Call(m, "MakeInput")
ret0, _ := ret[0].(v1.GreetInput)
return ret0
}
// MakeInput indicates an expected call of MakeInput
func (mr *MockInputMakerMockRecorder) MakeInput() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MakeInput", reflect.TypeOf((*MockInputMaker)(nil).MakeInput))
}

View File

@@ -1,37 +0,0 @@
package greeter
import (
"testing"
"github.com/golang/mock/gomock"
"github.com/golang/mock/mockgen/tests/custom_package_name/client/v1"
)
func TestGreeter_Greet(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
input := client.GreetInput{
Name: "Foo",
}
inputMaker := NewMockInputMaker(ctrl)
inputMaker.EXPECT().
MakeInput().
Return(input)
g := &Greeter{
InputMaker: inputMaker,
Client: &client.Client{},
}
greeting, err := g.Greet()
if err != nil {
t.Fatalf("Unexpected error: %v", err)
}
expected := "Hello, Foo!"
if greeting != expected {
t.Fatalf("Expected greeting to be %v but got %v", expected, greeting)
}
}

View File

@@ -1,5 +0,0 @@
package validator
func Validate(s string) error {
return nil
}

View File

@@ -1,4 +0,0 @@
//go:generate mockgen -package empty_interface -destination mock.go -source input.go
package empty_interface
type Empty interface{}

View File

@@ -1,32 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: input.go
// Package empty_interface is a generated GoMock package.
package empty_interface
import (
gomock "github.com/golang/mock/gomock"
)
// MockEmpty is a mock of Empty interface
type MockEmpty struct {
ctrl *gomock.Controller
recorder *MockEmptyMockRecorder
}
// MockEmptyMockRecorder is the mock recorder for MockEmpty
type MockEmptyMockRecorder struct {
mock *MockEmpty
}
// NewMockEmpty creates a new mock instance
func NewMockEmpty(ctrl *gomock.Controller) *MockEmpty {
mock := &MockEmpty{ctrl: ctrl}
mock.recorder = &MockEmptyMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockEmpty) EXPECT() *MockEmptyMockRecorder {
return m.recorder
}

View File

@@ -1,26 +0,0 @@
The generated mock methods use some hardcoded variable/receiver names that can
have conflicts with the argument names that are defined by the code for which
the mock is generated when using the source generation method.
Example:
```go
type Example interface {
Method(_m, _mr, m, mr int)
}
```
```go
// Method mocks base method
func (_m *MockExample) Method(_m int, _mr int, m int, mr int) {
_m.ctrl.Call(_m, "Method", _m, _mr, m, mr)
}
```
In the above example one of the interface method parameters is called `_m`
but unfortunately the generated receiver name is also called `_m` so the
mock code won't compile.
The generator has to make sure that generated identifiers (e.g.: the receiver
names) are always different from the arg names that might come from external
sources.

View File

@@ -1,16 +0,0 @@
//go:generate mockgen -destination bugreport_mock.go -package bugreport -source=bugreport.go
package bugreport
type Example interface {
// _m and _mr were used by the buggy code: the '_' prefix was there hoping
// that no one will use method argument names starting with '_' reducing
// the chance of collision with generated identifiers.
// m and mr are used by the bugfixed new code, the '_' prefix has been
// removed because the new code generator changes the names of the
// generated identifiers in case they would collide with identifiers
// coming from argument names.
Method(_m, _mr, m, mr int)
VarargMethod(_s, _x, a, ret int, varargs ...int)
}

View File

@@ -1,58 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: bugreport.go
// Package bugreport is a generated GoMock package.
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
}
// Method mocks base method
func (m_2 *MockExample) Method(_m, _mr, m, mr int) {
m_2.ctrl.Call(m_2, "Method", _m, _mr, m, mr)
}
// Method indicates an expected call of Method
func (mr_2 *MockExampleMockRecorder) Method(_m, _mr, m, mr interface{}) *gomock.Call {
return mr_2.mock.ctrl.RecordCallWithMethodType(mr_2.mock, "Method", reflect.TypeOf((*MockExample)(nil).Method), _m, _mr, m, mr)
}
// VarargMethod mocks base method
func (m *MockExample) VarargMethod(_s, _x, a, ret int, varargs ...int) {
varargs_2 := []interface{}{_s, _x, a, ret}
for _, a_2 := range varargs {
varargs_2 = append(varargs_2, a_2)
}
m.ctrl.Call(m, "VarargMethod", varargs_2...)
}
// VarargMethod indicates an expected call of VarargMethod
func (mr *MockExampleMockRecorder) VarargMethod(_s, _x, a, ret interface{}, varargs ...interface{}) *gomock.Call {
varargs_2 := append([]interface{}{_s, _x, a, ret}, varargs...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VarargMethod", reflect.TypeOf((*MockExample)(nil).VarargMethod), varargs_2...)
}

View File

@@ -1,26 +0,0 @@
package bugreport
import (
"github.com/golang/mock/gomock"
"testing"
)
func TestExample_Method(t *testing.T) {
ctrl := gomock.NewController(t)
m := NewMockExample(ctrl)
m.EXPECT().Method(1, 2, 3, 4)
m.Method(1, 2, 3, 4)
ctrl.Finish()
}
func TestExample_VarargMethod(t *testing.T) {
ctrl := gomock.NewController(t)
m := NewMockExample(ctrl)
m.EXPECT().VarargMethod(1, 2, 3, 4, 6, 7)
m.VarargMethod(1, 2, 3, 4, 6, 7)
ctrl.Finish()
}

View File

@@ -1,3 +0,0 @@
Test the case where the generated code uses a type defined in the source package (in source mode). There are two test cases:
- the output is in a new package
- the output is in the same package as the input

View File

@@ -1,9 +0,0 @@
//go:generate mockgen -destination ../source_mock.go -source=source.go
//go:generate mockgen -package source -destination source_mock.go -source=source.go
package source
type X struct{}
type S interface {
F(X)
}

View File

@@ -1,43 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: source.go
// Package source is a generated GoMock package.
package source
import (
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockS is a mock of S interface
type MockS struct {
ctrl *gomock.Controller
recorder *MockSMockRecorder
}
// MockSMockRecorder is the mock recorder for MockS
type MockSMockRecorder struct {
mock *MockS
}
// NewMockS creates a new mock instance
func NewMockS(ctrl *gomock.Controller) *MockS {
mock := &MockS{ctrl: ctrl}
mock.recorder = &MockSMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockS) EXPECT() *MockSMockRecorder {
return m.recorder
}
// F mocks base method
func (m *MockS) F(arg0 X) {
m.ctrl.Call(m, "F", arg0)
}
// F indicates an expected call of F
func (mr *MockSMockRecorder) F(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F", reflect.TypeOf((*MockS)(nil).F), arg0)
}

View File

@@ -1,44 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: source.go
// Package mock_source is a generated GoMock package.
package mock_source
import (
gomock "github.com/golang/mock/gomock"
definition "github.com/golang/mock/mockgen/tests/import_source/definition"
reflect "reflect"
)
// MockS is a mock of S interface
type MockS struct {
ctrl *gomock.Controller
recorder *MockSMockRecorder
}
// MockSMockRecorder is the mock recorder for MockS
type MockSMockRecorder struct {
mock *MockS
}
// NewMockS creates a new mock instance
func NewMockS(ctrl *gomock.Controller) *MockS {
mock := &MockS{ctrl: ctrl}
mock.recorder = &MockSMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockS) EXPECT() *MockSMockRecorder {
return m.recorder
}
// F mocks base method
func (m *MockS) F(arg0 definition.X) {
m.ctrl.Call(m, "F", arg0)
}
// F indicates an expected call of F
func (mr *MockSMockRecorder) F(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F", reflect.TypeOf((*MockS)(nil).F), arg0)
}

View File

@@ -1,3 +0,0 @@
//go:generate mockgen -destination subdir/internal/pkg/reflect_output/mock.go github.com/golang/mock/mockgen/tests/internal_pkg/subdir/internal/pkg Intf
//go:generate mockgen -source subdir/internal/pkg/input.go -destination subdir/internal/pkg/source_output/mock.go
package test

View File

@@ -1,9 +0,0 @@
package pkg
type Arg interface {
Foo() int
}
type Intf interface {
F() Arg
}

View File

@@ -1,46 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/golang/mock/mockgen/tests/internal_pkg/subdir/internal/pkg (interfaces: Intf)
// Package mock_pkg is a generated GoMock package.
package mock_pkg
import (
gomock "github.com/golang/mock/gomock"
pkg "github.com/golang/mock/mockgen/tests/internal_pkg/subdir/internal/pkg"
reflect "reflect"
)
// MockIntf is a mock of Intf interface
type MockIntf struct {
ctrl *gomock.Controller
recorder *MockIntfMockRecorder
}
// MockIntfMockRecorder is the mock recorder for MockIntf
type MockIntfMockRecorder struct {
mock *MockIntf
}
// NewMockIntf creates a new mock instance
func NewMockIntf(ctrl *gomock.Controller) *MockIntf {
mock := &MockIntf{ctrl: ctrl}
mock.recorder = &MockIntfMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockIntf) EXPECT() *MockIntfMockRecorder {
return m.recorder
}
// F mocks base method
func (m *MockIntf) F() pkg.Arg {
ret := m.ctrl.Call(m, "F")
ret0, _ := ret[0].(pkg.Arg)
return ret0
}
// F indicates an expected call of F
func (mr *MockIntfMockRecorder) F() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F", reflect.TypeOf((*MockIntf)(nil).F))
}

View File

@@ -1,81 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: subdir/internal/pkg/input.go
// Package mock_pkg is a generated GoMock package.
package mock_pkg
import (
gomock "github.com/golang/mock/gomock"
pkg "github.com/golang/mock/mockgen/tests/internal_pkg/subdir/internal/pkg"
reflect "reflect"
)
// MockArg is a mock of Arg interface
type MockArg struct {
ctrl *gomock.Controller
recorder *MockArgMockRecorder
}
// MockArgMockRecorder is the mock recorder for MockArg
type MockArgMockRecorder struct {
mock *MockArg
}
// NewMockArg creates a new mock instance
func NewMockArg(ctrl *gomock.Controller) *MockArg {
mock := &MockArg{ctrl: ctrl}
mock.recorder = &MockArgMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockArg) EXPECT() *MockArgMockRecorder {
return m.recorder
}
// Foo mocks base method
func (m *MockArg) Foo() int {
ret := m.ctrl.Call(m, "Foo")
ret0, _ := ret[0].(int)
return ret0
}
// Foo indicates an expected call of Foo
func (mr *MockArgMockRecorder) Foo() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Foo", reflect.TypeOf((*MockArg)(nil).Foo))
}
// MockIntf is a mock of Intf interface
type MockIntf struct {
ctrl *gomock.Controller
recorder *MockIntfMockRecorder
}
// MockIntfMockRecorder is the mock recorder for MockIntf
type MockIntfMockRecorder struct {
mock *MockIntf
}
// NewMockIntf creates a new mock instance
func NewMockIntf(ctrl *gomock.Controller) *MockIntf {
mock := &MockIntf{ctrl: ctrl}
mock.recorder = &MockIntfMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockIntf) EXPECT() *MockIntfMockRecorder {
return m.recorder
}
// F mocks base method
func (m *MockIntf) F() pkg.Arg {
ret := m.ctrl.Call(m, "F")
ret0, _ := ret[0].(pkg.Arg)
return ret0
}
// F indicates an expected call of F
func (mr *MockIntfMockRecorder) F() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F", reflect.TypeOf((*MockIntf)(nil).F))
}

View File

@@ -1 +0,0 @@
From #52, this tests an unexported method in the mocked interface.

View File

@@ -1,15 +0,0 @@
//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"))
}

View File

@@ -1,45 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: bugreport.go
// Package bugreport is a generated GoMock package.
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(arg0 string) string {
ret := m.ctrl.Call(m, "someMethod", arg0)
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)
}

View File

@@ -1,17 +0,0 @@
package 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)
}

View File

@@ -1,2 +0,0 @@
Test for [Issue#4](https://github.com/golang/mock/issues/4).
Also see discussion on [#28](https://github.com/golang/mock/pull/28).

View File

@@ -1,4 +0,0 @@
package vendor_dep
//go:generate mockgen -package vendor_dep -destination mock.go github.com/golang/mock/mockgen/tests/vendor_dep VendorsDep
//go:generate mockgen -destination source_mock_package/mock.go -source=vendor_dep.go

View File

@@ -1,46 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/golang/mock/mockgen/tests/vendor_dep (interfaces: VendorsDep)
// Package vendor_dep is a generated GoMock package.
package vendor_dep
import (
a "a"
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockVendorsDep is a mock of VendorsDep interface
type MockVendorsDep struct {
ctrl *gomock.Controller
recorder *MockVendorsDepMockRecorder
}
// MockVendorsDepMockRecorder is the mock recorder for MockVendorsDep
type MockVendorsDepMockRecorder struct {
mock *MockVendorsDep
}
// NewMockVendorsDep creates a new mock instance
func NewMockVendorsDep(ctrl *gomock.Controller) *MockVendorsDep {
mock := &MockVendorsDep{ctrl: ctrl}
mock.recorder = &MockVendorsDepMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockVendorsDep) EXPECT() *MockVendorsDepMockRecorder {
return m.recorder
}
// Foo mocks base method
func (m *MockVendorsDep) Foo() a.Ifc {
ret := m.ctrl.Call(m, "Foo")
ret0, _ := ret[0].(a.Ifc)
return ret0
}
// Foo indicates an expected call of Foo
func (mr *MockVendorsDepMockRecorder) Foo() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Foo", reflect.TypeOf((*MockVendorsDep)(nil).Foo))
}

View File

@@ -1,46 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: vendor_dep.go
// Package mock_vendor_dep is a generated GoMock package.
package mock_vendor_dep
import (
a "a"
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockVendorsDep is a mock of VendorsDep interface
type MockVendorsDep struct {
ctrl *gomock.Controller
recorder *MockVendorsDepMockRecorder
}
// MockVendorsDepMockRecorder is the mock recorder for MockVendorsDep
type MockVendorsDepMockRecorder struct {
mock *MockVendorsDep
}
// NewMockVendorsDep creates a new mock instance
func NewMockVendorsDep(ctrl *gomock.Controller) *MockVendorsDep {
mock := &MockVendorsDep{ctrl: ctrl}
mock.recorder = &MockVendorsDepMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockVendorsDep) EXPECT() *MockVendorsDepMockRecorder {
return m.recorder
}
// Foo mocks base method
func (m *MockVendorsDep) Foo() a.Ifc {
ret := m.ctrl.Call(m, "Foo")
ret0, _ := ret[0].(a.Ifc)
return ret0
}
// Foo indicates an expected call of Foo
func (mr *MockVendorsDepMockRecorder) Foo() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Foo", reflect.TypeOf((*MockVendorsDep)(nil).Foo))
}

View File

@@ -1,7 +0,0 @@
package vendor_dep
import "a"
type VendorsDep interface {
Foo() a.Ifc
}

View File

@@ -1 +0,0 @@
Test for [Issue#4](https://github.com/golang/mock/issues/4).

View File

@@ -1,3 +0,0 @@
package vendor_pkg
//go:generate mockgen -destination mock.go -package vendor_pkg a Ifc

View File

@@ -1,99 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: a (interfaces: Ifc)
// Package vendor_pkg is a generated GoMock package.
package vendor_pkg
import (
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockIfc is a mock of Ifc interface
type MockIfc struct {
ctrl *gomock.Controller
recorder *MockIfcMockRecorder
}
// MockIfcMockRecorder is the mock recorder for MockIfc
type MockIfcMockRecorder struct {
mock *MockIfc
}
// NewMockIfc creates a new mock instance
func NewMockIfc(ctrl *gomock.Controller) *MockIfc {
mock := &MockIfc{ctrl: ctrl}
mock.recorder = &MockIfcMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockIfc) EXPECT() *MockIfcMockRecorder {
return m.recorder
}
// A mocks base method
func (m *MockIfc) A(arg0 string) string {
ret := m.ctrl.Call(m, "A", arg0)
ret0, _ := ret[0].(string)
return ret0
}
// A indicates an expected call of A
func (mr *MockIfcMockRecorder) A(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "A", reflect.TypeOf((*MockIfc)(nil).A), arg0)
}
// B mocks base method
func (m *MockIfc) B(arg0 int) int {
ret := m.ctrl.Call(m, "B", arg0)
ret0, _ := ret[0].(int)
return ret0
}
// B indicates an expected call of B
func (mr *MockIfcMockRecorder) B(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "B", reflect.TypeOf((*MockIfc)(nil).B), arg0)
}
// C mocks base method
func (m *MockIfc) C(arg0 chan int) chan int {
ret := m.ctrl.Call(m, "C", arg0)
ret0, _ := ret[0].(chan int)
return ret0
}
// C indicates an expected call of C
func (mr *MockIfcMockRecorder) C(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "C", reflect.TypeOf((*MockIfc)(nil).C), arg0)
}
// D mocks base method
func (m *MockIfc) D(arg0 interface{}) {
m.ctrl.Call(m, "D", arg0)
}
// D indicates an expected call of D
func (mr *MockIfcMockRecorder) D(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "D", reflect.TypeOf((*MockIfc)(nil).D), arg0)
}
// E mocks base method
func (m *MockIfc) E(arg0 map[string]interface{}) {
m.ctrl.Call(m, "E", arg0)
}
// E indicates an expected call of E
func (mr *MockIfcMockRecorder) E(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "E", reflect.TypeOf((*MockIfc)(nil).E), arg0)
}
// F mocks base method
func (m *MockIfc) F(arg0 []float64) {
m.ctrl.Call(m, "F", arg0)
}
// F indicates an expected call of F
func (mr *MockIfcMockRecorder) F(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "F", reflect.TypeOf((*MockIfc)(nil).F), arg0)
}