From 9a80e3fa7d2469b9e8fac5502de2ef1dac2c0fe4 Mon Sep 17 00:00:00 2001 From: Jared Ticotin Date: Fri, 13 Dec 2024 14:05:59 -0500 Subject: [PATCH 1/6] handle interfaces with generics --- arguments/parser.go | 7 +- fixtures/genericinterface/genericinterface.go | 21 ++ .../fake_generic_interface.go | 245 ++++++++++++++++++ .../fake_generic_interface2.go | 245 ++++++++++++++++++ generator/fake.go | 29 ++- generator/interface_template.go | 20 +- generator/loader.go | 39 ++- 7 files changed, 580 insertions(+), 26 deletions(-) create mode 100644 fixtures/genericinterface/genericinterface.go create mode 100644 fixtures/genericinterface/genericinterfacefakes/fake_generic_interface.go create mode 100644 fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go diff --git a/arguments/parser.go b/arguments/parser.go index 557d495..edc32b4 100644 --- a/arguments/parser.go +++ b/arguments/parser.go @@ -91,7 +91,7 @@ func New(args []string, workingDir string, evaler Evaler, stater Stater) (*Parse } func (a *ParsedArguments) PrettyPrint() { - b, _ := json.Marshal(a) + b, _ := json.MarshalIndent(a, "", " ") fmt.Println(string(b)) } @@ -105,6 +105,7 @@ func (a *ParsedArguments) parseInterfaceName(packageMode bool, args []string) { a.InterfaceName = fullyQualifiedInterface[len(fullyQualifiedInterface)-1] } else { a.InterfaceName = args[1] + a.InterfaceName = strings.Split(a.InterfaceName, "[")[0] } } @@ -141,7 +142,8 @@ func (a *ParsedArguments) parseOutputPath(packageMode bool, workingDir string, o if strings.HasSuffix(outputPath, ".go") { outputPathIsFilename = true } - snakeCaseName := strings.ToLower(camelRegexp.ReplaceAllString(a.FakeImplName, "${1}_${2}")) + fakeImplName := strings.Split(a.FakeImplName, "[")[0] + snakeCaseName := strings.ToLower(camelRegexp.ReplaceAllString(fakeImplName, "${1}_${2}")) if outputPath != "" { if !filepath.IsAbs(outputPath) { @@ -187,6 +189,7 @@ func (a *ParsedArguments) parsePackagePath(packageMode bool, args []string) { a.PackagePath = strings.Join(fullyQualifiedInterface[:len(fullyQualifiedInterface)-1], ".") } else { a.InterfaceName = args[1] + a.InterfaceName = strings.Split(a.InterfaceName, "[")[0] } if a.PackagePath == "" { diff --git a/fixtures/genericinterface/genericinterface.go b/fixtures/genericinterface/genericinterface.go new file mode 100644 index 0000000..8addfc6 --- /dev/null +++ b/fixtures/genericinterface/genericinterface.go @@ -0,0 +1,21 @@ +package genericinterface + +//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate + +type CustomType any + +//counterfeiter:generate . GenericInterface[T CustomType] +type GenericInterface[T CustomType] interface { + ReturnT() T + TakeT(T) + TakeAndReturnT(T) T + DoSomething() +} + +//counterfeiter:generate . GenericInterface2 +type GenericInterface2[T CustomType] interface { + ReturnT() T + TakeT(T) + TakeAndReturnT(T) T + DoSomething() +} diff --git a/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface.go b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface.go new file mode 100644 index 0000000..16e9476 --- /dev/null +++ b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface.go @@ -0,0 +1,245 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package genericinterfacefakes + +import ( + "sync" + + "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericinterface" +) + +type FakeGenericInterface[T genericinterface.CustomType] struct { + DoSomethingStub func() + doSomethingMutex sync.RWMutex + doSomethingArgsForCall []struct { + } + ReturnTStub func() T + returnTMutex sync.RWMutex + returnTArgsForCall []struct { + } + returnTReturns struct { + result1 T + } + returnTReturnsOnCall map[int]struct { + result1 T + } + TakeAndReturnTStub func(T) T + takeAndReturnTMutex sync.RWMutex + takeAndReturnTArgsForCall []struct { + arg1 T + } + takeAndReturnTReturns struct { + result1 T + } + takeAndReturnTReturnsOnCall map[int]struct { + result1 T + } + TakeTStub func(T) + takeTMutex sync.RWMutex + takeTArgsForCall []struct { + arg1 T + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeGenericInterface[T]) DoSomething() { + fake.doSomethingMutex.Lock() + fake.doSomethingArgsForCall = append(fake.doSomethingArgsForCall, struct { + }{}) + stub := fake.DoSomethingStub + fake.recordInvocation("DoSomething", []interface{}{}) + fake.doSomethingMutex.Unlock() + if stub != nil { + fake.DoSomethingStub() + } +} + +func (fake *FakeGenericInterface[T]) DoSomethingCallCount() int { + fake.doSomethingMutex.RLock() + defer fake.doSomethingMutex.RUnlock() + return len(fake.doSomethingArgsForCall) +} + +func (fake *FakeGenericInterface[T]) DoSomethingCalls(stub func()) { + fake.doSomethingMutex.Lock() + defer fake.doSomethingMutex.Unlock() + fake.DoSomethingStub = stub +} + +func (fake *FakeGenericInterface[T]) ReturnT() T { + fake.returnTMutex.Lock() + ret, specificReturn := fake.returnTReturnsOnCall[len(fake.returnTArgsForCall)] + fake.returnTArgsForCall = append(fake.returnTArgsForCall, struct { + }{}) + stub := fake.ReturnTStub + fakeReturns := fake.returnTReturns + fake.recordInvocation("ReturnT", []interface{}{}) + fake.returnTMutex.Unlock() + if stub != nil { + return stub() + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterface[T]) ReturnTCallCount() int { + fake.returnTMutex.RLock() + defer fake.returnTMutex.RUnlock() + return len(fake.returnTArgsForCall) +} + +func (fake *FakeGenericInterface[T]) ReturnTCalls(stub func() T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = stub +} + +func (fake *FakeGenericInterface[T]) ReturnTReturns(result1 T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = nil + fake.returnTReturns = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterface[T]) ReturnTReturnsOnCall(i int, result1 T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = nil + if fake.returnTReturnsOnCall == nil { + fake.returnTReturnsOnCall = make(map[int]struct { + result1 T + }) + } + fake.returnTReturnsOnCall[i] = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterface[T]) TakeAndReturnT(arg1 T) T { + fake.takeAndReturnTMutex.Lock() + ret, specificReturn := fake.takeAndReturnTReturnsOnCall[len(fake.takeAndReturnTArgsForCall)] + fake.takeAndReturnTArgsForCall = append(fake.takeAndReturnTArgsForCall, struct { + arg1 T + }{arg1}) + stub := fake.TakeAndReturnTStub + fakeReturns := fake.takeAndReturnTReturns + fake.recordInvocation("TakeAndReturnT", []interface{}{arg1}) + fake.takeAndReturnTMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterface[T]) TakeAndReturnTCallCount() int { + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + return len(fake.takeAndReturnTArgsForCall) +} + +func (fake *FakeGenericInterface[T]) TakeAndReturnTCalls(stub func(T) T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = stub +} + +func (fake *FakeGenericInterface[T]) TakeAndReturnTArgsForCall(i int) T { + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + argsForCall := fake.takeAndReturnTArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterface[T]) TakeAndReturnTReturns(result1 T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = nil + fake.takeAndReturnTReturns = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterface[T]) TakeAndReturnTReturnsOnCall(i int, result1 T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = nil + if fake.takeAndReturnTReturnsOnCall == nil { + fake.takeAndReturnTReturnsOnCall = make(map[int]struct { + result1 T + }) + } + fake.takeAndReturnTReturnsOnCall[i] = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterface[T]) TakeT(arg1 T) { + fake.takeTMutex.Lock() + fake.takeTArgsForCall = append(fake.takeTArgsForCall, struct { + arg1 T + }{arg1}) + stub := fake.TakeTStub + fake.recordInvocation("TakeT", []interface{}{arg1}) + fake.takeTMutex.Unlock() + if stub != nil { + fake.TakeTStub(arg1) + } +} + +func (fake *FakeGenericInterface[T]) TakeTCallCount() int { + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + return len(fake.takeTArgsForCall) +} + +func (fake *FakeGenericInterface[T]) TakeTCalls(stub func(T)) { + fake.takeTMutex.Lock() + defer fake.takeTMutex.Unlock() + fake.TakeTStub = stub +} + +func (fake *FakeGenericInterface[T]) TakeTArgsForCall(i int) T { + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + argsForCall := fake.takeTArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterface[T]) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.doSomethingMutex.RLock() + defer fake.doSomethingMutex.RUnlock() + fake.returnTMutex.RLock() + defer fake.returnTMutex.RUnlock() + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeGenericInterface[T]) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ genericinterface.GenericInterface[genericinterface.CustomType] = new(FakeGenericInterface[genericinterface.CustomType]) diff --git a/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go new file mode 100644 index 0000000..082e7a6 --- /dev/null +++ b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go @@ -0,0 +1,245 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package genericinterfacefakes + +import ( + "sync" + + "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericinterface" +) + +type FakeGenericInterface2[T genericinterface.CustomType] struct { + DoSomethingStub func() + doSomethingMutex sync.RWMutex + doSomethingArgsForCall []struct { + } + ReturnTStub func() T + returnTMutex sync.RWMutex + returnTArgsForCall []struct { + } + returnTReturns struct { + result1 T + } + returnTReturnsOnCall map[int]struct { + result1 T + } + TakeAndReturnTStub func(T) T + takeAndReturnTMutex sync.RWMutex + takeAndReturnTArgsForCall []struct { + arg1 T + } + takeAndReturnTReturns struct { + result1 T + } + takeAndReturnTReturnsOnCall map[int]struct { + result1 T + } + TakeTStub func(T) + takeTMutex sync.RWMutex + takeTArgsForCall []struct { + arg1 T + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeGenericInterface2[T]) DoSomething() { + fake.doSomethingMutex.Lock() + fake.doSomethingArgsForCall = append(fake.doSomethingArgsForCall, struct { + }{}) + stub := fake.DoSomethingStub + fake.recordInvocation("DoSomething", []interface{}{}) + fake.doSomethingMutex.Unlock() + if stub != nil { + fake.DoSomethingStub() + } +} + +func (fake *FakeGenericInterface2[T]) DoSomethingCallCount() int { + fake.doSomethingMutex.RLock() + defer fake.doSomethingMutex.RUnlock() + return len(fake.doSomethingArgsForCall) +} + +func (fake *FakeGenericInterface2[T]) DoSomethingCalls(stub func()) { + fake.doSomethingMutex.Lock() + defer fake.doSomethingMutex.Unlock() + fake.DoSomethingStub = stub +} + +func (fake *FakeGenericInterface2[T]) ReturnT() T { + fake.returnTMutex.Lock() + ret, specificReturn := fake.returnTReturnsOnCall[len(fake.returnTArgsForCall)] + fake.returnTArgsForCall = append(fake.returnTArgsForCall, struct { + }{}) + stub := fake.ReturnTStub + fakeReturns := fake.returnTReturns + fake.recordInvocation("ReturnT", []interface{}{}) + fake.returnTMutex.Unlock() + if stub != nil { + return stub() + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterface2[T]) ReturnTCallCount() int { + fake.returnTMutex.RLock() + defer fake.returnTMutex.RUnlock() + return len(fake.returnTArgsForCall) +} + +func (fake *FakeGenericInterface2[T]) ReturnTCalls(stub func() T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = stub +} + +func (fake *FakeGenericInterface2[T]) ReturnTReturns(result1 T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = nil + fake.returnTReturns = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterface2[T]) ReturnTReturnsOnCall(i int, result1 T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = nil + if fake.returnTReturnsOnCall == nil { + fake.returnTReturnsOnCall = make(map[int]struct { + result1 T + }) + } + fake.returnTReturnsOnCall[i] = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterface2[T]) TakeAndReturnT(arg1 T) T { + fake.takeAndReturnTMutex.Lock() + ret, specificReturn := fake.takeAndReturnTReturnsOnCall[len(fake.takeAndReturnTArgsForCall)] + fake.takeAndReturnTArgsForCall = append(fake.takeAndReturnTArgsForCall, struct { + arg1 T + }{arg1}) + stub := fake.TakeAndReturnTStub + fakeReturns := fake.takeAndReturnTReturns + fake.recordInvocation("TakeAndReturnT", []interface{}{arg1}) + fake.takeAndReturnTMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterface2[T]) TakeAndReturnTCallCount() int { + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + return len(fake.takeAndReturnTArgsForCall) +} + +func (fake *FakeGenericInterface2[T]) TakeAndReturnTCalls(stub func(T) T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = stub +} + +func (fake *FakeGenericInterface2[T]) TakeAndReturnTArgsForCall(i int) T { + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + argsForCall := fake.takeAndReturnTArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterface2[T]) TakeAndReturnTReturns(result1 T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = nil + fake.takeAndReturnTReturns = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterface2[T]) TakeAndReturnTReturnsOnCall(i int, result1 T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = nil + if fake.takeAndReturnTReturnsOnCall == nil { + fake.takeAndReturnTReturnsOnCall = make(map[int]struct { + result1 T + }) + } + fake.takeAndReturnTReturnsOnCall[i] = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterface2[T]) TakeT(arg1 T) { + fake.takeTMutex.Lock() + fake.takeTArgsForCall = append(fake.takeTArgsForCall, struct { + arg1 T + }{arg1}) + stub := fake.TakeTStub + fake.recordInvocation("TakeT", []interface{}{arg1}) + fake.takeTMutex.Unlock() + if stub != nil { + fake.TakeTStub(arg1) + } +} + +func (fake *FakeGenericInterface2[T]) TakeTCallCount() int { + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + return len(fake.takeTArgsForCall) +} + +func (fake *FakeGenericInterface2[T]) TakeTCalls(stub func(T)) { + fake.takeTMutex.Lock() + defer fake.takeTMutex.Unlock() + fake.TakeTStub = stub +} + +func (fake *FakeGenericInterface2[T]) TakeTArgsForCall(i int) T { + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + argsForCall := fake.takeTArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterface2[T]) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.doSomethingMutex.RLock() + defer fake.doSomethingMutex.RUnlock() + fake.returnTMutex.RLock() + defer fake.returnTMutex.RUnlock() + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeGenericInterface2[T]) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ genericinterface.GenericInterface2[genericinterface.CustomType] = new(FakeGenericInterface2[genericinterface.CustomType]) diff --git a/generator/fake.go b/generator/fake.go index bf88f18..5c2a6fd 100644 --- a/generator/fake.go +++ b/generator/fake.go @@ -25,19 +25,22 @@ const ( // Fake is used to generate a Fake implementation of an interface. type Fake struct { - Packages []*packages.Package - Package *packages.Package - Target *types.TypeName - Mode FakeMode - DestinationPackage string - Name string - TargetAlias string - TargetName string - TargetPackage string - Imports Imports - Methods []Method - Function Method - Header string + Packages []*packages.Package + Package *packages.Package + Target *types.TypeName + Mode FakeMode + DestinationPackage string + Name string + GenericTypeParametersAndConstraints string + GenericTypeParameters string + GenericTypeConstraints string + TargetAlias string + TargetName string + TargetPackage string + Imports Imports + Methods []Method + Function Method + Header string } // Method is a method of the interface. diff --git a/generator/interface_template.go b/generator/interface_template.go index 1a8fde9..3be9c1a 100644 --- a/generator/interface_template.go +++ b/generator/interface_template.go @@ -27,7 +27,7 @@ import ( {{- end}} ) -type {{.Name}} struct { +type {{.Name}}{{.GenericTypeParametersAndConstraints}} struct { {{- range .Methods}} {{.Name}}Stub func({{.Params.AsArgs}}) {{.Returns.AsReturnSignature}} {{UnExport .Name}}Mutex sync.RWMutex @@ -54,7 +54,7 @@ type {{.Name}} struct { } {{range .Methods -}} -func (fake *{{$.Name}}) {{.Name}}({{.Params.AsNamedArgsWithTypes}}) {{.Returns.AsReturnSignature}} { +func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{.Name}}({{.Params.AsNamedArgsWithTypes}}) {{.Returns.AsReturnSignature}} { {{- range .Params.Slices}} var {{UnExport .Name}}Copy {{.Type}} if {{UnExport .Name}} != nil { @@ -90,20 +90,20 @@ func (fake *{{$.Name}}) {{.Name}}({{.Params.AsNamedArgsWithTypes}}) {{.Returns.A {{- end}} } -func (fake *{{$.Name}}) {{Title .Name}}CallCount() int { +func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{Title .Name}}CallCount() int { fake.{{UnExport .Name}}Mutex.RLock() defer fake.{{UnExport .Name}}Mutex.RUnlock() return len(fake.{{UnExport .Name}}ArgsForCall) } -func (fake *{{$.Name}}) {{Title .Name}}Calls(stub func({{.Params.AsArgs}}) {{.Returns.AsReturnSignature}}) { +func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{Title .Name}}Calls(stub func({{.Params.AsArgs}}) {{.Returns.AsReturnSignature}}) { fake.{{UnExport .Name}}Mutex.Lock() defer fake.{{UnExport .Name}}Mutex.Unlock() fake.{{.Name}}Stub = stub } {{if .Params.HasLength -}} -func (fake *{{$.Name}}) {{Title .Name}}ArgsForCall(i int) {{.Params.AsReturnSignature}} { +func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{Title .Name}}ArgsForCall(i int) {{.Params.AsReturnSignature}} { fake.{{UnExport .Name}}Mutex.RLock() defer fake.{{UnExport .Name}}Mutex.RUnlock() argsForCall := fake.{{UnExport .Name}}ArgsForCall[i] @@ -112,7 +112,7 @@ func (fake *{{$.Name}}) {{Title .Name}}ArgsForCall(i int) {{.Params.AsReturnSign {{- end}} {{if .Returns.HasLength -}} -func (fake *{{$.Name}}) {{Title .Name}}Returns({{.Returns.AsNamedArgsWithTypes}}) { +func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{Title .Name}}Returns({{.Returns.AsNamedArgsWithTypes}}) { fake.{{UnExport .Name}}Mutex.Lock() defer fake.{{UnExport .Name}}Mutex.Unlock() fake.{{.Name}}Stub = nil @@ -123,7 +123,7 @@ func (fake *{{$.Name}}) {{Title .Name}}Returns({{.Returns.AsNamedArgsWithTypes}} }{ {{- .Returns.AsNamedArgs -}} } } -func (fake *{{$.Name}}) {{Title .Name}}ReturnsOnCall(i int, {{.Returns.AsNamedArgsWithTypes}}) { +func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{Title .Name}}ReturnsOnCall(i int, {{.Returns.AsNamedArgsWithTypes}}) { fake.{{UnExport .Name}}Mutex.Lock() defer fake.{{UnExport .Name}}Mutex.Unlock() fake.{{.Name}}Stub = nil @@ -144,7 +144,7 @@ func (fake *{{$.Name}}) {{Title .Name}}ReturnsOnCall(i int, {{.Returns.AsNamedAr {{end -}} {{end}} -func (fake *{{.Name}}) Invocations() map[string][][]interface{} { +func (fake *{{.Name}}{{$.GenericTypeParameters}}) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() {{- range .Methods}} @@ -158,7 +158,7 @@ func (fake *{{.Name}}) Invocations() map[string][][]interface{} { return copiedInvocations } -func (fake *{{.Name}}) recordInvocation(key string, args []interface{}) { +func (fake *{{.Name}}{{$.GenericTypeParameters}}) recordInvocation(key string, args []interface{}) { fake.invocationsMutex.Lock() defer fake.invocationsMutex.Unlock() if fake.invocations == nil { @@ -171,6 +171,6 @@ func (fake *{{.Name}}) recordInvocation(key string, args []interface{}) { } {{if IsExported .TargetName -}} -var _ {{.TargetAlias}}.{{.TargetName}} = new({{.Name}}) +var _ {{.TargetAlias}}.{{.TargetName}}{{.GenericTypeConstraints}} = new({{.Name}}{{.GenericTypeConstraints}}) {{- end}} ` diff --git a/generator/loader.go b/generator/loader.go index 4ffb873..648ba49 100644 --- a/generator/loader.go +++ b/generator/loader.go @@ -57,9 +57,32 @@ func (f *Fake) loadPackages(c Cacher, workingDir string) error { return nil } +func (f *Fake) getGenericTypeData(typeName *types.TypeName) (paramName string, constraintName string, found bool) { + if named, ok := typeName.Type().(*types.Named); ok { + if _, ok := named.Underlying().(*types.Interface); ok { + typeParams := named.TypeParams() + if typeParams.Len() > 0 { + for i := 0; i < typeParams.Len(); i++ { + param := typeParams.At(i) + paramName = param.Obj().Name() + constraint := param.Constraint() + constraintSections := strings.Split(constraint.String(), "/") + constraintName = constraintSections[len(constraintSections)-1] + found = true + return + } + } + } + } + return +} + func (f *Fake) findPackage() error { var target *types.TypeName var pkg *packages.Package + genericTypeParametersAndConstraints := []string{} + genericTypeConstraints := []string{} + genericTypeParameters := []string{} for i := range f.Packages { if f.Packages[i].Types == nil || f.Packages[i].Types.Scope() == nil { continue @@ -72,6 +95,15 @@ func (f *Fake) findPackage() error { raw := pkg.Types.Scope().Lookup(f.TargetName) if raw != nil { if typeName, ok := raw.(*types.TypeName); ok { + if paramName, constraintName, found := f.getGenericTypeData(typeName); found { + genericTypeParameters = append(genericTypeParameters, paramName) + genericTypeConstraints = append(genericTypeConstraints, constraintName) + genericTypeParametersAndConstraints = append( + genericTypeParametersAndConstraints, + fmt.Sprintf("%s %s", paramName, constraintName), + ) + } + target = typeName break } @@ -89,6 +121,11 @@ func (f *Fake) findPackage() error { f.Target = target f.Package = pkg f.TargetPackage = imports.VendorlessPath(pkg.PkgPath) + if len(genericTypeParameters) > 0 { + f.GenericTypeParametersAndConstraints = fmt.Sprintf("[%s]", strings.Join(genericTypeParametersAndConstraints, ", ")) + f.GenericTypeParameters = fmt.Sprintf("[%s]", strings.Join(genericTypeParameters, ", ")) + f.GenericTypeConstraints = fmt.Sprintf("[%s]", strings.Join(genericTypeConstraints, ", ")) + } t := f.Imports.Add(pkg.Name, f.TargetPackage) f.TargetAlias = t.Alias if f.Mode != Package { @@ -97,7 +134,7 @@ func (f *Fake) findPackage() error { if f.Mode == InterfaceOrFunction { if !f.IsInterface() && !f.IsFunction() { - return fmt.Errorf("cannot generate an fake for %s because it is not an interface or function", f.TargetName) + return fmt.Errorf("cannot generate a fake for %s because it is not an interface or function", f.TargetName) } } From 204c0672669b2e4c37cab6ece7472d364d6278b5 Mon Sep 17 00:00:00 2001 From: Jared Ticotin Date: Fri, 13 Dec 2024 14:22:49 -0500 Subject: [PATCH 2/6] multiple generic types in one interface --- fixtures/genericinterface/genericinterface.go | 22 +- .../fake_generic_interface.go | 4 +- .../fake_generic_interface2.go | 4 +- .../fake_generic_interface_multiple_types.go | 689 ++++++++++++++++++ generator/loader.go | 20 +- 5 files changed, 724 insertions(+), 15 deletions(-) create mode 100644 fixtures/genericinterface/genericinterfacefakes/fake_generic_interface_multiple_types.go diff --git a/fixtures/genericinterface/genericinterface.go b/fixtures/genericinterface/genericinterface.go index 8addfc6..b286b78 100644 --- a/fixtures/genericinterface/genericinterface.go +++ b/fixtures/genericinterface/genericinterface.go @@ -2,10 +2,11 @@ package genericinterface //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate -type CustomType any +type CustomTypeT any +type CustomTypeU any //counterfeiter:generate . GenericInterface[T CustomType] -type GenericInterface[T CustomType] interface { +type GenericInterface[T CustomTypeT] interface { ReturnT() T TakeT(T) TakeAndReturnT(T) T @@ -13,9 +14,24 @@ type GenericInterface[T CustomType] interface { } //counterfeiter:generate . GenericInterface2 -type GenericInterface2[T CustomType] interface { +type GenericInterface2[T CustomTypeT] interface { ReturnT() T TakeT(T) TakeAndReturnT(T) T DoSomething() } + +//counterfeiter:generate . GenericInterfaceMultipleTypes +type GenericInterfaceMultipleTypes[T CustomTypeT, U CustomTypeU] interface { + ReturnT() T + ReturnU() U + ReturnTAndU() (T, U) + TakeT(T) + TakeU(U) + TakeTAndU(T, U) + TakeAndReturnT(T) T + TakeAndReturnU(U) U + TakeAndReturnTAndU(T, U) (T, U) + TakeTAndReturnU(T) U + DoSomething() +} diff --git a/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface.go b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface.go index 16e9476..2f06411 100644 --- a/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface.go +++ b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface.go @@ -7,7 +7,7 @@ import ( "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericinterface" ) -type FakeGenericInterface[T genericinterface.CustomType] struct { +type FakeGenericInterface[T genericinterface.CustomTypeT] struct { DoSomethingStub func() doSomethingMutex sync.RWMutex doSomethingArgsForCall []struct { @@ -242,4 +242,4 @@ func (fake *FakeGenericInterface[T]) recordInvocation(key string, args []interfa fake.invocations[key] = append(fake.invocations[key], args) } -var _ genericinterface.GenericInterface[genericinterface.CustomType] = new(FakeGenericInterface[genericinterface.CustomType]) +var _ genericinterface.GenericInterface[genericinterface.CustomTypeT] = new(FakeGenericInterface[genericinterface.CustomTypeT]) diff --git a/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go index 082e7a6..a3a15d5 100644 --- a/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go +++ b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go @@ -7,7 +7,7 @@ import ( "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericinterface" ) -type FakeGenericInterface2[T genericinterface.CustomType] struct { +type FakeGenericInterface2[T genericinterface.CustomTypeT] struct { DoSomethingStub func() doSomethingMutex sync.RWMutex doSomethingArgsForCall []struct { @@ -242,4 +242,4 @@ func (fake *FakeGenericInterface2[T]) recordInvocation(key string, args []interf fake.invocations[key] = append(fake.invocations[key], args) } -var _ genericinterface.GenericInterface2[genericinterface.CustomType] = new(FakeGenericInterface2[genericinterface.CustomType]) +var _ genericinterface.GenericInterface2[genericinterface.CustomTypeT] = new(FakeGenericInterface2[genericinterface.CustomTypeT]) diff --git a/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface_multiple_types.go b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface_multiple_types.go new file mode 100644 index 0000000..45679e0 --- /dev/null +++ b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface_multiple_types.go @@ -0,0 +1,689 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package genericinterfacefakes + +import ( + "sync" + + "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericinterface" +) + +type FakeGenericInterfaceMultipleTypes[T genericinterface.CustomTypeT, U genericinterface.CustomTypeU] struct { + DoSomethingStub func() + doSomethingMutex sync.RWMutex + doSomethingArgsForCall []struct { + } + ReturnTStub func() T + returnTMutex sync.RWMutex + returnTArgsForCall []struct { + } + returnTReturns struct { + result1 T + } + returnTReturnsOnCall map[int]struct { + result1 T + } + ReturnTAndUStub func() (T, U) + returnTAndUMutex sync.RWMutex + returnTAndUArgsForCall []struct { + } + returnTAndUReturns struct { + result1 T + result2 U + } + returnTAndUReturnsOnCall map[int]struct { + result1 T + result2 U + } + ReturnUStub func() U + returnUMutex sync.RWMutex + returnUArgsForCall []struct { + } + returnUReturns struct { + result1 U + } + returnUReturnsOnCall map[int]struct { + result1 U + } + TakeAndReturnTStub func(T) T + takeAndReturnTMutex sync.RWMutex + takeAndReturnTArgsForCall []struct { + arg1 T + } + takeAndReturnTReturns struct { + result1 T + } + takeAndReturnTReturnsOnCall map[int]struct { + result1 T + } + TakeAndReturnTAndUStub func(T, U) (T, U) + takeAndReturnTAndUMutex sync.RWMutex + takeAndReturnTAndUArgsForCall []struct { + arg1 T + arg2 U + } + takeAndReturnTAndUReturns struct { + result1 T + result2 U + } + takeAndReturnTAndUReturnsOnCall map[int]struct { + result1 T + result2 U + } + TakeAndReturnUStub func(U) U + takeAndReturnUMutex sync.RWMutex + takeAndReturnUArgsForCall []struct { + arg1 U + } + takeAndReturnUReturns struct { + result1 U + } + takeAndReturnUReturnsOnCall map[int]struct { + result1 U + } + TakeTStub func(T) + takeTMutex sync.RWMutex + takeTArgsForCall []struct { + arg1 T + } + TakeTAndReturnUStub func(T) U + takeTAndReturnUMutex sync.RWMutex + takeTAndReturnUArgsForCall []struct { + arg1 T + } + takeTAndReturnUReturns struct { + result1 U + } + takeTAndReturnUReturnsOnCall map[int]struct { + result1 U + } + TakeTAndUStub func(T, U) + takeTAndUMutex sync.RWMutex + takeTAndUArgsForCall []struct { + arg1 T + arg2 U + } + TakeUStub func(U) + takeUMutex sync.RWMutex + takeUArgsForCall []struct { + arg1 U + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) DoSomething() { + fake.doSomethingMutex.Lock() + fake.doSomethingArgsForCall = append(fake.doSomethingArgsForCall, struct { + }{}) + stub := fake.DoSomethingStub + fake.recordInvocation("DoSomething", []interface{}{}) + fake.doSomethingMutex.Unlock() + if stub != nil { + fake.DoSomethingStub() + } +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) DoSomethingCallCount() int { + fake.doSomethingMutex.RLock() + defer fake.doSomethingMutex.RUnlock() + return len(fake.doSomethingArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) DoSomethingCalls(stub func()) { + fake.doSomethingMutex.Lock() + defer fake.doSomethingMutex.Unlock() + fake.DoSomethingStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnT() T { + fake.returnTMutex.Lock() + ret, specificReturn := fake.returnTReturnsOnCall[len(fake.returnTArgsForCall)] + fake.returnTArgsForCall = append(fake.returnTArgsForCall, struct { + }{}) + stub := fake.ReturnTStub + fakeReturns := fake.returnTReturns + fake.recordInvocation("ReturnT", []interface{}{}) + fake.returnTMutex.Unlock() + if stub != nil { + return stub() + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnTCallCount() int { + fake.returnTMutex.RLock() + defer fake.returnTMutex.RUnlock() + return len(fake.returnTArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnTCalls(stub func() T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnTReturns(result1 T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = nil + fake.returnTReturns = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnTReturnsOnCall(i int, result1 T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = nil + if fake.returnTReturnsOnCall == nil { + fake.returnTReturnsOnCall = make(map[int]struct { + result1 T + }) + } + fake.returnTReturnsOnCall[i] = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnTAndU() (T, U) { + fake.returnTAndUMutex.Lock() + ret, specificReturn := fake.returnTAndUReturnsOnCall[len(fake.returnTAndUArgsForCall)] + fake.returnTAndUArgsForCall = append(fake.returnTAndUArgsForCall, struct { + }{}) + stub := fake.ReturnTAndUStub + fakeReturns := fake.returnTAndUReturns + fake.recordInvocation("ReturnTAndU", []interface{}{}) + fake.returnTAndUMutex.Unlock() + if stub != nil { + return stub() + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnTAndUCallCount() int { + fake.returnTAndUMutex.RLock() + defer fake.returnTAndUMutex.RUnlock() + return len(fake.returnTAndUArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnTAndUCalls(stub func() (T, U)) { + fake.returnTAndUMutex.Lock() + defer fake.returnTAndUMutex.Unlock() + fake.ReturnTAndUStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnTAndUReturns(result1 T, result2 U) { + fake.returnTAndUMutex.Lock() + defer fake.returnTAndUMutex.Unlock() + fake.ReturnTAndUStub = nil + fake.returnTAndUReturns = struct { + result1 T + result2 U + }{result1, result2} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnTAndUReturnsOnCall(i int, result1 T, result2 U) { + fake.returnTAndUMutex.Lock() + defer fake.returnTAndUMutex.Unlock() + fake.ReturnTAndUStub = nil + if fake.returnTAndUReturnsOnCall == nil { + fake.returnTAndUReturnsOnCall = make(map[int]struct { + result1 T + result2 U + }) + } + fake.returnTAndUReturnsOnCall[i] = struct { + result1 T + result2 U + }{result1, result2} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnU() U { + fake.returnUMutex.Lock() + ret, specificReturn := fake.returnUReturnsOnCall[len(fake.returnUArgsForCall)] + fake.returnUArgsForCall = append(fake.returnUArgsForCall, struct { + }{}) + stub := fake.ReturnUStub + fakeReturns := fake.returnUReturns + fake.recordInvocation("ReturnU", []interface{}{}) + fake.returnUMutex.Unlock() + if stub != nil { + return stub() + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnUCallCount() int { + fake.returnUMutex.RLock() + defer fake.returnUMutex.RUnlock() + return len(fake.returnUArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnUCalls(stub func() U) { + fake.returnUMutex.Lock() + defer fake.returnUMutex.Unlock() + fake.ReturnUStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnUReturns(result1 U) { + fake.returnUMutex.Lock() + defer fake.returnUMutex.Unlock() + fake.ReturnUStub = nil + fake.returnUReturns = struct { + result1 U + }{result1} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) ReturnUReturnsOnCall(i int, result1 U) { + fake.returnUMutex.Lock() + defer fake.returnUMutex.Unlock() + fake.ReturnUStub = nil + if fake.returnUReturnsOnCall == nil { + fake.returnUReturnsOnCall = make(map[int]struct { + result1 U + }) + } + fake.returnUReturnsOnCall[i] = struct { + result1 U + }{result1} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnT(arg1 T) T { + fake.takeAndReturnTMutex.Lock() + ret, specificReturn := fake.takeAndReturnTReturnsOnCall[len(fake.takeAndReturnTArgsForCall)] + fake.takeAndReturnTArgsForCall = append(fake.takeAndReturnTArgsForCall, struct { + arg1 T + }{arg1}) + stub := fake.TakeAndReturnTStub + fakeReturns := fake.takeAndReturnTReturns + fake.recordInvocation("TakeAndReturnT", []interface{}{arg1}) + fake.takeAndReturnTMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTCallCount() int { + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + return len(fake.takeAndReturnTArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTCalls(stub func(T) T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTArgsForCall(i int) T { + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + argsForCall := fake.takeAndReturnTArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTReturns(result1 T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = nil + fake.takeAndReturnTReturns = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTReturnsOnCall(i int, result1 T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = nil + if fake.takeAndReturnTReturnsOnCall == nil { + fake.takeAndReturnTReturnsOnCall = make(map[int]struct { + result1 T + }) + } + fake.takeAndReturnTReturnsOnCall[i] = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTAndU(arg1 T, arg2 U) (T, U) { + fake.takeAndReturnTAndUMutex.Lock() + ret, specificReturn := fake.takeAndReturnTAndUReturnsOnCall[len(fake.takeAndReturnTAndUArgsForCall)] + fake.takeAndReturnTAndUArgsForCall = append(fake.takeAndReturnTAndUArgsForCall, struct { + arg1 T + arg2 U + }{arg1, arg2}) + stub := fake.TakeAndReturnTAndUStub + fakeReturns := fake.takeAndReturnTAndUReturns + fake.recordInvocation("TakeAndReturnTAndU", []interface{}{arg1, arg2}) + fake.takeAndReturnTAndUMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTAndUCallCount() int { + fake.takeAndReturnTAndUMutex.RLock() + defer fake.takeAndReturnTAndUMutex.RUnlock() + return len(fake.takeAndReturnTAndUArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTAndUCalls(stub func(T, U) (T, U)) { + fake.takeAndReturnTAndUMutex.Lock() + defer fake.takeAndReturnTAndUMutex.Unlock() + fake.TakeAndReturnTAndUStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTAndUArgsForCall(i int) (T, U) { + fake.takeAndReturnTAndUMutex.RLock() + defer fake.takeAndReturnTAndUMutex.RUnlock() + argsForCall := fake.takeAndReturnTAndUArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTAndUReturns(result1 T, result2 U) { + fake.takeAndReturnTAndUMutex.Lock() + defer fake.takeAndReturnTAndUMutex.Unlock() + fake.TakeAndReturnTAndUStub = nil + fake.takeAndReturnTAndUReturns = struct { + result1 T + result2 U + }{result1, result2} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnTAndUReturnsOnCall(i int, result1 T, result2 U) { + fake.takeAndReturnTAndUMutex.Lock() + defer fake.takeAndReturnTAndUMutex.Unlock() + fake.TakeAndReturnTAndUStub = nil + if fake.takeAndReturnTAndUReturnsOnCall == nil { + fake.takeAndReturnTAndUReturnsOnCall = make(map[int]struct { + result1 T + result2 U + }) + } + fake.takeAndReturnTAndUReturnsOnCall[i] = struct { + result1 T + result2 U + }{result1, result2} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnU(arg1 U) U { + fake.takeAndReturnUMutex.Lock() + ret, specificReturn := fake.takeAndReturnUReturnsOnCall[len(fake.takeAndReturnUArgsForCall)] + fake.takeAndReturnUArgsForCall = append(fake.takeAndReturnUArgsForCall, struct { + arg1 U + }{arg1}) + stub := fake.TakeAndReturnUStub + fakeReturns := fake.takeAndReturnUReturns + fake.recordInvocation("TakeAndReturnU", []interface{}{arg1}) + fake.takeAndReturnUMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnUCallCount() int { + fake.takeAndReturnUMutex.RLock() + defer fake.takeAndReturnUMutex.RUnlock() + return len(fake.takeAndReturnUArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnUCalls(stub func(U) U) { + fake.takeAndReturnUMutex.Lock() + defer fake.takeAndReturnUMutex.Unlock() + fake.TakeAndReturnUStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnUArgsForCall(i int) U { + fake.takeAndReturnUMutex.RLock() + defer fake.takeAndReturnUMutex.RUnlock() + argsForCall := fake.takeAndReturnUArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnUReturns(result1 U) { + fake.takeAndReturnUMutex.Lock() + defer fake.takeAndReturnUMutex.Unlock() + fake.TakeAndReturnUStub = nil + fake.takeAndReturnUReturns = struct { + result1 U + }{result1} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeAndReturnUReturnsOnCall(i int, result1 U) { + fake.takeAndReturnUMutex.Lock() + defer fake.takeAndReturnUMutex.Unlock() + fake.TakeAndReturnUStub = nil + if fake.takeAndReturnUReturnsOnCall == nil { + fake.takeAndReturnUReturnsOnCall = make(map[int]struct { + result1 U + }) + } + fake.takeAndReturnUReturnsOnCall[i] = struct { + result1 U + }{result1} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeT(arg1 T) { + fake.takeTMutex.Lock() + fake.takeTArgsForCall = append(fake.takeTArgsForCall, struct { + arg1 T + }{arg1}) + stub := fake.TakeTStub + fake.recordInvocation("TakeT", []interface{}{arg1}) + fake.takeTMutex.Unlock() + if stub != nil { + fake.TakeTStub(arg1) + } +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTCallCount() int { + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + return len(fake.takeTArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTCalls(stub func(T)) { + fake.takeTMutex.Lock() + defer fake.takeTMutex.Unlock() + fake.TakeTStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTArgsForCall(i int) T { + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + argsForCall := fake.takeTArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTAndReturnU(arg1 T) U { + fake.takeTAndReturnUMutex.Lock() + ret, specificReturn := fake.takeTAndReturnUReturnsOnCall[len(fake.takeTAndReturnUArgsForCall)] + fake.takeTAndReturnUArgsForCall = append(fake.takeTAndReturnUArgsForCall, struct { + arg1 T + }{arg1}) + stub := fake.TakeTAndReturnUStub + fakeReturns := fake.takeTAndReturnUReturns + fake.recordInvocation("TakeTAndReturnU", []interface{}{arg1}) + fake.takeTAndReturnUMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTAndReturnUCallCount() int { + fake.takeTAndReturnUMutex.RLock() + defer fake.takeTAndReturnUMutex.RUnlock() + return len(fake.takeTAndReturnUArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTAndReturnUCalls(stub func(T) U) { + fake.takeTAndReturnUMutex.Lock() + defer fake.takeTAndReturnUMutex.Unlock() + fake.TakeTAndReturnUStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTAndReturnUArgsForCall(i int) T { + fake.takeTAndReturnUMutex.RLock() + defer fake.takeTAndReturnUMutex.RUnlock() + argsForCall := fake.takeTAndReturnUArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTAndReturnUReturns(result1 U) { + fake.takeTAndReturnUMutex.Lock() + defer fake.takeTAndReturnUMutex.Unlock() + fake.TakeTAndReturnUStub = nil + fake.takeTAndReturnUReturns = struct { + result1 U + }{result1} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTAndReturnUReturnsOnCall(i int, result1 U) { + fake.takeTAndReturnUMutex.Lock() + defer fake.takeTAndReturnUMutex.Unlock() + fake.TakeTAndReturnUStub = nil + if fake.takeTAndReturnUReturnsOnCall == nil { + fake.takeTAndReturnUReturnsOnCall = make(map[int]struct { + result1 U + }) + } + fake.takeTAndReturnUReturnsOnCall[i] = struct { + result1 U + }{result1} +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTAndU(arg1 T, arg2 U) { + fake.takeTAndUMutex.Lock() + fake.takeTAndUArgsForCall = append(fake.takeTAndUArgsForCall, struct { + arg1 T + arg2 U + }{arg1, arg2}) + stub := fake.TakeTAndUStub + fake.recordInvocation("TakeTAndU", []interface{}{arg1, arg2}) + fake.takeTAndUMutex.Unlock() + if stub != nil { + fake.TakeTAndUStub(arg1, arg2) + } +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTAndUCallCount() int { + fake.takeTAndUMutex.RLock() + defer fake.takeTAndUMutex.RUnlock() + return len(fake.takeTAndUArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTAndUCalls(stub func(T, U)) { + fake.takeTAndUMutex.Lock() + defer fake.takeTAndUMutex.Unlock() + fake.TakeTAndUStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeTAndUArgsForCall(i int) (T, U) { + fake.takeTAndUMutex.RLock() + defer fake.takeTAndUMutex.RUnlock() + argsForCall := fake.takeTAndUArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeU(arg1 U) { + fake.takeUMutex.Lock() + fake.takeUArgsForCall = append(fake.takeUArgsForCall, struct { + arg1 U + }{arg1}) + stub := fake.TakeUStub + fake.recordInvocation("TakeU", []interface{}{arg1}) + fake.takeUMutex.Unlock() + if stub != nil { + fake.TakeUStub(arg1) + } +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeUCallCount() int { + fake.takeUMutex.RLock() + defer fake.takeUMutex.RUnlock() + return len(fake.takeUArgsForCall) +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeUCalls(stub func(U)) { + fake.takeUMutex.Lock() + defer fake.takeUMutex.Unlock() + fake.TakeUStub = stub +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) TakeUArgsForCall(i int) U { + fake.takeUMutex.RLock() + defer fake.takeUMutex.RUnlock() + argsForCall := fake.takeUArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.doSomethingMutex.RLock() + defer fake.doSomethingMutex.RUnlock() + fake.returnTMutex.RLock() + defer fake.returnTMutex.RUnlock() + fake.returnTAndUMutex.RLock() + defer fake.returnTAndUMutex.RUnlock() + fake.returnUMutex.RLock() + defer fake.returnUMutex.RUnlock() + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + fake.takeAndReturnTAndUMutex.RLock() + defer fake.takeAndReturnTAndUMutex.RUnlock() + fake.takeAndReturnUMutex.RLock() + defer fake.takeAndReturnUMutex.RUnlock() + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + fake.takeTAndReturnUMutex.RLock() + defer fake.takeTAndReturnUMutex.RUnlock() + fake.takeTAndUMutex.RLock() + defer fake.takeTAndUMutex.RUnlock() + fake.takeUMutex.RLock() + defer fake.takeUMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeGenericInterfaceMultipleTypes[T, U]) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ genericinterface.GenericInterfaceMultipleTypes[genericinterface.CustomTypeT, genericinterface.CustomTypeU] = new(FakeGenericInterfaceMultipleTypes[genericinterface.CustomTypeT, genericinterface.CustomTypeU]) diff --git a/generator/loader.go b/generator/loader.go index 648ba49..7c190a0 100644 --- a/generator/loader.go +++ b/generator/loader.go @@ -57,19 +57,22 @@ func (f *Fake) loadPackages(c Cacher, workingDir string) error { return nil } -func (f *Fake) getGenericTypeData(typeName *types.TypeName) (paramName string, constraintName string, found bool) { +func (f *Fake) getGenericTypeData(typeName *types.TypeName) (paramNames []string, constraintNames []string, paramAndConstraintNames []string, found bool) { if named, ok := typeName.Type().(*types.Named); ok { if _, ok := named.Underlying().(*types.Interface); ok { typeParams := named.TypeParams() + fmt.Printf("len: %d\n", typeParams.Len()) if typeParams.Len() > 0 { for i := 0; i < typeParams.Len(); i++ { param := typeParams.At(i) - paramName = param.Obj().Name() + paramName := param.Obj().Name() constraint := param.Constraint() constraintSections := strings.Split(constraint.String(), "/") - constraintName = constraintSections[len(constraintSections)-1] + constraintName := constraintSections[len(constraintSections)-1] + paramNames = append(paramNames, paramName) + constraintNames = append(constraintNames, constraintName) + paramAndConstraintNames = append(paramAndConstraintNames, fmt.Sprintf("%s %s", paramName, constraintName)) found = true - return } } } @@ -95,12 +98,12 @@ func (f *Fake) findPackage() error { raw := pkg.Types.Scope().Lookup(f.TargetName) if raw != nil { if typeName, ok := raw.(*types.TypeName); ok { - if paramName, constraintName, found := f.getGenericTypeData(typeName); found { - genericTypeParameters = append(genericTypeParameters, paramName) - genericTypeConstraints = append(genericTypeConstraints, constraintName) + if paramNames, constraintNames, paramAndConstraintNames, found := f.getGenericTypeData(typeName); found { + genericTypeParameters = append(genericTypeParameters, paramNames...) + genericTypeConstraints = append(genericTypeConstraints, constraintNames...) genericTypeParametersAndConstraints = append( genericTypeParametersAndConstraints, - fmt.Sprintf("%s %s", paramName, constraintName), + paramAndConstraintNames..., ) } @@ -121,6 +124,7 @@ func (f *Fake) findPackage() error { f.Target = target f.Package = pkg f.TargetPackage = imports.VendorlessPath(pkg.PkgPath) + fmt.Printf("genericTypeParameters: %v\n", genericTypeParameters) if len(genericTypeParameters) > 0 { f.GenericTypeParametersAndConstraints = fmt.Sprintf("[%s]", strings.Join(genericTypeParametersAndConstraints, ", ")) f.GenericTypeParameters = fmt.Sprintf("[%s]", strings.Join(genericTypeParameters, ", ")) From e7c0976ea7156bc1b3169ee20eaaea9c5464ee80 Mon Sep 17 00:00:00 2001 From: Jared Ticotin Date: Fri, 13 Dec 2024 14:24:10 -0500 Subject: [PATCH 3/6] remove test printing --- generator/loader.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/generator/loader.go b/generator/loader.go index 7c190a0..106ddfb 100644 --- a/generator/loader.go +++ b/generator/loader.go @@ -61,7 +61,6 @@ func (f *Fake) getGenericTypeData(typeName *types.TypeName) (paramNames []string if named, ok := typeName.Type().(*types.Named); ok { if _, ok := named.Underlying().(*types.Interface); ok { typeParams := named.TypeParams() - fmt.Printf("len: %d\n", typeParams.Len()) if typeParams.Len() > 0 { for i := 0; i < typeParams.Len(); i++ { param := typeParams.At(i) @@ -124,7 +123,6 @@ func (f *Fake) findPackage() error { f.Target = target f.Package = pkg f.TargetPackage = imports.VendorlessPath(pkg.PkgPath) - fmt.Printf("genericTypeParameters: %v\n", genericTypeParameters) if len(genericTypeParameters) > 0 { f.GenericTypeParametersAndConstraints = fmt.Sprintf("[%s]", strings.Join(genericTypeParametersAndConstraints, ", ")) f.GenericTypeParameters = fmt.Sprintf("[%s]", strings.Join(genericTypeParameters, ", ")) From ceb8b76b4e4408b147fce6c65ed41d8c7c3fd766 Mon Sep 17 00:00:00 2001 From: Jared Ticotin Date: Fri, 13 Dec 2024 15:14:31 -0500 Subject: [PATCH 4/6] parser changes undone. requiring args to not include type params or constraints --- arguments/parser.go | 5 +---- fixtures/genericinterface/genericinterface.go | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/arguments/parser.go b/arguments/parser.go index edc32b4..7b1ec82 100644 --- a/arguments/parser.go +++ b/arguments/parser.go @@ -105,7 +105,6 @@ func (a *ParsedArguments) parseInterfaceName(packageMode bool, args []string) { a.InterfaceName = fullyQualifiedInterface[len(fullyQualifiedInterface)-1] } else { a.InterfaceName = args[1] - a.InterfaceName = strings.Split(a.InterfaceName, "[")[0] } } @@ -142,8 +141,7 @@ func (a *ParsedArguments) parseOutputPath(packageMode bool, workingDir string, o if strings.HasSuffix(outputPath, ".go") { outputPathIsFilename = true } - fakeImplName := strings.Split(a.FakeImplName, "[")[0] - snakeCaseName := strings.ToLower(camelRegexp.ReplaceAllString(fakeImplName, "${1}_${2}")) + snakeCaseName := strings.ToLower(camelRegexp.ReplaceAllString(a.FakeImplName, "${1}_${2}")) if outputPath != "" { if !filepath.IsAbs(outputPath) { @@ -189,7 +187,6 @@ func (a *ParsedArguments) parsePackagePath(packageMode bool, args []string) { a.PackagePath = strings.Join(fullyQualifiedInterface[:len(fullyQualifiedInterface)-1], ".") } else { a.InterfaceName = args[1] - a.InterfaceName = strings.Split(a.InterfaceName, "[")[0] } if a.PackagePath == "" { diff --git a/fixtures/genericinterface/genericinterface.go b/fixtures/genericinterface/genericinterface.go index b286b78..a92313a 100644 --- a/fixtures/genericinterface/genericinterface.go +++ b/fixtures/genericinterface/genericinterface.go @@ -5,16 +5,17 @@ package genericinterface type CustomTypeT any type CustomTypeU any -//counterfeiter:generate . GenericInterface[T CustomType] -type GenericInterface[T CustomTypeT] interface { - ReturnT() T - TakeT(T) - TakeAndReturnT(T) T - DoSomething() -} +// incorrect setup. this would fail +// //counterfeiter:generate . GenericInterfaceBad[T CustomType] +// type GenericInterfaceBad[T CustomTypeT] interface { +// ReturnT() T +// TakeT(T) +// TakeAndReturnT(T) T +// DoSomething() +// } -//counterfeiter:generate . GenericInterface2 -type GenericInterface2[T CustomTypeT] interface { +//counterfeiter:generate . GenericInterface +type GenericInterface[T CustomTypeT] interface { ReturnT() T TakeT(T) TakeAndReturnT(T) T From 00d12aa1edf2f282af8b989266e4f415d92bfb67 Mon Sep 17 00:00:00 2001 From: Jared Ticotin Date: Fri, 13 Dec 2024 15:15:25 -0500 Subject: [PATCH 5/6] removed unused fake --- .../fake_generic_interface2.go | 245 ------------------ 1 file changed, 245 deletions(-) delete mode 100644 fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go diff --git a/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go deleted file mode 100644 index a3a15d5..0000000 --- a/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface2.go +++ /dev/null @@ -1,245 +0,0 @@ -// Code generated by counterfeiter. DO NOT EDIT. -package genericinterfacefakes - -import ( - "sync" - - "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericinterface" -) - -type FakeGenericInterface2[T genericinterface.CustomTypeT] struct { - DoSomethingStub func() - doSomethingMutex sync.RWMutex - doSomethingArgsForCall []struct { - } - ReturnTStub func() T - returnTMutex sync.RWMutex - returnTArgsForCall []struct { - } - returnTReturns struct { - result1 T - } - returnTReturnsOnCall map[int]struct { - result1 T - } - TakeAndReturnTStub func(T) T - takeAndReturnTMutex sync.RWMutex - takeAndReturnTArgsForCall []struct { - arg1 T - } - takeAndReturnTReturns struct { - result1 T - } - takeAndReturnTReturnsOnCall map[int]struct { - result1 T - } - TakeTStub func(T) - takeTMutex sync.RWMutex - takeTArgsForCall []struct { - arg1 T - } - invocations map[string][][]interface{} - invocationsMutex sync.RWMutex -} - -func (fake *FakeGenericInterface2[T]) DoSomething() { - fake.doSomethingMutex.Lock() - fake.doSomethingArgsForCall = append(fake.doSomethingArgsForCall, struct { - }{}) - stub := fake.DoSomethingStub - fake.recordInvocation("DoSomething", []interface{}{}) - fake.doSomethingMutex.Unlock() - if stub != nil { - fake.DoSomethingStub() - } -} - -func (fake *FakeGenericInterface2[T]) DoSomethingCallCount() int { - fake.doSomethingMutex.RLock() - defer fake.doSomethingMutex.RUnlock() - return len(fake.doSomethingArgsForCall) -} - -func (fake *FakeGenericInterface2[T]) DoSomethingCalls(stub func()) { - fake.doSomethingMutex.Lock() - defer fake.doSomethingMutex.Unlock() - fake.DoSomethingStub = stub -} - -func (fake *FakeGenericInterface2[T]) ReturnT() T { - fake.returnTMutex.Lock() - ret, specificReturn := fake.returnTReturnsOnCall[len(fake.returnTArgsForCall)] - fake.returnTArgsForCall = append(fake.returnTArgsForCall, struct { - }{}) - stub := fake.ReturnTStub - fakeReturns := fake.returnTReturns - fake.recordInvocation("ReturnT", []interface{}{}) - fake.returnTMutex.Unlock() - if stub != nil { - return stub() - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeGenericInterface2[T]) ReturnTCallCount() int { - fake.returnTMutex.RLock() - defer fake.returnTMutex.RUnlock() - return len(fake.returnTArgsForCall) -} - -func (fake *FakeGenericInterface2[T]) ReturnTCalls(stub func() T) { - fake.returnTMutex.Lock() - defer fake.returnTMutex.Unlock() - fake.ReturnTStub = stub -} - -func (fake *FakeGenericInterface2[T]) ReturnTReturns(result1 T) { - fake.returnTMutex.Lock() - defer fake.returnTMutex.Unlock() - fake.ReturnTStub = nil - fake.returnTReturns = struct { - result1 T - }{result1} -} - -func (fake *FakeGenericInterface2[T]) ReturnTReturnsOnCall(i int, result1 T) { - fake.returnTMutex.Lock() - defer fake.returnTMutex.Unlock() - fake.ReturnTStub = nil - if fake.returnTReturnsOnCall == nil { - fake.returnTReturnsOnCall = make(map[int]struct { - result1 T - }) - } - fake.returnTReturnsOnCall[i] = struct { - result1 T - }{result1} -} - -func (fake *FakeGenericInterface2[T]) TakeAndReturnT(arg1 T) T { - fake.takeAndReturnTMutex.Lock() - ret, specificReturn := fake.takeAndReturnTReturnsOnCall[len(fake.takeAndReturnTArgsForCall)] - fake.takeAndReturnTArgsForCall = append(fake.takeAndReturnTArgsForCall, struct { - arg1 T - }{arg1}) - stub := fake.TakeAndReturnTStub - fakeReturns := fake.takeAndReturnTReturns - fake.recordInvocation("TakeAndReturnT", []interface{}{arg1}) - fake.takeAndReturnTMutex.Unlock() - if stub != nil { - return stub(arg1) - } - if specificReturn { - return ret.result1 - } - return fakeReturns.result1 -} - -func (fake *FakeGenericInterface2[T]) TakeAndReturnTCallCount() int { - fake.takeAndReturnTMutex.RLock() - defer fake.takeAndReturnTMutex.RUnlock() - return len(fake.takeAndReturnTArgsForCall) -} - -func (fake *FakeGenericInterface2[T]) TakeAndReturnTCalls(stub func(T) T) { - fake.takeAndReturnTMutex.Lock() - defer fake.takeAndReturnTMutex.Unlock() - fake.TakeAndReturnTStub = stub -} - -func (fake *FakeGenericInterface2[T]) TakeAndReturnTArgsForCall(i int) T { - fake.takeAndReturnTMutex.RLock() - defer fake.takeAndReturnTMutex.RUnlock() - argsForCall := fake.takeAndReturnTArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeGenericInterface2[T]) TakeAndReturnTReturns(result1 T) { - fake.takeAndReturnTMutex.Lock() - defer fake.takeAndReturnTMutex.Unlock() - fake.TakeAndReturnTStub = nil - fake.takeAndReturnTReturns = struct { - result1 T - }{result1} -} - -func (fake *FakeGenericInterface2[T]) TakeAndReturnTReturnsOnCall(i int, result1 T) { - fake.takeAndReturnTMutex.Lock() - defer fake.takeAndReturnTMutex.Unlock() - fake.TakeAndReturnTStub = nil - if fake.takeAndReturnTReturnsOnCall == nil { - fake.takeAndReturnTReturnsOnCall = make(map[int]struct { - result1 T - }) - } - fake.takeAndReturnTReturnsOnCall[i] = struct { - result1 T - }{result1} -} - -func (fake *FakeGenericInterface2[T]) TakeT(arg1 T) { - fake.takeTMutex.Lock() - fake.takeTArgsForCall = append(fake.takeTArgsForCall, struct { - arg1 T - }{arg1}) - stub := fake.TakeTStub - fake.recordInvocation("TakeT", []interface{}{arg1}) - fake.takeTMutex.Unlock() - if stub != nil { - fake.TakeTStub(arg1) - } -} - -func (fake *FakeGenericInterface2[T]) TakeTCallCount() int { - fake.takeTMutex.RLock() - defer fake.takeTMutex.RUnlock() - return len(fake.takeTArgsForCall) -} - -func (fake *FakeGenericInterface2[T]) TakeTCalls(stub func(T)) { - fake.takeTMutex.Lock() - defer fake.takeTMutex.Unlock() - fake.TakeTStub = stub -} - -func (fake *FakeGenericInterface2[T]) TakeTArgsForCall(i int) T { - fake.takeTMutex.RLock() - defer fake.takeTMutex.RUnlock() - argsForCall := fake.takeTArgsForCall[i] - return argsForCall.arg1 -} - -func (fake *FakeGenericInterface2[T]) Invocations() map[string][][]interface{} { - fake.invocationsMutex.RLock() - defer fake.invocationsMutex.RUnlock() - fake.doSomethingMutex.RLock() - defer fake.doSomethingMutex.RUnlock() - fake.returnTMutex.RLock() - defer fake.returnTMutex.RUnlock() - fake.takeAndReturnTMutex.RLock() - defer fake.takeAndReturnTMutex.RUnlock() - fake.takeTMutex.RLock() - defer fake.takeTMutex.RUnlock() - copiedInvocations := map[string][][]interface{}{} - for key, value := range fake.invocations { - copiedInvocations[key] = value - } - return copiedInvocations -} - -func (fake *FakeGenericInterface2[T]) recordInvocation(key string, args []interface{}) { - fake.invocationsMutex.Lock() - defer fake.invocationsMutex.Unlock() - if fake.invocations == nil { - fake.invocations = map[string][][]interface{}{} - } - if fake.invocations[key] == nil { - fake.invocations[key] = [][]interface{}{} - } - fake.invocations[key] = append(fake.invocations[key], args) -} - -var _ genericinterface.GenericInterface2[genericinterface.CustomTypeT] = new(FakeGenericInterface2[genericinterface.CustomTypeT]) From 1db6bf15a574d12550176a7f9861945029be48b5 Mon Sep 17 00:00:00 2001 From: Jared Ticotin Date: Fri, 13 Dec 2024 15:24:35 -0500 Subject: [PATCH 6/6] test with built in constraint --- fixtures/genericinterface/genericinterface.go | 8 + .../fake_generic_interface_any.go | 245 ++++++++++++++++++ 2 files changed, 253 insertions(+) create mode 100644 fixtures/genericinterface/genericinterfacefakes/fake_generic_interface_any.go diff --git a/fixtures/genericinterface/genericinterface.go b/fixtures/genericinterface/genericinterface.go index a92313a..5850b1a 100644 --- a/fixtures/genericinterface/genericinterface.go +++ b/fixtures/genericinterface/genericinterface.go @@ -22,6 +22,14 @@ type GenericInterface[T CustomTypeT] interface { DoSomething() } +//counterfeiter:generate . GenericInterfaceAny +type GenericInterfaceAny[T any] interface { + ReturnT() T + TakeT(T) + TakeAndReturnT(T) T + DoSomething() +} + //counterfeiter:generate . GenericInterfaceMultipleTypes type GenericInterfaceMultipleTypes[T CustomTypeT, U CustomTypeU] interface { ReturnT() T diff --git a/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface_any.go b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface_any.go new file mode 100644 index 0000000..9fad9f3 --- /dev/null +++ b/fixtures/genericinterface/genericinterfacefakes/fake_generic_interface_any.go @@ -0,0 +1,245 @@ +// Code generated by counterfeiter. DO NOT EDIT. +package genericinterfacefakes + +import ( + "sync" + + "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericinterface" +) + +type FakeGenericInterfaceAny[T any] struct { + DoSomethingStub func() + doSomethingMutex sync.RWMutex + doSomethingArgsForCall []struct { + } + ReturnTStub func() T + returnTMutex sync.RWMutex + returnTArgsForCall []struct { + } + returnTReturns struct { + result1 T + } + returnTReturnsOnCall map[int]struct { + result1 T + } + TakeAndReturnTStub func(T) T + takeAndReturnTMutex sync.RWMutex + takeAndReturnTArgsForCall []struct { + arg1 T + } + takeAndReturnTReturns struct { + result1 T + } + takeAndReturnTReturnsOnCall map[int]struct { + result1 T + } + TakeTStub func(T) + takeTMutex sync.RWMutex + takeTArgsForCall []struct { + arg1 T + } + invocations map[string][][]interface{} + invocationsMutex sync.RWMutex +} + +func (fake *FakeGenericInterfaceAny[T]) DoSomething() { + fake.doSomethingMutex.Lock() + fake.doSomethingArgsForCall = append(fake.doSomethingArgsForCall, struct { + }{}) + stub := fake.DoSomethingStub + fake.recordInvocation("DoSomething", []interface{}{}) + fake.doSomethingMutex.Unlock() + if stub != nil { + fake.DoSomethingStub() + } +} + +func (fake *FakeGenericInterfaceAny[T]) DoSomethingCallCount() int { + fake.doSomethingMutex.RLock() + defer fake.doSomethingMutex.RUnlock() + return len(fake.doSomethingArgsForCall) +} + +func (fake *FakeGenericInterfaceAny[T]) DoSomethingCalls(stub func()) { + fake.doSomethingMutex.Lock() + defer fake.doSomethingMutex.Unlock() + fake.DoSomethingStub = stub +} + +func (fake *FakeGenericInterfaceAny[T]) ReturnT() T { + fake.returnTMutex.Lock() + ret, specificReturn := fake.returnTReturnsOnCall[len(fake.returnTArgsForCall)] + fake.returnTArgsForCall = append(fake.returnTArgsForCall, struct { + }{}) + stub := fake.ReturnTStub + fakeReturns := fake.returnTReturns + fake.recordInvocation("ReturnT", []interface{}{}) + fake.returnTMutex.Unlock() + if stub != nil { + return stub() + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterfaceAny[T]) ReturnTCallCount() int { + fake.returnTMutex.RLock() + defer fake.returnTMutex.RUnlock() + return len(fake.returnTArgsForCall) +} + +func (fake *FakeGenericInterfaceAny[T]) ReturnTCalls(stub func() T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = stub +} + +func (fake *FakeGenericInterfaceAny[T]) ReturnTReturns(result1 T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = nil + fake.returnTReturns = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterfaceAny[T]) ReturnTReturnsOnCall(i int, result1 T) { + fake.returnTMutex.Lock() + defer fake.returnTMutex.Unlock() + fake.ReturnTStub = nil + if fake.returnTReturnsOnCall == nil { + fake.returnTReturnsOnCall = make(map[int]struct { + result1 T + }) + } + fake.returnTReturnsOnCall[i] = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterfaceAny[T]) TakeAndReturnT(arg1 T) T { + fake.takeAndReturnTMutex.Lock() + ret, specificReturn := fake.takeAndReturnTReturnsOnCall[len(fake.takeAndReturnTArgsForCall)] + fake.takeAndReturnTArgsForCall = append(fake.takeAndReturnTArgsForCall, struct { + arg1 T + }{arg1}) + stub := fake.TakeAndReturnTStub + fakeReturns := fake.takeAndReturnTReturns + fake.recordInvocation("TakeAndReturnT", []interface{}{arg1}) + fake.takeAndReturnTMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeGenericInterfaceAny[T]) TakeAndReturnTCallCount() int { + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + return len(fake.takeAndReturnTArgsForCall) +} + +func (fake *FakeGenericInterfaceAny[T]) TakeAndReturnTCalls(stub func(T) T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = stub +} + +func (fake *FakeGenericInterfaceAny[T]) TakeAndReturnTArgsForCall(i int) T { + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + argsForCall := fake.takeAndReturnTArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterfaceAny[T]) TakeAndReturnTReturns(result1 T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = nil + fake.takeAndReturnTReturns = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterfaceAny[T]) TakeAndReturnTReturnsOnCall(i int, result1 T) { + fake.takeAndReturnTMutex.Lock() + defer fake.takeAndReturnTMutex.Unlock() + fake.TakeAndReturnTStub = nil + if fake.takeAndReturnTReturnsOnCall == nil { + fake.takeAndReturnTReturnsOnCall = make(map[int]struct { + result1 T + }) + } + fake.takeAndReturnTReturnsOnCall[i] = struct { + result1 T + }{result1} +} + +func (fake *FakeGenericInterfaceAny[T]) TakeT(arg1 T) { + fake.takeTMutex.Lock() + fake.takeTArgsForCall = append(fake.takeTArgsForCall, struct { + arg1 T + }{arg1}) + stub := fake.TakeTStub + fake.recordInvocation("TakeT", []interface{}{arg1}) + fake.takeTMutex.Unlock() + if stub != nil { + fake.TakeTStub(arg1) + } +} + +func (fake *FakeGenericInterfaceAny[T]) TakeTCallCount() int { + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + return len(fake.takeTArgsForCall) +} + +func (fake *FakeGenericInterfaceAny[T]) TakeTCalls(stub func(T)) { + fake.takeTMutex.Lock() + defer fake.takeTMutex.Unlock() + fake.TakeTStub = stub +} + +func (fake *FakeGenericInterfaceAny[T]) TakeTArgsForCall(i int) T { + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + argsForCall := fake.takeTArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeGenericInterfaceAny[T]) Invocations() map[string][][]interface{} { + fake.invocationsMutex.RLock() + defer fake.invocationsMutex.RUnlock() + fake.doSomethingMutex.RLock() + defer fake.doSomethingMutex.RUnlock() + fake.returnTMutex.RLock() + defer fake.returnTMutex.RUnlock() + fake.takeAndReturnTMutex.RLock() + defer fake.takeAndReturnTMutex.RUnlock() + fake.takeTMutex.RLock() + defer fake.takeTMutex.RUnlock() + copiedInvocations := map[string][][]interface{}{} + for key, value := range fake.invocations { + copiedInvocations[key] = value + } + return copiedInvocations +} + +func (fake *FakeGenericInterfaceAny[T]) recordInvocation(key string, args []interface{}) { + fake.invocationsMutex.Lock() + defer fake.invocationsMutex.Unlock() + if fake.invocations == nil { + fake.invocations = map[string][][]interface{}{} + } + if fake.invocations[key] == nil { + fake.invocations[key] = [][]interface{}{} + } + fake.invocations[key] = append(fake.invocations[key], args) +} + +var _ genericinterface.GenericInterfaceAny[any] = new(FakeGenericInterfaceAny[any])