package template import ( "fmt" "testing" "github.com/stretchr/testify/require" ) func TestGenerate(t *testing.T) { type testCase struct { template string additionalOpts []Opt data interface{} expected string expectErr bool } tests := map[string]testCase{ "template without arguments": { template: "this is a template", data: nil, expected: "this is a template", expectErr: false, }, "template with arguments but no data": { template: "this is a {{.String}}", data: nil, expected: "this is a ", expectErr: false, }, "template with arguments": { template: "this is a {{.String}}", data: struct { String string }{ String: "foobar", }, expected: "this is a foobar", expectErr: false, }, "template with builtin functions": { template: `{{.String | truncate 10}} {{.String | uppercase}} {{.String | lowercase}} {{.String | replace " " "."}} {{.String | sha256}} {{.String | base64}} {{.String | truncate_sha256 20}}`, data: struct { String string }{ String: "Some string with Multiple Capitals LETTERS", }, expected: `Some strin SOME STRING WITH MULTIPLE CAPITALS LETTERS some string with multiple capitals letters Some.string.with.Multiple.Capitals.LETTERS da9872dd96609c72897defa11fe81017a62c3f44339d9d3b43fe37540ede3601 U29tZSBzdHJpbmcgd2l0aCBNdWx0aXBsZSBDYXBpdGFscyBMRVRURVJT Some string 6841cf80`, expectErr: false, }, "custom function": { template: "{{foo}}", additionalOpts: []Opt{ Function("foo", func() string { return "custom-foo" }), }, expected: "custom-foo", expectErr: false, }, } for name, test := range tests { t.Run(name, func(t *testing.T) { opts := append(test.additionalOpts, Template(test.template)) st, err := NewTemplate(opts...) require.NoError(t, err) actual, err := st.Generate(test.data) if test.expectErr && err == nil { t.Fatalf("err expected, got nil") } if !test.expectErr && err != nil { t.Fatalf("no error expected, got: %s", err) } require.Equal(t, test.expected, actual) }) } t.Run("random", func(t *testing.T) { for i := 1; i < 100; i++ { st, err := NewTemplate( Template(fmt.Sprintf("{{random %d}}", i)), ) require.NoError(t, err) actual, err := st.Generate(nil) require.NoError(t, err) require.Regexp(t, fmt.Sprintf("^[a-zA-Z0-9]{%d}$", i), actual) } }) t.Run("unix_time", func(t *testing.T) { for i := 0; i < 100; i++ { st, err := NewTemplate( Template("{{unix_time}}"), ) require.NoError(t, err) actual, err := st.Generate(nil) require.NoError(t, err) require.Regexp(t, "^[0-9]+$", actual) } }) t.Run("unix_time_millis", func(t *testing.T) { for i := 0; i < 100; i++ { st, err := NewTemplate( Template("{{unix_time_millis}}"), ) require.NoError(t, err) actual, err := st.Generate(nil) require.NoError(t, err) require.Regexp(t, "^[0-9]+$", actual) } }) t.Run("timestamp", func(t *testing.T) { for i := 0; i < 100; i++ { st, err := NewTemplate( Template(`{{timestamp "2006-01-02T15:04:05.000Z"}}`), ) require.NoError(t, err) actual, err := st.Generate(nil) require.NoError(t, err) require.Regexp(t, `^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$`, actual) } }) } func TestBadConstructorArguments(t *testing.T) { type testCase struct { opts []Opt } tests := map[string]testCase{ "missing template": { opts: nil, }, "missing custom function name": { opts: []Opt{ Template("foo bar"), Function("", func() string { return "foo" }), }, }, "missing custom function": { opts: []Opt{ Template("foo bar"), Function("foo", nil), }, }, "bad template": { opts: []Opt{ Template("{{.String"), }, }, } for name, test := range tests { t.Run(name, func(t *testing.T) { st, err := NewTemplate(test.opts...) require.Error(t, err) str, err := st.Generate(nil) require.Error(t, err) require.Equal(t, "", str) }) } t.Run("erroring custom function", func(t *testing.T) { st, err := NewTemplate( Template("{{foo}}"), Function("foo", func() (string, error) { return "", fmt.Errorf("an error!") }), ) require.NoError(t, err) str, err := st.Generate(nil) require.Error(t, err) require.Equal(t, "", str) }) }