diff --git a/go.mod b/go.mod index de854205..3950b834 100644 --- a/go.mod +++ b/go.mod @@ -1,19 +1,38 @@ module github.com/vektra/mockery/v2 -go 1.16 +go 1.18 require ( github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.26.1 - github.com/spf13/afero v1.8.0 // indirect github.com/spf13/cobra v1.3.0 github.com/spf13/viper v1.10.1 github.com/stretchr/testify v1.7.0 golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce + golang.org/x/tools v0.1.11-0.20220502222022-556c550a3816 + gopkg.in/yaml.v2 v2.4.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/magiconair/properties v1.8.5 // indirect + github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/pelletier/go-toml v1.9.4 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/afero v1.8.0 // indirect + github.com/spf13/cast v1.4.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.1.1 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect - golang.org/x/tools v0.1.10 + golang.org/x/text v0.3.7 // indirect gopkg.in/ini.v1 v1.66.3 // indirect - gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index a57eaac4..7a184db4 100644 --- a/go.sum +++ b/go.sum @@ -197,7 +197,6 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0 github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -317,7 +316,6 @@ github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= -github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -356,7 +354,6 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= @@ -382,7 +379,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI= @@ -423,8 +419,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -468,8 +464,6 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -564,10 +558,8 @@ golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -642,12 +634,11 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.11-0.20220502222022-556c550a3816 h1:KDN1gdvkjXcpAMWJCUAIM1WiDgcWqr91B58SpqEAG4E= +golang.org/x/tools v0.1.11-0.20220502222022-556c550a3816/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -681,7 +672,6 @@ google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdr google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -781,7 +771,6 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/mocks/pkg/fixtures/EmbeddedGet.go b/mocks/pkg/fixtures/EmbeddedGet.go new file mode 100644 index 00000000..c91df07e --- /dev/null +++ b/mocks/pkg/fixtures/EmbeddedGet.go @@ -0,0 +1,42 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + mock "github.com/stretchr/testify/mock" + constraints "github.com/vektra/mockery/v2/pkg/fixtures/constraints" +) + +// EmbeddedGet is an autogenerated mock type for the EmbeddedGet type +type EmbeddedGet[T constraints.Signed] struct { + mock.Mock +} + +// Get provides a mock function with given fields: +func (_m *EmbeddedGet[T]) Get() T { + ret := _m.Called() + + var r0 T + if rf, ok := ret.Get(0).(func() T); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(T) + } + + return r0 +} + +type NewEmbeddedGetT interface { + mock.TestingT + Cleanup(func()) +} + +// NewEmbeddedGet creates a new instance of EmbeddedGet. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewEmbeddedGet[T constraints.Signed](t NewEmbeddedGetT) *EmbeddedGet[T] { + mock := &EmbeddedGet[T]{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/pkg/fixtures/GetGeneric.go b/mocks/pkg/fixtures/GetGeneric.go new file mode 100644 index 00000000..67d1f578 --- /dev/null +++ b/mocks/pkg/fixtures/GetGeneric.go @@ -0,0 +1,42 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + mock "github.com/stretchr/testify/mock" + constraints "github.com/vektra/mockery/v2/pkg/fixtures/constraints" +) + +// GetGeneric is an autogenerated mock type for the GetGeneric type +type GetGeneric[T constraints.Integer] struct { + mock.Mock +} + +// Get provides a mock function with given fields: +func (_m *GetGeneric[T]) Get() T { + ret := _m.Called() + + var r0 T + if rf, ok := ret.Get(0).(func() T); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(T) + } + + return r0 +} + +type NewGetGenericT interface { + mock.TestingT + Cleanup(func()) +} + +// NewGetGeneric creates a new instance of GetGeneric. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewGetGeneric[T constraints.Integer](t NewGetGenericT) *GetGeneric[T] { + mock := &GetGeneric[T]{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/pkg/fixtures/GetInt.go b/mocks/pkg/fixtures/GetInt.go new file mode 100644 index 00000000..8dfe94b5 --- /dev/null +++ b/mocks/pkg/fixtures/GetInt.go @@ -0,0 +1,39 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// GetInt is an autogenerated mock type for the GetInt type +type GetInt struct { + mock.Mock +} + +// Get provides a mock function with given fields: +func (_m *GetInt) Get() int { + ret := _m.Called() + + var r0 int + if rf, ok := ret.Get(0).(func() int); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int) + } + + return r0 +} + +type NewGetIntT interface { + mock.TestingT + Cleanup(func()) +} + +// NewGetInt creates a new instance of GetInt. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewGetInt(t NewGetIntT) *GetInt { + mock := &GetInt{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/pkg/fixtures/RequesterGenerics.go b/mocks/pkg/fixtures/RequesterGenerics.go new file mode 100644 index 00000000..433e1b63 --- /dev/null +++ b/mocks/pkg/fixtures/RequesterGenerics.go @@ -0,0 +1,96 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import ( + io "io" + + constraints "github.com/vektra/mockery/v2/pkg/fixtures/constraints" + + mock "github.com/stretchr/testify/mock" + + test "github.com/vektra/mockery/v2/pkg/fixtures" +) + +// RequesterGenerics is an autogenerated mock type for the RequesterGenerics type +type RequesterGenerics[TAny interface{}, TComparable comparable, TSigned constraints.Signed, TIntf test.GetInt, TExternalIntf io.Writer, TGenIntf test.GetGeneric[TSigned], TInlineType interface{ ~int | ~uint }, TInlineTypeGeneric interface { + ~int | test.GenericType[int, test.GetInt] + comparable +}] struct { + mock.Mock +} + +// GenericAnonymousStructs provides a mock function with given fields: _a0 +func (_m *RequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]) GenericAnonymousStructs(_a0 struct{ Type1 TExternalIntf }) struct { + Type2 test.GenericType[string, test.EmbeddedGet[int]] +} { + ret := _m.Called(_a0) + + var r0 struct { + Type2 test.GenericType[string, test.EmbeddedGet[int]] + } + if rf, ok := ret.Get(0).(func(struct{ Type1 TExternalIntf }) struct { + Type2 test.GenericType[string, test.EmbeddedGet[int]] + }); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(struct { + Type2 test.GenericType[string, test.EmbeddedGet[int]] + }) + } + + return r0 +} + +// GenericArguments provides a mock function with given fields: _a0, _a1 +func (_m *RequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]) GenericArguments(_a0 TAny, _a1 TComparable) (TSigned, TIntf) { + ret := _m.Called(_a0, _a1) + + var r0 TSigned + if rf, ok := ret.Get(0).(func(TAny, TComparable) TSigned); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Get(0).(TSigned) + } + + var r1 TIntf + if rf, ok := ret.Get(1).(func(TAny, TComparable) TIntf); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Get(1).(TIntf) + } + + return r0, r1 +} + +// GenericStructs provides a mock function with given fields: _a0 +func (_m *RequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]) GenericStructs(_a0 test.GenericType[TAny, TIntf]) test.GenericType[TSigned, TIntf] { + ret := _m.Called(_a0) + + var r0 test.GenericType[TSigned, TIntf] + if rf, ok := ret.Get(0).(func(test.GenericType[TAny, TIntf]) test.GenericType[TSigned, TIntf]); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(test.GenericType[TSigned, TIntf]) + } + + return r0 +} + +type NewRequesterGenericsT interface { + mock.TestingT + Cleanup(func()) +} + +// NewRequesterGenerics creates a new instance of RequesterGenerics. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewRequesterGenerics[TAny interface{}, TComparable comparable, TSigned constraints.Signed, TIntf test.GetInt, TExternalIntf io.Writer, TGenIntf test.GetGeneric[TSigned], TInlineType interface{ ~int | ~uint }, TInlineTypeGeneric interface { + ~int | test.GenericType[int, test.GetInt] + comparable +}](t NewRequesterGenericsT) *RequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric] { + mock := &RequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/pkg/fixtures/constraints/Integer.go b/mocks/pkg/fixtures/constraints/Integer.go new file mode 100644 index 00000000..61b21e81 --- /dev/null +++ b/mocks/pkg/fixtures/constraints/Integer.go @@ -0,0 +1,25 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// Integer is an autogenerated mock type for the Integer type +type Integer struct { + mock.Mock +} + +type NewIntegerT interface { + mock.TestingT + Cleanup(func()) +} + +// NewInteger creates a new instance of Integer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewInteger(t NewIntegerT) *Integer { + mock := &Integer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/mocks/pkg/fixtures/constraints/Signed.go b/mocks/pkg/fixtures/constraints/Signed.go new file mode 100644 index 00000000..30b94696 --- /dev/null +++ b/mocks/pkg/fixtures/constraints/Signed.go @@ -0,0 +1,25 @@ +// Code generated by mockery. DO NOT EDIT. + +package mocks + +import mock "github.com/stretchr/testify/mock" + +// Signed is an autogenerated mock type for the Signed type +type Signed struct { + mock.Mock +} + +type NewSignedT interface { + mock.TestingT + Cleanup(func()) +} + +// NewSigned creates a new instance of Signed. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewSigned(t NewSignedT) *Signed { + mock := &Signed{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/fixtures/constraints/constraints.go b/pkg/fixtures/constraints/constraints.go new file mode 100644 index 00000000..a17dc2e0 --- /dev/null +++ b/pkg/fixtures/constraints/constraints.go @@ -0,0 +1,9 @@ +package constraints + +type Signed interface { + ~int +} + +type Integer interface { + ~int +} diff --git a/pkg/fixtures/generic.go b/pkg/fixtures/generic.go new file mode 100644 index 00000000..802becb5 --- /dev/null +++ b/pkg/fixtures/generic.go @@ -0,0 +1,38 @@ +package test + +import ( + "io" + + "github.com/vektra/mockery/v2/pkg/fixtures/constraints" +) + +type RequesterGenerics[ + TAny any, + TComparable comparable, + TSigned constraints.Signed, // external constraint + TIntf GetInt, // internal interface + TExternalIntf io.Writer, // external interface + TGenIntf GetGeneric[TSigned], // generic interface + TInlineType interface{ ~int | ~uint }, // inlined interface constraints + TInlineTypeGeneric interface { + ~int | GenericType[int, GetInt] + comparable + }, // inlined type constraints +] interface { + GenericArguments(TAny, TComparable) (TSigned, TIntf) + GenericStructs(GenericType[TAny, TIntf]) GenericType[TSigned, TIntf] + GenericAnonymousStructs(struct{ Type1 TExternalIntf }) struct { + Type2 GenericType[string, EmbeddedGet[int]] + } +} + +type GenericType[T any, S GetInt] struct { + Any T + Some []S +} + +type GetInt interface{ Get() int } + +type GetGeneric[T constraints.Integer] interface{ Get() T } + +type EmbeddedGet[T constraints.Signed] interface{ GetGeneric[T] } diff --git a/pkg/generator.go b/pkg/generator.go index a681e7df..539dc17f 100644 --- a/pkg/generator.go +++ b/pkg/generator.go @@ -71,6 +71,20 @@ func (g *Generator) populateImports(ctx context.Context) { log.Debug().Msgf("populating imports") + // imports from generic type constraints + if tParams := g.iface.NamedType.TypeParams(); tParams != nil && tParams.Len() > 0 { + for i := 0; i < tParams.Len(); i++ { + g.renderType(ctx, tParams.At(i).Constraint()) + } + } + + // imports from type arguments + if tArgs := g.iface.NamedType.TypeArgs(); tArgs != nil && tArgs.Len() > 0 { + for i := 0; i < tArgs.Len(); i++ { + g.renderType(ctx, tArgs.At(i)) + } + } + for _, method := range g.iface.Methods() { ftype := method.Signature g.addImportsFromTuple(ctx, ftype.Params()) @@ -88,6 +102,18 @@ func (g *Generator) addImportsFromTuple(ctx context.Context, list *types.Tuple) } } +// getPackageScopedType returns the appropriate string representation for the +// object TypeName. The string may either be the unqualified name (in the case +// the mock will live in the same package as the interface being mocked, e.g. +// `Foo`) or the package pathname (in the case the type lives in a package +// external to the mock, e.g. `packagename.Foo`). +func (g *Generator) getPackageScopedType(ctx context.Context, o *types.TypeName) string { + if o.Pkg() == nil || o.Pkg().Name() == "main" || (!g.KeepTree && g.InPackage && o.Pkg() == g.iface.Pkg) { + return o.Name() + } + return g.addPackageImport(ctx, o.Pkg()) + "." + o.Name() +} + func (g *Generator) addPackageImport(ctx context.Context, pkg *types.Package) string { return g.addPackageImportWithName(ctx, pkg.Path(), pkg.Name()) } @@ -231,6 +257,44 @@ func (g *Generator) mockName() string { return g.maybeMakeNameExported(g.iface.Name, g.Exported) } +// getTypeConstraintString returns type constraint string for a given interface. +// For instance, a method using this constraint: +// +// func Foo[T Stringer](s []T) (ret []string) { +// +// } +// +// The constraint returned will be "[T Stringer]" +// +// https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#type-parameters +func (g *Generator) getTypeConstraintString(ctx context.Context) string { + tp := g.iface.NamedType.TypeParams() + if tp == nil || tp.Len() == 0 { + return "" + } + qualifiedParams := make([]string, 0, tp.Len()) + for i := 0; i < tp.Len(); i++ { + param := tp.At(i) + qualifiedParams = append(qualifiedParams, fmt.Sprintf("%s %s", param.String(), g.renderType(ctx, param.Constraint()))) + } + return fmt.Sprintf("[%s]", strings.Join(qualifiedParams, ", ")) +} + +// getInstantiatedTypeString returns the "instantiated" type names for a given +// constraint list. For instance, if your interface has the constraints +// `[S Stringer, I int, C Comparable]`, this method would return: `[S, I, C]` +func (g *Generator) getInstantiatedTypeString() string { + tp := g.iface.NamedType.TypeParams() + if tp == nil || tp.Len() == 0 { + return "" + } + params := make([]string, 0, tp.Len()) + for i := 0; i < tp.Len(); i++ { + params = append(params, tp.At(i).String()) + } + return fmt.Sprintf("[%s]", strings.Join(params, ", ")) +} + func (g *Generator) expecterName() string { return g.mockName() + "_Expecter" } @@ -335,11 +399,21 @@ type namer interface { func (g *Generator) renderType(ctx context.Context, typ types.Type) string { switch t := typ.(type) { case *types.Named: - o := t.Obj() - if o.Pkg() == nil || o.Pkg().Name() == "main" || (!g.KeepTree && g.InPackage && o.Pkg() == g.iface.Pkg) { - return o.Name() + name := g.getPackageScopedType(ctx, t.Obj()) + if t.TypeArgs() == nil || t.TypeArgs().Len() == 0 { + return name } - return g.addPackageImport(ctx, o.Pkg()) + "." + o.Name() + args := make([]string, 0, t.TypeArgs().Len()) + for i := 0; i < t.TypeArgs().Len(); i++ { + arg := t.TypeArgs().At(i) + args = append(args, g.renderType(ctx, arg)) + } + return fmt.Sprintf("%s[%s]", name, strings.Join(args, ",")) + case *types.TypeParam: + if t.Constraint() != nil { + return t.Obj().Name() + } + return g.getPackageScopedType(ctx, t.Obj()) case *types.Basic: if t.Kind() == types.UnsafePointer { return "unsafe.Pointer" @@ -404,7 +478,27 @@ func (g *Generator) renderType(ctx context.Context, typ types.Type) string { panic("Unable to mock inline interfaces with methods") } - return "interface{}" + rv := []string{"interface{"} + for i := 0; i < t.NumEmbeddeds(); i++ { + rv = append(rv, g.renderType(ctx, t.EmbeddedType(i))) + } + rv = append(rv, "}") + sep := "" + if t.NumEmbeddeds() > 1 { + sep = "\n" + } + return strings.Join(rv, sep) + case *types.Union: + rv := make([]string, 0, t.Len()) + for i := 0; i < t.Len(); i++ { + term := t.Term(i) + if term.Tilde() { + rv = append(rv, "~"+g.renderType(ctx, term.Type())) + } else { + rv = append(rv, g.renderType(ctx, term.Type())) + } + } + return strings.Join(rv, "|") case namer: return t.Name() default: @@ -512,7 +606,7 @@ func (g *Generator) Generate(ctx context.Context) error { ) g.printf( - "type %s struct {\n\tmock.Mock\n}\n\n", g.mockName(), + "type %s%s struct {\n\tmock.Mock\n}\n\n", g.mockName(), g.getTypeConstraintString(ctx), ) if g.WithExpecter { @@ -541,7 +635,7 @@ func (g *Generator) Generate(ctx context.Context) error { ) } g.printf( - "func (_m *%s) %s(%s) ", g.mockName(), fname, + "func (_m *%s%s) %s(%s) ", g.mockName(), g.getInstantiatedTypeString(), fname, strings.Join(params.Params, ", "), ) @@ -612,7 +706,7 @@ func (g *Generator) Generate(ctx context.Context) error { } } - g.generateConstructor() + g.generateConstructor(ctx) return nil } @@ -712,7 +806,7 @@ func (_c *{{.CallStruct}}) Return({{range .Returns.Params}}{{.}},{{end}}) *{{.Ca `) } -func (g *Generator) generateConstructor() { +func (g *Generator) generateConstructor(ctx context.Context) { const constructorTemplate = ` type {{ .ConstructorTestingInterfaceName }} interface { mock.TestingT @@ -720,8 +814,8 @@ type {{ .ConstructorTestingInterfaceName }} interface { } // {{ .ConstructorName }} creates a new instance of {{ .MockName }}. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func {{ .ConstructorName }}(t {{ .ConstructorTestingInterfaceName }}) *{{ .MockName }} { - mock := &{{ .MockName }}{} +func {{ .ConstructorName }}{{ .TypeConstraint }}(t {{ .ConstructorTestingInterfaceName }}) *{{ .MockName }}{{ .InstantiatedTypeString }} { + mock := &{{ .MockName }}{{ .InstantiatedTypeString }}{} mock.Mock.Test(t) t.Cleanup(func() { mock.AssertExpectations(t) }) @@ -735,11 +829,15 @@ func {{ .ConstructorName }}(t {{ .ConstructorTestingInterfaceName }}) *{{ .MockN data := struct { ConstructorName string ConstructorTestingInterfaceName string + InstantiatedTypeString string MockName string + TypeConstraint string }{ ConstructorName: constructorName, ConstructorTestingInterfaceName: constructorName + "T", + InstantiatedTypeString: g.getInstantiatedTypeString(), MockName: mockName, + TypeConstraint: g.getTypeConstraintString(ctx), } g.printTemplate(data, constructorTemplate) } diff --git a/pkg/generator_test.go b/pkg/generator_test.go index b47addef..2d5190f0 100644 --- a/pkg/generator_test.go +++ b/pkg/generator_test.go @@ -2025,6 +2025,180 @@ import mock "github.com/stretchr/testify/mock" s.checkPrologueGeneration(generator, expected) } +func (s *GeneratorSuite) TestGenericGenerator() { + expected := `// RequesterGenerics is an autogenerated mock type for the RequesterGenerics type +type RequesterGenerics[TAny interface{}, TComparable comparable, TSigned constraints.Signed, TIntf test.GetInt, TExternalIntf io.Writer, TGenIntf test.GetGeneric[TSigned], TInlineType interface{ ~int | ~uint }, TInlineTypeGeneric interface { + ~int | test.GenericType[int, test.GetInt] + comparable +}] struct { + mock.Mock +} + +// GenericAnonymousStructs provides a mock function with given fields: _a0 +func (_m *RequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]) GenericAnonymousStructs(_a0 struct{ Type1 TExternalIntf }) struct { + Type2 test.GenericType[string, test.EmbeddedGet[int]] +} { + ret := _m.Called(_a0) + + var r0 struct { + Type2 test.GenericType[string, test.EmbeddedGet[int]] + } + if rf, ok := ret.Get(0).(func(struct{ Type1 TExternalIntf }) struct { + Type2 test.GenericType[string, test.EmbeddedGet[int]] + }); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(struct { + Type2 test.GenericType[string, test.EmbeddedGet[int]] + }) + } + + return r0 +} + +// GenericArguments provides a mock function with given fields: _a0, _a1 +func (_m *RequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]) GenericArguments(_a0 TAny, _a1 TComparable) (TSigned, TIntf) { + ret := _m.Called(_a0, _a1) + + var r0 TSigned + if rf, ok := ret.Get(0).(func(TAny, TComparable) TSigned); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Get(0).(TSigned) + } + + var r1 TIntf + if rf, ok := ret.Get(1).(func(TAny, TComparable) TIntf); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Get(1).(TIntf) + } + + return r0, r1 +} + +// GenericStructs provides a mock function with given fields: _a0 +func (_m *RequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]) GenericStructs(_a0 test.GenericType[TAny, TIntf]) test.GenericType[TSigned, TIntf] { + ret := _m.Called(_a0) + + var r0 test.GenericType[TSigned, TIntf] + if rf, ok := ret.Get(0).(func(test.GenericType[TAny, TIntf]) test.GenericType[TSigned, TIntf]); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(test.GenericType[TSigned, TIntf]) + } + + return r0 +} + +type NewRequesterGenericsT interface { + mock.TestingT + Cleanup(func()) +} + +// NewRequesterGenerics creates a new instance of RequesterGenerics. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewRequesterGenerics[TAny interface{}, TComparable comparable, TSigned constraints.Signed, TIntf test.GetInt, TExternalIntf io.Writer, TGenIntf test.GetGeneric[TSigned], TInlineType interface{ ~int | ~uint }, TInlineTypeGeneric interface { + ~int | test.GenericType[int, test.GetInt] + comparable +}](t NewRequesterGenericsT) *RequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric] { + mock := &RequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} +` + s.checkGeneration("generic.go", "RequesterGenerics", false, "", expected) +} + +func (s *GeneratorSuite) TestGenericInpkgGenerator() { + expected := `// MockRequesterGenerics is an autogenerated mock type for the RequesterGenerics type +type MockRequesterGenerics[TAny interface{}, TComparable comparable, TSigned constraints.Signed, TIntf GetInt, TExternalIntf io.Writer, TGenIntf GetGeneric[TSigned], TInlineType interface{ ~int | ~uint }, TInlineTypeGeneric interface { + ~int | GenericType[int, GetInt] + comparable +}] struct { + mock.Mock +} + +// GenericAnonymousStructs provides a mock function with given fields: _a0 +func (_m *MockRequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]) GenericAnonymousStructs(_a0 struct{ Type1 TExternalIntf }) struct { + Type2 GenericType[string, EmbeddedGet[int]] +} { + ret := _m.Called(_a0) + + var r0 struct { + Type2 GenericType[string, EmbeddedGet[int]] + } + if rf, ok := ret.Get(0).(func(struct{ Type1 TExternalIntf }) struct { + Type2 GenericType[string, EmbeddedGet[int]] + }); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(struct { + Type2 GenericType[string, EmbeddedGet[int]] + }) + } + + return r0 +} + +// GenericArguments provides a mock function with given fields: _a0, _a1 +func (_m *MockRequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]) GenericArguments(_a0 TAny, _a1 TComparable) (TSigned, TIntf) { + ret := _m.Called(_a0, _a1) + + var r0 TSigned + if rf, ok := ret.Get(0).(func(TAny, TComparable) TSigned); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Get(0).(TSigned) + } + + var r1 TIntf + if rf, ok := ret.Get(1).(func(TAny, TComparable) TIntf); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Get(1).(TIntf) + } + + return r0, r1 +} + +// GenericStructs provides a mock function with given fields: _a0 +func (_m *MockRequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]) GenericStructs(_a0 GenericType[TAny, TIntf]) GenericType[TSigned, TIntf] { + ret := _m.Called(_a0) + + var r0 GenericType[TSigned, TIntf] + if rf, ok := ret.Get(0).(func(GenericType[TAny, TIntf]) GenericType[TSigned, TIntf]); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(GenericType[TSigned, TIntf]) + } + + return r0 +} + +type NewMockRequesterGenericsT interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockRequesterGenerics creates a new instance of MockRequesterGenerics. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockRequesterGenerics[TAny interface{}, TComparable comparable, TSigned constraints.Signed, TIntf GetInt, TExternalIntf io.Writer, TGenIntf GetGeneric[TSigned], TInlineType interface{ ~int | ~uint }, TInlineTypeGeneric interface { + ~int | GenericType[int, GetInt] + comparable +}](t NewMockRequesterGenericsT) *MockRequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric] { + mock := &MockRequesterGenerics[TAny, TComparable, TSigned, TIntf, TExternalIntf, TGenIntf, TInlineType, TInlineTypeGeneric]{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} +` + s.checkGeneration("generic.go", "RequesterGenerics", true, "", expected) +} + func TestGeneratorSuite(t *testing.T) { generatorSuite := new(GeneratorSuite) suite.Run(t, generatorSuite)