Skip to content

Commit

Permalink
Add TemplateData to opts
Browse files Browse the repository at this point in the history
  • Loading branch information
Tito Lins committed Nov 25, 2020
1 parent 2435ae5 commit 65b11e6
Show file tree
Hide file tree
Showing 13 changed files with 182 additions and 11 deletions.
2 changes: 2 additions & 0 deletions gotests.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Options struct {
Template string // Name of custom template set
TemplateDir string // Path to custom template set
TemplateParams map[string]interface{} // Custom external parameters
TemplateData [][]byte // Data slice for templates
}

// A GeneratedTest contains information about a test file with generated tests.
Expand Down Expand Up @@ -124,6 +125,7 @@ func generateTest(src models.Path, files []models.Path, opt *Options) (*Generate
Template: opt.Template,
TemplateDir: opt.TemplateDir,
TemplateParams: opt.TemplateParams,
TemplateData: opt.TemplateData,
})
if err != nil {
return nil, fmt.Errorf("output.Process: %v", err)
Expand Down
24 changes: 13 additions & 11 deletions gotests/process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@ const (

// Set of options to use when generating tests.
type Options struct {
OnlyFuncs string // Regexp string for filter matches.
ExclFuncs string // Regexp string for excluding matches.
ExportedFuncs bool // Only include exported functions.
AllFuncs bool // Include all non-tested functions.
PrintInputs bool // Print function parameters as part of error messages.
Subtests bool // Print tests using Go 1.7 subtests
Parallel bool // Print tests that runs the subtests in parallel.
WriteOutput bool // Write output to test file(s).
Template string // Name of custom template set
TemplateDir string // Path to custom template set
TemplateParamsPath string // Path to custom parameters json file(s).
OnlyFuncs string // Regexp string for filter matches.
ExclFuncs string // Regexp string for excluding matches.
ExportedFuncs bool // Only include exported functions.
AllFuncs bool // Include all non-tested functions.
PrintInputs bool // Print function parameters as part of error messages.
Subtests bool // Print tests using Go 1.7 subtests
Parallel bool // Print tests that runs the subtests in parallel.
WriteOutput bool // Write output to test file(s).
Template string // Name of custom template set
TemplateDir string // Path to custom template set
TemplateParamsPath string // Path to custom parameters json file(s).
TemplateData [][]byte // Data slice for templates
}

// Generates tests for the Go files defined in args with the given options.
Expand Down Expand Up @@ -98,6 +99,7 @@ func parseOptions(out io.Writer, opt *Options) *gotests.Options {
Template: opt.Template,
TemplateDir: opt.TemplateDir,
TemplateParams: templateParams,
TemplateData: opt.TemplateData,
}
}

Expand Down
36 changes: 36 additions & 0 deletions gotests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"go/types"
"io/ioutil"
"path"
"path/filepath"
"regexp"
"runtime"
"strings"
Expand All @@ -28,6 +29,7 @@ func TestGenerateTests(t *testing.T) {
templateDir string
template string
templateParamsPath string
templateData [][]byte
}
tests := []struct {
name string
Expand Down Expand Up @@ -725,6 +727,14 @@ func TestGenerateTests(t *testing.T) {
wantNoTests: true,
wantErr: true,
},
{
name: "With templateData",
args: args{
srcPath: `testdata/test004.go`,
templateData: mustLoadExternalTemplateDir(t, "testdata/templatedata/"),
},
want: mustReadAndFormatGoFile(t, "testdata/goldens/function_with_return_value_template_data.go"),
},
}
tmp, err := ioutil.TempDir("", "gotests_test")
if err != nil {
Expand Down Expand Up @@ -752,6 +762,7 @@ func TestGenerateTests(t *testing.T) {
TemplateDir: tt.args.templateDir,
Template: tt.args.template,
TemplateParams: params,
TemplateData: tt.args.templateData,
})
if (err != nil) != tt.wantErr {
t.Errorf("%q. GenerateTests(%v) error = %v, wantErr %v", tt.name, tt.args.srcPath, err, tt.wantErr)
Expand Down Expand Up @@ -816,6 +827,31 @@ func loadExternalJsonFile(file string) (map[string]interface{}, error) {
return params, err
}

func mustLoadExternalTemplateDir(t *testing.T, dir string) [][]byte {
files, err := ioutil.ReadDir(dir)
if err != nil {
t.Fatalf("ioutil.ReadDir: %v", err)
}

templateData := make([][]byte, 0)

for _, f := range files {
filePath := filepath.Join(dir, f.Name())
templateData = append(templateData, mustLoadExternalTemplateFile(t, filePath))
}

return templateData
}

func mustLoadExternalTemplateFile(t *testing.T, file string) []byte {
buf, err := ioutil.ReadFile(file)
if err != nil {
t.Fatalf("loading external template file: %v", err)
}

return buf
}

func toSnakeCase(s string) string {
var res []rune
for _, r := range []rune(s) {
Expand Down
3 changes: 3 additions & 0 deletions internal/output/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Options struct {
Template string
TemplateDir string
TemplateParams map[string]interface{}
TemplateData [][]byte
}

func Process(head *models.Header, funcs []*models.Function, opt *Options) ([]byte, error) {
Expand All @@ -34,6 +35,8 @@ func Process(head *models.Header, funcs []*models.Function, opt *Options) ([]byt
if err != nil {
return nil, fmt.Errorf("loading custom templates of name: %v", err)
}
} else if opt != nil && opt.TemplateData != nil {
render.LoadFromData(opt.TemplateData)
}

tf, err := ioutil.TempFile("", "gotests_")
Expand Down
8 changes: 8 additions & 0 deletions internal/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ func init() {
}
}

// LoadFromData allows to load from a data slice
func LoadFromData(templateData [][]byte) {
initEmptyTmpls()
for _, d := range templateData {
tmpls = template.Must(tmpls.Parse(string(d)))
}
}

// LoadCustomTemplates allows to load in custom templates from a specified path.
func LoadCustomTemplates(dir string) error {
initEmptyTmpls()
Expand Down
17 changes: 17 additions & 0 deletions testdata/goldens/function_with_return_value_template_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package testdata

import "testing"

func TestFoo4(t *testing.T) {
testCases := []struct {
name string
want bool
}{
// TODO: Add test cases.
}
for _, tt := range testCases {
if got := Foo4(); got != tt.want {
t.Errorf("%q. Foo4() = %v, want %v", tt.name, got, tt.want)
}
}
}
1 change: 1 addition & 0 deletions testdata/templatedata/call.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{define "call"}}{{with .Receiver}}{{if not .IsStruct}}tt.{{end}}{{Receiver .}}.{{end}}{{.Name}}({{range $i, $el := .Parameters}}{{if $i}}, {{end}}{{if not .IsWriter}}tt.args.{{end}}{{Param .}}{{if .Type.IsVariadic}}...{{end}}{{end}}){{end}}
86 changes: 86 additions & 0 deletions testdata/templatedata/function.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
{{define "function"}}
{{- $f := .}}

func {{.TestName}}(t *testing.T) {
{{- with .Receiver}}
{{- if .IsStruct}}
{{- if .Fields}}
type fields struct {
{{- range .Fields}}
{{Field .}} {{.Type}}
{{- end}}
}
{{- end}}
{{- end}}
{{- end}}
{{- if .TestParameters}}
type args struct {
{{- range .TestParameters}}
{{Param .}} {{.Type}}
{{- end}}
}
{{- end}}
testCases := []struct {
name string
{{- with .Receiver}}
{{- if and .IsStruct .Fields}}
fields fields
{{- else}}
{{Receiver .}} {{.Type}}
{{- end}}
{{- end}}
{{- if .TestParameters}}
args args
{{- end}}
{{- range .TestResults}}
{{Want .}} {{.Type}}
{{- end}}
{{- if .ReturnsError}}
wantErr bool
{{- end}}
}{
// TODO: Add test cases.
}
for {{if (or .Subtests (not .IsNaked))}} _, tt := {{end}} range testCases {
{{- if .Subtests }}t.Run(tt.name, func(t *testing.T) { {{- end -}}
{{- with .Receiver}}
{{- if .IsStruct}}
{{Receiver .}} := {{if .Type.IsStar}}&{{end}}{{.Type.Value}}{
{{- range .Fields}}
{{.Name}}: tt.fields.{{Field .}},
{{- end}}
}
{{- end}}
{{- end}}
{{- range .Parameters}}
{{- if .IsWriter}}
{{Param .}} := &bytes.Buffer{}
{{- end}}
{{- end}}
{{- if and (not .OnlyReturnsError) (not .OnlyReturnsOneValue) }}
{{template "results" $f}} {{template "call" $f}}
{{- end}}
{{- if .ReturnsError}}
if {{if .OnlyReturnsError}} err := {{template "call" $f}}; {{end}} (err != nil) != tt.wantErr {
t.Errorf("{{template "message" $f}} error = %v, wantErr %v", {{template "inputs" $f}} err, tt.wantErr)
{{- if .TestResults}}
{{if .Subtests }}return{{else}}continue{{end}}
{{- end}}
}
{{- end}}
{{- range .TestResults}}
{{- if .IsWriter}}
if {{Got .}} := {{Param .}}.String(); {{Got .}} != tt.{{Want .}} {
{{- else if .IsBasicType}}
if {{if $f.OnlyReturnsOneValue}}{{Got .}} := {{template "inline" $f}}; {{end}} {{Got .}} != tt.{{Want .}} {
{{- else}}
if {{if $f.OnlyReturnsOneValue}}{{Got .}} := {{template "inline" $f}}; {{end}} !reflect.DeepEqual({{Got .}}, tt.{{Want .}}) {
{{- end}}
t.Errorf("{{template "message" $f}} {{if $f.ReturnsMultiple}}{{Got .}} {{end}}= %v, want %v", {{template "inputs" $f}} {{Got .}}, tt.{{Want .}})
}
{{- end}}
{{- if .Subtests }} }) {{- end -}}
}
}

{{end}}
10 changes: 10 additions & 0 deletions testdata/templatedata/header.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{{define "header"}}
{{range .Comments}}{{.}}
{{end}}
package {{.Package}}

import (
{{range .Imports}}{{.Name}} {{.Path}}
{{end}}
)
{{end}}
1 change: 1 addition & 0 deletions testdata/templatedata/inline.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{define "inline"}} {{template "call" .}} {{end}}
1 change: 1 addition & 0 deletions testdata/templatedata/inputs.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{define "inputs"}}{{$f := .}}{{if not .Subtests}}tt.name, {{end}}{{if $f.PrintInputs}}{{range $f.Parameters}}tt.args.{{Param .}}, {{end}}{{end}}{{end}}
3 changes: 3 additions & 0 deletions testdata/templatedata/message.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{define "message" -}}
{{if not .Subtests}}%q. {{end}}{{with .Receiver}}{{.Type.Value}}.{{end}}{{.Name}}({{if .PrintInputs}}{{range $i, $el := .Parameters}}{{if $i}}, {{end}}%v{{end}}{{end}})
{{- end}}
1 change: 1 addition & 0 deletions testdata/templatedata/results.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{define "results"}} {{range $i, $el := .Results}}{{if $i}}, {{end}}{{Got .}}{{end}}{{if .ReturnsError}}, err{{end}} {{if or .Results .ReturnsError}} := {{end}} {{end}}

0 comments on commit 65b11e6

Please sign in to comment.