diff --git a/README.md b/README.md
index f8b2c67..adaa794 100644
--- a/README.md
+++ b/README.md
@@ -20,10 +20,11 @@ go install github.com/kelveny/mockcompose
## Usage
```
- mockcompose can be launched with following options
-
+mockcompose generates mocking implementation for Go classes, interfaces and functions.
-c string
name of the source class to generate against
+ -help
+ if set, print usage information
-i string
name of the source interface to generate against
-mock value
@@ -305,4 +306,61 @@ func TestMockVariadic(t *testing.T) {
### __Answer__: If you've gone through FAQ answers above, you know that `mockcompose` of course can!
+
+
+### 5. How do I configure `go generate` in YAML?
+
+
+### __Answer__: Check out `mockcompose` self-test example [yaml](https://github.com/kelveny/mockcompose/tree/main/test/yaml)
+
+
+`go generate` configuration: mocks.go
+```go
+//go:generate mockcompose
+package yaml
+```
+
+`go generate` YAML configuration file: .mockcompose.yaml
+```yaml
+mockcompose:
+ - name: mockFmt
+ testOnly: true
+ sourcePkg: fmt
+ mock:
+ - Sprintf
+ - name: mockJson
+ testOnly: true
+ sourcePkg: encoding/json
+ mock:
+ - Marshal
+ - name: mockSampleClz
+ testOnly: true
+ className: sampleClz
+ real:
+ - "methodThatUsesGlobalFunction,fmt=fmtMock"
+ - name: mockSampleClz2
+ testOnly: true
+ className: sampleClz
+ real:
+ - "methodThatUsesMultileGlobalFunctions,fmt=fmtMock:json=jsonMock"
+ - name: mockSampleClz3
+ testOnly: true
+ className: sampleClz
+ real:
+ - "methodThatUsesMultileGlobalFunctions,fmt=fmtMock"
+ - name: MockSampleInterface
+ testOnly: true
+ interfaceName: SampleInterface
+ - name: mockFoo
+ testOnly: true
+ interfaceName: Foo
+ sourcePkg: github.com/kelveny/mockcompose/test/foo
+ - name: mockFmtclonedFuncs
+ testOnly: true
+ real:
+ - "functionThatUsesMultileGlobalFunctions,fmt=fmtMock:json=jsonMock"
+ - "functionThatUsesGlobalFunction,fmt=fmtMock"
+ - "functionThatUsesMultileGlobalFunctions2,fmt=fmtMock"
+```
+If `mockcompose` detects `.mockcompose.yaml` or `.mockcompose.yml` in package directory, it will load code generation configuration from the file.
diff --git a/cmd/common.go b/cmd/common.go
index 3e4ceb0..d64c821 100644
--- a/cmd/common.go
+++ b/cmd/common.go
@@ -27,16 +27,22 @@ package %s
`
)
-type commandOptions struct {
- mockName *string
- mockPkg *string
- clzName *string
- intfName *string
- srcPkg *string
- testOnly *bool
-
- methodsToClone stringSlice
- methodsToMock stringSlice
+// must be public for it to be used in loading YAML configuration
+type CommandOptions struct {
+ MockName string `yaml:"name"`
+ MockPkg string `yaml:"mockPkg"`
+ ClzName string `yaml:"className"`
+ IntfName string `yaml:"interfaceName"`
+ SrcPkg string `yaml:"sourcePkg"`
+ TestOnly bool `yaml:"testOnly"`
+
+ MethodsToClone []string `yaml:"real,flow"`
+ MethodsToMock []string `yaml:"mock,flow"`
+}
+
+// must be public for it to be used in loading YAML configuration
+type Config struct {
+ Mockcompose []CommandOptions `yaml:"mockcompose,flow"`
}
type parsedFileGenerator interface {
diff --git a/cmd/mockcompose.go b/cmd/mockcompose.go
index 24faa75..5bc6c30 100644
--- a/cmd/mockcompose.go
+++ b/cmd/mockcompose.go
@@ -3,7 +3,11 @@ package cmd
import (
"flag"
"fmt"
+ "io/ioutil"
"os"
+ "path/filepath"
+
+ yaml "gopkg.in/yaml.v2"
"github.com/kelveny/mockcompose/pkg/gofile"
"github.com/kelveny/mockcompose/pkg/logger"
@@ -24,112 +28,97 @@ mockcompose generates mocking implementation for Go classes, interfaces and func
os.Exit(1)
}
-func Execute() {
- var methodsToClone stringSlice
- var methodsToMock stringSlice
-
- vb := flag.Bool("v", false, "if set, print verbose logging messages")
- testOnly := flag.Bool("testonly", true, "if set, append _test to generated file name")
- prtVersion := flag.Bool("version", false, "if set, print version information")
- mockName := flag.String("n", "", "name of the generated class")
- mockPkg := flag.String("pkg", "", "name of the package that the generated class resides")
- clzName := flag.String("c", "", "name of the source class to generate against")
- srcPkg := flag.String("p", "", "path of the source package in which to search interfaces and functions")
- intfName := flag.String("i", "", "name of the source interface to generate against")
- flag.Var(&methodsToClone, "real", "name of the method function to be cloned from source class or source function")
- flag.Var(&methodsToMock, "mock", "name of the function to be mocked")
-
- flag.Parse()
-
- if *prtVersion {
- fmt.Println(GetSemverInfo())
- os.Exit(0)
+func loadConfig() *Config {
+ pkgDir, err := filepath.Abs("")
+ logger.Log(logger.VERBOSE, "Check directory %s for YAML configuration\n", pkgDir)
+ if err != nil {
+ logger.Log(logger.ERROR, "Error in accessing file system. error: %s\n", err)
+ os.Exit(1)
}
- if *vb {
- logger.LogLevel = int(logger.VERBOSE)
+ if cfg := loadYamlConfig(filepath.Join(pkgDir, ".mockcompose.yaml")); cfg != nil {
+ return cfg
+ }
- logger.Log(logger.VERBOSE, "Set logging to verbose mode\n")
+ if cfg := loadYamlConfig(filepath.Join(pkgDir, ".mockcompose.yml")); cfg != nil {
+ return cfg
}
- if *mockPkg == "" {
- *mockPkg = gofile.DerivePackage()
+ return nil
+}
- logger.Log(logger.VERBOSE, "Derive package name as: %s\n", *mockPkg)
- }
- fmt.Println()
+func loadYamlConfig(yamlFile string) *Config {
+ yamlConfig, err := ioutil.ReadFile(yamlFile)
+ if err == nil {
+ cfg := Config{}
- if *mockName == "" {
- usage()
- os.Exit(1)
+ err := yaml.Unmarshal(yamlConfig, &cfg)
+ if err != nil {
+ logger.Log(logger.ERROR, "Failed to load YAML config: %s\n", err)
+ }
+ return &cfg
}
- options := &commandOptions{
- mockName,
- mockPkg,
- clzName,
- intfName,
- srcPkg,
- testOnly,
- methodsToClone,
- methodsToMock,
- }
+ return nil
+}
+func executeOptions(options *CommandOptions) {
var g parsedFileGenerator
- if *clzName != "" {
- if len(methodsToClone) == 0 {
+
+ if options.ClzName != "" {
+ if len(options.MethodsToClone) == 0 {
logger.Log(logger.ERROR, "Please specify at least one real method name with -real option\n")
os.Exit(1)
}
g = &classMethodGenerator{
- clzName: *options.clzName,
- mockPkgName: *options.mockPkg,
- mockName: *options.mockName,
- methodsToClone: options.methodsToClone,
- methodsToMock: options.methodsToMock,
+ clzName: options.ClzName,
+ mockPkgName: options.MockPkg,
+ mockName: options.MockName,
+ methodsToClone: options.MethodsToClone,
+ methodsToMock: options.MethodsToMock,
}
- } else if *intfName != "" {
+ } else if options.IntfName != "" {
g = &interfaceMockGenerator{
- mockPkgName: *options.mockPkg,
- mockName: *options.mockName,
- intfName: *options.intfName,
+ mockPkgName: options.MockPkg,
+ mockName: options.MockName,
+ intfName: options.IntfName,
}
- if *options.srcPkg != "" {
+ if options.SrcPkg != "" {
scanPackageToGenerate(g.(loadedPackageGenerator), options)
return
}
} else {
- if len(methodsToMock) == 0 && len(methodsToClone) == 0 {
+ if len(options.MethodsToMock) == 0 && len(options.MethodsToClone) == 0 {
logger.Log(logger.ERROR, "no function to mock or clone\n")
os.Exit(1)
}
- if len(methodsToMock) > 0 && len(methodsToClone) > 0 {
+ if len(options.MethodsToMock) > 0 && len(options.MethodsToClone) > 0 {
logger.Log(logger.ERROR, "option -real and option -mock are exclusive in function clone generation\n")
os.Exit(1)
}
- if len(methodsToClone) > 0 {
- if *options.srcPkg != "" {
+ if len(options.MethodsToClone) > 0 {
+ if options.SrcPkg != "" {
logger.Log(logger.PROMPT,
"No source package support in function clone generation, ignore source package %s\n",
- *options.srcPkg)
+ options.SrcPkg)
}
g = &functionCloneGenerator{
- mockPkgName: *options.mockPkg,
- mockName: *options.mockName,
- methodsToClone: *&options.methodsToClone,
+ mockPkgName: options.MockPkg,
+ mockName: options.MockName,
+ methodsToClone: options.MethodsToClone,
}
} else {
g = &functionMockGenerator{
- mockPkgName: *options.mockPkg,
- mockName: *options.mockName,
- methodsToMock: *&options.methodsToMock,
+ mockPkgName: options.MockPkg,
+ mockName: options.MockName,
+ methodsToMock: options.MethodsToMock,
}
- if *options.srcPkg != "" {
+ if options.SrcPkg != "" {
scanPackageToGenerate(g.(loadedPackageGenerator), options)
return
}
@@ -138,3 +127,78 @@ func Execute() {
scanCWDToGenerate(g, options)
}
+
+func Execute() {
+ var methodsToClone stringSlice
+ var methodsToMock stringSlice
+
+ vb := flag.Bool("v", false, "if set, print verbose logging messages")
+ testOnly := flag.Bool("testonly", true, "if set, append _test to generated file name")
+ prtVersion := flag.Bool("version", false, "if set, print version information")
+ help := flag.Bool("help", false, "if set, print usage information")
+ mockName := flag.String("n", "", "name of the generated class")
+ mockPkg := flag.String("pkg", "", "name of the package that the generated class resides")
+ clzName := flag.String("c", "", "name of the source class to generate against")
+ srcPkg := flag.String("p", "", "path of the source package in which to search interfaces and functions")
+ intfName := flag.String("i", "", "name of the source interface to generate against")
+ flag.Var(&methodsToClone, "real", "name of the method function to be cloned from source class or source function")
+ flag.Var(&methodsToMock, "mock", "name of the function to be mocked")
+
+ flag.Parse()
+
+ if *prtVersion {
+ fmt.Println(GetSemverInfo())
+ os.Exit(0)
+ }
+
+ if *help {
+ usage()
+ os.Exit(0)
+ }
+
+ if *vb {
+ logger.LogLevel = int(logger.VERBOSE)
+
+ logger.Log(logger.VERBOSE, "Set logging to verbose mode\n")
+ }
+
+ if cfg := loadConfig(); cfg != nil {
+ logger.Log(logger.VERBOSE, "Found mockcompose YAML configuration, ignore command line options\n")
+
+ derivedPkg := gofile.DerivePackage()
+ for _, options := range cfg.Mockcompose {
+ if options.MockPkg == "" {
+ options.MockPkg = derivedPkg
+ }
+
+ executeOptions(&options)
+ }
+
+ return
+ }
+
+ if *mockPkg == "" {
+ *mockPkg = gofile.DerivePackage()
+
+ logger.Log(logger.VERBOSE, "Derive package name as: %s\n", *mockPkg)
+ }
+ fmt.Println()
+
+ if *mockName == "" {
+ usage()
+ os.Exit(1)
+ }
+
+ options := &CommandOptions{
+ MockName: *mockName,
+ MockPkg: *mockPkg,
+ ClzName: *clzName,
+ IntfName: *intfName,
+ SrcPkg: *srcPkg,
+ TestOnly: *testOnly,
+ MethodsToClone: methodsToClone,
+ MethodsToMock: methodsToMock,
+ }
+
+ executeOptions(options)
+}
diff --git a/cmd/scan.go b/cmd/scan.go
index cfb2230..5274f0f 100644
--- a/cmd/scan.go
+++ b/cmd/scan.go
@@ -18,25 +18,25 @@ import (
func scanPackageToGenerate(
g loadedPackageGenerator,
- options *commandOptions,
+ options *CommandOptions,
) {
cfg := &packages.Config{Mode: packages.NeedTypes | packages.NeedSyntax}
- pkgs, err := packages.Load(cfg, *options.srcPkg)
+ pkgs, err := packages.Load(cfg, options.SrcPkg)
if err != nil {
logger.Log(logger.ERROR, "Error in loading package %s, error: %s\n",
- *options.srcPkg, err,
+ options.SrcPkg, err,
)
return
}
- logger.Log(logger.PROMPT, "Scan package %s...\n", *options.srcPkg)
+ logger.Log(logger.PROMPT, "Scan package %s...\n", options.SrcPkg)
var outputFileName string
- if *options.testOnly {
- outputFileName = fmt.Sprintf("mockc_%s_test.go", *options.mockName)
+ if options.TestOnly {
+ outputFileName = fmt.Sprintf("mockc_%s_test.go", options.MockName)
} else {
- outputFileName = fmt.Sprintf("mockc_%s.go", *options.mockName)
+ outputFileName = fmt.Sprintf("mockc_%s.go", options.MockName)
}
output, err := os.OpenFile(
@@ -76,13 +76,13 @@ func scanPackageToGenerate(
gofile.FormatGoFile(outputFileName)
- logger.Log(logger.PROMPT, "Done scan with package %s\n\n", *options.srcPkg)
+ logger.Log(logger.PROMPT, "Done scan with package %s\n\n", options.SrcPkg)
}
// scan current working directory
func scanCWDToGenerate(
g parsedFileGenerator,
- options *commandOptions,
+ options *CommandOptions,
) {
pkgDir, err := filepath.Abs("")
logger.Log(logger.VERBOSE, "Check directory %s for code generation\n", pkgDir)
@@ -107,7 +107,7 @@ func scanCWDToGenerate(
// not in use
func scanGoPathToGenerate(
g parsedFileGenerator,
- options *commandOptions,
+ options *CommandOptions,
) {
// iterate candidates from package directory
gopathConfig := gofile.GetGoPathConfig()
@@ -115,7 +115,7 @@ func scanGoPathToGenerate(
for _, gopath := range strings.Split(gopathConfig, string(filepath.ListSeparator)) {
// support scanning of subfolder src/ and pkg/
for _, subFolder := range []string{"src", "pkg"} {
- pkgDir, err := filepath.Abs(path.Join(gopath, subFolder, *options.mockPkg))
+ pkgDir, err := filepath.Abs(path.Join(gopath, subFolder, options.MockPkg))
logger.Log(logger.VERBOSE, "Check directory %s for code generation\n", pkgDir)
if err != nil {
logger.Log(logger.ERROR, "Error in accessing file system. error: %s\n", err)
@@ -139,7 +139,7 @@ func scanGoPathToGenerate(
func scanFileToGenerate(
g parsedFileGenerator,
- options *commandOptions,
+ options *CommandOptions,
pkgDir string,
fileInfo os.FileInfo,
) {
@@ -163,10 +163,10 @@ func scanFileToGenerate(
}
var outputFileName string
- if *options.testOnly {
- outputFileName = fmt.Sprintf("mockc_%s_test.go", *options.mockName)
+ if options.TestOnly {
+ outputFileName = fmt.Sprintf("mockc_%s_test.go", options.MockName)
} else {
- outputFileName = fmt.Sprintf("mockc_%s.go", *options.mockName)
+ outputFileName = fmt.Sprintf("mockc_%s.go", options.MockName)
}
output, err := os.OpenFile(
diff --git a/go.mod b/go.mod
index 8c956de..116e959 100644
--- a/go.mod
+++ b/go.mod
@@ -7,4 +7,5 @@ require (
golang.org/x/mod v0.4.2 // indirect
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 // indirect
golang.org/x/tools v0.1.0
+ gopkg.in/yaml.v2 v2.4.0
)
diff --git a/go.sum b/go.sum
index 1036f08..63b41ad 100644
--- a/go.sum
+++ b/go.sum
@@ -36,5 +36,7 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1N
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/test/clonefn/fn.go b/test/clonefn/fn.go
index 5717ca9..0092034 100644
--- a/test/clonefn/fn.go
+++ b/test/clonefn/fn.go
@@ -25,7 +25,7 @@ func functionThatUsesMultileGlobalFunctions(
// skip fansy logic...
//
- // call out to a global function in fmt package and filepath package
+ // call out to a global function in fmt package and json package
b, _ := json.Marshal(format)
return string(b) + fmt.Sprintf(format, args...)
}
@@ -38,7 +38,7 @@ func functionThatUsesMultileGlobalFunctions2(
// skip fansy logic...
//
- // call out to a global function in fmt package and filepath package
+ // call out to a global function in fmt package and json package
b, _ := json.Marshal(format)
return string(b) + fmt.Sprintf(format, args...)
}
diff --git a/test/mockfn/fn.go b/test/mockfn/fn.go
index 71e6e04..7eb7c37 100644
--- a/test/mockfn/fn.go
+++ b/test/mockfn/fn.go
@@ -28,7 +28,7 @@ func (c *sampleClz) methodThatUsesMultileGlobalFunctions(
// skip fansy logic...
//
- // call out to a global function in fmt package and filepath package
+ // call out to a global function in fmt package and json package
b, _ := json.Marshal(format)
return string(b) + fmt.Sprintf(format, args...)
}
diff --git a/test/yaml/.mockcompose.yaml b/test/yaml/.mockcompose.yaml
new file mode 100644
index 0000000..57ed5c7
--- /dev/null
+++ b/test/yaml/.mockcompose.yaml
@@ -0,0 +1,39 @@
+mockcompose:
+ - name: mockFmt
+ testOnly: true
+ sourcePkg: fmt
+ mock:
+ - Sprintf
+ - name: mockJson
+ testOnly: true
+ sourcePkg: encoding/json
+ mock:
+ - Marshal
+ - name: mockSampleClz
+ testOnly: true
+ className: sampleClz
+ real:
+ - "methodThatUsesGlobalFunction,fmt=fmtMock"
+ - name: mockSampleClz2
+ testOnly: true
+ className: sampleClz
+ real:
+ - "methodThatUsesMultileGlobalFunctions,fmt=fmtMock:json=jsonMock"
+ - name: mockSampleClz3
+ testOnly: true
+ className: sampleClz
+ real:
+ - "methodThatUsesMultileGlobalFunctions,fmt=fmtMock"
+ - name: MockSampleInterface
+ testOnly: true
+ interfaceName: SampleInterface
+ - name: mockFoo
+ testOnly: true
+ interfaceName: Foo
+ sourcePkg: github.com/kelveny/mockcompose/test/foo
+ - name: mockFmtclonedFuncs
+ testOnly: true
+ real:
+ - "functionThatUsesMultileGlobalFunctions,fmt=fmtMock:json=jsonMock"
+ - "functionThatUsesGlobalFunction,fmt=fmtMock"
+ - "functionThatUsesMultileGlobalFunctions2,fmt=fmtMock"
diff --git a/test/yaml/mockc_MockSampleInterface_test.go b/test/yaml/mockc_MockSampleInterface_test.go
new file mode 100644
index 0000000..de25b63
--- /dev/null
+++ b/test/yaml/mockc_MockSampleInterface_test.go
@@ -0,0 +1,214 @@
+//
+// CODE GENERATED AUTOMATICALLY WITH github.com/kelveny/mockcompose
+// THIS FILE SHOULD NOT BE EDITED BY HAND
+//
+package yaml
+
+import (
+ "github.com/kelveny/mockcompose/test/foo"
+ "github.com/stretchr/testify/mock"
+)
+
+type MockSampleInterface struct {
+ mock.Mock
+}
+
+func (m *MockSampleInterface) Unnamed(_a0 string, _a1 int, _a2 chan<- string) error {
+
+ _mc_ret := m.Called(_a0, _a1, _a2)
+
+ var _r0 error
+
+ if _rfn, ok := _mc_ret.Get(0).(func(string, int, chan<- string) error); ok {
+ _r0 = _rfn(_a0, _a1, _a2)
+ } else {
+ _r0 = _mc_ret.Error(0)
+ }
+
+ return _r0
+
+}
+
+func (m *MockSampleInterface) Variadic(format string, args ...string) string {
+
+ _mc_args := make([]interface{}, 0, 1+len(args))
+
+ _mc_args = append(_mc_args, format)
+
+ for _, _va := range args {
+ _mc_args = append(_mc_args, _va)
+ }
+
+ _mc_ret := m.Called(_mc_args...)
+
+ var _r0 string
+
+ if _rfn, ok := _mc_ret.Get(0).(func(string, ...string) string); ok {
+ _r0 = _rfn(format, args...)
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).(string)
+ }
+ }
+
+ return _r0
+
+}
+
+func (m *MockSampleInterface) Variadic2(format string, args ...interface{}) string {
+
+ _mc_args := make([]interface{}, 0, 1+len(args))
+
+ _mc_args = append(_mc_args, format)
+
+ for _, _va := range args {
+ _mc_args = append(_mc_args, _va)
+ }
+
+ _mc_ret := m.Called(_mc_args...)
+
+ var _r0 string
+
+ if _rfn, ok := _mc_ret.Get(0).(func(string, ...interface{}) string); ok {
+ _r0 = _rfn(format, args...)
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).(string)
+ }
+ }
+
+ return _r0
+
+}
+
+func (m *MockSampleInterface) Variadic3(args ...string) string {
+
+ _mc_args := make([]interface{}, 0, 0+len(args))
+
+ for _, _va := range args {
+ _mc_args = append(_mc_args, _va)
+ }
+
+ _mc_ret := m.Called(_mc_args...)
+
+ var _r0 string
+
+ if _rfn, ok := _mc_ret.Get(0).(func(...string) string); ok {
+ _r0 = _rfn(args...)
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).(string)
+ }
+ }
+
+ return _r0
+
+}
+
+func (m *MockSampleInterface) Variadic4(args ...interface{}) string {
+
+ _mc_ret := m.Called(args...)
+
+ var _r0 string
+
+ if _rfn, ok := _mc_ret.Get(0).(func(...interface{}) string); ok {
+ _r0 = _rfn(args...)
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).(string)
+ }
+ }
+
+ return _r0
+
+}
+
+func (m *MockSampleInterface) CallFooBar(f foo.Foo) (bool, string) {
+
+ _mc_ret := m.Called(f)
+
+ var _r0 bool
+
+ if _rfn, ok := _mc_ret.Get(0).(func(foo.Foo) bool); ok {
+ _r0 = _rfn(f)
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).(bool)
+ }
+ }
+
+ var _r1 string
+
+ if _rfn, ok := _mc_ret.Get(1).(func(foo.Foo) string); ok {
+ _r1 = _rfn(f)
+ } else {
+ if _mc_ret.Get(1) != nil {
+ _r1 = _mc_ret.Get(1).(string)
+ }
+ }
+
+ return _r0, _r1
+
+}
+
+func (m *MockSampleInterface) CollapsedParams(arg1 []byte, arg2 []byte) string {
+
+ _mc_ret := m.Called(arg1, arg2)
+
+ var _r0 string
+
+ if _rfn, ok := _mc_ret.Get(0).(func([]byte, []byte) string); ok {
+ _r0 = _rfn(arg1, arg2)
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).(string)
+ }
+ }
+
+ return _r0
+
+}
+
+func (m *MockSampleInterface) CollapsedReturns() (x int, y int, z string) {
+
+ _mc_ret := m.Called()
+
+ var _r0 int
+
+ if _rfn, ok := _mc_ret.Get(0).(func() int); ok {
+ _r0 = _rfn()
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).(int)
+ }
+ }
+
+ var _r1 int
+
+ if _rfn, ok := _mc_ret.Get(1).(func() int); ok {
+ _r1 = _rfn()
+ } else {
+ if _mc_ret.Get(1) != nil {
+ _r1 = _mc_ret.Get(1).(int)
+ }
+ }
+
+ var _r2 string
+
+ if _rfn, ok := _mc_ret.Get(2).(func() string); ok {
+ _r2 = _rfn()
+ } else {
+ if _mc_ret.Get(2) != nil {
+ _r2 = _mc_ret.Get(2).(string)
+ }
+ }
+
+ return _r0, _r1, _r2
+
+}
+
+func (m *MockSampleInterface) VoidReturn() {
+
+ m.Called()
+
+}
diff --git a/test/yaml/mockc_mockFmt_test.go b/test/yaml/mockc_mockFmt_test.go
new file mode 100644
index 0000000..ad44925
--- /dev/null
+++ b/test/yaml/mockc_mockFmt_test.go
@@ -0,0 +1,39 @@
+//
+// CODE GENERATED AUTOMATICALLY WITH github.com/kelveny/mockcompose
+// THIS FILE SHOULD NOT BE EDITED BY HAND
+//
+package yaml
+
+import (
+ "github.com/stretchr/testify/mock"
+)
+
+type mockFmt struct {
+ mock.Mock
+}
+
+func (m *mockFmt) Sprintf(format string, a ...interface{}) string {
+
+ _mc_args := make([]interface{}, 0, 1+len(a))
+
+ _mc_args = append(_mc_args, format)
+
+ for _, _va := range a {
+ _mc_args = append(_mc_args, _va)
+ }
+
+ _mc_ret := m.Called(_mc_args...)
+
+ var _r0 string
+
+ if _rfn, ok := _mc_ret.Get(0).(func(string, ...interface{}) string); ok {
+ _r0 = _rfn(format, a...)
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).(string)
+ }
+ }
+
+ return _r0
+
+}
diff --git a/test/yaml/mockc_mockFmtclonedFuncs_test.go b/test/yaml/mockc_mockFmtclonedFuncs_test.go
new file mode 100644
index 0000000..8fe7b52
--- /dev/null
+++ b/test/yaml/mockc_mockFmtclonedFuncs_test.go
@@ -0,0 +1,30 @@
+//
+// CODE GENERATED AUTOMATICALLY WITH github.com/kelveny/mockcompose
+// THIS FILE SHOULD NOT BE EDITED BY HAND
+//
+package yaml
+
+import (
+ "encoding/json"
+)
+
+func functionThatUsesGlobalFunction_clone(format string, args ...interface{}) string {
+ fmt := fmtMock
+
+ return fmt.Sprintf(format, args...)
+}
+
+func functionThatUsesMultileGlobalFunctions_clone(format string, args ...interface{}) string {
+ fmt := fmtMock
+ json := jsonMock
+
+ b, _ := json.Marshal(format)
+ return string(b) + fmt.Sprintf(format, args...)
+}
+
+func functionThatUsesMultileGlobalFunctions2_clone(format string, args ...interface{}) string {
+ fmt := fmtMock
+
+ b, _ := json.Marshal(format)
+ return string(b) + fmt.Sprintf(format, args...)
+}
diff --git a/test/yaml/mockc_mockFoo_test.go b/test/yaml/mockc_mockFoo_test.go
new file mode 100644
index 0000000..8483c2c
--- /dev/null
+++ b/test/yaml/mockc_mockFoo_test.go
@@ -0,0 +1,49 @@
+//
+// CODE GENERATED AUTOMATICALLY WITH github.com/kelveny/mockcompose
+// THIS FILE SHOULD NOT BE EDITED BY HAND
+//
+package yaml
+
+import (
+ "github.com/stretchr/testify/mock"
+)
+
+type mockFoo struct {
+ mock.Mock
+}
+
+func (m *mockFoo) Foo() string {
+
+ _mc_ret := m.Called()
+
+ var _r0 string
+
+ if _rfn, ok := _mc_ret.Get(0).(func() string); ok {
+ _r0 = _rfn()
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).(string)
+ }
+ }
+
+ return _r0
+
+}
+
+func (m *mockFoo) Bar() bool {
+
+ _mc_ret := m.Called()
+
+ var _r0 bool
+
+ if _rfn, ok := _mc_ret.Get(0).(func() bool); ok {
+ _r0 = _rfn()
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).(bool)
+ }
+ }
+
+ return _r0
+
+}
diff --git a/test/yaml/mockc_mockJson_test.go b/test/yaml/mockc_mockJson_test.go
new file mode 100644
index 0000000..997ead7
--- /dev/null
+++ b/test/yaml/mockc_mockJson_test.go
@@ -0,0 +1,39 @@
+//
+// CODE GENERATED AUTOMATICALLY WITH github.com/kelveny/mockcompose
+// THIS FILE SHOULD NOT BE EDITED BY HAND
+//
+package yaml
+
+import (
+ "github.com/stretchr/testify/mock"
+)
+
+type mockJson struct {
+ mock.Mock
+}
+
+func (m *mockJson) Marshal(v interface{}) ([]byte, error) {
+
+ _mc_ret := m.Called(v)
+
+ var _r0 []byte
+
+ if _rfn, ok := _mc_ret.Get(0).(func(interface{}) []byte); ok {
+ _r0 = _rfn(v)
+ } else {
+ if _mc_ret.Get(0) != nil {
+ _r0 = _mc_ret.Get(0).([]byte)
+ }
+ }
+
+ var _r1 error
+
+ if _rfn, ok := _mc_ret.Get(1).(func(interface{}) error); ok {
+ _r1 = _rfn(v)
+ } else {
+ _r1 = _mc_ret.Error(1)
+ }
+
+ return _r0, _r1
+
+}
diff --git a/test/yaml/mockc_mockSampleClz2_test.go b/test/yaml/mockc_mockSampleClz2_test.go
new file mode 100644
index 0000000..8d40367
--- /dev/null
+++ b/test/yaml/mockc_mockSampleClz2_test.go
@@ -0,0 +1,22 @@
+//
+// CODE GENERATED AUTOMATICALLY WITH github.com/kelveny/mockcompose
+// THIS FILE SHOULD NOT BE EDITED BY HAND
+//
+package yaml
+
+import (
+ "github.com/stretchr/testify/mock"
+)
+
+type mockSampleClz2 struct {
+ sampleClz
+ mock.Mock
+}
+
+func (c *mockSampleClz2) methodThatUsesMultileGlobalFunctions(format string, args ...interface{}) string {
+ fmt := fmtMock
+ json := jsonMock
+
+ b, _ := json.Marshal(format)
+ return string(b) + fmt.Sprintf(format, args...)
+}
diff --git a/test/yaml/mockc_mockSampleClz3_test.go b/test/yaml/mockc_mockSampleClz3_test.go
new file mode 100644
index 0000000..0b3e22f
--- /dev/null
+++ b/test/yaml/mockc_mockSampleClz3_test.go
@@ -0,0 +1,22 @@
+//
+// CODE GENERATED AUTOMATICALLY WITH github.com/kelveny/mockcompose
+// THIS FILE SHOULD NOT BE EDITED BY HAND
+//
+package yaml
+
+import (
+ "encoding/json"
+ "github.com/stretchr/testify/mock"
+)
+
+type mockSampleClz3 struct {
+ sampleClz
+ mock.Mock
+}
+
+func (c *mockSampleClz3) methodThatUsesMultileGlobalFunctions(format string, args ...interface{}) string {
+ fmt := fmtMock
+
+ b, _ := json.Marshal(format)
+ return string(b) + fmt.Sprintf(format, args...)
+}
diff --git a/test/yaml/mockc_mockSampleClz_test.go b/test/yaml/mockc_mockSampleClz_test.go
new file mode 100644
index 0000000..a5ee4bf
--- /dev/null
+++ b/test/yaml/mockc_mockSampleClz_test.go
@@ -0,0 +1,20 @@
+//
+// CODE GENERATED AUTOMATICALLY WITH github.com/kelveny/mockcompose
+// THIS FILE SHOULD NOT BE EDITED BY HAND
+//
+package yaml
+
+import (
+ "github.com/stretchr/testify/mock"
+)
+
+type mockSampleClz struct {
+ sampleClz
+ mock.Mock
+}
+
+func (c *mockSampleClz) methodThatUsesGlobalFunction(format string, args ...interface{}) string {
+ fmt := fmtMock
+
+ return fmt.Sprintf(format, args...)
+}
diff --git a/test/yaml/mocks.go b/test/yaml/mocks.go
new file mode 100644
index 0000000..1ddb442
--- /dev/null
+++ b/test/yaml/mocks.go
@@ -0,0 +1,2 @@
+//go:generate mockcompose
+package yaml
diff --git a/test/yaml/yaml.go b/test/yaml/yaml.go
new file mode 100644
index 0000000..cc7f297
--- /dev/null
+++ b/test/yaml/yaml.go
@@ -0,0 +1,97 @@
+package yaml
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/kelveny/mockcompose/test/foo"
+)
+
+type SampleInterface interface {
+ // test unnamed parameters
+ Unnamed(string, int, chan<- string) error
+
+ // test method/function with variadic parameters
+ Variadic(format string, args ...string) string
+ Variadic2(format string, args ...interface{}) string
+ Variadic3(args ...string) string
+ Variadic4(args ...interface{}) string
+
+ // test cross-package imports
+ CallFooBar(f foo.Foo) (bool, string)
+
+ // test collapsed paramemters
+ CollapsedParams(arg1, arg2 []byte) string
+
+ // test collapsed returns
+ CollapsedReturns() (x, y int, z string)
+
+ // test void return
+ VoidReturn()
+}
+
+type sampleClz struct {
+}
+
+func (c *sampleClz) methodThatUsesGlobalFunction(
+ format string,
+ args ...interface{},
+) string {
+ //
+ // skip fansy logic...
+ //
+
+ // call out to a global function in fmt package
+ return fmt.Sprintf(format, args...)
+}
+
+func (c *sampleClz) methodThatUsesMultileGlobalFunctions(
+ format string,
+ args ...interface{},
+) string {
+ //
+ // skip fansy logic...
+ //
+
+ // call out to a global function in fmt package and json package
+ b, _ := json.Marshal(format)
+ return string(b) + fmt.Sprintf(format, args...)
+}
+
+func functionThatUsesGlobalFunction(
+ format string,
+ args ...interface{},
+) string {
+ //
+ // skip fansy logic...
+ //
+
+ // call out to a global function in fmt package
+ return fmt.Sprintf(format, args...)
+}
+
+func functionThatUsesMultileGlobalFunctions(
+ format string,
+ args ...interface{},
+) string {
+ //
+ // skip fansy logic...
+ //
+
+ // call out to a global function in fmt package and json package
+ b, _ := json.Marshal(format)
+ return string(b) + fmt.Sprintf(format, args...)
+}
+
+func functionThatUsesMultileGlobalFunctions2(
+ format string,
+ args ...interface{},
+) string {
+ //
+ // skip fansy logic...
+ //
+
+ // call out to a global function in fmt package and json package
+ b, _ := json.Marshal(format)
+ return string(b) + fmt.Sprintf(format, args...)
+}
diff --git a/test/yaml/yaml_test.go b/test/yaml/yaml_test.go
new file mode 100644
index 0000000..39a9501
--- /dev/null
+++ b/test/yaml/yaml_test.go
@@ -0,0 +1,53 @@
+package yaml
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/mock"
+ "github.com/stretchr/testify/require"
+)
+
+var jsonMock *mockJson = &mockJson{}
+var fmtMock *mockFmt = &mockFmt{}
+
+func TestSampleClz(t *testing.T) {
+ assert := require.New(t)
+
+ // setup function mocks
+ jsonMock.On("Marshal", mock.Anything).Return(([]byte)("mocked Marshal"), nil)
+ fmtMock.On("Sprintf", mock.Anything, mock.Anything).Return("mocked Sprintf")
+
+ // inside mockSampleClz.methodThatUsesMultileGlobalFunctions: fmt.Sprintf is mocked
+ sc := mockSampleClz{}
+ assert.True(sc.methodThatUsesGlobalFunction("format", "value") == "mocked Sprintf")
+
+ // inside mockSampleClz2.methodThatUsesMultileGlobalFunctions: both json.Marshal()
+ // and fmt.Sprintf are mocked
+ sc2 := mockSampleClz2{}
+ assert.True(sc2.methodThatUsesMultileGlobalFunctions("format", "value") == "mocked Marshalmocked Sprintf")
+
+ // inside mockSampleClz3.methodThatUsesMultileGlobalFunctions: json.Marshal() is not mocked,
+ // fmt.Sprintf is mocked
+ sc3 := mockSampleClz3{}
+ assert.True(sc3.methodThatUsesMultileGlobalFunctions("format", "value") == "\"format\"mocked Sprintf")
+}
+
+func TestClonedFuncs(t *testing.T) {
+ assert := require.New(t)
+
+ // setup function mocks
+ jsonMock.On("Marshal", mock.Anything).Return(([]byte)("mocked Marshal"), nil)
+ fmtMock.On("Sprintf", mock.Anything, mock.Anything).Return("mocked Sprintf")
+
+ // inside functionThatUsesMultileGlobalFunctions: fmt.Sprintf is mocked
+ assert.True(functionThatUsesGlobalFunction_clone("format", "value") == "mocked Sprintf")
+
+ // inside functionThatUsesMultileGlobalFunctions: both json.Marshal()
+ // and fmt.Sprintf are mocked
+ assert.True(functionThatUsesMultileGlobalFunctions_clone("format", "value") == "mocked Marshalmocked Sprintf")
+
+ // inside functionThatUsesMultileGlobalFunctions2: json.Marshal() is not mocked,
+ // fmt.Sprintf is mocked
+ assert.True(functionThatUsesMultileGlobalFunctions2_clone("format", "value") == "\"format\"mocked Sprintf")
+
+}