github.com/paultyng/terraform@v0.6.11-0.20180227224804-66ff8f8bed40/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 TestValidationStringMatch(t *testing.T) { 115 runTestCases(t, []testCase{ 116 { 117 val: "foobar", 118 f: StringMatch(regexp.MustCompile(".*foo.*"), ""), 119 }, 120 { 121 val: "bar", 122 f: StringMatch(regexp.MustCompile(".*foo.*"), ""), 123 expectedErr: regexp.MustCompile("expected value of [\\w]+ to match regular expression " + regexp.QuoteMeta(`".*foo.*"`)), 124 }, 125 { 126 val: "bar", 127 f: StringMatch(regexp.MustCompile(".*foo.*"), "value must contain foo"), 128 expectedErr: regexp.MustCompile("invalid value for [\\w]+ \\(value must contain foo\\)"), 129 }, 130 }) 131 } 132 133 func TestValidationRegexp(t *testing.T) { 134 runTestCases(t, []testCase{ 135 { 136 val: ".*foo.*", 137 f: ValidateRegexp, 138 }, 139 { 140 val: "foo(bar", 141 f: ValidateRegexp, 142 expectedErr: regexp.MustCompile(regexp.QuoteMeta("error parsing regexp: missing closing ): `foo(bar`")), 143 }, 144 }) 145 } 146 147 func TestValidateJsonString(t *testing.T) { 148 type testCases struct { 149 Value string 150 ErrCount int 151 } 152 153 invalidCases := []testCases{ 154 { 155 Value: `{0:"1"}`, 156 ErrCount: 1, 157 }, 158 { 159 Value: `{'abc':1}`, 160 ErrCount: 1, 161 }, 162 { 163 Value: `{"def":}`, 164 ErrCount: 1, 165 }, 166 { 167 Value: `{"xyz":[}}`, 168 ErrCount: 1, 169 }, 170 } 171 172 for _, tc := range invalidCases { 173 _, errors := ValidateJsonString(tc.Value, "json") 174 if len(errors) != tc.ErrCount { 175 t.Fatalf("Expected %q to trigger a validation error.", tc.Value) 176 } 177 } 178 179 validCases := []testCases{ 180 { 181 Value: ``, 182 ErrCount: 0, 183 }, 184 { 185 Value: `{}`, 186 ErrCount: 0, 187 }, 188 { 189 Value: `{"abc":["1","2"]}`, 190 ErrCount: 0, 191 }, 192 } 193 194 for _, tc := range validCases { 195 _, errors := ValidateJsonString(tc.Value, "json") 196 if len(errors) != tc.ErrCount { 197 t.Fatalf("Expected %q not to trigger a validation error.", tc.Value) 198 } 199 } 200 } 201 202 func TestValidateListUniqueStrings(t *testing.T) { 203 runTestCases(t, []testCase{ 204 { 205 val: []interface{}{"foo", "bar"}, 206 f: ValidateListUniqueStrings, 207 }, 208 { 209 val: []interface{}{"foo", "bar", "foo"}, 210 f: ValidateListUniqueStrings, 211 expectedErr: regexp.MustCompile("duplicate entry - foo"), 212 }, 213 { 214 val: []interface{}{"foo", "bar", "foo", "baz", "bar"}, 215 f: ValidateListUniqueStrings, 216 expectedErr: regexp.MustCompile("duplicate entry - (?:foo|bar)"), 217 }, 218 }) 219 } 220 221 func TestValidationNoZeroValues(t *testing.T) { 222 runTestCases(t, []testCase{ 223 { 224 val: "foo", 225 f: NoZeroValues, 226 }, 227 { 228 val: 1, 229 f: NoZeroValues, 230 }, 231 { 232 val: float64(1), 233 f: NoZeroValues, 234 }, 235 { 236 val: "", 237 f: NoZeroValues, 238 expectedErr: regexp.MustCompile("must not be empty"), 239 }, 240 { 241 val: 0, 242 f: NoZeroValues, 243 expectedErr: regexp.MustCompile("must not be zero"), 244 }, 245 { 246 val: float64(0), 247 f: NoZeroValues, 248 expectedErr: regexp.MustCompile("must not be zero"), 249 }, 250 }) 251 } 252 253 func runTestCases(t *testing.T, cases []testCase) { 254 matchErr := func(errs []error, r *regexp.Regexp) bool { 255 // err must match one provided 256 for _, err := range errs { 257 if r.MatchString(err.Error()) { 258 return true 259 } 260 } 261 262 return false 263 } 264 265 for i, tc := range cases { 266 _, errs := tc.f(tc.val, "test_property") 267 268 if len(errs) == 0 && tc.expectedErr == nil { 269 continue 270 } 271 272 if len(errs) != 0 && tc.expectedErr == nil { 273 t.Fatalf("expected test case %d to produce no errors, got %v", i, errs) 274 } 275 276 if !matchErr(errs, tc.expectedErr) { 277 t.Fatalf("expected test case %d to produce error matching \"%s\", got %v", i, tc.expectedErr, errs) 278 } 279 } 280 }