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") + +}