Skip to content

Commit

Permalink
Merge pull request #625 from LandonTClipp/issue_623
Browse files Browse the repository at this point in the history
Add `InterfaceDirRelative` template variable
  • Loading branch information
LandonTClipp committed May 14, 2023
2 parents 05d270e + 66f7b66 commit f9586f1
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 18 deletions.
3 changes: 2 additions & 1 deletion docs/configuration.md
Expand Up @@ -96,7 +96,8 @@ These are the config options when using the `packages` config option. Use of the

| name | description |
|------|-------------|
| InterfaceDir | The path of the original interface being mocked. This can be used as <br>`#!yaml dir: "{{.InterfaceDir}}"` to place your mocks adjacent to the original interface. This should not be used for external interfaces. |
| InterfaceDir | The directory path of the original interface being mocked. This can be used as <br>`#!yaml dir: "{{.InterfaceDir}}"` to place your mocks adjacent to the original interface. This should not be used for external interfaces. |
| InterfaceDirRelative | The directory path of the original interface being mocked, relative to the current working directory. If the path cannot be made relative to the current working directory, this variable will be set equal to `PackagePath` |
| InterfaceName | The name of the original interface being mocked |
| InterfaceNameCamel | Converts a string `interface_name` to `InterfaceName` |
| InterfaceNameLowerCamel | Converts `InterfaceName` to `interfaceName` |
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -3,7 +3,7 @@ module github.com/vektra/mockery/v2
go 1.19

