diff --git a/internal/registry/registry.go b/internal/registry/registry.go index ca0f1aa..4109c88 100644 --- a/internal/registry/registry.go +++ b/internal/registry/registry.go @@ -96,7 +96,7 @@ func (r *Registry) AddImport(pkg *types.Package) *Package { imprt := Package{pkg: pkg, Alias: r.aliases[path]} if conflict, ok := r.searchImport(imprt.Qualifier()); ok { - resolveImportConflict(&imprt, conflict, 0) + r.resolveImportConflict(&imprt, conflict, 0) } r.imports[path] = &imprt @@ -126,6 +126,30 @@ func (r Registry) searchImport(name string) (*Package, bool) { return nil, false } +// resolveImportConflict generates and assigns a unique alias for +// packages with conflicting qualifiers. +func (r Registry) resolveImportConflict(a, b *Package, lvl int) { + if a.uniqueName(lvl) == b.uniqueName(lvl) { + r.resolveImportConflict(a, b, lvl+1) + return + } + + for _, p := range []*Package{a, b} { + name := p.uniqueName(lvl) + // Even though the name is not conflicting with the other package we + // got, the new name we want to pick might already be taken. So check + // again for conflicts and resolve them as well. Since the name for + // this package would also get set in the recursive function call, skip + // setting the alias after it. + if conflict, ok := r.searchImport(name); ok && conflict != p { + r.resolveImportConflict(p, conflict, lvl+1) + continue + } + + p.Alias = name + } +} + func pkgInfoFromPath(srcDir string, mode packages.LoadMode) (*packages.Package, error) { pkgs, err := packages.Load(&packages.Config{ Mode: mode, @@ -182,15 +206,3 @@ func parseImportsAliases(pkg *packages.Package) map[string]string { } return aliases } - -// resolveImportConflict generates and assigns a unique alias for -// packages with conflicting qualifiers. -func resolveImportConflict(a, b *Package, lvl int) { - u1, u2 := a.uniqueName(lvl), b.uniqueName(lvl) - if u1 != u2 { - a.Alias, b.Alias = u1, u2 - return - } - - resolveImportConflict(a, b, lvl+1) -} diff --git a/pkg/moq/moq_test.go b/pkg/moq/moq_test.go index ccd5006..758e92c 100644 --- a/pkg/moq/moq_test.go +++ b/pkg/moq/moq_test.go @@ -389,6 +389,12 @@ func TestMockGolden(t *testing.T) { interfaces: []string{"GenericStore1", "GenericStore2", "AliasStore"}, goldenFile: filepath.Join("testpackages/generics", "generics_moq.golden.go"), }, + { + name: "TransientImport", + cfg: Config{SrcDir: "testpackages/transientimport"}, + interfaces: []string{"Transient"}, + goldenFile: filepath.Join("testpackages/transientimport", "transient_moq.golden.go"), + }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { diff --git a/pkg/moq/testpackages/transientimport/base/type.go b/pkg/moq/testpackages/transientimport/base/type.go new file mode 100644 index 0000000..f099285 --- /dev/null +++ b/pkg/moq/testpackages/transientimport/base/type.go @@ -0,0 +1,13 @@ +package base + +import ( + four "github.com/matryer/moq/pkg/moq/testpackages/transientimport/four/app/v1" + one "github.com/matryer/moq/pkg/moq/testpackages/transientimport/one/v1" + "github.com/matryer/moq/pkg/moq/testpackages/transientimport/onev1" + three "github.com/matryer/moq/pkg/moq/testpackages/transientimport/three/v1" + two "github.com/matryer/moq/pkg/moq/testpackages/transientimport/two/app/v1" +) + +type Transient interface { + DoSomething(onev1.Zero, one.One, two.Two, three.Three, four.Four) +} diff --git a/pkg/moq/testpackages/transientimport/four/app/v1/four.go b/pkg/moq/testpackages/transientimport/four/app/v1/four.go new file mode 100644 index 0000000..ba02f3a --- /dev/null +++ b/pkg/moq/testpackages/transientimport/four/app/v1/four.go @@ -0,0 +1,3 @@ +package v1 + +type Four string diff --git a/pkg/moq/testpackages/transientimport/one/v1/one.go b/pkg/moq/testpackages/transientimport/one/v1/one.go new file mode 100644 index 0000000..0608265 --- /dev/null +++ b/pkg/moq/testpackages/transientimport/one/v1/one.go @@ -0,0 +1,3 @@ +package v1 + +type One string diff --git a/pkg/moq/testpackages/transientimport/onev1/zero.go b/pkg/moq/testpackages/transientimport/onev1/zero.go new file mode 100644 index 0000000..fd94c32 --- /dev/null +++ b/pkg/moq/testpackages/transientimport/onev1/zero.go @@ -0,0 +1,3 @@ +package onev1 + +type Zero string diff --git a/pkg/moq/testpackages/transientimport/three/v1/three.go b/pkg/moq/testpackages/transientimport/three/v1/three.go new file mode 100644 index 0000000..3287196 --- /dev/null +++ b/pkg/moq/testpackages/transientimport/three/v1/three.go @@ -0,0 +1,3 @@ +package v1 + +type Three string diff --git a/pkg/moq/testpackages/transientimport/transient.go b/pkg/moq/testpackages/transientimport/transient.go new file mode 100644 index 0000000..854d637 --- /dev/null +++ b/pkg/moq/testpackages/transientimport/transient.go @@ -0,0 +1,7 @@ +package transientimport + +import ( + "github.com/matryer/moq/pkg/moq/testpackages/transientimport/base" +) + +type Transient = base.Transient diff --git a/pkg/moq/testpackages/transientimport/transient_moq.golden.go b/pkg/moq/testpackages/transientimport/transient_moq.golden.go new file mode 100644 index 0000000..093351c --- /dev/null +++ b/pkg/moq/testpackages/transientimport/transient_moq.golden.go @@ -0,0 +1,103 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package transientimport + +import ( + fourappv1 "github.com/matryer/moq/pkg/moq/testpackages/transientimport/four/app/v1" + transientimportonev1 "github.com/matryer/moq/pkg/moq/testpackages/transientimport/one/v1" + testpackagestransientimportonev1 "github.com/matryer/moq/pkg/moq/testpackages/transientimport/onev1" + threev1 "github.com/matryer/moq/pkg/moq/testpackages/transientimport/three/v1" + twoappv1 "github.com/matryer/moq/pkg/moq/testpackages/transientimport/two/app/v1" + "sync" +) + +// Ensure, that TransientMock does implement Transient. +// If this is not the case, regenerate this file with moq. +var _ Transient = &TransientMock{} + +// TransientMock is a mock implementation of Transient. +// +// func TestSomethingThatUsesTransient(t *testing.T) { +// +// // make and configure a mocked Transient +// mockedTransient := &TransientMock{ +// DoSomethingFunc: func(zero testpackagestransientimportonev1.Zero, one transientimportonev1.One, two twoappv1.Two, three threev1.Three, four fourappv1.Four) { +// panic("mock out the DoSomething method") +// }, +// } +// +// // use mockedTransient in code that requires Transient +// // and then make assertions. +// +// } +type TransientMock struct { + // DoSomethingFunc mocks the DoSomething method. + DoSomethingFunc func(zero testpackagestransientimportonev1.Zero, one transientimportonev1.One, two twoappv1.Two, three threev1.Three, four fourappv1.Four) + + // calls tracks calls to the methods. + calls struct { + // DoSomething holds details about calls to the DoSomething method. + DoSomething []struct { + // Zero is the zero argument value. + Zero testpackagestransientimportonev1.Zero + // One is the one argument value. + One transientimportonev1.One + // Two is the two argument value. + Two twoappv1.Two + // Three is the three argument value. + Three threev1.Three + // Four is the four argument value. + Four fourappv1.Four + } + } + lockDoSomething sync.RWMutex +} + +// DoSomething calls DoSomethingFunc. +func (mock *TransientMock) DoSomething(zero testpackagestransientimportonev1.Zero, one transientimportonev1.One, two twoappv1.Two, three threev1.Three, four fourappv1.Four) { + if mock.DoSomethingFunc == nil { + panic("TransientMock.DoSomethingFunc: method is nil but Transient.DoSomething was just called") + } + callInfo := struct { + Zero testpackagestransientimportonev1.Zero + One transientimportonev1.One + Two twoappv1.Two + Three threev1.Three + Four fourappv1.Four + }{ + Zero: zero, + One: one, + Two: two, + Three: three, + Four: four, + } + mock.lockDoSomething.Lock() + mock.calls.DoSomething = append(mock.calls.DoSomething, callInfo) + mock.lockDoSomething.Unlock() + mock.DoSomethingFunc(zero, one, two, three, four) +} + +// DoSomethingCalls gets all the calls that were made to DoSomething. +// Check the length with: +// +// len(mockedTransient.DoSomethingCalls()) +func (mock *TransientMock) DoSomethingCalls() []struct { + Zero testpackagestransientimportonev1.Zero + One transientimportonev1.One + Two twoappv1.Two + Three threev1.Three + Four fourappv1.Four +} { + var calls []struct { + Zero testpackagestransientimportonev1.Zero + One transientimportonev1.One + Two twoappv1.Two + Three threev1.Three + Four fourappv1.Four + } + mock.lockDoSomething.RLock() + calls = mock.calls.DoSomething + mock.lockDoSomething.RUnlock() + return calls +} diff --git a/pkg/moq/testpackages/transientimport/two/app/v1/two.go b/pkg/moq/testpackages/transientimport/two/app/v1/two.go new file mode 100644 index 0000000..6e0f040 --- /dev/null +++ b/pkg/moq/testpackages/transientimport/two/app/v1/two.go @@ -0,0 +1,3 @@ +package v1 + +type Two string