From a041b163cd8fed4e8dc293d5fb9fffe8365e3c35 Mon Sep 17 00:00:00 2001 From: Ivan Feofanov Date: Tue, 31 Jan 2023 13:20:05 +0400 Subject: [PATCH] feat: generate exported mocks with `-e` flag --- mocktail.go | 23 +- mocktail_test.go | 63 +- readme.md | 10 + syrup.go | 13 +- testdata/exported/a/a.go | 43 + testdata/exported/a/b/b.go | 14 + testdata/exported/a/c/c.go | 5 + testdata/exported/a/go.mod | 16 + testdata/exported/a/go.sum | 20 + testdata/exported/a/mock_gen.go | 3397 ++++++++++++++++++++++ testdata/exported/a/mock_gen.go.golden | 3397 ++++++++++++++++++++++ testdata/exported/a/mock_test.go | 55 + testdata/exported/b/b.go | 5 + testdata/exported/b/c/c.go | 38 + testdata/exported/b/c/mock_gen.go | 2923 +++++++++++++++++++ testdata/exported/b/c/mock_gen.go.golden | 2923 +++++++++++++++++++ testdata/exported/b/c/mock_test.go | 38 + testdata/exported/b/go.mod | 16 + testdata/exported/b/go.sum | 20 + 19 files changed, 13007 insertions(+), 12 deletions(-) create mode 100644 testdata/exported/a/a.go create mode 100644 testdata/exported/a/b/b.go create mode 100644 testdata/exported/a/c/c.go create mode 100644 testdata/exported/a/go.mod create mode 100644 testdata/exported/a/go.sum create mode 100644 testdata/exported/a/mock_gen.go create mode 100644 testdata/exported/a/mock_gen.go.golden create mode 100644 testdata/exported/a/mock_test.go create mode 100644 testdata/exported/b/b.go create mode 100644 testdata/exported/b/c/c.go create mode 100644 testdata/exported/b/c/mock_gen.go create mode 100644 testdata/exported/b/c/mock_gen.go.golden create mode 100644 testdata/exported/b/c/mock_test.go create mode 100644 testdata/exported/b/go.mod create mode 100644 testdata/exported/b/go.sum diff --git a/mocktail.go b/mocktail.go index a627689..b042a84 100644 --- a/mocktail.go +++ b/mocktail.go @@ -4,6 +4,7 @@ package main import ( "bufio" "bytes" + "flag" "fmt" "go/format" "go/importer" @@ -18,8 +19,9 @@ import ( ) const ( - srcMockFile = "mock_test.go" - outputMockFile = "mock_gen_test.go" + srcMockFile = "mock_test.go" + outputMockFile = "mock_gen_test.go" + outputExportedMockFile = "mock_gen.go" ) const contextType = "context.Context" @@ -45,6 +47,10 @@ func main() { log.Fatal("get module path", err) } + var exported bool + flag.BoolVar(&exported, "e", false, "generate exported mocks") + flag.Parse() + root := info.Dir err = os.Chdir(root) @@ -61,7 +67,7 @@ func main() { return } - err = generate(model) + err = generate(model, exported) if err != nil { log.Fatalf("generate: %v", err) } @@ -233,7 +239,7 @@ func getTypeImports(t types.Type) []string { } } -func generate(model map[string]PackageDesc) error { +func generate(model map[string]PackageDesc, exported bool) error { for fp, pkgDesc := range model { buffer := bytes.NewBufferString("") @@ -243,7 +249,7 @@ func generate(model map[string]PackageDesc) error { } for _, interfaceDesc := range pkgDesc.Interfaces { - err = writeMockBase(buffer, interfaceDesc.Name) + err = writeMockBase(buffer, interfaceDesc.Name, exported) if err != nil { return err } @@ -279,7 +285,12 @@ func generate(model map[string]PackageDesc) error { return fmt.Errorf("source: %w", err) } - out := filepath.Join(filepath.Dir(fp), outputMockFile) + fileName := outputMockFile + if exported { + fileName = outputExportedMockFile + } + + out := filepath.Join(filepath.Dir(fp), fileName) log.Println(out) diff --git a/mocktail_test.go b/mocktail_test.go index ac288db..c6968bc 100644 --- a/mocktail_test.go +++ b/mocktail_test.go @@ -12,9 +12,9 @@ import ( "github.com/stretchr/testify/require" ) -const testRoot = "./testdata/src" - func TestMocktail(t *testing.T) { + const testRoot = "./testdata/src" + if runtime.GOOS == "windows" { t.Skip(runtime.GOOS) } @@ -70,3 +70,62 @@ func TestMocktail(t *testing.T) { require.NoError(t, err) } } + +func TestMocktail_exported(t *testing.T) { + const testRoot = "./testdata/exported" + + if runtime.GOOS == "windows" { + t.Skip(runtime.GOOS) + } + + dir, errR := os.ReadDir(testRoot) + require.NoError(t, errR) + + for _, entry := range dir { + if !entry.IsDir() { + continue + } + + t.Setenv("MOCKTAIL_TEST_PATH", filepath.Join(testRoot, entry.Name())) + + output, err := exec.Command("go", "run", ".", "-e").CombinedOutput() + t.Log(string(output)) + + require.NoError(t, err) + } + + errW := filepath.WalkDir(testRoot, func(path string, d fs.DirEntry, errW error) error { + if errW != nil { + return errW + } + + if d.IsDir() || d.Name() != outputMockFile { + return nil + } + + genBytes, err := os.ReadFile(path) + require.NoError(t, err) + + goldenBytes, err := os.ReadFile(path + ".golden") + require.NoError(t, err) + + assert.Equal(t, string(goldenBytes), string(genBytes)) + + return nil + }) + require.NoError(t, errW) + + for _, entry := range dir { + if !entry.IsDir() { + continue + } + + cmd := exec.Command("go", "test", "-v", "./...") + cmd.Dir = filepath.Join(testRoot, entry.Name()) + + output, err := cmd.CombinedOutput() + t.Log(string(output)) + + require.NoError(t, err) + } +} diff --git a/readme.md b/readme.md index 142139b..02fde4b 100644 --- a/readme.md +++ b/readme.md @@ -98,6 +98,16 @@ func TestMock(t *testing.T) { } ``` +## Exportable Mocks + +If you need to use your mocks in external packages just add flag `-e`: + +```shell +mocktail -e +``` + +In this case, mock will be created in the same package but in the file `mock_gen.go`. +