package template import ( "bytes" "reflect" "testing" "text/template" ) func TestBuildFuncMapEntriesAreFunctions(t *testing.T) { fm := BuildFuncMap() if len(fm) < 100 { t.Errorf("unexpectedly small func map: %d", len(fm)) } for name, fn := range fm { if reflect.TypeOf(fn).Kind() != reflect.Func { t.Errorf("%s is not a function", name) } } for _, name := range []string{"toSnakeCase", "sqlToGo", "filterTables", "toJSON", "enumerate", "get", "sortTablesByName", "dict", "seq"} { if _, ok := fm[name]; !ok { t.Errorf("missing %s", name) } } // Must be accepted by text/template (valid names and signatures). if _, err := template.New("x").Funcs(fm).Parse("ok"); err != nil { t.Fatalf("funcmap rejected by text/template: %v", err) } } func TestBuildFuncMapRender(t *testing.T) { tests := []struct { name, tmpl, want string }{ {"add", `{{add 2 3}}`, "5"}, {"sub", `{{sub 5 3}}`, "2"}, {"mul", `{{mul 2 3}}`, "6"}, {"div", `{{div 6 3}}`, "2"}, {"div zero", `{{div 6 0}}`, "0"}, {"mod", `{{mod 7 3}}`, "1"}, {"mod zero", `{{mod 7 0}}`, "0"}, {"default nil", `{{default "d" .Missing}}`, "d"}, {"default set", `{{default "d" "v"}}`, "v"}, {"dict", `{{get (dict "a" 1) "a"}}`, "1"}, {"dict odd", `{{if dict "a"}}set{{else}}nil{{end}}`, "nil"}, {"dict non-string key", `{{if dict 1 2}}set{{else}}nil{{end}}`, "nil"}, {"list", `{{len (list 1 2 3)}}`, "3"}, {"seq", `{{range seq 1 3}}{{.}}{{end}}`, "123"}, {"seq reversed", `{{len (seq 3 1)}}`, "0"}, {"snake", `{{toSnakeCase "UserName"}}`, "user_name"}, {"pluralize", `{{pluralize "category"}}`, "categories"}, {"sqlToGo", `{{sqlToGo "integer" true}}`, ""}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tpl, err := template.New("t").Funcs(BuildFuncMap()).Parse(tt.tmpl) if err != nil { t.Fatalf("parse: %v", err) } var buf bytes.Buffer if err := tpl.Execute(&buf, map[string]interface{}{}); err != nil { t.Fatalf("execute: %v", err) } if tt.name == "sqlToGo" { if buf.Len() == 0 { t.Error("sqlToGo rendered nothing") } return } if buf.String() != tt.want { t.Errorf("got %q, want %q", buf.String(), tt.want) } }) } }