├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── codeql-analysis.yml │ └── go.yml ├── .gitignore ├── .golangci.yaml ├── LICENSE ├── README.md ├── arguments ├── files.go ├── parser.go ├── parser_test.go ├── parser_windows_test.go └── usage.go ├── benchmark_test.go ├── command ├── runner.go ├── runner_internals_test.go └── runner_test.go ├── fixtures ├── aliased_interfaces.go ├── aliased_package │ ├── aliased_packagefakes │ │ └── fake_in_aliased_package.go │ └── in_aliased_package.go ├── another_package │ ├── another_packagefakes │ │ └── fake_another_interface.go │ └── types.go ├── blank.go ├── compound_return.go ├── custom_output.go ├── customfakesdir │ └── fake_custom_output.go ├── dot_imports.go ├── dup_packages │ ├── a │ │ ├── a.go │ │ └── foo │ │ │ └── a.go │ ├── alias.go │ ├── b │ │ └── foo │ │ │ └── b.go │ ├── dupA.go │ ├── dupAB.go │ ├── dupB.go │ ├── dup_packagenames.go │ ├── foo │ │ └── multi_import.go │ └── go.mod ├── embeds_interfaces.go ├── externalpkg │ ├── aliased_interface.go │ └── externalpkgfakes │ │ └── fake_context.go ├── fixturesfakes │ ├── fake_aliased_interface.go │ ├── fake_dot_imports.go │ ├── fake_embeds_interfaces.go │ ├── fake_first_interface.go │ ├── fake_has_imports.go │ ├── fake_has_other_types.go │ ├── fake_has_var_args.go │ ├── fake_has_var_args_with_local_types.go │ ├── fake_imports_go_hyphen_package.go │ ├── fake_inline_struct_params.go │ ├── fake_reuses_arg_types.go │ ├── fake_second_interface.go │ ├── fake_something.go │ ├── fake_something_else.go │ ├── fake_something_factory.go │ ├── fake_something_with_foreign_interface.go │ ├── fake_unexported_func.go │ └── fake_unexported_interface.go ├── genericinterface │ ├── genericinterface.go │ └── genericinterfacefakes │ │ ├── fake_generic_interface.go │ │ ├── fake_generic_interface_any.go │ │ └── fake_generic_interface_multiple_types.go ├── genericparam │ ├── genericparam.go │ ├── genericparamfakes │ │ ├── fake_generic_param_func.go │ │ └── fake_generic_param_interface.go │ ├── genericparamtype │ │ └── genericparamtype.go │ └── genericreturntype │ │ └── genericreturntype.go ├── go-hyphenpackage │ └── fixture.go ├── has_imports.go ├── has_other_types.go ├── has_var_args.go ├── headers │ ├── default.header.go.txt │ ├── defaultheader │ │ ├── defaultheaderfakes │ │ │ ├── fake_header_default.go │ │ │ └── fake_header_specific.go │ │ └── header.go │ ├── nodefaultheader │ │ ├── headers.go │ │ └── nodefaultheaderfakes │ │ │ ├── fake_header_default.go │ │ │ └── fake_header_specific.go │ └── specific.header.go.txt ├── hyphenated_package_same_name │ ├── go.mod │ ├── hyphen-ated │ │ └── some_package │ │ │ └── types.go │ └── some_package │ │ └── interface.go ├── imports_go_hyphen_package.go ├── inline_struct_params.go ├── internalpkg │ ├── aliased_interface.go │ ├── internal │ │ └── internal_interface.go │ └── internalpkgfakes │ │ └── fake_context.go ├── multiple_interfaces.go ├── other_types.go ├── packagegen │ ├── apackage │ │ └── apackage.go │ └── package_gen.go ├── packagemode │ ├── flag.go │ ├── flagcustomfakesdir │ │ ├── flagcustomfakesdirfakes │ │ │ └── fake_packagemode.go │ │ └── packagemode.go │ └── packagemodeshim │ │ ├── packagemode.go │ │ └── packagemodeshimfakes │ │ └── fake_packagemode.go ├── request_factory.go ├── reuses_arg_types.go ├── something.go ├── something_remote.go ├── sql │ ├── db.go │ └── sqlfakes │ │ └── fake_db.go ├── sync │ ├── interface.go │ └── syncfakes │ │ └── fake_sync_something.go ├── type_aliases │ ├── extra │ │ ├── m.go │ │ └── primitive │ │ │ └── m.go │ ├── go.mod │ └── interface.go ├── typed_function.go └── unexported.go ├── generated_fakes_test.go ├── generator ├── cache.go ├── ctx.go ├── ctx_old.go ├── fake.go ├── file_reader.go ├── file_reader_other_test.go ├── file_reader_test.go ├── file_reader_windows_test.go ├── function_loader.go ├── function_template.go ├── generator_internals_test.go ├── import.go ├── import_test.go ├── interface_loader.go ├── interface_template.go ├── loader.go ├── package_loader.go ├── package_template.go ├── param.go └── return.go ├── go.mod ├── go.sum ├── integration ├── copy_test.go ├── empty.go ├── roundtrip_module_test.go ├── roundtrip_test.go ├── testdata │ ├── expected_fake_multiab.txt │ ├── expected_fake_somethingfactory.txt │ ├── expected_fake_writecloser.header.txt │ └── expected_fake_writecloser.noheader.txt └── util_test.go ├── main.go └── scripts ├── checkclean.sh ├── ci.ps1 ├── ci.sh ├── cleanfakes.sh └── counterfeiter.bat /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.145.1/containers/go/.devcontainer/base.Dockerfile 2 | 3 | # [Choice] Go version: 1, 1.15, 1.14 4 | ARG VARIANT="1" 5 | FROM mcr.microsoft.com/vscode/devcontainers/go:0-${VARIANT} 6 | 7 | # [Option] Install Node.js 8 | ARG INSTALL_NODE="false" 9 | ARG NODE_VERSION="lts/*" 10 | RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi 11 | 12 | # [Optional] Uncomment this section to install additional OS packages. 13 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 14 | # && apt-get -y install --no-install-recommends 15 | 16 | # [Optional] Uncomment the next line to use go get to install anything else you need 17 | # RUN go get -x 18 | 19 | # [Optional] Uncomment this line to install global node packages. 20 | # RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Go", 3 | "build": { 4 | "dockerfile": "Dockerfile", 5 | "args": { 6 | // Update the VARIANT arg to pick a version of Go: 1, 1.15, 1.14 7 | "VARIANT": "1", 8 | // Options 9 | "INSTALL_NODE": "false", 10 | "NODE_VERSION": "lts/*" 11 | } 12 | }, 13 | "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ], 14 | 15 | // Set *default* container specific settings.json values on container create. 16 | "settings": { 17 | "ref": "vscode://schemas/settings/machine", 18 | "go.toolsManagement.checkForUpdates": "proxy", 19 | "go.useLanguageServer": true, 20 | "go.gopath": "/go", 21 | "go.goroot": "/usr/local/go", 22 | "go.toolsGopath": "/go/bin" 23 | }, 24 | 25 | // Add the IDs of extensions you want installed when the container is created. 26 | "extensions": [ 27 | "golang.Go" 28 | ] 29 | 30 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 31 | // "forwardPorts": [], 32 | 33 | // Use 'postCreateCommand' to run commands after the container is created. 34 | // "postCreateCommand": "go version", 35 | 36 | // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. 37 | // "remoteUser": "vscode" 38 | } 39 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: gomod 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "13:00" 8 | open-pull-requests-limit: 100 9 | reviewers: 10 | - "joefitzgerald" 11 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: 'CodeQL' 13 | 14 | on: 15 | push: 16 | branches: [main] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [main] 20 | schedule: 21 | - cron: '45 1 * * 2' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: ['go'] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v1 72 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | on: 3 | push: 4 | pull_request: 5 | workflow_dispatch: 6 | inputs: 7 | debug_enabled: 8 | type: boolean 9 | description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)' 10 | required: false 11 | default: false 12 | jobs: 13 | build: 14 | name: Build and Test 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | matrix: 18 | go: [stable, oldstable] 19 | os: [ubuntu-latest, windows-latest] 20 | steps: 21 | - name: Set git to use LF 22 | run: | 23 | git config --global core.autocrlf false 24 | git config --global core.eol lf 25 | - uses: actions/checkout@v4 26 | - name: Set up Go 27 | uses: actions/setup-go@v4 28 | with: 29 | go-version: ${{ matrix.go }} 30 | # Enable tmate debugging of manually-triggered workflows if the input option was provided 31 | - name: Setup tmate session 32 | uses: mxschmitt/action-tmate@v3 33 | if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} 34 | - name: Build and Test (Linux and macOS) 35 | run: ./scripts/ci.sh 36 | if: ${{ matrix.os != 'windows-latest' }} 37 | - name: Build and Test (Windows) 38 | run: .\scripts\ci.ps1 39 | if: ${{ matrix.os == 'windows-latest' }} 40 | -------------------------------------------------------------------------------- /.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 | *.iml 25 | .idea 26 | .envrc 27 | 28 | /counterfeiter 29 | integration/testdata/output 30 | *.profile 31 | *.bench 32 | /.vscode 33 | -------------------------------------------------------------------------------- /.golangci.yaml: -------------------------------------------------------------------------------- 1 | run: 2 | skip-dirs: 3 | - fixtures -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 maxbrunsfeld 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. -------------------------------------------------------------------------------- /arguments/files.go: -------------------------------------------------------------------------------- 1 | package arguments 2 | 3 | import "os" 4 | 5 | type Evaler func(string) (string, error) 6 | type Stater func(string) (os.FileInfo, error) 7 | -------------------------------------------------------------------------------- /arguments/parser_windows_test.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package arguments_test 4 | 5 | import ( 6 | "io" 7 | "log" 8 | "os" 9 | "path/filepath" 10 | "time" 11 | 12 | "testing" 13 | 14 | "github.com/maxbrunsfeld/counterfeiter/v6/arguments" 15 | 16 | . "github.com/onsi/gomega" 17 | "github.com/sclevine/spec" 18 | "github.com/sclevine/spec/report" 19 | ) 20 | 21 | func TestParsingArguments(t *testing.T) { 22 | spec.Run(t, "ParsingArguments (Windows)", testParsingArguments, spec.Report(report.Terminal{})) 23 | } 24 | 25 | func testParsingArguments(t *testing.T, when spec.G, it spec.S) { 26 | var ( 27 | err error 28 | parsedArgs *arguments.ParsedArguments 29 | args []string 30 | workingDir string 31 | evaler arguments.Evaler 32 | stater arguments.Stater 33 | ) 34 | 35 | justBefore := func() { 36 | parsedArgs, err = arguments.New(args, workingDir, evaler, stater) 37 | } 38 | 39 | it.Before(func() { 40 | RegisterTestingT(t) 41 | log.SetOutput(io.Discard) 42 | workingDir = "C:\\Users\\test-user\\workspace" 43 | 44 | evaler = func(input string) (string, error) { 45 | return input, nil 46 | } 47 | stater = func(filename string) (os.FileInfo, error) { 48 | return fakeFileInfo(filename, true), nil 49 | } 50 | }) 51 | 52 | when("when a single argument is provided with the output directory", func() { 53 | it.Before(func() { 54 | args = []string{"counterfeiter", "-o", "C:\\tmp\\foo", "io.Writer"} 55 | justBefore() 56 | }) 57 | 58 | it("copies the provided output path into the result", func() { 59 | Expect(parsedArgs.OutputPath).To(Equal("C:\\tmp\\foo\\fake_writer.go")) 60 | Expect(err).NotTo(HaveOccurred()) 61 | }) 62 | }) 63 | 64 | when("when two arguments are provided", func() { 65 | it.Before(func() { 66 | args = []string{"counterfeiter", "my\\specialpackage", "MySpecialInterface"} 67 | justBefore() 68 | }) 69 | 70 | it("snake cases the filename for the output directory", func() { 71 | Expect(parsedArgs.OutputPath).To(Equal( 72 | filepath.Join( 73 | parsedArgs.SourcePackageDir, 74 | "specialpackagefakes", 75 | "fake_my_special_interface.go", 76 | ), 77 | )) 78 | Expect(err).NotTo(HaveOccurred()) 79 | }) 80 | 81 | when("the source directory", func() { 82 | it("should be an absolute path", func() { 83 | Expect(filepath.IsAbs(parsedArgs.SourcePackageDir)).To(BeTrue()) 84 | Expect(err).NotTo(HaveOccurred()) 85 | }) 86 | }) 87 | }) 88 | 89 | when("when three arguments are provided", func() { 90 | when("and the third one is '-'", func() { 91 | it.Before(func() { 92 | args = []string{"counterfeiter", "my/mypackage", "MySpecialInterface", "-"} 93 | justBefore() 94 | }) 95 | 96 | it("snake cases the filename for the output directory", func() { 97 | Expect(parsedArgs.OutputPath).To(Equal( 98 | filepath.Join( 99 | parsedArgs.SourcePackageDir, 100 | "mypackagefakes", 101 | "fake_my_special_interface.go", 102 | ), 103 | )) 104 | Expect(err).NotTo(HaveOccurred()) 105 | }) 106 | 107 | when("the source directory", func() { 108 | it("should be an absolute path", func() { 109 | Expect(filepath.IsAbs(parsedArgs.SourcePackageDir)).To(BeTrue()) 110 | Expect(err).NotTo(HaveOccurred()) 111 | }) 112 | }) 113 | }) 114 | }) 115 | } 116 | 117 | func fakeFileInfo(filename string, isDir bool) os.FileInfo { 118 | return testFileInfo{name: filename, isDir: isDir} 119 | } 120 | 121 | type testFileInfo struct { 122 | name string 123 | isDir bool 124 | } 125 | 126 | func (testFileInfo testFileInfo) Name() string { 127 | return testFileInfo.name 128 | } 129 | 130 | func (testFileInfo testFileInfo) IsDir() bool { 131 | return testFileInfo.isDir 132 | } 133 | 134 | func (testFileInfo testFileInfo) Size() int64 { 135 | return 0 136 | } 137 | 138 | func (testFileInfo testFileInfo) Mode() os.FileMode { 139 | return 0 140 | } 141 | 142 | func (testFileInfo testFileInfo) ModTime() time.Time { 143 | return time.Now() 144 | } 145 | 146 | func (testFileInfo testFileInfo) Sys() interface{} { 147 | return nil 148 | } 149 | -------------------------------------------------------------------------------- /arguments/usage.go: -------------------------------------------------------------------------------- 1 | package arguments 2 | 3 | const usage = ` 4 | USAGE 5 | counterfeiter 6 | [-generate>] [-o ] [-p] [--fake-name ] 7 | [-header ] 8 | [] [-] 9 | 10 | ARGUMENTS 11 | source-path 12 | Path to the file or directory containing the interface to fake. 13 | In package mode (-p), source-path should instead specify the path 14 | of the input package; alternatively you can use the package name 15 | (e.g. "os") and the path will be inferred from your GOROOT. 16 | 17 | interface 18 | If source-path is specified: Name of the interface to fake. 19 | If no source-path is specified: Fully qualified interface path of the interface to fake. 20 | If -p is specified, this will be the name of the interface to generate. 21 | 22 | example: 23 | # writes "FakeStdInterface" to ./packagefakes/fake_std_interface.go 24 | counterfeiter package/subpackage.StdInterface 25 | 26 | '-' argument 27 | Write code to standard out instead of to a file 28 | 29 | OPTIONS 30 | -generate 31 | Identify all //counterfeiter:generate directives in .go file in the 32 | current working directory and generate fakes for them. You can pass 33 | arguments as usual. 34 | 35 | NOTE: This is not the same as //go:generate directives 36 | (used with the 'go generate' command), but it can be combined with 37 | go generate by adding the following to a .go file: 38 | 39 | # runs counterfeiter in generate mode 40 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 41 | 42 | example: 43 | Add the following to a .go file: 44 | 45 | //counterfeiter:generate . MyInterface 46 | //counterfeiter:generate . MyOtherInterface 47 | //counterfeiter:generate . MyThirdInterface 48 | 49 | # run counterfeiter 50 | counterfeiter -generate 51 | # writes "FakeMyInterface" to ./mypackagefakes/fake_my_interface.go 52 | # writes "FakeMyOtherInterface" to ./mypackagefakes/fake_my_other_interface.go 53 | # writes "FakeMyThirdInterface" to ./mypackagefakes/fake_my_third_interface.go 54 | 55 | -o 56 | Path to the file or directory for the generated fakes. 57 | This also determines the package name that will be used. 58 | By default, the generated fakes will be generated in 59 | the package "xyzfakes" which is nested in package "xyz", 60 | where "xyz" is the name of referenced package. 61 | 62 | example: 63 | # writes "FakeMyInterface" to ./mySpecialFakesDir/specialFake.go 64 | counterfeiter -o ./mySpecialFakesDir/specialFake.go ./mypackage MyInterface 65 | 66 | # writes "FakeMyInterface" to ./mySpecialFakesDir/fake_my_interface.go 67 | counterfeiter -o ./mySpecialFakesDir ./mypackage MyInterface 68 | 69 | -p 70 | Package mode: When invoked in package mode, counterfeiter 71 | will generate an interface and shim implementation from a 72 | package in your module. Counterfeiter finds the public methods 73 | in the package and adds those method signatures 74 | to the generated interface . 75 | 76 | example: 77 | # generates os.go (interface) and osshim.go (shim) in ${PWD}/osshim 78 | counterfeiter -p os 79 | # now generate fake in ${PWD}/osshim/os_fake (fake_os.go) 80 | go generate osshim/... 81 | 82 | -header 83 | Path to the file which should be used as a header for all generated fakes. 84 | By default, no special header is used. 85 | This is useful to e.g. add a licence header to every fake. 86 | 87 | If the generate mode is used and both the "go:generate" and the 88 | "counterfeiter:generate" specify a header file, the header file from the 89 | "counterfeiter:generate" line takes precedence. 90 | 91 | example: 92 | # having the following code in a package ... 93 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -header ./generic.go.txt -generate 94 | //counterfeiter:generate -header ./specific.go.txt . MyInterface 95 | //counterfeiter:generate . MyOtherInterface 96 | //counterfeiter:generate . MyThirdInterface 97 | 98 | # ... generating the fakes ... 99 | go generate . 100 | 101 | # writes "FakeMyInterface" with ./specific.go.txt as a header 102 | # writes "FakeMyOtherInterface" & "FakeMyThirdInterface" with ./generic.go.txt as a header 103 | 104 | --fake-name 105 | Name of the fake struct to generate. By default, 'Fake' will 106 | be prepended to the name of the original interface. (ignored in 107 | -p mode) 108 | 109 | example: 110 | # writes "CoolThing" to ./mypackagefakes/cool_thing.go 111 | counterfeiter --fake-name CoolThing ./mypackage MyInterface 112 | ` 113 | -------------------------------------------------------------------------------- /benchmark_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "log" 6 | "path/filepath" 7 | "testing" 8 | 9 | "github.com/maxbrunsfeld/counterfeiter/v6/arguments" 10 | "github.com/maxbrunsfeld/counterfeiter/v6/generator" 11 | ) 12 | 13 | func BenchmarkDoGenerate(b *testing.B) { 14 | b.StopTimer() 15 | workingDir, err := filepath.Abs(filepath.Join(".", "fixtures")) 16 | if err != nil { 17 | b.Fatal(err) 18 | } 19 | log.SetOutput(io.Discard) 20 | 21 | args := &arguments.ParsedArguments{ 22 | GenerateInterfaceAndShimFromPackageDirectory: false, 23 | SourcePackageDir: workingDir, 24 | PackagePath: workingDir, 25 | OutputPath: filepath.Join(workingDir, "fixturesfakes", "fake_something.go"), 26 | DestinationPackageName: "fixturesfakes", 27 | InterfaceName: "Something", 28 | FakeImplName: "FakeSomething", 29 | PrintToStdOut: false, 30 | } 31 | 32 | caches := map[string]struct { 33 | cache generator.Cacher 34 | headerReader generator.FileReader 35 | }{ 36 | "without caches": { 37 | cache: &generator.FakeCache{}, 38 | headerReader: &generator.SimpleFileReader{}, 39 | }, 40 | "with caches": { 41 | cache: &generator.Cache{}, 42 | headerReader: &generator.CachedFileReader{}, 43 | }, 44 | } 45 | 46 | headers := map[string]string{ 47 | "without headerfile": "", 48 | "with headerfile": "headers/default.header.go.txt", 49 | } 50 | 51 | for name, caches := range caches { 52 | caches := caches 53 | b.Run(name, func(b *testing.B) { 54 | for name, headerFile := range headers { 55 | headerFile := headerFile 56 | b.Run(name, func(b *testing.B) { 57 | args.HeaderFile = headerFile 58 | b.StartTimer() 59 | for i := 0; i < b.N; i++ { 60 | if _, err := doGenerate(workingDir, args, caches.cache, caches.headerReader); err != nil { 61 | b.Errorf("Expected doGenerate not to return an error, got %v", err) 62 | } 63 | } 64 | }) // b.Run for headerFiles 65 | } 66 | }) // b.Run for caches 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /command/runner.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "fmt" 5 | "go/build" 6 | "os" 7 | "path/filepath" 8 | "sort" 9 | "strconv" 10 | "strings" 11 | ) 12 | 13 | func Detect(cwd string, args []string, generateMode bool) ([]Invocation, error) { 14 | if generateMode { 15 | return generateModeInvocations(cwd) 16 | } 17 | 18 | file := os.Getenv("GOFILE") 19 | var lineno int 20 | if goline, err := strconv.Atoi(os.Getenv("GOLINE")); err == nil { 21 | lineno = goline 22 | } 23 | 24 | i, err := NewInvocation(file, lineno, args) 25 | if err != nil { 26 | return nil, err 27 | } 28 | return []Invocation{i}, nil 29 | } 30 | 31 | type Invocation struct { 32 | Args []string 33 | Line int 34 | File string 35 | } 36 | 37 | func NewInvocation(file string, line int, args []string) (Invocation, error) { 38 | if len(args) < 1 { 39 | return Invocation{}, fmt.Errorf("%s:%v an invocation of counterfeiter must have arguments", file, line) 40 | } 41 | i := Invocation{ 42 | File: file, 43 | Line: line, 44 | Args: args, 45 | } 46 | return i, nil 47 | } 48 | 49 | func generateModeInvocations(cwd string) ([]Invocation, error) { 50 | var result []Invocation 51 | // Find all the go files 52 | pkg, err := build.ImportDir(cwd, build.IgnoreVendor) 53 | if err != nil { 54 | return nil, err 55 | } 56 | 57 | gofiles := make([]string, 0, len(pkg.GoFiles)+len(pkg.CgoFiles)+len(pkg.TestGoFiles)+len(pkg.XTestGoFiles)) 58 | gofiles = append(gofiles, pkg.GoFiles...) 59 | gofiles = append(gofiles, pkg.CgoFiles...) 60 | gofiles = append(gofiles, pkg.TestGoFiles...) 61 | gofiles = append(gofiles, pkg.XTestGoFiles...) 62 | sort.Strings(gofiles) 63 | 64 | for _, file := range gofiles { 65 | invocations, err := invocationsInFile(cwd, file) 66 | if err != nil { 67 | return nil, err 68 | } 69 | result = append(result, invocations...) 70 | } 71 | 72 | return result, nil 73 | } 74 | 75 | func invocationsInFile(dir string, file string) ([]Invocation, error) { 76 | str, err := os.ReadFile(filepath.Join(dir, file)) 77 | if err != nil { 78 | return nil, err 79 | } 80 | lines := strings.Split(string(str), "\n") 81 | 82 | var result []Invocation 83 | line := 0 84 | for i := range lines { 85 | line++ 86 | args, ok := matchForString(lines[i]) 87 | if !ok { 88 | continue 89 | } 90 | inv, err := NewInvocation(file, line, args) 91 | if err != nil { 92 | return nil, err 93 | } 94 | 95 | result = append(result, inv) 96 | } 97 | 98 | return result, nil 99 | } 100 | 101 | const generateDirectivePrefix = "//counterfeiter:generate " 102 | 103 | func matchForString(s string) ([]string, bool) { 104 | if !strings.HasPrefix(s, generateDirectivePrefix) { 105 | return nil, false 106 | } 107 | return stringToArgs(s[len(generateDirectivePrefix):]), true 108 | } 109 | 110 | func stringToArgs(s string) []string { 111 | a := strings.Fields(s) 112 | result := []string{ 113 | "counterfeiter", 114 | } 115 | result = append(result, a...) 116 | return result 117 | } 118 | -------------------------------------------------------------------------------- /command/runner_internals_test.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "log" 5 | "testing" 6 | 7 | . "github.com/onsi/gomega" 8 | "github.com/sclevine/spec" 9 | "github.com/sclevine/spec/report" 10 | ) 11 | 12 | func TestRunner(t *testing.T) { 13 | spec.Run(t, "Regexp", testRegexp, spec.Report(report.Terminal{})) 14 | } 15 | 16 | type Case struct { 17 | input string 18 | matches bool 19 | args []string 20 | } 21 | 22 | func testRegexp(t *testing.T, when spec.G, it spec.S) { 23 | var cases []Case 24 | 25 | it.Before(func() { 26 | RegisterTestingT(t) 27 | log.SetFlags(log.Llongfile) 28 | cases = []Case{ 29 | { 30 | input: "//go:generate counterfeiter . Intf", 31 | matches: false, 32 | }, 33 | { 34 | input: "//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . Intf", 35 | matches: false, 36 | }, 37 | { 38 | input: "//counterfeiter:generate . Intf", 39 | matches: true, 40 | args: []string{"counterfeiter", ".", "Intf"}, 41 | }, 42 | { 43 | input: "//go:generate stringer -type=Enum", 44 | matches: false, 45 | }, 46 | } 47 | }) 48 | 49 | it("splits args correctly", func() { 50 | Expect(stringToArgs(". Intf")).To(ConsistOf([]string{"counterfeiter", ".", "Intf"})) 51 | Expect(stringToArgs(" . Intf ")).To(ConsistOf([]string{"counterfeiter", ".", "Intf"})) 52 | }) 53 | 54 | it("matches lines appropriately", func() { 55 | for _, c := range cases { 56 | result, ok := matchForString(c.input) 57 | if c.matches { 58 | Expect(ok).To(BeTrue(), c.input) 59 | Expect(result).To(ConsistOf(c.args), c.input) 60 | } else { 61 | Expect(ok).To(BeFalse()) 62 | } 63 | } 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /command/runner_test.go: -------------------------------------------------------------------------------- 1 | package command_test 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "path/filepath" 7 | "testing" 8 | 9 | "github.com/maxbrunsfeld/counterfeiter/v6/command" 10 | . "github.com/onsi/gomega" 11 | "github.com/sclevine/spec" 12 | "github.com/sclevine/spec/report" 13 | ) 14 | 15 | func TestRunner(t *testing.T) { 16 | spec.Run(t, "Runner", testRunner, spec.Report(report.Terminal{})) 17 | } 18 | 19 | func testRunner(t *testing.T, when spec.G, it spec.S) { 20 | reset := func() { 21 | os.Unsetenv("DOLLAR") 22 | os.Unsetenv("GOFILE") 23 | os.Unsetenv("GOLINE") 24 | os.Unsetenv("GOPACKAGE") 25 | } 26 | 27 | it.Before(func() { 28 | RegisterTestingT(t) 29 | reset() 30 | log.SetFlags(log.Llongfile) 31 | }) 32 | 33 | it.After(func() { 34 | reset() 35 | }) 36 | 37 | when("counterfeiter has been invoked directly", func() { 38 | it.Before(func() { 39 | }) 40 | 41 | it("creates an invocation", func() { 42 | i, err := command.Detect(filepath.Join(".", "..", "fixtures"), []string{"counterfeiter", ".", "AliasedInterface"}, false) 43 | Expect(err).NotTo(HaveOccurred()) 44 | Expect(i).NotTo(BeNil()) 45 | Expect(i).To(HaveLen(1)) 46 | Expect(i[0].Args).To(HaveLen(3)) 47 | Expect(i[0].Args[1]).To(Equal(".")) 48 | Expect(i[0].Args[2]).To(Equal("AliasedInterface")) 49 | }) 50 | }) 51 | 52 | when("counterfeiter is invoked in generate mode", func() { 53 | it.Before(func() { 54 | os.Unsetenv("DOLLAR") 55 | os.Unsetenv("GOFILE") 56 | os.Unsetenv("GOLINE") 57 | os.Unsetenv("GOPACKAGE") 58 | }) 59 | 60 | it("creates invocations", func() { 61 | i, err := command.Detect(filepath.Join(".", "..", "fixtures"), []string{"counterfeiter", ".", "AliasedInterface"}, true) 62 | Expect(err).NotTo(HaveOccurred()) 63 | Expect(i).NotTo(BeNil()) 64 | Expect(len(i)).To(Equal(19)) 65 | Expect(i[0].File).To(Equal("aliased_interfaces.go")) 66 | Expect(i[0].Line).To(Equal(6)) 67 | Expect(i[0].Args).To(HaveLen(3)) 68 | Expect(i[0].Args[0]).To(Equal("counterfeiter")) 69 | Expect(i[0].Args[1]).To(Equal(".")) 70 | Expect(i[0].Args[2]).To(Equal("AliasedInterface")) 71 | }) 72 | }) 73 | 74 | when("counterfeiter has been invoked by go generate", func() { 75 | it.Before(func() { 76 | os.Setenv("DOLLAR", "$") 77 | os.Setenv("GOFILE", "aliased_interfaces.go") 78 | os.Setenv("GOLINE", "5") 79 | os.Setenv("GOPACKAGE", "fixtures") 80 | }) 81 | 82 | it("creates invocations but does not include generate mode as an invocation", func() { 83 | i, err := command.Detect(filepath.Join(".", "..", "fixtures"), []string{"counterfeiter", ".", "AliasedInterface"}, false) 84 | Expect(err).NotTo(HaveOccurred()) 85 | Expect(i).NotTo(BeNil()) 86 | Expect(len(i)).To(Equal(1)) 87 | Expect(i[0].File).To(Equal("aliased_interfaces.go")) 88 | Expect(i[0].Line).To(Equal(5)) 89 | Expect(i[0].Args).To(HaveLen(3)) 90 | Expect(i[0].Args[0]).To(Equal("counterfeiter")) 91 | Expect(i[0].Args[1]).To(Equal(".")) 92 | Expect(i[0].Args[2]).To(Equal("AliasedInterface")) 93 | }) 94 | }) 95 | } 96 | -------------------------------------------------------------------------------- /fixtures/aliased_interfaces.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | import alias "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/another_package" 4 | 5 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 6 | //counterfeiter:generate . AliasedInterface 7 | 8 | // AliasedInterface is an interface that embeds an interface in an aliased package. 9 | type AliasedInterface interface { 10 | alias.AnotherInterface 11 | } 12 | -------------------------------------------------------------------------------- /fixtures/aliased_package/aliased_packagefakes/fake_in_aliased_package.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package aliased_packagefakes 3 | 4 | import ( 5 | "sync" 6 | 7 | the_aliased_package "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/aliased_package" 8 | ) 9 | 10 | type FakeInAliasedPackage struct { 11 | StuffStub func(int) string 12 | stuffMutex sync.RWMutex 13 | stuffArgsForCall []struct { 14 | arg1 int 15 | } 16 | stuffReturns struct { 17 | result1 string 18 | } 19 | stuffReturnsOnCall map[int]struct { 20 | result1 string 21 | } 22 | invocations map[string][][]interface{} 23 | invocationsMutex sync.RWMutex 24 | } 25 | 26 | func (fake *FakeInAliasedPackage) Stuff(arg1 int) string { 27 | fake.stuffMutex.Lock() 28 | ret, specificReturn := fake.stuffReturnsOnCall[len(fake.stuffArgsForCall)] 29 | fake.stuffArgsForCall = append(fake.stuffArgsForCall, struct { 30 | arg1 int 31 | }{arg1}) 32 | stub := fake.StuffStub 33 | fakeReturns := fake.stuffReturns 34 | fake.recordInvocation("Stuff", []interface{}{arg1}) 35 | fake.stuffMutex.Unlock() 36 | if stub != nil { 37 | return stub(arg1) 38 | } 39 | if specificReturn { 40 | return ret.result1 41 | } 42 | return fakeReturns.result1 43 | } 44 | 45 | func (fake *FakeInAliasedPackage) StuffCallCount() int { 46 | fake.stuffMutex.RLock() 47 | defer fake.stuffMutex.RUnlock() 48 | return len(fake.stuffArgsForCall) 49 | } 50 | 51 | func (fake *FakeInAliasedPackage) StuffCalls(stub func(int) string) { 52 | fake.stuffMutex.Lock() 53 | defer fake.stuffMutex.Unlock() 54 | fake.StuffStub = stub 55 | } 56 | 57 | func (fake *FakeInAliasedPackage) StuffArgsForCall(i int) int { 58 | fake.stuffMutex.RLock() 59 | defer fake.stuffMutex.RUnlock() 60 | argsForCall := fake.stuffArgsForCall[i] 61 | return argsForCall.arg1 62 | } 63 | 64 | func (fake *FakeInAliasedPackage) StuffReturns(result1 string) { 65 | fake.stuffMutex.Lock() 66 | defer fake.stuffMutex.Unlock() 67 | fake.StuffStub = nil 68 | fake.stuffReturns = struct { 69 | result1 string 70 | }{result1} 71 | } 72 | 73 | func (fake *FakeInAliasedPackage) StuffReturnsOnCall(i int, result1 string) { 74 | fake.stuffMutex.Lock() 75 | defer fake.stuffMutex.Unlock() 76 | fake.StuffStub = nil 77 | if fake.stuffReturnsOnCall == nil { 78 | fake.stuffReturnsOnCall = make(map[int]struct { 79 | result1 string 80 | }) 81 | } 82 | fake.stuffReturnsOnCall[i] = struct { 83 | result1 string 84 | }{result1} 85 | } 86 | 87 | func (fake *FakeInAliasedPackage) Invocations() map[string][][]interface{} { 88 | fake.invocationsMutex.RLock() 89 | defer fake.invocationsMutex.RUnlock() 90 | fake.stuffMutex.RLock() 91 | defer fake.stuffMutex.RUnlock() 92 | copiedInvocations := map[string][][]interface{}{} 93 | for key, value := range fake.invocations { 94 | copiedInvocations[key] = value 95 | } 96 | return copiedInvocations 97 | } 98 | 99 | func (fake *FakeInAliasedPackage) recordInvocation(key string, args []interface{}) { 100 | fake.invocationsMutex.Lock() 101 | defer fake.invocationsMutex.Unlock() 102 | if fake.invocations == nil { 103 | fake.invocations = map[string][][]interface{}{} 104 | } 105 | if fake.invocations[key] == nil { 106 | fake.invocations[key] = [][]interface{}{} 107 | } 108 | fake.invocations[key] = append(fake.invocations[key], args) 109 | } 110 | 111 | var _ the_aliased_package.InAliasedPackage = new(FakeInAliasedPackage) 112 | -------------------------------------------------------------------------------- /fixtures/aliased_package/in_aliased_package.go: -------------------------------------------------------------------------------- 1 | package the_aliased_package // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/aliased_package" 2 | 3 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . InAliasedPackage 4 | type InAliasedPackage interface { 5 | Stuff(int) string 6 | } 7 | -------------------------------------------------------------------------------- /fixtures/another_package/another_packagefakes/fake_another_interface.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package another_packagefakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/another_package" 8 | ) 9 | 10 | type FakeAnotherInterface struct { 11 | AnotherMethodStub func([]another_package.SomeType, map[another_package.SomeType]another_package.SomeType, *another_package.SomeType, another_package.SomeType, chan another_package.SomeType) 12 | anotherMethodMutex sync.RWMutex 13 | anotherMethodArgsForCall []struct { 14 | arg1 []another_package.SomeType 15 | arg2 map[another_package.SomeType]another_package.SomeType 16 | arg3 *another_package.SomeType 17 | arg4 another_package.SomeType 18 | arg5 chan another_package.SomeType 19 | } 20 | invocations map[string][][]interface{} 21 | invocationsMutex sync.RWMutex 22 | } 23 | 24 | func (fake *FakeAnotherInterface) AnotherMethod(arg1 []another_package.SomeType, arg2 map[another_package.SomeType]another_package.SomeType, arg3 *another_package.SomeType, arg4 another_package.SomeType, arg5 chan another_package.SomeType) { 25 | var arg1Copy []another_package.SomeType 26 | if arg1 != nil { 27 | arg1Copy = make([]another_package.SomeType, len(arg1)) 28 | copy(arg1Copy, arg1) 29 | } 30 | fake.anotherMethodMutex.Lock() 31 | fake.anotherMethodArgsForCall = append(fake.anotherMethodArgsForCall, struct { 32 | arg1 []another_package.SomeType 33 | arg2 map[another_package.SomeType]another_package.SomeType 34 | arg3 *another_package.SomeType 35 | arg4 another_package.SomeType 36 | arg5 chan another_package.SomeType 37 | }{arg1Copy, arg2, arg3, arg4, arg5}) 38 | stub := fake.AnotherMethodStub 39 | fake.recordInvocation("AnotherMethod", []interface{}{arg1Copy, arg2, arg3, arg4, arg5}) 40 | fake.anotherMethodMutex.Unlock() 41 | if stub != nil { 42 | fake.AnotherMethodStub(arg1, arg2, arg3, arg4, arg5) 43 | } 44 | } 45 | 46 | func (fake *FakeAnotherInterface) AnotherMethodCallCount() int { 47 | fake.anotherMethodMutex.RLock() 48 | defer fake.anotherMethodMutex.RUnlock() 49 | return len(fake.anotherMethodArgsForCall) 50 | } 51 | 52 | func (fake *FakeAnotherInterface) AnotherMethodCalls(stub func([]another_package.SomeType, map[another_package.SomeType]another_package.SomeType, *another_package.SomeType, another_package.SomeType, chan another_package.SomeType)) { 53 | fake.anotherMethodMutex.Lock() 54 | defer fake.anotherMethodMutex.Unlock() 55 | fake.AnotherMethodStub = stub 56 | } 57 | 58 | func (fake *FakeAnotherInterface) AnotherMethodArgsForCall(i int) ([]another_package.SomeType, map[another_package.SomeType]another_package.SomeType, *another_package.SomeType, another_package.SomeType, chan another_package.SomeType) { 59 | fake.anotherMethodMutex.RLock() 60 | defer fake.anotherMethodMutex.RUnlock() 61 | argsForCall := fake.anotherMethodArgsForCall[i] 62 | return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5 63 | } 64 | 65 | func (fake *FakeAnotherInterface) Invocations() map[string][][]interface{} { 66 | fake.invocationsMutex.RLock() 67 | defer fake.invocationsMutex.RUnlock() 68 | fake.anotherMethodMutex.RLock() 69 | defer fake.anotherMethodMutex.RUnlock() 70 | copiedInvocations := map[string][][]interface{}{} 71 | for key, value := range fake.invocations { 72 | copiedInvocations[key] = value 73 | } 74 | return copiedInvocations 75 | } 76 | 77 | func (fake *FakeAnotherInterface) recordInvocation(key string, args []interface{}) { 78 | fake.invocationsMutex.Lock() 79 | defer fake.invocationsMutex.Unlock() 80 | if fake.invocations == nil { 81 | fake.invocations = map[string][][]interface{}{} 82 | } 83 | if fake.invocations[key] == nil { 84 | fake.invocations[key] = [][]interface{}{} 85 | } 86 | fake.invocations[key] = append(fake.invocations[key], args) 87 | } 88 | 89 | var _ another_package.AnotherInterface = new(FakeAnotherInterface) 90 | -------------------------------------------------------------------------------- /fixtures/another_package/types.go: -------------------------------------------------------------------------------- 1 | package another_package // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/another_package" 2 | 3 | type SomeType int 4 | 5 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . AnotherInterface 6 | type AnotherInterface interface { 7 | AnotherMethod([]SomeType, map[SomeType]SomeType, *SomeType, SomeType, chan SomeType) 8 | } 9 | -------------------------------------------------------------------------------- /fixtures/blank.go: -------------------------------------------------------------------------------- 1 | package fixtures // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 2 | -------------------------------------------------------------------------------- /fixtures/compound_return.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | //counterfeiter:generate . SomethingElse 4 | type SomethingElse interface { 5 | ReturnStuff() (a, b int) 6 | } 7 | -------------------------------------------------------------------------------- /fixtures/custom_output.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | //counterfeiter:generate -o ./customfakesdir . CustomOutput 4 | type CustomOutput interface { 5 | CustomFolder() 6 | } 7 | -------------------------------------------------------------------------------- /fixtures/customfakesdir/fake_custom_output.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package customfakesdir 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeCustomOutput struct { 11 | CustomFolderStub func() 12 | customFolderMutex sync.RWMutex 13 | customFolderArgsForCall []struct { 14 | } 15 | invocations map[string][][]interface{} 16 | invocationsMutex sync.RWMutex 17 | } 18 | 19 | func (fake *FakeCustomOutput) CustomFolder() { 20 | fake.customFolderMutex.Lock() 21 | fake.customFolderArgsForCall = append(fake.customFolderArgsForCall, struct { 22 | }{}) 23 | stub := fake.CustomFolderStub 24 | fake.recordInvocation("CustomFolder", []interface{}{}) 25 | fake.customFolderMutex.Unlock() 26 | if stub != nil { 27 | fake.CustomFolderStub() 28 | } 29 | } 30 | 31 | func (fake *FakeCustomOutput) CustomFolderCallCount() int { 32 | fake.customFolderMutex.RLock() 33 | defer fake.customFolderMutex.RUnlock() 34 | return len(fake.customFolderArgsForCall) 35 | } 36 | 37 | func (fake *FakeCustomOutput) CustomFolderCalls(stub func()) { 38 | fake.customFolderMutex.Lock() 39 | defer fake.customFolderMutex.Unlock() 40 | fake.CustomFolderStub = stub 41 | } 42 | 43 | func (fake *FakeCustomOutput) Invocations() map[string][][]interface{} { 44 | fake.invocationsMutex.RLock() 45 | defer fake.invocationsMutex.RUnlock() 46 | fake.customFolderMutex.RLock() 47 | defer fake.customFolderMutex.RUnlock() 48 | copiedInvocations := map[string][][]interface{}{} 49 | for key, value := range fake.invocations { 50 | copiedInvocations[key] = value 51 | } 52 | return copiedInvocations 53 | } 54 | 55 | func (fake *FakeCustomOutput) recordInvocation(key string, args []interface{}) { 56 | fake.invocationsMutex.Lock() 57 | defer fake.invocationsMutex.Unlock() 58 | if fake.invocations == nil { 59 | fake.invocations = map[string][][]interface{}{} 60 | } 61 | if fake.invocations[key] == nil { 62 | fake.invocations[key] = [][]interface{}{} 63 | } 64 | fake.invocations[key] = append(fake.invocations[key], args) 65 | } 66 | 67 | var _ fixtures.CustomOutput = new(FakeCustomOutput) 68 | -------------------------------------------------------------------------------- /fixtures/dot_imports.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | . "os" 7 | ) 8 | 9 | //counterfeiter:generate . DotImports 10 | type DotImports interface { 11 | DoThings(io.Writer, *File) *http.Client 12 | } 13 | -------------------------------------------------------------------------------- /fixtures/dup_packages/a/a.go: -------------------------------------------------------------------------------- 1 | package a // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/a" 2 | 3 | import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/a/foo" 4 | 5 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . A 6 | type A interface { 7 | V1() foo.I 8 | } 9 | -------------------------------------------------------------------------------- /fixtures/dup_packages/a/foo/a.go: -------------------------------------------------------------------------------- 1 | package foo // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/a/foo" 2 | 3 | type S struct{} 4 | 5 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . I 6 | type I interface { 7 | FromA() S 8 | } 9 | -------------------------------------------------------------------------------- /fixtures/dup_packages/alias.go: -------------------------------------------------------------------------------- 1 | package dup_packages // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages" 2 | 3 | import ( 4 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/a" 5 | afoo "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/a/foo" 6 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/b/foo" 7 | ) 8 | 9 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 10 | //counterfeiter:generate . AliasV1 11 | type AliasV1 interface { 12 | a.A 13 | afoo.I 14 | foo.I 15 | } 16 | -------------------------------------------------------------------------------- /fixtures/dup_packages/b/foo/b.go: -------------------------------------------------------------------------------- 1 | package foo // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/b/foo" 2 | 3 | type S struct{} 4 | 5 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . I 6 | type I interface { 7 | FromB() S 8 | } 9 | -------------------------------------------------------------------------------- /fixtures/dup_packages/dupA.go: -------------------------------------------------------------------------------- 1 | package dup_packages // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages" 2 | 3 | import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/a/foo" 4 | 5 | //counterfeiter:generate . DupA 6 | type DupA interface { 7 | A() foo.S 8 | } 9 | -------------------------------------------------------------------------------- /fixtures/dup_packages/dupAB.go: -------------------------------------------------------------------------------- 1 | package dup_packages // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages" 2 | 3 | //counterfeiter:generate . DupAB 4 | type DupAB interface { 5 | DupA 6 | DupB 7 | } 8 | -------------------------------------------------------------------------------- /fixtures/dup_packages/dupB.go: -------------------------------------------------------------------------------- 1 | package dup_packages // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages" 2 | 3 | import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/b/foo" 4 | 5 | //counterfeiter:generate . DupB 6 | type DupB interface { 7 | B() foo.S 8 | } 9 | -------------------------------------------------------------------------------- /fixtures/dup_packages/dup_packagenames.go: -------------------------------------------------------------------------------- 1 | package dup_packages // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages" 2 | 3 | import ( 4 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/a/foo" 5 | bfoo "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/b/foo" 6 | ) 7 | 8 | //counterfeiter:generate . AB 9 | type AB interface { 10 | A() foo.S 11 | foo.I 12 | B() bfoo.S 13 | bfoo.I 14 | } 15 | -------------------------------------------------------------------------------- /fixtures/dup_packages/foo/multi_import.go: -------------------------------------------------------------------------------- 1 | package foo // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/foo" 2 | 3 | import ( 4 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/a/foo" 5 | bfoo "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/b/foo" 6 | ) 7 | 8 | type S struct{} 9 | 10 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . MultiAB 11 | type MultiAB interface { 12 | Mine() S 13 | foo.I 14 | bfoo.I 15 | } 16 | -------------------------------------------------------------------------------- /fixtures/dup_packages/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages 2 | 3 | go 1.22 4 | -------------------------------------------------------------------------------- /fixtures/embeds_interfaces.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/another_package" 7 | ) 8 | 9 | //counterfeiter:generate . EmbedsInterfaces 10 | type EmbedsInterfaces interface { 11 | http.Handler 12 | another_package.AnotherInterface 13 | InterfaceToEmbed 14 | 15 | DoThings() 16 | } 17 | 18 | type InterfaceToEmbed interface { 19 | EmbeddedMethod() string 20 | } 21 | -------------------------------------------------------------------------------- /fixtures/externalpkg/aliased_interface.go: -------------------------------------------------------------------------------- 1 | package externalpkg 2 | 3 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 4 | //counterfeiter:generate github.com/maxbrunsfeld/counterfeiter/v6/fixtures/internalpkg.Context 5 | -------------------------------------------------------------------------------- /fixtures/externalpkg/externalpkgfakes/fake_context.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package externalpkgfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/internalpkg" 8 | ) 9 | 10 | type FakeContext struct { 11 | DoSomethingStub func() 12 | doSomethingMutex sync.RWMutex 13 | doSomethingArgsForCall []struct { 14 | } 15 | invocations map[string][][]interface{} 16 | invocationsMutex sync.RWMutex 17 | } 18 | 19 | func (fake *FakeContext) DoSomething() { 20 | fake.doSomethingMutex.Lock() 21 | fake.doSomethingArgsForCall = append(fake.doSomethingArgsForCall, struct { 22 | }{}) 23 | stub := fake.DoSomethingStub 24 | fake.recordInvocation("DoSomething", []interface{}{}) 25 | fake.doSomethingMutex.Unlock() 26 | if stub != nil { 27 | fake.DoSomethingStub() 28 | } 29 | } 30 | 31 | func (fake *FakeContext) DoSomethingCallCount() int { 32 | fake.doSomethingMutex.RLock() 33 | defer fake.doSomethingMutex.RUnlock() 34 | return len(fake.doSomethingArgsForCall) 35 | } 36 | 37 | func (fake *FakeContext) DoSomethingCalls(stub func()) { 38 | fake.doSomethingMutex.Lock() 39 | defer fake.doSomethingMutex.Unlock() 40 | fake.DoSomethingStub = stub 41 | } 42 | 43 | func (fake *FakeContext) Invocations() map[string][][]interface{} { 44 | fake.invocationsMutex.RLock() 45 | defer fake.invocationsMutex.RUnlock() 46 | fake.doSomethingMutex.RLock() 47 | defer fake.doSomethingMutex.RUnlock() 48 | copiedInvocations := map[string][][]interface{}{} 49 | for key, value := range fake.invocations { 50 | copiedInvocations[key] = value 51 | } 52 | return copiedInvocations 53 | } 54 | 55 | func (fake *FakeContext) recordInvocation(key string, args []interface{}) { 56 | fake.invocationsMutex.Lock() 57 | defer fake.invocationsMutex.Unlock() 58 | if fake.invocations == nil { 59 | fake.invocations = map[string][][]interface{}{} 60 | } 61 | if fake.invocations[key] == nil { 62 | fake.invocations[key] = [][]interface{}{} 63 | } 64 | fake.invocations[key] = append(fake.invocations[key], args) 65 | } 66 | 67 | var _ internalpkg.Context = new(FakeContext) 68 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_aliased_interface.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/another_package" 9 | ) 10 | 11 | type FakeAliasedInterface struct { 12 | AnotherMethodStub func([]another_package.SomeType, map[another_package.SomeType]another_package.SomeType, *another_package.SomeType, another_package.SomeType, chan another_package.SomeType) 13 | anotherMethodMutex sync.RWMutex 14 | anotherMethodArgsForCall []struct { 15 | arg1 []another_package.SomeType 16 | arg2 map[another_package.SomeType]another_package.SomeType 17 | arg3 *another_package.SomeType 18 | arg4 another_package.SomeType 19 | arg5 chan another_package.SomeType 20 | } 21 | invocations map[string][][]interface{} 22 | invocationsMutex sync.RWMutex 23 | } 24 | 25 | func (fake *FakeAliasedInterface) AnotherMethod(arg1 []another_package.SomeType, arg2 map[another_package.SomeType]another_package.SomeType, arg3 *another_package.SomeType, arg4 another_package.SomeType, arg5 chan another_package.SomeType) { 26 | var arg1Copy []another_package.SomeType 27 | if arg1 != nil { 28 | arg1Copy = make([]another_package.SomeType, len(arg1)) 29 | copy(arg1Copy, arg1) 30 | } 31 | fake.anotherMethodMutex.Lock() 32 | fake.anotherMethodArgsForCall = append(fake.anotherMethodArgsForCall, struct { 33 | arg1 []another_package.SomeType 34 | arg2 map[another_package.SomeType]another_package.SomeType 35 | arg3 *another_package.SomeType 36 | arg4 another_package.SomeType 37 | arg5 chan another_package.SomeType 38 | }{arg1Copy, arg2, arg3, arg4, arg5}) 39 | stub := fake.AnotherMethodStub 40 | fake.recordInvocation("AnotherMethod", []interface{}{arg1Copy, arg2, arg3, arg4, arg5}) 41 | fake.anotherMethodMutex.Unlock() 42 | if stub != nil { 43 | fake.AnotherMethodStub(arg1, arg2, arg3, arg4, arg5) 44 | } 45 | } 46 | 47 | func (fake *FakeAliasedInterface) AnotherMethodCallCount() int { 48 | fake.anotherMethodMutex.RLock() 49 | defer fake.anotherMethodMutex.RUnlock() 50 | return len(fake.anotherMethodArgsForCall) 51 | } 52 | 53 | func (fake *FakeAliasedInterface) AnotherMethodCalls(stub func([]another_package.SomeType, map[another_package.SomeType]another_package.SomeType, *another_package.SomeType, another_package.SomeType, chan another_package.SomeType)) { 54 | fake.anotherMethodMutex.Lock() 55 | defer fake.anotherMethodMutex.Unlock() 56 | fake.AnotherMethodStub = stub 57 | } 58 | 59 | func (fake *FakeAliasedInterface) AnotherMethodArgsForCall(i int) ([]another_package.SomeType, map[another_package.SomeType]another_package.SomeType, *another_package.SomeType, another_package.SomeType, chan another_package.SomeType) { 60 | fake.anotherMethodMutex.RLock() 61 | defer fake.anotherMethodMutex.RUnlock() 62 | argsForCall := fake.anotherMethodArgsForCall[i] 63 | return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3, argsForCall.arg4, argsForCall.arg5 64 | } 65 | 66 | func (fake *FakeAliasedInterface) Invocations() map[string][][]interface{} { 67 | fake.invocationsMutex.RLock() 68 | defer fake.invocationsMutex.RUnlock() 69 | fake.anotherMethodMutex.RLock() 70 | defer fake.anotherMethodMutex.RUnlock() 71 | copiedInvocations := map[string][][]interface{}{} 72 | for key, value := range fake.invocations { 73 | copiedInvocations[key] = value 74 | } 75 | return copiedInvocations 76 | } 77 | 78 | func (fake *FakeAliasedInterface) recordInvocation(key string, args []interface{}) { 79 | fake.invocationsMutex.Lock() 80 | defer fake.invocationsMutex.Unlock() 81 | if fake.invocations == nil { 82 | fake.invocations = map[string][][]interface{}{} 83 | } 84 | if fake.invocations[key] == nil { 85 | fake.invocations[key] = [][]interface{}{} 86 | } 87 | fake.invocations[key] = append(fake.invocations[key], args) 88 | } 89 | 90 | var _ fixtures.AliasedInterface = new(FakeAliasedInterface) 91 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_dot_imports.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "io" 6 | "net/http" 7 | "os" 8 | "sync" 9 | 10 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 11 | ) 12 | 13 | type FakeDotImports struct { 14 | DoThingsStub func(io.Writer, *os.File) *http.Client 15 | doThingsMutex sync.RWMutex 16 | doThingsArgsForCall []struct { 17 | arg1 io.Writer 18 | arg2 *os.File 19 | } 20 | doThingsReturns struct { 21 | result1 *http.Client 22 | } 23 | doThingsReturnsOnCall map[int]struct { 24 | result1 *http.Client 25 | } 26 | invocations map[string][][]interface{} 27 | invocationsMutex sync.RWMutex 28 | } 29 | 30 | func (fake *FakeDotImports) DoThings(arg1 io.Writer, arg2 *os.File) *http.Client { 31 | fake.doThingsMutex.Lock() 32 | ret, specificReturn := fake.doThingsReturnsOnCall[len(fake.doThingsArgsForCall)] 33 | fake.doThingsArgsForCall = append(fake.doThingsArgsForCall, struct { 34 | arg1 io.Writer 35 | arg2 *os.File 36 | }{arg1, arg2}) 37 | stub := fake.DoThingsStub 38 | fakeReturns := fake.doThingsReturns 39 | fake.recordInvocation("DoThings", []interface{}{arg1, arg2}) 40 | fake.doThingsMutex.Unlock() 41 | if stub != nil { 42 | return stub(arg1, arg2) 43 | } 44 | if specificReturn { 45 | return ret.result1 46 | } 47 | return fakeReturns.result1 48 | } 49 | 50 | func (fake *FakeDotImports) DoThingsCallCount() int { 51 | fake.doThingsMutex.RLock() 52 | defer fake.doThingsMutex.RUnlock() 53 | return len(fake.doThingsArgsForCall) 54 | } 55 | 56 | func (fake *FakeDotImports) DoThingsCalls(stub func(io.Writer, *os.File) *http.Client) { 57 | fake.doThingsMutex.Lock() 58 | defer fake.doThingsMutex.Unlock() 59 | fake.DoThingsStub = stub 60 | } 61 | 62 | func (fake *FakeDotImports) DoThingsArgsForCall(i int) (io.Writer, *os.File) { 63 | fake.doThingsMutex.RLock() 64 | defer fake.doThingsMutex.RUnlock() 65 | argsForCall := fake.doThingsArgsForCall[i] 66 | return argsForCall.arg1, argsForCall.arg2 67 | } 68 | 69 | func (fake *FakeDotImports) DoThingsReturns(result1 *http.Client) { 70 | fake.doThingsMutex.Lock() 71 | defer fake.doThingsMutex.Unlock() 72 | fake.DoThingsStub = nil 73 | fake.doThingsReturns = struct { 74 | result1 *http.Client 75 | }{result1} 76 | } 77 | 78 | func (fake *FakeDotImports) DoThingsReturnsOnCall(i int, result1 *http.Client) { 79 | fake.doThingsMutex.Lock() 80 | defer fake.doThingsMutex.Unlock() 81 | fake.DoThingsStub = nil 82 | if fake.doThingsReturnsOnCall == nil { 83 | fake.doThingsReturnsOnCall = make(map[int]struct { 84 | result1 *http.Client 85 | }) 86 | } 87 | fake.doThingsReturnsOnCall[i] = struct { 88 | result1 *http.Client 89 | }{result1} 90 | } 91 | 92 | func (fake *FakeDotImports) Invocations() map[string][][]interface{} { 93 | fake.invocationsMutex.RLock() 94 | defer fake.invocationsMutex.RUnlock() 95 | fake.doThingsMutex.RLock() 96 | defer fake.doThingsMutex.RUnlock() 97 | copiedInvocations := map[string][][]interface{}{} 98 | for key, value := range fake.invocations { 99 | copiedInvocations[key] = value 100 | } 101 | return copiedInvocations 102 | } 103 | 104 | func (fake *FakeDotImports) recordInvocation(key string, args []interface{}) { 105 | fake.invocationsMutex.Lock() 106 | defer fake.invocationsMutex.Unlock() 107 | if fake.invocations == nil { 108 | fake.invocations = map[string][][]interface{}{} 109 | } 110 | if fake.invocations[key] == nil { 111 | fake.invocations[key] = [][]interface{}{} 112 | } 113 | fake.invocations[key] = append(fake.invocations[key], args) 114 | } 115 | 116 | var _ fixtures.DotImports = new(FakeDotImports) 117 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_first_interface.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeFirstInterface struct { 11 | DoThingsStub func() 12 | doThingsMutex sync.RWMutex 13 | doThingsArgsForCall []struct { 14 | } 15 | invocations map[string][][]interface{} 16 | invocationsMutex sync.RWMutex 17 | } 18 | 19 | func (fake *FakeFirstInterface) DoThings() { 20 | fake.doThingsMutex.Lock() 21 | fake.doThingsArgsForCall = append(fake.doThingsArgsForCall, struct { 22 | }{}) 23 | stub := fake.DoThingsStub 24 | fake.recordInvocation("DoThings", []interface{}{}) 25 | fake.doThingsMutex.Unlock() 26 | if stub != nil { 27 | fake.DoThingsStub() 28 | } 29 | } 30 | 31 | func (fake *FakeFirstInterface) DoThingsCallCount() int { 32 | fake.doThingsMutex.RLock() 33 | defer fake.doThingsMutex.RUnlock() 34 | return len(fake.doThingsArgsForCall) 35 | } 36 | 37 | func (fake *FakeFirstInterface) DoThingsCalls(stub func()) { 38 | fake.doThingsMutex.Lock() 39 | defer fake.doThingsMutex.Unlock() 40 | fake.DoThingsStub = stub 41 | } 42 | 43 | func (fake *FakeFirstInterface) Invocations() map[string][][]interface{} { 44 | fake.invocationsMutex.RLock() 45 | defer fake.invocationsMutex.RUnlock() 46 | fake.doThingsMutex.RLock() 47 | defer fake.doThingsMutex.RUnlock() 48 | copiedInvocations := map[string][][]interface{}{} 49 | for key, value := range fake.invocations { 50 | copiedInvocations[key] = value 51 | } 52 | return copiedInvocations 53 | } 54 | 55 | func (fake *FakeFirstInterface) recordInvocation(key string, args []interface{}) { 56 | fake.invocationsMutex.Lock() 57 | defer fake.invocationsMutex.Unlock() 58 | if fake.invocations == nil { 59 | fake.invocations = map[string][][]interface{}{} 60 | } 61 | if fake.invocations[key] == nil { 62 | fake.invocations[key] = [][]interface{}{} 63 | } 64 | fake.invocations[key] = append(fake.invocations[key], args) 65 | } 66 | 67 | var _ fixtures.FirstInterface = new(FakeFirstInterface) 68 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_has_imports.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "io" 6 | "net/http" 7 | "os" 8 | "sync" 9 | 10 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 11 | ) 12 | 13 | type FakeHasImports struct { 14 | DoThingsStub func(io.Writer, *os.File) *http.Client 15 | doThingsMutex sync.RWMutex 16 | doThingsArgsForCall []struct { 17 | arg1 io.Writer 18 | arg2 *os.File 19 | } 20 | doThingsReturns struct { 21 | result1 *http.Client 22 | } 23 | doThingsReturnsOnCall map[int]struct { 24 | result1 *http.Client 25 | } 26 | invocations map[string][][]interface{} 27 | invocationsMutex sync.RWMutex 28 | } 29 | 30 | func (fake *FakeHasImports) DoThings(arg1 io.Writer, arg2 *os.File) *http.Client { 31 | fake.doThingsMutex.Lock() 32 | ret, specificReturn := fake.doThingsReturnsOnCall[len(fake.doThingsArgsForCall)] 33 | fake.doThingsArgsForCall = append(fake.doThingsArgsForCall, struct { 34 | arg1 io.Writer 35 | arg2 *os.File 36 | }{arg1, arg2}) 37 | stub := fake.DoThingsStub 38 | fakeReturns := fake.doThingsReturns 39 | fake.recordInvocation("DoThings", []interface{}{arg1, arg2}) 40 | fake.doThingsMutex.Unlock() 41 | if stub != nil { 42 | return stub(arg1, arg2) 43 | } 44 | if specificReturn { 45 | return ret.result1 46 | } 47 | return fakeReturns.result1 48 | } 49 | 50 | func (fake *FakeHasImports) DoThingsCallCount() int { 51 | fake.doThingsMutex.RLock() 52 | defer fake.doThingsMutex.RUnlock() 53 | return len(fake.doThingsArgsForCall) 54 | } 55 | 56 | func (fake *FakeHasImports) DoThingsCalls(stub func(io.Writer, *os.File) *http.Client) { 57 | fake.doThingsMutex.Lock() 58 | defer fake.doThingsMutex.Unlock() 59 | fake.DoThingsStub = stub 60 | } 61 | 62 | func (fake *FakeHasImports) DoThingsArgsForCall(i int) (io.Writer, *os.File) { 63 | fake.doThingsMutex.RLock() 64 | defer fake.doThingsMutex.RUnlock() 65 | argsForCall := fake.doThingsArgsForCall[i] 66 | return argsForCall.arg1, argsForCall.arg2 67 | } 68 | 69 | func (fake *FakeHasImports) DoThingsReturns(result1 *http.Client) { 70 | fake.doThingsMutex.Lock() 71 | defer fake.doThingsMutex.Unlock() 72 | fake.DoThingsStub = nil 73 | fake.doThingsReturns = struct { 74 | result1 *http.Client 75 | }{result1} 76 | } 77 | 78 | func (fake *FakeHasImports) DoThingsReturnsOnCall(i int, result1 *http.Client) { 79 | fake.doThingsMutex.Lock() 80 | defer fake.doThingsMutex.Unlock() 81 | fake.DoThingsStub = nil 82 | if fake.doThingsReturnsOnCall == nil { 83 | fake.doThingsReturnsOnCall = make(map[int]struct { 84 | result1 *http.Client 85 | }) 86 | } 87 | fake.doThingsReturnsOnCall[i] = struct { 88 | result1 *http.Client 89 | }{result1} 90 | } 91 | 92 | func (fake *FakeHasImports) Invocations() map[string][][]interface{} { 93 | fake.invocationsMutex.RLock() 94 | defer fake.invocationsMutex.RUnlock() 95 | fake.doThingsMutex.RLock() 96 | defer fake.doThingsMutex.RUnlock() 97 | copiedInvocations := map[string][][]interface{}{} 98 | for key, value := range fake.invocations { 99 | copiedInvocations[key] = value 100 | } 101 | return copiedInvocations 102 | } 103 | 104 | func (fake *FakeHasImports) recordInvocation(key string, args []interface{}) { 105 | fake.invocationsMutex.Lock() 106 | defer fake.invocationsMutex.Unlock() 107 | if fake.invocations == nil { 108 | fake.invocations = map[string][][]interface{}{} 109 | } 110 | if fake.invocations[key] == nil { 111 | fake.invocations[key] = [][]interface{}{} 112 | } 113 | fake.invocations[key] = append(fake.invocations[key], args) 114 | } 115 | 116 | var _ fixtures.HasImports = new(FakeHasImports) 117 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_has_other_types.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeHasOtherTypes struct { 11 | GetThingStub func(fixtures.SomeString) fixtures.SomeFunc 12 | getThingMutex sync.RWMutex 13 | getThingArgsForCall []struct { 14 | arg1 fixtures.SomeString 15 | } 16 | getThingReturns struct { 17 | result1 fixtures.SomeFunc 18 | } 19 | getThingReturnsOnCall map[int]struct { 20 | result1 fixtures.SomeFunc 21 | } 22 | invocations map[string][][]interface{} 23 | invocationsMutex sync.RWMutex 24 | } 25 | 26 | func (fake *FakeHasOtherTypes) GetThing(arg1 fixtures.SomeString) fixtures.SomeFunc { 27 | fake.getThingMutex.Lock() 28 | ret, specificReturn := fake.getThingReturnsOnCall[len(fake.getThingArgsForCall)] 29 | fake.getThingArgsForCall = append(fake.getThingArgsForCall, struct { 30 | arg1 fixtures.SomeString 31 | }{arg1}) 32 | stub := fake.GetThingStub 33 | fakeReturns := fake.getThingReturns 34 | fake.recordInvocation("GetThing", []interface{}{arg1}) 35 | fake.getThingMutex.Unlock() 36 | if stub != nil { 37 | return stub(arg1) 38 | } 39 | if specificReturn { 40 | return ret.result1 41 | } 42 | return fakeReturns.result1 43 | } 44 | 45 | func (fake *FakeHasOtherTypes) GetThingCallCount() int { 46 | fake.getThingMutex.RLock() 47 | defer fake.getThingMutex.RUnlock() 48 | return len(fake.getThingArgsForCall) 49 | } 50 | 51 | func (fake *FakeHasOtherTypes) GetThingCalls(stub func(fixtures.SomeString) fixtures.SomeFunc) { 52 | fake.getThingMutex.Lock() 53 | defer fake.getThingMutex.Unlock() 54 | fake.GetThingStub = stub 55 | } 56 | 57 | func (fake *FakeHasOtherTypes) GetThingArgsForCall(i int) fixtures.SomeString { 58 | fake.getThingMutex.RLock() 59 | defer fake.getThingMutex.RUnlock() 60 | argsForCall := fake.getThingArgsForCall[i] 61 | return argsForCall.arg1 62 | } 63 | 64 | func (fake *FakeHasOtherTypes) GetThingReturns(result1 fixtures.SomeFunc) { 65 | fake.getThingMutex.Lock() 66 | defer fake.getThingMutex.Unlock() 67 | fake.GetThingStub = nil 68 | fake.getThingReturns = struct { 69 | result1 fixtures.SomeFunc 70 | }{result1} 71 | } 72 | 73 | func (fake *FakeHasOtherTypes) GetThingReturnsOnCall(i int, result1 fixtures.SomeFunc) { 74 | fake.getThingMutex.Lock() 75 | defer fake.getThingMutex.Unlock() 76 | fake.GetThingStub = nil 77 | if fake.getThingReturnsOnCall == nil { 78 | fake.getThingReturnsOnCall = make(map[int]struct { 79 | result1 fixtures.SomeFunc 80 | }) 81 | } 82 | fake.getThingReturnsOnCall[i] = struct { 83 | result1 fixtures.SomeFunc 84 | }{result1} 85 | } 86 | 87 | func (fake *FakeHasOtherTypes) Invocations() map[string][][]interface{} { 88 | fake.invocationsMutex.RLock() 89 | defer fake.invocationsMutex.RUnlock() 90 | fake.getThingMutex.RLock() 91 | defer fake.getThingMutex.RUnlock() 92 | copiedInvocations := map[string][][]interface{}{} 93 | for key, value := range fake.invocations { 94 | copiedInvocations[key] = value 95 | } 96 | return copiedInvocations 97 | } 98 | 99 | func (fake *FakeHasOtherTypes) recordInvocation(key string, args []interface{}) { 100 | fake.invocationsMutex.Lock() 101 | defer fake.invocationsMutex.Unlock() 102 | if fake.invocations == nil { 103 | fake.invocations = map[string][][]interface{}{} 104 | } 105 | if fake.invocations[key] == nil { 106 | fake.invocations[key] = [][]interface{}{} 107 | } 108 | fake.invocations[key] = append(fake.invocations[key], args) 109 | } 110 | 111 | var _ fixtures.HasOtherTypes = new(FakeHasOtherTypes) 112 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_has_var_args.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeHasVarArgs struct { 11 | DoMoreThingsStub func(int, int, ...string) int 12 | doMoreThingsMutex sync.RWMutex 13 | doMoreThingsArgsForCall []struct { 14 | arg1 int 15 | arg2 int 16 | arg3 []string 17 | } 18 | doMoreThingsReturns struct { 19 | result1 int 20 | } 21 | doMoreThingsReturnsOnCall map[int]struct { 22 | result1 int 23 | } 24 | DoThingsStub func(int, ...string) int 25 | doThingsMutex sync.RWMutex 26 | doThingsArgsForCall []struct { 27 | arg1 int 28 | arg2 []string 29 | } 30 | doThingsReturns struct { 31 | result1 int 32 | } 33 | doThingsReturnsOnCall map[int]struct { 34 | result1 int 35 | } 36 | invocations map[string][][]interface{} 37 | invocationsMutex sync.RWMutex 38 | } 39 | 40 | func (fake *FakeHasVarArgs) DoMoreThings(arg1 int, arg2 int, arg3 ...string) int { 41 | fake.doMoreThingsMutex.Lock() 42 | ret, specificReturn := fake.doMoreThingsReturnsOnCall[len(fake.doMoreThingsArgsForCall)] 43 | fake.doMoreThingsArgsForCall = append(fake.doMoreThingsArgsForCall, struct { 44 | arg1 int 45 | arg2 int 46 | arg3 []string 47 | }{arg1, arg2, arg3}) 48 | stub := fake.DoMoreThingsStub 49 | fakeReturns := fake.doMoreThingsReturns 50 | fake.recordInvocation("DoMoreThings", []interface{}{arg1, arg2, arg3}) 51 | fake.doMoreThingsMutex.Unlock() 52 | if stub != nil { 53 | return stub(arg1, arg2, arg3...) 54 | } 55 | if specificReturn { 56 | return ret.result1 57 | } 58 | return fakeReturns.result1 59 | } 60 | 61 | func (fake *FakeHasVarArgs) DoMoreThingsCallCount() int { 62 | fake.doMoreThingsMutex.RLock() 63 | defer fake.doMoreThingsMutex.RUnlock() 64 | return len(fake.doMoreThingsArgsForCall) 65 | } 66 | 67 | func (fake *FakeHasVarArgs) DoMoreThingsCalls(stub func(int, int, ...string) int) { 68 | fake.doMoreThingsMutex.Lock() 69 | defer fake.doMoreThingsMutex.Unlock() 70 | fake.DoMoreThingsStub = stub 71 | } 72 | 73 | func (fake *FakeHasVarArgs) DoMoreThingsArgsForCall(i int) (int, int, []string) { 74 | fake.doMoreThingsMutex.RLock() 75 | defer fake.doMoreThingsMutex.RUnlock() 76 | argsForCall := fake.doMoreThingsArgsForCall[i] 77 | return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 78 | } 79 | 80 | func (fake *FakeHasVarArgs) DoMoreThingsReturns(result1 int) { 81 | fake.doMoreThingsMutex.Lock() 82 | defer fake.doMoreThingsMutex.Unlock() 83 | fake.DoMoreThingsStub = nil 84 | fake.doMoreThingsReturns = struct { 85 | result1 int 86 | }{result1} 87 | } 88 | 89 | func (fake *FakeHasVarArgs) DoMoreThingsReturnsOnCall(i int, result1 int) { 90 | fake.doMoreThingsMutex.Lock() 91 | defer fake.doMoreThingsMutex.Unlock() 92 | fake.DoMoreThingsStub = nil 93 | if fake.doMoreThingsReturnsOnCall == nil { 94 | fake.doMoreThingsReturnsOnCall = make(map[int]struct { 95 | result1 int 96 | }) 97 | } 98 | fake.doMoreThingsReturnsOnCall[i] = struct { 99 | result1 int 100 | }{result1} 101 | } 102 | 103 | func (fake *FakeHasVarArgs) DoThings(arg1 int, arg2 ...string) int { 104 | fake.doThingsMutex.Lock() 105 | ret, specificReturn := fake.doThingsReturnsOnCall[len(fake.doThingsArgsForCall)] 106 | fake.doThingsArgsForCall = append(fake.doThingsArgsForCall, struct { 107 | arg1 int 108 | arg2 []string 109 | }{arg1, arg2}) 110 | stub := fake.DoThingsStub 111 | fakeReturns := fake.doThingsReturns 112 | fake.recordInvocation("DoThings", []interface{}{arg1, arg2}) 113 | fake.doThingsMutex.Unlock() 114 | if stub != nil { 115 | return stub(arg1, arg2...) 116 | } 117 | if specificReturn { 118 | return ret.result1 119 | } 120 | return fakeReturns.result1 121 | } 122 | 123 | func (fake *FakeHasVarArgs) DoThingsCallCount() int { 124 | fake.doThingsMutex.RLock() 125 | defer fake.doThingsMutex.RUnlock() 126 | return len(fake.doThingsArgsForCall) 127 | } 128 | 129 | func (fake *FakeHasVarArgs) DoThingsCalls(stub func(int, ...string) int) { 130 | fake.doThingsMutex.Lock() 131 | defer fake.doThingsMutex.Unlock() 132 | fake.DoThingsStub = stub 133 | } 134 | 135 | func (fake *FakeHasVarArgs) DoThingsArgsForCall(i int) (int, []string) { 136 | fake.doThingsMutex.RLock() 137 | defer fake.doThingsMutex.RUnlock() 138 | argsForCall := fake.doThingsArgsForCall[i] 139 | return argsForCall.arg1, argsForCall.arg2 140 | } 141 | 142 | func (fake *FakeHasVarArgs) DoThingsReturns(result1 int) { 143 | fake.doThingsMutex.Lock() 144 | defer fake.doThingsMutex.Unlock() 145 | fake.DoThingsStub = nil 146 | fake.doThingsReturns = struct { 147 | result1 int 148 | }{result1} 149 | } 150 | 151 | func (fake *FakeHasVarArgs) DoThingsReturnsOnCall(i int, result1 int) { 152 | fake.doThingsMutex.Lock() 153 | defer fake.doThingsMutex.Unlock() 154 | fake.DoThingsStub = nil 155 | if fake.doThingsReturnsOnCall == nil { 156 | fake.doThingsReturnsOnCall = make(map[int]struct { 157 | result1 int 158 | }) 159 | } 160 | fake.doThingsReturnsOnCall[i] = struct { 161 | result1 int 162 | }{result1} 163 | } 164 | 165 | func (fake *FakeHasVarArgs) Invocations() map[string][][]interface{} { 166 | fake.invocationsMutex.RLock() 167 | defer fake.invocationsMutex.RUnlock() 168 | fake.doMoreThingsMutex.RLock() 169 | defer fake.doMoreThingsMutex.RUnlock() 170 | fake.doThingsMutex.RLock() 171 | defer fake.doThingsMutex.RUnlock() 172 | copiedInvocations := map[string][][]interface{}{} 173 | for key, value := range fake.invocations { 174 | copiedInvocations[key] = value 175 | } 176 | return copiedInvocations 177 | } 178 | 179 | func (fake *FakeHasVarArgs) recordInvocation(key string, args []interface{}) { 180 | fake.invocationsMutex.Lock() 181 | defer fake.invocationsMutex.Unlock() 182 | if fake.invocations == nil { 183 | fake.invocations = map[string][][]interface{}{} 184 | } 185 | if fake.invocations[key] == nil { 186 | fake.invocations[key] = [][]interface{}{} 187 | } 188 | fake.invocations[key] = append(fake.invocations[key], args) 189 | } 190 | 191 | var _ fixtures.HasVarArgs = new(FakeHasVarArgs) 192 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_has_var_args_with_local_types.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeHasVarArgsWithLocalTypes struct { 11 | DoThingsStub func(...fixtures.LocalType) 12 | doThingsMutex sync.RWMutex 13 | doThingsArgsForCall []struct { 14 | arg1 []fixtures.LocalType 15 | } 16 | invocations map[string][][]interface{} 17 | invocationsMutex sync.RWMutex 18 | } 19 | 20 | func (fake *FakeHasVarArgsWithLocalTypes) DoThings(arg1 ...fixtures.LocalType) { 21 | fake.doThingsMutex.Lock() 22 | fake.doThingsArgsForCall = append(fake.doThingsArgsForCall, struct { 23 | arg1 []fixtures.LocalType 24 | }{arg1}) 25 | stub := fake.DoThingsStub 26 | fake.recordInvocation("DoThings", []interface{}{arg1}) 27 | fake.doThingsMutex.Unlock() 28 | if stub != nil { 29 | fake.DoThingsStub(arg1...) 30 | } 31 | } 32 | 33 | func (fake *FakeHasVarArgsWithLocalTypes) DoThingsCallCount() int { 34 | fake.doThingsMutex.RLock() 35 | defer fake.doThingsMutex.RUnlock() 36 | return len(fake.doThingsArgsForCall) 37 | } 38 | 39 | func (fake *FakeHasVarArgsWithLocalTypes) DoThingsCalls(stub func(...fixtures.LocalType)) { 40 | fake.doThingsMutex.Lock() 41 | defer fake.doThingsMutex.Unlock() 42 | fake.DoThingsStub = stub 43 | } 44 | 45 | func (fake *FakeHasVarArgsWithLocalTypes) DoThingsArgsForCall(i int) []fixtures.LocalType { 46 | fake.doThingsMutex.RLock() 47 | defer fake.doThingsMutex.RUnlock() 48 | argsForCall := fake.doThingsArgsForCall[i] 49 | return argsForCall.arg1 50 | } 51 | 52 | func (fake *FakeHasVarArgsWithLocalTypes) Invocations() map[string][][]interface{} { 53 | fake.invocationsMutex.RLock() 54 | defer fake.invocationsMutex.RUnlock() 55 | fake.doThingsMutex.RLock() 56 | defer fake.doThingsMutex.RUnlock() 57 | copiedInvocations := map[string][][]interface{}{} 58 | for key, value := range fake.invocations { 59 | copiedInvocations[key] = value 60 | } 61 | return copiedInvocations 62 | } 63 | 64 | func (fake *FakeHasVarArgsWithLocalTypes) recordInvocation(key string, args []interface{}) { 65 | fake.invocationsMutex.Lock() 66 | defer fake.invocationsMutex.Unlock() 67 | if fake.invocations == nil { 68 | fake.invocations = map[string][][]interface{}{} 69 | } 70 | if fake.invocations[key] == nil { 71 | fake.invocations[key] = [][]interface{}{} 72 | } 73 | fake.invocations[key] = append(fake.invocations[key], args) 74 | } 75 | 76 | var _ fixtures.HasVarArgsWithLocalTypes = new(FakeHasVarArgsWithLocalTypes) 77 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_imports_go_hyphen_package.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | hyphenpackage "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/go-hyphenpackage" 9 | ) 10 | 11 | type FakeImportsGoHyphenPackage struct { 12 | UseHyphenTypeStub func(hyphenpackage.HyphenType) 13 | useHyphenTypeMutex sync.RWMutex 14 | useHyphenTypeArgsForCall []struct { 15 | arg1 hyphenpackage.HyphenType 16 | } 17 | invocations map[string][][]interface{} 18 | invocationsMutex sync.RWMutex 19 | } 20 | 21 | func (fake *FakeImportsGoHyphenPackage) UseHyphenType(arg1 hyphenpackage.HyphenType) { 22 | fake.useHyphenTypeMutex.Lock() 23 | fake.useHyphenTypeArgsForCall = append(fake.useHyphenTypeArgsForCall, struct { 24 | arg1 hyphenpackage.HyphenType 25 | }{arg1}) 26 | stub := fake.UseHyphenTypeStub 27 | fake.recordInvocation("UseHyphenType", []interface{}{arg1}) 28 | fake.useHyphenTypeMutex.Unlock() 29 | if stub != nil { 30 | fake.UseHyphenTypeStub(arg1) 31 | } 32 | } 33 | 34 | func (fake *FakeImportsGoHyphenPackage) UseHyphenTypeCallCount() int { 35 | fake.useHyphenTypeMutex.RLock() 36 | defer fake.useHyphenTypeMutex.RUnlock() 37 | return len(fake.useHyphenTypeArgsForCall) 38 | } 39 | 40 | func (fake *FakeImportsGoHyphenPackage) UseHyphenTypeCalls(stub func(hyphenpackage.HyphenType)) { 41 | fake.useHyphenTypeMutex.Lock() 42 | defer fake.useHyphenTypeMutex.Unlock() 43 | fake.UseHyphenTypeStub = stub 44 | } 45 | 46 | func (fake *FakeImportsGoHyphenPackage) UseHyphenTypeArgsForCall(i int) hyphenpackage.HyphenType { 47 | fake.useHyphenTypeMutex.RLock() 48 | defer fake.useHyphenTypeMutex.RUnlock() 49 | argsForCall := fake.useHyphenTypeArgsForCall[i] 50 | return argsForCall.arg1 51 | } 52 | 53 | func (fake *FakeImportsGoHyphenPackage) Invocations() map[string][][]interface{} { 54 | fake.invocationsMutex.RLock() 55 | defer fake.invocationsMutex.RUnlock() 56 | fake.useHyphenTypeMutex.RLock() 57 | defer fake.useHyphenTypeMutex.RUnlock() 58 | copiedInvocations := map[string][][]interface{}{} 59 | for key, value := range fake.invocations { 60 | copiedInvocations[key] = value 61 | } 62 | return copiedInvocations 63 | } 64 | 65 | func (fake *FakeImportsGoHyphenPackage) recordInvocation(key string, args []interface{}) { 66 | fake.invocationsMutex.Lock() 67 | defer fake.invocationsMutex.Unlock() 68 | if fake.invocations == nil { 69 | fake.invocations = map[string][][]interface{}{} 70 | } 71 | if fake.invocations[key] == nil { 72 | fake.invocations[key] = [][]interface{}{} 73 | } 74 | fake.invocations[key] = append(fake.invocations[key], args) 75 | } 76 | 77 | var _ fixtures.ImportsGoHyphenPackage = new(FakeImportsGoHyphenPackage) 78 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_inline_struct_params.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "context" 6 | "net/http" 7 | "sync" 8 | "time" 9 | 10 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 11 | ) 12 | 13 | type FakeInlineStructParams struct { 14 | DoSomethingStub func(context.Context, struct { 15 | SomeString string 16 | SomeStringPointer *string 17 | SomeTime time.Time 18 | SomeTimePointer *time.Time 19 | HTTPRequest http.Request 20 | }) error 21 | doSomethingMutex sync.RWMutex 22 | doSomethingArgsForCall []struct { 23 | arg1 context.Context 24 | arg2 struct { 25 | SomeString string 26 | SomeStringPointer *string 27 | SomeTime time.Time 28 | SomeTimePointer *time.Time 29 | HTTPRequest http.Request 30 | } 31 | } 32 | doSomethingReturns struct { 33 | result1 error 34 | } 35 | doSomethingReturnsOnCall map[int]struct { 36 | result1 error 37 | } 38 | invocations map[string][][]interface{} 39 | invocationsMutex sync.RWMutex 40 | } 41 | 42 | func (fake *FakeInlineStructParams) DoSomething(arg1 context.Context, arg2 struct { 43 | SomeString string 44 | SomeStringPointer *string 45 | SomeTime time.Time 46 | SomeTimePointer *time.Time 47 | HTTPRequest http.Request 48 | }) error { 49 | fake.doSomethingMutex.Lock() 50 | ret, specificReturn := fake.doSomethingReturnsOnCall[len(fake.doSomethingArgsForCall)] 51 | fake.doSomethingArgsForCall = append(fake.doSomethingArgsForCall, struct { 52 | arg1 context.Context 53 | arg2 struct { 54 | SomeString string 55 | SomeStringPointer *string 56 | SomeTime time.Time 57 | SomeTimePointer *time.Time 58 | HTTPRequest http.Request 59 | } 60 | }{arg1, arg2}) 61 | stub := fake.DoSomethingStub 62 | fakeReturns := fake.doSomethingReturns 63 | fake.recordInvocation("DoSomething", []interface{}{arg1, arg2}) 64 | fake.doSomethingMutex.Unlock() 65 | if stub != nil { 66 | return stub(arg1, arg2) 67 | } 68 | if specificReturn { 69 | return ret.result1 70 | } 71 | return fakeReturns.result1 72 | } 73 | 74 | func (fake *FakeInlineStructParams) DoSomethingCallCount() int { 75 | fake.doSomethingMutex.RLock() 76 | defer fake.doSomethingMutex.RUnlock() 77 | return len(fake.doSomethingArgsForCall) 78 | } 79 | 80 | func (fake *FakeInlineStructParams) DoSomethingCalls(stub func(context.Context, struct { 81 | SomeString string 82 | SomeStringPointer *string 83 | SomeTime time.Time 84 | SomeTimePointer *time.Time 85 | HTTPRequest http.Request 86 | }) error) { 87 | fake.doSomethingMutex.Lock() 88 | defer fake.doSomethingMutex.Unlock() 89 | fake.DoSomethingStub = stub 90 | } 91 | 92 | func (fake *FakeInlineStructParams) DoSomethingArgsForCall(i int) (context.Context, struct { 93 | SomeString string 94 | SomeStringPointer *string 95 | SomeTime time.Time 96 | SomeTimePointer *time.Time 97 | HTTPRequest http.Request 98 | }) { 99 | fake.doSomethingMutex.RLock() 100 | defer fake.doSomethingMutex.RUnlock() 101 | argsForCall := fake.doSomethingArgsForCall[i] 102 | return argsForCall.arg1, argsForCall.arg2 103 | } 104 | 105 | func (fake *FakeInlineStructParams) DoSomethingReturns(result1 error) { 106 | fake.doSomethingMutex.Lock() 107 | defer fake.doSomethingMutex.Unlock() 108 | fake.DoSomethingStub = nil 109 | fake.doSomethingReturns = struct { 110 | result1 error 111 | }{result1} 112 | } 113 | 114 | func (fake *FakeInlineStructParams) DoSomethingReturnsOnCall(i int, result1 error) { 115 | fake.doSomethingMutex.Lock() 116 | defer fake.doSomethingMutex.Unlock() 117 | fake.DoSomethingStub = nil 118 | if fake.doSomethingReturnsOnCall == nil { 119 | fake.doSomethingReturnsOnCall = make(map[int]struct { 120 | result1 error 121 | }) 122 | } 123 | fake.doSomethingReturnsOnCall[i] = struct { 124 | result1 error 125 | }{result1} 126 | } 127 | 128 | func (fake *FakeInlineStructParams) Invocations() map[string][][]interface{} { 129 | fake.invocationsMutex.RLock() 130 | defer fake.invocationsMutex.RUnlock() 131 | fake.doSomethingMutex.RLock() 132 | defer fake.doSomethingMutex.RUnlock() 133 | copiedInvocations := map[string][][]interface{}{} 134 | for key, value := range fake.invocations { 135 | copiedInvocations[key] = value 136 | } 137 | return copiedInvocations 138 | } 139 | 140 | func (fake *FakeInlineStructParams) recordInvocation(key string, args []interface{}) { 141 | fake.invocationsMutex.Lock() 142 | defer fake.invocationsMutex.Unlock() 143 | if fake.invocations == nil { 144 | fake.invocations = map[string][][]interface{}{} 145 | } 146 | if fake.invocations[key] == nil { 147 | fake.invocations[key] = [][]interface{}{} 148 | } 149 | fake.invocations[key] = append(fake.invocations[key], args) 150 | } 151 | 152 | var _ fixtures.InlineStructParams = new(FakeInlineStructParams) 153 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_reuses_arg_types.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeReusesArgTypes struct { 11 | DoThingsStub func(string, string) 12 | doThingsMutex sync.RWMutex 13 | doThingsArgsForCall []struct { 14 | arg1 string 15 | arg2 string 16 | } 17 | invocations map[string][][]interface{} 18 | invocationsMutex sync.RWMutex 19 | } 20 | 21 | func (fake *FakeReusesArgTypes) DoThings(arg1 string, arg2 string) { 22 | fake.doThingsMutex.Lock() 23 | fake.doThingsArgsForCall = append(fake.doThingsArgsForCall, struct { 24 | arg1 string 25 | arg2 string 26 | }{arg1, arg2}) 27 | stub := fake.DoThingsStub 28 | fake.recordInvocation("DoThings", []interface{}{arg1, arg2}) 29 | fake.doThingsMutex.Unlock() 30 | if stub != nil { 31 | fake.DoThingsStub(arg1, arg2) 32 | } 33 | } 34 | 35 | func (fake *FakeReusesArgTypes) DoThingsCallCount() int { 36 | fake.doThingsMutex.RLock() 37 | defer fake.doThingsMutex.RUnlock() 38 | return len(fake.doThingsArgsForCall) 39 | } 40 | 41 | func (fake *FakeReusesArgTypes) DoThingsCalls(stub func(string, string)) { 42 | fake.doThingsMutex.Lock() 43 | defer fake.doThingsMutex.Unlock() 44 | fake.DoThingsStub = stub 45 | } 46 | 47 | func (fake *FakeReusesArgTypes) DoThingsArgsForCall(i int) (string, string) { 48 | fake.doThingsMutex.RLock() 49 | defer fake.doThingsMutex.RUnlock() 50 | argsForCall := fake.doThingsArgsForCall[i] 51 | return argsForCall.arg1, argsForCall.arg2 52 | } 53 | 54 | func (fake *FakeReusesArgTypes) Invocations() map[string][][]interface{} { 55 | fake.invocationsMutex.RLock() 56 | defer fake.invocationsMutex.RUnlock() 57 | fake.doThingsMutex.RLock() 58 | defer fake.doThingsMutex.RUnlock() 59 | copiedInvocations := map[string][][]interface{}{} 60 | for key, value := range fake.invocations { 61 | copiedInvocations[key] = value 62 | } 63 | return copiedInvocations 64 | } 65 | 66 | func (fake *FakeReusesArgTypes) recordInvocation(key string, args []interface{}) { 67 | fake.invocationsMutex.Lock() 68 | defer fake.invocationsMutex.Unlock() 69 | if fake.invocations == nil { 70 | fake.invocations = map[string][][]interface{}{} 71 | } 72 | if fake.invocations[key] == nil { 73 | fake.invocations[key] = [][]interface{}{} 74 | } 75 | fake.invocations[key] = append(fake.invocations[key], args) 76 | } 77 | 78 | var _ fixtures.ReusesArgTypes = new(FakeReusesArgTypes) 79 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_second_interface.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeSecondInterface struct { 11 | EmbeddedMethodStub func() string 12 | embeddedMethodMutex sync.RWMutex 13 | embeddedMethodArgsForCall []struct { 14 | } 15 | embeddedMethodReturns struct { 16 | result1 string 17 | } 18 | embeddedMethodReturnsOnCall map[int]struct { 19 | result1 string 20 | } 21 | invocations map[string][][]interface{} 22 | invocationsMutex sync.RWMutex 23 | } 24 | 25 | func (fake *FakeSecondInterface) EmbeddedMethod() string { 26 | fake.embeddedMethodMutex.Lock() 27 | ret, specificReturn := fake.embeddedMethodReturnsOnCall[len(fake.embeddedMethodArgsForCall)] 28 | fake.embeddedMethodArgsForCall = append(fake.embeddedMethodArgsForCall, struct { 29 | }{}) 30 | stub := fake.EmbeddedMethodStub 31 | fakeReturns := fake.embeddedMethodReturns 32 | fake.recordInvocation("EmbeddedMethod", []interface{}{}) 33 | fake.embeddedMethodMutex.Unlock() 34 | if stub != nil { 35 | return stub() 36 | } 37 | if specificReturn { 38 | return ret.result1 39 | } 40 | return fakeReturns.result1 41 | } 42 | 43 | func (fake *FakeSecondInterface) EmbeddedMethodCallCount() int { 44 | fake.embeddedMethodMutex.RLock() 45 | defer fake.embeddedMethodMutex.RUnlock() 46 | return len(fake.embeddedMethodArgsForCall) 47 | } 48 | 49 | func (fake *FakeSecondInterface) EmbeddedMethodCalls(stub func() string) { 50 | fake.embeddedMethodMutex.Lock() 51 | defer fake.embeddedMethodMutex.Unlock() 52 | fake.EmbeddedMethodStub = stub 53 | } 54 | 55 | func (fake *FakeSecondInterface) EmbeddedMethodReturns(result1 string) { 56 | fake.embeddedMethodMutex.Lock() 57 | defer fake.embeddedMethodMutex.Unlock() 58 | fake.EmbeddedMethodStub = nil 59 | fake.embeddedMethodReturns = struct { 60 | result1 string 61 | }{result1} 62 | } 63 | 64 | func (fake *FakeSecondInterface) EmbeddedMethodReturnsOnCall(i int, result1 string) { 65 | fake.embeddedMethodMutex.Lock() 66 | defer fake.embeddedMethodMutex.Unlock() 67 | fake.EmbeddedMethodStub = nil 68 | if fake.embeddedMethodReturnsOnCall == nil { 69 | fake.embeddedMethodReturnsOnCall = make(map[int]struct { 70 | result1 string 71 | }) 72 | } 73 | fake.embeddedMethodReturnsOnCall[i] = struct { 74 | result1 string 75 | }{result1} 76 | } 77 | 78 | func (fake *FakeSecondInterface) Invocations() map[string][][]interface{} { 79 | fake.invocationsMutex.RLock() 80 | defer fake.invocationsMutex.RUnlock() 81 | fake.embeddedMethodMutex.RLock() 82 | defer fake.embeddedMethodMutex.RUnlock() 83 | copiedInvocations := map[string][][]interface{}{} 84 | for key, value := range fake.invocations { 85 | copiedInvocations[key] = value 86 | } 87 | return copiedInvocations 88 | } 89 | 90 | func (fake *FakeSecondInterface) recordInvocation(key string, args []interface{}) { 91 | fake.invocationsMutex.Lock() 92 | defer fake.invocationsMutex.Unlock() 93 | if fake.invocations == nil { 94 | fake.invocations = map[string][][]interface{}{} 95 | } 96 | if fake.invocations[key] == nil { 97 | fake.invocations[key] = [][]interface{}{} 98 | } 99 | fake.invocations[key] = append(fake.invocations[key], args) 100 | } 101 | 102 | var _ fixtures.SecondInterface = new(FakeSecondInterface) 103 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_something_else.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeSomethingElse struct { 11 | ReturnStuffStub func() (int, int) 12 | returnStuffMutex sync.RWMutex 13 | returnStuffArgsForCall []struct { 14 | } 15 | returnStuffReturns struct { 16 | result1 int 17 | result2 int 18 | } 19 | returnStuffReturnsOnCall map[int]struct { 20 | result1 int 21 | result2 int 22 | } 23 | invocations map[string][][]interface{} 24 | invocationsMutex sync.RWMutex 25 | } 26 | 27 | func (fake *FakeSomethingElse) ReturnStuff() (int, int) { 28 | fake.returnStuffMutex.Lock() 29 | ret, specificReturn := fake.returnStuffReturnsOnCall[len(fake.returnStuffArgsForCall)] 30 | fake.returnStuffArgsForCall = append(fake.returnStuffArgsForCall, struct { 31 | }{}) 32 | stub := fake.ReturnStuffStub 33 | fakeReturns := fake.returnStuffReturns 34 | fake.recordInvocation("ReturnStuff", []interface{}{}) 35 | fake.returnStuffMutex.Unlock() 36 | if stub != nil { 37 | return stub() 38 | } 39 | if specificReturn { 40 | return ret.result1, ret.result2 41 | } 42 | return fakeReturns.result1, fakeReturns.result2 43 | } 44 | 45 | func (fake *FakeSomethingElse) ReturnStuffCallCount() int { 46 | fake.returnStuffMutex.RLock() 47 | defer fake.returnStuffMutex.RUnlock() 48 | return len(fake.returnStuffArgsForCall) 49 | } 50 | 51 | func (fake *FakeSomethingElse) ReturnStuffCalls(stub func() (int, int)) { 52 | fake.returnStuffMutex.Lock() 53 | defer fake.returnStuffMutex.Unlock() 54 | fake.ReturnStuffStub = stub 55 | } 56 | 57 | func (fake *FakeSomethingElse) ReturnStuffReturns(result1 int, result2 int) { 58 | fake.returnStuffMutex.Lock() 59 | defer fake.returnStuffMutex.Unlock() 60 | fake.ReturnStuffStub = nil 61 | fake.returnStuffReturns = struct { 62 | result1 int 63 | result2 int 64 | }{result1, result2} 65 | } 66 | 67 | func (fake *FakeSomethingElse) ReturnStuffReturnsOnCall(i int, result1 int, result2 int) { 68 | fake.returnStuffMutex.Lock() 69 | defer fake.returnStuffMutex.Unlock() 70 | fake.ReturnStuffStub = nil 71 | if fake.returnStuffReturnsOnCall == nil { 72 | fake.returnStuffReturnsOnCall = make(map[int]struct { 73 | result1 int 74 | result2 int 75 | }) 76 | } 77 | fake.returnStuffReturnsOnCall[i] = struct { 78 | result1 int 79 | result2 int 80 | }{result1, result2} 81 | } 82 | 83 | func (fake *FakeSomethingElse) Invocations() map[string][][]interface{} { 84 | fake.invocationsMutex.RLock() 85 | defer fake.invocationsMutex.RUnlock() 86 | fake.returnStuffMutex.RLock() 87 | defer fake.returnStuffMutex.RUnlock() 88 | copiedInvocations := map[string][][]interface{}{} 89 | for key, value := range fake.invocations { 90 | copiedInvocations[key] = value 91 | } 92 | return copiedInvocations 93 | } 94 | 95 | func (fake *FakeSomethingElse) recordInvocation(key string, args []interface{}) { 96 | fake.invocationsMutex.Lock() 97 | defer fake.invocationsMutex.Unlock() 98 | if fake.invocations == nil { 99 | fake.invocations = map[string][][]interface{}{} 100 | } 101 | if fake.invocations[key] == nil { 102 | fake.invocations[key] = [][]interface{}{} 103 | } 104 | fake.invocations[key] = append(fake.invocations[key], args) 105 | } 106 | 107 | var _ fixtures.SomethingElse = new(FakeSomethingElse) 108 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_something_factory.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeSomethingFactory struct { 11 | Stub func(string, map[string]interface{}) string 12 | mutex sync.RWMutex 13 | argsForCall []struct { 14 | arg1 string 15 | arg2 map[string]interface{} 16 | } 17 | returns struct { 18 | result1 string 19 | } 20 | returnsOnCall map[int]struct { 21 | result1 string 22 | } 23 | invocations map[string][][]interface{} 24 | invocationsMutex sync.RWMutex 25 | } 26 | 27 | func (fake *FakeSomethingFactory) Spy(arg1 string, arg2 map[string]interface{}) string { 28 | fake.mutex.Lock() 29 | ret, specificReturn := fake.returnsOnCall[len(fake.argsForCall)] 30 | fake.argsForCall = append(fake.argsForCall, struct { 31 | arg1 string 32 | arg2 map[string]interface{} 33 | }{arg1, arg2}) 34 | stub := fake.Stub 35 | returns := fake.returns 36 | fake.recordInvocation("SomethingFactory", []interface{}{arg1, arg2}) 37 | fake.mutex.Unlock() 38 | if stub != nil { 39 | return stub(arg1, arg2) 40 | } 41 | if specificReturn { 42 | return ret.result1 43 | } 44 | return returns.result1 45 | } 46 | 47 | func (fake *FakeSomethingFactory) CallCount() int { 48 | fake.mutex.RLock() 49 | defer fake.mutex.RUnlock() 50 | return len(fake.argsForCall) 51 | } 52 | 53 | func (fake *FakeSomethingFactory) Calls(stub func(string, map[string]interface{}) string) { 54 | fake.mutex.Lock() 55 | defer fake.mutex.Unlock() 56 | fake.Stub = stub 57 | } 58 | 59 | func (fake *FakeSomethingFactory) ArgsForCall(i int) (string, map[string]interface{}) { 60 | fake.mutex.RLock() 61 | defer fake.mutex.RUnlock() 62 | return fake.argsForCall[i].arg1, fake.argsForCall[i].arg2 63 | } 64 | 65 | func (fake *FakeSomethingFactory) Returns(result1 string) { 66 | fake.mutex.Lock() 67 | defer fake.mutex.Unlock() 68 | fake.Stub = nil 69 | fake.returns = struct { 70 | result1 string 71 | }{result1} 72 | } 73 | 74 | func (fake *FakeSomethingFactory) ReturnsOnCall(i int, result1 string) { 75 | fake.mutex.Lock() 76 | defer fake.mutex.Unlock() 77 | fake.Stub = nil 78 | if fake.returnsOnCall == nil { 79 | fake.returnsOnCall = make(map[int]struct { 80 | result1 string 81 | }) 82 | } 83 | fake.returnsOnCall[i] = struct { 84 | result1 string 85 | }{result1} 86 | } 87 | 88 | func (fake *FakeSomethingFactory) Invocations() map[string][][]interface{} { 89 | fake.invocationsMutex.RLock() 90 | defer fake.invocationsMutex.RUnlock() 91 | fake.mutex.RLock() 92 | defer fake.mutex.RUnlock() 93 | copiedInvocations := map[string][][]interface{}{} 94 | for key, value := range fake.invocations { 95 | copiedInvocations[key] = value 96 | } 97 | return copiedInvocations 98 | } 99 | 100 | func (fake *FakeSomethingFactory) recordInvocation(key string, args []interface{}) { 101 | fake.invocationsMutex.Lock() 102 | defer fake.invocationsMutex.Unlock() 103 | if fake.invocations == nil { 104 | fake.invocations = map[string][][]interface{}{} 105 | } 106 | if fake.invocations[key] == nil { 107 | fake.invocations[key] = [][]interface{}{} 108 | } 109 | fake.invocations[key] = append(fake.invocations[key], args) 110 | } 111 | 112 | var _ fixtures.SomethingFactory = new(FakeSomethingFactory).Spy 113 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_something_with_foreign_interface.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeSomethingWithForeignInterface struct { 11 | StuffStub func(int) string 12 | stuffMutex sync.RWMutex 13 | stuffArgsForCall []struct { 14 | arg1 int 15 | } 16 | stuffReturns struct { 17 | result1 string 18 | } 19 | stuffReturnsOnCall map[int]struct { 20 | result1 string 21 | } 22 | invocations map[string][][]interface{} 23 | invocationsMutex sync.RWMutex 24 | } 25 | 26 | func (fake *FakeSomethingWithForeignInterface) Stuff(arg1 int) string { 27 | fake.stuffMutex.Lock() 28 | ret, specificReturn := fake.stuffReturnsOnCall[len(fake.stuffArgsForCall)] 29 | fake.stuffArgsForCall = append(fake.stuffArgsForCall, struct { 30 | arg1 int 31 | }{arg1}) 32 | stub := fake.StuffStub 33 | fakeReturns := fake.stuffReturns 34 | fake.recordInvocation("Stuff", []interface{}{arg1}) 35 | fake.stuffMutex.Unlock() 36 | if stub != nil { 37 | return stub(arg1) 38 | } 39 | if specificReturn { 40 | return ret.result1 41 | } 42 | return fakeReturns.result1 43 | } 44 | 45 | func (fake *FakeSomethingWithForeignInterface) StuffCallCount() int { 46 | fake.stuffMutex.RLock() 47 | defer fake.stuffMutex.RUnlock() 48 | return len(fake.stuffArgsForCall) 49 | } 50 | 51 | func (fake *FakeSomethingWithForeignInterface) StuffCalls(stub func(int) string) { 52 | fake.stuffMutex.Lock() 53 | defer fake.stuffMutex.Unlock() 54 | fake.StuffStub = stub 55 | } 56 | 57 | func (fake *FakeSomethingWithForeignInterface) StuffArgsForCall(i int) int { 58 | fake.stuffMutex.RLock() 59 | defer fake.stuffMutex.RUnlock() 60 | argsForCall := fake.stuffArgsForCall[i] 61 | return argsForCall.arg1 62 | } 63 | 64 | func (fake *FakeSomethingWithForeignInterface) StuffReturns(result1 string) { 65 | fake.stuffMutex.Lock() 66 | defer fake.stuffMutex.Unlock() 67 | fake.StuffStub = nil 68 | fake.stuffReturns = struct { 69 | result1 string 70 | }{result1} 71 | } 72 | 73 | func (fake *FakeSomethingWithForeignInterface) StuffReturnsOnCall(i int, result1 string) { 74 | fake.stuffMutex.Lock() 75 | defer fake.stuffMutex.Unlock() 76 | fake.StuffStub = nil 77 | if fake.stuffReturnsOnCall == nil { 78 | fake.stuffReturnsOnCall = make(map[int]struct { 79 | result1 string 80 | }) 81 | } 82 | fake.stuffReturnsOnCall[i] = struct { 83 | result1 string 84 | }{result1} 85 | } 86 | 87 | func (fake *FakeSomethingWithForeignInterface) Invocations() map[string][][]interface{} { 88 | fake.invocationsMutex.RLock() 89 | defer fake.invocationsMutex.RUnlock() 90 | fake.stuffMutex.RLock() 91 | defer fake.stuffMutex.RUnlock() 92 | copiedInvocations := map[string][][]interface{}{} 93 | for key, value := range fake.invocations { 94 | copiedInvocations[key] = value 95 | } 96 | return copiedInvocations 97 | } 98 | 99 | func (fake *FakeSomethingWithForeignInterface) recordInvocation(key string, args []interface{}) { 100 | fake.invocationsMutex.Lock() 101 | defer fake.invocationsMutex.Unlock() 102 | if fake.invocations == nil { 103 | fake.invocations = map[string][][]interface{}{} 104 | } 105 | if fake.invocations[key] == nil { 106 | fake.invocations[key] = [][]interface{}{} 107 | } 108 | fake.invocations[key] = append(fake.invocations[key], args) 109 | } 110 | 111 | var _ fixtures.SomethingWithForeignInterface = new(FakeSomethingWithForeignInterface) 112 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_unexported_func.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | ) 7 | 8 | type FakeUnexportedFunc struct { 9 | Stub func(string, map[string]interface{}) string 10 | mutex sync.RWMutex 11 | argsForCall []struct { 12 | arg1 string 13 | arg2 map[string]interface{} 14 | } 15 | returns struct { 16 | result1 string 17 | } 18 | returnsOnCall map[int]struct { 19 | result1 string 20 | } 21 | invocations map[string][][]interface{} 22 | invocationsMutex sync.RWMutex 23 | } 24 | 25 | func (fake *FakeUnexportedFunc) Spy(arg1 string, arg2 map[string]interface{}) string { 26 | fake.mutex.Lock() 27 | ret, specificReturn := fake.returnsOnCall[len(fake.argsForCall)] 28 | fake.argsForCall = append(fake.argsForCall, struct { 29 | arg1 string 30 | arg2 map[string]interface{} 31 | }{arg1, arg2}) 32 | stub := fake.Stub 33 | returns := fake.returns 34 | fake.recordInvocation("unexportedFunc", []interface{}{arg1, arg2}) 35 | fake.mutex.Unlock() 36 | if stub != nil { 37 | return stub(arg1, arg2) 38 | } 39 | if specificReturn { 40 | return ret.result1 41 | } 42 | return returns.result1 43 | } 44 | 45 | func (fake *FakeUnexportedFunc) CallCount() int { 46 | fake.mutex.RLock() 47 | defer fake.mutex.RUnlock() 48 | return len(fake.argsForCall) 49 | } 50 | 51 | func (fake *FakeUnexportedFunc) Calls(stub func(string, map[string]interface{}) string) { 52 | fake.mutex.Lock() 53 | defer fake.mutex.Unlock() 54 | fake.Stub = stub 55 | } 56 | 57 | func (fake *FakeUnexportedFunc) ArgsForCall(i int) (string, map[string]interface{}) { 58 | fake.mutex.RLock() 59 | defer fake.mutex.RUnlock() 60 | return fake.argsForCall[i].arg1, fake.argsForCall[i].arg2 61 | } 62 | 63 | func (fake *FakeUnexportedFunc) Returns(result1 string) { 64 | fake.mutex.Lock() 65 | defer fake.mutex.Unlock() 66 | fake.Stub = nil 67 | fake.returns = struct { 68 | result1 string 69 | }{result1} 70 | } 71 | 72 | func (fake *FakeUnexportedFunc) ReturnsOnCall(i int, result1 string) { 73 | fake.mutex.Lock() 74 | defer fake.mutex.Unlock() 75 | fake.Stub = nil 76 | if fake.returnsOnCall == nil { 77 | fake.returnsOnCall = make(map[int]struct { 78 | result1 string 79 | }) 80 | } 81 | fake.returnsOnCall[i] = struct { 82 | result1 string 83 | }{result1} 84 | } 85 | 86 | func (fake *FakeUnexportedFunc) Invocations() map[string][][]interface{} { 87 | fake.invocationsMutex.RLock() 88 | defer fake.invocationsMutex.RUnlock() 89 | fake.mutex.RLock() 90 | defer fake.mutex.RUnlock() 91 | copiedInvocations := map[string][][]interface{}{} 92 | for key, value := range fake.invocations { 93 | copiedInvocations[key] = value 94 | } 95 | return copiedInvocations 96 | } 97 | 98 | func (fake *FakeUnexportedFunc) recordInvocation(key string, args []interface{}) { 99 | fake.invocationsMutex.Lock() 100 | defer fake.invocationsMutex.Unlock() 101 | if fake.invocations == nil { 102 | fake.invocations = map[string][][]interface{}{} 103 | } 104 | if fake.invocations[key] == nil { 105 | fake.invocations[key] = [][]interface{}{} 106 | } 107 | fake.invocations[key] = append(fake.invocations[key], args) 108 | } 109 | -------------------------------------------------------------------------------- /fixtures/fixturesfakes/fake_unexported_interface.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | ) 7 | 8 | type FakeUnexportedInterface struct { 9 | MethodStub func(string, map[string]interface{}) string 10 | methodMutex sync.RWMutex 11 | methodArgsForCall []struct { 12 | arg1 string 13 | arg2 map[string]interface{} 14 | } 15 | methodReturns struct { 16 | result1 string 17 | } 18 | methodReturnsOnCall map[int]struct { 19 | result1 string 20 | } 21 | invocations map[string][][]interface{} 22 | invocationsMutex sync.RWMutex 23 | } 24 | 25 | func (fake *FakeUnexportedInterface) Method(arg1 string, arg2 map[string]interface{}) string { 26 | fake.methodMutex.Lock() 27 | ret, specificReturn := fake.methodReturnsOnCall[len(fake.methodArgsForCall)] 28 | fake.methodArgsForCall = append(fake.methodArgsForCall, struct { 29 | arg1 string 30 | arg2 map[string]interface{} 31 | }{arg1, arg2}) 32 | stub := fake.MethodStub 33 | fakeReturns := fake.methodReturns 34 | fake.recordInvocation("Method", []interface{}{arg1, arg2}) 35 | fake.methodMutex.Unlock() 36 | if stub != nil { 37 | return stub(arg1, arg2) 38 | } 39 | if specificReturn { 40 | return ret.result1 41 | } 42 | return fakeReturns.result1 43 | } 44 | 45 | func (fake *FakeUnexportedInterface) MethodCallCount() int { 46 | fake.methodMutex.RLock() 47 | defer fake.methodMutex.RUnlock() 48 | return len(fake.methodArgsForCall) 49 | } 50 | 51 | func (fake *FakeUnexportedInterface) MethodCalls(stub func(string, map[string]interface{}) string) { 52 | fake.methodMutex.Lock() 53 | defer fake.methodMutex.Unlock() 54 | fake.MethodStub = stub 55 | } 56 | 57 | func (fake *FakeUnexportedInterface) MethodArgsForCall(i int) (string, map[string]interface{}) { 58 | fake.methodMutex.RLock() 59 | defer fake.methodMutex.RUnlock() 60 | argsForCall := fake.methodArgsForCall[i] 61 | return argsForCall.arg1, argsForCall.arg2 62 | } 63 | 64 | func (fake *FakeUnexportedInterface) MethodReturns(result1 string) { 65 | fake.methodMutex.Lock() 66 | defer fake.methodMutex.Unlock() 67 | fake.MethodStub = nil 68 | fake.methodReturns = struct { 69 | result1 string 70 | }{result1} 71 | } 72 | 73 | func (fake *FakeUnexportedInterface) MethodReturnsOnCall(i int, result1 string) { 74 | fake.methodMutex.Lock() 75 | defer fake.methodMutex.Unlock() 76 | fake.MethodStub = nil 77 | if fake.methodReturnsOnCall == nil { 78 | fake.methodReturnsOnCall = make(map[int]struct { 79 | result1 string 80 | }) 81 | } 82 | fake.methodReturnsOnCall[i] = struct { 83 | result1 string 84 | }{result1} 85 | } 86 | 87 | func (fake *FakeUnexportedInterface) Invocations() map[string][][]interface{} { 88 | fake.invocationsMutex.RLock() 89 | defer fake.invocationsMutex.RUnlock() 90 | fake.methodMutex.RLock() 91 | defer fake.methodMutex.RUnlock() 92 | copiedInvocations := map[string][][]interface{}{} 93 | for key, value := range fake.invocations { 94 | copiedInvocations[key] = value 95 | } 96 | return copiedInvocations 97 | } 98 | 99 | func (fake *FakeUnexportedInterface) recordInvocation(key string, args []interface{}) { 100 | fake.invocationsMutex.Lock() 101 | defer fake.invocationsMutex.Unlock() 102 | if fake.invocations == nil { 103 | fake.invocations = map[string][][]interface{}{} 104 | } 105 | if fake.invocations[key] == nil { 106 | fake.invocations[key] = [][]interface{}{} 107 | } 108 | fake.invocations[key] = append(fake.invocations[key], args) 109 | } 110 | -------------------------------------------------------------------------------- /fixtures/genericinterface/genericinterface.go: -------------------------------------------------------------------------------- 1 | package genericinterface 2 | 3 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 4 | 5 | type CustomTypeT any 6 | type CustomTypeU any 7 | 8 | // incorrect setup. this would fail 9 | // //counterfeiter:generate . GenericInterfaceBad[T CustomType] 10 | // type GenericInterfaceBad[T CustomTypeT] interface { 11 | // ReturnT() T 12 | // TakeT(T) 13 | // TakeAndReturnT(T) T 14 | // DoSomething() 15 | // } 16 | 17 | //counterfeiter:generate . GenericInterface 18 | type GenericInterface[T CustomTypeT] interface { 19 | ReturnT() T 20 | TakeT(T) 21 | TakeAndReturnT(T) T 22 | DoSomething() 23 | } 24 | 25 | //counterfeiter:generate . GenericInterfaceAny 26 | type GenericInterfaceAny[T any] interface { 27 | ReturnT() T 28 | TakeT(T) 29 | TakeAndReturnT(T) T 30 | DoSomething() 31 | } 32 | 33 | //counterfeiter:generate . GenericInterfaceMultipleTypes 34 | type GenericInterfaceMultipleTypes[T CustomTypeT, U CustomTypeU] interface { 35 | ReturnT() T 36 | ReturnU() U 37 | ReturnTAndU() (T, U) 38 | TakeT(T) 39 | TakeU(U) 40 | TakeTAndU(T, U) 41 | TakeAndReturnT(T) T 42 | TakeAndReturnU(U) U 43 | TakeAndReturnTAndU(T, U) (T, U) 44 | TakeTAndReturnU(T) U 45 | DoSomething() 46 | } 47 | -------------------------------------------------------------------------------- /fixtures/genericparam/genericparam.go: -------------------------------------------------------------------------------- 1 | package genericparam 2 | 3 | import ( 4 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericparam/genericparamtype" 5 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericparam/genericreturntype" 6 | ) 7 | 8 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 9 | 10 | //counterfeiter:generate . GenericParamFunc 11 | type GenericParamFunc func(Generic[genericparamtype.T]) Generic[genericreturntype.R] 12 | 13 | //counterfeiter:generate . GenericParamInterface 14 | type GenericParamInterface interface { 15 | DoSomething(Generic[genericparamtype.T]) Generic[genericreturntype.R] 16 | } 17 | 18 | type Generic[T any] struct{ _ T } 19 | -------------------------------------------------------------------------------- /fixtures/genericparam/genericparamfakes/fake_generic_param_func.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package genericparamfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericparam" 8 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericparam/genericparamtype" 9 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericparam/genericreturntype" 10 | ) 11 | 12 | type FakeGenericParamFunc struct { 13 | Stub func(genericparam.Generic[genericparamtype.T]) genericparam.Generic[genericreturntype.R] 14 | mutex sync.RWMutex 15 | argsForCall []struct { 16 | arg1 genericparam.Generic[genericparamtype.T] 17 | } 18 | returns struct { 19 | result1 genericparam.Generic[genericreturntype.R] 20 | } 21 | returnsOnCall map[int]struct { 22 | result1 genericparam.Generic[genericreturntype.R] 23 | } 24 | invocations map[string][][]interface{} 25 | invocationsMutex sync.RWMutex 26 | } 27 | 28 | func (fake *FakeGenericParamFunc) Spy(arg1 genericparam.Generic[genericparamtype.T]) genericparam.Generic[genericreturntype.R] { 29 | fake.mutex.Lock() 30 | ret, specificReturn := fake.returnsOnCall[len(fake.argsForCall)] 31 | fake.argsForCall = append(fake.argsForCall, struct { 32 | arg1 genericparam.Generic[genericparamtype.T] 33 | }{arg1}) 34 | stub := fake.Stub 35 | returns := fake.returns 36 | fake.recordInvocation("GenericParamFunc", []interface{}{arg1}) 37 | fake.mutex.Unlock() 38 | if stub != nil { 39 | return stub(arg1) 40 | } 41 | if specificReturn { 42 | return ret.result1 43 | } 44 | return returns.result1 45 | } 46 | 47 | func (fake *FakeGenericParamFunc) CallCount() int { 48 | fake.mutex.RLock() 49 | defer fake.mutex.RUnlock() 50 | return len(fake.argsForCall) 51 | } 52 | 53 | func (fake *FakeGenericParamFunc) Calls(stub func(genericparam.Generic[genericparamtype.T]) genericparam.Generic[genericreturntype.R]) { 54 | fake.mutex.Lock() 55 | defer fake.mutex.Unlock() 56 | fake.Stub = stub 57 | } 58 | 59 | func (fake *FakeGenericParamFunc) ArgsForCall(i int) genericparam.Generic[genericparamtype.T] { 60 | fake.mutex.RLock() 61 | defer fake.mutex.RUnlock() 62 | return fake.argsForCall[i].arg1 63 | } 64 | 65 | func (fake *FakeGenericParamFunc) Returns(result1 genericparam.Generic[genericreturntype.R]) { 66 | fake.mutex.Lock() 67 | defer fake.mutex.Unlock() 68 | fake.Stub = nil 69 | fake.returns = struct { 70 | result1 genericparam.Generic[genericreturntype.R] 71 | }{result1} 72 | } 73 | 74 | func (fake *FakeGenericParamFunc) ReturnsOnCall(i int, result1 genericparam.Generic[genericreturntype.R]) { 75 | fake.mutex.Lock() 76 | defer fake.mutex.Unlock() 77 | fake.Stub = nil 78 | if fake.returnsOnCall == nil { 79 | fake.returnsOnCall = make(map[int]struct { 80 | result1 genericparam.Generic[genericreturntype.R] 81 | }) 82 | } 83 | fake.returnsOnCall[i] = struct { 84 | result1 genericparam.Generic[genericreturntype.R] 85 | }{result1} 86 | } 87 | 88 | func (fake *FakeGenericParamFunc) Invocations() map[string][][]interface{} { 89 | fake.invocationsMutex.RLock() 90 | defer fake.invocationsMutex.RUnlock() 91 | fake.mutex.RLock() 92 | defer fake.mutex.RUnlock() 93 | copiedInvocations := map[string][][]interface{}{} 94 | for key, value := range fake.invocations { 95 | copiedInvocations[key] = value 96 | } 97 | return copiedInvocations 98 | } 99 | 100 | func (fake *FakeGenericParamFunc) recordInvocation(key string, args []interface{}) { 101 | fake.invocationsMutex.Lock() 102 | defer fake.invocationsMutex.Unlock() 103 | if fake.invocations == nil { 104 | fake.invocations = map[string][][]interface{}{} 105 | } 106 | if fake.invocations[key] == nil { 107 | fake.invocations[key] = [][]interface{}{} 108 | } 109 | fake.invocations[key] = append(fake.invocations[key], args) 110 | } 111 | 112 | var _ genericparam.GenericParamFunc = new(FakeGenericParamFunc).Spy 113 | -------------------------------------------------------------------------------- /fixtures/genericparam/genericparamfakes/fake_generic_param_interface.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package genericparamfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericparam" 8 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericparam/genericparamtype" 9 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/genericparam/genericreturntype" 10 | ) 11 | 12 | type FakeGenericParamInterface struct { 13 | DoSomethingStub func(genericparam.Generic[genericparamtype.T]) genericparam.Generic[genericreturntype.R] 14 | doSomethingMutex sync.RWMutex 15 | doSomethingArgsForCall []struct { 16 | arg1 genericparam.Generic[genericparamtype.T] 17 | } 18 | doSomethingReturns struct { 19 | result1 genericparam.Generic[genericreturntype.R] 20 | } 21 | doSomethingReturnsOnCall map[int]struct { 22 | result1 genericparam.Generic[genericreturntype.R] 23 | } 24 | invocations map[string][][]interface{} 25 | invocationsMutex sync.RWMutex 26 | } 27 | 28 | func (fake *FakeGenericParamInterface) DoSomething(arg1 genericparam.Generic[genericparamtype.T]) genericparam.Generic[genericreturntype.R] { 29 | fake.doSomethingMutex.Lock() 30 | ret, specificReturn := fake.doSomethingReturnsOnCall[len(fake.doSomethingArgsForCall)] 31 | fake.doSomethingArgsForCall = append(fake.doSomethingArgsForCall, struct { 32 | arg1 genericparam.Generic[genericparamtype.T] 33 | }{arg1}) 34 | stub := fake.DoSomethingStub 35 | fakeReturns := fake.doSomethingReturns 36 | fake.recordInvocation("DoSomething", []interface{}{arg1}) 37 | fake.doSomethingMutex.Unlock() 38 | if stub != nil { 39 | return stub(arg1) 40 | } 41 | if specificReturn { 42 | return ret.result1 43 | } 44 | return fakeReturns.result1 45 | } 46 | 47 | func (fake *FakeGenericParamInterface) DoSomethingCallCount() int { 48 | fake.doSomethingMutex.RLock() 49 | defer fake.doSomethingMutex.RUnlock() 50 | return len(fake.doSomethingArgsForCall) 51 | } 52 | 53 | func (fake *FakeGenericParamInterface) DoSomethingCalls(stub func(genericparam.Generic[genericparamtype.T]) genericparam.Generic[genericreturntype.R]) { 54 | fake.doSomethingMutex.Lock() 55 | defer fake.doSomethingMutex.Unlock() 56 | fake.DoSomethingStub = stub 57 | } 58 | 59 | func (fake *FakeGenericParamInterface) DoSomethingArgsForCall(i int) genericparam.Generic[genericparamtype.T] { 60 | fake.doSomethingMutex.RLock() 61 | defer fake.doSomethingMutex.RUnlock() 62 | argsForCall := fake.doSomethingArgsForCall[i] 63 | return argsForCall.arg1 64 | } 65 | 66 | func (fake *FakeGenericParamInterface) DoSomethingReturns(result1 genericparam.Generic[genericreturntype.R]) { 67 | fake.doSomethingMutex.Lock() 68 | defer fake.doSomethingMutex.Unlock() 69 | fake.DoSomethingStub = nil 70 | fake.doSomethingReturns = struct { 71 | result1 genericparam.Generic[genericreturntype.R] 72 | }{result1} 73 | } 74 | 75 | func (fake *FakeGenericParamInterface) DoSomethingReturnsOnCall(i int, result1 genericparam.Generic[genericreturntype.R]) { 76 | fake.doSomethingMutex.Lock() 77 | defer fake.doSomethingMutex.Unlock() 78 | fake.DoSomethingStub = nil 79 | if fake.doSomethingReturnsOnCall == nil { 80 | fake.doSomethingReturnsOnCall = make(map[int]struct { 81 | result1 genericparam.Generic[genericreturntype.R] 82 | }) 83 | } 84 | fake.doSomethingReturnsOnCall[i] = struct { 85 | result1 genericparam.Generic[genericreturntype.R] 86 | }{result1} 87 | } 88 | 89 | func (fake *FakeGenericParamInterface) Invocations() map[string][][]interface{} { 90 | fake.invocationsMutex.RLock() 91 | defer fake.invocationsMutex.RUnlock() 92 | fake.doSomethingMutex.RLock() 93 | defer fake.doSomethingMutex.RUnlock() 94 | copiedInvocations := map[string][][]interface{}{} 95 | for key, value := range fake.invocations { 96 | copiedInvocations[key] = value 97 | } 98 | return copiedInvocations 99 | } 100 | 101 | func (fake *FakeGenericParamInterface) recordInvocation(key string, args []interface{}) { 102 | fake.invocationsMutex.Lock() 103 | defer fake.invocationsMutex.Unlock() 104 | if fake.invocations == nil { 105 | fake.invocations = map[string][][]interface{}{} 106 | } 107 | if fake.invocations[key] == nil { 108 | fake.invocations[key] = [][]interface{}{} 109 | } 110 | fake.invocations[key] = append(fake.invocations[key], args) 111 | } 112 | 113 | var _ genericparam.GenericParamInterface = new(FakeGenericParamInterface) 114 | -------------------------------------------------------------------------------- /fixtures/genericparam/genericparamtype/genericparamtype.go: -------------------------------------------------------------------------------- 1 | package genericparamtype 2 | 3 | type T string 4 | -------------------------------------------------------------------------------- /fixtures/genericparam/genericreturntype/genericreturntype.go: -------------------------------------------------------------------------------- 1 | package genericreturntype 2 | 3 | type R struct{} 4 | -------------------------------------------------------------------------------- /fixtures/go-hyphenpackage/fixture.go: -------------------------------------------------------------------------------- 1 | package hyphenpackage // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/go-hyphenpackage" 2 | 3 | type HyphenType struct{} 4 | -------------------------------------------------------------------------------- /fixtures/has_imports.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | import ( 4 | "io" 5 | "net/http" 6 | some_alias "os" 7 | ) 8 | 9 | //counterfeiter:generate . HasImports 10 | type HasImports interface { 11 | DoThings(io.Writer, *some_alias.File) *http.Client 12 | } 13 | -------------------------------------------------------------------------------- /fixtures/has_other_types.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | //counterfeiter:generate . HasOtherTypes 4 | type HasOtherTypes interface { 5 | GetThing(SomeString) SomeFunc 6 | } 7 | -------------------------------------------------------------------------------- /fixtures/has_var_args.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | //counterfeiter:generate . HasVarArgs 4 | type HasVarArgs interface { 5 | DoThings(int, ...string) int 6 | DoMoreThings(int, int, ...string) int 7 | } 8 | 9 | //counterfeiter:generate . HasVarArgsWithLocalTypes 10 | type HasVarArgsWithLocalTypes interface { 11 | DoThings(...LocalType) 12 | } 13 | 14 | type LocalType struct{} 15 | -------------------------------------------------------------------------------- /fixtures/headers/default.header.go.txt: -------------------------------------------------------------------------------- 1 | // This is a default header for all the fakes in this package 2 | // 3 | 4 | -------------------------------------------------------------------------------- /fixtures/headers/defaultheader/defaultheaderfakes/fake_header_default.go: -------------------------------------------------------------------------------- 1 | // This is a default header for all the fakes in this package 2 | // 3 | 4 | // Code generated by counterfeiter. DO NOT EDIT. 5 | package defaultheaderfakes 6 | 7 | import ( 8 | "sync" 9 | 10 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/headers/defaultheader" 11 | ) 12 | 13 | type FakeHeaderDefault struct { 14 | invocations map[string][][]interface{} 15 | invocationsMutex sync.RWMutex 16 | } 17 | 18 | func (fake *FakeHeaderDefault) Invocations() map[string][][]interface{} { 19 | fake.invocationsMutex.RLock() 20 | defer fake.invocationsMutex.RUnlock() 21 | copiedInvocations := map[string][][]interface{}{} 22 | for key, value := range fake.invocations { 23 | copiedInvocations[key] = value 24 | } 25 | return copiedInvocations 26 | } 27 | 28 | func (fake *FakeHeaderDefault) recordInvocation(key string, args []interface{}) { 29 | fake.invocationsMutex.Lock() 30 | defer fake.invocationsMutex.Unlock() 31 | if fake.invocations == nil { 32 | fake.invocations = map[string][][]interface{}{} 33 | } 34 | if fake.invocations[key] == nil { 35 | fake.invocations[key] = [][]interface{}{} 36 | } 37 | fake.invocations[key] = append(fake.invocations[key], args) 38 | } 39 | 40 | var _ defaultheader.HeaderDefault = new(FakeHeaderDefault) 41 | -------------------------------------------------------------------------------- /fixtures/headers/defaultheader/defaultheaderfakes/fake_header_specific.go: -------------------------------------------------------------------------------- 1 | // This is a specific header for only some of the fakes in this package 2 | // 3 | 4 | // Code generated by counterfeiter. DO NOT EDIT. 5 | package defaultheaderfakes 6 | 7 | import ( 8 | "sync" 9 | 10 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/headers/defaultheader" 11 | ) 12 | 13 | type FakeHeaderSpecific struct { 14 | invocations map[string][][]interface{} 15 | invocationsMutex sync.RWMutex 16 | } 17 | 18 | func (fake *FakeHeaderSpecific) Invocations() map[string][][]interface{} { 19 | fake.invocationsMutex.RLock() 20 | defer fake.invocationsMutex.RUnlock() 21 | copiedInvocations := map[string][][]interface{}{} 22 | for key, value := range fake.invocations { 23 | copiedInvocations[key] = value 24 | } 25 | return copiedInvocations 26 | } 27 | 28 | func (fake *FakeHeaderSpecific) recordInvocation(key string, args []interface{}) { 29 | fake.invocationsMutex.Lock() 30 | defer fake.invocationsMutex.Unlock() 31 | if fake.invocations == nil { 32 | fake.invocations = map[string][][]interface{}{} 33 | } 34 | if fake.invocations[key] == nil { 35 | fake.invocations[key] = [][]interface{}{} 36 | } 37 | fake.invocations[key] = append(fake.invocations[key], args) 38 | } 39 | 40 | var _ defaultheader.HeaderSpecific = new(FakeHeaderSpecific) 41 | -------------------------------------------------------------------------------- /fixtures/headers/defaultheader/header.go: -------------------------------------------------------------------------------- 1 | package defaultheader // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/headers/defaultheader" 2 | 3 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -header ../default.header.go.txt -generate 4 | 5 | //counterfeiter:generate . HeaderDefault 6 | type HeaderDefault interface{} 7 | 8 | //counterfeiter:generate -header ../specific.header.go.txt . HeaderSpecific 9 | type HeaderSpecific interface{} 10 | -------------------------------------------------------------------------------- /fixtures/headers/nodefaultheader/headers.go: -------------------------------------------------------------------------------- 1 | package nodefaultheader // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/headers/nodefaultheader" 2 | 3 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 4 | 5 | //counterfeiter:generate . HeaderDefault 6 | type HeaderDefault interface{} 7 | 8 | //counterfeiter:generate -header ../specific.header.go.txt . HeaderSpecific 9 | type HeaderSpecific interface{} 10 | -------------------------------------------------------------------------------- /fixtures/headers/nodefaultheader/nodefaultheaderfakes/fake_header_default.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package nodefaultheaderfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/headers/nodefaultheader" 8 | ) 9 | 10 | type FakeHeaderDefault struct { 11 | invocations map[string][][]interface{} 12 | invocationsMutex sync.RWMutex 13 | } 14 | 15 | func (fake *FakeHeaderDefault) Invocations() map[string][][]interface{} { 16 | fake.invocationsMutex.RLock() 17 | defer fake.invocationsMutex.RUnlock() 18 | copiedInvocations := map[string][][]interface{}{} 19 | for key, value := range fake.invocations { 20 | copiedInvocations[key] = value 21 | } 22 | return copiedInvocations 23 | } 24 | 25 | func (fake *FakeHeaderDefault) recordInvocation(key string, args []interface{}) { 26 | fake.invocationsMutex.Lock() 27 | defer fake.invocationsMutex.Unlock() 28 | if fake.invocations == nil { 29 | fake.invocations = map[string][][]interface{}{} 30 | } 31 | if fake.invocations[key] == nil { 32 | fake.invocations[key] = [][]interface{}{} 33 | } 34 | fake.invocations[key] = append(fake.invocations[key], args) 35 | } 36 | 37 | var _ nodefaultheader.HeaderDefault = new(FakeHeaderDefault) 38 | -------------------------------------------------------------------------------- /fixtures/headers/nodefaultheader/nodefaultheaderfakes/fake_header_specific.go: -------------------------------------------------------------------------------- 1 | // This is a specific header for only some of the fakes in this package 2 | // 3 | 4 | // Code generated by counterfeiter. DO NOT EDIT. 5 | package nodefaultheaderfakes 6 | 7 | import ( 8 | "sync" 9 | 10 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/headers/nodefaultheader" 11 | ) 12 | 13 | type FakeHeaderSpecific struct { 14 | invocations map[string][][]interface{} 15 | invocationsMutex sync.RWMutex 16 | } 17 | 18 | func (fake *FakeHeaderSpecific) Invocations() map[string][][]interface{} { 19 | fake.invocationsMutex.RLock() 20 | defer fake.invocationsMutex.RUnlock() 21 | copiedInvocations := map[string][][]interface{}{} 22 | for key, value := range fake.invocations { 23 | copiedInvocations[key] = value 24 | } 25 | return copiedInvocations 26 | } 27 | 28 | func (fake *FakeHeaderSpecific) recordInvocation(key string, args []interface{}) { 29 | fake.invocationsMutex.Lock() 30 | defer fake.invocationsMutex.Unlock() 31 | if fake.invocations == nil { 32 | fake.invocations = map[string][][]interface{}{} 33 | } 34 | if fake.invocations[key] == nil { 35 | fake.invocations[key] = [][]interface{}{} 36 | } 37 | fake.invocations[key] = append(fake.invocations[key], args) 38 | } 39 | 40 | var _ nodefaultheader.HeaderSpecific = new(FakeHeaderSpecific) 41 | -------------------------------------------------------------------------------- /fixtures/headers/specific.header.go.txt: -------------------------------------------------------------------------------- 1 | // This is a specific header for only some of the fakes in this package 2 | // 3 | 4 | -------------------------------------------------------------------------------- /fixtures/hyphenated_package_same_name/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/maxbrunsfeld/counterfeiter/v6/fixtures/hyphenated_package_same_name 2 | -------------------------------------------------------------------------------- /fixtures/hyphenated_package_same_name/hyphen-ated/some_package/types.go: -------------------------------------------------------------------------------- 1 | package some_package // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/hyphenated_package_same_name/hyphen-ated/some_package" 2 | 3 | type Thing int 4 | -------------------------------------------------------------------------------- /fixtures/hyphenated_package_same_name/some_package/interface.go: -------------------------------------------------------------------------------- 1 | package some_package // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/hyphenated_package_same_name/some_package" 2 | 3 | import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/hyphenated_package_same_name/hyphen-ated/some_package" 4 | 5 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . SomeInterface 6 | type SomeInterface interface { 7 | CreateThing() some_package.Thing 8 | } 9 | -------------------------------------------------------------------------------- /fixtures/imports_go_hyphen_package.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | import ( 4 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/go-hyphenpackage" 5 | ) 6 | 7 | //counterfeiter:generate . ImportsGoHyphenPackage 8 | type ImportsGoHyphenPackage interface { 9 | UseHyphenType(hyphenpackage.HyphenType) 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/inline_struct_params.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | //counterfeiter:generate . InlineStructParams 10 | type InlineStructParams interface { 11 | DoSomething(ctx context.Context, body struct { 12 | SomeString string 13 | SomeStringPointer *string 14 | SomeTime time.Time 15 | SomeTimePointer *time.Time 16 | HTTPRequest http.Request 17 | }) error 18 | } 19 | -------------------------------------------------------------------------------- /fixtures/internalpkg/aliased_interface.go: -------------------------------------------------------------------------------- 1 | package internalpkg 2 | 3 | import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/internalpkg/internal" 4 | 5 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 6 | //counterfeiter:generate . Context 7 | 8 | type Context = internal.Context 9 | -------------------------------------------------------------------------------- /fixtures/internalpkg/internal/internal_interface.go: -------------------------------------------------------------------------------- 1 | package internal 2 | 3 | type Context interface { 4 | DoSomething() 5 | } 6 | -------------------------------------------------------------------------------- /fixtures/internalpkg/internalpkgfakes/fake_context.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package internalpkgfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/internalpkg" 8 | ) 9 | 10 | type FakeContext struct { 11 | DoSomethingStub func() 12 | doSomethingMutex sync.RWMutex 13 | doSomethingArgsForCall []struct { 14 | } 15 | invocations map[string][][]interface{} 16 | invocationsMutex sync.RWMutex 17 | } 18 | 19 | func (fake *FakeContext) DoSomething() { 20 | fake.doSomethingMutex.Lock() 21 | fake.doSomethingArgsForCall = append(fake.doSomethingArgsForCall, struct { 22 | }{}) 23 | stub := fake.DoSomethingStub 24 | fake.recordInvocation("DoSomething", []interface{}{}) 25 | fake.doSomethingMutex.Unlock() 26 | if stub != nil { 27 | fake.DoSomethingStub() 28 | } 29 | } 30 | 31 | func (fake *FakeContext) DoSomethingCallCount() int { 32 | fake.doSomethingMutex.RLock() 33 | defer fake.doSomethingMutex.RUnlock() 34 | return len(fake.doSomethingArgsForCall) 35 | } 36 | 37 | func (fake *FakeContext) DoSomethingCalls(stub func()) { 38 | fake.doSomethingMutex.Lock() 39 | defer fake.doSomethingMutex.Unlock() 40 | fake.DoSomethingStub = stub 41 | } 42 | 43 | func (fake *FakeContext) Invocations() map[string][][]interface{} { 44 | fake.invocationsMutex.RLock() 45 | defer fake.invocationsMutex.RUnlock() 46 | fake.doSomethingMutex.RLock() 47 | defer fake.doSomethingMutex.RUnlock() 48 | copiedInvocations := map[string][][]interface{}{} 49 | for key, value := range fake.invocations { 50 | copiedInvocations[key] = value 51 | } 52 | return copiedInvocations 53 | } 54 | 55 | func (fake *FakeContext) recordInvocation(key string, args []interface{}) { 56 | fake.invocationsMutex.Lock() 57 | defer fake.invocationsMutex.Unlock() 58 | if fake.invocations == nil { 59 | fake.invocations = map[string][][]interface{}{} 60 | } 61 | if fake.invocations[key] == nil { 62 | fake.invocations[key] = [][]interface{}{} 63 | } 64 | fake.invocations[key] = append(fake.invocations[key], args) 65 | } 66 | 67 | var _ internalpkg.Context = new(FakeContext) 68 | -------------------------------------------------------------------------------- /fixtures/multiple_interfaces.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | //counterfeiter:generate . FirstInterface 4 | type FirstInterface interface { 5 | DoThings() 6 | } 7 | 8 | //counterfeiter:generate . SecondInterface 9 | type SecondInterface interface { 10 | EmbeddedMethod() string 11 | } 12 | -------------------------------------------------------------------------------- /fixtures/other_types.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | type SomeNum uint64 4 | type SomeString string 5 | type SomeFunc func(SomeNum) bool 6 | -------------------------------------------------------------------------------- /fixtures/packagegen/apackage/apackage.go: -------------------------------------------------------------------------------- 1 | package ostest 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "time" 7 | ) 8 | 9 | func FindProcess(pid int) (*os.Process, error) { 10 | return os.FindProcess(pid) 11 | } 12 | 13 | func Hostname() (name string, err error) { 14 | return os.Hostname() 15 | } 16 | 17 | func Expand(s string, mapping func(string) string) string { 18 | return os.Expand(s, mapping) 19 | } 20 | 21 | func Clearenv() { 22 | os.Clearenv() 23 | } 24 | 25 | func Environ() []string { 26 | return os.Environ() 27 | } 28 | 29 | func Chtimes(name string, atime time.Time, mtime time.Time) error { 30 | return os.Chtimes(name, atime, mtime) 31 | } 32 | 33 | func MkdirAll(path string, perm os.FileMode) error { 34 | return os.MkdirAll(path, perm) 35 | } 36 | 37 | func Exit(code int) { 38 | os.Exit(code) 39 | } 40 | 41 | func Fictional(lol ...string) { 42 | fmt.Printf("%#v", lol) 43 | } 44 | -------------------------------------------------------------------------------- /fixtures/packagegen/package_gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package osshim 3 | 4 | import ( 5 | "os" 6 | "time" 7 | ) 8 | 9 | type Os interface { 10 | FindProcess(pid int) (*os.Process, error) 11 | Hostname() (name string, err error) 12 | Expand(s string, mapping func(string) string) string 13 | Clearenv() 14 | Environ() []string 15 | Chtimes(name string, atime time.Time, mtime time.Time) error 16 | MkdirAll(path string, perm os.FileMode) error 17 | Exit(code int) 18 | Fictional(lol ...string) 19 | } 20 | -------------------------------------------------------------------------------- /fixtures/packagemode/flag.go: -------------------------------------------------------------------------------- 1 | package packagemode 2 | 3 | import "flag" 4 | 5 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 6 | //counterfeiter:generate -p github.com/maxbrunsfeld/counterfeiter/v6/fixtures/packagemode 7 | //counterfeiter:generate -o flagcustomfakesdir -p github.com/maxbrunsfeld/counterfeiter/v6/fixtures/packagemode 8 | 9 | func Arg(arg1 int) string { 10 | return flag.Arg(arg1) 11 | } 12 | 13 | func Args() []string { 14 | return flag.Args() 15 | } 16 | 17 | func Bool(arg1 string, arg2 bool, arg3 string) *bool { 18 | return flag.Bool(arg1, arg2, arg3) 19 | } 20 | 21 | func BoolVar(arg1 *bool, arg2 string, arg3 bool, arg4 string) { 22 | flag.BoolVar(arg1, arg2, arg3, arg4) 23 | } 24 | -------------------------------------------------------------------------------- /fixtures/packagemode/flagcustomfakesdir/packagemode.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package packagemodeshim 3 | 4 | import ( 5 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/packagemode" 6 | ) 7 | 8 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 9 | //counterfeiter:generate . Packagemode 10 | 11 | // Packagemode is a generated interface representing the exported functions 12 | // in the github.com/maxbrunsfeld/counterfeiter/v6/fixtures/packagemode package. 13 | type Packagemode interface { 14 | Arg(arg1 int) string 15 | Args() []string 16 | Bool(arg1 string, arg2 bool, arg3 string) *bool 17 | BoolVar(arg1 *bool, arg2 string, arg3 bool, arg4 string) 18 | } 19 | 20 | type PackagemodeShim struct{} 21 | 22 | func (p *PackagemodeShim) Arg(arg1 int) string { 23 | return packagemode.Arg(arg1) 24 | } 25 | 26 | func (p *PackagemodeShim) Args() []string { 27 | return packagemode.Args() 28 | } 29 | 30 | func (p *PackagemodeShim) Bool(arg1 string, arg2 bool, arg3 string) *bool { 31 | return packagemode.Bool(arg1, arg2, arg3) 32 | } 33 | 34 | func (p *PackagemodeShim) BoolVar(arg1 *bool, arg2 string, arg3 bool, arg4 string) { 35 | packagemode.BoolVar(arg1, arg2, arg3, arg4) 36 | } 37 | 38 | var _ Packagemode = new(PackagemodeShim) 39 | -------------------------------------------------------------------------------- /fixtures/packagemode/packagemodeshim/packagemode.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package packagemodeshim 3 | 4 | import ( 5 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/packagemode" 6 | ) 7 | 8 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 9 | //counterfeiter:generate . Packagemode 10 | 11 | // Packagemode is a generated interface representing the exported functions 12 | // in the github.com/maxbrunsfeld/counterfeiter/v6/fixtures/packagemode package. 13 | type Packagemode interface { 14 | Arg(arg1 int) string 15 | Args() []string 16 | Bool(arg1 string, arg2 bool, arg3 string) *bool 17 | BoolVar(arg1 *bool, arg2 string, arg3 bool, arg4 string) 18 | } 19 | 20 | type PackagemodeShim struct{} 21 | 22 | func (p *PackagemodeShim) Arg(arg1 int) string { 23 | return packagemode.Arg(arg1) 24 | } 25 | 26 | func (p *PackagemodeShim) Args() []string { 27 | return packagemode.Args() 28 | } 29 | 30 | func (p *PackagemodeShim) Bool(arg1 string, arg2 bool, arg3 string) *bool { 31 | return packagemode.Bool(arg1, arg2, arg3) 32 | } 33 | 34 | func (p *PackagemodeShim) BoolVar(arg1 *bool, arg2 string, arg3 bool, arg4 string) { 35 | packagemode.BoolVar(arg1, arg2, arg3, arg4) 36 | } 37 | 38 | var _ Packagemode = new(PackagemodeShim) 39 | -------------------------------------------------------------------------------- /fixtures/request_factory.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | type Params struct{} 4 | type Request struct{} 5 | type RequestFactory func(Params, map[string]interface{}) (Request, error) 6 | -------------------------------------------------------------------------------- /fixtures/reuses_arg_types.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | //counterfeiter:generate . ReusesArgTypes 4 | type ReusesArgTypes interface { 5 | DoThings(x, y string) 6 | } 7 | -------------------------------------------------------------------------------- /fixtures/something.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | //counterfeiter:generate . Something 4 | type Something interface { 5 | DoThings(string, uint64) (int, error) 6 | DoNothing() 7 | DoASlice([]byte) 8 | DoAnArray([4]byte) 9 | } 10 | -------------------------------------------------------------------------------- /fixtures/something_remote.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | import the_aliased_package "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/aliased_package" 4 | 5 | //counterfeiter:generate . SomethingWithForeignInterface 6 | 7 | // SomethingWithForeignInterface is an interface that embeds a foreign interface. 8 | type SomethingWithForeignInterface interface { 9 | the_aliased_package.InAliasedPackage 10 | } 11 | -------------------------------------------------------------------------------- /fixtures/sql/db.go: -------------------------------------------------------------------------------- 1 | package sql 2 | 3 | import ( 4 | "database/sql" 5 | ) 6 | 7 | //go:generate counterfeiter . DB 8 | 9 | type DB interface { 10 | Exec(query string, args ...interface{}) (sql.Result, error) 11 | } 12 | -------------------------------------------------------------------------------- /fixtures/sql/sqlfakes/fake_db.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package sqlfakes 3 | 4 | import ( 5 | sqla "database/sql" 6 | "sync" 7 | 8 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/sql" 9 | ) 10 | 11 | type FakeDB struct { 12 | ExecStub func(string, ...interface{}) (sqla.Result, error) 13 | execMutex sync.RWMutex 14 | execArgsForCall []struct { 15 | arg1 string 16 | arg2 []interface{} 17 | } 18 | execReturns struct { 19 | result1 sqla.Result 20 | result2 error 21 | } 22 | execReturnsOnCall map[int]struct { 23 | result1 sqla.Result 24 | result2 error 25 | } 26 | invocations map[string][][]interface{} 27 | invocationsMutex sync.RWMutex 28 | } 29 | 30 | func (fake *FakeDB) Exec(arg1 string, arg2 ...interface{}) (sqla.Result, error) { 31 | fake.execMutex.Lock() 32 | ret, specificReturn := fake.execReturnsOnCall[len(fake.execArgsForCall)] 33 | fake.execArgsForCall = append(fake.execArgsForCall, struct { 34 | arg1 string 35 | arg2 []interface{} 36 | }{arg1, arg2}) 37 | stub := fake.ExecStub 38 | fakeReturns := fake.execReturns 39 | fake.recordInvocation("Exec", []interface{}{arg1, arg2}) 40 | fake.execMutex.Unlock() 41 | if stub != nil { 42 | return stub(arg1, arg2...) 43 | } 44 | if specificReturn { 45 | return ret.result1, ret.result2 46 | } 47 | return fakeReturns.result1, fakeReturns.result2 48 | } 49 | 50 | func (fake *FakeDB) ExecCallCount() int { 51 | fake.execMutex.RLock() 52 | defer fake.execMutex.RUnlock() 53 | return len(fake.execArgsForCall) 54 | } 55 | 56 | func (fake *FakeDB) ExecCalls(stub func(string, ...interface{}) (sqla.Result, error)) { 57 | fake.execMutex.Lock() 58 | defer fake.execMutex.Unlock() 59 | fake.ExecStub = stub 60 | } 61 | 62 | func (fake *FakeDB) ExecArgsForCall(i int) (string, []interface{}) { 63 | fake.execMutex.RLock() 64 | defer fake.execMutex.RUnlock() 65 | argsForCall := fake.execArgsForCall[i] 66 | return argsForCall.arg1, argsForCall.arg2 67 | } 68 | 69 | func (fake *FakeDB) ExecReturns(result1 sqla.Result, result2 error) { 70 | fake.execMutex.Lock() 71 | defer fake.execMutex.Unlock() 72 | fake.ExecStub = nil 73 | fake.execReturns = struct { 74 | result1 sqla.Result 75 | result2 error 76 | }{result1, result2} 77 | } 78 | 79 | func (fake *FakeDB) ExecReturnsOnCall(i int, result1 sqla.Result, result2 error) { 80 | fake.execMutex.Lock() 81 | defer fake.execMutex.Unlock() 82 | fake.ExecStub = nil 83 | if fake.execReturnsOnCall == nil { 84 | fake.execReturnsOnCall = make(map[int]struct { 85 | result1 sqla.Result 86 | result2 error 87 | }) 88 | } 89 | fake.execReturnsOnCall[i] = struct { 90 | result1 sqla.Result 91 | result2 error 92 | }{result1, result2} 93 | } 94 | 95 | func (fake *FakeDB) Invocations() map[string][][]interface{} { 96 | fake.invocationsMutex.RLock() 97 | defer fake.invocationsMutex.RUnlock() 98 | fake.execMutex.RLock() 99 | defer fake.execMutex.RUnlock() 100 | copiedInvocations := map[string][][]interface{}{} 101 | for key, value := range fake.invocations { 102 | copiedInvocations[key] = value 103 | } 104 | return copiedInvocations 105 | } 106 | 107 | func (fake *FakeDB) recordInvocation(key string, args []interface{}) { 108 | fake.invocationsMutex.Lock() 109 | defer fake.invocationsMutex.Unlock() 110 | if fake.invocations == nil { 111 | fake.invocations = map[string][][]interface{}{} 112 | } 113 | if fake.invocations[key] == nil { 114 | fake.invocations[key] = [][]interface{}{} 115 | } 116 | fake.invocations[key] = append(fake.invocations[key], args) 117 | } 118 | 119 | var _ sql.DB = new(FakeDB) 120 | -------------------------------------------------------------------------------- /fixtures/sync/interface.go: -------------------------------------------------------------------------------- 1 | package sync // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/sync" 2 | 3 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . SyncSomething 4 | type SyncSomething interface { 5 | DoThings(string, uint64) (int, error) 6 | DoNothing() 7 | DoASlice([]byte) 8 | DoAnArray([4]byte) 9 | } 10 | -------------------------------------------------------------------------------- /fixtures/type_aliases/extra/m.go: -------------------------------------------------------------------------------- 1 | package extra // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/type_aliases/extra" 2 | 3 | import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/type_aliases/extra/primitive" 4 | 5 | type M = primitive.M 6 | -------------------------------------------------------------------------------- /fixtures/type_aliases/extra/primitive/m.go: -------------------------------------------------------------------------------- 1 | package primitive // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/type_aliases/primitive" 2 | 3 | type M map[string]interface{} 4 | -------------------------------------------------------------------------------- /fixtures/type_aliases/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/maxbrunsfeld/counterfeiter/v6/fixtures/type_aliases 2 | 3 | go 1.22 4 | -------------------------------------------------------------------------------- /fixtures/type_aliases/interface.go: -------------------------------------------------------------------------------- 1 | package type_aliases // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/type_aliases" 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/type_aliases/extra" 7 | ) 8 | 9 | //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 10 | 11 | //counterfeiter:generate . WithAliasedType 12 | type WithAliasedType interface { 13 | FindExample(ctx context.Context, filter extra.M) ([]string, error) 14 | } 15 | -------------------------------------------------------------------------------- /fixtures/typed_function.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | //counterfeiter:generate . SomethingFactory 4 | type SomethingFactory func(string, map[string]interface{}) string 5 | -------------------------------------------------------------------------------- /fixtures/unexported.go: -------------------------------------------------------------------------------- 1 | package fixtures 2 | 3 | //counterfeiter:generate . unexportedFunc 4 | type unexportedFunc func(string, map[string]interface{}) string 5 | 6 | //counterfeiter:generate . unexportedInterface 7 | type unexportedInterface interface { 8 | Method(string, map[string]interface{}) string 9 | } 10 | -------------------------------------------------------------------------------- /generator/cache.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import "golang.org/x/tools/go/packages" 4 | 5 | type Cache struct { 6 | packageMap map[string]interface{} 7 | } 8 | 9 | type FakeCache struct{} 10 | 11 | func (c *FakeCache) Load(packagePath string) ([]*packages.Package, bool) { return nil, false } 12 | func (c *FakeCache) Store(packagePath string, packages []*packages.Package) {} 13 | 14 | type Cacher interface { 15 | Load(packagePath string) ([]*packages.Package, bool) 16 | Store(packagePath string, packages []*packages.Package) 17 | } 18 | 19 | func (c *Cache) Load(packagePath string) ([]*packages.Package, bool) { 20 | p, ok := c.packageMap[packagePath] 21 | if !ok { 22 | return nil, false 23 | } 24 | packages, ok := p.([]*packages.Package) 25 | return packages, ok 26 | } 27 | 28 | func (c *Cache) Store(packagePath string, packages []*packages.Package) { 29 | if c.packageMap == nil { 30 | c.packageMap = map[string]interface{}{} 31 | } 32 | c.packageMap[packagePath] = packages 33 | } 34 | -------------------------------------------------------------------------------- /generator/ctx.go: -------------------------------------------------------------------------------- 1 | //go:build go1.14 2 | 3 | package generator 4 | 5 | import "go/build" 6 | 7 | func getBuildContext(workingDir string) build.Context { 8 | ctx := build.Default 9 | ctx.Dir = workingDir 10 | return ctx 11 | } 12 | -------------------------------------------------------------------------------- /generator/ctx_old.go: -------------------------------------------------------------------------------- 1 | //go:build !go1.14 2 | 3 | package generator 4 | 5 | import "go/build" 6 | 7 | func getBuildContext(workingDir string) build.Context { 8 | ctx := build.Default 9 | return ctx 10 | } 11 | -------------------------------------------------------------------------------- /generator/fake.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "go/types" 7 | "log" 8 | "strings" 9 | "text/template" 10 | "unicode" 11 | "unicode/utf8" 12 | 13 | "golang.org/x/tools/go/packages" 14 | "golang.org/x/tools/imports" 15 | ) 16 | 17 | // FakeMode indicates the type of Fake to generate. 18 | type FakeMode int 19 | 20 | // FakeMode can be Interface, Function, or Package. 21 | const ( 22 | InterfaceOrFunction FakeMode = iota 23 | Package 24 | ) 25 | 26 | // Fake is used to generate a Fake implementation of an interface. 27 | type Fake struct { 28 | Packages []*packages.Package 29 | Package *packages.Package 30 | Target *types.TypeName 31 | Mode FakeMode 32 | DestinationPackage string 33 | Name string 34 | GenericTypeParametersAndConstraints string 35 | GenericTypeParameters string 36 | GenericTypeConstraints string 37 | TargetAlias string 38 | TargetName string 39 | TargetPackage string 40 | Imports Imports 41 | Methods []Method 42 | Function Method 43 | Header string 44 | } 45 | 46 | // Method is a method of the interface. 47 | type Method struct { 48 | Name string 49 | Params Params 50 | Returns Returns 51 | } 52 | 53 | // NewFake returns a Fake that loads the package and finds the interface or the 54 | // function. 55 | func NewFake(fakeMode FakeMode, targetName string, packagePath string, fakeName string, destinationPackage string, headerContent string, workingDir string, cache Cacher) (*Fake, error) { 56 | f := &Fake{ 57 | TargetName: targetName, 58 | TargetPackage: packagePath, 59 | Name: fakeName, 60 | Mode: fakeMode, 61 | DestinationPackage: destinationPackage, 62 | Imports: newImports(), 63 | Header: headerContent, 64 | } 65 | 66 | f.Imports.Add("sync", "sync") 67 | err := f.loadPackages(cache, workingDir) 68 | if err != nil { 69 | return nil, err 70 | } 71 | 72 | // TODO: Package mode here 73 | err = f.findPackage() 74 | if err != nil { 75 | return nil, err 76 | } 77 | 78 | if f.IsInterface() || f.Mode == Package { 79 | f.loadMethods() 80 | } 81 | if f.IsFunction() { 82 | err = f.loadMethodForFunction() 83 | if err != nil { 84 | return nil, err 85 | } 86 | } 87 | return f, nil 88 | } 89 | 90 | // IsInterface indicates whether the fake is for an interface. 91 | func (f *Fake) IsInterface() bool { 92 | if f.Target == nil || f.Target.Type() == nil { 93 | return false 94 | } 95 | return types.IsInterface(f.Target.Type()) 96 | } 97 | 98 | // IsFunction indicates whether the fake is for a function.. 99 | func (f *Fake) IsFunction() bool { 100 | if f.Target == nil || f.Target.Type() == nil || f.Target.Type().Underlying() == nil { 101 | return false 102 | } 103 | _, ok := f.Target.Type().Underlying().(*types.Signature) 104 | return ok 105 | } 106 | 107 | func unexport(s string) string { 108 | s = strings.TrimSpace(s) 109 | if s == "" { 110 | return "" 111 | } 112 | r, n := utf8.DecodeRuneInString(s) 113 | return string(unicode.ToLower(r)) + s[n:] 114 | } 115 | 116 | func isExported(s string) bool { 117 | r, _ := utf8.DecodeRuneInString(s) 118 | return unicode.IsUpper(r) 119 | } 120 | 121 | // Generate uses the Fake to generate an implementation, optionally running 122 | // goimports on the output. 123 | func (f *Fake) Generate(runImports bool) ([]byte, error) { 124 | var tmpl *template.Template 125 | if f.IsInterface() { 126 | log.Printf("Writing fake %s for interface %s to package %s\n", f.Name, f.TargetName, f.DestinationPackage) 127 | tmpl = template.Must(template.New("fake").Funcs(interfaceFuncs).Parse(interfaceTemplate)) 128 | } 129 | if f.IsFunction() { 130 | log.Printf("Writing fake %s for function %s to package %s\n", f.Name, f.TargetName, f.DestinationPackage) 131 | tmpl = template.Must(template.New("fake").Funcs(functionFuncs).Parse(functionTemplate)) 132 | } 133 | if f.Mode == Package { 134 | log.Printf("Writing fake %s for package %s to package %s\n", f.Name, f.TargetPackage, f.DestinationPackage) 135 | tmpl = template.Must(template.New("fake").Funcs(packageFuncs).Parse(packageTemplate)) 136 | } 137 | if tmpl == nil { 138 | return nil, errors.New("counterfeiter can only generate fakes for interfaces or specific functions") 139 | } 140 | 141 | b := &bytes.Buffer{} 142 | err := tmpl.Execute(b, f) 143 | if err != nil { 144 | return nil, err 145 | } 146 | if runImports { 147 | return imports.Process("counterfeiter_temp_process_file", b.Bytes(), nil) 148 | } 149 | return b.Bytes(), nil 150 | } 151 | -------------------------------------------------------------------------------- /generator/file_reader.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "io" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | type FileReader interface { 10 | Get(cwd, path string) (content string, err error) 11 | } 12 | 13 | type Opener func(string) (io.ReadCloser, error) 14 | 15 | var ( 16 | defaultOpen Opener = func(p string) (io.ReadCloser, error) { return os.Open(p) } 17 | ) 18 | 19 | func (open Opener) readString(path string) (string, error) { 20 | if open == nil { 21 | open = defaultOpen 22 | } 23 | 24 | f, err := open(path) 25 | if err != nil { 26 | return "", err 27 | } 28 | defer f.Close() 29 | 30 | b, err := io.ReadAll(f) 31 | if err != nil { 32 | return "", err 33 | } 34 | 35 | return string(b), nil 36 | } 37 | 38 | type SimpleFileReader struct { 39 | Open Opener 40 | } 41 | 42 | var _ FileReader = &SimpleFileReader{} 43 | 44 | func (r *SimpleFileReader) Get(cwd, path string) (string, error) { 45 | if path == "" { 46 | return "", nil 47 | } 48 | 49 | p := normalisePath(cwd, path) 50 | return r.Open.readString(p) 51 | } 52 | 53 | type CachedFileReader struct { 54 | Open Opener 55 | cache map[string]string 56 | } 57 | 58 | var _ FileReader = &CachedFileReader{} 59 | 60 | func (r *CachedFileReader) Get(cwd, path string) (string, error) { 61 | if path == "" { 62 | return "", nil 63 | } 64 | 65 | p := normalisePath(cwd, path) 66 | 67 | if s, ok := r.cache[p]; ok { 68 | return s, nil 69 | } 70 | 71 | s, err := r.Open.readString(p) 72 | if err != nil { 73 | return "", err 74 | } 75 | 76 | if r.cache == nil { 77 | r.cache = map[string]string{} 78 | } 79 | r.cache[p] = s 80 | return s, nil 81 | } 82 | 83 | func normalisePath(cwd, path string) string { 84 | if !filepath.IsAbs(path) { 85 | path = filepath.Join(cwd, path) 86 | } 87 | return filepath.Clean(path) 88 | } 89 | -------------------------------------------------------------------------------- /generator/file_reader_other_test.go: -------------------------------------------------------------------------------- 1 | //go:build !windows 2 | 3 | package generator_test 4 | 5 | const ( 6 | relFile = "file.ext" 7 | absFile = "/file.ext" 8 | workingDir = "/some/dir" 9 | 10 | relFileUp = "../file.ext" 11 | expectedFileUp = "/some/file.ext" 12 | ) 13 | -------------------------------------------------------------------------------- /generator/file_reader_windows_test.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package generator_test 4 | 5 | const ( 6 | relFile = "file.ext" 7 | absFile = "c:\\file.ext" 8 | workingDir = "c:\\some\\dir" 9 | 10 | relFileUp = "..\\file.ext" 11 | expectedFileUp = "c:\\some\\file.ext" 12 | ) 13 | -------------------------------------------------------------------------------- /generator/function_loader.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "errors" 5 | "go/types" 6 | ) 7 | 8 | func (f *Fake) loadMethodForFunction() error { 9 | t, ok := f.Target.Type().(*types.Named) 10 | if !ok { 11 | return errors.New("target is not a named type") 12 | } 13 | sig, ok := t.Underlying().(*types.Signature) 14 | if !ok { 15 | return errors.New("target does not have an underlying function signature") 16 | } 17 | f.addTypesForMethod(sig) 18 | f.Function = methodForSignature(sig, f.TargetName, f.Imports) 19 | return nil 20 | } 21 | -------------------------------------------------------------------------------- /generator/function_template.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "strings" 5 | "text/template" 6 | ) 7 | 8 | var functionFuncs = template.FuncMap{ 9 | "ToLower": strings.ToLower, 10 | "UnExport": unexport, 11 | "Replace": strings.Replace, 12 | "IsExported": isExported, 13 | } 14 | 15 | const functionTemplate string = `{{.Header}}// Code generated by counterfeiter. DO NOT EDIT. 16 | package {{.DestinationPackage}} 17 | 18 | import ( 19 | {{- range $index, $import := .Imports.ByAlias}} 20 | {{$import}} 21 | {{- end}} 22 | ) 23 | 24 | type {{.Name}} struct { 25 | Stub func({{.Function.Params.AsArgs}}) {{.Function.Returns.AsReturnSignature}} 26 | mutex sync.RWMutex 27 | argsForCall []struct{ 28 | {{- range .Function.Params}} 29 | {{.Name}} {{if .IsVariadic}}{{Replace .Type "..." "[]" -1}}{{else}}{{.Type}}{{end}} 30 | {{- end}} 31 | } 32 | {{- if .Function.Returns.HasLength}} 33 | returns struct{ 34 | {{- range .Function.Returns}} 35 | {{UnExport .Name}} {{.Type}} 36 | {{- end}} 37 | } 38 | returnsOnCall map[int]struct{ 39 | {{- range .Function.Returns}} 40 | {{UnExport .Name}} {{.Type}} 41 | {{- end}} 42 | } 43 | {{- end}} 44 | invocations map[string][][]interface{} 45 | invocationsMutex sync.RWMutex 46 | } 47 | 48 | func (fake *{{.Name}}) Spy({{.Function.Params.AsNamedArgsWithTypes}}) {{.Function.Returns.AsReturnSignature}} { 49 | {{- range .Function.Params.Slices}} 50 | var {{UnExport .Name}}Copy {{.Type}} 51 | if {{UnExport .Name}} != nil { 52 | {{UnExport .Name}}Copy = make({{.Type}}, len({{UnExport .Name}})) 53 | copy({{UnExport .Name}}Copy, {{UnExport .Name}}) 54 | } 55 | {{- end}} 56 | fake.mutex.Lock() 57 | {{if .Function.Returns.HasLength}}ret, specificReturn := fake.returnsOnCall[len(fake.argsForCall)] 58 | {{end}}fake.argsForCall = append(fake.argsForCall, struct{ 59 | {{- range .Function.Params}} 60 | {{.Name}} {{if .IsVariadic}}{{Replace .Type "..." "[]" -1}}{{else}}{{.Type}}{{end}} 61 | {{- end}} 62 | }{ {{- .Function.Params.AsNamedArgs -}} }) 63 | stub := fake.Stub 64 | {{- if .Function.Returns.HasLength}} 65 | returns := fake.returns 66 | {{- end}} 67 | fake.recordInvocation("{{.TargetName}}", []interface{}{ {{- if .Function.Params.HasLength}}{{.Function.Params.AsNamedArgs}}{{end -}} }) 68 | fake.mutex.Unlock() 69 | if stub != nil { 70 | {{if .Function.Returns.HasLength}}return stub({{.Function.Params.AsNamedArgsForInvocation}}){{else}}fake.Stub({{.Function.Params.AsNamedArgsForInvocation}}){{end}} 71 | } 72 | {{- if .Function.Returns.HasLength}} 73 | if specificReturn { 74 | return {{.Function.Returns.WithPrefix "ret."}} 75 | } 76 | return {{.Function.Returns.WithPrefix "returns."}} 77 | {{- end}} 78 | } 79 | 80 | func (fake *{{.Name}}) CallCount() int { 81 | fake.mutex.RLock() 82 | defer fake.mutex.RUnlock() 83 | return len(fake.argsForCall) 84 | } 85 | 86 | func (fake *{{.Name}}) Calls(stub func({{.Function.Params.AsArgs}}) {{.Function.Returns.AsReturnSignature}}) { 87 | fake.mutex.Lock() 88 | defer fake.mutex.Unlock() 89 | fake.Stub = stub 90 | } 91 | 92 | {{if .Function.Params.HasLength -}} 93 | func (fake *{{.Name}}) ArgsForCall(i int) {{.Function.Params.AsReturnSignature}} { 94 | fake.mutex.RLock() 95 | defer fake.mutex.RUnlock() 96 | return {{.Function.Params.WithPrefix "fake.argsForCall[i]."}} 97 | } 98 | {{- end}} 99 | 100 | {{if .Function.Returns.HasLength -}} 101 | func (fake *{{.Name}}) Returns({{.Function.Returns.AsNamedArgsWithTypes}}) { 102 | fake.mutex.Lock() 103 | defer fake.mutex.Unlock() 104 | fake.Stub = nil 105 | fake.returns = struct { 106 | {{- range .Function.Returns}} 107 | {{UnExport .Name}} {{.Type}} 108 | {{- end}} 109 | }{ {{- .Function.Returns.AsNamedArgs -}} } 110 | } 111 | 112 | func (fake *{{.Name}}) ReturnsOnCall(i int, {{.Function.Returns.AsNamedArgsWithTypes}}) { 113 | fake.mutex.Lock() 114 | defer fake.mutex.Unlock() 115 | fake.Stub = nil 116 | if fake.returnsOnCall == nil { 117 | fake.returnsOnCall = make(map[int]struct { 118 | {{- range .Function.Returns}} 119 | {{UnExport .Name}} {{.Type}} 120 | {{- end}} 121 | }) 122 | } 123 | fake.returnsOnCall[i] = struct { 124 | {{- range .Function.Returns}} 125 | {{UnExport .Name}} {{.Type}} 126 | {{- end}} 127 | }{ {{- .Function.Returns.AsNamedArgs -}} } 128 | } 129 | {{- end}} 130 | 131 | func (fake *{{.Name}}) Invocations() map[string][][]interface{} { 132 | fake.invocationsMutex.RLock() 133 | defer fake.invocationsMutex.RUnlock() 134 | fake.mutex.RLock() 135 | defer fake.mutex.RUnlock() 136 | copiedInvocations := map[string][][]interface{}{} 137 | for key, value := range fake.invocations { 138 | copiedInvocations[key] = value 139 | } 140 | return copiedInvocations 141 | } 142 | 143 | func (fake *{{.Name}}) recordInvocation(key string, args []interface{}) { 144 | fake.invocationsMutex.Lock() 145 | defer fake.invocationsMutex.Unlock() 146 | if fake.invocations == nil { 147 | fake.invocations = map[string][][]interface{}{} 148 | } 149 | if fake.invocations[key] == nil { 150 | fake.invocations[key] = [][]interface{}{} 151 | } 152 | fake.invocations[key] = append(fake.invocations[key], args) 153 | } 154 | 155 | {{if IsExported .TargetName -}} 156 | var _ {{.TargetAlias}}.{{.TargetName}} = new({{.Name}}).Spy 157 | {{- end}} 158 | ` 159 | -------------------------------------------------------------------------------- /generator/import.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "fmt" 5 | "go/types" 6 | "path" 7 | "strings" 8 | 9 | "golang.org/x/tools/imports" 10 | ) 11 | 12 | // Imports indexes imports by package path and alias so that all imports have a 13 | // unique alias, and no package is included twice. 14 | type Imports struct { 15 | ByAlias map[string]Import 16 | ByPkgPath map[string]Import 17 | } 18 | 19 | func newImports() Imports { 20 | return Imports{ 21 | ByAlias: make(map[string]Import), 22 | ByPkgPath: make(map[string]Import), 23 | } 24 | } 25 | 26 | // Import is a package import with the associated alias for that package. 27 | type Import struct { 28 | Alias string 29 | PkgPath string 30 | } 31 | 32 | // String returns a string that may be used as an import line in a go source 33 | // file. Imports with aliases that match the package basename are printed without 34 | // an alias. 35 | func (i Import) String() string { 36 | if path.Base(i.PkgPath) == i.Alias { 37 | return `"` + i.PkgPath + `"` 38 | } 39 | return fmt.Sprintf(`%s "%s"`, i.Alias, i.PkgPath) 40 | } 41 | 42 | // Add creates an import with the given alias and path, and adds it to 43 | // Fake.Imports. 44 | func (i *Imports) Add(alias string, path string) Import { 45 | path = imports.VendorlessPath(strings.TrimSpace(path)) 46 | alias = strings.TrimSpace(alias) 47 | 48 | imp, exists := i.ByPkgPath[path] 49 | if exists { 50 | return imp 51 | } 52 | 53 | _, exists = i.ByAlias[alias] 54 | if exists { 55 | alias = uniqueAliasForImport(alias, i.ByAlias) 56 | } 57 | 58 | result := Import{Alias: alias, PkgPath: path} 59 | i.ByPkgPath[path] = result 60 | i.ByAlias[alias] = result 61 | return result 62 | } 63 | 64 | func uniqueAliasForImport(alias string, imports map[string]Import) string { 65 | for i := 0; ; i++ { 66 | newAlias := alias + string('a'+byte(i)) 67 | if _, exists := imports[newAlias]; !exists { 68 | return newAlias 69 | } 70 | } 71 | } 72 | 73 | // AliasForPackage returns a package alias for the package. 74 | func (i *Imports) AliasForPackage(p *types.Package) string { 75 | return i.ByPkgPath[imports.VendorlessPath(p.Path())].Alias 76 | } 77 | -------------------------------------------------------------------------------- /generator/import_test.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/onsi/gomega" 7 | ) 8 | 9 | func TestImport_String(t *testing.T) { 10 | var testcases = []struct { 11 | name string 12 | imp Import 13 | expected string 14 | }{ 15 | { 16 | name: "stdlib package", 17 | imp: Import{Alias: "os", PkgPath: "os"}, 18 | expected: `"os"`, 19 | }, 20 | { 21 | name: "alias matches base name", 22 | imp: Import{Alias: "foo", PkgPath: "example.com/goo/foo"}, 23 | expected: `"example.com/goo/foo"`, 24 | }, 25 | { 26 | name: "custom package alias", 27 | imp: Import{Alias: "thinga", PkgPath: "example.com/go-thing"}, 28 | expected: `thinga "example.com/go-thing"`, 29 | }, 30 | } 31 | 32 | for _, tc := range testcases { 33 | t.Run(tc.name, func(t *testing.T) { 34 | o := gomega.NewGomegaWithT(t) 35 | o.Expect(tc.imp.String()).To(gomega.Equal(tc.expected)) 36 | }) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /generator/interface_loader.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "fmt" 5 | "go/types" 6 | "strings" 7 | 8 | "golang.org/x/tools/go/types/typeutil" 9 | ) 10 | 11 | func (f *Fake) addTypesForMethod(sig *types.Signature) { 12 | for i := 0; i < sig.Results().Len(); i++ { 13 | ret := sig.Results().At(i) 14 | f.addImportsFor(ret.Type()) 15 | } 16 | for i := 0; i < sig.Params().Len(); i++ { 17 | param := sig.Params().At(i) 18 | f.addImportsFor(param.Type()) 19 | } 20 | } 21 | 22 | func methodForSignature(sig *types.Signature, methodName string, imports Imports) Method { 23 | params := []Param{} 24 | for i := 0; i < sig.Params().Len(); i++ { 25 | param := sig.Params().At(i) 26 | isVariadic := i == sig.Params().Len()-1 && sig.Variadic() 27 | typ := types.TypeString(param.Type(), imports.AliasForPackage) 28 | if isVariadic { 29 | typ = "..." + typ[2:] // Change []string to ...string 30 | } 31 | p := Param{ 32 | Name: fmt.Sprintf("arg%v", i+1), 33 | Type: typ, 34 | IsVariadic: isVariadic, 35 | IsSlice: strings.HasPrefix(typ, "[]"), 36 | } 37 | params = append(params, p) 38 | } 39 | returns := []Return{} 40 | for i := 0; i < sig.Results().Len(); i++ { 41 | ret := sig.Results().At(i) 42 | r := Return{ 43 | Name: fmt.Sprintf("result%v", i+1), 44 | Type: types.TypeString(ret.Type(), imports.AliasForPackage), 45 | } 46 | returns = append(returns, r) 47 | } 48 | return Method{ 49 | Name: methodName, 50 | Returns: returns, 51 | Params: params, 52 | } 53 | } 54 | 55 | // interfaceMethodSet identifies the methods that are exported for a given 56 | // interface. 57 | func interfaceMethodSet(t types.Type) []*rawMethod { 58 | if t == nil { 59 | return nil 60 | } 61 | var result []*rawMethod 62 | methods := typeutil.IntuitiveMethodSet(t, nil) 63 | for i := range methods { 64 | if methods[i].Obj() == nil || methods[i].Type() == nil { 65 | continue 66 | } 67 | fun, ok := methods[i].Obj().(*types.Func) 68 | if !ok { 69 | continue 70 | } 71 | sig, ok := methods[i].Type().(*types.Signature) 72 | if !ok { 73 | continue 74 | } 75 | result = append(result, &rawMethod{ 76 | Func: fun, 77 | Signature: sig, 78 | }) 79 | } 80 | 81 | return result 82 | } 83 | 84 | func (f *Fake) loadMethods() { 85 | var methods []*rawMethod 86 | if f.Mode == Package { 87 | methods = packageMethodSet(f.Package) 88 | } else { 89 | if !f.IsInterface() || f.Target == nil || f.Target.Type() == nil { 90 | return 91 | } 92 | methods = interfaceMethodSet(f.Target.Type()) 93 | } 94 | 95 | for i := range methods { 96 | f.addTypesForMethod(methods[i].Signature) 97 | } 98 | 99 | for i := range methods { 100 | method := methodForSignature(methods[i].Signature, methods[i].Func.Name(), f.Imports) 101 | f.Methods = append(f.Methods, method) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /generator/interface_template.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "strings" 5 | "text/template" 6 | 7 | "golang.org/x/text/cases" 8 | "golang.org/x/text/language" 9 | ) 10 | 11 | var title = cases.Title(language.Und, cases.NoLower) 12 | 13 | var interfaceFuncs = template.FuncMap{ 14 | "ToLower": strings.ToLower, 15 | "UnExport": unexport, 16 | "Replace": strings.Replace, 17 | "IsExported": isExported, 18 | "Title": title.String, 19 | } 20 | 21 | const interfaceTemplate string = `{{.Header}}// Code generated by counterfeiter. DO NOT EDIT. 22 | package {{.DestinationPackage}} 23 | 24 | import ( 25 | {{- range $index, $import := .Imports.ByAlias}} 26 | {{$import}} 27 | {{- end}} 28 | ) 29 | 30 | type {{.Name}}{{.GenericTypeParametersAndConstraints}} struct { 31 | {{- range .Methods}} 32 | {{.Name}}Stub func({{.Params.AsArgs}}) {{.Returns.AsReturnSignature}} 33 | {{UnExport .Name}}Mutex sync.RWMutex 34 | {{UnExport .Name}}ArgsForCall []struct{ 35 | {{- range .Params}} 36 | {{.Name}} {{if .IsVariadic}}{{Replace .Type "..." "[]" -1}}{{else}}{{.Type}}{{end}} 37 | {{- end}} 38 | } 39 | {{- if .Returns.HasLength}} 40 | {{UnExport .Name}}Returns struct{ 41 | {{- range .Returns}} 42 | {{UnExport .Name}} {{.Type}} 43 | {{- end}} 44 | } 45 | {{UnExport .Name}}ReturnsOnCall map[int]struct{ 46 | {{- range .Returns}} 47 | {{UnExport .Name}} {{.Type}} 48 | {{- end}} 49 | } 50 | {{- end}} 51 | {{- end}} 52 | invocations map[string][][]interface{} 53 | invocationsMutex sync.RWMutex 54 | } 55 | 56 | {{range .Methods -}} 57 | func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{.Name}}({{.Params.AsNamedArgsWithTypes}}) {{.Returns.AsReturnSignature}} { 58 | {{- range .Params.Slices}} 59 | var {{UnExport .Name}}Copy {{.Type}} 60 | if {{UnExport .Name}} != nil { 61 | {{UnExport .Name}}Copy = make({{.Type}}, len({{UnExport .Name}})) 62 | copy({{UnExport .Name}}Copy, {{UnExport .Name}}) 63 | } 64 | {{- end}} 65 | fake.{{UnExport .Name}}Mutex.Lock() 66 | {{- if .Returns.HasLength}} 67 | ret, specificReturn := fake.{{UnExport .Name}}ReturnsOnCall[len(fake.{{UnExport .Name}}ArgsForCall)] 68 | {{- end}} 69 | fake.{{UnExport .Name}}ArgsForCall = append(fake.{{UnExport .Name}}ArgsForCall, struct{ 70 | {{- range .Params}} 71 | {{.Name}} {{if .IsVariadic}}{{Replace .Type "..." "[]" -1}}{{else}}{{.Type}}{{end}} 72 | {{- end}} 73 | }{ {{- .Params.AsNamedArgs -}} }) 74 | stub := fake.{{.Name}}Stub 75 | {{- if .Returns.HasLength}} 76 | fakeReturns := fake.{{UnExport .Name}}Returns 77 | {{- end}} 78 | fake.recordInvocation("{{.Name}}", []interface{}{ {{- if .Params.HasLength}}{{.Params.AsNamedArgs}}{{end -}} }) 79 | fake.{{UnExport .Name}}Mutex.Unlock() 80 | if stub != nil { 81 | {{- if .Returns.HasLength}} 82 | return stub({{.Params.AsNamedArgsForInvocation}}){{else}}fake.{{.Name}}Stub({{.Params.AsNamedArgsForInvocation}}) 83 | {{- end}} 84 | } 85 | {{- if .Returns.HasLength}} 86 | if specificReturn { 87 | return {{.Returns.WithPrefix "ret."}} 88 | } 89 | return {{.Returns.WithPrefix "fakeReturns."}} 90 | {{- end}} 91 | } 92 | 93 | func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{Title .Name}}CallCount() int { 94 | fake.{{UnExport .Name}}Mutex.RLock() 95 | defer fake.{{UnExport .Name}}Mutex.RUnlock() 96 | return len(fake.{{UnExport .Name}}ArgsForCall) 97 | } 98 | 99 | func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{Title .Name}}Calls(stub func({{.Params.AsArgs}}) {{.Returns.AsReturnSignature}}) { 100 | fake.{{UnExport .Name}}Mutex.Lock() 101 | defer fake.{{UnExport .Name}}Mutex.Unlock() 102 | fake.{{.Name}}Stub = stub 103 | } 104 | 105 | {{if .Params.HasLength -}} 106 | func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{Title .Name}}ArgsForCall(i int) {{.Params.AsReturnSignature}} { 107 | fake.{{UnExport .Name}}Mutex.RLock() 108 | defer fake.{{UnExport .Name}}Mutex.RUnlock() 109 | argsForCall := fake.{{UnExport .Name}}ArgsForCall[i] 110 | return {{.Params.WithPrefix "argsForCall."}} 111 | } 112 | {{- end}} 113 | 114 | {{if .Returns.HasLength -}} 115 | func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{Title .Name}}Returns({{.Returns.AsNamedArgsWithTypes}}) { 116 | fake.{{UnExport .Name}}Mutex.Lock() 117 | defer fake.{{UnExport .Name}}Mutex.Unlock() 118 | fake.{{.Name}}Stub = nil 119 | fake.{{UnExport .Name}}Returns = struct { 120 | {{- range .Returns}} 121 | {{UnExport .Name}} {{.Type}} 122 | {{- end}} 123 | }{ {{- .Returns.AsNamedArgs -}} } 124 | } 125 | 126 | func (fake *{{$.Name}}{{$.GenericTypeParameters}}) {{Title .Name}}ReturnsOnCall(i int, {{.Returns.AsNamedArgsWithTypes}}) { 127 | fake.{{UnExport .Name}}Mutex.Lock() 128 | defer fake.{{UnExport .Name}}Mutex.Unlock() 129 | fake.{{.Name}}Stub = nil 130 | if fake.{{UnExport .Name}}ReturnsOnCall == nil { 131 | fake.{{UnExport .Name}}ReturnsOnCall = make(map[int]struct { 132 | {{- range .Returns}} 133 | {{UnExport .Name}} {{.Type}} 134 | {{- end}} 135 | }) 136 | } 137 | fake.{{UnExport .Name}}ReturnsOnCall[i] = struct { 138 | {{- range .Returns}} 139 | {{UnExport .Name}} {{.Type}} 140 | {{- end}} 141 | }{ {{- .Returns.AsNamedArgs -}} } 142 | } 143 | 144 | {{end -}} 145 | {{end}} 146 | 147 | func (fake *{{.Name}}{{$.GenericTypeParameters}}) Invocations() map[string][][]interface{} { 148 | fake.invocationsMutex.RLock() 149 | defer fake.invocationsMutex.RUnlock() 150 | {{- range .Methods}} 151 | fake.{{UnExport .Name}}Mutex.RLock() 152 | defer fake.{{UnExport .Name}}Mutex.RUnlock() 153 | {{- end}} 154 | copiedInvocations := map[string][][]interface{}{} 155 | for key, value := range fake.invocations { 156 | copiedInvocations[key] = value 157 | } 158 | return copiedInvocations 159 | } 160 | 161 | func (fake *{{.Name}}{{$.GenericTypeParameters}}) recordInvocation(key string, args []interface{}) { 162 | fake.invocationsMutex.Lock() 163 | defer fake.invocationsMutex.Unlock() 164 | if fake.invocations == nil { 165 | fake.invocations = map[string][][]interface{}{} 166 | } 167 | if fake.invocations[key] == nil { 168 | fake.invocations[key] = [][]interface{}{} 169 | } 170 | fake.invocations[key] = append(fake.invocations[key], args) 171 | } 172 | 173 | {{if IsExported .TargetName -}} 174 | var _ {{.TargetAlias}}.{{.TargetName}}{{.GenericTypeConstraints}} = new({{.Name}}{{.GenericTypeConstraints}}) 175 | {{- end}} 176 | ` 177 | -------------------------------------------------------------------------------- /generator/loader.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "fmt" 5 | "go/build" 6 | "go/types" 7 | "log" 8 | "path/filepath" 9 | "reflect" 10 | "strings" 11 | 12 | "golang.org/x/tools/go/packages" 13 | "golang.org/x/tools/imports" 14 | ) 15 | 16 | func (f *Fake) loadPackages(c Cacher, workingDir string) error { 17 | log.Println("loading packages...") 18 | p, ok := c.Load(f.TargetPackage) 19 | if ok { 20 | f.Packages = p 21 | log.Printf("loaded %v packages from cache\n", len(f.Packages)) 22 | return nil 23 | } 24 | importPath := f.TargetPackage 25 | if !filepath.IsAbs(importPath) { 26 | ctx := getBuildContext(workingDir) 27 | bp, err := ctx.Import(f.TargetPackage, workingDir, build.FindOnly) 28 | if err != nil { 29 | return err 30 | } 31 | importPath = bp.ImportPath 32 | } 33 | p, err := packages.Load(&packages.Config{ 34 | Mode: packages.NeedName | packages.NeedFiles | packages.NeedImports | packages.NeedDeps | packages.NeedTypes | packages.NeedTypesInfo, 35 | Dir: workingDir, 36 | Tests: true, 37 | }, importPath) 38 | if err != nil { 39 | return err 40 | } 41 | for i := range p { 42 | if len(p[i].Errors) > 0 { 43 | if i == 0 { 44 | err = p[i].Errors[0] 45 | } 46 | for j := range p[i].Errors { 47 | log.Printf("error loading packages: %v", strings.TrimPrefix(fmt.Sprintf("%v", p[i].Errors[j]), "-: ")) 48 | } 49 | } 50 | } 51 | if err != nil { 52 | return err 53 | } 54 | f.Packages = p 55 | c.Store(f.TargetPackage, p) 56 | log.Printf("loaded %v packages\n", len(f.Packages)) 57 | return nil 58 | } 59 | 60 | func (f *Fake) getGenericTypeData(typeName *types.TypeName) (paramNames []string, constraintNames []string, paramAndConstraintNames []string, found bool) { 61 | if named, ok := typeName.Type().(*types.Named); ok { 62 | if _, ok := named.Underlying().(*types.Interface); ok { 63 | typeParams := named.TypeParams() 64 | if typeParams.Len() > 0 { 65 | for i := 0; i < typeParams.Len(); i++ { 66 | param := typeParams.At(i) 67 | paramName := param.Obj().Name() 68 | constraint := param.Constraint() 69 | constraintSections := strings.Split(constraint.String(), "/") 70 | constraintName := constraintSections[len(constraintSections)-1] 71 | paramNames = append(paramNames, paramName) 72 | constraintNames = append(constraintNames, constraintName) 73 | paramAndConstraintNames = append(paramAndConstraintNames, fmt.Sprintf("%s %s", paramName, constraintName)) 74 | found = true 75 | } 76 | } 77 | } 78 | } 79 | return 80 | } 81 | 82 | func (f *Fake) findPackage() error { 83 | var target *types.TypeName 84 | var pkg *packages.Package 85 | genericTypeParametersAndConstraints := []string{} 86 | genericTypeConstraints := []string{} 87 | genericTypeParameters := []string{} 88 | for i := range f.Packages { 89 | if f.Packages[i].Types == nil || f.Packages[i].Types.Scope() == nil { 90 | continue 91 | } 92 | pkg = f.Packages[i] 93 | if f.Mode == Package { 94 | break 95 | } 96 | 97 | raw := pkg.Types.Scope().Lookup(f.TargetName) 98 | if raw != nil { 99 | if typeName, ok := raw.(*types.TypeName); ok { 100 | if paramNames, constraintNames, paramAndConstraintNames, found := f.getGenericTypeData(typeName); found { 101 | genericTypeParameters = append(genericTypeParameters, paramNames...) 102 | genericTypeConstraints = append(genericTypeConstraints, constraintNames...) 103 | genericTypeParametersAndConstraints = append( 104 | genericTypeParametersAndConstraints, 105 | paramAndConstraintNames..., 106 | ) 107 | } 108 | 109 | target = typeName 110 | break 111 | } 112 | } 113 | pkg = nil 114 | } 115 | if pkg == nil { 116 | switch f.Mode { 117 | case Package: 118 | return fmt.Errorf("cannot find package with name: %s", f.TargetPackage) 119 | case InterfaceOrFunction: 120 | return fmt.Errorf("cannot find package with target: %s", f.TargetName) 121 | } 122 | } 123 | f.Target = target 124 | f.Package = pkg 125 | f.TargetPackage = imports.VendorlessPath(pkg.PkgPath) 126 | if len(genericTypeParameters) > 0 { 127 | f.GenericTypeParametersAndConstraints = fmt.Sprintf("[%s]", strings.Join(genericTypeParametersAndConstraints, ", ")) 128 | f.GenericTypeParameters = fmt.Sprintf("[%s]", strings.Join(genericTypeParameters, ", ")) 129 | f.GenericTypeConstraints = fmt.Sprintf("[%s]", strings.Join(genericTypeConstraints, ", ")) 130 | } 131 | t := f.Imports.Add(pkg.Name, f.TargetPackage) 132 | f.TargetAlias = t.Alias 133 | if f.Mode != Package { 134 | f.TargetName = target.Name() 135 | } 136 | 137 | if f.Mode == InterfaceOrFunction { 138 | if !f.IsInterface() && !f.IsFunction() { 139 | return fmt.Errorf("cannot generate a fake for %s because it is not an interface or function", f.TargetName) 140 | } 141 | } 142 | 143 | if f.IsInterface() { 144 | log.Printf("Found interface with name: [%s]\n", f.TargetName) 145 | } 146 | if f.IsFunction() { 147 | log.Printf("Found function with name: [%s]\n", f.TargetName) 148 | } 149 | if f.Mode == Package { 150 | log.Printf("Found package with name: [%s]\n", f.TargetPackage) 151 | } 152 | return nil 153 | } 154 | 155 | // addImportsFor inspects the given type and adds imports to the fake if importable 156 | // types are found. 157 | func (f *Fake) addImportsFor(typ types.Type) { 158 | if typ == nil { 159 | return 160 | } 161 | 162 | switch t := typ.(type) { 163 | case *types.Basic: 164 | return 165 | case *types.Pointer: 166 | f.addImportsFor(t.Elem()) 167 | case *types.Map: 168 | f.addImportsFor(t.Key()) 169 | f.addImportsFor(t.Elem()) 170 | case *types.Chan: 171 | f.addImportsFor(t.Elem()) 172 | case *types.Alias: 173 | f.addImportsForNamedType(t) 174 | case *types.Named: 175 | f.addImportsForNamedType(t) 176 | case *types.Slice: 177 | f.addImportsFor(t.Elem()) 178 | case *types.Array: 179 | f.addImportsFor(t.Elem()) 180 | case *types.Interface: 181 | return 182 | case *types.Signature: 183 | f.addTypesForMethod(t) 184 | case *types.Struct: 185 | for i := 0; i < t.NumFields(); i++ { 186 | f.addImportsFor(t.Field(i).Type()) 187 | } 188 | default: 189 | log.Printf("!!! WARNING: Missing case for type %s\n", reflect.TypeOf(typ).String()) 190 | } 191 | } 192 | 193 | func (f *Fake) addImportsForNamedType(t interface { 194 | Obj() *types.TypeName 195 | TypeArgs() *types.TypeList 196 | }) { 197 | if t.Obj() != nil && t.Obj().Pkg() != nil { 198 | typeArgs := t.TypeArgs() 199 | for i := 0; i < typeArgs.Len(); i++ { 200 | f.addImportsFor(typeArgs.At(i)) 201 | } 202 | f.Imports.Add(t.Obj().Pkg().Name(), t.Obj().Pkg().Path()) 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /generator/package_loader.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "go/types" 5 | 6 | "golang.org/x/tools/go/packages" 7 | ) 8 | 9 | type rawMethod struct { 10 | Func *types.Func 11 | Signature *types.Signature 12 | } 13 | 14 | // packageMethodSet identifies the functions that are exported from a given 15 | // package. 16 | func packageMethodSet(p *packages.Package) []*rawMethod { 17 | if p == nil || p.Types == nil || p.Types.Scope() == nil { 18 | return nil 19 | } 20 | var result []*rawMethod 21 | scope := p.Types.Scope() 22 | for _, name := range scope.Names() { 23 | obj := scope.Lookup(name) 24 | if !obj.Exported() { 25 | continue // skip unexported names 26 | } 27 | fun, ok := obj.(*types.Func) 28 | if !ok { 29 | continue 30 | } 31 | sig, ok := obj.Type().(*types.Signature) 32 | if !ok { 33 | continue 34 | } 35 | result = append(result, &rawMethod{ 36 | Func: fun, 37 | Signature: sig, 38 | }) 39 | } 40 | 41 | return result 42 | } 43 | -------------------------------------------------------------------------------- /generator/package_template.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "strings" 5 | "text/template" 6 | ) 7 | 8 | var packageFuncs = template.FuncMap{ 9 | "ToLower": strings.ToLower, 10 | "UnExport": unexport, 11 | "Replace": strings.Replace, 12 | "Generate": func(suffix string) string { return suffix + ":generate" }, // yes, this seems insane but ensures that we can use `go generate ./...` from the main package 13 | } 14 | 15 | const packageTemplate string = `{{.Header}}// Code generated by counterfeiter. DO NOT EDIT. 16 | package {{.DestinationPackage}} 17 | 18 | import ( 19 | {{- range $index, $import := .Imports.ByAlias}} 20 | {{$import}} 21 | {{- end}} 22 | ) 23 | 24 | //{{Generate "go"}} go run github.com/maxbrunsfeld/counterfeiter/v6 -generate 25 | //{{Generate "counterfeiter"}} . {{.Name}} 26 | 27 | // {{.Name}} is a generated interface representing the exported functions 28 | // in the {{.TargetPackage}} package. 29 | type {{.Name}} interface { 30 | {{- range .Methods}} 31 | {{.Name}}({{.Params.AsNamedArgsWithTypes}}) {{.Returns.AsReturnSignature}} 32 | {{- end}} 33 | } 34 | 35 | type {{.Name}}Shim struct {} 36 | 37 | {{- range .Methods}} 38 | func (p *{{$.Name}}Shim) {{.Name}}({{.Params.AsNamedArgsWithTypes}}) {{.Returns.AsReturnSignature}} { 39 | {{if .Returns.HasLength}}return {{end}}{{$.TargetAlias}}.{{.Name}}({{.Params.AsNamedArgsForInvocation}}) 40 | } 41 | {{end}} 42 | var _ {{.Name}} = new({{.Name}}Shim) 43 | ` 44 | -------------------------------------------------------------------------------- /generator/param.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import "strings" 4 | 5 | // Params is a slice of Param. 6 | type Params []Param 7 | 8 | // Param is an argument to a function. 9 | type Param struct { 10 | Name string 11 | Type string 12 | IsVariadic bool 13 | IsSlice bool 14 | } 15 | 16 | // Slices returns those params that are a slice. 17 | func (p Params) Slices() Params { 18 | var result Params 19 | for i := range p { 20 | if p[i].IsSlice { 21 | result = append(result, p[i]) 22 | } 23 | } 24 | return result 25 | } 26 | 27 | // HasLength returns true if there are params. It returns false if there are no 28 | // params. 29 | func (p Params) HasLength() bool { 30 | return len(p) > 0 31 | } 32 | 33 | // WithPrefix builds a string representing a functions parameters, and adds a 34 | // prefix to each. 35 | func (p Params) WithPrefix(prefix string) string { 36 | if len(p) == 0 { 37 | return "" 38 | } 39 | 40 | params := []string{} 41 | for i := range p { 42 | if prefix == "" { 43 | params = append(params, unexport(p[i].Name)) 44 | } else { 45 | params = append(params, prefix+unexport(p[i].Name)) 46 | } 47 | } 48 | return strings.Join(params, ", ") 49 | } 50 | 51 | // AsArgs builds a string that represents the parameters to a function as 52 | // arguments to a function invocation. 53 | func (p Params) AsArgs() string { 54 | if len(p) == 0 { 55 | return "" 56 | } 57 | 58 | params := []string{} 59 | for i := range p { 60 | params = append(params, p[i].Type) 61 | } 62 | return strings.Join(params, ", ") 63 | } 64 | 65 | // AsNamedArgsWithTypes builds a string that represents parameters as named 66 | // arguments to a function, with associated types. 67 | func (p Params) AsNamedArgsWithTypes() string { 68 | if len(p) == 0 { 69 | return "" 70 | } 71 | 72 | params := []string{} 73 | for i := range p { 74 | params = append(params, unexport(p[i].Name)+" "+p[i].Type) 75 | } 76 | return strings.Join(params, ", ") 77 | } 78 | 79 | // AsNamedArgs builds a string that represents parameters as named arguments. 80 | func (p Params) AsNamedArgs() string { 81 | if len(p) == 0 { 82 | return "" 83 | } 84 | 85 | params := []string{} 86 | for i := range p { 87 | if p[i].IsSlice { 88 | params = append(params, unexport(p[i].Name)+"Copy") 89 | } else { 90 | params = append(params, unexport(p[i].Name)) 91 | } 92 | } 93 | return strings.Join(params, ", ") 94 | } 95 | 96 | // AsNamedArgsForInvocation builds a string that represents a function's 97 | // arguments as required for invocation of the function. 98 | func (p Params) AsNamedArgsForInvocation() string { 99 | if len(p) == 0 { 100 | return "" 101 | } 102 | 103 | params := []string{} 104 | for i := range p { 105 | if p[i].IsVariadic { 106 | params = append(params, unexport(p[i].Name)+"...") 107 | } else { 108 | params = append(params, unexport(p[i].Name)) 109 | } 110 | } 111 | return strings.Join(params, ", ") 112 | } 113 | 114 | // AsReturnSignature builds a string representing signature for the params of 115 | // a function. 116 | func (p Params) AsReturnSignature() string { 117 | if len(p) == 0 { 118 | return "" 119 | } 120 | if len(p) == 1 { 121 | if p[0].IsVariadic { 122 | return strings.Replace(p[0].Type, "...", "[]", -1) 123 | } 124 | return p[0].Type 125 | } 126 | result := "(" 127 | for i := range p { 128 | t := p[i].Type 129 | if p[i].IsVariadic { 130 | t = strings.Replace(t, "...", "[]", -1) 131 | } 132 | result = result + t 133 | if i < len(p) { 134 | result = result + ", " 135 | } 136 | } 137 | result = result + ")" 138 | return result 139 | } 140 | -------------------------------------------------------------------------------- /generator/return.go: -------------------------------------------------------------------------------- 1 | package generator 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | // Returns is a slice of Return. 8 | type Returns []Return 9 | 10 | // Return is the result of a method's invocation. 11 | type Return struct { 12 | Name string 13 | Type string 14 | } 15 | 16 | // HasLength is true if there are returns, else false. 17 | func (r Returns) HasLength() bool { 18 | return len(r) > 0 19 | } 20 | 21 | // WithPrefix builds a string representing the parameters returned from a 22 | // function, and adds a prefix to each. 23 | func (r Returns) WithPrefix(p string) string { 24 | if len(r) == 0 { 25 | return "" 26 | } 27 | 28 | rets := []string{} 29 | for i := range r { 30 | if p == "" { 31 | rets = append(rets, unexport(r[i].Name)) 32 | } else { 33 | rets = append(rets, p+unexport(r[i].Name)) 34 | } 35 | } 36 | return strings.Join(rets, ", ") 37 | } 38 | 39 | // AsArgs builds a string representing the arguments passed to a function. 40 | func (r Returns) AsArgs() string { 41 | if len(r) == 0 { 42 | return "" 43 | } 44 | 45 | rets := []string{} 46 | for i := range r { 47 | rets = append(rets, r[i].Type) 48 | } 49 | return strings.Join(rets, ", ") 50 | } 51 | 52 | // AsNamedArgsWithTypes builds a string representing a function's named 53 | // arguments, with associated types. 54 | func (r Returns) AsNamedArgsWithTypes() string { 55 | if len(r) == 0 { 56 | return "" 57 | } 58 | 59 | rets := []string{} 60 | for i := range r { 61 | rets = append(rets, unexport(r[i].Name)+" "+r[i].Type) 62 | } 63 | return strings.Join(rets, ", ") 64 | } 65 | 66 | // AsNamedArgs builds a string representing a function's named arguments. 67 | func (r Returns) AsNamedArgs() string { 68 | if len(r) == 0 { 69 | return "" 70 | } 71 | 72 | rets := []string{} 73 | for i := range r { 74 | rets = append(rets, unexport(r[i].Name)) 75 | } 76 | return strings.Join(rets, ", ") 77 | } 78 | 79 | // AsReturnSignature builds a string representing signature for the returns of 80 | // a function. 81 | func (r Returns) AsReturnSignature() string { 82 | if len(r) == 0 { 83 | return "" 84 | } 85 | if len(r) == 1 { 86 | return r[0].Type 87 | } 88 | result := "(" 89 | for i := range r { 90 | result = result + r[i].Type 91 | if i < len(r) { 92 | result = result + ", " 93 | } 94 | } 95 | result = result + ")" 96 | return result 97 | } 98 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/maxbrunsfeld/counterfeiter/v6 2 | 3 | require ( 4 | github.com/onsi/gomega v1.37.0 5 | github.com/sclevine/spec v1.4.0 6 | golang.org/x/text v0.25.0 7 | golang.org/x/tools v0.33.0 8 | ) 9 | 10 | require ( 11 | github.com/google/go-cmp v0.7.0 // indirect 12 | golang.org/x/mod v0.24.0 // indirect 13 | golang.org/x/net v0.40.0 // indirect 14 | golang.org/x/sync v0.14.0 // indirect 15 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect 16 | gopkg.in/yaml.v3 v3.0.1 // indirect 17 | ) 18 | 19 | go 1.23.0 20 | 21 | toolchain go1.24.1 22 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= 2 | github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= 3 | github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= 4 | github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= 5 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 6 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 7 | github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= 8 | github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= 9 | github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= 10 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 11 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 12 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 13 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 14 | github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0= 15 | github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM= 16 | github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= 17 | github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= 18 | github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8= 19 | github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4QnFHkOM= 20 | golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= 21 | golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= 22 | golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= 23 | golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= 24 | golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= 25 | golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 26 | golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= 27 | golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 28 | golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= 29 | golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= 30 | golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= 31 | golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= 32 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 33 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 34 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 35 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 36 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 37 | -------------------------------------------------------------------------------- /integration/copy_test.go: -------------------------------------------------------------------------------- 1 | package integration_test 2 | 3 | import ( 4 | "io" 5 | "io/fs" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | // Copy copies src to dest, doesn't matter if src is a directory or a file 12 | func Copy(src, dest string) error { 13 | info, err := os.Lstat(src) 14 | if err != nil { 15 | return err 16 | } 17 | return copy(src, dest, info) 18 | } 19 | 20 | // copy dispatches copy-funcs according to the mode. 21 | // Because this "copy" could be called recursively, 22 | // "info" MUST be given here, NOT nil. 23 | func copy(src, dest string, info os.FileInfo) error { 24 | if info.Mode()&os.ModeSymlink != 0 { 25 | return lcopy(src, dest, info) 26 | } 27 | if info.IsDir() { 28 | if strings.HasSuffix(src, "fakes") { 29 | return nil 30 | } 31 | return dcopy(src, dest, info) 32 | } 33 | return fcopy(src, dest, info) 34 | } 35 | 36 | // fcopy is for just a file, 37 | // with considering existence of parent directory 38 | // and file permission. 39 | func fcopy(src, dest string, info os.FileInfo) error { 40 | if err := os.MkdirAll(filepath.Dir(dest), os.ModePerm); err != nil { 41 | return err 42 | } 43 | 44 | f, err := os.Create(dest) 45 | if err != nil { 46 | return err 47 | } 48 | defer f.Close() 49 | 50 | if err = os.Chmod(f.Name(), info.Mode()); err != nil { 51 | return err 52 | } 53 | 54 | s, err := os.Open(src) 55 | if err != nil { 56 | return err 57 | } 58 | defer s.Close() 59 | 60 | _, err = io.Copy(f, s) 61 | return err 62 | } 63 | 64 | // dcopy is for a directory, 65 | // with scanning contents inside the directory 66 | // and pass everything to "copy" recursively. 67 | func dcopy(srcdir, destdir string, info os.FileInfo) error { 68 | if err := os.MkdirAll(destdir, info.Mode()); err != nil { 69 | return err 70 | } 71 | 72 | entries, err := os.ReadDir(srcdir) 73 | if err != nil { 74 | return err 75 | } 76 | contents := make([]fs.FileInfo, 0, len(entries)) 77 | for _, entry := range entries { 78 | info, err := entry.Info() 79 | if err != nil { 80 | return err 81 | } 82 | contents = append(contents, info) 83 | } 84 | 85 | for _, content := range contents { 86 | cs, cd := filepath.Join(srcdir, content.Name()), filepath.Join(destdir, content.Name()) 87 | if err := copy(cs, cd, content); err != nil { 88 | // If any error, exit immediately 89 | return err 90 | } 91 | } 92 | return nil 93 | } 94 | 95 | // lcopy is for a symlink, 96 | // with just creating a new symlink by replicating src symlink. 97 | func lcopy(src, dest string, info os.FileInfo) error { 98 | src, err := os.Readlink(src) 99 | if err != nil { 100 | return err 101 | } 102 | return os.Symlink(src, dest) 103 | } 104 | -------------------------------------------------------------------------------- /integration/empty.go: -------------------------------------------------------------------------------- 1 | package integration 2 | 3 | // empty go file to prevent go build from complaining in go <=1.10 4 | -------------------------------------------------------------------------------- /integration/roundtrip_module_test.go: -------------------------------------------------------------------------------- 1 | //go:build go1.11 2 | 3 | package integration_test 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/sclevine/spec" 9 | "github.com/sclevine/spec/report" 10 | ) 11 | 12 | func TestIntegration(t *testing.T) { 13 | suite := spec.New("integration", spec.Report(report.Terminal{})) 14 | suite("round trip as module", testRoundTripAsModule) 15 | suite.Run(t) 16 | } 17 | 18 | func testRoundTripAsModule(t *testing.T, when spec.G, it spec.S) { 19 | runTests(t, when, it) 20 | } 21 | -------------------------------------------------------------------------------- /integration/testdata/expected_fake_multiab.txt: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package foofakes 3 | 4 | import ( 5 | "sync" 6 | 7 | fooa "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/a/foo" 8 | foob "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/b/foo" 9 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/dup_packages/foo" 10 | ) 11 | 12 | type FakeMultiAB struct { 13 | MineStub func() foo.S 14 | mineMutex sync.RWMutex 15 | mineArgsForCall []struct{} 16 | mineReturns struct { 17 | result1 foo.S 18 | } 19 | mineReturnsOnCall map[int]struct { 20 | result1 foo.S 21 | } 22 | FromAStub func() fooa.S 23 | fromAMutex sync.RWMutex 24 | fromAArgsForCall []struct{} 25 | fromAReturns struct { 26 | result1 fooa.S 27 | } 28 | fromAReturnsOnCall map[int]struct { 29 | result1 fooa.S 30 | } 31 | FromBStub func() foob.S 32 | fromBMutex sync.RWMutex 33 | fromBArgsForCall []struct{} 34 | fromBReturns struct { 35 | result1 foob.S 36 | } 37 | fromBReturnsOnCall map[int]struct { 38 | result1 foob.S 39 | } 40 | invocations map[string][][]interface{} 41 | invocationsMutex sync.RWMutex 42 | } 43 | 44 | func (fake *FakeMultiAB) Mine() foo.S { 45 | fake.mineMutex.Lock() 46 | ret, specificReturn := fake.mineReturnsOnCall[len(fake.mineArgsForCall)] 47 | fake.mineArgsForCall = append(fake.mineArgsForCall, struct{}{}) 48 | stub := fake.MineStub 49 | fakeReturns := fake.mineReturns 50 | fake.mineMutex.Unlock() 51 | fake.recordInvocation("Mine", []interface{}{}) 52 | if stub != nil { 53 | return stub() 54 | } 55 | if specificReturn { 56 | return ret.result1 57 | } 58 | return fakeReturns.result1 59 | } 60 | 61 | func (fake *FakeMultiAB) MineCallCount() int { 62 | fake.mineMutex.RLock() 63 | defer fake.mineMutex.RUnlock() 64 | return len(fake.mineArgsForCall) 65 | } 66 | 67 | func (fake *FakeMultiAB) MineCalls(stub func() foo.S) { 68 | fake.mineMutex.Lock() 69 | defer fake.mineMutex.Unlock() 70 | fake.MineStub = stub 71 | } 72 | 73 | func (fake *FakeMultiAB) MineReturns(result1 foo.S) { 74 | fake.mineMutex.Lock() 75 | defer fake.mineMutex.Unlock() 76 | fake.MineStub = nil 77 | fake.mineReturns = struct { 78 | result1 foo.S 79 | }{result1} 80 | } 81 | 82 | func (fake *FakeMultiAB) MineReturnsOnCall(i int, result1 foo.S) { 83 | fake.mineMutex.Lock() 84 | defer fake.mineMutex.Unlock() 85 | fake.MineStub = nil 86 | if fake.mineReturnsOnCall == nil { 87 | fake.mineReturnsOnCall = make(map[int]struct { 88 | result1 foo.S 89 | }) 90 | } 91 | fake.mineReturnsOnCall[i] = struct { 92 | result1 foo.S 93 | }{result1} 94 | } 95 | 96 | func (fake *FakeMultiAB) FromA() fooa.S { 97 | fake.fromAMutex.Lock() 98 | ret, specificReturn := fake.fromAReturnsOnCall[len(fake.fromAArgsForCall)] 99 | fake.fromAArgsForCall = append(fake.fromAArgsForCall, struct{}{}) 100 | stub := fake.FromAStub 101 | fakeReturns := fake.fromAReturns 102 | fake.recordInvocation("FromA", []interface{}{}) 103 | fake.fromAMutex.Unlock() 104 | if stub != nil { 105 | return stub() 106 | } 107 | if specificReturn { 108 | return ret.result1 109 | } 110 | return fakeReturns.result1 111 | } 112 | 113 | func (fake *FakeMultiAB) FromACallCount() int { 114 | fake.fromAMutex.RLock() 115 | defer fake.fromAMutex.RUnlock() 116 | return len(fake.fromAArgsForCall) 117 | } 118 | 119 | func (fake *FakeMultiAB) FromACalls(stub func() fooa.S) { 120 | fake.fromAMutex.Lock() 121 | defer fake.fromAMutex.Unlock() 122 | fake.FromAStub = stub 123 | } 124 | 125 | func (fake *FakeMultiAB) FromAReturns(result1 fooa.S) { 126 | fake.fromAMutex.Lock() 127 | defer fake.fromAMutex.Unlock() 128 | fake.FromAStub = nil 129 | fake.fromAReturns = struct { 130 | result1 fooa.S 131 | }{result1} 132 | } 133 | 134 | func (fake *FakeMultiAB) FromAReturnsOnCall(i int, result1 fooa.S) { 135 | fake.fromAMutex.Lock() 136 | defer fake.fromAMutex.Unlock() 137 | fake.FromAStub = nil 138 | if fake.fromAReturnsOnCall == nil { 139 | fake.fromAReturnsOnCall = make(map[int]struct { 140 | result1 fooa.S 141 | }) 142 | } 143 | fake.fromAReturnsOnCall[i] = struct { 144 | result1 fooa.S 145 | }{result1} 146 | } 147 | 148 | func (fake *FakeMultiAB) FromB() foob.S { 149 | fake.fromBMutex.Lock() 150 | ret, specificReturn := fake.fromBReturnsOnCall[len(fake.fromBArgsForCall)] 151 | fake.fromBArgsForCall = append(fake.fromBArgsForCall, struct{}{}) 152 | stub := fake.FromBStub 153 | fakeReturns := fake.fromBReturns 154 | fake.recordInvocation("FromB", []interface{}{}) 155 | fake.fromBMutex.Unlock() 156 | if stub != nil { 157 | return stub() 158 | } 159 | if specificReturn { 160 | return ret.result1 161 | } 162 | return fakeReturns.result1 163 | } 164 | 165 | func (fake *FakeMultiAB) FromBCallCount() int { 166 | fake.fromBMutex.RLock() 167 | defer fake.fromBMutex.RUnlock() 168 | return len(fake.fromBArgsForCall) 169 | } 170 | 171 | func (fake *FakeMultiAB) FromBCalls(stub func() foob.S) { 172 | fake.fromBMutex.Lock() 173 | defer fake.fromBMutex.Unlock() 174 | fake.FromBStub = stub 175 | } 176 | 177 | func (fake *FakeMultiAB) FromBReturns(result1 foob.S) { 178 | fake.fromBMutex.Lock() 179 | defer fake.fromBMutex.Unlock() 180 | fake.FromBStub = nil 181 | fake.fromBReturns = struct { 182 | result1 foob.S 183 | }{result1} 184 | } 185 | 186 | func (fake *FakeMultiAB) FromBReturnsOnCall(i int, result1 foob.S) { 187 | fake.fromBMutex.Lock() 188 | defer fake.fromBMutex.Unlock() 189 | fake.FromBStub = nil 190 | if fake.fromBReturnsOnCall == nil { 191 | fake.fromBReturnsOnCall = make(map[int]struct { 192 | result1 foob.S 193 | }) 194 | } 195 | fake.fromBReturnsOnCall[i] = struct { 196 | result1 foob.S 197 | }{result1} 198 | } 199 | 200 | func (fake *FakeMultiAB) Invocations() map[string][][]interface{} { 201 | fake.invocationsMutex.RLock() 202 | defer fake.invocationsMutex.RUnlock() 203 | fake.mineMutex.RLock() 204 | defer fake.mineMutex.RUnlock() 205 | fake.fromAMutex.RLock() 206 | defer fake.fromAMutex.RUnlock() 207 | fake.fromBMutex.RLock() 208 | defer fake.fromBMutex.RUnlock() 209 | copiedInvocations := map[string][][]interface{}{} 210 | for key, value := range fake.invocations { 211 | copiedInvocations[key] = value 212 | } 213 | return copiedInvocations 214 | } 215 | 216 | func (fake *FakeMultiAB) recordInvocation(key string, args []interface{}) { 217 | fake.invocationsMutex.Lock() 218 | defer fake.invocationsMutex.Unlock() 219 | if fake.invocations == nil { 220 | fake.invocations = map[string][][]interface{}{} 221 | } 222 | if fake.invocations[key] == nil { 223 | fake.invocations[key] = [][]interface{}{} 224 | } 225 | fake.invocations[key] = append(fake.invocations[key], args) 226 | } 227 | 228 | var _ foo.MultiAB = new(FakeMultiAB) 229 | -------------------------------------------------------------------------------- /integration/testdata/expected_fake_somethingfactory.txt: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package fixturesfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/maxbrunsfeld/counterfeiter/v6/fixtures" 8 | ) 9 | 10 | type FakeSomethingFactory struct { 11 | Stub func(string, map[string]interface{}) string 12 | mutex sync.RWMutex 13 | argsForCall []struct { 14 | arg1 string 15 | arg2 map[string]interface{} 16 | } 17 | returns struct { 18 | result1 string 19 | } 20 | returnsOnCall map[int]struct { 21 | result1 string 22 | } 23 | invocations map[string][][]interface{} 24 | invocationsMutex sync.RWMutex 25 | } 26 | 27 | func (fake *FakeSomethingFactory) Spy(arg1 string, arg2 map[string]interface{}) string { 28 | fake.mutex.Lock() 29 | ret, specificReturn := fake.returnsOnCall[len(fake.argsForCall)] 30 | fake.argsForCall = append(fake.argsForCall, struct { 31 | arg1 string 32 | arg2 map[string]interface{} 33 | }{arg1, arg2}) 34 | stub := fake.Stub 35 | returns := fake.returns 36 | fake.recordInvocation("SomethingFactory", []interface{}{arg1, arg2}) 37 | fake.mutex.Unlock() 38 | if stub != nil { 39 | return stub(arg1, arg2) 40 | } 41 | if specificReturn { 42 | return ret.result1 43 | } 44 | return returns.result1 45 | } 46 | 47 | func (fake *FakeSomethingFactory) CallCount() int { 48 | fake.mutex.RLock() 49 | defer fake.mutex.RUnlock() 50 | return len(fake.argsForCall) 51 | } 52 | 53 | func (fake *FakeSomethingFactory) Calls(stub func(string, map[string]interface{}) string) { 54 | fake.mutex.Lock() 55 | defer fake.mutex.Unlock() 56 | fake.Stub = stub 57 | } 58 | 59 | func (fake *FakeSomethingFactory) ArgsForCall(i int) (string, map[string]interface{}) { 60 | fake.mutex.RLock() 61 | defer fake.mutex.RUnlock() 62 | return fake.argsForCall[i].arg1, fake.argsForCall[i].arg2 63 | } 64 | 65 | func (fake *FakeSomethingFactory) Returns(result1 string) { 66 | fake.mutex.Lock() 67 | defer fake.mutex.Unlock() 68 | fake.Stub = nil 69 | fake.returns = struct { 70 | result1 string 71 | }{result1} 72 | } 73 | 74 | func (fake *FakeSomethingFactory) ReturnsOnCall(i int, result1 string) { 75 | fake.mutex.Lock() 76 | defer fake.mutex.Unlock() 77 | fake.Stub = nil 78 | if fake.returnsOnCall == nil { 79 | fake.returnsOnCall = make(map[int]struct { 80 | result1 string 81 | }) 82 | } 83 | fake.returnsOnCall[i] = struct { 84 | result1 string 85 | }{result1} 86 | } 87 | 88 | func (fake *FakeSomethingFactory) Invocations() map[string][][]interface{} { 89 | fake.invocationsMutex.RLock() 90 | defer fake.invocationsMutex.RUnlock() 91 | fake.mutex.RLock() 92 | defer fake.mutex.RUnlock() 93 | copiedInvocations := map[string][][]interface{}{} 94 | for key, value := range fake.invocations { 95 | copiedInvocations[key] = value 96 | } 97 | return copiedInvocations 98 | } 99 | 100 | func (fake *FakeSomethingFactory) recordInvocation(key string, args []interface{}) { 101 | fake.invocationsMutex.Lock() 102 | defer fake.invocationsMutex.Unlock() 103 | if fake.invocations == nil { 104 | fake.invocations = map[string][][]interface{}{} 105 | } 106 | if fake.invocations[key] == nil { 107 | fake.invocations[key] = [][]interface{}{} 108 | } 109 | fake.invocations[key] = append(fake.invocations[key], args) 110 | } 111 | 112 | var _ fixtures.SomethingFactory = new(FakeSomethingFactory).Spy 113 | -------------------------------------------------------------------------------- /integration/testdata/expected_fake_writecloser.header.txt: -------------------------------------------------------------------------------- 1 | // some header 2 | // 3 | 4 | // Code generated by counterfeiter. DO NOT EDIT. 5 | package custom 6 | 7 | import ( 8 | "io" 9 | "sync" 10 | ) 11 | 12 | type FakeWriteCloser struct { 13 | CloseStub func() error 14 | closeMutex sync.RWMutex 15 | closeArgsForCall []struct { 16 | } 17 | closeReturns struct { 18 | result1 error 19 | } 20 | closeReturnsOnCall map[int]struct { 21 | result1 error 22 | } 23 | WriteStub func([]byte) (int, error) 24 | writeMutex sync.RWMutex 25 | writeArgsForCall []struct { 26 | arg1 []byte 27 | } 28 | writeReturns struct { 29 | result1 int 30 | result2 error 31 | } 32 | writeReturnsOnCall map[int]struct { 33 | result1 int 34 | result2 error 35 | } 36 | invocations map[string][][]interface{} 37 | invocationsMutex sync.RWMutex 38 | } 39 | 40 | func (fake *FakeWriteCloser) Close() error { 41 | fake.closeMutex.Lock() 42 | ret, specificReturn := fake.closeReturnsOnCall[len(fake.closeArgsForCall)] 43 | fake.closeArgsForCall = append(fake.closeArgsForCall, struct { 44 | }{}) 45 | stub := fake.CloseStub 46 | fakeReturns := fake.closeReturns 47 | fake.recordInvocation("Close", []interface{}{}) 48 | fake.closeMutex.Unlock() 49 | if stub != nil { 50 | return stub() 51 | } 52 | if specificReturn { 53 | return ret.result1 54 | } 55 | return fakeReturns.result1 56 | } 57 | 58 | func (fake *FakeWriteCloser) CloseCallCount() int { 59 | fake.closeMutex.RLock() 60 | defer fake.closeMutex.RUnlock() 61 | return len(fake.closeArgsForCall) 62 | } 63 | 64 | func (fake *FakeWriteCloser) CloseCalls(stub func() error) { 65 | fake.closeMutex.Lock() 66 | defer fake.closeMutex.Unlock() 67 | fake.CloseStub = stub 68 | } 69 | 70 | func (fake *FakeWriteCloser) CloseReturns(result1 error) { 71 | fake.closeMutex.Lock() 72 | defer fake.closeMutex.Unlock() 73 | fake.CloseStub = nil 74 | fake.closeReturns = struct { 75 | result1 error 76 | }{result1} 77 | } 78 | 79 | func (fake *FakeWriteCloser) CloseReturnsOnCall(i int, result1 error) { 80 | fake.closeMutex.Lock() 81 | defer fake.closeMutex.Unlock() 82 | fake.CloseStub = nil 83 | if fake.closeReturnsOnCall == nil { 84 | fake.closeReturnsOnCall = make(map[int]struct { 85 | result1 error 86 | }) 87 | } 88 | fake.closeReturnsOnCall[i] = struct { 89 | result1 error 90 | }{result1} 91 | } 92 | 93 | func (fake *FakeWriteCloser) Write(arg1 []byte) (int, error) { 94 | var arg1Copy []byte 95 | if arg1 != nil { 96 | arg1Copy = make([]byte, len(arg1)) 97 | copy(arg1Copy, arg1) 98 | } 99 | fake.writeMutex.Lock() 100 | ret, specificReturn := fake.writeReturnsOnCall[len(fake.writeArgsForCall)] 101 | fake.writeArgsForCall = append(fake.writeArgsForCall, struct { 102 | arg1 []byte 103 | }{arg1Copy}) 104 | stub := fake.WriteStub 105 | fakeReturns := fake.writeReturns 106 | fake.recordInvocation("Write", []interface{}{arg1Copy}) 107 | fake.writeMutex.Unlock() 108 | if stub != nil { 109 | return stub(arg1) 110 | } 111 | if specificReturn { 112 | return ret.result1, ret.result2 113 | } 114 | return fakeReturns.result1, fakeReturns.result2 115 | } 116 | 117 | func (fake *FakeWriteCloser) WriteCallCount() int { 118 | fake.writeMutex.RLock() 119 | defer fake.writeMutex.RUnlock() 120 | return len(fake.writeArgsForCall) 121 | } 122 | 123 | func (fake *FakeWriteCloser) WriteCalls(stub func([]byte) (int, error)) { 124 | fake.writeMutex.Lock() 125 | defer fake.writeMutex.Unlock() 126 | fake.WriteStub = stub 127 | } 128 | 129 | func (fake *FakeWriteCloser) WriteArgsForCall(i int) []byte { 130 | fake.writeMutex.RLock() 131 | defer fake.writeMutex.RUnlock() 132 | argsForCall := fake.writeArgsForCall[i] 133 | return argsForCall.arg1 134 | } 135 | 136 | func (fake *FakeWriteCloser) WriteReturns(result1 int, result2 error) { 137 | fake.writeMutex.Lock() 138 | defer fake.writeMutex.Unlock() 139 | fake.WriteStub = nil 140 | fake.writeReturns = struct { 141 | result1 int 142 | result2 error 143 | }{result1, result2} 144 | } 145 | 146 | func (fake *FakeWriteCloser) WriteReturnsOnCall(i int, result1 int, result2 error) { 147 | fake.writeMutex.Lock() 148 | defer fake.writeMutex.Unlock() 149 | fake.WriteStub = nil 150 | if fake.writeReturnsOnCall == nil { 151 | fake.writeReturnsOnCall = make(map[int]struct { 152 | result1 int 153 | result2 error 154 | }) 155 | } 156 | fake.writeReturnsOnCall[i] = struct { 157 | result1 int 158 | result2 error 159 | }{result1, result2} 160 | } 161 | 162 | func (fake *FakeWriteCloser) Invocations() map[string][][]interface{} { 163 | fake.invocationsMutex.RLock() 164 | defer fake.invocationsMutex.RUnlock() 165 | fake.closeMutex.RLock() 166 | defer fake.closeMutex.RUnlock() 167 | fake.writeMutex.RLock() 168 | defer fake.writeMutex.RUnlock() 169 | copiedInvocations := map[string][][]interface{}{} 170 | for key, value := range fake.invocations { 171 | copiedInvocations[key] = value 172 | } 173 | return copiedInvocations 174 | } 175 | 176 | func (fake *FakeWriteCloser) recordInvocation(key string, args []interface{}) { 177 | fake.invocationsMutex.Lock() 178 | defer fake.invocationsMutex.Unlock() 179 | if fake.invocations == nil { 180 | fake.invocations = map[string][][]interface{}{} 181 | } 182 | if fake.invocations[key] == nil { 183 | fake.invocations[key] = [][]interface{}{} 184 | } 185 | fake.invocations[key] = append(fake.invocations[key], args) 186 | } 187 | 188 | var _ io.WriteCloser = new(FakeWriteCloser) 189 | -------------------------------------------------------------------------------- /integration/testdata/expected_fake_writecloser.noheader.txt: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package custom 3 | 4 | import ( 5 | "io" 6 | "sync" 7 | ) 8 | 9 | type FakeWriteCloser struct { 10 | CloseStub func() error 11 | closeMutex sync.RWMutex 12 | closeArgsForCall []struct { 13 | } 14 | closeReturns struct { 15 | result1 error 16 | } 17 | closeReturnsOnCall map[int]struct { 18 | result1 error 19 | } 20 | WriteStub func([]byte) (int, error) 21 | writeMutex sync.RWMutex 22 | writeArgsForCall []struct { 23 | arg1 []byte 24 | } 25 | writeReturns struct { 26 | result1 int 27 | result2 error 28 | } 29 | writeReturnsOnCall map[int]struct { 30 | result1 int 31 | result2 error 32 | } 33 | invocations map[string][][]interface{} 34 | invocationsMutex sync.RWMutex 35 | } 36 | 37 | func (fake *FakeWriteCloser) Close() error { 38 | fake.closeMutex.Lock() 39 | ret, specificReturn := fake.closeReturnsOnCall[len(fake.closeArgsForCall)] 40 | fake.closeArgsForCall = append(fake.closeArgsForCall, struct { 41 | }{}) 42 | stub := fake.CloseStub 43 | fakeReturns := fake.closeReturns 44 | fake.recordInvocation("Close", []interface{}{}) 45 | fake.closeMutex.Unlock() 46 | if stub != nil { 47 | return stub() 48 | } 49 | if specificReturn { 50 | return ret.result1 51 | } 52 | return fakeReturns.result1 53 | } 54 | 55 | func (fake *FakeWriteCloser) CloseCallCount() int { 56 | fake.closeMutex.RLock() 57 | defer fake.closeMutex.RUnlock() 58 | return len(fake.closeArgsForCall) 59 | } 60 | 61 | func (fake *FakeWriteCloser) CloseCalls(stub func() error) { 62 | fake.closeMutex.Lock() 63 | defer fake.closeMutex.Unlock() 64 | fake.CloseStub = stub 65 | } 66 | 67 | func (fake *FakeWriteCloser) CloseReturns(result1 error) { 68 | fake.closeMutex.Lock() 69 | defer fake.closeMutex.Unlock() 70 | fake.CloseStub = nil 71 | fake.closeReturns = struct { 72 | result1 error 73 | }{result1} 74 | } 75 | 76 | func (fake *FakeWriteCloser) CloseReturnsOnCall(i int, result1 error) { 77 | fake.closeMutex.Lock() 78 | defer fake.closeMutex.Unlock() 79 | fake.CloseStub = nil 80 | if fake.closeReturnsOnCall == nil { 81 | fake.closeReturnsOnCall = make(map[int]struct { 82 | result1 error 83 | }) 84 | } 85 | fake.closeReturnsOnCall[i] = struct { 86 | result1 error 87 | }{result1} 88 | } 89 | 90 | func (fake *FakeWriteCloser) Write(arg1 []byte) (int, error) { 91 | var arg1Copy []byte 92 | if arg1 != nil { 93 | arg1Copy = make([]byte, len(arg1)) 94 | copy(arg1Copy, arg1) 95 | } 96 | fake.writeMutex.Lock() 97 | ret, specificReturn := fake.writeReturnsOnCall[len(fake.writeArgsForCall)] 98 | fake.writeArgsForCall = append(fake.writeArgsForCall, struct { 99 | arg1 []byte 100 | }{arg1Copy}) 101 | stub := fake.WriteStub 102 | fakeReturns := fake.writeReturns 103 | fake.recordInvocation("Write", []interface{}{arg1Copy}) 104 | fake.writeMutex.Unlock() 105 | if stub != nil { 106 | return stub(arg1) 107 | } 108 | if specificReturn { 109 | return ret.result1, ret.result2 110 | } 111 | return fakeReturns.result1, fakeReturns.result2 112 | } 113 | 114 | func (fake *FakeWriteCloser) WriteCallCount() int { 115 | fake.writeMutex.RLock() 116 | defer fake.writeMutex.RUnlock() 117 | return len(fake.writeArgsForCall) 118 | } 119 | 120 | func (fake *FakeWriteCloser) WriteCalls(stub func([]byte) (int, error)) { 121 | fake.writeMutex.Lock() 122 | defer fake.writeMutex.Unlock() 123 | fake.WriteStub = stub 124 | } 125 | 126 | func (fake *FakeWriteCloser) WriteArgsForCall(i int) []byte { 127 | fake.writeMutex.RLock() 128 | defer fake.writeMutex.RUnlock() 129 | argsForCall := fake.writeArgsForCall[i] 130 | return argsForCall.arg1 131 | } 132 | 133 | func (fake *FakeWriteCloser) WriteReturns(result1 int, result2 error) { 134 | fake.writeMutex.Lock() 135 | defer fake.writeMutex.Unlock() 136 | fake.WriteStub = nil 137 | fake.writeReturns = struct { 138 | result1 int 139 | result2 error 140 | }{result1, result2} 141 | } 142 | 143 | func (fake *FakeWriteCloser) WriteReturnsOnCall(i int, result1 int, result2 error) { 144 | fake.writeMutex.Lock() 145 | defer fake.writeMutex.Unlock() 146 | fake.WriteStub = nil 147 | if fake.writeReturnsOnCall == nil { 148 | fake.writeReturnsOnCall = make(map[int]struct { 149 | result1 int 150 | result2 error 151 | }) 152 | } 153 | fake.writeReturnsOnCall[i] = struct { 154 | result1 int 155 | result2 error 156 | }{result1, result2} 157 | } 158 | 159 | func (fake *FakeWriteCloser) Invocations() map[string][][]interface{} { 160 | fake.invocationsMutex.RLock() 161 | defer fake.invocationsMutex.RUnlock() 162 | fake.closeMutex.RLock() 163 | defer fake.closeMutex.RUnlock() 164 | fake.writeMutex.RLock() 165 | defer fake.writeMutex.RUnlock() 166 | copiedInvocations := map[string][][]interface{}{} 167 | for key, value := range fake.invocations { 168 | copiedInvocations[key] = value 169 | } 170 | return copiedInvocations 171 | } 172 | 173 | func (fake *FakeWriteCloser) recordInvocation(key string, args []interface{}) { 174 | fake.invocationsMutex.Lock() 175 | defer fake.invocationsMutex.Unlock() 176 | if fake.invocations == nil { 177 | fake.invocations = map[string][][]interface{}{} 178 | } 179 | if fake.invocations[key] == nil { 180 | fake.invocations[key] = [][]interface{}{} 181 | } 182 | fake.invocations[key] = append(fake.invocations[key], args) 183 | } 184 | 185 | var _ io.WriteCloser = new(FakeWriteCloser) 186 | -------------------------------------------------------------------------------- /integration/util_test.go: -------------------------------------------------------------------------------- 1 | package integration_test 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "os" 7 | "os/exec" 8 | "path/filepath" 9 | 10 | "io/fs" 11 | 12 | . "github.com/onsi/gomega" 13 | ) 14 | 15 | func WriteOutput(b []byte, file string) { 16 | _ = os.MkdirAll(filepath.Dir(file), 0700) 17 | _ = os.WriteFile(file, b, fs.FileMode(0600)) 18 | } 19 | 20 | func RunBuild(baseDir string) { 21 | cmd := exec.Command("go", "build", "./...") 22 | cmd.Dir = baseDir 23 | stdout := &bytes.Buffer{} 24 | stderr := &bytes.Buffer{} 25 | cmd.Stdout = stdout 26 | cmd.Stderr = stderr 27 | err := cmd.Run() 28 | if err != nil { 29 | fmt.Println(stdout.String()) 30 | fmt.Println(stderr.String()) 31 | } 32 | Expect(err).NotTo(HaveOccurred()) 33 | } 34 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "go/format" 7 | "io" 8 | "log" 9 | "os" 10 | "path/filepath" 11 | "runtime/debug" 12 | "runtime/pprof" 13 | 14 | "github.com/maxbrunsfeld/counterfeiter/v6/arguments" 15 | "github.com/maxbrunsfeld/counterfeiter/v6/command" 16 | "github.com/maxbrunsfeld/counterfeiter/v6/generator" 17 | ) 18 | 19 | func main() { 20 | debug.SetGCPercent(-1) 21 | 22 | if err := run(); err != nil { 23 | fail("%v", err) 24 | } 25 | } 26 | 27 | func run() error { 28 | profile := os.Getenv("COUNTERFEITER_PROFILE") != "" 29 | if profile { 30 | p, err := filepath.Abs(filepath.Join(".", "counterfeiter.profile")) 31 | if err != nil { 32 | return err 33 | } 34 | f, err := os.Create(p) 35 | if err != nil { 36 | return err 37 | } 38 | if err := pprof.StartCPUProfile(f); err != nil { 39 | return err 40 | } 41 | fmt.Printf("Profile: %s\n", p) 42 | defer pprof.StopCPUProfile() 43 | } 44 | 45 | log.SetFlags(log.Lshortfile) 46 | if !isDebug() { 47 | log.SetOutput(io.Discard) 48 | } 49 | 50 | cwd, err := os.Getwd() 51 | if err != nil { 52 | return errors.New("Error - couldn't determine current working directory") 53 | } 54 | 55 | var cache generator.Cacher 56 | var headerReader generator.FileReader 57 | if disableCache() { 58 | cache = &generator.FakeCache{} 59 | headerReader = &generator.SimpleFileReader{} 60 | } else { 61 | cache = &generator.Cache{} 62 | headerReader = &generator.CachedFileReader{} 63 | } 64 | var invocations []command.Invocation 65 | var args *arguments.ParsedArguments 66 | args, _ = arguments.New(os.Args, cwd, filepath.EvalSymlinks, os.Stat) 67 | generateMode := false 68 | if args != nil { 69 | generateMode = args.GenerateMode 70 | } 71 | if !generateMode && shouldPrintGenerateWarning() { 72 | fmt.Printf("\nWARNING: Invoking counterfeiter multiple times from \"go generate\" is slow.\nConsider using counterfeiter:generate directives to speed things up.\nSee https://github.com/maxbrunsfeld/counterfeiter#step-2b---add-counterfeitergenerate-directives for more information.\nSet the \"COUNTERFEITER_NO_GENERATE_WARNING\" environment variable to suppress this message.\n\n") 73 | } 74 | invocations, err = command.Detect(cwd, os.Args, generateMode) 75 | if err != nil { 76 | return err 77 | } 78 | 79 | for i := range invocations { 80 | a, err := arguments.New(invocations[i].Args, cwd, filepath.EvalSymlinks, os.Stat) 81 | if err != nil { 82 | return err 83 | } 84 | 85 | // If the '//counterfeiter:generate ...' line does not have a '-header' 86 | // flag, we use the one from the "global" 87 | // '//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate -header /some/header.txt' 88 | // line (which defaults to none). By doing so, we can configure the header 89 | // once per package, which is probably the most common case for adding 90 | // licence headers (i.e. all the fakes will have the same licence headers). 91 | a.HeaderFile = or(a.HeaderFile, args.HeaderFile) 92 | 93 | err = generate(cwd, a, cache, headerReader) 94 | if err != nil { 95 | return err 96 | } 97 | } 98 | return nil 99 | } 100 | 101 | func or(opts ...string) string { 102 | for _, s := range opts { 103 | if s != "" { 104 | return s 105 | } 106 | } 107 | return "" 108 | } 109 | 110 | func isDebug() bool { 111 | return os.Getenv("COUNTERFEITER_DEBUG") != "" 112 | } 113 | 114 | func disableCache() bool { 115 | return os.Getenv("COUNTERFEITER_DISABLECACHE") != "" 116 | } 117 | 118 | func shouldPrintGenerateWarning() bool { 119 | return invokedByGoGenerate() && os.Getenv("COUNTERFEITER_NO_GENERATE_WARNING") == "" 120 | } 121 | 122 | func invokedByGoGenerate() bool { 123 | return os.Getenv("DOLLAR") == "$" 124 | } 125 | 126 | func generate(workingDir string, args *arguments.ParsedArguments, cache generator.Cacher, headerReader generator.FileReader) error { 127 | if !args.Quiet { 128 | if err := reportStarting(workingDir, args.OutputPath, args.FakeImplName); err != nil { 129 | return err 130 | } 131 | } 132 | 133 | b, err := doGenerate(workingDir, args, cache, headerReader) 134 | if err != nil { 135 | return err 136 | } 137 | 138 | if err := printCode(b, args.OutputPath, args.PrintToStdOut); err != nil { 139 | return err 140 | } 141 | 142 | if !args.Quiet { 143 | fmt.Fprint(os.Stderr, "Done\n") 144 | } 145 | 146 | return nil 147 | } 148 | 149 | func doGenerate(workingDir string, args *arguments.ParsedArguments, cache generator.Cacher, headerReader generator.FileReader) ([]byte, error) { 150 | mode := generator.InterfaceOrFunction 151 | if args.GenerateInterfaceAndShimFromPackageDirectory { 152 | mode = generator.Package 153 | } 154 | 155 | headerContent, err := headerReader.Get(workingDir, args.HeaderFile) 156 | if err != nil { 157 | return nil, err 158 | } 159 | 160 | f, err := generator.NewFake(mode, args.InterfaceName, args.PackagePath, args.FakeImplName, args.DestinationPackageName, headerContent, workingDir, cache) 161 | if err != nil { 162 | return nil, err 163 | } 164 | return f.Generate(true) 165 | } 166 | 167 | func printCode(code []byte, outputPath string, printToStdOut bool) error { 168 | formattedCode, err := format.Source(code) 169 | if err != nil { 170 | return err 171 | } 172 | 173 | if printToStdOut { 174 | fmt.Println(string(formattedCode)) 175 | return nil 176 | } 177 | _ = os.MkdirAll(filepath.Dir(outputPath), 0777) 178 | file, err := os.Create(outputPath) 179 | if err != nil { 180 | return fmt.Errorf("Couldn't create fake file - %v", err) 181 | } 182 | 183 | _, err = file.Write(formattedCode) 184 | if err != nil { 185 | return fmt.Errorf("Couldn't write to fake file - %v", err) 186 | } 187 | return nil 188 | } 189 | 190 | func reportStarting(workingDir string, outputPath, fakeName string) error { 191 | rel, err := filepath.Rel(workingDir, outputPath) 192 | if err != nil { 193 | return err 194 | } 195 | 196 | msg := fmt.Sprintf("Writing `%s` to `%s`... ", fakeName, rel) 197 | if isDebug() { 198 | msg = msg + "\n" 199 | } 200 | fmt.Fprint(os.Stderr, msg) 201 | return nil 202 | } 203 | 204 | func fail(s string, args ...interface{}) { 205 | fmt.Printf("\n"+s+"\n", args...) 206 | os.Exit(1) 207 | } 208 | -------------------------------------------------------------------------------- /scripts/checkclean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | cd "$(dirname "$0")/.." 6 | echo 7 | echo "Validating that generated fakes have not changed..." 8 | echo 9 | git diff --exit-code 10 | if output=$(git status --porcelain) && [ ! -z "$output" ]; then 11 | echo "the working copy is not clean; make sure that go generate ./... has been run, and" 12 | echo "that you have committed or ignored all files before running ./scripts/ci.sh" 13 | exit 1 14 | fi 15 | -------------------------------------------------------------------------------- /scripts/ci.ps1: -------------------------------------------------------------------------------- 1 | echo "=========================" 2 | echo "windows build is starting" 3 | echo "=========================" 4 | 5 | function ExitWithCode 6 | { 7 | param 8 | ( 9 | $exitcode 10 | ) 11 | 12 | $host.SetShouldExit($exitcode) 13 | exit 14 | } 15 | 16 | echo "running go vet..." 17 | echo "-------------------" 18 | echo "" 19 | 20 | go vet ./... 21 | if ($LASTEXITCODE -ne 0) { 22 | ExitWithCode -exitcode $LASTEXITCODE 23 | } 24 | 25 | echo "installing counterfeiter..." 26 | echo "---------------------------" 27 | echo "" 28 | go install . 29 | if ($LASTEXITCODE -ne 0) { 30 | ExitWithCode -exitcode $LASTEXITCODE 31 | } 32 | set-alias counterfeiter counterfeiter.exe 33 | 34 | echo "generating fakes..." 35 | echo "-------------------" 36 | echo "" 37 | 38 | go generate ./... 39 | if ($LASTEXITCODE -ne 0) { 40 | ExitWithCode -exitcode $LASTEXITCODE 41 | } 42 | 43 | echo "ensuring generated fakes compile..." 44 | echo "-----------------------------------" 45 | echo "" 46 | go build -v ./... 47 | if ($LASTEXITCODE -ne 0) { 48 | ExitWithCode -exitcode $LASTEXITCODE 49 | } 50 | 51 | echo "running tests..." 52 | echo "----------------" 53 | echo "" 54 | go test -v -race ./... 55 | if ($LASTEXITCODE -ne 0) { 56 | ExitWithCode -exitcode $LASTEXITCODE 57 | } 58 | 59 | echo "Windows test suite was a 'sweet' success" 60 | -------------------------------------------------------------------------------- /scripts/ci.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | cd "$(dirname "$0")/.." 6 | pwd 7 | 8 | GOCOMMAND="go" 9 | # GOCOMMAND="go1.22rc1" 10 | 11 | # run ${GOCOMMAND} vet to verify everything builds and to check common issues 12 | echo 13 | echo "Running ${GOCOMMAND} vet..." 14 | echo 15 | ${GOCOMMAND} vet ./... 16 | 17 | # counterfeit all the things 18 | echo 19 | echo "Installing counterfeiter..." 20 | echo 21 | ${GOCOMMAND} install . 22 | 23 | # counterfeit all the things 24 | echo 25 | echo "Generating fakes used by tests..." 26 | echo 27 | ${GOCOMMAND} generate ./... 28 | 29 | # validate that the generated fakes match the committed fakes 30 | echo 31 | echo "Validating that generated fakes have not changed..." 32 | echo 33 | git diff --exit-code 34 | if output=$(git status --porcelain) && [ ! -z "$output" ]; then 35 | echo "the working copy is not clean; make sure that ${GOCOMMAND} generate ./... has been run, and" 36 | echo "that you have committed or ignored all files before running ./scripts/ci.sh" 37 | exit 1 38 | fi 39 | 40 | # check that the fakes compile 41 | echo 42 | echo "Ensuring generated fakes compile..." 43 | echo 44 | ${GOCOMMAND} build -v ./... 45 | 46 | # run the tests using the fakes 47 | echo 48 | echo "Running tests..." 49 | echo 50 | ${GOCOMMAND} test -race ./... 51 | 52 | echo " 53 | _______ _ _ _______ _______ _______ 54 | | || | _ | || || || | 55 | | _____|| || || || ___|| ___||_ _| 56 | | |_____ | || |___ | |___ | | 57 | |_____ || || ___|| ___| | | 58 | _____| || _ || |___ | |___ | | 59 | |_______||__| |__||_______||_______| |___| 60 | _______ __ __ ___ _______ _______ 61 | | || | | || | | || | 62 | | _____|| | | || | |_ _|| ___| 63 | | |_____ | |_| || | | | | |___ 64 | |_____ || || | | | | ___| 65 | _____| || || | | | | |___ 66 | |_______||_______||___| |___| |_______| 67 | _______ __ __ _______ _______ _______ _______ _______ 68 | | || | | || || || || || | 69 | | _____|| | | || || || ___|| _____|| _____| 70 | | |_____ | |_| || || || |___ | |_____ | |_____ 71 | |_____ || || _|| _|| ___||_____ ||_____ | 72 | _____| || || |_ | |_ | |___ _____| | _____| | 73 | |_______||_______||_______||_______||_______||_______||_______| 74 | " 75 | -------------------------------------------------------------------------------- /scripts/cleanfakes.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | cd "$(dirname "$0")/.." 6 | pwd 7 | find ./ -path '*fakes/fake*.go' -print0 | xargs -0 rm -rf 8 | -------------------------------------------------------------------------------- /scripts/counterfeiter.bat: -------------------------------------------------------------------------------- 1 | counterfeiter.exe 2 | --------------------------------------------------------------------------------