Skip to content

Commit 367bd3e

Browse files
ewbankkitappilon
authored andcommitted
Sort map keys and return a Diagnostic for all invalid keys.
1 parent d32617d commit 367bd3e

File tree

2 files changed

+48
-13
lines changed

2 files changed

+48
-13
lines changed

helper/validation/map.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package validation
33
import (
44
"fmt"
55
"regexp"
6+
"sort"
67

78
"github.com/hashicorp/go-cty/cty"
89
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@@ -15,7 +16,7 @@ func MapKeyLenBetween(min, max int) schema.SchemaValidateDiagFunc {
1516
return func(v interface{}, path cty.Path) diag.Diagnostics {
1617
var diags diag.Diagnostics
1718

18-
for key := range v.(map[string]interface{}) {
19+
for _, key := range sortedKeys(v.(map[string]interface{})) {
1920
len := len(key)
2021
if len < min || len > max {
2122
diags = append(diags, diag.Diagnostic{
@@ -24,7 +25,6 @@ func MapKeyLenBetween(min, max int) schema.SchemaValidateDiagFunc {
2425
Detail: fmt.Sprintf("Key length should be in the range (%d - %d): %s (length = %d)", min, max, key, len),
2526
AttributePath: append(path, cty.IndexStep{Key: cty.StringVal(key)}),
2627
})
27-
break
2828
}
2929
}
3030

@@ -121,3 +121,17 @@ func MapValueMatch(r *regexp.Regexp, message string) schema.SchemaValidateFunc {
121121
return warnings, errors
122122
}
123123
}
124+
125+
func sortedKeys(m map[string]interface{}) []string {
126+
keys := make([]string, len(m))
127+
128+
i := 0
129+
for key := range m {
130+
keys[i] = key
131+
i++
132+
}
133+
134+
sort.Strings(keys)
135+
136+
return keys
137+
}

helper/validation/map_test.go

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,23 @@ func TestValidationMapKeyLenBetween(t *testing.T) {
3737
},
3838
},
3939
},
40+
"TooLongAndTooShort": {
41+
Value: map[string]interface{}{
42+
"UVWXYZ": "123456",
43+
"ABC": "123",
44+
"U": "1",
45+
},
46+
ExpectedDiags: diag.Diagnostics{
47+
{
48+
Severity: diag.Error,
49+
AttributePath: append(cty.Path{}, cty.IndexStep{Key: cty.StringVal("U")}),
50+
},
51+
{
52+
Severity: diag.Error,
53+
AttributePath: append(cty.Path{}, cty.IndexStep{Key: cty.StringVal("UVWXYZ")}),
54+
},
55+
},
56+
},
4057
"AllGood": {
4158
Value: map[string]interface{}{
4259
"AB": "12",
@@ -52,17 +69,7 @@ func TestValidationMapKeyLenBetween(t *testing.T) {
5269
t.Run(tn, func(t *testing.T) {
5370
diags := fn(tc.Value, cty.Path{})
5471

55-
if len(diags) != len(tc.ExpectedDiags) {
56-
t.Fatalf("%s: wrong number of diags, expected %d, got %d", tn, len(tc.ExpectedDiags), len(diags))
57-
}
58-
for j := range diags {
59-
if diags[j].Severity != tc.ExpectedDiags[j].Severity {
60-
t.Fatalf("%s: expected severity %v, got %v", tn, tc.ExpectedDiags[j].Severity, diags[j].Severity)
61-
}
62-
if !diags[j].AttributePath.Equals(tc.ExpectedDiags[j].AttributePath) {
63-
t.Fatalf("%s: attribute paths do not match expected: %v, got %v", tn, tc.ExpectedDiags[j].AttributePath, diags[j].AttributePath)
64-
}
65-
}
72+
checkDiagnostics(t, tn, diags, tc.ExpectedDiags)
6673
})
6774
}
6875
}
@@ -207,3 +214,17 @@ func TestValidationValueKeyMatch(t *testing.T) {
207214
})
208215
}
209216
}
217+
218+
func checkDiagnostics(t *testing.T, tn string, got, expected diag.Diagnostics) {
219+
if len(got) != len(expected) {
220+
t.Fatalf("%s: wrong number of diags, expected %d, got %d", tn, len(expected), len(got))
221+
}
222+
for j := range got {
223+
if got[j].Severity != expected[j].Severity {
224+
t.Fatalf("%s: expected severity %v, got %v", tn, expected[j].Severity, got[j].Severity)
225+
}
226+
if !got[j].AttributePath.Equals(expected[j].AttributePath) {
227+
t.Fatalf("%s: attribute paths do not match expected: %v, got %v", tn, expected[j].AttributePath, got[j].AttributePath)
228+
}
229+
}
230+
}

0 commit comments

Comments
 (0)