Skip to content

Commit

Permalink
Merge pull request #153 from hoegaarden/headers
Browse files Browse the repository at this point in the history
Allow adding headers to generated fakes
  • Loading branch information
joefitzgerald authored May 1, 2020
2 parents a447b66 + 9f0dd8a commit dccb639
Show file tree
Hide file tree
Showing 25 changed files with 843 additions and 59 deletions.
8 changes: 8 additions & 0 deletions arguments/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ func New(args []string, workingDir string, evaler Evaler, stater Stater) (*Parse
false,
"Identify all //counterfeiter:generate directives in the current working directory and generate fakes for them",
)
headerFlag := fs.String(
"header",
"",
"A path to a file that should be used as a header for the generated fake",
)
helpFlag := fs.Bool(
"help",
false,
Expand All @@ -62,6 +67,7 @@ func New(args []string, workingDir string, evaler Evaler, stater Stater) (*Parse
PrintToStdOut: any(args, "-"),
GenerateInterfaceAndShimFromPackageDirectory: packageMode,
GenerateMode: *generateFlag,
HeaderFile: *headerFlag,
}
if *generateFlag {
return result, nil
Expand Down Expand Up @@ -193,6 +199,8 @@ type ParsedArguments struct {

PrintToStdOut bool
GenerateMode bool

HeaderFile string
}

func fixupUnexportedNames(interfaceName string) string {
Expand Down
12 changes: 12 additions & 0 deletions arguments/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,18 @@ func testParsingArguments(t *testing.T, when spec.G, it spec.S) {
Expect(parsedArgs.DestinationPackageName).To(Equal("fake_command_runnerfakes"))
})
})

when("when '-header' is used", func() {
it.Before(func() {
args = []string{"counterfeiter", "-header", "some/header/file", "some.interface"}
justBefore()
})

it("sets the HeaderFile attriburte on the parsedArgs struct", func() {
Expect(parsedArgs.HeaderFile).To(Equal("some/header/file"))
Expect(err).NotTo(HaveOccurred())
})
})
}

