feat: add tmpl function `required` (#1188)
Co-authored-by: Raymond Liu (RD-TW) <raymond_liu@trend.com.tw>
This commit is contained in:
parent
870cc03c70
commit
7d11f5dedc
|
|
@ -26,6 +26,7 @@ func (c *Context) createFuncMap() template.FuncMap {
|
||||||
"get": get,
|
"get": get,
|
||||||
"getOrNil": getOrNil,
|
"getOrNil": getOrNil,
|
||||||
"tpl": c.Tpl,
|
"tpl": c.Tpl,
|
||||||
|
"required": Required,
|
||||||
}
|
}
|
||||||
if c.preRender {
|
if c.preRender {
|
||||||
// disable potential side-effect template calls
|
// disable potential side-effect template calls
|
||||||
|
|
@ -242,3 +243,15 @@ func RequiredEnv(name string) (string, error) {
|
||||||
|
|
||||||
return "", fmt.Errorf("required env var `%s` is not set", name)
|
return "", fmt.Errorf("required env var `%s` is not set", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Required(warn string, val interface{}) (interface{}, error) {
|
||||||
|
if val == nil {
|
||||||
|
return nil, fmt.Errorf(warn)
|
||||||
|
} else if _, ok := val.(string); ok {
|
||||||
|
if val == "" {
|
||||||
|
return nil, fmt.Errorf(warn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return val, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,3 +133,47 @@ func TestTpl(t *testing.T) {
|
||||||
t.Errorf("unexpected result: expected=%v, actual=%v", expected, actual)
|
t.Errorf("unexpected result: expected=%v, actual=%v", expected, actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRequired(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
warn string
|
||||||
|
val interface{}
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want interface{}
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "required val is nil",
|
||||||
|
args: args{warn: "This value is required", val: nil},
|
||||||
|
want: nil,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "required val is empty string",
|
||||||
|
args: args{warn: "This value is required", val: ""},
|
||||||
|
want: nil,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "required val is existed",
|
||||||
|
args: args{warn: "This value is required", val: "foo"},
|
||||||
|
want: "foo",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := Required(tt.args.warn, tt.args.val)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Required() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("Required() got = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -250,3 +250,81 @@ func Test_renderTemplateToString(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRenderTemplate_Required(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
s string
|
||||||
|
data map[string]interface{}
|
||||||
|
want string
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: ".foo is existed",
|
||||||
|
s: `{{ required ".foo.bar is required" .foo }}`,
|
||||||
|
data: map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
},
|
||||||
|
want: "bar",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ".foo.bar is existed",
|
||||||
|
s: `{{ required "foo.bar is required" .foo.bar }}`,
|
||||||
|
data: map[string]interface{}{
|
||||||
|
"foo": map[string]interface{}{
|
||||||
|
"bar": "FOO_BAR",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: "FOO_BAR",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ".foo.bar is existed but value is nil",
|
||||||
|
s: `{{ required "foo.bar is required" .foo.bar }}`,
|
||||||
|
data: map[string]interface{}{
|
||||||
|
"foo": map[string]interface{}{
|
||||||
|
"bar": nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ".foo.bar is existed but value is empty string",
|
||||||
|
s: `{{ required "foo.bar is required" .foo.bar }}`,
|
||||||
|
data: map[string]interface{}{
|
||||||
|
"foo": map[string]interface{}{
|
||||||
|
"bar": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ".foo is nil",
|
||||||
|
s: `{{ required "foo is required" .foo }}`,
|
||||||
|
data: map[string]interface{}{
|
||||||
|
"foo": nil,
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: ".foo is a empty string",
|
||||||
|
s: `{{ required "foo is required" .foo }}`,
|
||||||
|
data: map[string]interface{}{
|
||||||
|
"foo": "",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
got, err := renderTemplateToString(tt.s, tt.data)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("renderTemplateToString() for %s error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("renderTemplateToString() for %s = %v, want %v", tt.name, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue