github.com/posener/terraform@v0.11.0-beta1.0.20171103235147-645df36af025/helper/validation/validation_test.go (about) 1 package validation 2 3 import ( 4 "regexp" 5 "testing" 6 7 "github.com/hashicorp/terraform/helper/schema" 8 ) 9 10 type testCase struct { 11 val interface{} 12 f schema.SchemaValidateFunc 13 expectedErr *regexp.Regexp 14 } 15 16 func TestValidationIntBetween(t *testing.T) { 17 runTestCases(t, []testCase{ 18 { 19 val: 1, 20 f: IntBetween(1, 1), 21 }, 22 { 23 val: 1, 24 f: IntBetween(0, 2), 25 }, 26 { 27 val: 1, 28 f: IntBetween(2, 3), 29 expectedErr: regexp.MustCompile("expected [\\w]+ to be in the range \\(2 - 3\\), got 1"), 30 }, 31 { 32 val: "1", 33 f: IntBetween(2, 3), 34 expectedErr: regexp.MustCompile("expected type of [\\w]+ to be int"), 35 }, 36 }) 37 } 38 39 func TestValidationIntAtLeast(t *testing.T) { 40 runTestCases(t, []testCase{ 41 { 42 val: 1, 43 f: IntAtLeast(1), 44 }, 45 { 46 val: 1, 47 f: IntAtLeast(0), 48 }, 49 { 50 val: 1, 51 f: IntAtLeast(2), 52 expectedErr: regexp.MustCompile("expected [\\w]+ to be at least \\(2\\), got 1"), 53 }, 54 { 55 val: "1", 56 f: IntAtLeast(2), 57 expectedErr: regexp.MustCompile("expected type of [\\w]+ to be int"), 58 }, 59 }) 60 } 61 62 func TestValidationIntAtMost(t *testing.T) { 63 runTestCases(t, []testCase{ 64 { 65 val: 1, 66 f: IntAtMost(1), 67 }, 68 { 69 val: 1, 70 f: IntAtMost(2), 71 }, 72 { 73 val: 1, 74 f: IntAtMost(0), 75 expectedErr: regexp.MustCompile("expected [\\w]+ to be at most \\(0\\), got 1"), 76 }, 77 { 78 val: "1", 79 f: IntAtMost(0), 80 expectedErr: regexp.MustCompile("expected type of [\\w]+ to be int"), 81 }, 82 }) 83 } 84 85 func TestValidationStringInSlice(t *testing.T) { 86 runTestCases(t, []testCase{ 87 { 88 val: "ValidValue", 89 f: StringInSlice([]string{"ValidValue", "AnotherValidValue"}, false), 90 }, 91 // ignore case 92 { 93 val: "VALIDVALUE", 94 f: StringInSlice([]string{"ValidValue", "AnotherValidValue"}, true), 95 }, 96 { 97 val: "VALIDVALUE", 98 f: StringInSlice([]string{"ValidValue", "AnotherValidValue"}, false), 99 expectedErr: regexp.MustCompile("expected [\\w]+ to be one of \\[ValidValue AnotherValidValue\\], got VALIDVALUE"), 100 }, 101 { 102 val: "InvalidValue", 103 f: StringInSlice([]string{"ValidValue", "AnotherValidValue"}, false), 104 expectedErr: regexp.MustCompile("expected [\\w]+ to be one of \\[ValidValue AnotherValidValue\\], got InvalidValue"), 105 }, 106 { 107 val: 1, 108 f: StringInSlice([]string{"ValidValue", "AnotherValidValue"}, false), 109 expectedErr: regexp.MustCompile("expected type of [\\w]+ to be string"), 110 }, 111 }) 112 } 113 114 func TestValidationRegexp(t *testing.T) { 115 runTestCases(t, []testCase{ 116 { 117 val: ".*foo.*", 118 f: ValidateRegexp, 119 }, 120 { 121 val: "foo(bar", 122 f: ValidateRegexp, 123 expectedErr: regexp.MustCompile(regexp.QuoteMeta("error parsing regexp: missing closing ): `foo(bar`")), 124 }, 125 }) 126 } 127 128 func TestValidateJsonString(t *testing.T) { 129 type testCases struct { 130 Value string 131 ErrCount int 132 } 133 134 invalidCases := []testCases{ 135 { 136 Value: `{0:"1"}`, 137 ErrCount: 1, 138 }, 139 { 140 Value: `{'abc':1}`, 141 ErrCount: 1, 142 }, 143 { 144 Value: `{"def":}`, 145 ErrCount: 1, 146 }, 147 { 148 Value: `{"xyz":[}}`, 149 ErrCount: 1, 150 }, 151 } 152 153 for _, tc := range invalidCases { 154 _, errors := ValidateJsonString(tc.Value, "json") 155 if len(errors) != tc.ErrCount { 156 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 157 } 158 } 159 160 validCases := []testCases{ 161 { 162 Value: ``, 163 ErrCount: 0, 164 }, 165 { 166 Value: `{}`, 167 ErrCount: 0, 168 }, 169 { 170 Value: `{"abc":["1","2"]}`, 171 ErrCount: 0, 172 }, 173 } 174 175 for _, tc := range validCases { 176 _, errors := ValidateJsonString(tc.Value, "json") 177 if len(errors) != tc.ErrCount { 178 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 179 } 180 } 181 } 182 183 func TestValidateListUniqueStrings(t *testing.T) { 184 runTestCases(t, []testCase{ 185 { 186 val: []interface{}{"foo", "bar"}, 187 f: ValidateListUniqueStrings, 188 }, 189 { 190 val: []interface{}{"foo", "bar", "foo"}, 191 f: ValidateListUniqueStrings, 192 expectedErr: regexp.MustCompile("duplicate entry - foo"), 193 }, 194 { 195 val: []interface{}{"foo", "bar", "foo", "baz", "bar"}, 196 f: ValidateListUniqueStrings, 197 expectedErr: regexp.MustCompile("duplicate entry - (?:foo|bar)"), 198 }, 199 }) 200 } 201 202 func TestValidationNoZeroValues(t *testing.T) { 203 runTestCases(t, []testCase{ 204 { 205 val: "foo", 206 f: NoZeroValues, 207 }, 208 { 209 val: 1, 210 f: NoZeroValues, 211 }, 212 { 213 val: float64(1), 214 f: NoZeroValues, 215 }, 216 { 217 val: "", 218 f: NoZeroValues, 219 expectedErr: regexp.MustCompile("must not be empty"), 220 }, 221 { 222 val: 0, 223 f: NoZeroValues, 224 expectedErr: regexp.MustCompile("must not be zero"), 225 }, 226 { 227 val: float64(0), 228 f: NoZeroValues, 229 expectedErr: regexp.MustCompile("must not be zero"), 230 }, 231 }) 232 } 233 234 func runTestCases(t *testing.T, cases []testCase) { 235 matchErr := func(errs []error, r *regexp.Regexp) bool { 236 // err must match one provided 237 for _, err := range errs { 238 if r.MatchString(err.Error()) { 239 return true 240 } 241 } 242 243 return false 244 } 245 246 for i, tc := range cases { 247 _, errs := tc.f(tc.val, "test_property") 248 249 if len(errs) == 0 && tc.expectedErr == nil { 250 continue 251 } 252 253 if len(errs) != 0 && tc.expectedErr == nil { 254 t.Fatalf("expected test case %d to produce no errors, got %v", i, errs) 255 } 256 257 if !matchErr(errs, tc.expectedErr) { 258 t.Fatalf("expected test case %d to produce error matching \"%s\", got %v", i, tc.expectedErr, errs) 259 } 260 } 261 }