Merge pull request #15936 from hashicorp/f-validate-list-no-duplicates

helper/validation: Add ValidateListUniqueStrings
This commit is contained in:
Chris Marchesi 2017-08-28 13:50:05 -07:00 committed by GitHub
commit 6c03958d4b
2 changed files with 36 additions and 0 deletions

View File

@ -148,6 +148,19 @@ func ValidateJsonString(v interface{}, k string) (ws []string, errors []error) {
return return
} }
// ValidateListUniqueStrings is a ValidateFunc that ensures a list has no
// duplicate items in it. It's useful for when a list is needed over a set
// because order matters, yet the items still need to be unique.
func ValidateListUniqueStrings(v interface{}, k string) (ws []string, errors []error) {
for n1, v1 := range v.([]interface{}) {
for n2, v2 := range v.([]interface{}) {
if v1.(string) == v2.(string) && n1 != n2 {
errors = append(errors, fmt.Errorf("%q: duplicate entry - %s", k, v1.(string)))
}
}
}
}
// ValidateRegexp returns a SchemaValidateFunc which tests to make sure the // ValidateRegexp returns a SchemaValidateFunc which tests to make sure the
// supplied string is a valid regular expression. // supplied string is a valid regular expression.
func ValidateRegexp(v interface{}, k string) (ws []string, errors []error) { func ValidateRegexp(v interface{}, k string) (ws []string, errors []error) {

View File

@ -180,6 +180,25 @@ func TestValidateJsonString(t *testing.T) {
} }
} }
func TestValidateListUniqueStrings(t *testing.T) {
runTestCases(t, []testCase{
{
val: []interface{}{"foo", "bar"},
f: ValidateListUniqueStrings,
},
{
val: []interface{}{"foo", "bar", "foo"},
f: ValidateListUniqueStrings,
expectedErr: regexp.MustCompile("duplicate entry - foo"),
},
{
val: []interface{}{"foo", "bar", "foo", "baz", "bar"},
f: ValidateListUniqueStrings,
expectedErr: regexp.MustCompile("duplicate entry - (?:foo|bar)"),
},
})
}
func runTestCases(t *testing.T, cases []testCase) { func runTestCases(t *testing.T, cases []testCase) {
matchErr := func(errs []error, r *regexp.Regexp) bool { matchErr := func(errs []error, r *regexp.Regexp) bool {
// err must match one provided // err must match one provided
@ -199,6 +218,10 @@ func runTestCases(t *testing.T, cases []testCase) {
continue continue
} }
if len(errs) != 0 && tc.expectedErr == nil {
t.Fatalf("expected test case %d to produce no errors, got %v", i, errs)
}
if !matchErr(errs, tc.expectedErr) { if !matchErr(errs, tc.expectedErr) {
t.Fatalf("expected test case %d to produce error matching \"%s\", got %v", i, tc.expectedErr, errs) t.Fatalf("expected test case %d to produce error matching \"%s\", got %v", i, tc.expectedErr, errs)
} }