Skip to content

Commit 11f93f0

Browse files
committed
Adding Map validation for SizeAtLeast (#6)
1 parent bcdec31 commit 11f93f0

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

mapvalidator/size_at_least.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package mapvalidator
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
8+
9+
"github.com/hashicorp/terraform-plugin-framework-validators/validatordiag"
10+
)
11+
12+
var _ tfsdk.AttributeValidator = sizeAtLeastValidator{}
13+
14+
// sizeAtLeastValidator validates that map contains at least min elements.
15+
type sizeAtLeastValidator struct {
16+
min int
17+
}
18+
19+
// Description describes the validation in plain text formatting.
20+
func (v sizeAtLeastValidator) Description(ctx context.Context) string {
21+
return fmt.Sprintf("map must contain at least %d elements", v.min)
22+
}
23+
24+
// MarkdownDescription describes the validation in Markdown formatting.
25+
func (v sizeAtLeastValidator) MarkdownDescription(ctx context.Context) string {
26+
return v.Description(ctx)
27+
}
28+
29+
// Validate performs the validation.
30+
func (v sizeAtLeastValidator) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) {
31+
elems, ok := validateMap(ctx, req, resp)
32+
if !ok {
33+
return
34+
}
35+
36+
if len(elems) < v.min {
37+
resp.Diagnostics.Append(validatordiag.AttributeValueDiagnostic(
38+
req.AttributePath,
39+
v.Description(ctx),
40+
fmt.Sprintf("%d", len(elems)),
41+
))
42+
43+
return
44+
}
45+
}
46+
47+
func SizeAtLeast(min int) tfsdk.AttributeValidator {
48+
return sizeAtLeastValidator{
49+
min: min,
50+
}
51+
}

mapvalidator/size_at_least_test.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package mapvalidator
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/attr"
8+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
"github.com/hashicorp/terraform-plugin-go/tftypes"
11+
)
12+
13+
func TestSizeAtLeastValidator(t *testing.T) {
14+
t.Parallel()
15+
16+
type testCase struct {
17+
val attr.Value
18+
min int
19+
expectError bool
20+
}
21+
tests := map[string]testCase{
22+
"not a Map": {
23+
val: types.Bool{Value: true},
24+
expectError: true,
25+
},
26+
"Map unknown": {
27+
val: types.Map{
28+
Unknown: true,
29+
ElemType: types.StringType,
30+
},
31+
expectError: false,
32+
},
33+
"Map null": {
34+
val: types.Map{
35+
Null: true,
36+
ElemType: types.StringType,
37+
},
38+
expectError: false,
39+
},
40+
"Map size greater than min": {
41+
val: types.Map{
42+
ElemType: types.StringType,
43+
Elems: map[string]attr.Value{
44+
"one": types.String{Value: "first"},
45+
"two": types.String{Value: "second"},
46+
},
47+
},
48+
min: 1,
49+
expectError: false,
50+
},
51+
"Map size equal to min": {
52+
val: types.Map{
53+
ElemType: types.StringType,
54+
Elems: map[string]attr.Value{
55+
"one": types.String{Value: "first"},
56+
},
57+
},
58+
min: 1,
59+
expectError: false,
60+
},
61+
"Map size less than min": {
62+
val: types.Map{
63+
ElemType: types.StringType,
64+
Elems: map[string]attr.Value{},
65+
},
66+
min: 1,
67+
expectError: true,
68+
},
69+
}
70+
71+
for name, test := range tests {
72+
name, test := name, test
73+
t.Run(name, func(t *testing.T) {
74+
request := tfsdk.ValidateAttributeRequest{
75+
AttributePath: tftypes.NewAttributePath().WithAttributeName("test"),
76+
AttributeConfig: test.val,
77+
}
78+
response := tfsdk.ValidateAttributeResponse{}
79+
SizeAtLeast(test.min).Validate(context.TODO(), request, &response)
80+
81+
if !response.Diagnostics.HasError() && test.expectError {
82+
t.Fatal("expected error, got no error")
83+
}
84+
85+
if response.Diagnostics.HasError() && !test.expectError {
86+
t.Fatalf("got unexpected error: %s", response.Diagnostics)
87+
}
88+
})
89+
}
90+
}

0 commit comments

Comments
 (0)