require (
github.com/chigopher/pathlib v0.13.0
github.com/chigopher/pathlib v1.0.0
github.com/iancoleman/strcase v0.2.0
github.com/jinzhu/copier v0.3.5
github.com/mitchellh/go-homedir v1.1.0
Expand Down
2 changes: 2 additions & 0 deletions go.work.sum
Expand Up @@ -294,6 +294,8 @@ github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnd
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chigopher/pathlib v1.0.0 h1:SbsCrFX4vDf4M2d8mT/RTzuVlKOjTKoPHK0HidsQFak=
github.com/chigopher/pathlib v1.0.0/go.mod h1:3+YPPV21mU9vyw8Mjp+F33CyCfE6iOzinpiqBcccv7I=
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8=
Expand Down
25 changes: 22 additions & 3 deletions pkg/outputter.go
Expand Up @@ -144,9 +144,29 @@ func parseConfigTemplates(ctx context.Context, c *config.Config, iface *Interfac
} else {
mock = "mock"
}

workingDir, err := os.Getwd()
if err != nil {
return fmt.Errorf("get working directory: %w", err)
}
var interfaceDirRelative string
interfaceDir := pathlib.NewPath(iface.FileName).Parent()
interfaceDirRelativePath, err := interfaceDir.RelativeToStr(workingDir)
if errors.Is(err, pathlib.ErrRelativeTo) {
log.Debug().
Stringer("interface-dir", interfaceDir).
Str("working-dir", workingDir).
Msg("can't make interfaceDir relative to working dir. Setting InterfaceDirRelative to package path.")

interfaceDirRelative = iface.Pkg.Path()
} else {
interfaceDirRelative = interfaceDirRelativePath.String()
}

// data is the struct sent to the template parser
data := struct {
InterfaceDir string
InterfaceDirRelative string
InterfaceName string
InterfaceNameCamel string
InterfaceNameLowerCamel string
Expand All @@ -157,6 +177,7 @@ func parseConfigTemplates(ctx context.Context, c *config.Config, iface *Interfac
PackagePath string
}{
InterfaceDir: filepath.Dir(iface.FileName),
InterfaceDirRelative: interfaceDirRelative,
InterfaceName: iface.Name,
InterfaceNameCamel: strcase.ToCamel(iface.Name),
InterfaceNameLowerCamel: strcase.ToLowerCamel(iface.Name),
Expand All @@ -166,8 +187,6 @@ func parseConfigTemplates(ctx context.Context, c *config.Config, iface *Interfac
PackageName: iface.Pkg.Name(),
PackagePath: iface.Pkg.Path(),
}
templ := template.New("interface-template")

// These are the config options that we allow
// to be parsed by the templater. The keys are
// just labels we're using for logs/errors
Expand Down Expand Up @@ -197,7 +216,7 @@ func parseConfigTemplates(ctx context.Context, c *config.Config, iface *Interfac
for name, attributePointer := range templateMap {
oldVal := *attributePointer

attributeTempl, err := templ.Parse(*attributePointer)
attributeTempl, err := template.New("interface-template").Parse(*attributePointer)
if err != nil {
return fmt.Errorf("failed to parse %s template: %w", name, err)
}
Expand Down
62 changes: 49 additions & 13 deletions pkg/outputter_test.go
Expand Up @@ -4,10 +4,12 @@ import (
"context"
"errors"
"fmt"
"os"
"reflect"
"testing"

"github.com/chigopher/pathlib"
"github.com/davecgh/go-spew/spew"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
pkgMocks "github.com/vektra/mockery/v2/mocks/github.com/vektra/mockery/v2/pkg"
Expand Down Expand Up @@ -65,6 +67,15 @@ func TestUnderscoreCaseName(t *testing.T) {
}

func Test_parseConfigTemplates(t *testing.T) {
mockPkg := func(t *testing.T) *pkgMocks.TypesPackage {
m := pkgMocks.NewTypesPackage(t)
m.EXPECT().Path().Return("github.com/user/project/package")
m.EXPECT().Name().Return("packageName")
return m
}
cwd, err := os.Getwd()
require.NoError(t, err)

type args struct {
c *config.Config
iface *Interface
Expand Down Expand Up @@ -96,19 +107,48 @@ func Test_parseConfigTemplates(t *testing.T) {
FileName: "path/to/foobar.go",
},
},
pkg: func(t *testing.T) *pkgMocks.TypesPackage {
m := pkgMocks.NewTypesPackage(t)
m.EXPECT().Path().Return("github.com/user/project/package")
m.EXPECT().Name().Return("packageName")
return m
},
pkg: mockPkg,
want: &config.Config{
Dir: "path/to/github.com/user/project/package",
FileName: "FooBar_FooBar_foo_bar.go",
MockName: "fooBar",
Outpkg: "packageName",
},
},
{
name: "InterfaceDirRelative in current working directory",
args: args{
c: &config.Config{
Dir: "{{.InterfaceDirRelative}}",
},

iface: &Interface{
Name: "FooBar",
FileName: cwd + "/path/to/foobar.go",
},
},
pkg: mockPkg,
want: &config.Config{
Dir: "path/to",
},
},
{
name: "InterfaceDirRelative not in current working directory",
args: args{
c: &config.Config{
Dir: "mocks/{{.InterfaceDirRelative}}",
},

iface: &Interface{
Name: "FooBar",
FileName: "/path/to/foobar.go",
},
},
pkg: mockPkg,
want: &config.Config{
Dir: "mocks/github.com/user/project/package",
},
},
{
name: "infinite loop in template variables",
args: args{
Expand All @@ -124,12 +164,7 @@ func Test_parseConfigTemplates(t *testing.T) {
FileName: "path/to/foobar.go",
},
},
pkg: func(t *testing.T) *pkgMocks.TypesPackage {
m := pkgMocks.NewTypesPackage(t)
m.EXPECT().Path().Return("github.com/user/project/package")
m.EXPECT().Name().Return("packageName")
return m
},
pkg: mockPkg,
disableWantCheck: true,
wantErr: ErrInfiniteLoop,
},
Expand All @@ -143,7 +178,7 @@ func Test_parseConfigTemplates(t *testing.T) {
t.Errorf("parseConfigTemplates() error = %v, wantErr %v", err, tt.wantErr)
}
if !tt.disableWantCheck && !reflect.DeepEqual(tt.args.c, tt.want) {
t.Errorf("*config.Config = %v, want %v", tt.args.c, tt.want)
t.Errorf("*config.Config = %s\n, want %+v", spew.Sdump(tt.args.c), spew.Sdump(tt.want))
}
})
}
Expand Down Expand Up @@ -173,6 +208,7 @@ func TestOutputter_Generate(t *testing.T) {
tt.fields.config.Dir = t.TempDir()
tt.fields.config.MockName = "Mock{{.InterfaceName}}"
tt.fields.config.FileName = "mock_{{.InterfaceName}}.go"
tt.fields.config.Outpkg = "{{.PackageName}}"

t.Run(tt.name, func(t *testing.T) {
m := &Outputter{
Expand Down

0 comments on commit f9586f1

Please sign in to comment.