Finished adding test template generation support

This commit is contained in:
Patrick O'brien 2016-03-21 15:15:14 +10:00
parent e62b411547
commit 3b0a5e80a1
17 changed files with 101 additions and 13 deletions

View file

@ -30,16 +30,37 @@ func boilRun(cmd *cobra.Command, args []string) {
imps.standard = sqlBoilerDefaultImports.standard
imps.thirdparty = sqlBoilerDefaultImports.thirdparty
// Loop through and generate every command template (excluding skipTemplates)
for _, command := range commandNames {
imps = combineImports(imps, sqlBoilerCustomImports[command])
out = append(out, generateTemplate(command, &data))
}
err := outHandler(cmdData.OutFolder, out, &data, &imps)
err := outHandler(cmdData.OutFolder, out, &data, &imps, false)
if err != nil {
errorQuit(err)
}
// Generate the test templates for all commands
if len(testTemplates) != 0 {
var testOut [][]byte
var testImps imports
testImps.standard = sqlBoilerDefaultTestImports.standard
testImps.thirdparty = sqlBoilerDefaultTestImports.thirdparty
// Loop through and generate every command test template (excluding skipTemplates)
for _, command := range commandNames {
testImps = combineImports(testImps, sqlBoilerCustomTestImports[command])
testOut = append(testOut, generateTestTemplate(command, &data))
}
err = outHandler(cmdData.OutFolder, testOut, &data, &testImps, true)
if err != nil {
errorQuit(err)
}
}
}
}

View file

