From 5074513c7d5158ebb40ff07822ba22995bd4f12e Mon Sep 17 00:00:00 2001 From: Reiji Tokuda Date: Sun, 20 Nov 2022 22:50:01 +0800 Subject: [PATCH 1/4] Modify mockgen for embed option --- mockgen/mockgen.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/mockgen/mockgen.go b/mockgen/mockgen.go index 79cb921c..9c55f1ca 100644 --- a/mockgen/mockgen.go +++ b/mockgen/mockgen.go @@ -61,6 +61,7 @@ var ( 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.") copyrightFile = flag.String("copyright_file", "", "Copyright file used to add copyright header") + embed = flag.Bool("embed", false, "Embed source interface into generated mock structure") debugParser = flag.Bool("debug_parser", false, "Print out parser results only.") showVersion = flag.Bool("version", false, "Print version.") @@ -341,6 +342,9 @@ func (g *generator) Generate(pkg *model.Package, outputPkgName string, outputPac g.packageMap[pth] = pkgName localNames[pkgName] = true } + if *embed { + g.packageMap[g.srcPackage] = pkg.Name + } if *writePkgComment { g.p("// Package %v is a generated GoMock package.", outputPkgName) @@ -362,7 +366,7 @@ func (g *generator) Generate(pkg *model.Package, outputPkgName string, outputPac g.p(")") for _, intf := range pkg.Interfaces { - if err := g.GenerateMockInterface(intf, outputPackagePath); err != nil { + if err := g.GenerateMockInterface(pkg.Name, intf, outputPackagePath); err != nil { return err } } @@ -404,7 +408,7 @@ func (g *generator) formattedTypeParams(it *model.Interface, pkgOverride string) return long.String(), short.String() } -func (g *generator) GenerateMockInterface(intf *model.Interface, outputPackagePath string) error { +func (g *generator) GenerateMockInterface(pkgName string, intf *model.Interface, outputPackagePath string) error { mockType := g.mockName(intf.Name) longTp, shortTp := g.formattedTypeParams(intf, outputPackagePath) @@ -412,6 +416,9 @@ func (g *generator) GenerateMockInterface(intf *model.Interface, outputPackagePa g.p("// %v is a mock of %v interface.", mockType, intf.Name) g.p("type %v%v struct {", mockType, longTp) g.in() + if *embed { + g.p("%v.%v", pkgName, intf.Name) + } g.p("ctrl *gomock.Controller") g.p("recorder *%vMockRecorder%v", mockType, shortTp) g.out() From f11c7db42d889cd29eba927abcf0fd209371ce1e Mon Sep 17 00:00:00 2001 From: Reiji Tokuda Date: Mon, 21 Nov 2022 00:36:37 +0800 Subject: [PATCH 2/4] Modify mockgen for embed option when output package is same package --- mockgen/mockgen.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mockgen/mockgen.go b/mockgen/mockgen.go index 9c55f1ca..b47d9e2e 100644 --- a/mockgen/mockgen.go +++ b/mockgen/mockgen.go @@ -342,7 +342,7 @@ func (g *generator) Generate(pkg *model.Package, outputPkgName string, outputPac g.packageMap[pth] = pkgName localNames[pkgName] = true } - if *embed { + if *embed && pkg.Name != *packageOut { g.packageMap[g.srcPackage] = pkg.Name } @@ -417,7 +417,11 @@ func (g *generator) GenerateMockInterface(pkgName string, intf *model.Interface, g.p("type %v%v struct {", mockType, longTp) g.in() if *embed { - g.p("%v.%v", pkgName, intf.Name) + if pkgName != *packageOut { + g.p("%v.%v", pkgName, intf.Name) + } else { + g.p("%v", intf.Name) + } } g.p("ctrl *gomock.Controller") g.p("recorder *%vMockRecorder%v", mockType, shortTp) From bb827da69db084bacb53f358a64e21e5cc773792 Mon Sep 17 00:00:00 2001 From: Reiji Tokuda Date: Mon, 21 Nov 2022 00:42:21 +0800 Subject: [PATCH 3/4] Add test of mockgen for embed option --- mockgen/internal/tests/embed/input.go | 17 +++++ mockgen/internal/tests/embed/mock.go | 61 ++++++++++++++++++ mockgen/internal/tests/embed/mock/mock.go | 62 +++++++++++++++++++ .../internal/tests/embed/mock/mock_test.go | 19 ++++++ mockgen/internal/tests/embed/mock_test.go | 18 ++++++ 5 files changed, 177 insertions(+) create mode 100644 mockgen/internal/tests/embed/input.go create mode 100644 mockgen/internal/tests/embed/mock.go create mode 100644 mockgen/internal/tests/embed/mock/mock.go create mode 100644 mockgen/internal/tests/embed/mock/mock_test.go create mode 100644 mockgen/internal/tests/embed/mock_test.go diff --git a/mockgen/internal/tests/embed/input.go b/mockgen/internal/tests/embed/input.go new file mode 100644 index 00000000..616bf916 --- /dev/null +++ b/mockgen/internal/tests/embed/input.go @@ -0,0 +1,17 @@ +package embed + +//go:generate mockgen -embed -package embed -destination mock.go . Hoge +//go:generate mockgen -embed -destination mock/mock.go . Hoge + +type Hoge interface { + Fuga() error + mustImplementedFunction() +} + +type HogeImpl struct { + s string +} + +func (h *HogeImpl) Fuga() error { + return nil +} diff --git a/mockgen/internal/tests/embed/mock.go b/mockgen/internal/tests/embed/mock.go new file mode 100644 index 00000000..59e28a7a --- /dev/null +++ b/mockgen/internal/tests/embed/mock.go @@ -0,0 +1,61 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/golang/mock/mockgen/internal/tests/embed (interfaces: Hoge) + +// Package embed is a generated GoMock package. +package embed + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" +) + +// MockHoge is a mock of Hoge interface. +type MockHoge struct { + Hoge + ctrl *gomock.Controller + recorder *MockHogeMockRecorder +} + +// MockHogeMockRecorder is the mock recorder for MockHoge. +type MockHogeMockRecorder struct { + mock *MockHoge +} + +// NewMockHoge creates a new mock instance. +func NewMockHoge(ctrl *gomock.Controller) *MockHoge { + mock := &MockHoge{ctrl: ctrl} + mock.recorder = &MockHogeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHoge) EXPECT() *MockHogeMockRecorder { + return m.recorder +} + +// Fuga mocks base method. +func (m *MockHoge) Fuga() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Fuga") + ret0, _ := ret[0].(error) + return ret0 +} + +// Fuga indicates an expected call of Fuga. +func (mr *MockHogeMockRecorder) Fuga() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Fuga", reflect.TypeOf((*MockHoge)(nil).Fuga)) +} + +// mustImplementedFunction mocks base method. +func (m *MockHoge) mustImplementedFunction() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "mustImplementedFunction") +} + +// mustImplementedFunction indicates an expected call of mustImplementedFunction. +func (mr *MockHogeMockRecorder) mustImplementedFunction() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "mustImplementedFunction", reflect.TypeOf((*MockHoge)(nil).mustImplementedFunction)) +} diff --git a/mockgen/internal/tests/embed/mock/mock.go b/mockgen/internal/tests/embed/mock/mock.go new file mode 100644 index 00000000..c4163de5 --- /dev/null +++ b/mockgen/internal/tests/embed/mock/mock.go @@ -0,0 +1,62 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/golang/mock/mockgen/internal/tests/embed (interfaces: Hoge) + +// Package mock_embed is a generated GoMock package. +package mock_embed + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + embed "github.com/golang/mock/mockgen/internal/tests/embed" +) + +// MockHoge is a mock of Hoge interface. +type MockHoge struct { + embed.Hoge + ctrl *gomock.Controller + recorder *MockHogeMockRecorder +} + +// MockHogeMockRecorder is the mock recorder for MockHoge. +type MockHogeMockRecorder struct { + mock *MockHoge +} + +// NewMockHoge creates a new mock instance. +func NewMockHoge(ctrl *gomock.Controller) *MockHoge { + mock := &MockHoge{ctrl: ctrl} + mock.recorder = &MockHogeMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHoge) EXPECT() *MockHogeMockRecorder { + return m.recorder +} + +// Fuga mocks base method. +func (m *MockHoge) Fuga() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Fuga") + ret0, _ := ret[0].(error) + return ret0 +} + +// Fuga indicates an expected call of Fuga. +func (mr *MockHogeMockRecorder) Fuga() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Fuga", reflect.TypeOf((*MockHoge)(nil).Fuga)) +} + +// mustImplementedFunction mocks base method. +func (m *MockHoge) mustImplementedFunction() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "mustImplementedFunction") +} + +// mustImplementedFunction indicates an expected call of mustImplementedFunction. +func (mr *MockHogeMockRecorder) mustImplementedFunction() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "mustImplementedFunction", reflect.TypeOf((*MockHoge)(nil).mustImplementedFunction)) +} diff --git a/mockgen/internal/tests/embed/mock/mock_test.go b/mockgen/internal/tests/embed/mock/mock_test.go new file mode 100644 index 00000000..26743068 --- /dev/null +++ b/mockgen/internal/tests/embed/mock/mock_test.go @@ -0,0 +1,19 @@ +package mock_embed_test + +import ( + reflect "reflect" + "testing" + + "github.com/golang/mock/gomock" + "github.com/golang/mock/mockgen/internal/tests/embed" + mock_embed "github.com/golang/mock/mockgen/internal/tests/embed/mock" +) + +func TestEmbed(t *testing.T) { + hoge := mock_embed.NewMockHoge(gomock.NewController(t)) + et := reflect.TypeOf((*embed.Hoge)(nil)).Elem() + ht := reflect.TypeOf(hoge) + if !ht.Implements(et) { + t.Errorf("source interface has been not implemented") + } +} diff --git a/mockgen/internal/tests/embed/mock_test.go b/mockgen/internal/tests/embed/mock_test.go new file mode 100644 index 00000000..1622fd32 --- /dev/null +++ b/mockgen/internal/tests/embed/mock_test.go @@ -0,0 +1,18 @@ +package embed_test + +import ( + reflect "reflect" + "testing" + + "github.com/golang/mock/gomock" + "github.com/golang/mock/mockgen/internal/tests/embed" +) + +func TestEmbed(t *testing.T) { + hoge := embed.NewMockHoge(gomock.NewController(t)) + et := reflect.TypeOf((*embed.Hoge)(nil)).Elem() + ht := reflect.TypeOf(hoge) + if !ht.Implements(et) { + t.Errorf("source interface has been not implemented") + } +} From 3430e03621202fc5962dcd65b009d141ac511b06 Mon Sep 17 00:00:00 2001 From: Reiji Tokuda Date: Mon, 21 Nov 2022 02:50:26 +0800 Subject: [PATCH 4/4] Add comment for test of mockgen --- mockgen/internal/tests/embed/mock_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/mockgen/internal/tests/embed/mock_test.go b/mockgen/internal/tests/embed/mock_test.go index 1622fd32..b744a442 100644 --- a/mockgen/internal/tests/embed/mock_test.go +++ b/mockgen/internal/tests/embed/mock_test.go @@ -1,3 +1,4 @@ +// This test is for when mock is same package as the source. package embed_test import (