func fakeFileInfo(filename string, isDir bool) os.FileInfo {
Expand Down
23 changes: 23 additions & 0 deletions arguments/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const usage = `
USAGE
counterfeiter
[-generate>] [-o <output-path>] [-p] [--fake-name <fake-name>]
[-header <header-file>]
[<source-path>] <interface> [-]
ARGUMENTS
Expand Down Expand Up @@ -75,6 +76,28 @@ OPTIONS
# now generate fake in ${PWD}/osshim/os_fake (fake_os.go)
go generate osshim/...
-header
Path to the file which should be used as a header for all generated fakes.
By default, no special header is used.
This is useful to e.g. add a licence header to every fake.
If the generate mode is used and both the "go:generate" and the
"counterfeiter:generate" specify a header file, the header file from the
"counterfeiter:generate" line takes precedence.
example:
# having the following code in a package ...
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -header ./generic.go.txt -generate
//counterfeiter:generate -header ./specific.go.txt . MyInterface
//counterfeiter:generate . MyOtherInterface
//counterfeiter:generate . MyThirdInterface
# ... generating the fakes ...
go generate .
# writes "FakeMyInterface" with ./specific.go.txt as a header
# writes "FakeMyOtherInterface" & "FakeMyThirdInterface" with ./generic.go.txt as a header
--fake-name
Name of the fake struct to generate. By default, 'Fake' will
be prepended to the name of the original interface. (ignored in
Expand Down
59 changes: 32 additions & 27 deletions benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/maxbrunsfeld/counterfeiter/v6/generator"
)

func BenchmarkWithoutCache(b *testing.B) {
func BenchmarkDoGenerate(b *testing.B) {
b.StopTimer()
workingDir, err := filepath.Abs(filepath.Join(".", "fixtures"))
if err != nil {
Expand All @@ -29,35 +29,40 @@ func BenchmarkWithoutCache(b *testing.B) {
PrintToStdOut: false,
}

cache := &generator.FakeCache{}
b.StartTimer()
for i := 0; i < b.N; i++ {
doGenerate(workingDir, args, cache)
caches := map[string]struct {
cache generator.Cacher
headerReader generator.FileReader
}{
"without caches": {
cache: &generator.FakeCache{},
headerReader: &generator.SimpleFileReader{},
},
"with caches": {
cache: &generator.Cache{},
headerReader: &generator.CachedFileReader{},
},
}
}

func BenchmarkWithCache(b *testing.B) {
b.StopTimer()
workingDir, err := filepath.Abs(filepath.Join(".", "fixtures"))
if err != nil {
b.Fatal(err)
}
log.SetOutput(ioutil.Discard)

args := &arguments.ParsedArguments{
GenerateInterfaceAndShimFromPackageDirectory: false,
SourcePackageDir: workingDir,
PackagePath: workingDir,
OutputPath: filepath.Join(workingDir, "fixturesfakes", "fake_something.go"),
DestinationPackageName: "fixturesfakes",
InterfaceName: "Something",
FakeImplName: "FakeSomething",
PrintToStdOut: false,
headers := map[string]string{
"without headerfile": "",
"with headerfile": "headers/default.header.go.txt",
}

cache := &generator.Cache{}
b.StartTimer()
for i := 0; i < b.N; i++ {
doGenerate(workingDir, args, cache)
for name, caches := range caches {
caches := caches
b.Run(name, func(b *testing.B) {
for name, headerFile := range headers {
headerFile := headerFile
b.Run(name, func(b *testing.B) {
args.HeaderFile = headerFile
b.StartTimer()
for i := 0; i < b.N; i++ {
if _, err := doGenerate(workingDir, args, caches.cache, caches.headerReader); err != nil {
b.Errorf("Expected doGenerate not to return an error, got %v", err)
}
}
}) // b.Run for headerFiles
}
}) // b.Run for caches
}
}
3 changes: 3 additions & 0 deletions fixtures/headers/default.header.go.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This is a default header for all the fakes in this package
//

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions fixtures/headers/defaultheader/header.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package defaultheader // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/headers/defaultheader"

//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -header ../default.header.go.txt -generate

//counterfeiter:generate . HeaderDefault
type HeaderDefault interface{}

//counterfeiter:generate -header ../specific.header.go.txt . HeaderSpecific
type HeaderSpecific interface{}
9 changes: 9 additions & 0 deletions fixtures/headers/nodefaultheader/headers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package nodefaultheader // import "github.com/maxbrunsfeld/counterfeiter/v6/fixtures/headers/nodefaultheader"

//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate

//counterfeiter:generate . HeaderDefault
type HeaderDefault interface{}

//counterfeiter:generate -header ../specific.header.go.txt . HeaderSpecific
type HeaderSpecific interface{}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions fixtures/headers/specific.header.go.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// This is a specific header for only some of the fakes in this package
//

4 changes: 3 additions & 1 deletion generator/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type Fake struct {
Imports Imports
Methods []Method
Function Method
Header string
}

// Method is a method of the interface.
Expand All @@ -48,14 +49,15 @@ type Method struct {

// NewFake returns a Fake that loads the package and finds the interface or the
// function.
func NewFake(fakeMode FakeMode, targetName string, packagePath string, fakeName string, destinationPackage string, workingDir string, cache Cacher) (*Fake, error) {
func NewFake(fakeMode FakeMode, targetName string, packagePath string, fakeName string, destinationPackage string, headerContent string, workingDir string, cache Cacher) (*Fake, error) {
f := &Fake{
TargetName: targetName,
TargetPackage: packagePath,
Name: fakeName,
Mode: fakeMode,
DestinationPackage: destinationPackage,
Imports: newImports(),
Header: headerContent,
}

f.Imports.Add("sync", "sync")
Expand Down
Loading

0 comments on commit dccb639

Please sign in to comment.