@ -14,7 +14,6 @@ type imports struct {
}
// sqlBoilerDefaultImports defines the list of default template imports.
// Imports that are defined
var sqlBoilerDefaultImports = imports{
standard: []string{
`"errors"`,
@ -26,7 +25,15 @@ var sqlBoilerDefaultImports = imports{
},
}
// sqlBoilerDefaultTestImports defines the list of default test template imports.
var sqlBoilerDefaultTestImports = imports{
standard: []string{
`"testing"`,
},
}
var sqlBoilerCustomImports map[string]imports
var sqlBoilerCustomTestImports map[string]imports
// sqlBoilerCommands points each command to its cobra.Command variable.
//

View file

@ -16,7 +16,13 @@ type PostgresCfg struct {
}
type Config struct {
Postgres PostgresCfg `toml:"postgres"`
Postgres PostgresCfg `toml:"postgres"`
// The TestPostgres object holds the configuration pointing to a test database.
// This test database is used to test all of the commands that have an accompanying
// command.testtpl file. These template files generate the go test functions.
//
// Note: These test templates will only be generated for the boil command,
// if an OutFolder is provided, and if all test config variables are present.
TestPostgres *PostgresCfg `toml:"postgres_test"`
}
@ -37,7 +43,7 @@ func LoadConfigFile(filename string) {
// If any of the test cfg variables are not present then test TestPostgres to nil
//
// As a safety precaution, set found to false if
// As a safety precaution, set TestPostgres to nil if
// the dbname is the same as the cfg dbname. This will prevent the test
// from erasing the production database tables if someone accidently
// configures the config.toml incorrectly.

View file

@ -61,7 +61,7 @@ func templater(cmd *cobra.Command, data *tplData) {
out := [][]byte{generateTemplate(cmd.Name(), data)}
imps := combineImports(sqlBoilerDefaultImports, sqlBoilerCustomImports[cmd.Name()])
err := outHandler(cmdData.OutFolder, out, data, &imps)
err := outHandler(cmdData.OutFolder, out, data, &imps, false)
if err != nil {
errorQuit(fmt.Errorf("Unable to generate the template for command %s: %s", cmd.Name(), err))
}
@ -75,12 +75,17 @@ var testHarnessFileOpen = func(filename string) (io.WriteCloser, error) {
// outHandler loops over the slice of byte slices, outputting them to either
// the OutFile if it is specified with a flag, or to Stdout if no flag is specified.
func outHandler(outFolder string, output [][]byte, data *tplData, imps *imports) error {
func outHandler(outFolder string, output [][]byte, data *tplData, imps *imports, testTemplate bool) error {
out := testHarnessStdout
var path string
if len(outFolder) != 0 {
path = outFolder + "/" + data.Table + ".go"
if testTemplate {
path = outFolder + "/" + data.Table + "_test.go"
} else {
path = outFolder + "/" + data.Table + ".go"
}
outFile, err := testHarnessFileOpen(path)
if err != nil {
errorQuit(fmt.Errorf("Unable to create output file %s: %s", path, err))

View file

@ -24,7 +24,7 @@ func TestOutHandler(t *testing.T) {
templateOutputs := [][]byte{[]byte("hello world"), []byte("patrick's dreams")}
if err := outHandler("", templateOutputs, &data, &imports{}); err != nil {
if err := outHandler("", templateOutputs, &data, &imports{}, false); err != nil {
t.Error(err)
}
@ -62,7 +62,7 @@ func TestOutHandlerFiles(t *testing.T) {
templateOutputs := [][]byte{[]byte("hello world"), []byte("patrick's dreams")}
if err := outHandler("folder", templateOutputs, &data, &imports{}); err != nil {
if err := outHandler("folder", templateOutputs, &data, &imports{}, false); err != nil {
t.Error(err)
}
if out := file.String(); out != "package patrick\n\nhello world\npatrick's dreams\n" {
@ -76,7 +76,7 @@ func TestOutHandlerFiles(t *testing.T) {
}
file = &bytes.Buffer{}
if err := outHandler("folder", templateOutputs, &data, &a1); err != nil {
if err := outHandler("folder", templateOutputs, &data, &a1, false); err != nil {
t.Error(err)
}
if out := file.String(); out != "package patrick\n\nimport \"fmt\"\nhello world\npatrick's dreams\n" {
@ -90,7 +90,7 @@ func TestOutHandlerFiles(t *testing.T) {
}
file = &bytes.Buffer{}
if err := outHandler("folder", templateOutputs, &data, &a2); err != nil {
if err := outHandler("folder", templateOutputs, &data, &a2, false); err != nil {
t.Error(err)
}
if out := file.String(); out != "package patrick\n\nimport \"github.com/spf13/cobra\"\nhello world\npatrick's dreams\n" {
@ -114,7 +114,7 @@ func TestOutHandlerFiles(t *testing.T) {
sort.Sort(ImportSorter(a3.standard))
sort.Sort(ImportSorter(a3.thirdparty))
if err := outHandler("folder", templateOutputs, &data, &a3); err != nil {
if err := outHandler("folder", templateOutputs, &data, &a3, false); err != nil {
t.Error(err)
}

View file

@ -14,7 +14,8 @@ import (
)
const (
templatesDirectory = "/cmds/templates"
templatesDirectory = "/cmds/templates"
templatesTestDirectory = "/cmds/templates_test"
)
// cmdData is used globally by all commands to access the table schema data,
@ -25,6 +26,9 @@ var cmdData *CmdData
// templates holds a slice of pointers to all templates in the templates directory.
var templates []*template.Template
// testTemplates holds a slice of pointers to all test templates in the templates directory.
var testTemplates []*template.Template
// SQLBoiler is the root app command
var SQLBoiler = &cobra.Command{
Use: "sqlboiler",
@ -89,6 +93,12 @@ func sqlBoilerPreRun(cmd *cobra.Command, args []string) {
if err != nil {
errorQuit(fmt.Errorf("Unable to initialize templates: %s", err))
}
// Initialize the test templates
testTemplates, err = initTemplates(templatesTestDirectory)
if err != nil {
errorQuit(fmt.Errorf("Unable to initialize test templates: %s", err))
}
}
// initDBDriver attempts to set the cmdData DBDriver based off the passed in

View file

@ -27,6 +27,22 @@ func generateTemplate(commandName string, data *tplData) []byte {
return output
}
// generateTestTemplate generates the test template associated to the passed in command name.
func generateTestTemplate(commandName string, data *tplData) []byte {
template := getTestTemplate(commandName)
if template == nil {
return []byte{}
}
output, err := processTemplate(template, data)
if err != nil {
errorQuit(fmt.Errorf("Unable to process the test template %s for table %s: %s", template.Name(), data.Table, err))
}
return output
}
// getTemplate returns a pointer to the template matching the passed in name
func getTemplate(name string) *template.Template {
var tpl *template.Template
@ -42,6 +58,21 @@ func getTemplate(name string) *template.Template {
return tpl
}
// getTemplate returns a pointer to the template matching the passed in name
func getTestTemplate(name string) *template.Template {
var tpl *template.Template
// Find the template that matches the passed in template name
for _, t := range testTemplates {
if t.Name() == name+".tpl" {
tpl = t
break
}
}
return tpl
}
// processTemplate takes a template and returns the output of the template execution.
func processTemplate(t *template.Template, data *tplData) ([]byte, error) {
var buf bytes.Buffer

View file

@ -0,0 +1,8 @@
{{- $tableNameSingular := titleCaseSingular .Table -}}
{{- $dbName := singular .Table -}}
{{- $tableNamePlural := titleCasePlural .Table -}}
{{- $varNamePlural := camelCasePlural .Table -}}
// {{$tableNamePlural}}All retrieves all records.
func Test{{$tableNamePlural}}All(t *testing.T) {
}

View file

View file

View file

View file

View file

View file

View file

View file

View file