Merge pull request #99 from yxxhero/add_e2e_tmpl_test

add e2e tmpl test
This commit is contained in:
Yusuke Kuoka 2022-06-05 13:23:08 +09:00 committed by GitHub
commit b986b3de9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 269 additions and 1 deletions

View File

@ -5,3 +5,12 @@ type Context struct {
basePath string
readFile func(string) ([]byte, error)
}
// SetBasePath sets the base path for the template
func (c *Context) SetBasePath(path string) {
c.basePath = path
}
func (c *Context) SetReadFile(f func(string) ([]byte, error)) {
c.readFile = f
}

View File

@ -172,6 +172,10 @@ func (c *Context) ReadFile(filename string) (string, error) {
path = filepath.Join(c.basePath, filename)
}
if c.readFile == nil {
return "", fmt.Errorf("readFile is not implemented")
}
bytes, err := c.readFile(path)
if err != nil {
return "", err

View File

@ -16,7 +16,7 @@ func TestHelmfileTemplateWithBuildCommand(t *testing.T) {
_, filename, _, _ := runtime.Caller(0)
projectRoot := filepath.Join(filepath.Dir(filename), "..", "..", "..", "..")
helmfileBin := filepath.Join(projectRoot, "helmfile")
testdataDir := "testdata"
testdataDir := "testdata/snapshot"
entries, err := os.ReadDir(testdataDir)
require.NoError(t, err)

View File

@ -0,0 +1 @@
test

View File

@ -0,0 +1,254 @@
package helmfile
import (
"bytes"
"os"
"testing"
"text/template"
"github.com/helmfile/helmfile/pkg/tmpl"
"github.com/stretchr/testify/require"
)
type tmplTestCase struct {
// envs are set in the test environment
envs map[string]string
// name of the test
name string
// tmplString is the template string to be parsed
tmplString string
// data is the data to be passed to the template
data interface{}
// wantErr is true if the template should fail to parse
wantErr bool
// output is the expected output of the template
output string
}
// setEnvs sets the environment variables for the test case
func (t *tmplTestCase) setEnvs() {
for k, v := range t.envs {
os.Setenv(k, v)
}
}
// unSetEnvs unsets the environment variables for the test case
func (t *tmplTestCase) unSetEnvs() {
for k := range t.envs {
os.Unsetenv(k)
}
}
var requireEnvTestCases = []tmplTestCase{
{
envs: map[string]string{
"TEST_VAR1": "test1",
},
name: "requiredEnvWithEnvs",
tmplString: `{{ requiredEnv "TEST_VAR1" }}`,
output: "test1",
},
{
name: "requiredEnv",
tmplString: `{{ requiredEnv "TEST_VAR" }}`,
wantErr: true,
},
}
var requiredTestCases = []tmplTestCase{
{
name: "requiredWithEmptyString",
tmplString: `{{ "" | required "required" }}`,
wantErr: true,
},
{
name: "required",
tmplString: `{{ "test" | required "required" }}`,
output: "test",
},
}
var envExecTestCases = []tmplTestCase{
{
name: "envExecWithEnvs",
tmplString: `{{ envExec (dict "testkey" "test2") "bash" (list "-c" "echo -n $testkey" ) }}`,
output: "test2",
},
{
name: "envExec",
tmplString: `{{ envExec (dict) "bash" (list "-c" "echo -n $testkey" ) }}`,
},
{
name: "envExecInvalidEnvType",
wantErr: true,
tmplString: `{{ envExec "dict" "bash" (list "-c" "echo -n $testkey" ) }}`,
},
}
var execTestCases = []tmplTestCase{
{
name: "exec",
tmplString: `{{ exec "bash" (list "-c" "echo -n $testkey" ) }}`,
},
{
name: "execWithError",
wantErr: true,
tmplString: `{{ exec "bash" (list "-c" "exit 1" ) }}`,
},
}
var readFileTestCases = []tmplTestCase{
{
name: "readFile",
tmplString: `{{ readFile "./testdata/tmpl/readfile.txt" }}`,
output: "test",
},
{
name: "readFileWithError",
tmplString: `{{ readFile "./testdata/tmpl/readfile_error.txt" }}`,
wantErr: true,
},
}
var toYamlTestCases = []tmplTestCase{
{
data: map[string]string{
"test": "test",
},
name: "toYaml",
tmplString: `{{ . | toYaml }}`,
output: "test: test\n",
},
}
var fromYamlTestCases = []tmplTestCase{
{
name: "fromYaml",
tmplString: `{{ $value := "test: test" | fromYaml }}
{{- $value.test }}`,
output: "test",
},
}
var setValueAtPathTestCases = []tmplTestCase{
{
data: map[string]interface{}{
"root": map[string]interface{}{
"testKey": map[string]interface{}{
"testKey2": "test",
},
},
},
name: "setValueAtPath",
tmplString: `{{- $newValues := . | setValueAtPath "root.testKey.testKey2" "testNewValue" }}
{{- $newValues.root.testKey.testKey2 }}`,
output: "testNewValue",
},
{
data: map[string]interface{}{
"root": "test",
},
wantErr: true,
name: "setValueAtPathWithInvalidPath",
tmplString: `{{ . | setValueAtPath "root.nokey" "testNewValue" }}`,
},
}
var getTestCases = []tmplTestCase{
{
data: map[string]interface{}{
"root": map[string]interface{}{
"testGetKey": map[string]interface{}{
"testGetKey2": "test",
},
},
},
name: "get",
tmplString: `{{- . | get "root.testGetKey.testGetKey2" "notfound" }}`,
output: "test",
},
{
data: map[string]interface{}{
"root": map[string]interface{}{
"testGetKey": map[string]interface{}{
"testGetKey2": "test",
},
},
},
name: "getNotExistWithDefault",
tmplString: `{{- . | get "root.testGetKey.testGetKey3" "notfound" }}`,
output: "notfound",
},
}
var tplTestCases = []tmplTestCase{
{
data: map[string]interface{}{
"root": "tplvalue",
},
name: "tpl",
tmplString: `{{ . | tpl "{{ .root }}" }}`,
output: "tplvalue",
},
{
data: map[string]interface{}{},
name: "tplInvalidTemplate",
wantErr: true,
tmplString: `{{ . | tpl "{{ .root }}" }}`,
},
}
// tmplTestCases are the test cases for the template tests
type tmplE2e struct {
tcs []tmplTestCase
}
// append for append testcase into tmplTestCases
func (t *tmplE2e) append(ts ...tmplTestCase) {
t.tcs = append(t.tcs, ts...)
}
// load for load testcase into tmplTestCases
func (t *tmplE2e) load() {
t.append(requireEnvTestCases...)
t.append(requiredTestCases...)
t.append(envExecTestCases...)
t.append(execTestCases...)
t.append(readFileTestCases...)
t.append(toYamlTestCases...)
t.append(fromYamlTestCases...)
t.append(setValueAtPathTestCases...)
t.append(getTestCases...)
t.append(tplTestCases...)
}
var tmplE2eTest = tmplE2e{}
// TestTmplStrings tests the template string
func TestTmplStrings(t *testing.T) {
c := &tmpl.Context{}
c.SetBasePath(".")
c.SetReadFile(os.ReadFile)
tmpl := template.New("stringTemplateTest").Funcs(c.CreateFuncMap())
tmplE2eTest.load()
for _, tc := range tmplE2eTest.tcs {
t.Run(tc.name, func(t *testing.T) {
tc.setEnvs()
defer tc.unSetEnvs()
tmpl, err := tmpl.Parse(tc.tmplString)
require.Nilf(t, err, "error parsing template: %v", err)
var tplResult bytes.Buffer
err = tmpl.Execute(&tplResult, tc.data)
if tc.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
require.Equal(t, tc.output, tplResult.String())
})
}
}