github.com/facebookincubator/ttpforge@v1.0.13-0.20240405153150-5ae801628835/pkg/args/spec_test.go (about) 1 /* 2 Copyright © 2023-present, Meta Platforms, Inc. and affiliates 3 Permission is hereby granted, free of charge, to any person obtaining a copy 4 of this software and associated documentation files (the "Software"), to deal 5 in the Software without restriction, including without limitation the rights 6 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 copies of the Software, and to permit persons to whom the Software is 8 furnished to do so, subject to the following conditions: 9 The above copyright notice and this permission notice shall be included in 10 all copies or substantial portions of the Software. 11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 12 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 14 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 15 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 17 THE SOFTWARE. 18 */ 19 20 package args 21 22 import ( 23 "testing" 24 25 "github.com/stretchr/testify/assert" 26 "github.com/stretchr/testify/require" 27 ) 28 29 type validateTestCase struct { 30 name string 31 specs []Spec 32 argKvStrs []string 33 expectedResult map[string]any 34 wantError bool 35 } 36 37 func checkValidateTestCase(t *testing.T, tc validateTestCase) { 38 args, err := ParseAndValidate(tc.specs, tc.argKvStrs) 39 if tc.wantError { 40 require.Error(t, err) 41 return 42 } 43 require.NoError(t, err) 44 assert.Equal(t, tc.expectedResult, args) 45 } 46 47 func TestValidateArgs(t *testing.T) { 48 49 testCases := []validateTestCase{ 50 { 51 name: "Parse String and Integer Arguments", 52 specs: []Spec{ 53 { 54 Name: "alpha", 55 }, 56 { 57 Name: "beta", 58 Type: "int", 59 }, 60 }, 61 argKvStrs: []string{ 62 "alpha=foo", 63 "beta=3", 64 }, 65 expectedResult: map[string]any{ 66 "alpha": "foo", 67 "beta": 3, 68 }, 69 wantError: false, 70 }, 71 { 72 name: "Parse String and Integer Argument (Default Value)", 73 specs: []Spec{ 74 { 75 Name: "alpha", 76 }, 77 { 78 Name: "beta", 79 Type: "int", 80 Default: "1337", 81 }, 82 }, 83 argKvStrs: []string{ 84 "alpha=foo", 85 }, 86 expectedResult: map[string]any{ 87 "alpha": "foo", 88 "beta": 1337, 89 }, 90 wantError: false, 91 }, 92 { 93 name: "Handle Extra Equals", 94 specs: []Spec{ 95 { 96 Name: "alpha", 97 }, 98 { 99 Name: "beta", 100 }, 101 }, 102 argKvStrs: []string{ 103 "alpha=foo", 104 "beta=bar=baz", 105 }, 106 expectedResult: map[string]any{ 107 "alpha": "foo", 108 "beta": "bar=baz", 109 }, 110 wantError: false, 111 }, 112 { 113 name: "Invalid Inputs (no '=')", 114 specs: []Spec{ 115 { 116 Name: "alpha", 117 }, 118 { 119 Name: "beta", 120 }, 121 }, 122 argKvStrs: []string{ 123 "alpha=foo", 124 "wut", 125 }, 126 wantError: true, 127 }, 128 { 129 name: "Invalid Inputs (Missing Required Argument)", 130 specs: []Spec{ 131 { 132 Name: "alpha", 133 }, 134 { 135 Name: "beta", 136 }, 137 }, 138 argKvStrs: []string{ 139 "alpha=foo", 140 }, 141 wantError: true, 142 }, 143 { 144 name: "Argument Name Not In Specs", 145 specs: []Spec{ 146 { 147 Name: "alpha", 148 }, 149 { 150 Name: "beta", 151 }, 152 }, 153 argKvStrs: []string{ 154 "alpha=foo", 155 "gamma=bar", 156 }, 157 wantError: true, 158 }, 159 { 160 name: "Duplicate Name in Specs", 161 specs: []Spec{ 162 { 163 Name: "alpha", 164 }, 165 { 166 Name: "alpha", 167 }, 168 }, 169 argKvStrs: []string{ 170 "alpha=foo", 171 }, 172 wantError: true, 173 }, 174 { 175 name: "Wrong Type (string instead of int)", 176 specs: []Spec{ 177 { 178 Name: "alpha", 179 }, 180 { 181 Name: "beta", 182 Type: "int", 183 }, 184 }, 185 argKvStrs: []string{ 186 "alpha=foo", 187 "beta=bar", 188 }, 189 wantError: true, 190 }, 191 { 192 name: "Default Value Wrong Type (string instead of int)", 193 specs: []Spec{ 194 { 195 Name: "alpha", 196 Type: "int", 197 Default: "wut", 198 }, 199 }, 200 argKvStrs: []string{ 201 "alpha=1337", 202 }, 203 wantError: true, 204 }, 205 { 206 name: "Format with valid value", 207 specs: []Spec{ 208 { 209 Name: "alpha", 210 Type: "string", 211 Format: "[A-Z_]+", 212 }, 213 }, 214 argKvStrs: []string{ 215 "alpha=CECI_NEST_PAS_UNE_INT", 216 }, 217 expectedResult: map[string]any{ 218 "alpha": "CECI_NEST_PAS_UNE_INT", 219 }, 220 wantError: false, 221 }, 222 { 223 name: "Format (Flexible Match; No Error)", 224 specs: []Spec{ 225 { 226 Name: "alpha", 227 Type: "string", 228 Format: "ab", 229 }, 230 }, 231 argKvStrs: []string{ 232 "alpha=xabyabz", 233 }, 234 expectedResult: map[string]any{ 235 "alpha": "xabyabz", 236 }, 237 }, 238 { 239 name: "Format (Strict Match; No Error)", 240 specs: []Spec{ 241 { 242 Name: "alpha", 243 Type: "string", 244 Format: "^ab$", 245 }, 246 }, 247 argKvStrs: []string{ 248 "alpha=ab", 249 }, 250 expectedResult: map[string]any{ 251 "alpha": "ab", 252 }, 253 }, 254 { 255 name: "Format (Strict Match; Error)", 256 specs: []Spec{ 257 { 258 Name: "alpha", 259 Type: "string", 260 Format: "^ab$", 261 }, 262 }, 263 argKvStrs: []string{ 264 "alpha=xaby", 265 }, 266 wantError: true, 267 }, 268 { 269 name: "Format with proper end and beginning tags", 270 specs: []Spec{ 271 { 272 Name: "alpha", 273 Type: "string", 274 Format: "^[A-Z_-]+$", 275 }, 276 }, 277 argKvStrs: []string{ 278 "alpha=CECI_NEST_PAS_UNE_INT-", 279 }, 280 expectedResult: map[string]any{ 281 "alpha": "CECI_NEST_PAS_UNE_INT-", 282 }, 283 wantError: false, 284 }, 285 { 286 name: "Format with improper regex", 287 specs: []Spec{ 288 { 289 Name: "alpha", 290 Type: "string", 291 Format: "^[A-Z_-]+[$$", 292 }, 293 }, 294 argKvStrs: []string{ 295 "alpha=CECI_NEST_PAS_UNE_INT-", 296 }, 297 wantError: true, 298 }, 299 } 300 301 for _, tc := range testCases { 302 t.Run(tc.name, func(t *testing.T) { 303 checkValidateTestCase(t, tc) 304 }) 305 } 306 307 }