Skip to content

Commit b6ac0d4

Browse files
committed
add test cases
1 parent 58c51c1 commit b6ac0d4

2 files changed

Lines changed: 114 additions & 9 deletions

File tree

pkg/validators/metadata_validators.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,24 @@ func (r *RangeValidator) validateTarget(
225225
delimiter *string,
226226
customErrMsg string) error {
227227
if lengthCheck {
228-
if delimiter != nil && len(values) > 0 {
229-
stringVal := values[0].AsString()
230-
segments := strings.Split(stringVal, *delimiter)
231-
return r.checkBounds(len(segments), min, max, customErrMsg, path)
228+
if delimiter != nil {
229+
if len(values) > 1 {
230+
return config.BpError{
231+
Err: fmt.Errorf("range validator with 'delimiter' option can only be used on a single string, not a list of values"),
232+
Path: path,
233+
}
234+
}
235+
if len(values) == 1 {
236+
if values[0].Type() != cty.String {
237+
return config.BpError{
238+
Err: fmt.Errorf("range validator with 'delimiter' expects a string value, but got %s", values[0].Type().FriendlyName()),
239+
Path: path,
240+
}
241+
}
242+
stringVal := values[0].AsString()
243+
segments := strings.Split(stringVal, *delimiter)
244+
return r.checkBounds(len(segments), min, max, customErrMsg, path)
245+
}
232246
}
233247

234248
return r.checkBounds(len(values), min, max, customErrMsg, path)
@@ -240,6 +254,12 @@ func (r *RangeValidator) validateTarget(
240254
}
241255
if val.Type() == cty.Number {
242256
f, _ := val.AsBigFloat().Float64()
257+
if f != float64(int64(f)) {
258+
return config.BpError{
259+
Err: fmt.Errorf("range validator only supports integer numbers, not %v", f),
260+
Path: path,
261+
}
262+
}
243263
if err := r.checkBounds(int(f), min, max, customErrMsg, path); err != nil {
244264
return err
245265
}

pkg/validators/metadata_validators_test.go

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,28 @@ func TestRangeValidator_Numeric(t *testing.T) {
453453
t.Fatalf("expected error message to contain 'too high', got: %q", err.Error())
454454
}
455455
})
456+
457+
t.Run("fails_on_float_value", func(t *testing.T) {
458+
bp := baseBP
459+
bp.Groups[0].Modules[0].Settings = config.NewDict(map[string]cty.Value{
460+
"float_var": cty.NumberFloatVal(2.5),
461+
})
462+
rule := modulereader.ValidationRule{
463+
Validator: "range",
464+
Inputs: map[string]interface{}{
465+
"vars": []interface{}{"float_var"},
466+
"min": 1,
467+
"max": 5,
468+
},
469+
}
470+
err := validator.Validate(bp, bp.Groups[0].Modules[0], rule, bp.Groups[0], 0)
471+
if err == nil {
472+
t.Fatalf("expected failure for non-integer numeric value")
473+
}
474+
if !strings.Contains(err.Error(), "range validator only supports integer numbers") {
475+
t.Fatalf("expected error message to contain 'range validator only supports integer numbers', got: %q", err.Error())
476+
}
477+
})
456478
}
457479

458480
func TestRangeValidator_Length(t *testing.T) {
@@ -554,12 +576,29 @@ func TestRangeValidator_Length(t *testing.T) {
554576
t.Fatalf("expected error message to contain 'too high', got: %q", err.Error())
555577
}
556578
})
579+
}
580+
func TestRangeValidator_Delimiter(t *testing.T) {
581+
baseBP := config.Blueprint{
582+
BlueprintName: "test-bp",
583+
Groups: []config.Group{
584+
{
585+
Name: "primary",
586+
Modules: []config.Module{
587+
{
588+
ID: "test-module",
589+
Source: "test/module",
590+
Settings: config.NewDict(map[string]cty.Value{
591+
"csv_string": cty.StringVal("one,two"),
592+
}),
593+
},
594+
},
595+
},
596+
},
597+
}
598+
599+
validator := RangeValidator{}
557600

558601
t.Run("passes_on_valid_segments_count", func(t *testing.T) {
559-
bp := baseBP
560-
bp.Groups[0].Modules[0].Settings = config.NewDict(map[string]cty.Value{
561-
"csv_string": cty.StringVal("one,two"),
562-
})
563602
rule := modulereader.ValidationRule{
564603
Validator: "range",
565604
ErrorMessage: "'csv_string' segment count is too low",
@@ -571,7 +610,7 @@ func TestRangeValidator_Length(t *testing.T) {
571610
"delimiter": ",",
572611
},
573612
}
574-
if err := validator.Validate(bp, bp.Groups[0].Modules[0], rule, bp.Groups[0], 0); err != nil {
613+
if err := validator.Validate(baseBP, baseBP.Groups[0].Modules[0], rule, baseBP.Groups[0], 0); err != nil {
575614
t.Fatalf("unexpected validation error: %v", err)
576615
}
577616
})
@@ -626,4 +665,50 @@ func TestRangeValidator_Length(t *testing.T) {
626665
t.Fatalf("expected error message to contain 'too high', got: %q", err.Error())
627666
}
628667
})
668+
669+
t.Run("fails_on_list_of_strings_with_delimiter", func(t *testing.T) {
670+
bp := baseBP
671+
bp.Groups[0].Modules[0].Settings = config.NewDict(map[string]cty.Value{
672+
"list_var": cty.TupleVal([]cty.Value{cty.StringVal("a,b"), cty.StringVal("c,d")}),
673+
})
674+
rule := modulereader.ValidationRule{
675+
Validator: "range",
676+
Inputs: map[string]interface{}{
677+
"vars": []interface{}{"list_var"},
678+
"min": 2,
679+
"length_check": true,
680+
"delimiter": ",",
681+
},
682+
}
683+
err := validator.Validate(bp, bp.Groups[0].Modules[0], rule, bp.Groups[0], 0)
684+
if err == nil {
685+
t.Fatalf("expected failure when delimiter is used on a list of strings")
686+
}
687+
if !strings.Contains(err.Error(), "not a list of values") {
688+
t.Fatalf("expected error message to contain 'not a list of values', got: %q", err.Error())
689+
}
690+
})
691+
692+
t.Run("fails_on_non_string_with_delimiter", func(t *testing.T) {
693+
bp := baseBP
694+
bp.Groups[0].Modules[0].Settings = config.NewDict(map[string]cty.Value{
695+
"num_var": cty.NumberIntVal(123),
696+
})
697+
rule := modulereader.ValidationRule{
698+
Validator: "range",
699+
Inputs: map[string]interface{}{
700+
"vars": []interface{}{"num_var"},
701+
"min": 1,
702+
"length_check": true,
703+
"delimiter": ",",
704+
},
705+
}
706+
err := validator.Validate(bp, bp.Groups[0].Modules[0], rule, bp.Groups[0], 0)
707+
if err == nil {
708+
t.Fatalf("expected failure when delimiter is used on a non-string value")
709+
}
710+
if !strings.Contains(err.Error(), "expects a string value") {
711+
t.Fatalf("expected error message to contain 'expects a string value', got: %q", err.Error())
712+
}
713+
})
629714
}

0 commit comments

Comments
 (0)