github.com/emreu/go-swagger@v0.22.1/generator/enum_test.go (about) 1 // Copyright 2015 go-swagger maintainers 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package generator 16 17 import ( 18 "bytes" 19 "fmt" 20 "strings" 21 "testing" 22 23 "github.com/go-openapi/loads" 24 "github.com/stretchr/testify/assert" 25 ) 26 27 func TestEnum_StringThing(t *testing.T) { 28 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 29 if assert.NoError(t, err) { 30 definitions := specDoc.Spec().Definitions 31 k := "StringThing" 32 schema := definitions[k] 33 opts := opts() 34 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 35 if assert.NoError(t, err) { 36 buf := bytes.NewBuffer(nil) 37 err := templates.MustGet("model").Execute(buf, genModel) 38 if assert.NoError(t, err) { 39 ff, err := opts.LanguageOpts.FormatContent("string_thing.go", buf.Bytes()) 40 if assert.NoError(t, err) { 41 res := string(ff) 42 assertInCode(t, "var stringThingEnum []interface{}", res) 43 assertInCode(t, k+") validateStringThingEnum(path, location string, value StringThing)", res) 44 assertInCode(t, "m.validateStringThingEnum(\"\", \"body\", m)", res) 45 } 46 } 47 } 48 } 49 } 50 51 func TestEnum_ComposedThing(t *testing.T) { 52 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 53 if assert.NoError(t, err) { 54 definitions := specDoc.Spec().Definitions 55 k := "ComposedThing" 56 schema := definitions[k] 57 opts := opts() 58 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 59 if assert.NoError(t, err) { 60 buf := bytes.NewBuffer(nil) 61 err := templates.MustGet("model").Execute(buf, genModel) 62 if assert.NoError(t, err) { 63 ff, err := opts.LanguageOpts.FormatContent("composed_thing.go", buf.Bytes()) 64 if assert.NoError(t, err) { 65 res := string(ff) 66 assertInCode(t, "m.StringThing.Validate(formats)", res) 67 assertInCode(t, "var composedThingTypeNamePropEnum []interface{}", res) 68 assertInCode(t, "m.validateNameEnum(\"name\", \"body\", *m.Name)", res) 69 assertInCode(t, k+") validateNameEnum(path, location string, value string)", res) 70 } 71 } 72 } 73 } 74 } 75 76 func TestEnum_IntThing(t *testing.T) { 77 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 78 if assert.NoError(t, err) { 79 definitions := specDoc.Spec().Definitions 80 k := "IntThing" 81 schema := definitions[k] 82 opts := opts() 83 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 84 if assert.NoError(t, err) { 85 buf := bytes.NewBuffer(nil) 86 err := templates.MustGet("model").Execute(buf, genModel) 87 if assert.NoError(t, err) { 88 ff, err := opts.LanguageOpts.FormatContent("int_thing.go", buf.Bytes()) 89 if assert.NoError(t, err) { 90 res := string(ff) 91 assertInCode(t, "var intThingEnum []interface{}", res) 92 assertInCode(t, k+") validateIntThingEnum(path, location string, value IntThing)", res) 93 assertInCode(t, "m.validateIntThingEnum(\"\", \"body\", m)", res) 94 } 95 } 96 } 97 } 98 } 99 100 func TestEnum_FloatThing(t *testing.T) { 101 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 102 if assert.NoError(t, err) { 103 definitions := specDoc.Spec().Definitions 104 k := "FloatThing" 105 schema := definitions[k] 106 opts := opts() 107 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 108 if assert.NoError(t, err) { 109 buf := bytes.NewBuffer(nil) 110 err := templates.MustGet("model").Execute(buf, genModel) 111 if assert.NoError(t, err) { 112 ff, err := opts.LanguageOpts.FormatContent("float_thing.go", buf.Bytes()) 113 if assert.NoError(t, err) { 114 res := string(ff) 115 assertInCode(t, "var floatThingEnum []interface{}", res) 116 assertInCode(t, k+") validateFloatThingEnum(path, location string, value FloatThing)", res) 117 assertInCode(t, "m.validateFloatThingEnum(\"\", \"body\", m)", res) 118 } 119 } 120 } 121 } 122 } 123 124 func TestEnum_SliceThing(t *testing.T) { 125 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 126 if assert.NoError(t, err) { 127 definitions := specDoc.Spec().Definitions 128 k := "SliceThing" 129 schema := definitions[k] 130 opts := opts() 131 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 132 if assert.NoError(t, err) { 133 buf := bytes.NewBuffer(nil) 134 err := templates.MustGet("model").Execute(buf, genModel) 135 if assert.NoError(t, err) { 136 ff, err := opts.LanguageOpts.FormatContent("slice_thing.go", buf.Bytes()) 137 if assert.NoError(t, err) { 138 res := string(ff) 139 assertInCode(t, "var sliceThingEnum []interface{}", res) 140 assertInCode(t, k+") validateSliceThingEnum(path, location string, value []string)", res) 141 assertInCode(t, "m.validateSliceThingEnum(\"\", \"body\", m)", res) 142 } 143 } 144 } 145 } 146 } 147 148 func TestEnum_SliceAndItemsThing(t *testing.T) { 149 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 150 if assert.NoError(t, err) { 151 definitions := specDoc.Spec().Definitions 152 k := "SliceAndItemsThing" 153 schema := definitions[k] 154 opts := opts() 155 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 156 if assert.NoError(t, err) { 157 buf := bytes.NewBuffer(nil) 158 err := templates.MustGet("model").Execute(buf, genModel) 159 if assert.NoError(t, err) { 160 ff, err := opts.LanguageOpts.FormatContent("slice_and_items_thing.go", buf.Bytes()) 161 if assert.NoError(t, err) { 162 res := string(ff) 163 assertInCode(t, "var sliceAndItemsThingEnum []interface{}", res) 164 assertInCode(t, k+") validateSliceAndItemsThingEnum(path, location string, value []string)", res) 165 assertInCode(t, "m.validateSliceAndItemsThingEnum(\"\", \"body\", m)", res) 166 assertInCode(t, "var sliceAndItemsThingItemsEnum []interface{}", res) 167 assertInCode(t, k+") validateSliceAndItemsThingItemsEnum(path, location string, value string)", res) 168 assertInCode(t, "m.validateSliceAndItemsThingItemsEnum(strconv.Itoa(i), \"body\", m[i])", res) 169 } 170 } 171 } 172 } 173 } 174 175 func TestEnum_SliceAndAdditionalItemsThing(t *testing.T) { 176 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 177 if assert.NoError(t, err) { 178 definitions := specDoc.Spec().Definitions 179 k := "SliceAndAdditionalItemsThing" 180 schema := definitions[k] 181 opts := opts() 182 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 183 if assert.NoError(t, err) { 184 buf := bytes.NewBuffer(nil) 185 err := templates.MustGet("model").Execute(buf, genModel) 186 if assert.NoError(t, err) { 187 ff, err := opts.LanguageOpts.FormatContent("slice_and_additional_items_thing.go", buf.Bytes()) 188 if assert.NoError(t, err) { 189 res := string(ff) 190 assertInCode(t, "var sliceAndAdditionalItemsThingEnum []interface{}", res) 191 assertInCode(t, k+") validateSliceAndAdditionalItemsThingEnum(path, location string, value *SliceAndAdditionalItemsThing)", res) 192 //assertInCode(t, "m.validateSliceAndAdditionalItemsThingEnum(\"\", \"body\", m)", res) 193 assertInCode(t, "var sliceAndAdditionalItemsThingTypeP0PropEnum []interface{}", res) 194 assertInCode(t, k+") validateP0Enum(path, location string, value string)", res) 195 assertInCode(t, "m.validateP0Enum(\"0\", \"body\", *m.P0)", res) 196 assertInCode(t, "var sliceAndAdditionalItemsThingItemsEnum []interface{}", res) 197 assertInCode(t, k+") validateSliceAndAdditionalItemsThingItemsEnum(path, location string, value float32)", res) 198 assertInCode(t, "m.validateSliceAndAdditionalItemsThingItemsEnum(strconv.Itoa(i+1), \"body\", m.SliceAndAdditionalItemsThingItems[i])", res) 199 } 200 } 201 } 202 } 203 } 204 205 func TestEnum_MapThing(t *testing.T) { 206 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 207 if assert.NoError(t, err) { 208 definitions := specDoc.Spec().Definitions 209 k := "MapThing" 210 schema := definitions[k] 211 opts := opts() 212 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 213 if assert.NoError(t, err) { 214 buf := bytes.NewBuffer(nil) 215 err := templates.MustGet("model").Execute(buf, genModel) 216 if assert.NoError(t, err) { 217 ff, err := opts.LanguageOpts.FormatContent("map_thing.go", buf.Bytes()) 218 if assert.NoError(t, err) { 219 res := string(ff) 220 assertInCode(t, "var mapThingEnum []interface{}", res) 221 assertInCode(t, k+") validateMapThingEnum(path, location string, value MapThing)", res) 222 assertInCode(t, "m.validateMapThingEnum(\"\", \"body\", m)", res) 223 assertInCode(t, "var mapThingValueEnum []interface{}", res) 224 assertInCode(t, k+") validateMapThingValueEnum(path, location string, value string)", res) 225 assertInCode(t, "m.validateMapThingValueEnum(k, \"body\", m[k])", res) 226 } else { 227 fmt.Println(buf.String()) 228 } 229 } 230 } 231 } 232 } 233 234 func TestEnum_ObjectThing(t *testing.T) { 235 // verify that additionalItems render the same from an expanded and a flattened spec 236 // known issue: there are some slight differences in generated code and variables for enum, 237 // depending on how the spec has been preprocessed 238 specs := []string{ 239 "../fixtures/codegen/todolist.enums.yml", 240 "../fixtures/codegen/todolist.enums.flattened.json", // this one is the first one, after "swagger flatten" 241 } 242 k := "ObjectThing" 243 for _, fixture := range specs { 244 t.Logf("%s from spec: %s", k, fixture) 245 specDoc, err := loads.Spec(fixture) 246 if assert.NoError(t, err) { 247 definitions := specDoc.Spec().Definitions 248 schema := definitions[k] 249 opts := opts() 250 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 251 if assert.NoError(t, err) { 252 buf := bytes.NewBuffer(nil) 253 err := templates.MustGet("model").Execute(buf, genModel) 254 if assert.NoError(t, err) { 255 ff, err := opts.LanguageOpts.FormatContent("object_thing.go", buf.Bytes()) 256 if assert.NoError(t, err) { 257 res := string(ff) 258 // all these remain unaffected 259 assertInCode(t, "var objectThingTypeNamePropEnum []interface{}", res) 260 assertInCode(t, "var objectThingTypeFlowerPropEnum []interface{}", res) 261 assertInCode(t, "var objectThingTypeFlourPropEnum []interface{}", res) 262 assertInCode(t, "var objectThingTypeWolvesPropEnum []interface{}", res) 263 assertInCode(t, "var objectThingWolvesValueEnum []interface{}", res) 264 assertInCode(t, "var objectThingCatsItemsEnum []interface{}", res) 265 assertInCode(t, k+") validateNameEnum(path, location string, value string)", res) 266 assertInCode(t, k+") validateFlowerEnum(path, location string, value int32)", res) 267 assertInCode(t, k+") validateFlourEnum(path, location string, value float32)", res) 268 assertInCode(t, k+") validateWolvesEnum(path, location string, value map[string]string)", res) 269 assertInCode(t, k+") validateWolvesValueEnum(path, location string, value string)", res) 270 assertInCode(t, k+") validateCatsItemsEnum(path, location string, value string)", res) 271 assertInCode(t, k+") validateCats(", res) 272 assertInCode(t, "m.validateNameEnum(\"name\", \"body\", *m.Name)", res) 273 assertInCode(t, "m.validateFlowerEnum(\"flower\", \"body\", m.Flower)", res) 274 assertInCode(t, "m.validateFlourEnum(\"flour\", \"body\", m.Flour)", res) 275 assertInCode(t, "m.validateWolvesEnum(\"wolves\", \"body\", m.Wolves)", res) 276 assertInCode(t, "m.validateWolvesValueEnum(\"wolves\"+\".\"+k, \"body\", m.Wolves[k])", res) 277 assertInCode(t, "m.validateCatsItemsEnum(\"cats\"+\".\"+strconv.Itoa(i), \"body\", m.Cats[i])", res) 278 279 // small naming differences may be found between the expand and the flatten version of spec 280 namingDifference := "Tuple0" 281 pathDifference := "P" 282 if strings.Contains(fixture, "flattened") { 283 // when expanded, all defs are in the same template for AdditionalItems 284 schema := definitions["objectThingLions"] 285 genModel, err = makeGenDefinition("ObjectThingLions", "models", schema, specDoc, opts) 286 if assert.NoError(t, err) { 287 buf = bytes.NewBuffer(nil) 288 err := templates.MustGet("model").Execute(buf, genModel) 289 if assert.NoError(t, err) { 290 ff, err := opts.LanguageOpts.FormatContent("object_thing_lions.go", buf.Bytes()) 291 if assert.NoError(t, err) { 292 res = string(ff) 293 } 294 } 295 } 296 namingDifference = "" 297 pathDifference = "" 298 } 299 // now common check resumes 300 assertInCode(t, "var objectThingLions"+namingDifference+"TypeP0PropEnum []interface{}", res) 301 assertInCode(t, "var objectThingLions"+namingDifference+"TypeP1PropEnum []interface{}", res) 302 assertInCode(t, "var objectThingLions"+namingDifference+"ItemsEnum []interface{}", res) 303 assertInCode(t, "m.validateP1Enum(\""+pathDifference+"1\", \"body\", *m.P1)", res) 304 assertInCode(t, "m.validateP0Enum(\""+pathDifference+"0\", \"body\", *m.P0)", res) 305 assertInCode(t, k+"Lions"+namingDifference+") validateObjectThingLions"+namingDifference+"ItemsEnum(path, location string, value float64)", res) 306 307 if namingDifference != "" { 308 assertInCode(t, "m.validateObjectThingLions"+namingDifference+"ItemsEnum(strconv.Itoa(i), \"body\", m.ObjectThingLions"+namingDifference+"Items[i])", res) 309 assertInCode(t, "var objectThingTypeLionsPropEnum []interface{}", res) 310 assertInCode(t, k+") validateLionsEnum(path, location string, value float64)", res) 311 } else { 312 assertInCode(t, "m.validateObjectThingLions"+namingDifference+"ItemsEnum(strconv.Itoa(i+2), \"body\", m.ObjectThingLions"+namingDifference+"Items[i])", res) 313 assertInCode(t, "var objectThingLionsItemsEnum []interface{}", res) 314 assertInCode(t, k+"Lions) validateObjectThingLionsItemsEnum(path, location string, value float64)", res) 315 } 316 317 } 318 } 319 } 320 } 321 } 322 } 323 324 func TestEnum_ComputeInstance(t *testing.T) { 325 // ensure that the enum validation for the anonymous object under the delegate property 326 // is rendered. 327 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 328 if assert.NoError(t, err) { 329 definitions := specDoc.Spec().Definitions 330 k := "ComputeInstance" 331 schema := definitions[k] 332 opts := opts() 333 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 334 if assert.NoError(t, err) { 335 buf := bytes.NewBuffer(nil) 336 err := templates.MustGet("model").Execute(buf, genModel) 337 if assert.NoError(t, err) { 338 ff, err := opts.LanguageOpts.FormatContent("object_thing.go", buf.Bytes()) 339 if assert.NoError(t, err) { 340 res := string(ff) 341 assertInCode(t, "Region *string `json:\"region\"`", res) 342 assertInCode(t, "var computeInstanceTypeRegionPropEnum []interface{}", res) 343 assertInCode(t, "m.validateRegionEnum(\"region\", \"body\", *m.Region)", res) 344 } 345 } 346 } 347 } 348 } 349 350 func TestEnum_Cluster(t *testing.T) { 351 // ensure that the enum validation for the anonymous object under the delegate property 352 // is rendered. 353 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 354 if assert.NoError(t, err) { 355 definitions := specDoc.Spec().Definitions 356 k := "Cluster" 357 schema := definitions[k] 358 opts := opts() 359 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 360 if assert.NoError(t, err) { 361 buf := bytes.NewBuffer(nil) 362 err := templates.MustGet("model").Execute(buf, genModel) 363 if assert.NoError(t, err) { 364 ff, err := opts.LanguageOpts.FormatContent("object_thing.go", buf.Bytes()) 365 if assert.NoError(t, err) { 366 res := string(ff) 367 assertInCode(t, "Data *ClusterData `json:\"data\"`", res) 368 assertInCode(t, `ClusterDataStatusScheduled string = "scheduled"`, res) 369 assertInCode(t, `ClusterDataStatusBuilding string = "building"`, res) 370 assertInCode(t, `ClusterDataStatusUp string = "up"`, res) 371 assertInCode(t, `ClusterDataStatusDeleting string = "deleting"`, res) 372 assertInCode(t, `ClusterDataStatusExited string = "exited"`, res) 373 assertInCode(t, `ClusterDataStatusError string = "error"`, res) 374 375 } 376 } 377 } 378 } 379 } 380 381 func TestEnum_NewPrototype(t *testing.T) { 382 // ensure that the enum validation for the anonymous object under the delegate property 383 // is rendered. 384 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 385 if assert.NoError(t, err) { 386 definitions := specDoc.Spec().Definitions 387 k := "NewPrototype" 388 schema := definitions[k] 389 opts := opts() 390 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 391 if assert.NoError(t, err) { 392 buf := bytes.NewBuffer(nil) 393 err := templates.MustGet("model").Execute(buf, genModel) 394 if assert.NoError(t, err) { 395 ff, err := opts.LanguageOpts.FormatContent("object_thing.go", buf.Bytes()) 396 if assert.NoError(t, err) { 397 res := string(ff) 398 assertInCode(t, "ActivatingUser *NewPrototypeActivatingUser `json:\"activating_user,omitempty\"`", res) 399 assertInCode(t, "Delegate *NewPrototypeDelegate `json:\"delegate\"`", res) 400 assertInCode(t, "Role *string `json:\"role\"`", res) 401 assertInCode(t, "var newPrototypeTypeRolePropEnum []interface{}", res) 402 assertInCode(t, "var newPrototypeDelegateTypeKindPropEnum []interface{}", res) 403 assertInCode(t, "m.validateDelegate(formats)", res) 404 assertInCode(t, "m.validateRole(formats)", res) 405 assertInCode(t, "m.validateActivatingUser(formats)", res) 406 assertInCode(t, "m.Delegate.Validate(formats)", res) 407 assertInCode(t, "m.ActivatingUser.Validate(formats)", res) 408 } 409 } 410 } 411 } 412 } 413 414 func TestEnum_Issue265(t *testing.T) { 415 specDoc, err := loads.Spec("../fixtures/codegen/sodabooth.json") 416 if assert.NoError(t, err) { 417 definitions := specDoc.Spec().Definitions 418 k := "SodaBrand" 419 schema := definitions[k] 420 opts := opts() 421 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 422 if assert.NoError(t, err) { 423 buf := bytes.NewBuffer(nil) 424 err := templates.MustGet("model").Execute(buf, genModel) 425 if assert.NoError(t, err) { 426 ff, err := opts.LanguageOpts.FormatContent("soda_brand.go", buf.Bytes()) 427 if assert.NoError(t, err) { 428 res := string(ff) 429 assert.Equal(t, 1, strings.Count(res, "m.validateSodaBrandEnum")) 430 } 431 } 432 } 433 } 434 } 435 436 func TestEnum_Issue325(t *testing.T) { 437 specDoc, err := loads.Spec("../fixtures/codegen/sodabooths.json") 438 if assert.NoError(t, err) { 439 definitions := specDoc.Spec().Definitions 440 k := "SodaBrand" 441 schema := definitions[k] 442 opts := opts() 443 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 444 if assert.NoError(t, err) { 445 buf := bytes.NewBuffer(nil) 446 err = templates.MustGet("model").Execute(buf, genModel) 447 if assert.NoError(t, err) { 448 ff, ferr := opts.LanguageOpts.FormatContent("soda_brand.go", buf.Bytes()) 449 if assert.NoError(t, ferr) { 450 res := string(ff) 451 assertInCode(t, "var sodaBrandEnum []interface{}", res) 452 assertInCode(t, "err := validate.Enum(path, location, value, sodaBrandEnum)", res) 453 assert.Equal(t, 1, strings.Count(res, "m.validateSodaBrandEnum")) 454 } 455 } 456 } 457 458 k = "Soda" 459 schema = definitions[k] 460 genModel, err = makeGenDefinition(k, "models", schema, specDoc, opts) 461 if assert.NoError(t, err) { 462 buf := bytes.NewBuffer(nil) 463 err := templates.MustGet("model").Execute(buf, genModel) 464 if assert.NoError(t, err) { 465 ff, err := opts.LanguageOpts.FormatContent("soda.go", buf.Bytes()) 466 if assert.NoError(t, err) { 467 res := string(ff) 468 assertInCode(t, "var sodaTypeBrandPropEnum []interface{}", res) 469 assertInCode(t, "err := validate.Enum(path, location, value, sodaTypeBrandPropEnum)", res) 470 assert.Equal(t, 1, strings.Count(res, "m.validateBrandEnum")) 471 } 472 } 473 } 474 } 475 } 476 477 func TestEnum_Issue352(t *testing.T) { 478 specDoc, err := loads.Spec("../fixtures/codegen/todolist.enums.yml") 479 if assert.NoError(t, err) { 480 definitions := specDoc.Spec().Definitions 481 k := "slp_action_enum" 482 schema := definitions[k] 483 opts := opts() 484 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 485 if assert.NoError(t, err) { 486 buf := bytes.NewBuffer(nil) 487 err := templates.MustGet("model").Execute(buf, genModel) 488 if assert.NoError(t, err) { 489 ff, err := opts.LanguageOpts.FormatContent("slp_action_enum.go", buf.Bytes()) 490 if assert.NoError(t, err) { 491 res := string(ff) 492 assertInCode(t, ", value SlpActionEnum", res) 493 } 494 } 495 } 496 } 497 }