diff --git a/template_nest.go b/template_nest.go index cfdde42..e484e39 100644 --- a/template_nest.go +++ b/template_nest.go @@ -111,12 +111,12 @@ func New(opts Option) (*TemplateNest, error) { func (nest *TemplateNest) index(filePath string) (TemplateFileIndex, error) { contents, err := ioutil.ReadFile(filePath) if err != nil { - return TemplateFileIndex{}, fmt.Errorf("Error reading file (`%s`): %w", filePath, err) + return TemplateFileIndex{}, fmt.Errorf("error reading file (`%s`): %w", filePath, err) } // Capture last modified time fileInfo, err := os.Stat(filePath) if err != nil { - return TemplateFileIndex{}, fmt.Errorf("Error getting file (`%s`) info: %w", filePath, err) + return TemplateFileIndex{}, fmt.Errorf("error getting file (`%s`) info: %w", filePath, err) } variableNames := make(map[string]struct{}) @@ -205,12 +205,16 @@ func (nest *TemplateNest) Render(toRender interface{}) (string, error) { case Hash: tLabel, ok := v[nest.option.NameLabel] if !ok { - return "", fmt.Errorf("missing template label: %s", nest.option.NameLabel) + return "", fmt.Errorf( + "encountered hash with no name label (name label: `%s`)", nest.option.NameLabel, + ) } tName, ok := tLabel.(string) if !ok { - return "", fmt.Errorf("invalid template label: %+v", tLabel) + return "", fmt.Errorf( + "encountered hash with invalid name label type: %+v", tLabel, + ) } tFile := nest.getTemplateFilePath(tName) @@ -225,11 +229,24 @@ func (nest *TemplateNest) Render(toRender interface{}) (string, error) { if !exists || fileInfo.ModTime().After(tIndex.LastModified) { newIndex, err := nest.index(tFile) if err != nil { - return "", fmt.Errorf("File index failed: %w", err) + return "", fmt.Errorf("file index failed: %w", err) } tIndex = newIndex } + if nest.option.DieOnBadParams { + for k, _ := range v { + // If a variable in template hash is not present in template + // file and it's not the template label then it's a bad param. + _, exists := tIndex.VariableNames[k] + if !exists && k != nest.option.NameLabel { + return "", fmt.Errorf( + "bad params in template hash, variable not present in template file: `%s`", k, + ) + } + } + } + rendered := tIndex.Contents for i := len(tIndex.Variables) - 1; i >= 0; i-- { variable := tIndex.Variables[i] @@ -257,6 +274,6 @@ func (nest *TemplateNest) Render(toRender interface{}) (string, error) { return strings.TrimSpace(rendered), nil default: - return "", fmt.Errorf("Unsupported template type: %+v", v) + return "", fmt.Errorf("unsupported template hash value type: %+v", v) } } diff --git a/tests/02_die_on_bad_params_test.go b/tests/02_die_on_bad_params_test.go new file mode 100644 index 0000000..a35bf9a --- /dev/null +++ b/tests/02_die_on_bad_params_test.go @@ -0,0 +1,72 @@ +package tests + +import ( + "git.virtual.blue/tomgracey/template-nest-go" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestDieOnPageWithBadParams(t *testing.T) { + nest, err := templatenest.New(templatenest.Option{ + TemplateDir: "templates", + DieOnBadParams: true, + }) + if err != nil { + t.Fatalf("Failed to initialize TemplateNest: %+v", err) + } + + page := templatenest.Hash{ + "TEMPLATE": "00-simple-page", + "variable": "Simple Variable", + "simple_component": "Simple Component", + "a_bad_param": "Bad Param", + } + + _, err = nest.Render(page) + if assert.NotNil(t, err) { + expected := "bad params in template hash, variable not present in template file: `a_bad_param`" + assert.Equal(t, expected, err.Error()) + } +} + +func TestDieOnPageWithBadParams01(t *testing.T) { + nest, err := templatenest.New(templatenest.Option{ + TemplateDir: "templates", + DieOnBadParams: true, + }) + if err != nil { + t.Fatalf("Failed to initialize TemplateNest: %+v", err) + } + + page := templatenest.Hash{ + "TEMPLATE": "00-simple-page", + "variable": "Simple Variable", + "a_bad_param": "Bad Param", + } + + _, err = nest.Render(page) + if assert.NotNil(t, err) { + expected := "bad params in template hash, variable not present in template file: `a_bad_param`" + assert.Equal(t, expected, err.Error()) + } +} + +func TestLiveOnPageWithBadParams(t *testing.T) { + nest, err := templatenest.New(templatenest.Option{ + TemplateDir: "templates", + DieOnBadParams: false, + }) + if err != nil { + t.Fatalf("Failed to initialize TemplateNest: %+v", err) + } + + page := templatenest.Hash{ + "TEMPLATE": "00-simple-page", + "variable": "Simple Variable", + "simple_component": "Simple Component", + "a_bad_param": "Bad Param", + } + + _, err = nest.Render(page) + assert.Nil(t, err) +}