From 005b899ec8e99f46580863219ceba8f56e866674 Mon Sep 17 00:00:00 2001 From: Suhas Karanth Date: Sun, 16 Aug 2020 12:55:01 +0530 Subject: [PATCH] Add noop formatter as an option (#133) Useful to print the generated source code for debugging. --- README.md | 7 +- main.go | 2 +- pkg/moq/formatter.go | 2 + pkg/moq/moq.go | 5 +- pkg/moq/moq_test.go | 5 +- .../imports/{testdata => two}/gofmt.golden.go | 22 ++-- .../{testdata => two}/goimports.golden.go | 22 ++-- .../testpackages/imports/two/noop.golden.go | 117 ++++++++++++++++++ 8 files changed, 154 insertions(+), 28 deletions(-) rename pkg/moq/testpackages/imports/{testdata => two}/gofmt.golden.go (78%) rename pkg/moq/testpackages/imports/{testdata => two}/goimports.golden.go (78%) create mode 100644 pkg/moq/testpackages/imports/two/noop.golden.go diff --git a/README.md b/README.md index 822d04d..bdf7347 100644 --- a/README.md +++ b/README.md @@ -26,13 +26,13 @@ $ go get github.com/matryer/moq ``` moq [flags] source-dir interface [interface2 [interface3 [...]]] -fmt string - go pretty-printer: gofmt (default) or goimports + go pretty-printer: gofmt, goimports or noop (default gofmt) -out string output file (default stdout) -pkg string package name (default will infer) -stub - return zero values when no mock implementation is provided, do not panic + return zero values when no mock implementation is provided, do not panic Specifying an alias for the mock is also supported with the format 'interface:alias' Ex: moq -pkg different . MyInterface:MyMock ``` @@ -109,6 +109,9 @@ The mocked structure implements the interface, where each method calls the assoc * Use closured variables inside your test function to capture details about the calls to the methods * Use `.MethodCalls()` to track the calls * Use `go:generate` to invoke the `moq` command +* If Moq fails with a `go/format` error, it indicates the generated code was not valid. + You can run the same command with `-fmt noop` to print the generated source code without attempting to format it. + This can aid in debugging the root cause. ## License diff --git a/main.go b/main.go index 238a2da..42011b1 100644 --- a/main.go +++ b/main.go @@ -25,7 +25,7 @@ func main() { var flags userFlags flag.StringVar(&flags.outFile, "out", "", "output file (default stdout)") flag.StringVar(&flags.pkgName, "pkg", "", "package name (default will infer)") - flag.StringVar(&flags.formatter, "fmt", "", "go pretty-printer: gofmt (default) or goimports") + flag.StringVar(&flags.formatter, "fmt", "", "go pretty-printer: gofmt, goimports or noop (default gofmt)") flag.BoolVar(&flags.stubImpl, "stub", false, "return zero values when no mock implementation is provided, do not panic") diff --git a/pkg/moq/formatter.go b/pkg/moq/formatter.go index 6154561..61d8c31 100644 --- a/pkg/moq/formatter.go +++ b/pkg/moq/formatter.go @@ -29,3 +29,5 @@ func gofmt(src []byte) ([]byte, error) { return formatted, nil } + +func noopFmt(src []byte) ([]byte, error) { return src, nil } diff --git a/pkg/moq/moq.go b/pkg/moq/moq.go index c3b0fa0..1725361 100644 --- a/pkg/moq/moq.go +++ b/pkg/moq/moq.go @@ -61,8 +61,11 @@ func New(conf Config) (*Mocker, error) { } fmter := gofmt - if conf.Formatter == "goimports" { + switch conf.Formatter { + case "goimports": fmter = goimports + case "noop": + fmter = noopFmt } return &Mocker{ diff --git a/pkg/moq/moq_test.go b/pkg/moq/moq_test.go index 1a490d6..65a0639 100644 --- a/pkg/moq/moq_test.go +++ b/pkg/moq/moq_test.go @@ -332,6 +332,7 @@ func TestFormatter(t *testing.T) { }{ {name: "gofmt", conf: Config{SrcDir: "testpackages/imports/two"}}, {name: "goimports", conf: Config{SrcDir: "testpackages/imports/two", Formatter: "goimports"}}, + {name: "noop", conf: Config{SrcDir: "testpackages/imports/two", Formatter: "noop"}}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { @@ -340,12 +341,12 @@ func TestFormatter(t *testing.T) { t.Fatalf("moq.New: %s", err) } var buf bytes.Buffer - err = m.Mock(&buf, "DoSomething") + err = m.Mock(&buf, "DoSomething:"+tc.name+"Mock") if err != nil { t.Errorf("m.Mock: %s", err) } - golden := filepath.Join("testpackages/imports/testdata", tc.name+".golden.go") + golden := filepath.Join("testpackages/imports/two", tc.name+".golden.go") if err := matchGoldenFile(golden, buf.Bytes()); err != nil { t.Errorf("check golden file: %s", err) } diff --git a/pkg/moq/testpackages/imports/testdata/gofmt.golden.go b/pkg/moq/testpackages/imports/two/gofmt.golden.go similarity index 78% rename from pkg/moq/testpackages/imports/testdata/gofmt.golden.go rename to pkg/moq/testpackages/imports/two/gofmt.golden.go index 9c50834..36312c4 100644 --- a/pkg/moq/testpackages/imports/testdata/gofmt.golden.go +++ b/pkg/moq/testpackages/imports/two/gofmt.golden.go @@ -8,16 +8,16 @@ import ( "sync" ) -// Ensure, that DoSomethingMock does implement DoSomething. +// Ensure, that gofmtMock does implement DoSomething. // If this is not the case, regenerate this file with moq. -var _ DoSomething = &DoSomethingMock{} +var _ DoSomething = &gofmtMock{} -// DoSomethingMock is a mock implementation of DoSomething. +// gofmtMock is a mock implementation of DoSomething. // // func TestSomethingThatUsesDoSomething(t *testing.T) { // // // make and configure a mocked DoSomething -// mockedDoSomething := &DoSomethingMock{ +// mockedDoSomething := &gofmtMock{ // AnotherFunc: func(thing one.Thing) error { // panic("mock out the Another method") // }, @@ -30,7 +30,7 @@ var _ DoSomething = &DoSomethingMock{} // // and then make assertions. // // } -type DoSomethingMock struct { +type gofmtMock struct { // AnotherFunc mocks the Another method. AnotherFunc func(thing one.Thing) error @@ -55,9 +55,9 @@ type DoSomethingMock struct { } // Another calls AnotherFunc. -func (mock *DoSomethingMock) Another(thing one.Thing) error { +func (mock *gofmtMock) Another(thing one.Thing) error { if mock.AnotherFunc == nil { - panic("DoSomethingMock.AnotherFunc: method is nil but DoSomething.Another was just called") + panic("gofmtMock.AnotherFunc: method is nil but DoSomething.Another was just called") } callInfo := struct { Thing one.Thing @@ -73,7 +73,7 @@ func (mock *DoSomethingMock) Another(thing one.Thing) error { // AnotherCalls gets all the calls that were made to Another. // Check the length with: // len(mockedDoSomething.AnotherCalls()) -func (mock *DoSomethingMock) AnotherCalls() []struct { +func (mock *gofmtMock) AnotherCalls() []struct { Thing one.Thing } { var calls []struct { @@ -86,9 +86,9 @@ func (mock *DoSomethingMock) AnotherCalls() []struct { } // Do calls DoFunc. -func (mock *DoSomethingMock) Do(thing one.Thing) error { +func (mock *gofmtMock) Do(thing one.Thing) error { if mock.DoFunc == nil { - panic("DoSomethingMock.DoFunc: method is nil but DoSomething.Do was just called") + panic("gofmtMock.DoFunc: method is nil but DoSomething.Do was just called") } callInfo := struct { Thing one.Thing @@ -104,7 +104,7 @@ func (mock *DoSomethingMock) Do(thing one.Thing) error { // DoCalls gets all the calls that were made to Do. // Check the length with: // len(mockedDoSomething.DoCalls()) -func (mock *DoSomethingMock) DoCalls() []struct { +func (mock *gofmtMock) DoCalls() []struct { Thing one.Thing } { var calls []struct { diff --git a/pkg/moq/testpackages/imports/testdata/goimports.golden.go b/pkg/moq/testpackages/imports/two/goimports.golden.go similarity index 78% rename from pkg/moq/testpackages/imports/testdata/goimports.golden.go rename to pkg/moq/testpackages/imports/two/goimports.golden.go index 526ab6b..989e7c7 100644 --- a/pkg/moq/testpackages/imports/testdata/goimports.golden.go +++ b/pkg/moq/testpackages/imports/two/goimports.golden.go @@ -9,16 +9,16 @@ import ( "github.com/matryer/moq/pkg/moq/testpackages/imports/one" ) -// Ensure, that DoSomethingMock does implement DoSomething. +// Ensure, that goimportsMock does implement DoSomething. // If this is not the case, regenerate this file with moq. -var _ DoSomething = &DoSomethingMock{} +var _ DoSomething = &goimportsMock{} -// DoSomethingMock is a mock implementation of DoSomething. +// goimportsMock is a mock implementation of DoSomething. // // func TestSomethingThatUsesDoSomething(t *testing.T) { // // // make and configure a mocked DoSomething -// mockedDoSomething := &DoSomethingMock{ +// mockedDoSomething := &goimportsMock{ // AnotherFunc: func(thing one.Thing) error { // panic("mock out the Another method") // }, @@ -31,7 +31,7 @@ var _ DoSomething = &DoSomethingMock{} // // and then make assertions. // // } -type DoSomethingMock struct { +type goimportsMock struct { // AnotherFunc mocks the Another method. AnotherFunc func(thing one.Thing) error @@ -56,9 +56,9 @@ type DoSomethingMock struct { } // Another calls AnotherFunc. -func (mock *DoSomethingMock) Another(thing one.Thing) error { +func (mock *goimportsMock) Another(thing one.Thing) error { if mock.AnotherFunc == nil { - panic("DoSomethingMock.AnotherFunc: method is nil but DoSomething.Another was just called") + panic("goimportsMock.AnotherFunc: method is nil but DoSomething.Another was just called") } callInfo := struct { Thing one.Thing @@ -74,7 +74,7 @@ func (mock *DoSomethingMock) Another(thing one.Thing) error { // AnotherCalls gets all the calls that were made to Another. // Check the length with: // len(mockedDoSomething.AnotherCalls()) -func (mock *DoSomethingMock) AnotherCalls() []struct { +func (mock *goimportsMock) AnotherCalls() []struct { Thing one.Thing } { var calls []struct { @@ -87,9 +87,9 @@ func (mock *DoSomethingMock) AnotherCalls() []struct { } // Do calls DoFunc. -func (mock *DoSomethingMock) Do(thing one.Thing) error { +func (mock *goimportsMock) Do(thing one.Thing) error { if mock.DoFunc == nil { - panic("DoSomethingMock.DoFunc: method is nil but DoSomething.Do was just called") + panic("goimportsMock.DoFunc: method is nil but DoSomething.Do was just called") } callInfo := struct { Thing one.Thing @@ -105,7 +105,7 @@ func (mock *DoSomethingMock) Do(thing one.Thing) error { // DoCalls gets all the calls that were made to Do. // Check the length with: // len(mockedDoSomething.DoCalls()) -func (mock *DoSomethingMock) DoCalls() []struct { +func (mock *goimportsMock) DoCalls() []struct { Thing one.Thing } { var calls []struct { diff --git a/pkg/moq/testpackages/imports/two/noop.golden.go b/pkg/moq/testpackages/imports/two/noop.golden.go new file mode 100644 index 0000000..4decf10 --- /dev/null +++ b/pkg/moq/testpackages/imports/two/noop.golden.go @@ -0,0 +1,117 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package two + +import ( + "sync" + "github.com/matryer/moq/pkg/moq/testpackages/imports/one" +) + +// Ensure, that noopMock does implement DoSomething. +// If this is not the case, regenerate this file with moq. +var _ DoSomething = &noopMock{} + +// noopMock is a mock implementation of DoSomething. +// +// func TestSomethingThatUsesDoSomething(t *testing.T) { +// +// // make and configure a mocked DoSomething +// mockedDoSomething := &noopMock{ +// AnotherFunc: func(thing one.Thing) error { +// panic("mock out the Another method") +// }, +// DoFunc: func(thing one.Thing) error { +// panic("mock out the Do method") +// }, +// } +// +// // use mockedDoSomething in code that requires DoSomething +// // and then make assertions. +// +// } +type noopMock struct { + // AnotherFunc mocks the Another method. + AnotherFunc func(thing one.Thing) error + + // DoFunc mocks the Do method. + DoFunc func(thing one.Thing) error + + // calls tracks calls to the methods. + calls struct { + // Another holds details about calls to the Another method. + Another []struct { + // Thing is the thing argument value. + Thing one.Thing + } + // Do holds details about calls to the Do method. + Do []struct { + // Thing is the thing argument value. + Thing one.Thing + } + } + lockAnother sync.RWMutex + lockDo sync.RWMutex +} + +// Another calls AnotherFunc. +func (mock *noopMock) Another(thing one.Thing) error { + if mock.AnotherFunc == nil { + panic("noopMock.AnotherFunc: method is nil but DoSomething.Another was just called") + } + callInfo := struct { + Thing one.Thing + }{ + Thing: thing, + } + mock.lockAnother.Lock() + mock.calls.Another = append(mock.calls.Another, callInfo) + mock.lockAnother.Unlock() + return mock.AnotherFunc(thing) +} + +// AnotherCalls gets all the calls that were made to Another. +// Check the length with: +// len(mockedDoSomething.AnotherCalls()) +func (mock *noopMock) AnotherCalls() []struct { + Thing one.Thing + } { + var calls []struct { + Thing one.Thing + } + mock.lockAnother.RLock() + calls = mock.calls.Another + mock.lockAnother.RUnlock() + return calls +} + +// Do calls DoFunc. +func (mock *noopMock) Do(thing one.Thing) error { + if mock.DoFunc == nil { + panic("noopMock.DoFunc: method is nil but DoSomething.Do was just called") + } + callInfo := struct { + Thing one.Thing + }{ + Thing: thing, + } + mock.lockDo.Lock() + mock.calls.Do = append(mock.calls.Do, callInfo) + mock.lockDo.Unlock() + return mock.DoFunc(thing) +} + +// DoCalls gets all the calls that were made to Do. +// Check the length with: +// len(mockedDoSomething.DoCalls()) +func (mock *noopMock) DoCalls() []struct { + Thing one.Thing + } { + var calls []struct { + Thing one.Thing + } + mock.lockDo.RLock() + calls = mock.calls.Do + mock.lockDo.RUnlock() + return calls +}