Skip to content

Commit d1ec2ed

Browse files
authored
Templates: validate required numeric values (#26959)
1 parent f5c690b commit d1ec2ed

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

util/templates/template.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ func (t *Template) RenderResult(renderMode int, other map[string]any) ([]byte, m
387387
}
388388

389389
// validate required fields from yaml
390-
if s == "" && p.IsRequired() && (renderMode == RenderModeUnitTest || renderMode == RenderModeInstance && !testing.Testing()) {
390+
if p.IsRequired() && p.IsZero(s) && (renderMode == RenderModeUnitTest || renderMode == RenderModeInstance && !testing.Testing()) {
391391
// validate required per usage
392392
if len(p.Usages) == 0 || slices.Contains(p.Usages, usage) {
393393
return nil, nil, fmt.Errorf("missing required `%s`", p.Name)

util/templates/template_test.go

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func TestPresets(t *testing.T) {
3232
}, tmpl.Params)
3333
}
3434

35-
func TestRequired(t *testing.T) {
35+
func TestRequiredString(t *testing.T) {
3636
tmpl := &Template{
3737
Params: []Param{
3838
{
@@ -63,6 +63,43 @@ func TestRequired(t *testing.T) {
6363
assert.NoError(t, err, "docs: required present but nil")
6464
}
6565

66+
func TestRequiredNumber(t *testing.T) {
67+
tmpl := &Template{
68+
Params: []Param{
69+
{
70+
Name: "param",
71+
Type: TypeInt,
72+
Required: true,
73+
},
74+
},
75+
}
76+
77+
_, _, err := tmpl.RenderResult(RenderModeUnitTest, map[string]any{
78+
"Param": "1",
79+
})
80+
assert.NoError(t, err, "test: required present")
81+
82+
_, _, err = tmpl.RenderResult(RenderModeUnitTest, map[string]any{
83+
"Param": "",
84+
})
85+
assert.Error(t, err, "test: required present but empty")
86+
87+
_, _, err = tmpl.RenderResult(RenderModeUnitTest, map[string]any{
88+
"Param": "0",
89+
})
90+
assert.Error(t, err, "test: required present but zero value")
91+
92+
_, _, err = tmpl.RenderResult(RenderModeUnitTest, map[string]any{
93+
"Param": nil,
94+
})
95+
assert.Error(t, err, "test: required present but nil")
96+
97+
_, _, err = tmpl.RenderResult(RenderModeDocs, map[string]any{
98+
"Param": nil,
99+
})
100+
assert.NoError(t, err, "docs: required present but nil")
101+
}
102+
66103
func TestRequiredDeprecated(t *testing.T) {
67104
tmpl := &Template{
68105
Params: []Param{

util/templates/types.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"dario.cat/mergo"
1313
"github.com/gosimple/slug"
14+
"github.com/spf13/cast"
1415
)
1516

1617
const (
@@ -269,6 +270,19 @@ func (p *Param) IsDeprecated() bool {
269270
return p.Deprecated
270271
}
271272

273+
func (p *Param) IsZero(s string) bool {
274+
switch p.Type {
275+
case TypeInt:
276+
return cast.ToInt64(s) == 0
277+
case TypeFloat:
278+
return cast.ToFloat64(s) == 0
279+
case TypeDuration:
280+
return cast.ToDuration(s) == 0
281+
default:
282+
return len(s) == 0
283+
}
284+
}
285+
272286
// yamlQuote quotes strings for yaml if they would otherwise by modified by the unmarshaler
273287
func (p *Param) yamlQuote(value string) string {
274288
if p.Type != TypeString {

0 commit comments

Comments
 (0)