├── .github ├── FUNDING.yml └── workflows │ ├── release.yml │ └── test.yml ├── .gitignore ├── .goreleaser.yml ├── LICENSE ├── README.md ├── example ├── example.go └── mockpersonstore_test.go ├── generate ├── generate.go └── generated.go ├── go.mod ├── go.sum ├── internal ├── registry │ ├── method_scope.go │ ├── package.go │ ├── registry.go │ ├── registry_test.go │ └── var.go └── template │ ├── template.go │ ├── template_data.go │ └── template_test.go ├── main.go ├── moq-logo-small.png ├── moq-logo.png ├── pkg └── moq │ ├── formatter.go │ ├── moq.go │ ├── moq_modules_test.go │ ├── moq_test.go │ └── testpackages │ ├── _parseerror │ └── service │ │ └── service.go │ ├── anonimport │ ├── iface.go │ ├── iface_moq.golden.go │ └── second_file.go │ ├── blankid │ ├── swallower.go │ └── swallower.golden.go │ ├── buildconstraints │ ├── go.mod │ ├── go.sum │ ├── user │ │ └── user.go │ └── vendor │ │ ├── github.com │ │ └── sudo-suhas │ │ │ └── moq-test-pkgs │ │ │ └── buildconstraints │ │ │ ├── go.mod │ │ │ ├── go17.go │ │ │ └── pre_go17.go │ │ └── modules.txt │ ├── channels │ ├── example.go │ └── queuer_moq.golden.go │ ├── dotimport │ ├── service.go │ └── service_moq_test.go │ ├── emptyinterface │ └── empty.go │ ├── example │ └── example.go │ ├── genericreturn │ ├── genericreturn.go │ ├── genericreturn.golden.go │ └── otherpackage │ │ └── otherpackage.go │ ├── generics │ ├── generics.go │ └── generics_moq.golden.go │ ├── genparamname │ ├── iface.go │ └── iface_moq.golden.go │ ├── go.mod │ ├── go.sum │ ├── gogenvendoring │ └── user │ │ ├── user.go │ │ └── user_moq_test.go │ ├── importalias │ ├── middleman.go │ ├── middleman_moq.golden.go │ ├── source │ │ └── client │ │ │ └── src_client.go │ └── target │ │ └── client │ │ └── tgt_client.go │ ├── imports │ ├── one │ │ └── one.go │ └── two │ │ ├── gofmt.golden.go │ │ ├── goimports.golden.go │ │ ├── noop.golden.go │ │ └── two.go │ ├── modules │ ├── go.mod │ └── simple.go │ ├── paramconflict │ ├── iface.go │ └── iface_moq.golden.go │ ├── rangenum │ ├── rangenum.go │ └── rangenum_moq.golden.go │ ├── samenameimport │ ├── samename.go │ └── samenameimport │ │ └── samename.go │ ├── shadow │ ├── http │ │ └── thing.go │ ├── mock │ │ └── thing_moq.golden.go │ ├── shadower.go │ └── shadower_moq.golden.go │ ├── shadowtypes │ ├── shadowtypes.go │ ├── shadowtypes_moq.golden.go │ └── types │ │ └── types.go │ ├── syncimport │ ├── sync │ │ └── thing.go │ ├── syncer.go │ └── syncer_moq.golden.go │ ├── transientimport │ ├── base │ │ └── type.go │ ├── four │ │ └── app │ │ │ └── v1 │ │ │ └── four.go │ ├── one │ │ └── v1 │ │ │ └── one.go │ ├── onev1 │ │ └── zero.go │ ├── three │ │ └── v1 │ │ │ └── three.go │ ├── transient.go │ ├── transient_moq.golden.go │ └── two │ │ └── app │ │ └── v1 │ │ └── two.go │ ├── typealias │ ├── typealias.go │ └── typealias_moq.golden.go │ ├── typealiastwo │ ├── internal │ │ └── typealiasinternal │ │ │ └── typealiasinternal.go │ └── typealiastwo.go │ ├── variadic │ ├── echoer.go │ ├── echoer.golden.go │ └── greeter.go │ ├── vendor │ ├── github.com │ │ └── sudo-suhas │ │ │ └── moq-test-pkgs │ │ │ └── somerepo │ │ │ ├── code.go │ │ │ └── go.mod │ └── modules.txt │ ├── vendoring │ ├── go.mod │ ├── go.sum │ ├── user │ │ └── user.go │ └── vendor │ │ ├── github.com │ │ └── sudo-suhas │ │ │ └── moq-test-pkgs │ │ │ └── somerepo │ │ │ ├── code.go │ │ │ └── go.mod │ │ └── modules.txt │ └── withresets │ ├── withresets.go │ └── withresets_moq.golden.go ├── preview.png └── releasing.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: matryer 2 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: goreleaser 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v[0-9]*' 7 | workflow_dispatch: 8 | 9 | jobs: 10 | goreleaser: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - 14 | name: Checkout 15 | uses: actions/checkout@v3 16 | with: 17 | fetch-depth: 0 18 | 19 | - run: git fetch --force --tags 20 | 21 | - 22 | name: Set up Go 23 | uses: actions/setup-go@v5 24 | with: 25 | go-version: 'stable' 26 | cache: true 27 | check-latest: true 28 | 29 | - 30 | name: Run GoReleaser 31 | uses: goreleaser/goreleaser-action@v2 32 | with: 33 | distribution: goreleaser 34 | version: latest 35 | args: release --clean 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | tags: [v*] 6 | branches: [main] 7 | pull_request: 8 | 9 | jobs: 10 | # See https://github.com/mvdan/github-actions-golang 11 | test: 12 | runs-on: ${{ matrix.os }} 13 | 14 | strategy: 15 | matrix: 16 | os: [ubuntu-latest] 17 | go-version: [oldstable, stable] 18 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-expanding-configurations 19 | include: 20 | - os: windows-latest 21 | go-version: stable 22 | - os: macos-latest 23 | go-version: stable 24 | 25 | steps: 26 | - name: Checkout code 27 | uses: actions/checkout@v3 28 | 29 | - name: Install Go 30 | uses: actions/setup-go@v3 31 | with: 32 | go-version: ${{ matrix.go-version }} 33 | cache: true 34 | 35 | - name: Go install moq 36 | run: go install 37 | 38 | - name: Run vet 39 | if: matrix.os == 'ubuntu-latest' 40 | run: go vet ./... 41 | 42 | - name: Lint 43 | if: matrix.os == 'ubuntu-latest' 44 | run: | 45 | go install golang.org/x/lint/golint@latest 46 | golint ./... 47 | 48 | - name: Test 49 | run: go test ./... 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | .vscode 26 | .idea 27 | .playground 28 | 29 | dist/ 30 | .DS_Store 31 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | # This is an example goreleaser.yaml file with some sane defaults. 2 | # Make sure to check the documentation at http://goreleaser.com 3 | builds: 4 | - env: 5 | - CGO_ENABLED=0 6 | goos: 7 | - darwin 8 | - windows 9 | - linux 10 | goarch: 11 | - amd64 12 | - arm 13 | - arm64 14 | ldflags: 15 | - -X main.Version={{.Version}} 16 | archives: 17 | - name_template: >- 18 | {{- .ProjectName }}_ 19 | {{- if eq .Os "darwin"}}macOS 20 | {{- else if eq .Os "linux"}}Linux 21 | {{- else if eq .Os "windows"}}Windows 22 | {{- else }}{{ .Os }}{{ end }}_ 23 | {{- if eq .Arch "amd64" }}x86_64 24 | {{- else if eq .Arch "386" }}i386 25 | {{- else }}{{ .Arch }}{{ end }} 26 | {{- if .Arm }}v{{ .Arm }}{{ end -}} 27 | universal_binaries: 28 | - replace: false 29 | checksum: 30 | name_template: 'checksums.txt' 31 | snapshot: 32 | name_template: "{{ .Tag }}" 33 | changelog: 34 | sort: asc 35 | filters: 36 | exclude: 37 | - '^docs:' 38 | - '^test:' 39 | release: 40 | github: 41 | owner: matryer 42 | name: moq 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Mat Ryer and David Hernandez 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![moq logo](moq-logo-small.png) [![build](https://github.com/matryer/moq/workflows/build/badge.svg)](https://github.com/matryer/moq/actions?query=branch%3Amaster) [![Go Report Card](https://goreportcard.com/badge/github.com/matryer/moq)](https://goreportcard.com/report/github.com/matryer/moq) 2 | 3 | Interface mocking tool for go generate. 4 | 5 | ### What is Moq? 6 | 7 | Moq is a tool that generates a struct from any interface. The struct can be used in test code as a mock of the interface. 8 | 9 | ![Preview](preview.png) 10 | 11 | above: Moq generates the code on the right. 12 | 13 | You can read more in the [Meet Moq blog post](http://bit.ly/meetmoq). 14 | 15 | ### Installing 16 | 17 | To start using latest released version of Moq, just run: 18 | 19 | ``` 20 | $ go install github.com/matryer/moq@latest 21 | ``` 22 | 23 | Note that Go 1.18+ is needed for installing from source. For using Moq with 24 | older Go versions, use the pre-built binaries published with 25 | [Moq releases](https://github.com/matryer/moq/releases). 26 | 27 | ### Usage 28 | 29 | ``` 30 | moq [flags] source-dir interface [interface2 [interface3 [...]]] 31 | -fmt string 32 | go pretty-printer: gofmt, goimports or noop (default gofmt) 33 | -out string 34 | output file (default stdout) 35 | -pkg string 36 | package name (default will infer) 37 | -rm 38 | first remove output file, if it exists 39 | -skip-ensure 40 | suppress mock implementation check, avoid import cycle if mocks generated outside of the tested package 41 | -stub 42 | return zero values when no mock implementation is provided, do not panic 43 | -version 44 | show the version for moq 45 | -with-resets 46 | generate functions to facilitate resetting calls made to a mock 47 | 48 | Specifying an alias for the mock is also supported with the format 'interface:alias' 49 | 50 | Ex: moq -pkg different . MyInterface:MyMock 51 | ``` 52 | 53 | **NOTE:** `source-dir` is the directory where the source code (definition) of the target interface is located. 54 | It needs to be a path to a directory and not the import statement for a Go package. 55 | 56 | In a command line: 57 | 58 | ``` 59 | $ moq -out mocks_test.go . MyInterface 60 | ``` 61 | 62 | In code (for go generate): 63 | 64 | ```go 65 | package my 66 | 67 | //go:generate moq -out myinterface_moq_test.go . MyInterface 68 | 69 | type MyInterface interface { 70 | Method1() error 71 | Method2(i int) 72 | } 73 | ``` 74 | 75 | Then run `go generate` for your package. 76 | 77 | ### How to use it 78 | 79 | Mocking interfaces is a nice way to write unit tests where you can easily control the behaviour of the mocked object. 80 | 81 | Moq creates a struct that has a function field for each method, which you can declare in your test code. 82 | 83 | In this example, Moq generated the `EmailSenderMock` type: 84 | 85 | ```go 86 | func TestCompleteSignup(t *testing.T) { 87 | 88 | var sentTo string 89 | 90 | mockedEmailSender = &EmailSenderMock{ 91 | SendFunc: func(to, subject, body string) error { 92 | sentTo = to 93 | return nil 94 | }, 95 | } 96 | 97 | CompleteSignUp("me@email.com", mockedEmailSender) 98 | 99 | callsToSend := len(mockedEmailSender.SendCalls()) 100 | if callsToSend != 1 { 101 | t.Errorf("Send was called %d times", callsToSend) 102 | } 103 | if sentTo != "me@email.com" { 104 | t.Errorf("unexpected recipient: %s", sentTo) 105 | } 106 | 107 | } 108 | 109 | func CompleteSignUp(to string, sender EmailSender) { 110 | // TODO: this 111 | } 112 | ``` 113 | 114 | The mocked structure implements the interface, where each method calls the associated function field. 115 | 116 | ## Tips 117 | 118 | * Keep mocked logic inside the test that is using it 119 | * Only mock the fields you need 120 | * It will panic if a nil function gets called 121 | * Name arguments in the interface for a better experience 122 | * Use closured variables inside your test function to capture details about the calls to the methods 123 | * Use `.MethodCalls()` to track the calls 124 | * Use `.ResetCalls()` to reset calls within an individual mock's context 125 | * Use `go:generate` to invoke the `moq` command 126 | * If Moq fails with a `go/format` error, it indicates the generated code was not valid. 127 | You can run the same command with `-fmt noop` to print the generated source code without attempting to format it. 128 | This can aid in debugging the root cause. 129 | 130 | ## License 131 | 132 | The Moq project (and all code) is licensed under the [MIT License](LICENSE). 133 | 134 | Moq was created by [Mat Ryer](https://twitter.com/matryer) and [David Hernandez](https://github.com/dahernan), with ideas lovingly stolen from [Ernesto Jimenez](https://github.com/ernesto-jimenez). Featuring a major refactor by @sudo-suhas, as well as lots of other contributors. 135 | 136 | The Moq logo was created by [Chris Ryer](http://chrisryer.co.uk) and is licensed under the [Creative Commons Attribution 3.0 License](https://creativecommons.org/licenses/by/3.0/). 137 | 138 | -------------------------------------------------------------------------------- /example/example.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import "context" 4 | 5 | //go:generate moq -out mockpersonstore_test.go . PersonStore 6 | 7 | // Person represents a real person. 8 | type Person struct { 9 | ID string 10 | Name string 11 | Company string 12 | Website string 13 | } 14 | 15 | // PersonStore provides access to Person objects. 16 | type PersonStore interface { 17 | Get(ctx context.Context, id string) (*Person, error) 18 | Create(ctx context.Context, person *Person, confirm bool) error 19 | } 20 | -------------------------------------------------------------------------------- /example/mockpersonstore_test.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package example 5 | 6 | import ( 7 | "context" 8 | "sync" 9 | ) 10 | 11 | // Ensure, that PersonStoreMock does implement PersonStore. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ PersonStore = &PersonStoreMock{} 14 | 15 | // PersonStoreMock is a mock implementation of PersonStore. 16 | // 17 | // func TestSomethingThatUsesPersonStore(t *testing.T) { 18 | // 19 | // // make and configure a mocked PersonStore 20 | // mockedPersonStore := &PersonStoreMock{ 21 | // CreateFunc: func(ctx context.Context, person *Person, confirm bool) error { 22 | // panic("mock out the Create method") 23 | // }, 24 | // GetFunc: func(ctx context.Context, id string) (*Person, error) { 25 | // panic("mock out the Get method") 26 | // }, 27 | // } 28 | // 29 | // // use mockedPersonStore in code that requires PersonStore 30 | // // and then make assertions. 31 | // 32 | // } 33 | type PersonStoreMock struct { 34 | // CreateFunc mocks the Create method. 35 | CreateFunc func(ctx context.Context, person *Person, confirm bool) error 36 | 37 | // GetFunc mocks the Get method. 38 | GetFunc func(ctx context.Context, id string) (*Person, error) 39 | 40 | // calls tracks calls to the methods. 41 | calls struct { 42 | // Create holds details about calls to the Create method. 43 | Create []struct { 44 | // Ctx is the ctx argument value. 45 | Ctx context.Context 46 | // Person is the person argument value. 47 | Person *Person 48 | // Confirm is the confirm argument value. 49 | Confirm bool 50 | } 51 | // Get holds details about calls to the Get method. 52 | Get []struct { 53 | // Ctx is the ctx argument value. 54 | Ctx context.Context 55 | // ID is the id argument value. 56 | ID string 57 | } 58 | } 59 | lockCreate sync.RWMutex 60 | lockGet sync.RWMutex 61 | } 62 | 63 | // Create calls CreateFunc. 64 | func (mock *PersonStoreMock) Create(ctx context.Context, person *Person, confirm bool) error { 65 | if mock.CreateFunc == nil { 66 | panic("PersonStoreMock.CreateFunc: method is nil but PersonStore.Create was just called") 67 | } 68 | callInfo := struct { 69 | Ctx context.Context 70 | Person *Person 71 | Confirm bool 72 | }{ 73 | Ctx: ctx, 74 | Person: person, 75 | Confirm: confirm, 76 | } 77 | mock.lockCreate.Lock() 78 | mock.calls.Create = append(mock.calls.Create, callInfo) 79 | mock.lockCreate.Unlock() 80 | return mock.CreateFunc(ctx, person, confirm) 81 | } 82 | 83 | // CreateCalls gets all the calls that were made to Create. 84 | // Check the length with: 85 | // len(mockedPersonStore.CreateCalls()) 86 | func (mock *PersonStoreMock) CreateCalls() []struct { 87 | Ctx context.Context 88 | Person *Person 89 | Confirm bool 90 | } { 91 | var calls []struct { 92 | Ctx context.Context 93 | Person *Person 94 | Confirm bool 95 | } 96 | mock.lockCreate.RLock() 97 | calls = mock.calls.Create 98 | mock.lockCreate.RUnlock() 99 | return calls 100 | } 101 | 102 | // Get calls GetFunc. 103 | func (mock *PersonStoreMock) Get(ctx context.Context, id string) (*Person, error) { 104 | if mock.GetFunc == nil { 105 | panic("PersonStoreMock.GetFunc: method is nil but PersonStore.Get was just called") 106 | } 107 | callInfo := struct { 108 | Ctx context.Context 109 | ID string 110 | }{ 111 | Ctx: ctx, 112 | ID: id, 113 | } 114 | mock.lockGet.Lock() 115 | mock.calls.Get = append(mock.calls.Get, callInfo) 116 | mock.lockGet.Unlock() 117 | return mock.GetFunc(ctx, id) 118 | } 119 | 120 | // GetCalls gets all the calls that were made to Get. 121 | // Check the length with: 122 | // len(mockedPersonStore.GetCalls()) 123 | func (mock *PersonStoreMock) GetCalls() []struct { 124 | Ctx context.Context 125 | ID string 126 | } { 127 | var calls []struct { 128 | Ctx context.Context 129 | ID string 130 | } 131 | mock.lockGet.RLock() 132 | calls = mock.calls.Get 133 | mock.lockGet.RUnlock() 134 | return calls 135 | } 136 | -------------------------------------------------------------------------------- /generate/generate.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | // In a terminal, run `go generate` in this directory to have 4 | // it generates the generated.go file. 5 | 6 | //go:generate moq -out generated.go . MyInterface 7 | 8 | // MyInterface is a test interface. 9 | type MyInterface interface { 10 | One() bool 11 | Two() int 12 | Three() string 13 | } 14 | -------------------------------------------------------------------------------- /generate/generated.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package generate 5 | 6 | import ( 7 | "sync" 8 | ) 9 | 10 | // Ensure, that MyInterfaceMock does implement MyInterface. 11 | // If this is not the case, regenerate this file with moq. 12 | var _ MyInterface = &MyInterfaceMock{} 13 | 14 | // MyInterfaceMock is a mock implementation of MyInterface. 15 | // 16 | // func TestSomethingThatUsesMyInterface(t *testing.T) { 17 | // 18 | // // make and configure a mocked MyInterface 19 | // mockedMyInterface := &MyInterfaceMock{ 20 | // OneFunc: func() bool { 21 | // panic("mock out the One method") 22 | // }, 23 | // ThreeFunc: func() string { 24 | // panic("mock out the Three method") 25 | // }, 26 | // TwoFunc: func() int { 27 | // panic("mock out the Two method") 28 | // }, 29 | // } 30 | // 31 | // // use mockedMyInterface in code that requires MyInterface 32 | // // and then make assertions. 33 | // 34 | // } 35 | type MyInterfaceMock struct { 36 | // OneFunc mocks the One method. 37 | OneFunc func() bool 38 | 39 | // ThreeFunc mocks the Three method. 40 | ThreeFunc func() string 41 | 42 | // TwoFunc mocks the Two method. 43 | TwoFunc func() int 44 | 45 | // calls tracks calls to the methods. 46 | calls struct { 47 | // One holds details about calls to the One method. 48 | One []struct { 49 | } 50 | // Three holds details about calls to the Three method. 51 | Three []struct { 52 | } 53 | // Two holds details about calls to the Two method. 54 | Two []struct { 55 | } 56 | } 57 | lockOne sync.RWMutex 58 | lockThree sync.RWMutex 59 | lockTwo sync.RWMutex 60 | } 61 | 62 | // One calls OneFunc. 63 | func (mock *MyInterfaceMock) One() bool { 64 | if mock.OneFunc == nil { 65 | panic("MyInterfaceMock.OneFunc: method is nil but MyInterface.One was just called") 66 | } 67 | callInfo := struct { 68 | }{} 69 | mock.lockOne.Lock() 70 | mock.calls.One = append(mock.calls.One, callInfo) 71 | mock.lockOne.Unlock() 72 | return mock.OneFunc() 73 | } 74 | 75 | // OneCalls gets all the calls that were made to One. 76 | // Check the length with: 77 | // len(mockedMyInterface.OneCalls()) 78 | func (mock *MyInterfaceMock) OneCalls() []struct { 79 | } { 80 | var calls []struct { 81 | } 82 | mock.lockOne.RLock() 83 | calls = mock.calls.One 84 | mock.lockOne.RUnlock() 85 | return calls 86 | } 87 | 88 | // Three calls ThreeFunc. 89 | func (mock *MyInterfaceMock) Three() string { 90 | if mock.ThreeFunc == nil { 91 | panic("MyInterfaceMock.ThreeFunc: method is nil but MyInterface.Three was just called") 92 | } 93 | callInfo := struct { 94 | }{} 95 | mock.lockThree.Lock() 96 | mock.calls.Three = append(mock.calls.Three, callInfo) 97 | mock.lockThree.Unlock() 98 | return mock.ThreeFunc() 99 | } 100 | 101 | // ThreeCalls gets all the calls that were made to Three. 102 | // Check the length with: 103 | // len(mockedMyInterface.ThreeCalls()) 104 | func (mock *MyInterfaceMock) ThreeCalls() []struct { 105 | } { 106 | var calls []struct { 107 | } 108 | mock.lockThree.RLock() 109 | calls = mock.calls.Three 110 | mock.lockThree.RUnlock() 111 | return calls 112 | } 113 | 114 | // Two calls TwoFunc. 115 | func (mock *MyInterfaceMock) Two() int { 116 | if mock.TwoFunc == nil { 117 | panic("MyInterfaceMock.TwoFunc: method is nil but MyInterface.Two was just called") 118 | } 119 | callInfo := struct { 120 | }{} 121 | mock.lockTwo.Lock() 122 | mock.calls.Two = append(mock.calls.Two, callInfo) 123 | mock.lockTwo.Unlock() 124 | return mock.TwoFunc() 125 | } 126 | 127 | // TwoCalls gets all the calls that were made to Two. 128 | // Check the length with: 129 | // len(mockedMyInterface.TwoCalls()) 130 | func (mock *MyInterfaceMock) TwoCalls() []struct { 131 | } { 132 | var calls []struct { 133 | } 134 | mock.lockTwo.RLock() 135 | calls = mock.calls.Two 136 | mock.lockTwo.RUnlock() 137 | return calls 138 | } 139 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/matryer/moq 2 | 3 | go 1.24 4 | 5 | require ( 6 | github.com/pmezard/go-difflib v1.0.0 7 | golang.org/x/tools v0.30.0 8 | ) 9 | 10 | require ( 11 | golang.org/x/mod v0.23.0 // indirect 12 | golang.org/x/sync v0.11.0 // indirect 13 | ) 14 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 2 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= 6 | golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= 7 | golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= 8 | golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 9 | golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= 10 | golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= 11 | -------------------------------------------------------------------------------- /internal/registry/method_scope.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "go/types" 5 | "strconv" 6 | ) 7 | 8 | // MethodScope is the sub-registry for allocating variables present in 9 | // the method scope. 10 | // 11 | // It should be created using a registry instance. 12 | type MethodScope struct { 13 | registry *Registry 14 | moqPkgPath string 15 | 16 | vars []*Var 17 | conflicted map[string]bool 18 | } 19 | 20 | // AddVar allocates a variable instance and adds it to the method scope. 21 | // 22 | // Variables names are generated if required and are ensured to be 23 | // without conflict with other variables and imported packages. It also 24 | // adds the relevant imports to the registry for each added variable. 25 | func (m *MethodScope) AddVar(vr *types.Var, suffix string) *Var { 26 | imports := make(map[string]*Package) 27 | m.populateImports(vr.Type(), imports) 28 | m.resolveImportVarConflicts(imports) 29 | 30 | name := varName(vr, suffix) 31 | // Ensure that the var name does not conflict with a package import. 32 | if _, ok := m.registry.searchImport(name); ok { 33 | name += "MoqParam" 34 | } 35 | if _, ok := m.searchVar(name); ok || m.conflicted[name] { 36 | name = m.resolveVarNameConflict(name) 37 | } 38 | 39 | v := Var{ 40 | vr: vr, 41 | imports: imports, 42 | moqPkgPath: m.moqPkgPath, 43 | Name: name, 44 | } 45 | m.vars = append(m.vars, &v) 46 | return &v 47 | } 48 | 49 | func (m *MethodScope) resolveVarNameConflict(suggested string) string { 50 | for n := 1; ; n++ { 51 | _, ok := m.searchVar(suggested + strconv.Itoa(n)) 52 | if ok { 53 | continue 54 | } 55 | 56 | if n == 1 { 57 | conflict, _ := m.searchVar(suggested) 58 | conflict.Name += "1" 59 | m.conflicted[suggested] = true 60 | n++ 61 | } 62 | return suggested + strconv.Itoa(n) 63 | } 64 | } 65 | 66 | func (m MethodScope) searchVar(name string) (*Var, bool) { 67 | for _, v := range m.vars { 68 | if v.Name == name { 69 | return v, true 70 | } 71 | } 72 | 73 | return nil, false 74 | } 75 | 76 | // populateImports extracts all the package imports for a given type 77 | // recursively. The imported packages by a single type can be more than 78 | // one (ex: map[a.Type]b.Type). 79 | func (m MethodScope) populateImports(t types.Type, imports map[string]*Package) { 80 | switch t := t.(type) { 81 | case *types.Named: 82 | if pkg := t.Obj().Pkg(); pkg != nil { 83 | imports[stripVendorPath(pkg.Path())] = m.registry.AddImport(pkg) 84 | } 85 | // The imports of a Type with a TypeList must be added to the imports list 86 | // For example: Foo[otherpackage.Bar] , must have otherpackage imported 87 | if targs := t.TypeArgs(); targs != nil { 88 | for i := 0; i < targs.Len(); i++ { 89 | m.populateImports(targs.At(i), imports) 90 | } 91 | } 92 | 93 | case *types.Alias: 94 | if pkg := t.Obj().Pkg(); pkg != nil { 95 | imports[stripVendorPath(pkg.Path())] = m.registry.AddImport(pkg) 96 | } 97 | // The imports of a Type with a TypeList must be added to the imports list 98 | // For example: Foo[otherpackage.Bar] , must have otherpackage imported 99 | if targs := t.TypeArgs(); targs != nil { 100 | for i := 0; i < targs.Len(); i++ { 101 | m.populateImports(targs.At(i), imports) 102 | } 103 | } 104 | 105 | case *types.Array: 106 | m.populateImports(t.Elem(), imports) 107 | 108 | case *types.Slice: 109 | m.populateImports(t.Elem(), imports) 110 | 111 | case *types.Signature: 112 | for i := 0; i < t.Params().Len(); i++ { 113 | m.populateImports(t.Params().At(i).Type(), imports) 114 | } 115 | for i := 0; i < t.Results().Len(); i++ { 116 | m.populateImports(t.Results().At(i).Type(), imports) 117 | } 118 | 119 | case *types.Map: 120 | m.populateImports(t.Key(), imports) 121 | m.populateImports(t.Elem(), imports) 122 | 123 | case *types.Chan: 124 | m.populateImports(t.Elem(), imports) 125 | 126 | case *types.Pointer: 127 | m.populateImports(t.Elem(), imports) 128 | 129 | case *types.Struct: // anonymous struct 130 | for i := 0; i < t.NumFields(); i++ { 131 | m.populateImports(t.Field(i).Type(), imports) 132 | } 133 | 134 | case *types.Interface: // anonymous interface 135 | for i := 0; i < t.NumExplicitMethods(); i++ { 136 | m.populateImports(t.ExplicitMethod(i).Type(), imports) 137 | } 138 | for i := 0; i < t.NumEmbeddeds(); i++ { 139 | m.populateImports(t.EmbeddedType(i), imports) 140 | } 141 | } 142 | } 143 | 144 | // resolveImportVarConflicts ensures that all the newly added imports do not 145 | // conflict with any of the existing vars. 146 | func (m MethodScope) resolveImportVarConflicts(imports map[string]*Package) { 147 | // Ensure that all the newly added imports do not conflict with any of the 148 | // existing vars. 149 | for _, imprt := range imports { 150 | if v, ok := m.searchVar(imprt.Qualifier()); ok { 151 | v.Name += "MoqParam" 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /internal/registry/package.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "go/types" 5 | "path" 6 | "strings" 7 | ) 8 | 9 | // Package represents an imported package. 10 | type Package struct { 11 | pkg *types.Package 12 | 13 | Alias string 14 | } 15 | 16 | // NewPackage creates a new instance of Package. 17 | func NewPackage(pkg *types.Package) *Package { return &Package{pkg: pkg} } 18 | 19 | // Qualifier returns the qualifier which must be used to refer to types 20 | // declared in the package. 21 | func (p *Package) Qualifier() string { 22 | if p == nil { 23 | return "" 24 | } 25 | 26 | if p.Alias != "" { 27 | return p.Alias 28 | } 29 | 30 | return p.pkg.Name() 31 | } 32 | 33 | // Path is the full package import path (without vendor). 34 | func (p *Package) Path() string { 35 | if p == nil { 36 | return "" 37 | } 38 | 39 | return stripVendorPath(p.pkg.Path()) 40 | } 41 | 42 | var replacer = strings.NewReplacer( 43 | "go-", "", 44 | "-go", "", 45 | "-", "", 46 | "_", "", 47 | ".", "", 48 | "@", "", 49 | "+", "", 50 | "~", "", 51 | ) 52 | 53 | // uniqueName generates a unique name for a package by concatenating 54 | // path components. The generated name is guaranteed to unique with an 55 | // appropriate level because the full package import paths themselves 56 | // are unique. 57 | func (p Package) uniqueName(lvl int) string { 58 | pp := strings.Split(p.Path(), "/") 59 | reverse(pp) 60 | 61 | var name string 62 | for i := 0; i < min(len(pp), lvl+1); i++ { 63 | name = strings.ToLower(replacer.Replace(pp[i])) + name 64 | } 65 | 66 | return name 67 | } 68 | 69 | // stripVendorPath strips the vendor dir prefix from a package path. 70 | // For example we might encounter an absolute path like 71 | // github.com/foo/bar/vendor/github.com/pkg/errors which is resolved 72 | // to github.com/pkg/errors. 73 | func stripVendorPath(p string) string { 74 | parts := strings.Split(p, "/vendor/") 75 | if len(parts) == 1 { 76 | return p 77 | } 78 | return strings.TrimLeft(path.Join(parts[1:]...), "/") 79 | } 80 | 81 | func min(a, b int) int { 82 | if a < b { 83 | return a 84 | } 85 | return b 86 | } 87 | 88 | func reverse(a []string) { 89 | for i := len(a)/2 - 1; i >= 0; i-- { 90 | opp := len(a) - 1 - i 91 | a[i], a[opp] = a[opp], a[i] 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /internal/registry/registry.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "go/ast" 7 | "go/types" 8 | "path/filepath" 9 | "sort" 10 | "strings" 11 | 12 | "golang.org/x/tools/go/packages" 13 | ) 14 | 15 | // Registry encapsulates types information for the source and mock 16 | // destination package. For the mock package, it tracks the list of 17 | // imports and ensures there are no conflicts in the imported package 18 | // qualifiers. 19 | type Registry struct { 20 | srcPkgName string 21 | srcPkgTypes *types.Package 22 | moqPkgPath string 23 | aliases map[string]string 24 | imports map[string]*Package 25 | } 26 | 27 | // New loads the source package info and returns a new instance of 28 | // Registry. 29 | func New(srcDir, moqPkg string) (*Registry, error) { 30 | srcPkg, err := pkgInfoFromPath( 31 | srcDir, packages.NeedName|packages.NeedSyntax|packages.NeedTypes, 32 | ) 33 | if err != nil { 34 | return nil, fmt.Errorf("couldn't load source package: %s", err) 35 | } 36 | 37 | return &Registry{ 38 | srcPkgName: srcPkg.Name, 39 | srcPkgTypes: srcPkg.Types, 40 | moqPkgPath: findPkgPath(moqPkg, srcPkg.PkgPath), 41 | aliases: parseImportsAliases(srcPkg.Syntax), 42 | imports: make(map[string]*Package), 43 | }, nil 44 | } 45 | 46 | // SrcPkg returns the types info for the source package. 47 | func (r Registry) SrcPkg() *types.Package { 48 | return r.srcPkgTypes 49 | } 50 | 51 | // SrcPkgName returns the name of the source package. 52 | func (r Registry) SrcPkgName() string { 53 | return r.srcPkgName 54 | } 55 | 56 | // LookupInterface returns the underlying interface definition of the 57 | // given interface name. 58 | func (r Registry) LookupInterface(name string) (*types.Interface, *types.TypeParamList, error) { 59 | obj := r.SrcPkg().Scope().Lookup(name) 60 | if obj == nil { 61 | return nil, nil, fmt.Errorf("interface not found: %s", name) 62 | } 63 | 64 | if !types.IsInterface(obj.Type()) { 65 | return nil, nil, fmt.Errorf("%s (%s) is not an interface", name, obj.Type()) 66 | } 67 | 68 | var tparams *types.TypeParamList 69 | named, ok := obj.Type().(*types.Named) 70 | if ok { 71 | tparams = named.TypeParams() 72 | } 73 | 74 | return obj.Type().Underlying().(*types.Interface).Complete(), tparams, nil 75 | } 76 | 77 | // MethodScope returns a new MethodScope. 78 | func (r *Registry) MethodScope() *MethodScope { 79 | return &MethodScope{ 80 | registry: r, 81 | moqPkgPath: r.moqPkgPath, 82 | conflicted: map[string]bool{}, 83 | } 84 | } 85 | 86 | // AddImport adds the given package to the set of imports. It generates a 87 | // suitable alias if there are any conflicts with previously imported 88 | // packages. 89 | func (r *Registry) AddImport(pkg *types.Package) *Package { 90 | path := stripVendorPath(pkg.Path()) 91 | if path == r.moqPkgPath { 92 | return nil 93 | } 94 | 95 | if imprt, ok := r.imports[path]; ok { 96 | return imprt 97 | } 98 | 99 | imprt := Package{pkg: pkg, Alias: r.aliases[path]} 100 | 101 | if conflict, ok := r.searchImport(imprt.Qualifier()); ok { 102 | r.resolveImportConflict(&imprt, conflict, 0) 103 | } 104 | 105 | r.imports[path] = &imprt 106 | return &imprt 107 | } 108 | 109 | // Imports returns the list of imported packages. The list is sorted by 110 | // path. 111 | func (r Registry) Imports() []*Package { 112 | imports := make([]*Package, 0, len(r.imports)) 113 | for _, imprt := range r.imports { 114 | imports = append(imports, imprt) 115 | } 116 | sort.Slice(imports, func(i, j int) bool { 117 | return imports[i].Path() < imports[j].Path() 118 | }) 119 | return imports 120 | } 121 | 122 | func (r Registry) searchImport(name string) (*Package, bool) { 123 | for _, imprt := range r.imports { 124 | if imprt.Qualifier() == name { 125 | return imprt, true 126 | } 127 | } 128 | 129 | return nil, false 130 | } 131 | 132 | // resolveImportConflict generates and assigns a unique alias for 133 | // packages with conflicting qualifiers. 134 | func (r Registry) resolveImportConflict(a, b *Package, lvl int) { 135 | if a.uniqueName(lvl) == b.uniqueName(lvl) { 136 | r.resolveImportConflict(a, b, lvl+1) 137 | return 138 | } 139 | 140 | for _, p := range []*Package{a, b} { 141 | name := p.uniqueName(lvl) 142 | // Even though the name is not conflicting with the other package we 143 | // got, the new name we want to pick might already be taken. So check 144 | // again for conflicts and resolve them as well. Since the name for 145 | // this package would also get set in the recursive function call, skip 146 | // setting the alias after it. 147 | if conflict, ok := r.searchImport(name); ok && conflict != p { 148 | r.resolveImportConflict(p, conflict, lvl+1) 149 | continue 150 | } 151 | 152 | p.Alias = name 153 | } 154 | } 155 | 156 | func pkgInfoFromPath(srcDir string, mode packages.LoadMode) (*packages.Package, error) { 157 | pkgs, err := packages.Load(&packages.Config{ 158 | Mode: mode, 159 | Dir: srcDir, 160 | }) 161 | if err != nil { 162 | return nil, err 163 | } 164 | if len(pkgs) == 0 { 165 | return nil, errors.New("package not found") 166 | } 167 | if len(pkgs) > 1 { 168 | return nil, errors.New("found more than one package") 169 | } 170 | if errs := pkgs[0].Errors; len(errs) != 0 { 171 | if len(errs) == 1 { 172 | return nil, errs[0] 173 | } 174 | return nil, fmt.Errorf("%s (and %d more errors)", errs[0], len(errs)-1) 175 | } 176 | return pkgs[0], nil 177 | } 178 | 179 | func findPkgPath(pkgInputVal string, srcPkgPath string) string { 180 | if pkgInputVal == "" { 181 | return srcPkgPath 182 | } 183 | if pkgInDir(srcPkgPath, pkgInputVal) { 184 | return srcPkgPath 185 | } 186 | subdirectoryPath := filepath.Join(srcPkgPath, pkgInputVal) 187 | if pkgInDir(subdirectoryPath, pkgInputVal) { 188 | return subdirectoryPath 189 | } 190 | return "" 191 | } 192 | 193 | func pkgInDir(pkgName, dir string) bool { 194 | currentPkg, err := pkgInfoFromPath(dir, packages.NeedName) 195 | if err != nil { 196 | return false 197 | } 198 | return currentPkg.Name == pkgName || currentPkg.Name+"_test" == pkgName 199 | } 200 | 201 | func parseImportsAliases(syntaxTree []*ast.File) map[string]string { 202 | aliases := make(map[string]string) 203 | for _, syntax := range syntaxTree { 204 | for _, imprt := range syntax.Imports { 205 | if imprt.Name != nil && imprt.Name.Name != "." && imprt.Name.Name != "_" { 206 | aliases[strings.Trim(imprt.Path.Value, `"`)] = imprt.Name.Name 207 | } 208 | } 209 | } 210 | return aliases 211 | } 212 | -------------------------------------------------------------------------------- /internal/registry/registry_test.go: -------------------------------------------------------------------------------- 1 | package registry_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/matryer/moq/internal/registry" 7 | ) 8 | 9 | func BenchmarkNew(b *testing.B) { 10 | for i := 0; i < b.N; i++ { 11 | registry.New("../../pkg/moq/testpackages/example", "") 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /internal/registry/var.go: -------------------------------------------------------------------------------- 1 | package registry 2 | 3 | import ( 4 | "go/types" 5 | "strings" 6 | ) 7 | 8 | // Var represents a method variable/parameter. 9 | // 10 | // It should be created using a method scope instance. 11 | type Var struct { 12 | vr *types.Var 13 | imports map[string]*Package 14 | moqPkgPath string 15 | 16 | Name string 17 | } 18 | 19 | // IsSlice returns whether the type (or the underlying type) is a slice. 20 | func (v Var) IsSlice() bool { 21 | _, ok := v.vr.Type().Underlying().(*types.Slice) 22 | return ok 23 | } 24 | 25 | // TypeString returns the variable type with the package qualifier in the 26 | // format 'pkg.Type'. 27 | func (v Var) TypeString() string { 28 | return types.TypeString(v.vr.Type(), v.packageQualifier) 29 | } 30 | 31 | // packageQualifier is a types.Qualifier. 32 | func (v Var) packageQualifier(pkg *types.Package) string { 33 | path := stripVendorPath(pkg.Path()) 34 | if v.moqPkgPath != "" && v.moqPkgPath == path { 35 | return "" 36 | } 37 | 38 | return v.imports[path].Qualifier() 39 | } 40 | 41 | func varName(vr *types.Var, suffix string) string { 42 | name := vr.Name() 43 | if name != "" && name != "_" { 44 | return name + suffix 45 | } 46 | 47 | name = varNameForType(vr.Type()) + suffix 48 | 49 | switch name { 50 | case "mock", "callInfo", "break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct", 51 | "chan", "else", "goto", "package", "switch", "const", "fallthrough", "if", "range", "type", "continue", "for", 52 | "import", "return", "var", 53 | // avoid shadowing basic types 54 | "string", "bool", "byte", "rune", "uintptr", 55 | "int", "int8", "int16", "int32", "int64", 56 | "uint", "uint8", "uint16", "uint32", "uint64", 57 | "float32", "float64", "complex64", "complex128": 58 | name += "MoqParam" 59 | } 60 | 61 | return name 62 | } 63 | 64 | // varNameForType generates a name for the variable using the type 65 | // information. 66 | // 67 | // Examples: 68 | // - string -> s 69 | // - int -> n 70 | // - chan int -> intCh 71 | // - []a.MyType -> myTypes 72 | // - map[string]int -> stringToInt 73 | // - error -> err 74 | // - a.MyType -> myType 75 | func varNameForType(t types.Type) string { 76 | nestedType := func(t types.Type) string { 77 | if t, ok := t.(*types.Basic); ok { 78 | return deCapitalise(t.String()) 79 | } 80 | return varNameForType(t) 81 | } 82 | 83 | switch t := t.(type) { 84 | case *types.Named: 85 | if t.Obj().Name() == "error" { 86 | return "err" 87 | } 88 | 89 | name := deCapitalise(t.Obj().Name()) 90 | if name == t.Obj().Name() { 91 | name += "MoqParam" 92 | } 93 | 94 | return name 95 | 96 | case *types.Basic: 97 | return basicTypeVarName(t) 98 | 99 | case *types.Array: 100 | return nestedType(t.Elem()) + "s" 101 | 102 | case *types.Slice: 103 | return nestedType(t.Elem()) + "s" 104 | 105 | case *types.Struct: // anonymous struct 106 | return "val" 107 | 108 | case *types.Pointer: 109 | return varNameForType(t.Elem()) 110 | 111 | case *types.Signature: 112 | return "fn" 113 | 114 | case *types.Interface: // anonymous interface 115 | return "ifaceVal" 116 | 117 | case *types.Map: 118 | return nestedType(t.Key()) + "To" + capitalise(nestedType(t.Elem())) 119 | 120 | case *types.Chan: 121 | return nestedType(t.Elem()) + "Ch" 122 | } 123 | 124 | return "v" 125 | } 126 | 127 | func basicTypeVarName(b *types.Basic) string { 128 | switch b.Info() { 129 | case types.IsBoolean: 130 | return "b" 131 | 132 | case types.IsInteger: 133 | return "n" 134 | 135 | case types.IsFloat: 136 | return "f" 137 | 138 | case types.IsString: 139 | return "s" 140 | } 141 | 142 | return "v" 143 | } 144 | 145 | func capitalise(s string) string { return strings.ToUpper(s[:1]) + s[1:] } 146 | func deCapitalise(s string) string { return strings.ToLower(s[:1]) + s[1:] } 147 | -------------------------------------------------------------------------------- /internal/template/template.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | "io" 5 | "strings" 6 | "text/template" 7 | 8 | "github.com/matryer/moq/internal/registry" 9 | ) 10 | 11 | // Template is the Moq template. It is capable of generating the Moq 12 | // implementation for the given template.Data. 13 | type Template struct { 14 | tmpl *template.Template 15 | } 16 | 17 | // New returns a new instance of Template. 18 | func New() (Template, error) { 19 | tmpl, err := template.New("moq").Funcs(templateFuncs).Parse(moqTemplate) 20 | if err != nil { 21 | return Template{}, err 22 | } 23 | 24 | return Template{tmpl: tmpl}, nil 25 | } 26 | 27 | // Execute generates and writes the Moq implementation for the given 28 | // data. 29 | func (t Template) Execute(w io.Writer, data Data) error { 30 | return t.tmpl.Execute(w, data) 31 | } 32 | 33 | // moqTemplate is the template for mocked code. 34 | // language=GoTemplate 35 | var moqTemplate = `// Code generated by moq; DO NOT EDIT. 36 | // github.com/matryer/moq 37 | 38 | package {{.PkgName}} 39 | 40 | import ( 41 | {{- range .Imports}} 42 | {{. | ImportStatement}} 43 | {{- end}} 44 | ) 45 | 46 | {{range $i, $mock := .Mocks -}} 47 | 48 | {{- if not $.SkipEnsure -}} 49 | // Ensure, that {{.MockName}} does implement {{$.SrcPkgQualifier}}{{.InterfaceName}}. 50 | // If this is not the case, regenerate this file with moq. 51 | var _ {{$.SrcPkgQualifier}}{{.InterfaceName -}} 52 | {{- if .TypeParams }}[ 53 | {{- range $index, $param := .TypeParams}} 54 | {{- if $index}}, {{end -}} 55 | {{if $param.Constraint}}{{$param.Constraint.String}}{{else}}{{$param.TypeString}}{{end}} 56 | {{- end -}} 57 | ] 58 | {{- end }} = &{{.MockName}} 59 | {{- if .TypeParams }}[ 60 | {{- range $index, $param := .TypeParams}} 61 | {{- if $index}}, {{end -}} 62 | {{if $param.Constraint}}{{$param.Constraint.String}}{{else}}{{$param.TypeString}}{{end}} 63 | {{- end -}} 64 | ] 65 | {{- end -}} 66 | {} 67 | {{- end}} 68 | 69 | // {{.MockName}} is a mock implementation of {{$.SrcPkgQualifier}}{{.InterfaceName}}. 70 | // 71 | // func TestSomethingThatUses{{.InterfaceName}}(t *testing.T) { 72 | // 73 | // // make and configure a mocked {{$.SrcPkgQualifier}}{{.InterfaceName}} 74 | // mocked{{.InterfaceName}} := &{{.MockName}}{ 75 | {{- range .Methods}} 76 | // {{.Name}}Func: func({{.ArgList}}) {{.ReturnArgTypeList}} { 77 | // panic("mock out the {{.Name}} method") 78 | // }, 79 | {{- end}} 80 | // } 81 | // 82 | // // use mocked{{.InterfaceName}} in code that requires {{$.SrcPkgQualifier}}{{.InterfaceName}} 83 | // // and then make assertions. 84 | // 85 | // } 86 | type {{.MockName}} 87 | {{- if .TypeParams -}} 88 | [{{- range $index, $param := .TypeParams}} 89 | {{- if $index}}, {{end}}{{$param.Name | Exported}} {{$param.TypeString}} 90 | {{- end -}}] 91 | {{- end }} struct { 92 | {{- range .Methods}} 93 | // {{.Name}}Func mocks the {{.Name}} method. 94 | {{.Name}}Func func({{.ArgList}}) {{.ReturnArgTypeList}} 95 | {{end}} 96 | // calls tracks calls to the methods. 97 | calls struct { 98 | {{- range .Methods}} 99 | // {{.Name}} holds details about calls to the {{.Name}} method. 100 | {{.Name}} []struct { 101 | {{- range .Params}} 102 | // {{.Name | Exported}} is the {{.Name}} argument value. 103 | {{.Name | Exported}} {{.TypeString}} 104 | {{- end}} 105 | } 106 | {{- end}} 107 | } 108 | {{- range .Methods}} 109 | lock{{.Name}} {{$.Imports | SyncPkgQualifier}}.RWMutex 110 | {{- end}} 111 | } 112 | {{range .Methods}} 113 | // {{.Name}} calls {{.Name}}Func. 114 | func (mock *{{$mock.MockName}} 115 | {{- if $mock.TypeParams -}} 116 | [{{- range $index, $param := $mock.TypeParams}} 117 | {{- if $index}}, {{end}}{{$param.Name | Exported}} 118 | {{- end -}}] 119 | {{- end -}} 120 | ) {{.Name}}({{.ArgList}}) {{.ReturnArgTypeList}} { 121 | {{- if not $.StubImpl}} 122 | if mock.{{.Name}}Func == nil { 123 | panic("{{$mock.MockName}}.{{.Name}}Func: method is nil but {{$mock.InterfaceName}}.{{.Name}} was just called") 124 | } 125 | {{- end}} 126 | callInfo := struct { 127 | {{- range .Params}} 128 | {{.Name | Exported}} {{.TypeString}} 129 | {{- end}} 130 | }{ 131 | {{- range .Params}} 132 | {{.Name | Exported}}: {{.Name}}, 133 | {{- end}} 134 | } 135 | mock.lock{{.Name}}.Lock() 136 | mock.calls.{{.Name}} = append(mock.calls.{{.Name}}, callInfo) 137 | mock.lock{{.Name}}.Unlock() 138 | {{- if .Returns}} 139 | {{- if $.StubImpl}} 140 | if mock.{{.Name}}Func == nil { 141 | var ( 142 | {{- range .Returns}} 143 | {{.Name}} {{.TypeString}} 144 | {{- end}} 145 | ) 146 | return {{.ReturnArgNameList}} 147 | } 148 | {{- end}} 149 | return mock.{{.Name}}Func({{.ArgCallList}}) 150 | {{- else}} 151 | {{- if $.StubImpl}} 152 | if mock.{{.Name}}Func == nil { 153 | return 154 | } 155 | {{- end}} 156 | mock.{{.Name}}Func({{.ArgCallList}}) 157 | {{- end}} 158 | } 159 | 160 | // {{.Name}}Calls gets all the calls that were made to {{.Name}}. 161 | // Check the length with: 162 | // 163 | // len(mocked{{$mock.InterfaceName}}.{{.Name}}Calls()) 164 | func (mock *{{$mock.MockName}} 165 | {{- if $mock.TypeParams -}} 166 | [{{- range $index, $param := $mock.TypeParams}} 167 | {{- if $index}}, {{end}}{{$param.Name | Exported}} 168 | {{- end -}}] 169 | {{- end -}} 170 | ) {{.Name}}Calls() []struct { 171 | {{- range .Params}} 172 | {{.Name | Exported}} {{.TypeString}} 173 | {{- end}} 174 | } { 175 | var calls []struct { 176 | {{- range .Params}} 177 | {{.Name | Exported}} {{.TypeString}} 178 | {{- end}} 179 | } 180 | mock.lock{{.Name}}.RLock() 181 | calls = mock.calls.{{.Name}} 182 | mock.lock{{.Name}}.RUnlock() 183 | return calls 184 | } 185 | {{- if $.WithResets}} 186 | // Reset{{.Name}}Calls reset all the calls that were made to {{.Name}}. 187 | func (mock *{{$mock.MockName}} 188 | {{- if $mock.TypeParams -}} 189 | [{{- range $index, $param := $mock.TypeParams}} 190 | {{- if $index}}, {{end}}{{$param.Name | Exported}} 191 | {{- end -}}] 192 | {{- end -}} 193 | ) Reset{{.Name}}Calls() { 194 | mock.lock{{.Name}}.Lock() 195 | mock.calls.{{.Name}} = nil 196 | mock.lock{{.Name}}.Unlock() 197 | } 198 | {{end}} 199 | {{end -}} 200 | {{- if $.WithResets}} 201 | // ResetCalls reset all the calls that were made to all mocked methods. 202 | func (mock *{{$mock.MockName}} 203 | {{- if $mock.TypeParams -}} 204 | [{{- range $index, $param := $mock.TypeParams}} 205 | {{- if $index}}, {{end}}{{$param.Name | Exported}} 206 | {{- end -}}] 207 | {{- end -}} 208 | ) ResetCalls() { 209 | {{- range .Methods}} 210 | mock.lock{{.Name}}.Lock() 211 | mock.calls.{{.Name}} = nil 212 | mock.lock{{.Name}}.Unlock() 213 | {{end -}} 214 | } 215 | {{end -}} 216 | {{end -}} 217 | ` 218 | 219 | // This list comes from the golint codebase. Golint will complain about any of 220 | // these being mixed-case, like "Id" instead of "ID". 221 | var golintInitialisms = []string{ 222 | "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS", 223 | "QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "UID", "UUID", "URI", 224 | "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", 225 | } 226 | 227 | var templateFuncs = template.FuncMap{ 228 | "ImportStatement": func(imprt *registry.Package) string { 229 | if imprt.Alias == "" { 230 | return `"` + imprt.Path() + `"` 231 | } 232 | return imprt.Alias + ` "` + imprt.Path() + `"` 233 | }, 234 | "SyncPkgQualifier": func(imports []*registry.Package) string { 235 | for _, imprt := range imports { 236 | if imprt.Path() == "sync" { 237 | return imprt.Qualifier() 238 | } 239 | } 240 | 241 | return "sync" 242 | }, 243 | "Exported": func(s string) string { 244 | if s == "" { 245 | return "" 246 | } 247 | for _, initialism := range golintInitialisms { 248 | if strings.ToUpper(s) == initialism { 249 | return initialism 250 | } 251 | } 252 | return strings.ToUpper(s[0:1]) + s[1:] 253 | }, 254 | } 255 | -------------------------------------------------------------------------------- /internal/template/template_data.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | "fmt" 5 | "go/types" 6 | "strings" 7 | 8 | "github.com/matryer/moq/internal/registry" 9 | ) 10 | 11 | // Data is the template data used to render the Moq template. 12 | type Data struct { 13 | PkgName string 14 | SrcPkgQualifier string 15 | Imports []*registry.Package 16 | Mocks []MockData 17 | StubImpl bool 18 | SkipEnsure bool 19 | WithResets bool 20 | } 21 | 22 | // MocksSomeMethod returns true of any one of the Mocks has at least 1 23 | // method. 24 | func (d Data) MocksSomeMethod() bool { 25 | for _, m := range d.Mocks { 26 | if len(m.Methods) > 0 { 27 | return true 28 | } 29 | } 30 | 31 | return false 32 | } 33 | 34 | // MockData is the data used to generate a mock for some interface. 35 | type MockData struct { 36 | InterfaceName string 37 | MockName string 38 | TypeParams []TypeParamData 39 | Methods []MethodData 40 | } 41 | 42 | // MethodData is the data which represents a method on some interface. 43 | type MethodData struct { 44 | Name string 45 | Params []ParamData 46 | Returns []ParamData 47 | } 48 | 49 | // ArgList is the string representation of method parameters, ex: 50 | // 's string, n int, foo bar.Baz'. 51 | func (m MethodData) ArgList() string { 52 | params := make([]string, len(m.Params)) 53 | for i, p := range m.Params { 54 | params[i] = p.MethodArg() 55 | } 56 | return strings.Join(params, ", ") 57 | } 58 | 59 | // ArgCallList is the string representation of method call parameters, 60 | // ex: 's, n, foo'. In case of a last variadic parameter, it will be of 61 | // the format 's, n, foos...' 62 | func (m MethodData) ArgCallList() string { 63 | params := make([]string, len(m.Params)) 64 | for i, p := range m.Params { 65 | params[i] = p.CallName() 66 | } 67 | return strings.Join(params, ", ") 68 | } 69 | 70 | // ReturnArgTypeList is the string representation of method return 71 | // types, ex: 'bar.Baz', '(string, error)'. 72 | func (m MethodData) ReturnArgTypeList() string { 73 | params := make([]string, len(m.Returns)) 74 | for i, p := range m.Returns { 75 | params[i] = p.TypeString() 76 | } 77 | if len(m.Returns) > 1 { 78 | return fmt.Sprintf("(%s)", strings.Join(params, ", ")) 79 | } 80 | return strings.Join(params, ", ") 81 | } 82 | 83 | // ReturnArgNameList is the string representation of values being 84 | // returned from the method, ex: 'foo', 's, err'. 85 | func (m MethodData) ReturnArgNameList() string { 86 | params := make([]string, len(m.Returns)) 87 | for i, p := range m.Returns { 88 | params[i] = p.Name() 89 | } 90 | return strings.Join(params, ", ") 91 | } 92 | 93 | // TypeParamData extends ParamData with a constraint. 94 | type TypeParamData struct { 95 | ParamData 96 | Constraint types.Type 97 | } 98 | 99 | // ParamData is the data which represents a parameter to some method of 100 | // an interface. 101 | type ParamData struct { 102 | Var *registry.Var 103 | Variadic bool 104 | } 105 | 106 | // Name returns the name of the parameter. 107 | func (p ParamData) Name() string { 108 | return p.Var.Name 109 | } 110 | 111 | // MethodArg is the representation of the parameter in the function 112 | // signature, ex: 'name a.Type'. 113 | func (p ParamData) MethodArg() string { 114 | if p.Variadic { 115 | return fmt.Sprintf("%s ...%s", p.Name(), p.TypeString()[2:]) 116 | } 117 | return fmt.Sprintf("%s %s", p.Name(), p.TypeString()) 118 | } 119 | 120 | // CallName returns the string representation of the parameter to be 121 | // used for a method call. For a variadic paramter, it will be of the 122 | // format 'foos...'. 123 | func (p ParamData) CallName() string { 124 | if p.Variadic { 125 | return p.Name() + "..." 126 | } 127 | return p.Name() 128 | } 129 | 130 | // TypeString returns the string representation of the type of the 131 | // parameter. 132 | func (p ParamData) TypeString() string { 133 | return p.Var.TypeString() 134 | } 135 | -------------------------------------------------------------------------------- /internal/template/template_test.go: -------------------------------------------------------------------------------- 1 | package template 2 | 3 | import ( 4 | "go/types" 5 | "testing" 6 | 7 | "github.com/matryer/moq/internal/registry" 8 | ) 9 | 10 | func TestTemplateFuncs(t *testing.T) { 11 | t.Run("Exported", func(t *testing.T) { 12 | f := templateFuncs["Exported"].(func(string) string) 13 | if f("") != "" { 14 | t.Errorf("Exported(...) want: ``; got: `%s`", f("")) 15 | } 16 | if f("var") != "Var" { 17 | t.Errorf("Exported(...) want: `Var`; got: `%s`", f("var")) 18 | } 19 | }) 20 | 21 | t.Run("ImportStatement", func(t *testing.T) { 22 | f := templateFuncs["ImportStatement"].(func(*registry.Package) string) 23 | pkg := registry.NewPackage(types.NewPackage("xyz", "xyz")) 24 | if f(pkg) != `"xyz"` { 25 | t.Errorf("ImportStatement(...): want: `\"xyz\"`; got: `%s`", f(pkg)) 26 | } 27 | 28 | pkg.Alias = "x" 29 | if f(pkg) != `x "xyz"` { 30 | t.Errorf("ImportStatement(...): want: `x \"xyz\"`; got: `%s`", f(pkg)) 31 | } 32 | }) 33 | 34 | t.Run("SyncPkgQualifier", func(t *testing.T) { 35 | f := templateFuncs["SyncPkgQualifier"].(func([]*registry.Package) string) 36 | if f(nil) != "sync" { 37 | t.Errorf("SyncPkgQualifier(...): want: `sync`; got: `%s`", f(nil)) 38 | } 39 | imports := []*registry.Package{ 40 | registry.NewPackage(types.NewPackage("sync", "sync")), 41 | registry.NewPackage(types.NewPackage("github.com/some/module", "module")), 42 | } 43 | if f(imports) != "sync" { 44 | t.Errorf("SyncPkgQualifier(...): want: `sync`; got: `%s`", f(imports)) 45 | } 46 | 47 | syncPkg := registry.NewPackage(types.NewPackage("sync", "sync")) 48 | syncPkg.Alias = "stdsync" 49 | otherSyncPkg := registry.NewPackage(types.NewPackage("github.com/someother/sync", "sync")) 50 | imports = []*registry.Package{otherSyncPkg, syncPkg} 51 | if f(imports) != "stdsync" { 52 | t.Errorf("SyncPkgQualifier(...): want: `stdsync`; got: `%s`", f(imports)) 53 | } 54 | }) 55 | } 56 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "flag" 7 | "fmt" 8 | "io" 9 | "os" 10 | "path/filepath" 11 | 12 | "github.com/matryer/moq/pkg/moq" 13 | ) 14 | 15 | // Version is the command version, injected at build time. 16 | var Version string = "dev" 17 | 18 | type userFlags struct { 19 | outFile string 20 | pkgName string 21 | formatter string 22 | stubImpl bool 23 | skipEnsure bool 24 | withResets bool 25 | remove bool 26 | args []string 27 | } 28 | 29 | func main() { 30 | var flags userFlags 31 | flag.StringVar(&flags.outFile, "out", "", "output file (default stdout)") 32 | flag.StringVar(&flags.pkgName, "pkg", "", "package name (default will infer)") 33 | flag.StringVar(&flags.formatter, "fmt", "", "go pretty-printer: gofmt, goimports or noop (default gofmt)") 34 | flag.BoolVar(&flags.stubImpl, "stub", false, 35 | "return zero values when no mock implementation is provided, do not panic") 36 | printVersion := flag.Bool("version", false, "show the version for moq") 37 | flag.BoolVar(&flags.skipEnsure, "skip-ensure", false, 38 | "suppress mock implementation check, avoid import cycle if mocks generated outside of the tested package") 39 | flag.BoolVar(&flags.remove, "rm", false, "first remove output file, if it exists") 40 | flag.BoolVar(&flags.withResets, "with-resets", false, 41 | "generate functions to facilitate resetting calls made to a mock") 42 | 43 | flag.Usage = func() { 44 | fmt.Println(`moq [flags] source-dir interface [interface2 [interface3 [...]]]`) 45 | flag.PrintDefaults() 46 | fmt.Println(`Specifying an alias for the mock is also supported with the format 'interface:alias'`) 47 | fmt.Println(`Ex: moq -pkg different . MyInterface:MyMock`) 48 | } 49 | 50 | flag.Parse() 51 | flags.args = flag.Args() 52 | 53 | if *printVersion { 54 | fmt.Printf("moq version %s\n", Version) 55 | os.Exit(0) 56 | } 57 | 58 | if err := run(flags); err != nil { 59 | fmt.Fprintln(os.Stderr, err) 60 | flag.Usage() 61 | os.Exit(1) 62 | } 63 | } 64 | 65 | func run(flags userFlags) error { 66 | if len(flags.args) < 2 { 67 | return errors.New("not enough arguments") 68 | } 69 | 70 | if flags.remove && flags.outFile != "" { 71 | if err := os.Remove(flags.outFile); err != nil { 72 | if !errors.Is(err, os.ErrNotExist) { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | var buf bytes.Buffer 79 | var out io.Writer = os.Stdout 80 | if flags.outFile != "" { 81 | out = &buf 82 | } 83 | 84 | srcDir, args := flags.args[0], flags.args[1:] 85 | m, err := moq.New(moq.Config{ 86 | SrcDir: srcDir, 87 | PkgName: flags.pkgName, 88 | Formatter: flags.formatter, 89 | StubImpl: flags.stubImpl, 90 | SkipEnsure: flags.skipEnsure, 91 | WithResets: flags.withResets, 92 | }) 93 | if err != nil { 94 | return err 95 | } 96 | 97 | if err = m.Mock(out, args...); err != nil { 98 | return err 99 | } 100 | 101 | if flags.outFile == "" { 102 | return nil 103 | } 104 | 105 | // create the file 106 | err = os.MkdirAll(filepath.Dir(flags.outFile), 0o750) 107 | if err != nil { 108 | return err 109 | } 110 | 111 | return os.WriteFile(flags.outFile, buf.Bytes(), 0o600) 112 | } 113 | -------------------------------------------------------------------------------- /moq-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matryer/moq/31af695e859b89ed710ee12c07720cea3e656b68/moq-logo-small.png -------------------------------------------------------------------------------- /moq-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matryer/moq/31af695e859b89ed710ee12c07720cea3e656b68/moq-logo.png -------------------------------------------------------------------------------- /pkg/moq/formatter.go: -------------------------------------------------------------------------------- 1 | package moq 2 | 3 | import ( 4 | "fmt" 5 | "go/format" 6 | 7 | "golang.org/x/tools/imports" 8 | ) 9 | 10 | func goimports(src []byte) ([]byte, error) { 11 | formatted, err := imports.Process("filename", src, &imports.Options{ 12 | TabWidth: 8, 13 | TabIndent: true, 14 | Comments: true, 15 | Fragment: true, 16 | }) 17 | if err != nil { 18 | return nil, fmt.Errorf("goimports: %s", err) 19 | } 20 | 21 | return formatted, nil 22 | } 23 | 24 | func gofmt(src []byte) ([]byte, error) { 25 | formatted, err := format.Source(src) 26 | if err != nil { 27 | return nil, fmt.Errorf("go/format: %s", err) 28 | } 29 | 30 | return formatted, nil 31 | } 32 | -------------------------------------------------------------------------------- /pkg/moq/moq.go: -------------------------------------------------------------------------------- 1 | package moq 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "go/token" 7 | "go/types" 8 | "io" 9 | "strings" 10 | 11 | "github.com/matryer/moq/internal/registry" 12 | "github.com/matryer/moq/internal/template" 13 | ) 14 | 15 | // Mocker can generate mock structs. 16 | type Mocker struct { 17 | cfg Config 18 | 19 | registry *registry.Registry 20 | tmpl template.Template 21 | } 22 | 23 | // Config specifies details about how interfaces should be mocked. 24 | // SrcDir is the only field which needs be specified. 25 | type Config struct { 26 | SrcDir string 27 | PkgName string 28 | Formatter string 29 | StubImpl bool 30 | SkipEnsure bool 31 | WithResets bool 32 | } 33 | 34 | // New makes a new Mocker for the specified package directory. 35 | func New(cfg Config) (*Mocker, error) { 36 | reg, err := registry.New(cfg.SrcDir, cfg.PkgName) 37 | if err != nil { 38 | return nil, err 39 | } 40 | 41 | tmpl, err := template.New() 42 | if err != nil { 43 | return nil, err 44 | } 45 | 46 | return &Mocker{ 47 | cfg: cfg, 48 | registry: reg, 49 | tmpl: tmpl, 50 | }, nil 51 | } 52 | 53 | // Mock generates a mock for the specified interface name. 54 | func (m *Mocker) Mock(w io.Writer, namePairs ...string) error { 55 | if len(namePairs) == 0 { 56 | return errors.New("must specify one interface") 57 | } 58 | 59 | mocks := make([]template.MockData, len(namePairs)) 60 | for i, np := range namePairs { 61 | name, mockName := parseInterfaceName(np) 62 | iface, tparams, err := m.registry.LookupInterface(name) 63 | if err != nil { 64 | return err 65 | } 66 | 67 | methods := make([]template.MethodData, iface.NumMethods()) 68 | for j := 0; j < iface.NumMethods(); j++ { 69 | methods[j] = m.methodData(iface.Method(j)) 70 | } 71 | 72 | mocks[i] = template.MockData{ 73 | InterfaceName: name, 74 | MockName: mockName, 75 | Methods: methods, 76 | TypeParams: m.typeParams(tparams), 77 | } 78 | } 79 | 80 | data := template.Data{ 81 | PkgName: m.mockPkgName(), 82 | Mocks: mocks, 83 | StubImpl: m.cfg.StubImpl, 84 | SkipEnsure: m.cfg.SkipEnsure, 85 | WithResets: m.cfg.WithResets, 86 | } 87 | 88 | if data.MocksSomeMethod() { 89 | m.registry.AddImport(types.NewPackage("sync", "sync")) 90 | } 91 | if m.registry.SrcPkgName() != m.mockPkgName() { 92 | data.SrcPkgQualifier = m.registry.SrcPkgName() + "." 93 | if !m.cfg.SkipEnsure { 94 | imprt := m.registry.AddImport(m.registry.SrcPkg()) 95 | data.SrcPkgQualifier = imprt.Qualifier() + "." 96 | } 97 | } 98 | 99 | data.Imports = m.registry.Imports() 100 | 101 | var buf bytes.Buffer 102 | if err := m.tmpl.Execute(&buf, data); err != nil { 103 | return err 104 | } 105 | 106 | formatted, err := m.format(buf.Bytes()) 107 | if err != nil { 108 | return err 109 | } 110 | 111 | if _, err := w.Write(formatted); err != nil { 112 | return err 113 | } 114 | return nil 115 | } 116 | 117 | func (m *Mocker) typeParams(tparams *types.TypeParamList) []template.TypeParamData { 118 | var tpd []template.TypeParamData 119 | if tparams == nil { 120 | return tpd 121 | } 122 | 123 | tpd = make([]template.TypeParamData, tparams.Len()) 124 | 125 | scope := m.registry.MethodScope() 126 | for i := 0; i < len(tpd); i++ { 127 | tp := tparams.At(i) 128 | typeParam := types.NewParam(token.Pos(i), tp.Obj().Pkg(), tp.Obj().Name(), tp.Constraint()) 129 | tpd[i] = template.TypeParamData{ 130 | ParamData: template.ParamData{Var: scope.AddVar(typeParam, "")}, 131 | Constraint: explicitConstraintType(typeParam), 132 | } 133 | } 134 | 135 | return tpd 136 | } 137 | 138 | func explicitConstraintType(typeParam *types.Var) (t types.Type) { 139 | underlying := typeParam.Type().Underlying().(*types.Interface) 140 | // check if any of the embedded types is either a basic type or a union, 141 | // because the generic type has to be an alias for one of those types then 142 | for j := 0; j < underlying.NumEmbeddeds(); j++ { 143 | t := underlying.EmbeddedType(j) 144 | switch t := t.(type) { 145 | case *types.Basic: 146 | return t 147 | case *types.Union: // only unions of basic types are allowed, so just take the first one as a valid type constraint 148 | return t.Term(0).Type() 149 | } 150 | } 151 | return nil 152 | } 153 | 154 | func (m *Mocker) methodData(f *types.Func) template.MethodData { 155 | sig := f.Type().(*types.Signature) 156 | 157 | scope := m.registry.MethodScope() 158 | n := sig.Params().Len() 159 | params := make([]template.ParamData, n) 160 | for i := 0; i < n; i++ { 161 | p := template.ParamData{ 162 | Var: scope.AddVar(sig.Params().At(i), ""), 163 | } 164 | p.Variadic = sig.Variadic() && i == n-1 && p.Var.IsSlice() // check for final variadic argument 165 | 166 | params[i] = p 167 | } 168 | 169 | n = sig.Results().Len() 170 | results := make([]template.ParamData, n) 171 | for i := 0; i < n; i++ { 172 | results[i] = template.ParamData{ 173 | Var: scope.AddVar(sig.Results().At(i), "Out"), 174 | } 175 | } 176 | 177 | return template.MethodData{ 178 | Name: f.Name(), 179 | Params: params, 180 | Returns: results, 181 | } 182 | } 183 | 184 | func (m *Mocker) mockPkgName() string { 185 | if m.cfg.PkgName != "" { 186 | return m.cfg.PkgName 187 | } 188 | 189 | return m.registry.SrcPkgName() 190 | } 191 | 192 | func (m *Mocker) format(src []byte) ([]byte, error) { 193 | switch m.cfg.Formatter { 194 | case "goimports": 195 | return goimports(src) 196 | 197 | case "noop": 198 | return src, nil 199 | } 200 | 201 | return gofmt(src) 202 | } 203 | 204 | func parseInterfaceName(namePair string) (ifaceName, mockName string) { 205 | parts := strings.SplitN(namePair, ":", 2) 206 | if len(parts) == 2 { 207 | return parts[0], parts[1] 208 | } 209 | 210 | ifaceName = parts[0] 211 | return ifaceName, ifaceName + "Mock" 212 | } 213 | -------------------------------------------------------------------------------- /pkg/moq/moq_modules_test.go: -------------------------------------------------------------------------------- 1 | // +build go1.11 2 | 3 | package moq 4 | 5 | import ( 6 | "bytes" 7 | "io" 8 | "io/ioutil" 9 | "os" 10 | "path/filepath" 11 | "strings" 12 | "testing" 13 | ) 14 | 15 | // copy copies srcPath to destPath, dirs and files 16 | func copy(srcPath, destPath string, item os.FileInfo) error { 17 | if item.IsDir() { 18 | if err := os.MkdirAll(destPath, os.FileMode(0750)); err != nil { 19 | return err 20 | } 21 | items, err := ioutil.ReadDir(srcPath) 22 | if err != nil { 23 | return err 24 | } 25 | for _, item := range items { 26 | src := filepath.Join(srcPath, item.Name()) 27 | dest := filepath.Join(destPath, item.Name()) 28 | if err := copy(src, dest, item); err != nil { 29 | return err 30 | } 31 | } 32 | } else { 33 | src, err := os.Open(srcPath) 34 | if err != nil { 35 | return err 36 | } 37 | defer src.Close() 38 | 39 | dest, err := os.Create(destPath) 40 | if err != nil { 41 | return err 42 | } 43 | defer dest.Close() 44 | 45 | _, err = io.Copy(dest, src) 46 | if err != nil { 47 | return err 48 | } 49 | } 50 | return nil 51 | } 52 | 53 | // copyTestPackage copies test package to a temporary directory 54 | func copyTestPackage(srcPath string) (string, error) { 55 | tmpDir, err := ioutil.TempDir("", "moq-tests") 56 | if err != nil { 57 | return "", err 58 | } 59 | 60 | info, err := os.Lstat(srcPath) 61 | if err != nil { 62 | return tmpDir, err 63 | } 64 | return tmpDir, copy(srcPath, tmpDir, info) 65 | } 66 | 67 | func TestModulesSamePackage(t *testing.T) { 68 | tmpDir, err := copyTestPackage("testpackages/modules") 69 | defer os.RemoveAll(tmpDir) 70 | if err != nil { 71 | t.Fatalf("Test package copy error: %s", err) 72 | } 73 | 74 | m, err := New(Config{SrcDir: tmpDir}) 75 | if err != nil { 76 | t.Fatalf("moq.New: %s", err) 77 | } 78 | var buf bytes.Buffer 79 | err = m.Mock(&buf, "Foo") 80 | if err != nil { 81 | t.Errorf("m.Mock: %s", err) 82 | } 83 | s := buf.String() 84 | if strings.Contains(s, `github.com/matryer/modules`) { 85 | t.Errorf("should not have cyclic dependency") 86 | } 87 | // assertions of things that should be mentioned 88 | var strs = []string{ 89 | "package simple", 90 | "var _ Foo = &FooMock{}", 91 | "type FooMock struct", 92 | } 93 | for _, str := range strs { 94 | if !strings.Contains(s, str) { 95 | t.Errorf("expected but missing: \"%s\"", str) 96 | } 97 | } 98 | } 99 | func TestModulesNestedPackage(t *testing.T) { 100 | tmpDir, err := copyTestPackage("testpackages/modules") 101 | defer os.RemoveAll(tmpDir) 102 | if err != nil { 103 | t.Fatalf("Test package copy error: %s", err) 104 | } 105 | 106 | m, err := New(Config{SrcDir: tmpDir, PkgName: "nested"}) 107 | if err != nil { 108 | t.Fatalf("moq.New: %s", err) 109 | } 110 | var buf bytes.Buffer 111 | err = m.Mock(&buf, "Foo") 112 | if err != nil { 113 | t.Errorf("m.Mock: %s", err) 114 | } 115 | s := buf.String() 116 | // assertions of things that should be mentioned 117 | var strs = []string{ 118 | "package nested", 119 | "github.com/matryer/modules", 120 | "var _ simple.Foo = &FooMock{}", 121 | "type FooMock struct", 122 | "func (mock *FooMock) FooIt(bar *simple.Bar) {", 123 | } 124 | for _, str := range strs { 125 | if !strings.Contains(s, str) { 126 | t.Errorf("expected but missing: \"%s\"", str) 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /pkg/moq/moq_test.go: -------------------------------------------------------------------------------- 1 | package moq 2 | 3 | import ( 4 | "bytes" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "strings" 12 | "testing" 13 | 14 | "github.com/pmezard/go-difflib/difflib" 15 | ) 16 | 17 | var update = flag.Bool("update", false, "Update golden files.") 18 | 19 | func TestMoq(t *testing.T) { 20 | m, err := New(Config{SrcDir: "testpackages/example"}) 21 | if err != nil { 22 | t.Fatalf("moq.New: %s", err) 23 | } 24 | var buf bytes.Buffer 25 | err = m.Mock(&buf, "PersonStore") 26 | if err != nil { 27 | t.Errorf("m.Mock: %s", err) 28 | } 29 | s := buf.String() 30 | // assertions of things that should be mentioned 31 | strs := []string{ 32 | "package example", 33 | "type PersonStoreMock struct", 34 | "CreateFunc func(ctx context.Context, person *Person, confirm bool) error", 35 | "GetFunc func(ctx context.Context, id string) (*Person, error)", 36 | "func (mock *PersonStoreMock) Create(ctx context.Context, person *Person, confirm bool) error", 37 | "func (mock *PersonStoreMock) Get(ctx context.Context, id string) (*Person, error)", 38 | "panic(\"PersonStoreMock.CreateFunc: method is nil but PersonStore.Create was just called\")", 39 | "panic(\"PersonStoreMock.GetFunc: method is nil but PersonStore.Get was just called\")", 40 | "mock.lockGet.Lock()", 41 | "mock.calls.Get = append(mock.calls.Get, callInfo)", 42 | "mock.lockGet.Unlock()", 43 | "// ID is the id argument value", 44 | } 45 | for _, str := range strs { 46 | if !strings.Contains(s, str) { 47 | t.Errorf("expected but missing: \"%s\"", str) 48 | } 49 | } 50 | } 51 | 52 | func TestMoqWithStaticCheck(t *testing.T) { 53 | m, err := New(Config{SrcDir: "testpackages/example"}) 54 | if err != nil { 55 | t.Fatalf("moq.New: %s", err) 56 | } 57 | var buf bytes.Buffer 58 | err = m.Mock(&buf, "PersonStore") 59 | if err != nil { 60 | t.Errorf("m.Mock: %s", err) 61 | } 62 | s := buf.String() 63 | // assertions of things that should be mentioned 64 | strs := []string{ 65 | "package example", 66 | "var _ PersonStore = &PersonStoreMock{}", 67 | "type PersonStoreMock struct", 68 | "CreateFunc func(ctx context.Context, person *Person, confirm bool) error", 69 | "GetFunc func(ctx context.Context, id string) (*Person, error)", 70 | "func (mock *PersonStoreMock) Create(ctx context.Context, person *Person, confirm bool) error", 71 | "func (mock *PersonStoreMock) Get(ctx context.Context, id string) (*Person, error)", 72 | "panic(\"PersonStoreMock.CreateFunc: method is nil but PersonStore.Create was just called\")", 73 | "panic(\"PersonStoreMock.GetFunc: method is nil but PersonStore.Get was just called\")", 74 | "mock.lockGet.Lock()", 75 | "mock.calls.Get = append(mock.calls.Get, callInfo)", 76 | "mock.lockGet.Unlock()", 77 | "// ID is the id argument value", 78 | } 79 | for _, str := range strs { 80 | if !strings.Contains(s, str) { 81 | t.Errorf("expected but missing: \"%s\"", str) 82 | } 83 | } 84 | } 85 | 86 | func TestMoqWithAlias(t *testing.T) { 87 | m, err := New(Config{SrcDir: "testpackages/example"}) 88 | if err != nil { 89 | t.Fatalf("moq.New: %s", err) 90 | } 91 | var buf bytes.Buffer 92 | err = m.Mock(&buf, "PersonStore:AnotherPersonStoreMock") 93 | if err != nil { 94 | t.Errorf("m.Mock: %s", err) 95 | } 96 | s := buf.String() 97 | // assertions of things that should be mentioned 98 | strs := []string{ 99 | "package example", 100 | "type AnotherPersonStoreMock struct", 101 | "CreateFunc func(ctx context.Context, person *Person, confirm bool) error", 102 | "GetFunc func(ctx context.Context, id string) (*Person, error)", 103 | "func (mock *AnotherPersonStoreMock) Create(ctx context.Context, person *Person, confirm bool) error", 104 | "func (mock *AnotherPersonStoreMock) Get(ctx context.Context, id string) (*Person, error)", 105 | "panic(\"AnotherPersonStoreMock.CreateFunc: method is nil but PersonStore.Create was just called\")", 106 | "panic(\"AnotherPersonStoreMock.GetFunc: method is nil but PersonStore.Get was just called\")", 107 | "mock.lockGet.Lock()", 108 | "mock.calls.Get = append(mock.calls.Get, callInfo)", 109 | "mock.lockGet.Unlock()", 110 | "// ID is the id argument value", 111 | } 112 | for _, str := range strs { 113 | if !strings.Contains(s, str) { 114 | t.Errorf("expected but missing: \"%s\"", str) 115 | } 116 | } 117 | } 118 | 119 | func TestMoqExplicitPackage(t *testing.T) { 120 | m, err := New(Config{SrcDir: "testpackages/example", PkgName: "different"}) 121 | if err != nil { 122 | t.Fatalf("moq.New: %s", err) 123 | } 124 | var buf bytes.Buffer 125 | err = m.Mock(&buf, "PersonStore") 126 | if err != nil { 127 | t.Errorf("m.Mock: %s", err) 128 | } 129 | s := buf.String() 130 | // assertions of things that should be mentioned 131 | strs := []string{ 132 | "package different", 133 | "type PersonStoreMock struct", 134 | "CreateFunc func(ctx context.Context, person *example.Person, confirm bool) error", 135 | "GetFunc func(ctx context.Context, id string) (*example.Person, error)", 136 | "func (mock *PersonStoreMock) Create(ctx context.Context, person *example.Person, confirm bool) error", 137 | "func (mock *PersonStoreMock) Get(ctx context.Context, id string) (*example.Person, error)", 138 | } 139 | for _, str := range strs { 140 | if !strings.Contains(s, str) { 141 | t.Errorf("expected but missing: \"%s\"", str) 142 | } 143 | } 144 | } 145 | 146 | func TestMoqExplicitPackageWithStaticCheck(t *testing.T) { 147 | m, err := New(Config{SrcDir: "testpackages/example", PkgName: "different"}) 148 | if err != nil { 149 | t.Fatalf("moq.New: %s", err) 150 | } 151 | var buf bytes.Buffer 152 | err = m.Mock(&buf, "PersonStore") 153 | if err != nil { 154 | t.Errorf("m.Mock: %s", err) 155 | } 156 | s := buf.String() 157 | // assertions of things that should be mentioned 158 | strs := []string{ 159 | "package different", 160 | "var _ example.PersonStore = &PersonStoreMock{}", 161 | "type PersonStoreMock struct", 162 | "CreateFunc func(ctx context.Context, person *example.Person, confirm bool) error", 163 | "GetFunc func(ctx context.Context, id string) (*example.Person, error)", 164 | "func (mock *PersonStoreMock) Create(ctx context.Context, person *example.Person, confirm bool) error", 165 | "func (mock *PersonStoreMock) Get(ctx context.Context, id string) (*example.Person, error)", 166 | } 167 | for _, str := range strs { 168 | if !strings.Contains(s, str) { 169 | t.Errorf("expected but missing: \"%s\"", str) 170 | } 171 | } 172 | } 173 | 174 | func TestMoqSkipEnsure(t *testing.T) { 175 | m, err := New(Config{SrcDir: "testpackages/example", PkgName: "different", SkipEnsure: true}) 176 | if err != nil { 177 | t.Fatalf("moq.New: %s", err) 178 | } 179 | var buf bytes.Buffer 180 | err = m.Mock(&buf, "PersonStore") 181 | if err != nil { 182 | t.Errorf("m.Mock: %s", err) 183 | } 184 | s := buf.String() 185 | // assertions of things that should be mentioned 186 | strs := []string{ 187 | "package different", 188 | "type PersonStoreMock struct", 189 | "CreateFunc func(ctx context.Context, person *example.Person, confirm bool) error", 190 | "GetFunc func(ctx context.Context, id string) (*example.Person, error)", 191 | "func (mock *PersonStoreMock) Create(ctx context.Context, person *example.Person, confirm bool) error", 192 | "func (mock *PersonStoreMock) Get(ctx context.Context, id string) (*example.Person, error)", 193 | } 194 | for _, str := range strs { 195 | if !strings.Contains(s, str) { 196 | t.Errorf("expected but missing: \"%s\"", str) 197 | } 198 | } 199 | } 200 | 201 | func TestNotCreatingEmptyDirWhenPkgIsGiven(t *testing.T) { 202 | m, err := New(Config{SrcDir: "testpackages/example", PkgName: "different"}) 203 | if err != nil { 204 | t.Fatalf("moq.New: %s", err) 205 | } 206 | var buf bytes.Buffer 207 | err = m.Mock(&buf, "PersonStore") 208 | if err != nil { 209 | t.Errorf("m.Mock: %s", err) 210 | } 211 | s := buf.String() 212 | if len(s) == 0 { 213 | t.Fatalf("mock should be generated") 214 | } 215 | if _, err := os.Stat("testpackages/example/different"); !os.IsNotExist(err) { 216 | t.Fatalf("no empty dir should be created by moq") 217 | } 218 | } 219 | 220 | // TestVariadicArguments tests to ensure variadic work as 221 | // expected. 222 | // see https://github.com/matryer/moq/issues/5 223 | func TestVariadicArguments(t *testing.T) { 224 | m, err := New(Config{SrcDir: "testpackages/variadic"}) 225 | if err != nil { 226 | t.Fatalf("moq.New: %s", err) 227 | } 228 | var buf bytes.Buffer 229 | err = m.Mock(&buf, "Greeter") 230 | if err != nil { 231 | t.Errorf("m.Mock: %s", err) 232 | } 233 | s := buf.String() 234 | // assertions of things that should be mentioned 235 | strs := []string{ 236 | "package variadic", 237 | "type GreeterMock struct", 238 | "GreetFunc func(ctx context.Context, names ...string) string", 239 | "return mock.GreetFunc(ctx, names...)", 240 | } 241 | for _, str := range strs { 242 | if !strings.Contains(s, str) { 243 | t.Errorf("expected but missing: \"%s\"", str) 244 | } 245 | } 246 | } 247 | 248 | func TestNothingToReturn(t *testing.T) { 249 | m, err := New(Config{SrcDir: "testpackages/example"}) 250 | if err != nil { 251 | t.Fatalf("moq.New: %s", err) 252 | } 253 | var buf bytes.Buffer 254 | err = m.Mock(&buf, "PersonStore") 255 | if err != nil { 256 | t.Errorf("m.Mock: %s", err) 257 | } 258 | s := buf.String() 259 | if strings.Contains(s, `return mock.ClearCacheFunc(id)`) { 260 | t.Errorf("should not have return for items that have no return arguments") 261 | } 262 | // assertions of things that should be mentioned 263 | strs := []string{ 264 | "mock.ClearCacheFunc(id)", 265 | } 266 | for _, str := range strs { 267 | if !strings.Contains(s, str) { 268 | t.Errorf("expected but missing: \"%s\"", str) 269 | } 270 | } 271 | } 272 | 273 | func TestImports(t *testing.T) { 274 | m, err := New(Config{SrcDir: "testpackages/imports/two"}) 275 | if err != nil { 276 | t.Fatalf("moq.New: %s", err) 277 | } 278 | var buf bytes.Buffer 279 | err = m.Mock(&buf, "DoSomething") 280 | if err != nil { 281 | t.Errorf("m.Mock: %s", err) 282 | } 283 | s := buf.String() 284 | strs := []string{ 285 | ` "sync"`, 286 | ` "github.com/matryer/moq/pkg/moq/testpackages/imports/one"`, 287 | } 288 | for _, str := range strs { 289 | if !strings.Contains(s, str) { 290 | t.Errorf("expected but missing: \"%s\"", str) 291 | } 292 | if len(strings.Split(s, str)) > 2 { 293 | t.Errorf("more than one: \"%s\"", str) 294 | } 295 | } 296 | } 297 | 298 | func TestMockGolden(t *testing.T) { 299 | cases := []struct { 300 | name string 301 | cfg Config 302 | interfaces []string 303 | goldenFile string 304 | }{ 305 | { 306 | // Tests to ensure slice return data type works as expected. 307 | // See https://github.com/matryer/moq/issues/124 308 | name: "SliceResult", 309 | cfg: Config{SrcDir: "testpackages/variadic"}, 310 | interfaces: []string{"Echoer"}, 311 | goldenFile: filepath.Join("testpackages/variadic", "echoer.golden.go"), 312 | }, 313 | { 314 | // Tests generation of mock where a method on the interface uses a 315 | // blank identifier. 316 | // See https://github.com/matryer/moq/issues/70 317 | name: "BlankID", 318 | cfg: Config{SrcDir: "testpackages/blankid"}, 319 | interfaces: []string{"Swallower"}, 320 | goldenFile: filepath.Join("testpackages/blankid", "swallower.golden.go"), 321 | }, 322 | { 323 | name: "ChannelNames", 324 | cfg: Config{SrcDir: "testpackages/channels", StubImpl: true}, 325 | interfaces: []string{"Queuer"}, 326 | goldenFile: filepath.Join("testpackages/channels", "queuer_moq.golden.go"), 327 | }, 328 | { 329 | // Tests generation of mock when the interface imports a different 330 | // package by the same name as it's own. 331 | // See https://github.com/matryer/moq/issues/94 332 | name: "PkgShadow", 333 | cfg: Config{SrcDir: "testpackages/shadow/http", PkgName: "mock"}, 334 | interfaces: []string{"Thing"}, 335 | goldenFile: filepath.Join("testpackages/shadow/mock", "thing_moq.golden.go"), 336 | }, 337 | { 338 | // Tests generation of mock when a method parameter shadows an 339 | // imported package name. 340 | name: "ParamShadow", 341 | cfg: Config{SrcDir: "testpackages/shadow"}, 342 | interfaces: []string{"Shadower"}, 343 | goldenFile: filepath.Join("testpackages/shadow", "shadower_moq.golden.go"), 344 | }, 345 | { 346 | name: "ImportAlias", 347 | cfg: Config{SrcDir: "testpackages/importalias"}, 348 | interfaces: []string{"MiddleMan"}, 349 | goldenFile: filepath.Join("testpackages/importalias", "middleman_moq.golden.go"), 350 | }, 351 | { 352 | // Tests conflict resolution for generated names of method 353 | // parameters. 354 | name: "ParamNameConflict", 355 | cfg: Config{SrcDir: "testpackages/paramconflict"}, 356 | interfaces: []string{"Interface"}, 357 | goldenFile: filepath.Join("testpackages/paramconflict", "iface_moq.golden.go"), 358 | }, 359 | { 360 | // Tests generation of names for unnamed method parameters. 361 | name: "GenerateParamNames", 362 | cfg: Config{SrcDir: "testpackages/genparamname"}, 363 | interfaces: []string{"Interface"}, 364 | goldenFile: filepath.Join("testpackages/genparamname", "iface_moq.golden.go"), 365 | }, 366 | { 367 | name: "SyncImport", 368 | cfg: Config{SrcDir: "testpackages/syncimport"}, 369 | interfaces: []string{"Syncer"}, 370 | goldenFile: filepath.Join("testpackages/syncimport", "syncer_moq.golden.go"), 371 | }, 372 | { 373 | // Tests anonymous imports are not included in the generated mock. 374 | name: "AnonymousImport", 375 | cfg: Config{SrcDir: "testpackages/anonimport"}, 376 | interfaces: []string{"Example"}, 377 | goldenFile: filepath.Join("testpackages/anonimport", "iface_moq.golden.go"), 378 | }, 379 | { 380 | name: "ShadowTypes", 381 | cfg: Config{SrcDir: "testpackages/shadowtypes"}, 382 | interfaces: []string{"ShadowTypes"}, 383 | goldenFile: filepath.Join("testpackages/shadowtypes", "shadowtypes_moq.golden.go"), 384 | }, 385 | { 386 | name: "Generics", 387 | cfg: Config{SrcDir: "testpackages/generics"}, 388 | interfaces: []string{"GenericStore1", "GenericStore2", "AliasStore"}, 389 | goldenFile: filepath.Join("testpackages/generics", "generics_moq.golden.go"), 390 | }, 391 | { 392 | name: "Generic Return Argument Type", 393 | cfg: Config{SrcDir: "testpackages/genericreturn"}, 394 | interfaces: []string{"IFooBar"}, 395 | goldenFile: filepath.Join("testpackages/genericreturn", "genericreturn.golden.go"), 396 | }, 397 | { 398 | name: "TransientImport", 399 | cfg: Config{SrcDir: "testpackages/transientimport"}, 400 | interfaces: []string{"Transient"}, 401 | goldenFile: filepath.Join("testpackages/transientimport", "transient_moq.golden.go"), 402 | }, 403 | { 404 | name: "WithResets", 405 | cfg: Config{SrcDir: "testpackages/withresets", WithResets: true}, 406 | interfaces: []string{"ResetStore", "ResetStoreGeneric"}, 407 | goldenFile: filepath.Join("testpackages/withresets", "withresets_moq.golden.go"), 408 | }, 409 | { 410 | name: "RangeNumber", 411 | cfg: Config{SrcDir: "testpackages/rangenum"}, 412 | interfaces: []string{"Magician"}, 413 | goldenFile: filepath.Join("testpackages/rangenum", "rangenum_moq.golden.go"), 414 | }, 415 | { 416 | name: "TypeAlias", 417 | cfg: Config{SrcDir: "testpackages/typealias"}, 418 | interfaces: []string{"Example"}, 419 | goldenFile: filepath.Join("testpackages/typealias", "typealias_moq.golden.go"), 420 | }, 421 | } 422 | for _, tc := range cases { 423 | t.Run(tc.name, func(t *testing.T) { 424 | m, err := New(tc.cfg) 425 | if err != nil { 426 | t.Fatalf("moq.New: %s", err) 427 | } 428 | 429 | var buf bytes.Buffer 430 | if err = m.Mock(&buf, tc.interfaces...); err != nil { 431 | t.Errorf("m.Mock: %s", err) 432 | return 433 | } 434 | 435 | if err := matchGoldenFile(tc.goldenFile, buf.Bytes()); err != nil { 436 | t.Errorf("check golden file: %s", err) 437 | } 438 | }) 439 | } 440 | } 441 | 442 | func TestFormatter(t *testing.T) { 443 | cases := []struct { 444 | name string 445 | conf Config 446 | }{ 447 | {name: "gofmt", conf: Config{SrcDir: "testpackages/imports/two"}}, 448 | {name: "goimports", conf: Config{SrcDir: "testpackages/imports/two", Formatter: "goimports"}}, 449 | {name: "noop", conf: Config{SrcDir: "testpackages/imports/two", Formatter: "noop"}}, 450 | } 451 | for _, tc := range cases { 452 | t.Run(tc.name, func(t *testing.T) { 453 | m, err := New(tc.conf) 454 | if err != nil { 455 | t.Fatalf("moq.New: %s", err) 456 | } 457 | var buf bytes.Buffer 458 | err = m.Mock(&buf, "DoSomething:"+tc.name+"Mock") 459 | if err != nil { 460 | t.Errorf("m.Mock: %s", err) 461 | } 462 | 463 | golden := filepath.Join("testpackages/imports/two", tc.name+".golden.go") 464 | if err := matchGoldenFile(golden, buf.Bytes()); err != nil { 465 | t.Errorf("check golden file: %s", err) 466 | } 467 | }) 468 | } 469 | } 470 | 471 | func matchGoldenFile(goldenFile string, actual []byte) error { 472 | // To update golden files, run the following: 473 | // go test -v -run '^$' github.com/matryer/moq/pkg/moq -update 474 | if *update { 475 | if err := os.MkdirAll(filepath.Dir(goldenFile), 0o750); err != nil { 476 | return fmt.Errorf("create dir: %s", err) 477 | } 478 | if err := os.WriteFile(goldenFile, actual, 0o600); err != nil { 479 | return fmt.Errorf("write: %s", err) 480 | } 481 | 482 | return nil 483 | } 484 | 485 | expected, err := os.ReadFile(goldenFile) 486 | if err != nil { 487 | return fmt.Errorf("read: %s: %s", goldenFile, err) 488 | } 489 | 490 | // Normalise newlines 491 | actual, expected = normalize(actual), normalize(expected) 492 | if !bytes.Equal(expected, actual) { 493 | diff, err := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ 494 | A: difflib.SplitLines(string(expected)), 495 | B: difflib.SplitLines(string(actual)), 496 | FromFile: "Expected", 497 | ToFile: "Actual", 498 | Context: 1, 499 | }) 500 | if err != nil { 501 | return fmt.Errorf("diff: %s", err) 502 | } 503 | return fmt.Errorf("match: %s:\n%s", goldenFile, diff) 504 | } 505 | 506 | return nil 507 | } 508 | 509 | func TestVendoredPackages(t *testing.T) { 510 | m, err := New(Config{SrcDir: "testpackages/vendoring/user"}) 511 | if err != nil { 512 | t.Fatalf("moq.New: %s", err) 513 | } 514 | var buf bytes.Buffer 515 | err = m.Mock(&buf, "Service") 516 | if err != nil { 517 | t.Errorf("mock error: %s", err) 518 | } 519 | s := buf.String() 520 | // assertions of things that should be mentioned 521 | strs := []string{ 522 | `"github.com/sudo-suhas/moq-test-pkgs/somerepo"`, 523 | } 524 | for _, str := range strs { 525 | if !strings.Contains(s, str) { 526 | t.Errorf("expected but missing: \"%s\"", str) 527 | } 528 | } 529 | } 530 | 531 | func TestVendoredInterface(t *testing.T) { 532 | m, err := New(Config{ 533 | SrcDir: "testpackages/vendoring/vendor/github.com/sudo-suhas/moq-test-pkgs/somerepo", 534 | PkgName: "someother", 535 | }) 536 | if err != nil { 537 | t.Fatalf("moq.New: %s", err) 538 | } 539 | var buf bytes.Buffer 540 | err = m.Mock(&buf, "SomeService") 541 | if err != nil { 542 | t.Errorf("mock error: %s", err) 543 | } 544 | s := buf.String() 545 | // assertions of things that should be mentioned 546 | strs := []string{ 547 | `"github.com/sudo-suhas/moq-test-pkgs/somerepo"`, 548 | } 549 | for _, str := range strs { 550 | if !strings.Contains(s, str) { 551 | t.Errorf("expected but missing: \"%s\"", str) 552 | } 553 | } 554 | incorrectImport := `"github.com/matryer/moq/pkg/moq/testpackages/vendoring/vendor/github.com/sudo-suhas/moq-test-pkgs/somerepo"` 555 | if strings.Contains(s, incorrectImport) { 556 | t.Errorf("unexpected import: %s", incorrectImport) 557 | } 558 | } 559 | 560 | func TestVendoredBuildConstraints(t *testing.T) { 561 | m, err := New(Config{SrcDir: "testpackages/buildconstraints/user"}) 562 | if err != nil { 563 | t.Fatalf("moq.New: %s", err) 564 | } 565 | var buf bytes.Buffer 566 | err = m.Mock(&buf, "Service") 567 | if err != nil { 568 | t.Errorf("mock error: %s", err) 569 | } 570 | s := buf.String() 571 | // assertions of things that should be mentioned 572 | strs := []string{ 573 | `"github.com/sudo-suhas/moq-test-pkgs/buildconstraints"`, 574 | } 575 | for _, str := range strs { 576 | if !strings.Contains(s, str) { 577 | t.Errorf("expected but missing: \"%s\"", str) 578 | } 579 | } 580 | } 581 | 582 | // TestDotImports tests for https://github.com/matryer/moq/issues/21. 583 | func TestDotImports(t *testing.T) { 584 | preDir, err := os.Getwd() 585 | if err != nil { 586 | t.Errorf("Getwd: %s", err) 587 | } 588 | err = os.Chdir("testpackages/dotimport") 589 | if err != nil { 590 | t.Errorf("Chdir: %s", err) 591 | } 592 | defer func() { 593 | err := os.Chdir(preDir) 594 | if err != nil { 595 | t.Errorf("Chdir back: %s", err) 596 | } 597 | }() 598 | m, err := New(Config{SrcDir: ".", PkgName: "moqtest_test"}) 599 | if err != nil { 600 | t.Fatalf("moq.New: %s", err) 601 | } 602 | var buf bytes.Buffer 603 | err = m.Mock(&buf, "Service") 604 | if err != nil { 605 | t.Errorf("mock error: %s", err) 606 | } 607 | s := buf.String() 608 | if strings.Contains(s, `"."`) { 609 | t.Error("contains invalid dot import") 610 | } 611 | } 612 | 613 | func TestEmptyInterface(t *testing.T) { 614 | m, err := New(Config{SrcDir: "testpackages/emptyinterface"}) 615 | if err != nil { 616 | t.Fatalf("moq.New: %s", err) 617 | } 618 | var buf bytes.Buffer 619 | err = m.Mock(&buf, "Empty") 620 | if err != nil { 621 | t.Errorf("mock error: %s", err) 622 | } 623 | s := buf.String() 624 | if strings.Contains(s, `"sync"`) { 625 | t.Error("contains sync import, although this package isn't used") 626 | } 627 | } 628 | 629 | func TestGoGenerateVendoredPackages(t *testing.T) { 630 | cmd := exec.Command("go", "generate", "./...") 631 | cmd.Dir = "testpackages/gogenvendoring" 632 | stdout, err := cmd.StdoutPipe() 633 | if err != nil { 634 | t.Errorf("StdoutPipe: %s", err) 635 | } 636 | defer stdout.Close() 637 | err = cmd.Start() 638 | if err != nil { 639 | t.Errorf("Start: %s", err) 640 | } 641 | buf := bytes.NewBuffer(nil) 642 | io.Copy(buf, stdout) 643 | err = cmd.Wait() 644 | if err != nil { 645 | if exitErr, ok := err.(*exec.ExitError); ok { 646 | t.Errorf("Wait: %s %s", exitErr, string(exitErr.Stderr)) 647 | } else { 648 | t.Errorf("Wait: %s", err) 649 | } 650 | } 651 | s := buf.String() 652 | if strings.Contains(s, `vendor/`) { 653 | t.Error("contains vendor directory in import path") 654 | } 655 | } 656 | 657 | func TestImportedPackageWithSameName(t *testing.T) { 658 | m, err := New(Config{SrcDir: "testpackages/samenameimport"}) 659 | if err != nil { 660 | t.Fatalf("moq.New: %s", err) 661 | } 662 | var buf bytes.Buffer 663 | err = m.Mock(&buf, "Example") 664 | if err != nil { 665 | t.Errorf("mock error: %s", err) 666 | } 667 | s := buf.String() 668 | if !strings.Contains(s, `a samename.A`) { 669 | t.Error("missing samename.A to address the struct A from the external package samename") 670 | } 671 | } 672 | 673 | func TestParseError(t *testing.T) { 674 | _, err := New(Config{SrcDir: "testpackages/_parseerror/service"}) 675 | if err == nil { 676 | t.Errorf("expected error but got nil") 677 | return 678 | } 679 | // The first clause is the common error. Only in go version 1.19.10 the error differs 680 | if !strings.Contains(err.Error(), `could not import github.com/matryer/notexist (invalid package name: "")`) && !strings.Contains(err.Error(), "stderr: go build github.com/matryer/notexist") { 681 | t.Errorf("unexpected error: %s", err.Error()) 682 | } 683 | } 684 | 685 | func TestMockError(t *testing.T) { 686 | m, err := New(Config{SrcDir: "testpackages/example"}) 687 | if err != nil { 688 | t.Fatalf("moq.New: %s", err) 689 | } 690 | cases := []struct { 691 | name string 692 | namePair string 693 | wantErr string 694 | }{ 695 | { 696 | name: "TypeNotFound", 697 | namePair: "DoesNotExist", 698 | wantErr: "interface not found: DoesNotExist", 699 | }, 700 | { 701 | name: "UnexpectedType", 702 | namePair: "Person", 703 | wantErr: "Person (github.com/matryer/moq/pkg/moq/testpackages/example.Person) is not an interface", 704 | }, 705 | } 706 | for _, tc := range cases { 707 | t.Run(tc.name, func(t *testing.T) { 708 | err := m.Mock(io.Discard, tc.namePair) 709 | if err == nil { 710 | t.Errorf("expected error but got nil") 711 | return 712 | } 713 | if !strings.Contains(err.Error(), tc.wantErr) { 714 | t.Errorf("unexpected error: %s", err.Error()) 715 | } 716 | }) 717 | } 718 | } 719 | 720 | // normalize normalizes \r\n (windows) and \r (mac) 721 | // into \n (unix) 722 | func normalize(d []byte) []byte { 723 | // Source: https://www.programming-books.io/essential/go/normalize-newlines-1d3abcf6f17c4186bb9617fa14074e48 724 | // replace CR LF \r\n (windows) with LF \n (unix) 725 | d = bytes.Replace(d, []byte{13, 10}, []byte{10}, -1) 726 | // replace CF \r (mac) with LF \n (unix) 727 | d = bytes.Replace(d, []byte{13}, []byte{10}, -1) 728 | return d 729 | } 730 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/_parseerror/service/service.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import "github.com/matryer/notexist" 4 | 5 | // Service does something good with computers. 6 | type Service interface { 7 | DoSomething(notexist.SomeType) error 8 | } 9 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/anonimport/iface.go: -------------------------------------------------------------------------------- 1 | package anonimport 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | // Example is a test interface. 8 | type Example interface { 9 | Ctx(ctx context.Context) 10 | } 11 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/anonimport/iface_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package anonimport 5 | 6 | import ( 7 | "context" 8 | "sync" 9 | ) 10 | 11 | // Ensure, that ExampleMock does implement Example. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ Example = &ExampleMock{} 14 | 15 | // ExampleMock is a mock implementation of Example. 16 | // 17 | // func TestSomethingThatUsesExample(t *testing.T) { 18 | // 19 | // // make and configure a mocked Example 20 | // mockedExample := &ExampleMock{ 21 | // CtxFunc: func(ctx context.Context) { 22 | // panic("mock out the Ctx method") 23 | // }, 24 | // } 25 | // 26 | // // use mockedExample in code that requires Example 27 | // // and then make assertions. 28 | // 29 | // } 30 | type ExampleMock struct { 31 | // CtxFunc mocks the Ctx method. 32 | CtxFunc func(ctx context.Context) 33 | 34 | // calls tracks calls to the methods. 35 | calls struct { 36 | // Ctx holds details about calls to the Ctx method. 37 | Ctx []struct { 38 | // Ctx is the ctx argument value. 39 | Ctx context.Context 40 | } 41 | } 42 | lockCtx sync.RWMutex 43 | } 44 | 45 | // Ctx calls CtxFunc. 46 | func (mock *ExampleMock) Ctx(ctx context.Context) { 47 | if mock.CtxFunc == nil { 48 | panic("ExampleMock.CtxFunc: method is nil but Example.Ctx was just called") 49 | } 50 | callInfo := struct { 51 | Ctx context.Context 52 | }{ 53 | Ctx: ctx, 54 | } 55 | mock.lockCtx.Lock() 56 | mock.calls.Ctx = append(mock.calls.Ctx, callInfo) 57 | mock.lockCtx.Unlock() 58 | mock.CtxFunc(ctx) 59 | } 60 | 61 | // CtxCalls gets all the calls that were made to Ctx. 62 | // Check the length with: 63 | // 64 | // len(mockedExample.CtxCalls()) 65 | func (mock *ExampleMock) CtxCalls() []struct { 66 | Ctx context.Context 67 | } { 68 | var calls []struct { 69 | Ctx context.Context 70 | } 71 | mock.lockCtx.RLock() 72 | calls = mock.calls.Ctx 73 | mock.lockCtx.RUnlock() 74 | return calls 75 | } 76 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/anonimport/second_file.go: -------------------------------------------------------------------------------- 1 | package anonimport 2 | 3 | import ( 4 | _ "context" // import for side effects 5 | ) 6 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/blankid/swallower.go: -------------------------------------------------------------------------------- 1 | package blankid 2 | 3 | // Swallower is a test interface. 4 | type Swallower interface { 5 | Swallow(_ string) 6 | } 7 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/blankid/swallower.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package blankid 5 | 6 | import ( 7 | "sync" 8 | ) 9 | 10 | // Ensure, that SwallowerMock does implement Swallower. 11 | // If this is not the case, regenerate this file with moq. 12 | var _ Swallower = &SwallowerMock{} 13 | 14 | // SwallowerMock is a mock implementation of Swallower. 15 | // 16 | // func TestSomethingThatUsesSwallower(t *testing.T) { 17 | // 18 | // // make and configure a mocked Swallower 19 | // mockedSwallower := &SwallowerMock{ 20 | // SwallowFunc: func(s string) { 21 | // panic("mock out the Swallow method") 22 | // }, 23 | // } 24 | // 25 | // // use mockedSwallower in code that requires Swallower 26 | // // and then make assertions. 27 | // 28 | // } 29 | type SwallowerMock struct { 30 | // SwallowFunc mocks the Swallow method. 31 | SwallowFunc func(s string) 32 | 33 | // calls tracks calls to the methods. 34 | calls struct { 35 | // Swallow holds details about calls to the Swallow method. 36 | Swallow []struct { 37 | // S is the s argument value. 38 | S string 39 | } 40 | } 41 | lockSwallow sync.RWMutex 42 | } 43 | 44 | // Swallow calls SwallowFunc. 45 | func (mock *SwallowerMock) Swallow(s string) { 46 | if mock.SwallowFunc == nil { 47 | panic("SwallowerMock.SwallowFunc: method is nil but Swallower.Swallow was just called") 48 | } 49 | callInfo := struct { 50 | S string 51 | }{ 52 | S: s, 53 | } 54 | mock.lockSwallow.Lock() 55 | mock.calls.Swallow = append(mock.calls.Swallow, callInfo) 56 | mock.lockSwallow.Unlock() 57 | mock.SwallowFunc(s) 58 | } 59 | 60 | // SwallowCalls gets all the calls that were made to Swallow. 61 | // Check the length with: 62 | // 63 | // len(mockedSwallower.SwallowCalls()) 64 | func (mock *SwallowerMock) SwallowCalls() []struct { 65 | S string 66 | } { 67 | var calls []struct { 68 | S string 69 | } 70 | mock.lockSwallow.RLock() 71 | calls = mock.calls.Swallow 72 | mock.lockSwallow.RUnlock() 73 | return calls 74 | } 75 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/buildconstraints/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/matryer/moq/pkg/moq/testpackages/buildconstraints 2 | 3 | go 1.14 4 | 5 | require github.com/sudo-suhas/moq-test-pkgs/buildconstraints v0.0.0-20200816045313-d2f573eea6c7 6 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/buildconstraints/go.sum: -------------------------------------------------------------------------------- 1 | github.com/sudo-suhas/moq-test-pkgs v0.0.0-20200816045313-d2f573eea6c7 h1:Nrz0lKzL7rEBWiclll8DLmBAuPZxMdJTe3UHzPOUkgg= 2 | github.com/sudo-suhas/moq-test-pkgs/buildconstraints v0.0.0-20200816045313-d2f573eea6c7 h1:/GmPJhGa5xWMHHdGZ7K5MNM6prYeSnlSUeExdNg62bk= 3 | github.com/sudo-suhas/moq-test-pkgs/buildconstraints v0.0.0-20200816045313-d2f573eea6c7/go.mod h1:3SKj4JbVOiJQrGo/HyVTyp+jKwC8eIIDtOaK4L5RZNE= 4 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/buildconstraints/user/user.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import "github.com/sudo-suhas/moq-test-pkgs/buildconstraints" 4 | 5 | // Service does something good with computers. 6 | type Service interface { 7 | DoSomething(buildconstraints.SomeType) error 8 | } 9 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/buildconstraints/vendor/github.com/sudo-suhas/moq-test-pkgs/buildconstraints/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/sudo-suhas/moq-test-pkgs/buildconstraints 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/buildconstraints/vendor/github.com/sudo-suhas/moq-test-pkgs/buildconstraints/go17.go: -------------------------------------------------------------------------------- 1 | // +build go1.7 2 | 3 | package buildconstraints 4 | 5 | var someVariable = "Value 1" 6 | 7 | // SomeType is just some old type. 8 | type SomeType struct { 9 | // Truth indicates whether true is true or not. Computers. 10 | Truth bool 11 | } 12 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/buildconstraints/vendor/github.com/sudo-suhas/moq-test-pkgs/buildconstraints/pre_go17.go: -------------------------------------------------------------------------------- 1 | // +build !go1.7 2 | 3 | package buildconstraints 4 | 5 | var someVariable = "Value 2" 6 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/buildconstraints/vendor/modules.txt: -------------------------------------------------------------------------------- 1 | # github.com/sudo-suhas/moq-test-pkgs/buildconstraints v0.0.0-20200816045313-d2f573eea6c7 2 | ## explicit 3 | github.com/sudo-suhas/moq-test-pkgs/buildconstraints 4 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/channels/example.go: -------------------------------------------------------------------------------- 1 | package channels 2 | 3 | // Queue is a type to be sent down a channel. 4 | type Queue []string 5 | 6 | // Queuer provides a channel example. 7 | type Queuer interface { 8 | Sub(topic string) (<-chan Queue, error) 9 | Unsub(topic string) 10 | } 11 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/channels/queuer_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package channels 5 | 6 | import ( 7 | "sync" 8 | ) 9 | 10 | // Ensure, that QueuerMock does implement Queuer. 11 | // If this is not the case, regenerate this file with moq. 12 | var _ Queuer = &QueuerMock{} 13 | 14 | // QueuerMock is a mock implementation of Queuer. 15 | // 16 | // func TestSomethingThatUsesQueuer(t *testing.T) { 17 | // 18 | // // make and configure a mocked Queuer 19 | // mockedQueuer := &QueuerMock{ 20 | // SubFunc: func(topic string) (<-chan Queue, error) { 21 | // panic("mock out the Sub method") 22 | // }, 23 | // UnsubFunc: func(topic string) { 24 | // panic("mock out the Unsub method") 25 | // }, 26 | // } 27 | // 28 | // // use mockedQueuer in code that requires Queuer 29 | // // and then make assertions. 30 | // 31 | // } 32 | type QueuerMock struct { 33 | // SubFunc mocks the Sub method. 34 | SubFunc func(topic string) (<-chan Queue, error) 35 | 36 | // UnsubFunc mocks the Unsub method. 37 | UnsubFunc func(topic string) 38 | 39 | // calls tracks calls to the methods. 40 | calls struct { 41 | // Sub holds details about calls to the Sub method. 42 | Sub []struct { 43 | // Topic is the topic argument value. 44 | Topic string 45 | } 46 | // Unsub holds details about calls to the Unsub method. 47 | Unsub []struct { 48 | // Topic is the topic argument value. 49 | Topic string 50 | } 51 | } 52 | lockSub sync.RWMutex 53 | lockUnsub sync.RWMutex 54 | } 55 | 56 | // Sub calls SubFunc. 57 | func (mock *QueuerMock) Sub(topic string) (<-chan Queue, error) { 58 | callInfo := struct { 59 | Topic string 60 | }{ 61 | Topic: topic, 62 | } 63 | mock.lockSub.Lock() 64 | mock.calls.Sub = append(mock.calls.Sub, callInfo) 65 | mock.lockSub.Unlock() 66 | if mock.SubFunc == nil { 67 | var ( 68 | queueChOut <-chan Queue 69 | errOut error 70 | ) 71 | return queueChOut, errOut 72 | } 73 | return mock.SubFunc(topic) 74 | } 75 | 76 | // SubCalls gets all the calls that were made to Sub. 77 | // Check the length with: 78 | // 79 | // len(mockedQueuer.SubCalls()) 80 | func (mock *QueuerMock) SubCalls() []struct { 81 | Topic string 82 | } { 83 | var calls []struct { 84 | Topic string 85 | } 86 | mock.lockSub.RLock() 87 | calls = mock.calls.Sub 88 | mock.lockSub.RUnlock() 89 | return calls 90 | } 91 | 92 | // Unsub calls UnsubFunc. 93 | func (mock *QueuerMock) Unsub(topic string) { 94 | callInfo := struct { 95 | Topic string 96 | }{ 97 | Topic: topic, 98 | } 99 | mock.lockUnsub.Lock() 100 | mock.calls.Unsub = append(mock.calls.Unsub, callInfo) 101 | mock.lockUnsub.Unlock() 102 | if mock.UnsubFunc == nil { 103 | return 104 | } 105 | mock.UnsubFunc(topic) 106 | } 107 | 108 | // UnsubCalls gets all the calls that were made to Unsub. 109 | // Check the length with: 110 | // 111 | // len(mockedQueuer.UnsubCalls()) 112 | func (mock *QueuerMock) UnsubCalls() []struct { 113 | Topic string 114 | } { 115 | var calls []struct { 116 | Topic string 117 | } 118 | mock.lockUnsub.RLock() 119 | calls = mock.calls.Unsub 120 | mock.lockUnsub.RUnlock() 121 | return calls 122 | } 123 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/dotimport/service.go: -------------------------------------------------------------------------------- 1 | // Package dotimport addresses issue 21. 2 | package dotimport 3 | 4 | //go:generate moq -out service_moq_test.go -pkg dotimport_test . Service 5 | 6 | // Service is the interface which should be mocked by moq 7 | type Service interface { 8 | User(ID string) (User, error) 9 | } 10 | 11 | // User is just a struct for testing 12 | type User struct { 13 | Name string 14 | } 15 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/dotimport/service_moq_test.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package dotimport_test 5 | 6 | import ( 7 | "github.com/matryer/moq/pkg/moq/testpackages/dotimport" 8 | "sync" 9 | ) 10 | 11 | // Ensure, that ServiceMock does implement dotimport.Service. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ dotimport.Service = &ServiceMock{} 14 | 15 | // ServiceMock is a mock implementation of dotimport.Service. 16 | // 17 | // func TestSomethingThatUsesService(t *testing.T) { 18 | // 19 | // // make and configure a mocked dotimport.Service 20 | // mockedService := &ServiceMock{ 21 | // UserFunc: func(ID string) (dotimport.User, error) { 22 | // panic("mock out the User method") 23 | // }, 24 | // } 25 | // 26 | // // use mockedService in code that requires dotimport.Service 27 | // // and then make assertions. 28 | // 29 | // } 30 | type ServiceMock struct { 31 | // UserFunc mocks the User method. 32 | UserFunc func(ID string) (dotimport.User, error) 33 | 34 | // calls tracks calls to the methods. 35 | calls struct { 36 | // User holds details about calls to the User method. 37 | User []struct { 38 | // ID is the ID argument value. 39 | ID string 40 | } 41 | } 42 | lockUser sync.RWMutex 43 | } 44 | 45 | // User calls UserFunc. 46 | func (mock *ServiceMock) User(ID string) (dotimport.User, error) { 47 | if mock.UserFunc == nil { 48 | panic("ServiceMock.UserFunc: method is nil but Service.User was just called") 49 | } 50 | callInfo := struct { 51 | ID string 52 | }{ 53 | ID: ID, 54 | } 55 | mock.lockUser.Lock() 56 | mock.calls.User = append(mock.calls.User, callInfo) 57 | mock.lockUser.Unlock() 58 | return mock.UserFunc(ID) 59 | } 60 | 61 | // UserCalls gets all the calls that were made to User. 62 | // Check the length with: 63 | // 64 | // len(mockedService.UserCalls()) 65 | func (mock *ServiceMock) UserCalls() []struct { 66 | ID string 67 | } { 68 | var calls []struct { 69 | ID string 70 | } 71 | mock.lockUser.RLock() 72 | calls = mock.calls.User 73 | mock.lockUser.RUnlock() 74 | return calls 75 | } 76 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/emptyinterface/empty.go: -------------------------------------------------------------------------------- 1 | package emptyinterface 2 | 3 | // Empty is an empty interface 4 | type Empty interface{} 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/example/example.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import "context" 4 | 5 | // Person is a person. 6 | type Person struct { 7 | ID string 8 | Name string 9 | Company string 10 | Website string 11 | } 12 | 13 | // PersonStore stores people. 14 | type PersonStore interface { 15 | Get(ctx context.Context, id string) (*Person, error) 16 | Create(ctx context.Context, person *Person, confirm bool) error 17 | ClearCache(id string) 18 | } 19 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/genericreturn/genericreturn.go: -------------------------------------------------------------------------------- 1 | package genericreturn 2 | 3 | import "github.com/matryer/moq/pkg/moq/testpackages/genericreturn/otherpackage" 4 | 5 | // GenericBar is a test type. 6 | type GenericBar[T any] struct { 7 | Bar T 8 | } 9 | 10 | // IFooBar is a test interface. 11 | type IFooBar interface { 12 | Foobar() GenericBar[otherpackage.Foo] 13 | } 14 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/genericreturn/genericreturn.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package genericreturn 5 | 6 | import ( 7 | "github.com/matryer/moq/pkg/moq/testpackages/genericreturn/otherpackage" 8 | "sync" 9 | ) 10 | 11 | // Ensure, that IFooBarMock does implement IFooBar. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ IFooBar = &IFooBarMock{} 14 | 15 | // IFooBarMock is a mock implementation of IFooBar. 16 | // 17 | // func TestSomethingThatUsesIFooBar(t *testing.T) { 18 | // 19 | // // make and configure a mocked IFooBar 20 | // mockedIFooBar := &IFooBarMock{ 21 | // FoobarFunc: func() GenericBar[otherpackage.Foo] { 22 | // panic("mock out the Foobar method") 23 | // }, 24 | // } 25 | // 26 | // // use mockedIFooBar in code that requires IFooBar 27 | // // and then make assertions. 28 | // 29 | // } 30 | type IFooBarMock struct { 31 | // FoobarFunc mocks the Foobar method. 32 | FoobarFunc func() GenericBar[otherpackage.Foo] 33 | 34 | // calls tracks calls to the methods. 35 | calls struct { 36 | // Foobar holds details about calls to the Foobar method. 37 | Foobar []struct { 38 | } 39 | } 40 | lockFoobar sync.RWMutex 41 | } 42 | 43 | // Foobar calls FoobarFunc. 44 | func (mock *IFooBarMock) Foobar() GenericBar[otherpackage.Foo] { 45 | if mock.FoobarFunc == nil { 46 | panic("IFooBarMock.FoobarFunc: method is nil but IFooBar.Foobar was just called") 47 | } 48 | callInfo := struct { 49 | }{} 50 | mock.lockFoobar.Lock() 51 | mock.calls.Foobar = append(mock.calls.Foobar, callInfo) 52 | mock.lockFoobar.Unlock() 53 | return mock.FoobarFunc() 54 | } 55 | 56 | // FoobarCalls gets all the calls that were made to Foobar. 57 | // Check the length with: 58 | // 59 | // len(mockedIFooBar.FoobarCalls()) 60 | func (mock *IFooBarMock) FoobarCalls() []struct { 61 | } { 62 | var calls []struct { 63 | } 64 | mock.lockFoobar.RLock() 65 | calls = mock.calls.Foobar 66 | mock.lockFoobar.RUnlock() 67 | return calls 68 | } 69 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/genericreturn/otherpackage/otherpackage.go: -------------------------------------------------------------------------------- 1 | package otherpackage 2 | 3 | // Foo is a test struct. 4 | type Foo struct { 5 | A int 6 | B string 7 | } 8 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/generics/generics.go: -------------------------------------------------------------------------------- 1 | package generics 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | ) 7 | 8 | // GenericStore1 is a test interface. 9 | type GenericStore1[T Key1, S any] interface { 10 | Get(ctx context.Context, id T) (S, error) 11 | Create(ctx context.Context, id T, value S) error 12 | } 13 | 14 | // GenericStore2 is a test interface. 15 | type GenericStore2[T Key2, S any] interface { 16 | Get(ctx context.Context, id T) (S, error) 17 | Create(ctx context.Context, id T, value S) error 18 | } 19 | 20 | // AliasStore is a test interface. 21 | type AliasStore GenericStore1[KeyImpl, bool] 22 | 23 | // Key1 is a test interface. 24 | type Key1 interface { 25 | fmt.Stringer 26 | } 27 | 28 | // Key2 is a test interface. 29 | type Key2 interface { 30 | ~[]byte | string 31 | } 32 | 33 | // KeyImpl is a test type. 34 | type KeyImpl []byte 35 | 36 | func (x KeyImpl) String() string { 37 | return string(x) 38 | } 39 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/generics/generics_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package generics 5 | 6 | import ( 7 | "context" 8 | "sync" 9 | ) 10 | 11 | // Ensure, that GenericStore1Mock does implement GenericStore1. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ GenericStore1[Key1, any] = &GenericStore1Mock[Key1, any]{} 14 | 15 | // GenericStore1Mock is a mock implementation of GenericStore1. 16 | // 17 | // func TestSomethingThatUsesGenericStore1(t *testing.T) { 18 | // 19 | // // make and configure a mocked GenericStore1 20 | // mockedGenericStore1 := &GenericStore1Mock{ 21 | // CreateFunc: func(ctx context.Context, id T, value S) error { 22 | // panic("mock out the Create method") 23 | // }, 24 | // GetFunc: func(ctx context.Context, id T) (S, error) { 25 | // panic("mock out the Get method") 26 | // }, 27 | // } 28 | // 29 | // // use mockedGenericStore1 in code that requires GenericStore1 30 | // // and then make assertions. 31 | // 32 | // } 33 | type GenericStore1Mock[T Key1, S any] struct { 34 | // CreateFunc mocks the Create method. 35 | CreateFunc func(ctx context.Context, id T, value S) error 36 | 37 | // GetFunc mocks the Get method. 38 | GetFunc func(ctx context.Context, id T) (S, error) 39 | 40 | // calls tracks calls to the methods. 41 | calls struct { 42 | // Create holds details about calls to the Create method. 43 | Create []struct { 44 | // Ctx is the ctx argument value. 45 | Ctx context.Context 46 | // ID is the id argument value. 47 | ID T 48 | // Value is the value argument value. 49 | Value S 50 | } 51 | // Get holds details about calls to the Get method. 52 | Get []struct { 53 | // Ctx is the ctx argument value. 54 | Ctx context.Context 55 | // ID is the id argument value. 56 | ID T 57 | } 58 | } 59 | lockCreate sync.RWMutex 60 | lockGet sync.RWMutex 61 | } 62 | 63 | // Create calls CreateFunc. 64 | func (mock *GenericStore1Mock[T, S]) Create(ctx context.Context, id T, value S) error { 65 | if mock.CreateFunc == nil { 66 | panic("GenericStore1Mock.CreateFunc: method is nil but GenericStore1.Create was just called") 67 | } 68 | callInfo := struct { 69 | Ctx context.Context 70 | ID T 71 | Value S 72 | }{ 73 | Ctx: ctx, 74 | ID: id, 75 | Value: value, 76 | } 77 | mock.lockCreate.Lock() 78 | mock.calls.Create = append(mock.calls.Create, callInfo) 79 | mock.lockCreate.Unlock() 80 | return mock.CreateFunc(ctx, id, value) 81 | } 82 | 83 | // CreateCalls gets all the calls that were made to Create. 84 | // Check the length with: 85 | // 86 | // len(mockedGenericStore1.CreateCalls()) 87 | func (mock *GenericStore1Mock[T, S]) CreateCalls() []struct { 88 | Ctx context.Context 89 | ID T 90 | Value S 91 | } { 92 | var calls []struct { 93 | Ctx context.Context 94 | ID T 95 | Value S 96 | } 97 | mock.lockCreate.RLock() 98 | calls = mock.calls.Create 99 | mock.lockCreate.RUnlock() 100 | return calls 101 | } 102 | 103 | // Get calls GetFunc. 104 | func (mock *GenericStore1Mock[T, S]) Get(ctx context.Context, id T) (S, error) { 105 | if mock.GetFunc == nil { 106 | panic("GenericStore1Mock.GetFunc: method is nil but GenericStore1.Get was just called") 107 | } 108 | callInfo := struct { 109 | Ctx context.Context 110 | ID T 111 | }{ 112 | Ctx: ctx, 113 | ID: id, 114 | } 115 | mock.lockGet.Lock() 116 | mock.calls.Get = append(mock.calls.Get, callInfo) 117 | mock.lockGet.Unlock() 118 | return mock.GetFunc(ctx, id) 119 | } 120 | 121 | // GetCalls gets all the calls that were made to Get. 122 | // Check the length with: 123 | // 124 | // len(mockedGenericStore1.GetCalls()) 125 | func (mock *GenericStore1Mock[T, S]) GetCalls() []struct { 126 | Ctx context.Context 127 | ID T 128 | } { 129 | var calls []struct { 130 | Ctx context.Context 131 | ID T 132 | } 133 | mock.lockGet.RLock() 134 | calls = mock.calls.Get 135 | mock.lockGet.RUnlock() 136 | return calls 137 | } 138 | 139 | // Ensure, that GenericStore2Mock does implement GenericStore2. 140 | // If this is not the case, regenerate this file with moq. 141 | var _ GenericStore2[[]byte, any] = &GenericStore2Mock[[]byte, any]{} 142 | 143 | // GenericStore2Mock is a mock implementation of GenericStore2. 144 | // 145 | // func TestSomethingThatUsesGenericStore2(t *testing.T) { 146 | // 147 | // // make and configure a mocked GenericStore2 148 | // mockedGenericStore2 := &GenericStore2Mock{ 149 | // CreateFunc: func(ctx context.Context, id T, value S) error { 150 | // panic("mock out the Create method") 151 | // }, 152 | // GetFunc: func(ctx context.Context, id T) (S, error) { 153 | // panic("mock out the Get method") 154 | // }, 155 | // } 156 | // 157 | // // use mockedGenericStore2 in code that requires GenericStore2 158 | // // and then make assertions. 159 | // 160 | // } 161 | type GenericStore2Mock[T Key2, S any] struct { 162 | // CreateFunc mocks the Create method. 163 | CreateFunc func(ctx context.Context, id T, value S) error 164 | 165 | // GetFunc mocks the Get method. 166 | GetFunc func(ctx context.Context, id T) (S, error) 167 | 168 | // calls tracks calls to the methods. 169 | calls struct { 170 | // Create holds details about calls to the Create method. 171 | Create []struct { 172 | // Ctx is the ctx argument value. 173 | Ctx context.Context 174 | // ID is the id argument value. 175 | ID T 176 | // Value is the value argument value. 177 | Value S 178 | } 179 | // Get holds details about calls to the Get method. 180 | Get []struct { 181 | // Ctx is the ctx argument value. 182 | Ctx context.Context 183 | // ID is the id argument value. 184 | ID T 185 | } 186 | } 187 | lockCreate sync.RWMutex 188 | lockGet sync.RWMutex 189 | } 190 | 191 | // Create calls CreateFunc. 192 | func (mock *GenericStore2Mock[T, S]) Create(ctx context.Context, id T, value S) error { 193 | if mock.CreateFunc == nil { 194 | panic("GenericStore2Mock.CreateFunc: method is nil but GenericStore2.Create was just called") 195 | } 196 | callInfo := struct { 197 | Ctx context.Context 198 | ID T 199 | Value S 200 | }{ 201 | Ctx: ctx, 202 | ID: id, 203 | Value: value, 204 | } 205 | mock.lockCreate.Lock() 206 | mock.calls.Create = append(mock.calls.Create, callInfo) 207 | mock.lockCreate.Unlock() 208 | return mock.CreateFunc(ctx, id, value) 209 | } 210 | 211 | // CreateCalls gets all the calls that were made to Create. 212 | // Check the length with: 213 | // 214 | // len(mockedGenericStore2.CreateCalls()) 215 | func (mock *GenericStore2Mock[T, S]) CreateCalls() []struct { 216 | Ctx context.Context 217 | ID T 218 | Value S 219 | } { 220 | var calls []struct { 221 | Ctx context.Context 222 | ID T 223 | Value S 224 | } 225 | mock.lockCreate.RLock() 226 | calls = mock.calls.Create 227 | mock.lockCreate.RUnlock() 228 | return calls 229 | } 230 | 231 | // Get calls GetFunc. 232 | func (mock *GenericStore2Mock[T, S]) Get(ctx context.Context, id T) (S, error) { 233 | if mock.GetFunc == nil { 234 | panic("GenericStore2Mock.GetFunc: method is nil but GenericStore2.Get was just called") 235 | } 236 | callInfo := struct { 237 | Ctx context.Context 238 | ID T 239 | }{ 240 | Ctx: ctx, 241 | ID: id, 242 | } 243 | mock.lockGet.Lock() 244 | mock.calls.Get = append(mock.calls.Get, callInfo) 245 | mock.lockGet.Unlock() 246 | return mock.GetFunc(ctx, id) 247 | } 248 | 249 | // GetCalls gets all the calls that were made to Get. 250 | // Check the length with: 251 | // 252 | // len(mockedGenericStore2.GetCalls()) 253 | func (mock *GenericStore2Mock[T, S]) GetCalls() []struct { 254 | Ctx context.Context 255 | ID T 256 | } { 257 | var calls []struct { 258 | Ctx context.Context 259 | ID T 260 | } 261 | mock.lockGet.RLock() 262 | calls = mock.calls.Get 263 | mock.lockGet.RUnlock() 264 | return calls 265 | } 266 | 267 | // Ensure, that AliasStoreMock does implement AliasStore. 268 | // If this is not the case, regenerate this file with moq. 269 | var _ AliasStore = &AliasStoreMock{} 270 | 271 | // AliasStoreMock is a mock implementation of AliasStore. 272 | // 273 | // func TestSomethingThatUsesAliasStore(t *testing.T) { 274 | // 275 | // // make and configure a mocked AliasStore 276 | // mockedAliasStore := &AliasStoreMock{ 277 | // CreateFunc: func(ctx context.Context, id KeyImpl, value bool) error { 278 | // panic("mock out the Create method") 279 | // }, 280 | // GetFunc: func(ctx context.Context, id KeyImpl) (bool, error) { 281 | // panic("mock out the Get method") 282 | // }, 283 | // } 284 | // 285 | // // use mockedAliasStore in code that requires AliasStore 286 | // // and then make assertions. 287 | // 288 | // } 289 | type AliasStoreMock struct { 290 | // CreateFunc mocks the Create method. 291 | CreateFunc func(ctx context.Context, id KeyImpl, value bool) error 292 | 293 | // GetFunc mocks the Get method. 294 | GetFunc func(ctx context.Context, id KeyImpl) (bool, error) 295 | 296 | // calls tracks calls to the methods. 297 | calls struct { 298 | // Create holds details about calls to the Create method. 299 | Create []struct { 300 | // Ctx is the ctx argument value. 301 | Ctx context.Context 302 | // ID is the id argument value. 303 | ID KeyImpl 304 | // Value is the value argument value. 305 | Value bool 306 | } 307 | // Get holds details about calls to the Get method. 308 | Get []struct { 309 | // Ctx is the ctx argument value. 310 | Ctx context.Context 311 | // ID is the id argument value. 312 | ID KeyImpl 313 | } 314 | } 315 | lockCreate sync.RWMutex 316 | lockGet sync.RWMutex 317 | } 318 | 319 | // Create calls CreateFunc. 320 | func (mock *AliasStoreMock) Create(ctx context.Context, id KeyImpl, value bool) error { 321 | if mock.CreateFunc == nil { 322 | panic("AliasStoreMock.CreateFunc: method is nil but AliasStore.Create was just called") 323 | } 324 | callInfo := struct { 325 | Ctx context.Context 326 | ID KeyImpl 327 | Value bool 328 | }{ 329 | Ctx: ctx, 330 | ID: id, 331 | Value: value, 332 | } 333 | mock.lockCreate.Lock() 334 | mock.calls.Create = append(mock.calls.Create, callInfo) 335 | mock.lockCreate.Unlock() 336 | return mock.CreateFunc(ctx, id, value) 337 | } 338 | 339 | // CreateCalls gets all the calls that were made to Create. 340 | // Check the length with: 341 | // 342 | // len(mockedAliasStore.CreateCalls()) 343 | func (mock *AliasStoreMock) CreateCalls() []struct { 344 | Ctx context.Context 345 | ID KeyImpl 346 | Value bool 347 | } { 348 | var calls []struct { 349 | Ctx context.Context 350 | ID KeyImpl 351 | Value bool 352 | } 353 | mock.lockCreate.RLock() 354 | calls = mock.calls.Create 355 | mock.lockCreate.RUnlock() 356 | return calls 357 | } 358 | 359 | // Get calls GetFunc. 360 | func (mock *AliasStoreMock) Get(ctx context.Context, id KeyImpl) (bool, error) { 361 | if mock.GetFunc == nil { 362 | panic("AliasStoreMock.GetFunc: method is nil but AliasStore.Get was just called") 363 | } 364 | callInfo := struct { 365 | Ctx context.Context 366 | ID KeyImpl 367 | }{ 368 | Ctx: ctx, 369 | ID: id, 370 | } 371 | mock.lockGet.Lock() 372 | mock.calls.Get = append(mock.calls.Get, callInfo) 373 | mock.lockGet.Unlock() 374 | return mock.GetFunc(ctx, id) 375 | } 376 | 377 | // GetCalls gets all the calls that were made to Get. 378 | // Check the length with: 379 | // 380 | // len(mockedAliasStore.GetCalls()) 381 | func (mock *AliasStoreMock) GetCalls() []struct { 382 | Ctx context.Context 383 | ID KeyImpl 384 | } { 385 | var calls []struct { 386 | Ctx context.Context 387 | ID KeyImpl 388 | } 389 | mock.lockGet.RLock() 390 | calls = mock.calls.Get 391 | mock.lockGet.RUnlock() 392 | return calls 393 | } 394 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/genparamname/iface.go: -------------------------------------------------------------------------------- 1 | package genparamname 2 | 3 | import ( 4 | "database/sql" 5 | "encoding/json" 6 | "fmt" 7 | "io" 8 | "net" 9 | "net/http" 10 | "net/http/httputil" 11 | "net/url" 12 | ) 13 | 14 | type ( 15 | // Go is a test function. 16 | Go func() 17 | 18 | myType struct{} 19 | ) 20 | 21 | // Interface is a test interface. 22 | type Interface interface { 23 | Method( 24 | *myType, 25 | [3]json.Number, 26 | []byte, 27 | map[sql.NullString]io.Reader, 28 | func(conn net.Conn), 29 | Go, 30 | chan *httputil.BufferPool, 31 | struct{ URL *url.URL }, 32 | interface { 33 | fmt.Stringer 34 | CookieJar() http.CookieJar 35 | }, 36 | ) 37 | } 38 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/genparamname/iface_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package genparamname 5 | 6 | import ( 7 | "database/sql" 8 | "encoding/json" 9 | "fmt" 10 | "io" 11 | "net" 12 | "net/http" 13 | "net/http/httputil" 14 | "net/url" 15 | "sync" 16 | ) 17 | 18 | // Ensure, that InterfaceMock does implement Interface. 19 | // If this is not the case, regenerate this file with moq. 20 | var _ Interface = &InterfaceMock{} 21 | 22 | // InterfaceMock is a mock implementation of Interface. 23 | // 24 | // func TestSomethingThatUsesInterface(t *testing.T) { 25 | // 26 | // // make and configure a mocked Interface 27 | // mockedInterface := &InterfaceMock{ 28 | // MethodFunc: func(myTypeMoqParam *myType, numbers [3]json.Number, bytes []byte, nullStringToReader map[sql.NullString]io.Reader, fn func(conn net.Conn), goMoqParam Go, bufferPoolCh chan *httputil.BufferPool, val struct{URL *url.URL}, ifaceVal interface{CookieJar() http.CookieJar; fmt.Stringer}) { 29 | // panic("mock out the Method method") 30 | // }, 31 | // } 32 | // 33 | // // use mockedInterface in code that requires Interface 34 | // // and then make assertions. 35 | // 36 | // } 37 | type InterfaceMock struct { 38 | // MethodFunc mocks the Method method. 39 | MethodFunc func(myTypeMoqParam *myType, numbers [3]json.Number, bytes []byte, nullStringToReader map[sql.NullString]io.Reader, fn func(conn net.Conn), goMoqParam Go, bufferPoolCh chan *httputil.BufferPool, val struct{ URL *url.URL }, ifaceVal interface { 40 | CookieJar() http.CookieJar 41 | fmt.Stringer 42 | }) 43 | 44 | // calls tracks calls to the methods. 45 | calls struct { 46 | // Method holds details about calls to the Method method. 47 | Method []struct { 48 | // MyTypeMoqParam is the myTypeMoqParam argument value. 49 | MyTypeMoqParam *myType 50 | // Numbers is the numbers argument value. 51 | Numbers [3]json.Number 52 | // Bytes is the bytes argument value. 53 | Bytes []byte 54 | // NullStringToReader is the nullStringToReader argument value. 55 | NullStringToReader map[sql.NullString]io.Reader 56 | // Fn is the fn argument value. 57 | Fn func(conn net.Conn) 58 | // GoMoqParam is the goMoqParam argument value. 59 | GoMoqParam Go 60 | // BufferPoolCh is the bufferPoolCh argument value. 61 | BufferPoolCh chan *httputil.BufferPool 62 | // Val is the val argument value. 63 | Val struct{ URL *url.URL } 64 | // IfaceVal is the ifaceVal argument value. 65 | IfaceVal interface { 66 | CookieJar() http.CookieJar 67 | fmt.Stringer 68 | } 69 | } 70 | } 71 | lockMethod sync.RWMutex 72 | } 73 | 74 | // Method calls MethodFunc. 75 | func (mock *InterfaceMock) Method(myTypeMoqParam *myType, numbers [3]json.Number, bytes []byte, nullStringToReader map[sql.NullString]io.Reader, fn func(conn net.Conn), goMoqParam Go, bufferPoolCh chan *httputil.BufferPool, val struct{ URL *url.URL }, ifaceVal interface { 76 | CookieJar() http.CookieJar 77 | fmt.Stringer 78 | }) { 79 | if mock.MethodFunc == nil { 80 | panic("InterfaceMock.MethodFunc: method is nil but Interface.Method was just called") 81 | } 82 | callInfo := struct { 83 | MyTypeMoqParam *myType 84 | Numbers [3]json.Number 85 | Bytes []byte 86 | NullStringToReader map[sql.NullString]io.Reader 87 | Fn func(conn net.Conn) 88 | GoMoqParam Go 89 | BufferPoolCh chan *httputil.BufferPool 90 | Val struct{ URL *url.URL } 91 | IfaceVal interface { 92 | CookieJar() http.CookieJar 93 | fmt.Stringer 94 | } 95 | }{ 96 | MyTypeMoqParam: myTypeMoqParam, 97 | Numbers: numbers, 98 | Bytes: bytes, 99 | NullStringToReader: nullStringToReader, 100 | Fn: fn, 101 | GoMoqParam: goMoqParam, 102 | BufferPoolCh: bufferPoolCh, 103 | Val: val, 104 | IfaceVal: ifaceVal, 105 | } 106 | mock.lockMethod.Lock() 107 | mock.calls.Method = append(mock.calls.Method, callInfo) 108 | mock.lockMethod.Unlock() 109 | mock.MethodFunc(myTypeMoqParam, numbers, bytes, nullStringToReader, fn, goMoqParam, bufferPoolCh, val, ifaceVal) 110 | } 111 | 112 | // MethodCalls gets all the calls that were made to Method. 113 | // Check the length with: 114 | // 115 | // len(mockedInterface.MethodCalls()) 116 | func (mock *InterfaceMock) MethodCalls() []struct { 117 | MyTypeMoqParam *myType 118 | Numbers [3]json.Number 119 | Bytes []byte 120 | NullStringToReader map[sql.NullString]io.Reader 121 | Fn func(conn net.Conn) 122 | GoMoqParam Go 123 | BufferPoolCh chan *httputil.BufferPool 124 | Val struct{ URL *url.URL } 125 | IfaceVal interface { 126 | CookieJar() http.CookieJar 127 | fmt.Stringer 128 | } 129 | } { 130 | var calls []struct { 131 | MyTypeMoqParam *myType 132 | Numbers [3]json.Number 133 | Bytes []byte 134 | NullStringToReader map[sql.NullString]io.Reader 135 | Fn func(conn net.Conn) 136 | GoMoqParam Go 137 | BufferPoolCh chan *httputil.BufferPool 138 | Val struct{ URL *url.URL } 139 | IfaceVal interface { 140 | CookieJar() http.CookieJar 141 | fmt.Stringer 142 | } 143 | } 144 | mock.lockMethod.RLock() 145 | calls = mock.calls.Method 146 | mock.lockMethod.RUnlock() 147 | return calls 148 | } 149 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/matryer/moq/pkg/moq/testpackages 2 | 3 | go 1.22.5 4 | 5 | require github.com/sudo-suhas/moq-test-pkgs/somerepo v0.0.0-20200816045313-d2f573eea6c7 6 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/go.sum: -------------------------------------------------------------------------------- 1 | github.com/sudo-suhas/moq-test-pkgs/somerepo v0.0.0-20200816045313-d2f573eea6c7 h1:5TDSgxW5A9Homgu8Kh0iB1aeRCgM1y8pZaxAR0TjeQs= 2 | github.com/sudo-suhas/moq-test-pkgs/somerepo v0.0.0-20200816045313-d2f573eea6c7/go.mod h1:3CK3+2qBd+EkNJP+dgGjVYIbEwRQWVf6EgcmyIjTi2A= 3 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/gogenvendoring/user/user.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import "github.com/sudo-suhas/moq-test-pkgs/somerepo" 4 | 5 | //go:generate moq -out user_moq_test.go . Service 6 | 7 | // Service does something good with computers. 8 | type Service interface { 9 | DoSomething(somerepo.SomeType) error 10 | } 11 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/gogenvendoring/user/user_moq_test.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package user 5 | 6 | import ( 7 | "github.com/sudo-suhas/moq-test-pkgs/somerepo" 8 | "sync" 9 | ) 10 | 11 | // Ensure, that ServiceMock does implement Service. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ Service = &ServiceMock{} 14 | 15 | // ServiceMock is a mock implementation of Service. 16 | // 17 | // func TestSomethingThatUsesService(t *testing.T) { 18 | // 19 | // // make and configure a mocked Service 20 | // mockedService := &ServiceMock{ 21 | // DoSomethingFunc: func(someType somerepo.SomeType) error { 22 | // panic("mock out the DoSomething method") 23 | // }, 24 | // } 25 | // 26 | // // use mockedService in code that requires Service 27 | // // and then make assertions. 28 | // 29 | // } 30 | type ServiceMock struct { 31 | // DoSomethingFunc mocks the DoSomething method. 32 | DoSomethingFunc func(someType somerepo.SomeType) error 33 | 34 | // calls tracks calls to the methods. 35 | calls struct { 36 | // DoSomething holds details about calls to the DoSomething method. 37 | DoSomething []struct { 38 | // SomeType is the someType argument value. 39 | SomeType somerepo.SomeType 40 | } 41 | } 42 | lockDoSomething sync.RWMutex 43 | } 44 | 45 | // DoSomething calls DoSomethingFunc. 46 | func (mock *ServiceMock) DoSomething(someType somerepo.SomeType) error { 47 | if mock.DoSomethingFunc == nil { 48 | panic("ServiceMock.DoSomethingFunc: method is nil but Service.DoSomething was just called") 49 | } 50 | callInfo := struct { 51 | SomeType somerepo.SomeType 52 | }{ 53 | SomeType: someType, 54 | } 55 | mock.lockDoSomething.Lock() 56 | mock.calls.DoSomething = append(mock.calls.DoSomething, callInfo) 57 | mock.lockDoSomething.Unlock() 58 | return mock.DoSomethingFunc(someType) 59 | } 60 | 61 | // DoSomethingCalls gets all the calls that were made to DoSomething. 62 | // Check the length with: 63 | // 64 | // len(mockedService.DoSomethingCalls()) 65 | func (mock *ServiceMock) DoSomethingCalls() []struct { 66 | SomeType somerepo.SomeType 67 | } { 68 | var calls []struct { 69 | SomeType somerepo.SomeType 70 | } 71 | mock.lockDoSomething.RLock() 72 | calls = mock.calls.DoSomething 73 | mock.lockDoSomething.RUnlock() 74 | return calls 75 | } 76 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/importalias/middleman.go: -------------------------------------------------------------------------------- 1 | package importalias 2 | 3 | import ( 4 | srcclient "github.com/matryer/moq/pkg/moq/testpackages/importalias/source/client" 5 | tgtclient "github.com/matryer/moq/pkg/moq/testpackages/importalias/target/client" 6 | ) 7 | 8 | // MiddleMan is a test interface. 9 | type MiddleMan interface { 10 | Connect(src srcclient.Client, tgt tgtclient.Client) 11 | } 12 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/importalias/middleman_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package importalias 5 | 6 | import ( 7 | srcclient "github.com/matryer/moq/pkg/moq/testpackages/importalias/source/client" 8 | tgtclient "github.com/matryer/moq/pkg/moq/testpackages/importalias/target/client" 9 | "sync" 10 | ) 11 | 12 | // Ensure, that MiddleManMock does implement MiddleMan. 13 | // If this is not the case, regenerate this file with moq. 14 | var _ MiddleMan = &MiddleManMock{} 15 | 16 | // MiddleManMock is a mock implementation of MiddleMan. 17 | // 18 | // func TestSomethingThatUsesMiddleMan(t *testing.T) { 19 | // 20 | // // make and configure a mocked MiddleMan 21 | // mockedMiddleMan := &MiddleManMock{ 22 | // ConnectFunc: func(src srcclient.Client, tgt tgtclient.Client) { 23 | // panic("mock out the Connect method") 24 | // }, 25 | // } 26 | // 27 | // // use mockedMiddleMan in code that requires MiddleMan 28 | // // and then make assertions. 29 | // 30 | // } 31 | type MiddleManMock struct { 32 | // ConnectFunc mocks the Connect method. 33 | ConnectFunc func(src srcclient.Client, tgt tgtclient.Client) 34 | 35 | // calls tracks calls to the methods. 36 | calls struct { 37 | // Connect holds details about calls to the Connect method. 38 | Connect []struct { 39 | // Src is the src argument value. 40 | Src srcclient.Client 41 | // Tgt is the tgt argument value. 42 | Tgt tgtclient.Client 43 | } 44 | } 45 | lockConnect sync.RWMutex 46 | } 47 | 48 | // Connect calls ConnectFunc. 49 | func (mock *MiddleManMock) Connect(src srcclient.Client, tgt tgtclient.Client) { 50 | if mock.ConnectFunc == nil { 51 | panic("MiddleManMock.ConnectFunc: method is nil but MiddleMan.Connect was just called") 52 | } 53 | callInfo := struct { 54 | Src srcclient.Client 55 | Tgt tgtclient.Client 56 | }{ 57 | Src: src, 58 | Tgt: tgt, 59 | } 60 | mock.lockConnect.Lock() 61 | mock.calls.Connect = append(mock.calls.Connect, callInfo) 62 | mock.lockConnect.Unlock() 63 | mock.ConnectFunc(src, tgt) 64 | } 65 | 66 | // ConnectCalls gets all the calls that were made to Connect. 67 | // Check the length with: 68 | // 69 | // len(mockedMiddleMan.ConnectCalls()) 70 | func (mock *MiddleManMock) ConnectCalls() []struct { 71 | Src srcclient.Client 72 | Tgt tgtclient.Client 73 | } { 74 | var calls []struct { 75 | Src srcclient.Client 76 | Tgt tgtclient.Client 77 | } 78 | mock.lockConnect.RLock() 79 | calls = mock.calls.Connect 80 | mock.lockConnect.RUnlock() 81 | return calls 82 | } 83 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/importalias/source/client/src_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | // Client is a test struct. 4 | type Client struct{} 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/importalias/target/client/tgt_client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | // Client is a test struct. 4 | type Client struct{} 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/imports/one/one.go: -------------------------------------------------------------------------------- 1 | package one 2 | 3 | // Thing is just a thing. 4 | type Thing struct{} 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/imports/two/gofmt.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package two 5 | 6 | import ( 7 | "github.com/matryer/moq/pkg/moq/testpackages/imports/one" 8 | "sync" 9 | ) 10 | 11 | // Ensure, that gofmtMock does implement DoSomething. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ DoSomething = &gofmtMock{} 14 | 15 | // gofmtMock is a mock implementation of DoSomething. 16 | // 17 | // func TestSomethingThatUsesDoSomething(t *testing.T) { 18 | // 19 | // // make and configure a mocked DoSomething 20 | // mockedDoSomething := &gofmtMock{ 21 | // AnotherFunc: func(thing one.Thing) error { 22 | // panic("mock out the Another method") 23 | // }, 24 | // DoFunc: func(thing one.Thing) error { 25 | // panic("mock out the Do method") 26 | // }, 27 | // } 28 | // 29 | // // use mockedDoSomething in code that requires DoSomething 30 | // // and then make assertions. 31 | // 32 | // } 33 | type gofmtMock struct { 34 | // AnotherFunc mocks the Another method. 35 | AnotherFunc func(thing one.Thing) error 36 | 37 | // DoFunc mocks the Do method. 38 | DoFunc func(thing one.Thing) error 39 | 40 | // calls tracks calls to the methods. 41 | calls struct { 42 | // Another holds details about calls to the Another method. 43 | Another []struct { 44 | // Thing is the thing argument value. 45 | Thing one.Thing 46 | } 47 | // Do holds details about calls to the Do method. 48 | Do []struct { 49 | // Thing is the thing argument value. 50 | Thing one.Thing 51 | } 52 | } 53 | lockAnother sync.RWMutex 54 | lockDo sync.RWMutex 55 | } 56 | 57 | // Another calls AnotherFunc. 58 | func (mock *gofmtMock) Another(thing one.Thing) error { 59 | if mock.AnotherFunc == nil { 60 | panic("gofmtMock.AnotherFunc: method is nil but DoSomething.Another was just called") 61 | } 62 | callInfo := struct { 63 | Thing one.Thing 64 | }{ 65 | Thing: thing, 66 | } 67 | mock.lockAnother.Lock() 68 | mock.calls.Another = append(mock.calls.Another, callInfo) 69 | mock.lockAnother.Unlock() 70 | return mock.AnotherFunc(thing) 71 | } 72 | 73 | // AnotherCalls gets all the calls that were made to Another. 74 | // Check the length with: 75 | // 76 | // len(mockedDoSomething.AnotherCalls()) 77 | func (mock *gofmtMock) AnotherCalls() []struct { 78 | Thing one.Thing 79 | } { 80 | var calls []struct { 81 | Thing one.Thing 82 | } 83 | mock.lockAnother.RLock() 84 | calls = mock.calls.Another 85 | mock.lockAnother.RUnlock() 86 | return calls 87 | } 88 | 89 | // Do calls DoFunc. 90 | func (mock *gofmtMock) Do(thing one.Thing) error { 91 | if mock.DoFunc == nil { 92 | panic("gofmtMock.DoFunc: method is nil but DoSomething.Do was just called") 93 | } 94 | callInfo := struct { 95 | Thing one.Thing 96 | }{ 97 | Thing: thing, 98 | } 99 | mock.lockDo.Lock() 100 | mock.calls.Do = append(mock.calls.Do, callInfo) 101 | mock.lockDo.Unlock() 102 | return mock.DoFunc(thing) 103 | } 104 | 105 | // DoCalls gets all the calls that were made to Do. 106 | // Check the length with: 107 | // 108 | // len(mockedDoSomething.DoCalls()) 109 | func (mock *gofmtMock) DoCalls() []struct { 110 | Thing one.Thing 111 | } { 112 | var calls []struct { 113 | Thing one.Thing 114 | } 115 | mock.lockDo.RLock() 116 | calls = mock.calls.Do 117 | mock.lockDo.RUnlock() 118 | return calls 119 | } 120 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/imports/two/goimports.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package two 5 | 6 | import ( 7 | "sync" 8 | 9 | "github.com/matryer/moq/pkg/moq/testpackages/imports/one" 10 | ) 11 | 12 | // Ensure, that goimportsMock does implement DoSomething. 13 | // If this is not the case, regenerate this file with moq. 14 | var _ DoSomething = &goimportsMock{} 15 | 16 | // goimportsMock is a mock implementation of DoSomething. 17 | // 18 | // func TestSomethingThatUsesDoSomething(t *testing.T) { 19 | // 20 | // // make and configure a mocked DoSomething 21 | // mockedDoSomething := &goimportsMock{ 22 | // AnotherFunc: func(thing one.Thing) error { 23 | // panic("mock out the Another method") 24 | // }, 25 | // DoFunc: func(thing one.Thing) error { 26 | // panic("mock out the Do method") 27 | // }, 28 | // } 29 | // 30 | // // use mockedDoSomething in code that requires DoSomething 31 | // // and then make assertions. 32 | // 33 | // } 34 | type goimportsMock struct { 35 | // AnotherFunc mocks the Another method. 36 | AnotherFunc func(thing one.Thing) error 37 | 38 | // DoFunc mocks the Do method. 39 | DoFunc func(thing one.Thing) error 40 | 41 | // calls tracks calls to the methods. 42 | calls struct { 43 | // Another holds details about calls to the Another method. 44 | Another []struct { 45 | // Thing is the thing argument value. 46 | Thing one.Thing 47 | } 48 | // Do holds details about calls to the Do method. 49 | Do []struct { 50 | // Thing is the thing argument value. 51 | Thing one.Thing 52 | } 53 | } 54 | lockAnother sync.RWMutex 55 | lockDo sync.RWMutex 56 | } 57 | 58 | // Another calls AnotherFunc. 59 | func (mock *goimportsMock) Another(thing one.Thing) error { 60 | if mock.AnotherFunc == nil { 61 | panic("goimportsMock.AnotherFunc: method is nil but DoSomething.Another was just called") 62 | } 63 | callInfo := struct { 64 | Thing one.Thing 65 | }{ 66 | Thing: thing, 67 | } 68 | mock.lockAnother.Lock() 69 | mock.calls.Another = append(mock.calls.Another, callInfo) 70 | mock.lockAnother.Unlock() 71 | return mock.AnotherFunc(thing) 72 | } 73 | 74 | // AnotherCalls gets all the calls that were made to Another. 75 | // Check the length with: 76 | // 77 | // len(mockedDoSomething.AnotherCalls()) 78 | func (mock *goimportsMock) AnotherCalls() []struct { 79 | Thing one.Thing 80 | } { 81 | var calls []struct { 82 | Thing one.Thing 83 | } 84 | mock.lockAnother.RLock() 85 | calls = mock.calls.Another 86 | mock.lockAnother.RUnlock() 87 | return calls 88 | } 89 | 90 | // Do calls DoFunc. 91 | func (mock *goimportsMock) Do(thing one.Thing) error { 92 | if mock.DoFunc == nil { 93 | panic("goimportsMock.DoFunc: method is nil but DoSomething.Do was just called") 94 | } 95 | callInfo := struct { 96 | Thing one.Thing 97 | }{ 98 | Thing: thing, 99 | } 100 | mock.lockDo.Lock() 101 | mock.calls.Do = append(mock.calls.Do, callInfo) 102 | mock.lockDo.Unlock() 103 | return mock.DoFunc(thing) 104 | } 105 | 106 | // DoCalls gets all the calls that were made to Do. 107 | // Check the length with: 108 | // 109 | // len(mockedDoSomething.DoCalls()) 110 | func (mock *goimportsMock) DoCalls() []struct { 111 | Thing one.Thing 112 | } { 113 | var calls []struct { 114 | Thing one.Thing 115 | } 116 | mock.lockDo.RLock() 117 | calls = mock.calls.Do 118 | mock.lockDo.RUnlock() 119 | return calls 120 | } 121 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/imports/two/noop.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package two 5 | 6 | import ( 7 | "github.com/matryer/moq/pkg/moq/testpackages/imports/one" 8 | "sync" 9 | ) 10 | 11 | // Ensure, that noopMock does implement DoSomething. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ DoSomething = &noopMock{} 14 | 15 | // noopMock is a mock implementation of DoSomething. 16 | // 17 | // func TestSomethingThatUsesDoSomething(t *testing.T) { 18 | // 19 | // // make and configure a mocked DoSomething 20 | // mockedDoSomething := &noopMock{ 21 | // AnotherFunc: func(thing one.Thing) error { 22 | // panic("mock out the Another method") 23 | // }, 24 | // DoFunc: func(thing one.Thing) error { 25 | // panic("mock out the Do method") 26 | // }, 27 | // } 28 | // 29 | // // use mockedDoSomething in code that requires DoSomething 30 | // // and then make assertions. 31 | // 32 | // } 33 | type noopMock struct { 34 | // AnotherFunc mocks the Another method. 35 | AnotherFunc func(thing one.Thing) error 36 | 37 | // DoFunc mocks the Do method. 38 | DoFunc func(thing one.Thing) error 39 | 40 | // calls tracks calls to the methods. 41 | calls struct { 42 | // Another holds details about calls to the Another method. 43 | Another []struct { 44 | // Thing is the thing argument value. 45 | Thing one.Thing 46 | } 47 | // Do holds details about calls to the Do method. 48 | Do []struct { 49 | // Thing is the thing argument value. 50 | Thing one.Thing 51 | } 52 | } 53 | lockAnother sync.RWMutex 54 | lockDo sync.RWMutex 55 | } 56 | 57 | // Another calls AnotherFunc. 58 | func (mock *noopMock) Another(thing one.Thing) error { 59 | if mock.AnotherFunc == nil { 60 | panic("noopMock.AnotherFunc: method is nil but DoSomething.Another was just called") 61 | } 62 | callInfo := struct { 63 | Thing one.Thing 64 | }{ 65 | Thing: thing, 66 | } 67 | mock.lockAnother.Lock() 68 | mock.calls.Another = append(mock.calls.Another, callInfo) 69 | mock.lockAnother.Unlock() 70 | return mock.AnotherFunc(thing) 71 | } 72 | 73 | // AnotherCalls gets all the calls that were made to Another. 74 | // Check the length with: 75 | // 76 | // len(mockedDoSomething.AnotherCalls()) 77 | func (mock *noopMock) AnotherCalls() []struct { 78 | Thing one.Thing 79 | } { 80 | var calls []struct { 81 | Thing one.Thing 82 | } 83 | mock.lockAnother.RLock() 84 | calls = mock.calls.Another 85 | mock.lockAnother.RUnlock() 86 | return calls 87 | } 88 | 89 | // Do calls DoFunc. 90 | func (mock *noopMock) Do(thing one.Thing) error { 91 | if mock.DoFunc == nil { 92 | panic("noopMock.DoFunc: method is nil but DoSomething.Do was just called") 93 | } 94 | callInfo := struct { 95 | Thing one.Thing 96 | }{ 97 | Thing: thing, 98 | } 99 | mock.lockDo.Lock() 100 | mock.calls.Do = append(mock.calls.Do, callInfo) 101 | mock.lockDo.Unlock() 102 | return mock.DoFunc(thing) 103 | } 104 | 105 | // DoCalls gets all the calls that were made to Do. 106 | // Check the length with: 107 | // 108 | // len(mockedDoSomething.DoCalls()) 109 | func (mock *noopMock) DoCalls() []struct { 110 | Thing one.Thing 111 | } { 112 | var calls []struct { 113 | Thing one.Thing 114 | } 115 | mock.lockDo.RLock() 116 | calls = mock.calls.Do 117 | mock.lockDo.RUnlock() 118 | return calls 119 | } 120 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/imports/two/two.go: -------------------------------------------------------------------------------- 1 | package two 2 | 3 | import ( 4 | "github.com/matryer/moq/pkg/moq/testpackages/imports/one" 5 | ) 6 | 7 | // DoSomething does something. 8 | type DoSomething interface { 9 | Do(thing one.Thing) error 10 | Another(thing one.Thing) error 11 | } 12 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/modules/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/matryer/modules 2 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/modules/simple.go: -------------------------------------------------------------------------------- 1 | package simple 2 | 3 | // Foo is a test interface 4 | type Foo interface { 5 | FooIt(bar *Bar) 6 | } 7 | 8 | // Bar is a test type 9 | type Bar struct{} 10 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/paramconflict/iface.go: -------------------------------------------------------------------------------- 1 | package paramconflict 2 | 3 | import "time" 4 | 5 | // Interface is a test interface. 6 | type Interface interface { 7 | Method(string, bool, string, bool, int, int32, int64, float32, float64, time.Time, time.Time) 8 | } 9 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/paramconflict/iface_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package paramconflict 5 | 6 | import ( 7 | "sync" 8 | "time" 9 | ) 10 | 11 | // Ensure, that InterfaceMock does implement Interface. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ Interface = &InterfaceMock{} 14 | 15 | // InterfaceMock is a mock implementation of Interface. 16 | // 17 | // func TestSomethingThatUsesInterface(t *testing.T) { 18 | // 19 | // // make and configure a mocked Interface 20 | // mockedInterface := &InterfaceMock{ 21 | // MethodFunc: func(s1 string, b1 bool, s2 string, b2 bool, n1 int, n2 int32, n3 int64, f1 float32, f2 float64, timeMoqParam1 time.Time, timeMoqParam2 time.Time) { 22 | // panic("mock out the Method method") 23 | // }, 24 | // } 25 | // 26 | // // use mockedInterface in code that requires Interface 27 | // // and then make assertions. 28 | // 29 | // } 30 | type InterfaceMock struct { 31 | // MethodFunc mocks the Method method. 32 | MethodFunc func(s1 string, b1 bool, s2 string, b2 bool, n1 int, n2 int32, n3 int64, f1 float32, f2 float64, timeMoqParam1 time.Time, timeMoqParam2 time.Time) 33 | 34 | // calls tracks calls to the methods. 35 | calls struct { 36 | // Method holds details about calls to the Method method. 37 | Method []struct { 38 | // S1 is the s1 argument value. 39 | S1 string 40 | // B1 is the b1 argument value. 41 | B1 bool 42 | // S2 is the s2 argument value. 43 | S2 string 44 | // B2 is the b2 argument value. 45 | B2 bool 46 | // N1 is the n1 argument value. 47 | N1 int 48 | // N2 is the n2 argument value. 49 | N2 int32 50 | // N3 is the n3 argument value. 51 | N3 int64 52 | // F1 is the f1 argument value. 53 | F1 float32 54 | // F2 is the f2 argument value. 55 | F2 float64 56 | // TimeMoqParam1 is the timeMoqParam1 argument value. 57 | TimeMoqParam1 time.Time 58 | // TimeMoqParam2 is the timeMoqParam2 argument value. 59 | TimeMoqParam2 time.Time 60 | } 61 | } 62 | lockMethod sync.RWMutex 63 | } 64 | 65 | // Method calls MethodFunc. 66 | func (mock *InterfaceMock) Method(s1 string, b1 bool, s2 string, b2 bool, n1 int, n2 int32, n3 int64, f1 float32, f2 float64, timeMoqParam1 time.Time, timeMoqParam2 time.Time) { 67 | if mock.MethodFunc == nil { 68 | panic("InterfaceMock.MethodFunc: method is nil but Interface.Method was just called") 69 | } 70 | callInfo := struct { 71 | S1 string 72 | B1 bool 73 | S2 string 74 | B2 bool 75 | N1 int 76 | N2 int32 77 | N3 int64 78 | F1 float32 79 | F2 float64 80 | TimeMoqParam1 time.Time 81 | TimeMoqParam2 time.Time 82 | }{ 83 | S1: s1, 84 | B1: b1, 85 | S2: s2, 86 | B2: b2, 87 | N1: n1, 88 | N2: n2, 89 | N3: n3, 90 | F1: f1, 91 | F2: f2, 92 | TimeMoqParam1: timeMoqParam1, 93 | TimeMoqParam2: timeMoqParam2, 94 | } 95 | mock.lockMethod.Lock() 96 | mock.calls.Method = append(mock.calls.Method, callInfo) 97 | mock.lockMethod.Unlock() 98 | mock.MethodFunc(s1, b1, s2, b2, n1, n2, n3, f1, f2, timeMoqParam1, timeMoqParam2) 99 | } 100 | 101 | // MethodCalls gets all the calls that were made to Method. 102 | // Check the length with: 103 | // 104 | // len(mockedInterface.MethodCalls()) 105 | func (mock *InterfaceMock) MethodCalls() []struct { 106 | S1 string 107 | B1 bool 108 | S2 string 109 | B2 bool 110 | N1 int 111 | N2 int32 112 | N3 int64 113 | F1 float32 114 | F2 float64 115 | TimeMoqParam1 time.Time 116 | TimeMoqParam2 time.Time 117 | } { 118 | var calls []struct { 119 | S1 string 120 | B1 bool 121 | S2 string 122 | B2 bool 123 | N1 int 124 | N2 int32 125 | N3 int64 126 | F1 float32 127 | F2 float64 128 | TimeMoqParam1 time.Time 129 | TimeMoqParam2 time.Time 130 | } 131 | mock.lockMethod.RLock() 132 | calls = mock.calls.Method 133 | mock.lockMethod.RUnlock() 134 | return calls 135 | } 136 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/rangenum/rangenum.go: -------------------------------------------------------------------------------- 1 | package rangenum 2 | 3 | import "fmt" 4 | 5 | func DoMagic() { 6 | for range 10 { 7 | fmt.Println("abrakadabra") 8 | } 9 | } 10 | 11 | type Magician interface { 12 | DoMagic() 13 | } 14 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/rangenum/rangenum_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package rangenum 5 | 6 | import ( 7 | "sync" 8 | ) 9 | 10 | // Ensure, that MagicianMock does implement Magician. 11 | // If this is not the case, regenerate this file with moq. 12 | var _ Magician = &MagicianMock{} 13 | 14 | // MagicianMock is a mock implementation of Magician. 15 | // 16 | // func TestSomethingThatUsesMagician(t *testing.T) { 17 | // 18 | // // make and configure a mocked Magician 19 | // mockedMagician := &MagicianMock{ 20 | // DoMagicFunc: func() { 21 | // panic("mock out the DoMagic method") 22 | // }, 23 | // } 24 | // 25 | // // use mockedMagician in code that requires Magician 26 | // // and then make assertions. 27 | // 28 | // } 29 | type MagicianMock struct { 30 | // DoMagicFunc mocks the DoMagic method. 31 | DoMagicFunc func() 32 | 33 | // calls tracks calls to the methods. 34 | calls struct { 35 | // DoMagic holds details about calls to the DoMagic method. 36 | DoMagic []struct { 37 | } 38 | } 39 | lockDoMagic sync.RWMutex 40 | } 41 | 42 | // DoMagic calls DoMagicFunc. 43 | func (mock *MagicianMock) DoMagic() { 44 | if mock.DoMagicFunc == nil { 45 | panic("MagicianMock.DoMagicFunc: method is nil but Magician.DoMagic was just called") 46 | } 47 | callInfo := struct { 48 | }{} 49 | mock.lockDoMagic.Lock() 50 | mock.calls.DoMagic = append(mock.calls.DoMagic, callInfo) 51 | mock.lockDoMagic.Unlock() 52 | mock.DoMagicFunc() 53 | } 54 | 55 | // DoMagicCalls gets all the calls that were made to DoMagic. 56 | // Check the length with: 57 | // 58 | // len(mockedMagician.DoMagicCalls()) 59 | func (mock *MagicianMock) DoMagicCalls() []struct { 60 | } { 61 | var calls []struct { 62 | } 63 | mock.lockDoMagic.RLock() 64 | calls = mock.calls.DoMagic 65 | mock.lockDoMagic.RUnlock() 66 | return calls 67 | } 68 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/samenameimport/samename.go: -------------------------------------------------------------------------------- 1 | package samename 2 | 3 | import samename "github.com/matryer/moq/pkg/moq/testpackages/samenameimport/samenameimport" 4 | 5 | // Example is used to test issues with packages, which import another package with the same name 6 | type Example interface { 7 | Do(a samename.A) error 8 | } 9 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/samenameimport/samenameimport/samename.go: -------------------------------------------------------------------------------- 1 | package samename 2 | 3 | // The A is used in the parent package as a dependency 4 | type A struct{} 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/shadow/http/thing.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import "net/http" 4 | 5 | // Thing is a test interface. 6 | type Thing interface { 7 | Blah(w http.ResponseWriter, r *http.Request) 8 | } 9 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/shadow/mock/thing_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package mock 5 | 6 | import ( 7 | shadowhttp "github.com/matryer/moq/pkg/moq/testpackages/shadow/http" 8 | nethttp "net/http" 9 | "sync" 10 | ) 11 | 12 | // Ensure, that ThingMock does implement shadowhttp.Thing. 13 | // If this is not the case, regenerate this file with moq. 14 | var _ shadowhttp.Thing = &ThingMock{} 15 | 16 | // ThingMock is a mock implementation of shadowhttp.Thing. 17 | // 18 | // func TestSomethingThatUsesThing(t *testing.T) { 19 | // 20 | // // make and configure a mocked shadowhttp.Thing 21 | // mockedThing := &ThingMock{ 22 | // BlahFunc: func(w nethttp.ResponseWriter, r *nethttp.Request) { 23 | // panic("mock out the Blah method") 24 | // }, 25 | // } 26 | // 27 | // // use mockedThing in code that requires shadowhttp.Thing 28 | // // and then make assertions. 29 | // 30 | // } 31 | type ThingMock struct { 32 | // BlahFunc mocks the Blah method. 33 | BlahFunc func(w nethttp.ResponseWriter, r *nethttp.Request) 34 | 35 | // calls tracks calls to the methods. 36 | calls struct { 37 | // Blah holds details about calls to the Blah method. 38 | Blah []struct { 39 | // W is the w argument value. 40 | W nethttp.ResponseWriter 41 | // R is the r argument value. 42 | R *nethttp.Request 43 | } 44 | } 45 | lockBlah sync.RWMutex 46 | } 47 | 48 | // Blah calls BlahFunc. 49 | func (mock *ThingMock) Blah(w nethttp.ResponseWriter, r *nethttp.Request) { 50 | if mock.BlahFunc == nil { 51 | panic("ThingMock.BlahFunc: method is nil but Thing.Blah was just called") 52 | } 53 | callInfo := struct { 54 | W nethttp.ResponseWriter 55 | R *nethttp.Request 56 | }{ 57 | W: w, 58 | R: r, 59 | } 60 | mock.lockBlah.Lock() 61 | mock.calls.Blah = append(mock.calls.Blah, callInfo) 62 | mock.lockBlah.Unlock() 63 | mock.BlahFunc(w, r) 64 | } 65 | 66 | // BlahCalls gets all the calls that were made to Blah. 67 | // Check the length with: 68 | // 69 | // len(mockedThing.BlahCalls()) 70 | func (mock *ThingMock) BlahCalls() []struct { 71 | W nethttp.ResponseWriter 72 | R *nethttp.Request 73 | } { 74 | var calls []struct { 75 | W nethttp.ResponseWriter 76 | R *nethttp.Request 77 | } 78 | mock.lockBlah.RLock() 79 | calls = mock.calls.Blah 80 | mock.lockBlah.RUnlock() 81 | return calls 82 | } 83 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/shadow/shadower.go: -------------------------------------------------------------------------------- 1 | package shadow 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | ) 7 | 8 | // Shadower is an interface, with a method, with a parameter whose name 9 | // shadows an import name. 10 | type Shadower interface { 11 | Shadow(io io.Reader) 12 | ShadowTwo(r io.Reader, io interface{}) 13 | ShadowThree(http interface{}, srv *http.Server) 14 | } 15 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/shadow/shadower_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package shadow 5 | 6 | import ( 7 | "io" 8 | "net/http" 9 | "sync" 10 | ) 11 | 12 | // Ensure, that ShadowerMock does implement Shadower. 13 | // If this is not the case, regenerate this file with moq. 14 | var _ Shadower = &ShadowerMock{} 15 | 16 | // ShadowerMock is a mock implementation of Shadower. 17 | // 18 | // func TestSomethingThatUsesShadower(t *testing.T) { 19 | // 20 | // // make and configure a mocked Shadower 21 | // mockedShadower := &ShadowerMock{ 22 | // ShadowFunc: func(ioMoqParam io.Reader) { 23 | // panic("mock out the Shadow method") 24 | // }, 25 | // ShadowThreeFunc: func(httpMoqParam interface{}, srv *http.Server) { 26 | // panic("mock out the ShadowThree method") 27 | // }, 28 | // ShadowTwoFunc: func(r io.Reader, ioMoqParam interface{}) { 29 | // panic("mock out the ShadowTwo method") 30 | // }, 31 | // } 32 | // 33 | // // use mockedShadower in code that requires Shadower 34 | // // and then make assertions. 35 | // 36 | // } 37 | type ShadowerMock struct { 38 | // ShadowFunc mocks the Shadow method. 39 | ShadowFunc func(ioMoqParam io.Reader) 40 | 41 | // ShadowThreeFunc mocks the ShadowThree method. 42 | ShadowThreeFunc func(httpMoqParam interface{}, srv *http.Server) 43 | 44 | // ShadowTwoFunc mocks the ShadowTwo method. 45 | ShadowTwoFunc func(r io.Reader, ioMoqParam interface{}) 46 | 47 | // calls tracks calls to the methods. 48 | calls struct { 49 | // Shadow holds details about calls to the Shadow method. 50 | Shadow []struct { 51 | // IoMoqParam is the ioMoqParam argument value. 52 | IoMoqParam io.Reader 53 | } 54 | // ShadowThree holds details about calls to the ShadowThree method. 55 | ShadowThree []struct { 56 | // HttpMoqParam is the httpMoqParam argument value. 57 | HttpMoqParam interface{} 58 | // Srv is the srv argument value. 59 | Srv *http.Server 60 | } 61 | // ShadowTwo holds details about calls to the ShadowTwo method. 62 | ShadowTwo []struct { 63 | // R is the r argument value. 64 | R io.Reader 65 | // IoMoqParam is the ioMoqParam argument value. 66 | IoMoqParam interface{} 67 | } 68 | } 69 | lockShadow sync.RWMutex 70 | lockShadowThree sync.RWMutex 71 | lockShadowTwo sync.RWMutex 72 | } 73 | 74 | // Shadow calls ShadowFunc. 75 | func (mock *ShadowerMock) Shadow(ioMoqParam io.Reader) { 76 | if mock.ShadowFunc == nil { 77 | panic("ShadowerMock.ShadowFunc: method is nil but Shadower.Shadow was just called") 78 | } 79 | callInfo := struct { 80 | IoMoqParam io.Reader 81 | }{ 82 | IoMoqParam: ioMoqParam, 83 | } 84 | mock.lockShadow.Lock() 85 | mock.calls.Shadow = append(mock.calls.Shadow, callInfo) 86 | mock.lockShadow.Unlock() 87 | mock.ShadowFunc(ioMoqParam) 88 | } 89 | 90 | // ShadowCalls gets all the calls that were made to Shadow. 91 | // Check the length with: 92 | // 93 | // len(mockedShadower.ShadowCalls()) 94 | func (mock *ShadowerMock) ShadowCalls() []struct { 95 | IoMoqParam io.Reader 96 | } { 97 | var calls []struct { 98 | IoMoqParam io.Reader 99 | } 100 | mock.lockShadow.RLock() 101 | calls = mock.calls.Shadow 102 | mock.lockShadow.RUnlock() 103 | return calls 104 | } 105 | 106 | // ShadowThree calls ShadowThreeFunc. 107 | func (mock *ShadowerMock) ShadowThree(httpMoqParam interface{}, srv *http.Server) { 108 | if mock.ShadowThreeFunc == nil { 109 | panic("ShadowerMock.ShadowThreeFunc: method is nil but Shadower.ShadowThree was just called") 110 | } 111 | callInfo := struct { 112 | HttpMoqParam interface{} 113 | Srv *http.Server 114 | }{ 115 | HttpMoqParam: httpMoqParam, 116 | Srv: srv, 117 | } 118 | mock.lockShadowThree.Lock() 119 | mock.calls.ShadowThree = append(mock.calls.ShadowThree, callInfo) 120 | mock.lockShadowThree.Unlock() 121 | mock.ShadowThreeFunc(httpMoqParam, srv) 122 | } 123 | 124 | // ShadowThreeCalls gets all the calls that were made to ShadowThree. 125 | // Check the length with: 126 | // 127 | // len(mockedShadower.ShadowThreeCalls()) 128 | func (mock *ShadowerMock) ShadowThreeCalls() []struct { 129 | HttpMoqParam interface{} 130 | Srv *http.Server 131 | } { 132 | var calls []struct { 133 | HttpMoqParam interface{} 134 | Srv *http.Server 135 | } 136 | mock.lockShadowThree.RLock() 137 | calls = mock.calls.ShadowThree 138 | mock.lockShadowThree.RUnlock() 139 | return calls 140 | } 141 | 142 | // ShadowTwo calls ShadowTwoFunc. 143 | func (mock *ShadowerMock) ShadowTwo(r io.Reader, ioMoqParam interface{}) { 144 | if mock.ShadowTwoFunc == nil { 145 | panic("ShadowerMock.ShadowTwoFunc: method is nil but Shadower.ShadowTwo was just called") 146 | } 147 | callInfo := struct { 148 | R io.Reader 149 | IoMoqParam interface{} 150 | }{ 151 | R: r, 152 | IoMoqParam: ioMoqParam, 153 | } 154 | mock.lockShadowTwo.Lock() 155 | mock.calls.ShadowTwo = append(mock.calls.ShadowTwo, callInfo) 156 | mock.lockShadowTwo.Unlock() 157 | mock.ShadowTwoFunc(r, ioMoqParam) 158 | } 159 | 160 | // ShadowTwoCalls gets all the calls that were made to ShadowTwo. 161 | // Check the length with: 162 | // 163 | // len(mockedShadower.ShadowTwoCalls()) 164 | func (mock *ShadowerMock) ShadowTwoCalls() []struct { 165 | R io.Reader 166 | IoMoqParam interface{} 167 | } { 168 | var calls []struct { 169 | R io.Reader 170 | IoMoqParam interface{} 171 | } 172 | mock.lockShadowTwo.RLock() 173 | calls = mock.calls.ShadowTwo 174 | mock.lockShadowTwo.RUnlock() 175 | return calls 176 | } 177 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/shadowtypes/shadowtypes.go: -------------------------------------------------------------------------------- 1 | package shadowtypes 2 | 3 | import ( 4 | "github.com/matryer/moq/pkg/moq/testpackages/shadowtypes/types" 5 | ) 6 | 7 | // ShadowTypes is a test interface. 8 | type ShadowTypes interface { 9 | // ShadowString is a test method. 10 | ShadowString(string, types.String) 11 | 12 | // ShadowInt is a test method. 13 | ShadowInt(int, types.Int) 14 | // ShadowInt8 is a test method. 15 | ShadowInt8(int8, types.Int8) 16 | // ShadowInt16 is a test method. 17 | ShadowInt16(int16, types.Int16) 18 | // ShadowInt32 is a test method. 19 | ShadowInt32(int32, types.Int32) 20 | // ShadowInt64 is a test method. 21 | ShadowInt64(int64, types.Int64) 22 | 23 | // ShadowUint is a test method. 24 | ShadowUint(uint, types.Uint) 25 | // ShadowUint8 is a test method. 26 | ShadowUint8(uint8, types.Uint8) 27 | // ShadowUint16 is a test method. 28 | ShadowUint16(uint16, types.Uint16) 29 | // ShadowUint32 is a test method. 30 | ShadowUint32(uint32, types.Uint32) 31 | // ShadowUint64 is a test method. 32 | ShadowUint64(uint64, types.Uint64) 33 | 34 | // ShadowFloat32 is a test method. 35 | ShadowFloat32(float32, types.Float32) 36 | // ShadowFloat64 is a test method. 37 | ShadowFloat64(float64, types.Float64) 38 | 39 | // ShadowByte is a test method. 40 | ShadowByte(byte, types.Byte) 41 | 42 | // ShadowRune is a test method. 43 | ShadowRune(rune, types.Rune) 44 | 45 | // ShadowBool is a test method. 46 | ShadowBool(bool, types.Bool) 47 | 48 | // ShadowComplex64 is a test method. 49 | ShadowComplex64(complex64, types.Complex64) 50 | // ShadowComplex128 is a test method. 51 | ShadowComplex128(complex128, types.Complex128) 52 | 53 | // ShadowUintptr is a test method. 54 | ShadowUintptr(uintptr, types.Uintptr) 55 | } 56 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/shadowtypes/types/types.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | // String is a test type. 4 | type String string 5 | 6 | // Int is a test type. 7 | type Int int 8 | // Int8 is a test type. 9 | type Int8 int8 10 | // Int16 is a test type. 11 | type Int16 int16 12 | // Int32 is a test type. 13 | type Int32 int32 14 | // Int64 is a test type. 15 | type Int64 int64 16 | 17 | // Uint is a test type. 18 | type Uint uint 19 | // Uint8 is a test type. 20 | type Uint8 uint 21 | // Uint16 is a test type. 22 | type Uint16 uint 23 | // Uint32 is a test type. 24 | type Uint32 uint 25 | // Uint64 is a test type. 26 | type Uint64 uint 27 | 28 | // Float32 is a test type. 29 | type Float32 float32 30 | // Float64 is a test type. 31 | type Float64 float64 32 | 33 | // Byte is a test type. 34 | type Byte byte 35 | 36 | // Rune is a test type. 37 | type Rune rune 38 | 39 | // Bool is a test type. 40 | type Bool bool 41 | 42 | // Complex64 is a test type. 43 | type Complex64 complex64 44 | // Complex128 is a test type. 45 | type Complex128 complex128 46 | 47 | // Uintptr is a test type. 48 | type Uintptr uintptr 49 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/syncimport/sync/thing.go: -------------------------------------------------------------------------------- 1 | package sync 2 | 3 | // Thing is a test type. 4 | type Thing string 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/syncimport/syncer.go: -------------------------------------------------------------------------------- 1 | package syncimport 2 | 3 | import ( 4 | stdsync "sync" 5 | 6 | "github.com/matryer/moq/pkg/moq/testpackages/syncimport/sync" 7 | ) 8 | 9 | // Syncer is a test interface. 10 | type Syncer interface { 11 | Blah(s sync.Thing, wg *stdsync.WaitGroup) 12 | } 13 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/syncimport/syncer_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package syncimport 5 | 6 | import ( 7 | "github.com/matryer/moq/pkg/moq/testpackages/syncimport/sync" 8 | stdsync "sync" 9 | ) 10 | 11 | // Ensure, that SyncerMock does implement Syncer. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ Syncer = &SyncerMock{} 14 | 15 | // SyncerMock is a mock implementation of Syncer. 16 | // 17 | // func TestSomethingThatUsesSyncer(t *testing.T) { 18 | // 19 | // // make and configure a mocked Syncer 20 | // mockedSyncer := &SyncerMock{ 21 | // BlahFunc: func(s sync.Thing, wg *stdsync.WaitGroup) { 22 | // panic("mock out the Blah method") 23 | // }, 24 | // } 25 | // 26 | // // use mockedSyncer in code that requires Syncer 27 | // // and then make assertions. 28 | // 29 | // } 30 | type SyncerMock struct { 31 | // BlahFunc mocks the Blah method. 32 | BlahFunc func(s sync.Thing, wg *stdsync.WaitGroup) 33 | 34 | // calls tracks calls to the methods. 35 | calls struct { 36 | // Blah holds details about calls to the Blah method. 37 | Blah []struct { 38 | // S is the s argument value. 39 | S sync.Thing 40 | // Wg is the wg argument value. 41 | Wg *stdsync.WaitGroup 42 | } 43 | } 44 | lockBlah stdsync.RWMutex 45 | } 46 | 47 | // Blah calls BlahFunc. 48 | func (mock *SyncerMock) Blah(s sync.Thing, wg *stdsync.WaitGroup) { 49 | if mock.BlahFunc == nil { 50 | panic("SyncerMock.BlahFunc: method is nil but Syncer.Blah was just called") 51 | } 52 | callInfo := struct { 53 | S sync.Thing 54 | Wg *stdsync.WaitGroup 55 | }{ 56 | S: s, 57 | Wg: wg, 58 | } 59 | mock.lockBlah.Lock() 60 | mock.calls.Blah = append(mock.calls.Blah, callInfo) 61 | mock.lockBlah.Unlock() 62 | mock.BlahFunc(s, wg) 63 | } 64 | 65 | // BlahCalls gets all the calls that were made to Blah. 66 | // Check the length with: 67 | // 68 | // len(mockedSyncer.BlahCalls()) 69 | func (mock *SyncerMock) BlahCalls() []struct { 70 | S sync.Thing 71 | Wg *stdsync.WaitGroup 72 | } { 73 | var calls []struct { 74 | S sync.Thing 75 | Wg *stdsync.WaitGroup 76 | } 77 | mock.lockBlah.RLock() 78 | calls = mock.calls.Blah 79 | mock.lockBlah.RUnlock() 80 | return calls 81 | } 82 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/transientimport/base/type.go: -------------------------------------------------------------------------------- 1 | package base 2 | 3 | import ( 4 | four "github.com/matryer/moq/pkg/moq/testpackages/transientimport/four/app/v1" 5 | one "github.com/matryer/moq/pkg/moq/testpackages/transientimport/one/v1" 6 | "github.com/matryer/moq/pkg/moq/testpackages/transientimport/onev1" 7 | three "github.com/matryer/moq/pkg/moq/testpackages/transientimport/three/v1" 8 | two "github.com/matryer/moq/pkg/moq/testpackages/transientimport/two/app/v1" 9 | ) 10 | 11 | // Transient is a test interface. 12 | type Transient interface { 13 | DoSomething(onev1.Zero, one.One, two.Two, three.Three, four.Four) 14 | } 15 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/transientimport/four/app/v1/four.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | // Four is a test type. 4 | type Four string 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/transientimport/one/v1/one.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | // One is a test type. 4 | type One string 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/transientimport/onev1/zero.go: -------------------------------------------------------------------------------- 1 | package onev1 2 | 3 | // Zero is a test type. 4 | type Zero string 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/transientimport/three/v1/three.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | // Three is a test type. 4 | type Three string 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/transientimport/transient.go: -------------------------------------------------------------------------------- 1 | package transientimport 2 | 3 | import ( 4 | "github.com/matryer/moq/pkg/moq/testpackages/transientimport/base" 5 | ) 6 | 7 | // Transient is a test interface. 8 | type Transient = base.Transient 9 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/transientimport/transient_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package transientimport 5 | 6 | import ( 7 | fourappv1 "github.com/matryer/moq/pkg/moq/testpackages/transientimport/four/app/v1" 8 | transientimportonev1 "github.com/matryer/moq/pkg/moq/testpackages/transientimport/one/v1" 9 | testpackagestransientimportonev1 "github.com/matryer/moq/pkg/moq/testpackages/transientimport/onev1" 10 | threev1 "github.com/matryer/moq/pkg/moq/testpackages/transientimport/three/v1" 11 | twoappv1 "github.com/matryer/moq/pkg/moq/testpackages/transientimport/two/app/v1" 12 | "sync" 13 | ) 14 | 15 | // Ensure, that TransientMock does implement Transient. 16 | // If this is not the case, regenerate this file with moq. 17 | var _ Transient = &TransientMock{} 18 | 19 | // TransientMock is a mock implementation of Transient. 20 | // 21 | // func TestSomethingThatUsesTransient(t *testing.T) { 22 | // 23 | // // make and configure a mocked Transient 24 | // mockedTransient := &TransientMock{ 25 | // DoSomethingFunc: func(zero testpackagestransientimportonev1.Zero, one transientimportonev1.One, two twoappv1.Two, three threev1.Three, four fourappv1.Four) { 26 | // panic("mock out the DoSomething method") 27 | // }, 28 | // } 29 | // 30 | // // use mockedTransient in code that requires Transient 31 | // // and then make assertions. 32 | // 33 | // } 34 | type TransientMock struct { 35 | // DoSomethingFunc mocks the DoSomething method. 36 | DoSomethingFunc func(zero testpackagestransientimportonev1.Zero, one transientimportonev1.One, two twoappv1.Two, three threev1.Three, four fourappv1.Four) 37 | 38 | // calls tracks calls to the methods. 39 | calls struct { 40 | // DoSomething holds details about calls to the DoSomething method. 41 | DoSomething []struct { 42 | // Zero is the zero argument value. 43 | Zero testpackagestransientimportonev1.Zero 44 | // One is the one argument value. 45 | One transientimportonev1.One 46 | // Two is the two argument value. 47 | Two twoappv1.Two 48 | // Three is the three argument value. 49 | Three threev1.Three 50 | // Four is the four argument value. 51 | Four fourappv1.Four 52 | } 53 | } 54 | lockDoSomething sync.RWMutex 55 | } 56 | 57 | // DoSomething calls DoSomethingFunc. 58 | func (mock *TransientMock) DoSomething(zero testpackagestransientimportonev1.Zero, one transientimportonev1.One, two twoappv1.Two, three threev1.Three, four fourappv1.Four) { 59 | if mock.DoSomethingFunc == nil { 60 | panic("TransientMock.DoSomethingFunc: method is nil but Transient.DoSomething was just called") 61 | } 62 | callInfo := struct { 63 | Zero testpackagestransientimportonev1.Zero 64 | One transientimportonev1.One 65 | Two twoappv1.Two 66 | Three threev1.Three 67 | Four fourappv1.Four 68 | }{ 69 | Zero: zero, 70 | One: one, 71 | Two: two, 72 | Three: three, 73 | Four: four, 74 | } 75 | mock.lockDoSomething.Lock() 76 | mock.calls.DoSomething = append(mock.calls.DoSomething, callInfo) 77 | mock.lockDoSomething.Unlock() 78 | mock.DoSomethingFunc(zero, one, two, three, four) 79 | } 80 | 81 | // DoSomethingCalls gets all the calls that were made to DoSomething. 82 | // Check the length with: 83 | // 84 | // len(mockedTransient.DoSomethingCalls()) 85 | func (mock *TransientMock) DoSomethingCalls() []struct { 86 | Zero testpackagestransientimportonev1.Zero 87 | One transientimportonev1.One 88 | Two twoappv1.Two 89 | Three threev1.Three 90 | Four fourappv1.Four 91 | } { 92 | var calls []struct { 93 | Zero testpackagestransientimportonev1.Zero 94 | One transientimportonev1.One 95 | Two twoappv1.Two 96 | Three threev1.Three 97 | Four fourappv1.Four 98 | } 99 | mock.lockDoSomething.RLock() 100 | calls = mock.calls.DoSomething 101 | mock.lockDoSomething.RUnlock() 102 | return calls 103 | } 104 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/transientimport/two/app/v1/two.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | // Two is a test type. 4 | type Two string 5 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/typealias/typealias.go: -------------------------------------------------------------------------------- 1 | package typealias 2 | 3 | import ( 4 | "github.com/matryer/moq/pkg/moq/testpackages/typealiastwo" 5 | ) 6 | 7 | type Example interface { 8 | Do(a typealiastwo.AliasType, b typealiastwo.GenericAliasType) error 9 | } 10 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/typealias/typealias_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package typealias 5 | 6 | import ( 7 | "github.com/matryer/moq/pkg/moq/testpackages/typealiastwo" 8 | "sync" 9 | ) 10 | 11 | // Ensure, that ExampleMock does implement Example. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ Example = &ExampleMock{} 14 | 15 | // ExampleMock is a mock implementation of Example. 16 | // 17 | // func TestSomethingThatUsesExample(t *testing.T) { 18 | // 19 | // // make and configure a mocked Example 20 | // mockedExample := &ExampleMock{ 21 | // DoFunc: func(a typealiastwo.AliasType, b typealiastwo.GenericAliasType) error { 22 | // panic("mock out the Do method") 23 | // }, 24 | // } 25 | // 26 | // // use mockedExample in code that requires Example 27 | // // and then make assertions. 28 | // 29 | // } 30 | type ExampleMock struct { 31 | // DoFunc mocks the Do method. 32 | DoFunc func(a typealiastwo.AliasType, b typealiastwo.GenericAliasType) error 33 | 34 | // calls tracks calls to the methods. 35 | calls struct { 36 | // Do holds details about calls to the Do method. 37 | Do []struct { 38 | // A is the a argument value. 39 | A typealiastwo.AliasType 40 | // B is the b argument value. 41 | B typealiastwo.GenericAliasType 42 | } 43 | } 44 | lockDo sync.RWMutex 45 | } 46 | 47 | // Do calls DoFunc. 48 | func (mock *ExampleMock) Do(a typealiastwo.AliasType, b typealiastwo.GenericAliasType) error { 49 | if mock.DoFunc == nil { 50 | panic("ExampleMock.DoFunc: method is nil but Example.Do was just called") 51 | } 52 | callInfo := struct { 53 | A typealiastwo.AliasType 54 | B typealiastwo.GenericAliasType 55 | }{ 56 | A: a, 57 | B: b, 58 | } 59 | mock.lockDo.Lock() 60 | mock.calls.Do = append(mock.calls.Do, callInfo) 61 | mock.lockDo.Unlock() 62 | return mock.DoFunc(a, b) 63 | } 64 | 65 | // DoCalls gets all the calls that were made to Do. 66 | // Check the length with: 67 | // 68 | // len(mockedExample.DoCalls()) 69 | func (mock *ExampleMock) DoCalls() []struct { 70 | A typealiastwo.AliasType 71 | B typealiastwo.GenericAliasType 72 | } { 73 | var calls []struct { 74 | A typealiastwo.AliasType 75 | B typealiastwo.GenericAliasType 76 | } 77 | mock.lockDo.RLock() 78 | calls = mock.calls.Do 79 | mock.lockDo.RUnlock() 80 | return calls 81 | } 82 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/typealiastwo/internal/typealiasinternal/typealiasinternal.go: -------------------------------------------------------------------------------- 1 | package typealiasinternal 2 | 3 | // we shouldn't be able to import these types directly, you need to use the alias in the parent package 4 | type MyInternalType struct { 5 | Foo int 6 | } 7 | 8 | type MyGenericType[T any] struct { 9 | A T 10 | } 11 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/typealiastwo/typealiastwo.go: -------------------------------------------------------------------------------- 1 | package typealiastwo 2 | 3 | import "github.com/matryer/moq/pkg/moq/testpackages/typealiastwo/internal/typealiasinternal" 4 | 5 | type AliasType = typealiasinternal.MyInternalType 6 | 7 | type GenericAliasType = typealiasinternal.MyGenericType[int] 8 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/variadic/echoer.go: -------------------------------------------------------------------------------- 1 | package variadic 2 | 3 | // Echoer is an interface. 4 | type Echoer interface { 5 | Echo(ss ...string) []string 6 | } 7 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/variadic/echoer.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package variadic 5 | 6 | import ( 7 | "sync" 8 | ) 9 | 10 | // Ensure, that EchoerMock does implement Echoer. 11 | // If this is not the case, regenerate this file with moq. 12 | var _ Echoer = &EchoerMock{} 13 | 14 | // EchoerMock is a mock implementation of Echoer. 15 | // 16 | // func TestSomethingThatUsesEchoer(t *testing.T) { 17 | // 18 | // // make and configure a mocked Echoer 19 | // mockedEchoer := &EchoerMock{ 20 | // EchoFunc: func(ss ...string) []string { 21 | // panic("mock out the Echo method") 22 | // }, 23 | // } 24 | // 25 | // // use mockedEchoer in code that requires Echoer 26 | // // and then make assertions. 27 | // 28 | // } 29 | type EchoerMock struct { 30 | // EchoFunc mocks the Echo method. 31 | EchoFunc func(ss ...string) []string 32 | 33 | // calls tracks calls to the methods. 34 | calls struct { 35 | // Echo holds details about calls to the Echo method. 36 | Echo []struct { 37 | // Ss is the ss argument value. 38 | Ss []string 39 | } 40 | } 41 | lockEcho sync.RWMutex 42 | } 43 | 44 | // Echo calls EchoFunc. 45 | func (mock *EchoerMock) Echo(ss ...string) []string { 46 | if mock.EchoFunc == nil { 47 | panic("EchoerMock.EchoFunc: method is nil but Echoer.Echo was just called") 48 | } 49 | callInfo := struct { 50 | Ss []string 51 | }{ 52 | Ss: ss, 53 | } 54 | mock.lockEcho.Lock() 55 | mock.calls.Echo = append(mock.calls.Echo, callInfo) 56 | mock.lockEcho.Unlock() 57 | return mock.EchoFunc(ss...) 58 | } 59 | 60 | // EchoCalls gets all the calls that were made to Echo. 61 | // Check the length with: 62 | // 63 | // len(mockedEchoer.EchoCalls()) 64 | func (mock *EchoerMock) EchoCalls() []struct { 65 | Ss []string 66 | } { 67 | var calls []struct { 68 | Ss []string 69 | } 70 | mock.lockEcho.RLock() 71 | calls = mock.calls.Echo 72 | mock.lockEcho.RUnlock() 73 | return calls 74 | } 75 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/variadic/greeter.go: -------------------------------------------------------------------------------- 1 | package variadic 2 | 3 | import "context" 4 | 5 | // Greeter greets people. 6 | type Greeter interface { 7 | Greet(ctx context.Context, names ...string) string 8 | } 9 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/vendor/github.com/sudo-suhas/moq-test-pkgs/somerepo/code.go: -------------------------------------------------------------------------------- 1 | // Package somerepo is a vendored package to test how moq deals with 2 | // packages in the vendor package. 3 | package somerepo 4 | 5 | // SomeType is just some old type. 6 | type SomeType struct { 7 | // Truth indicates whether true is true or not. Computers. 8 | Truth bool 9 | } 10 | 11 | // SomeService is a test interface. 12 | type SomeService interface { 13 | Get() SomeType 14 | } 15 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/vendor/github.com/sudo-suhas/moq-test-pkgs/somerepo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/sudo-suhas/moq-test-pkgs/somerepo 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/vendor/modules.txt: -------------------------------------------------------------------------------- 1 | # github.com/sudo-suhas/moq-test-pkgs/somerepo v0.0.0-20200816045313-d2f573eea6c7 2 | ## explicit 3 | github.com/sudo-suhas/moq-test-pkgs/somerepo 4 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/vendoring/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/matryer/moq/pkg/moq/testpackages/vendoring 2 | 3 | go 1.14 4 | 5 | require github.com/sudo-suhas/moq-test-pkgs/somerepo v0.0.0-20200816045313-d2f573eea6c7 6 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/vendoring/go.sum: -------------------------------------------------------------------------------- 1 | github.com/sudo-suhas/moq-test-pkgs/somerepo v0.0.0-20200816045313-d2f573eea6c7 h1:5TDSgxW5A9Homgu8Kh0iB1aeRCgM1y8pZaxAR0TjeQs= 2 | github.com/sudo-suhas/moq-test-pkgs/somerepo v0.0.0-20200816045313-d2f573eea6c7/go.mod h1:3CK3+2qBd+EkNJP+dgGjVYIbEwRQWVf6EgcmyIjTi2A= 3 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/vendoring/user/user.go: -------------------------------------------------------------------------------- 1 | package user 2 | 3 | import "github.com/sudo-suhas/moq-test-pkgs/somerepo" 4 | 5 | // Service does something good with computers. 6 | type Service interface { 7 | DoSomething(somerepo.SomeType) error 8 | } 9 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/vendoring/vendor/github.com/sudo-suhas/moq-test-pkgs/somerepo/code.go: -------------------------------------------------------------------------------- 1 | // Package somerepo is a vendored package to test how moq deals with 2 | // packages in the vendor package. 3 | package somerepo 4 | 5 | // SomeType is just some old type. 6 | type SomeType struct { 7 | // Truth indicates whether true is true or not. Computers. 8 | Truth bool 9 | } 10 | 11 | // SomeService is a test interface. 12 | type SomeService interface { 13 | Get() SomeType 14 | } 15 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/vendoring/vendor/github.com/sudo-suhas/moq-test-pkgs/somerepo/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/sudo-suhas/moq-test-pkgs/somerepo 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/vendoring/vendor/modules.txt: -------------------------------------------------------------------------------- 1 | # github.com/sudo-suhas/moq-test-pkgs/somerepo v0.0.0-20200816045313-d2f573eea6c7 2 | ## explicit 3 | github.com/sudo-suhas/moq-test-pkgs/somerepo 4 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/withresets/withresets.go: -------------------------------------------------------------------------------- 1 | package withresets 2 | 3 | import "context" 4 | 5 | // Reset is a reset. 6 | type Reset struct { 7 | ID string 8 | Name string 9 | Company string 10 | Website string 11 | } 12 | 13 | // ResetStore stores resets. 14 | type ResetStore interface { 15 | Get(ctx context.Context, id string) (*Reset, error) 16 | Create(ctx context.Context, person *Reset, confirm bool) error 17 | ClearCache(id string) 18 | } 19 | 20 | type ResetStoreGeneric[T, S any] interface { 21 | Get(ctx context.Context, id T) (string, error) 22 | Create(ctx context.Context, id T, value S) error 23 | } 24 | -------------------------------------------------------------------------------- /pkg/moq/testpackages/withresets/withresets_moq.golden.go: -------------------------------------------------------------------------------- 1 | // Code generated by moq; DO NOT EDIT. 2 | // github.com/matryer/moq 3 | 4 | package withresets 5 | 6 | import ( 7 | "context" 8 | "sync" 9 | ) 10 | 11 | // Ensure, that ResetStoreMock does implement ResetStore. 12 | // If this is not the case, regenerate this file with moq. 13 | var _ ResetStore = &ResetStoreMock{} 14 | 15 | // ResetStoreMock is a mock implementation of ResetStore. 16 | // 17 | // func TestSomethingThatUsesResetStore(t *testing.T) { 18 | // 19 | // // make and configure a mocked ResetStore 20 | // mockedResetStore := &ResetStoreMock{ 21 | // ClearCacheFunc: func(id string) { 22 | // panic("mock out the ClearCache method") 23 | // }, 24 | // CreateFunc: func(ctx context.Context, person *Reset, confirm bool) error { 25 | // panic("mock out the Create method") 26 | // }, 27 | // GetFunc: func(ctx context.Context, id string) (*Reset, error) { 28 | // panic("mock out the Get method") 29 | // }, 30 | // } 31 | // 32 | // // use mockedResetStore in code that requires ResetStore 33 | // // and then make assertions. 34 | // 35 | // } 36 | type ResetStoreMock struct { 37 | // ClearCacheFunc mocks the ClearCache method. 38 | ClearCacheFunc func(id string) 39 | 40 | // CreateFunc mocks the Create method. 41 | CreateFunc func(ctx context.Context, person *Reset, confirm bool) error 42 | 43 | // GetFunc mocks the Get method. 44 | GetFunc func(ctx context.Context, id string) (*Reset, error) 45 | 46 | // calls tracks calls to the methods. 47 | calls struct { 48 | // ClearCache holds details about calls to the ClearCache method. 49 | ClearCache []struct { 50 | // ID is the id argument value. 51 | ID string 52 | } 53 | // Create holds details about calls to the Create method. 54 | Create []struct { 55 | // Ctx is the ctx argument value. 56 | Ctx context.Context 57 | // Person is the person argument value. 58 | Person *Reset 59 | // Confirm is the confirm argument value. 60 | Confirm bool 61 | } 62 | // Get holds details about calls to the Get method. 63 | Get []struct { 64 | // Ctx is the ctx argument value. 65 | Ctx context.Context 66 | // ID is the id argument value. 67 | ID string 68 | } 69 | } 70 | lockClearCache sync.RWMutex 71 | lockCreate sync.RWMutex 72 | lockGet sync.RWMutex 73 | } 74 | 75 | // ClearCache calls ClearCacheFunc. 76 | func (mock *ResetStoreMock) ClearCache(id string) { 77 | if mock.ClearCacheFunc == nil { 78 | panic("ResetStoreMock.ClearCacheFunc: method is nil but ResetStore.ClearCache was just called") 79 | } 80 | callInfo := struct { 81 | ID string 82 | }{ 83 | ID: id, 84 | } 85 | mock.lockClearCache.Lock() 86 | mock.calls.ClearCache = append(mock.calls.ClearCache, callInfo) 87 | mock.lockClearCache.Unlock() 88 | mock.ClearCacheFunc(id) 89 | } 90 | 91 | // ClearCacheCalls gets all the calls that were made to ClearCache. 92 | // Check the length with: 93 | // 94 | // len(mockedResetStore.ClearCacheCalls()) 95 | func (mock *ResetStoreMock) ClearCacheCalls() []struct { 96 | ID string 97 | } { 98 | var calls []struct { 99 | ID string 100 | } 101 | mock.lockClearCache.RLock() 102 | calls = mock.calls.ClearCache 103 | mock.lockClearCache.RUnlock() 104 | return calls 105 | } 106 | 107 | // ResetClearCacheCalls reset all the calls that were made to ClearCache. 108 | func (mock *ResetStoreMock) ResetClearCacheCalls() { 109 | mock.lockClearCache.Lock() 110 | mock.calls.ClearCache = nil 111 | mock.lockClearCache.Unlock() 112 | } 113 | 114 | // Create calls CreateFunc. 115 | func (mock *ResetStoreMock) Create(ctx context.Context, person *Reset, confirm bool) error { 116 | if mock.CreateFunc == nil { 117 | panic("ResetStoreMock.CreateFunc: method is nil but ResetStore.Create was just called") 118 | } 119 | callInfo := struct { 120 | Ctx context.Context 121 | Person *Reset 122 | Confirm bool 123 | }{ 124 | Ctx: ctx, 125 | Person: person, 126 | Confirm: confirm, 127 | } 128 | mock.lockCreate.Lock() 129 | mock.calls.Create = append(mock.calls.Create, callInfo) 130 | mock.lockCreate.Unlock() 131 | return mock.CreateFunc(ctx, person, confirm) 132 | } 133 | 134 | // CreateCalls gets all the calls that were made to Create. 135 | // Check the length with: 136 | // 137 | // len(mockedResetStore.CreateCalls()) 138 | func (mock *ResetStoreMock) CreateCalls() []struct { 139 | Ctx context.Context 140 | Person *Reset 141 | Confirm bool 142 | } { 143 | var calls []struct { 144 | Ctx context.Context 145 | Person *Reset 146 | Confirm bool 147 | } 148 | mock.lockCreate.RLock() 149 | calls = mock.calls.Create 150 | mock.lockCreate.RUnlock() 151 | return calls 152 | } 153 | 154 | // ResetCreateCalls reset all the calls that were made to Create. 155 | func (mock *ResetStoreMock) ResetCreateCalls() { 156 | mock.lockCreate.Lock() 157 | mock.calls.Create = nil 158 | mock.lockCreate.Unlock() 159 | } 160 | 161 | // Get calls GetFunc. 162 | func (mock *ResetStoreMock) Get(ctx context.Context, id string) (*Reset, error) { 163 | if mock.GetFunc == nil { 164 | panic("ResetStoreMock.GetFunc: method is nil but ResetStore.Get was just called") 165 | } 166 | callInfo := struct { 167 | Ctx context.Context 168 | ID string 169 | }{ 170 | Ctx: ctx, 171 | ID: id, 172 | } 173 | mock.lockGet.Lock() 174 | mock.calls.Get = append(mock.calls.Get, callInfo) 175 | mock.lockGet.Unlock() 176 | return mock.GetFunc(ctx, id) 177 | } 178 | 179 | // GetCalls gets all the calls that were made to Get. 180 | // Check the length with: 181 | // 182 | // len(mockedResetStore.GetCalls()) 183 | func (mock *ResetStoreMock) GetCalls() []struct { 184 | Ctx context.Context 185 | ID string 186 | } { 187 | var calls []struct { 188 | Ctx context.Context 189 | ID string 190 | } 191 | mock.lockGet.RLock() 192 | calls = mock.calls.Get 193 | mock.lockGet.RUnlock() 194 | return calls 195 | } 196 | 197 | // ResetGetCalls reset all the calls that were made to Get. 198 | func (mock *ResetStoreMock) ResetGetCalls() { 199 | mock.lockGet.Lock() 200 | mock.calls.Get = nil 201 | mock.lockGet.Unlock() 202 | } 203 | 204 | // ResetCalls reset all the calls that were made to all mocked methods. 205 | func (mock *ResetStoreMock) ResetCalls() { 206 | mock.lockClearCache.Lock() 207 | mock.calls.ClearCache = nil 208 | mock.lockClearCache.Unlock() 209 | 210 | mock.lockCreate.Lock() 211 | mock.calls.Create = nil 212 | mock.lockCreate.Unlock() 213 | 214 | mock.lockGet.Lock() 215 | mock.calls.Get = nil 216 | mock.lockGet.Unlock() 217 | } 218 | 219 | // Ensure, that ResetStoreGenericMock does implement ResetStoreGeneric. 220 | // If this is not the case, regenerate this file with moq. 221 | var _ ResetStoreGeneric[any, any] = &ResetStoreGenericMock[any, any]{} 222 | 223 | // ResetStoreGenericMock is a mock implementation of ResetStoreGeneric. 224 | // 225 | // func TestSomethingThatUsesResetStoreGeneric(t *testing.T) { 226 | // 227 | // // make and configure a mocked ResetStoreGeneric 228 | // mockedResetStoreGeneric := &ResetStoreGenericMock{ 229 | // CreateFunc: func(ctx context.Context, id T, value S) error { 230 | // panic("mock out the Create method") 231 | // }, 232 | // GetFunc: func(ctx context.Context, id T) (string, error) { 233 | // panic("mock out the Get method") 234 | // }, 235 | // } 236 | // 237 | // // use mockedResetStoreGeneric in code that requires ResetStoreGeneric 238 | // // and then make assertions. 239 | // 240 | // } 241 | type ResetStoreGenericMock[T any, S any] struct { 242 | // CreateFunc mocks the Create method. 243 | CreateFunc func(ctx context.Context, id T, value S) error 244 | 245 | // GetFunc mocks the Get method. 246 | GetFunc func(ctx context.Context, id T) (string, error) 247 | 248 | // calls tracks calls to the methods. 249 | calls struct { 250 | // Create holds details about calls to the Create method. 251 | Create []struct { 252 | // Ctx is the ctx argument value. 253 | Ctx context.Context 254 | // ID is the id argument value. 255 | ID T 256 | // Value is the value argument value. 257 | Value S 258 | } 259 | // Get holds details about calls to the Get method. 260 | Get []struct { 261 | // Ctx is the ctx argument value. 262 | Ctx context.Context 263 | // ID is the id argument value. 264 | ID T 265 | } 266 | } 267 | lockCreate sync.RWMutex 268 | lockGet sync.RWMutex 269 | } 270 | 271 | // Create calls CreateFunc. 272 | func (mock *ResetStoreGenericMock[T, S]) Create(ctx context.Context, id T, value S) error { 273 | if mock.CreateFunc == nil { 274 | panic("ResetStoreGenericMock.CreateFunc: method is nil but ResetStoreGeneric.Create was just called") 275 | } 276 | callInfo := struct { 277 | Ctx context.Context 278 | ID T 279 | Value S 280 | }{ 281 | Ctx: ctx, 282 | ID: id, 283 | Value: value, 284 | } 285 | mock.lockCreate.Lock() 286 | mock.calls.Create = append(mock.calls.Create, callInfo) 287 | mock.lockCreate.Unlock() 288 | return mock.CreateFunc(ctx, id, value) 289 | } 290 | 291 | // CreateCalls gets all the calls that were made to Create. 292 | // Check the length with: 293 | // 294 | // len(mockedResetStoreGeneric.CreateCalls()) 295 | func (mock *ResetStoreGenericMock[T, S]) CreateCalls() []struct { 296 | Ctx context.Context 297 | ID T 298 | Value S 299 | } { 300 | var calls []struct { 301 | Ctx context.Context 302 | ID T 303 | Value S 304 | } 305 | mock.lockCreate.RLock() 306 | calls = mock.calls.Create 307 | mock.lockCreate.RUnlock() 308 | return calls 309 | } 310 | 311 | // ResetCreateCalls reset all the calls that were made to Create. 312 | func (mock *ResetStoreGenericMock[T, S]) ResetCreateCalls() { 313 | mock.lockCreate.Lock() 314 | mock.calls.Create = nil 315 | mock.lockCreate.Unlock() 316 | } 317 | 318 | // Get calls GetFunc. 319 | func (mock *ResetStoreGenericMock[T, S]) Get(ctx context.Context, id T) (string, error) { 320 | if mock.GetFunc == nil { 321 | panic("ResetStoreGenericMock.GetFunc: method is nil but ResetStoreGeneric.Get was just called") 322 | } 323 | callInfo := struct { 324 | Ctx context.Context 325 | ID T 326 | }{ 327 | Ctx: ctx, 328 | ID: id, 329 | } 330 | mock.lockGet.Lock() 331 | mock.calls.Get = append(mock.calls.Get, callInfo) 332 | mock.lockGet.Unlock() 333 | return mock.GetFunc(ctx, id) 334 | } 335 | 336 | // GetCalls gets all the calls that were made to Get. 337 | // Check the length with: 338 | // 339 | // len(mockedResetStoreGeneric.GetCalls()) 340 | func (mock *ResetStoreGenericMock[T, S]) GetCalls() []struct { 341 | Ctx context.Context 342 | ID T 343 | } { 344 | var calls []struct { 345 | Ctx context.Context 346 | ID T 347 | } 348 | mock.lockGet.RLock() 349 | calls = mock.calls.Get 350 | mock.lockGet.RUnlock() 351 | return calls 352 | } 353 | 354 | // ResetGetCalls reset all the calls that were made to Get. 355 | func (mock *ResetStoreGenericMock[T, S]) ResetGetCalls() { 356 | mock.lockGet.Lock() 357 | mock.calls.Get = nil 358 | mock.lockGet.Unlock() 359 | } 360 | 361 | // ResetCalls reset all the calls that were made to all mocked methods. 362 | func (mock *ResetStoreGenericMock[T, S]) ResetCalls() { 363 | mock.lockCreate.Lock() 364 | mock.calls.Create = nil 365 | mock.lockCreate.Unlock() 366 | 367 | mock.lockGet.Lock() 368 | mock.calls.Get = nil 369 | mock.lockGet.Unlock() 370 | } 371 | -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matryer/moq/31af695e859b89ed710ee12c07720cea3e656b68/preview.png -------------------------------------------------------------------------------- /releasing.md: -------------------------------------------------------------------------------- 1 | # Releasing 2 | 3 | This tool uses Go Releaser to manage release builds. 4 | 5 | ## Setup 6 | 7 | Install Go Releaser. 8 | 9 | ```bash 10 | brew install goreleaser/tap/goreleaser 11 | ``` 12 | 13 | * Make a [New personal access token on GitHub](https://github.com/settings/tokens/new) and set it as the `GITHUB_TOKEN` environment variable 14 | 15 | ## Releasing 16 | 17 | Tag the repo: 18 | 19 | ```bash 20 | $ git tag -a v0.1.0 -m "release tag." 21 | $ git push origin v0.1.0 22 | ``` 23 | 24 | Then: 25 | 26 | ```bash 27 | GITHUB_TOKEN=xxx goreleaser --clean 28 | ``` 29 | 30 | ## Testing 31 | 32 | To test and verify changes to Go Releaser config, use the following: 33 | 34 | ```bash 35 | goreleaser --snapshot --skip=publish --clean 36 | ``` 37 | --------------------------------------------------------------------------------