github.com/rzurga/go-swagger@v0.28.1-0.20211109195225-5d1f453ffa3a/generator/discriminators_test.go (about) 1 package generator 2 3 import ( 4 "bytes" 5 "testing" 6 7 "github.com/go-openapi/analysis" 8 "github.com/go-openapi/loads" 9 "github.com/go-openapi/swag" 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestBuildDiscriminatorMap(t *testing.T) { 15 specDoc, err := loads.Spec("../fixtures/codegen/todolist.discriminators.yml") 16 require.NoError(t, err) 17 18 di := discriminatorInfo(analysis.New(specDoc.Spec())) 19 assert.Len(t, di.Discriminators, 1) 20 assert.Len(t, di.Discriminators["#/definitions/Pet"].Children, 2) 21 assert.Len(t, di.Discriminated, 2) 22 } 23 24 func TestGenerateModel_DiscriminatorSlices(t *testing.T) { 25 specDoc, err := loads.Spec("../fixtures/codegen/todolist.discriminators.yml") 26 require.NoError(t, err) 27 28 definitions := specDoc.Spec().Definitions 29 k := "Kennel" 30 schema := definitions[k] 31 opts := opts() 32 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 33 require.NoError(t, err) 34 assert.True(t, genModel.HasBaseType) 35 36 buf := bytes.NewBuffer(nil) 37 err = opts.templates.MustGet("model").Execute(buf, genModel) 38 require.NoError(t, err) 39 40 b, err := opts.LanguageOpts.FormatContent("has_discriminator.go", buf.Bytes()) 41 require.NoErrorf(t, err, buf.String()) 42 43 res := string(b) 44 assertInCode(t, "type Kennel struct {", res) 45 assertInCode(t, "ID int64 `json:\"id,omitempty\"`", res) 46 assertInCode(t, "Pets []Pet `json:\"pets\"`", res) 47 assertInCode(t, "if err := m.petsField[i].Validate(formats); err != nil {", res) 48 assertInCode(t, "m.validatePet", res) 49 } 50 51 func TestGenerateModel_Discriminators(t *testing.T) { 52 specDoc, e := loads.Spec("../fixtures/codegen/todolist.discriminators.yml") 53 require.NoError(t, e) 54 55 definitions := specDoc.Spec().Definitions 56 57 for _, k := range []string{"cat", "Dog"} { 58 schema := definitions[k] 59 opts := opts() 60 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 61 require.NoError(t, err) 62 63 assert.True(t, genModel.IsComplexObject) 64 assert.Equal(t, "petType", genModel.DiscriminatorField) 65 assert.Equal(t, k, genModel.DiscriminatorValue) 66 67 buf := bytes.NewBuffer(nil) 68 err = opts.templates.MustGet("model").Execute(buf, genModel) 69 require.NoError(t, err) 70 71 b, err := opts.LanguageOpts.FormatContent("discriminated.go", buf.Bytes()) 72 require.NoErrorf(t, err, buf.String()) 73 74 res := string(b) 75 assertNotInCode(t, "m.Pet.Validate", res) 76 assertInCode(t, "if err := m.validateName(formats); err != nil {", res) 77 78 if k == "Dog" { 79 assertInCode(t, "func (m *Dog) validatePackSize(formats strfmt.Registry) error {", res) 80 assertInCode(t, "if err := m.validatePackSize(formats); err != nil {", res) 81 assertInCode(t, "PackSize: m.PackSize,", res) 82 assertInCode(t, "validate.Required(\"packSize\", \"body\", m.PackSize)", res) 83 } else { 84 assertInCode(t, "func (m *Cat) validateHuntingSkill(formats strfmt.Registry) error {", res) 85 assertInCode(t, "if err := m.validateHuntingSkill(formats); err != nil {", res) 86 assertInCode(t, "if err := m.validateHuntingSkillEnum(\"huntingSkill\", \"body\", *m.HuntingSkill); err != nil {", res) 87 assertInCode(t, "HuntingSkill: m.HuntingSkill", res) 88 } 89 90 assertInCode(t, "Name *string `json:\"name\"`", res) 91 assertInCode(t, "PetType string `json:\"petType\"`", res) 92 93 assertInCode(t, "result.nameField = base.Name", res) 94 assertInCode(t, "if base.PetType != result.PetType() {", res) 95 assertInCode(t, "return errors.New(422, \"invalid petType value: %q\", base.PetType)", res) 96 97 kk := swag.ToGoName(k) 98 assertInCode(t, "func (m *"+kk+") Name() *string", res) 99 assertInCode(t, "func (m *"+kk+") SetName(val *string)", res) 100 assertInCode(t, "func (m *"+kk+") PetType() string", res) 101 assertInCode(t, "func (m *"+kk+") SetPetType(val string)", res) 102 assertInCode(t, "validate.Required(\"name\", \"body\", m.Name())", res) 103 } 104 105 k := "Pet" 106 schema := definitions[k] 107 opts := opts() 108 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 109 require.NoError(t, err) 110 111 assert.True(t, genModel.IsComplexObject) 112 assert.Equal(t, "petType", genModel.DiscriminatorField) 113 assert.Len(t, genModel.Discriminates, 3) 114 assert.Len(t, genModel.ExtraSchemas, 0) 115 assert.Equal(t, "Pet", genModel.Discriminates["Pet"]) 116 assert.Equal(t, "Cat", genModel.Discriminates["cat"]) 117 assert.Equal(t, "Dog", genModel.Discriminates["Dog"]) 118 119 buf := bytes.NewBuffer(nil) 120 err = opts.templates.MustGet("model").Execute(buf, genModel) 121 require.NoError(t, err) 122 123 b, err := opts.LanguageOpts.FormatContent("with_discriminator.go", buf.Bytes()) 124 require.NoErrorf(t, err, buf.String()) 125 126 res := string(b) 127 assertInCode(t, "type Pet interface {", res) 128 assertInCode(t, "runtime.Validatable", res) 129 assertInCode(t, "Name() *string", res) 130 assertInCode(t, "SetName(*string)", res) 131 assertInCode(t, "PetType() string", res) 132 assertInCode(t, "SetPetType(string)", res) 133 assertInCode(t, "type pet struct {", res) 134 assertInCode(t, "UnmarshalPet(reader io.Reader, consumer runtime.Consumer) (Pet, error)", res) 135 assertInCode(t, "PetType string `json:\"petType\"`", res) 136 assertInCode(t, "validate.RequiredString(\"petType\"", res) 137 assertInCode(t, "switch getType.PetType {", res) 138 assertInCode(t, "var result pet", res) 139 assertInCode(t, "var result Cat", res) 140 assertInCode(t, "var result Dog", res) 141 } 142 143 func TestGenerateModel_UsesDiscriminator(t *testing.T) { 144 specDoc, err := loads.Spec("../fixtures/codegen/todolist.discriminators.yml") 145 require.NoError(t, err) 146 147 definitions := specDoc.Spec().Definitions 148 k := "WithPet" 149 schema := definitions[k] 150 opts := opts() 151 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 152 require.NoError(t, err) 153 154 require.True(t, genModel.HasBaseType) 155 156 buf := bytes.NewBuffer(nil) 157 err = opts.templates.MustGet("model").Execute(buf, genModel) 158 require.NoError(t, err) 159 160 b, err := opts.LanguageOpts.FormatContent("has_discriminator.go", buf.Bytes()) 161 require.NoErrorf(t, err, buf.String()) 162 res := string(b) 163 assertInCode(t, "type WithPet struct {", res) 164 assertInCode(t, "ID int64 `json:\"id,omitempty\"`", res) 165 assertInCode(t, "petField Pet", res) 166 assertInCode(t, "if err := m.Pet().Validate(formats); err != nil {", res) 167 assertInCode(t, "m.validatePet", res) 168 } 169 170 func TestGenerateClient_OKResponseWithDiscriminator(t *testing.T) { 171 specDoc, err := loads.Spec("../fixtures/codegen/todolist.discriminators.yml") 172 require.NoError(t, err) 173 174 method, path, op, ok := analysis.New(specDoc.Spec()).OperationForName("modelOp") 175 require.True(t, ok) 176 177 opts := opts() 178 bldr := codeGenOpBuilder{ 179 Name: "modelOp", 180 Method: method, 181 Path: path, 182 APIPackage: "restapi", 183 ModelsPackage: "models", 184 Principal: "", 185 Target: ".", 186 Doc: specDoc, 187 Analyzed: analysis.New(specDoc.Spec()), 188 Operation: *op, 189 Authed: false, 190 DefaultScheme: "http", 191 ExtraSchemas: make(map[string]GenSchema), 192 GenOpts: opts, 193 } 194 195 genOp, err := bldr.MakeOperation() 196 require.NoError(t, err) 197 198 assert.True(t, genOp.Responses[0].Schema.IsBaseType) 199 var buf bytes.Buffer 200 err = opts.templates.MustGet("clientResponse").Execute(&buf, genOp) 201 require.NoError(t, err) 202 203 res := buf.String() 204 assertInCode(t, "Payload models.Pet", res) 205 assertInCode(t, "o.Payload = payload", res) 206 assertInCode(t, "payload, err := models.UnmarshalPet(response.Body(), consumer)", res) 207 } 208 209 func TestGenerateServer_Parameters(t *testing.T) { 210 specDoc, err := loads.Spec("../fixtures/codegen/todolist.discriminators.yml") 211 require.NoError(t, err) 212 213 method, path, op, ok := analysis.New(specDoc.Spec()).OperationForName("modelOp") 214 require.True(t, ok) 215 216 opts := opts() 217 bldr := codeGenOpBuilder{ 218 Name: "modelOp", 219 Method: method, 220 Path: path, 221 APIPackage: "restapi", 222 ModelsPackage: "models", 223 Principal: "", 224 Target: ".", 225 Doc: specDoc, 226 Analyzed: analysis.New(specDoc.Spec()), 227 Operation: *op, 228 Authed: false, 229 DefaultScheme: "http", 230 ExtraSchemas: make(map[string]GenSchema), 231 GenOpts: opts, 232 } 233 genOp, err := bldr.MakeOperation() 234 require.NoError(t, err) 235 236 assert.True(t, genOp.Responses[0].Schema.IsBaseType) 237 var buf bytes.Buffer 238 err = opts.templates.MustGet("serverParameter").Execute(&buf, genOp) 239 require.NoErrorf(t, err, buf.String()) 240 241 res := buf.String() 242 assertInCode(t, "Pet models.Pet", res) 243 assertInCode(t, "body, err := models.UnmarshalPet(r.Body, route.Consumer)", res) 244 assertInCode(t, "o.Pet = body", res) 245 } 246 247 func TestGenerateModel_Discriminator_Billforward(t *testing.T) { 248 specDoc, err := loads.Spec("../fixtures/codegen/billforward.discriminators.yml") 249 require.NoError(t, err) 250 251 definitions := specDoc.Spec().Definitions 252 k := "FlatPricingComponent" 253 schema := definitions[k] 254 opts := opts() 255 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 256 require.NoError(t, err) 257 require.True(t, genModel.IsSubType) 258 259 buf := bytes.NewBuffer(nil) 260 err = opts.templates.MustGet("model").Execute(buf, genModel) 261 require.NoError(t, err) 262 263 b, err := opts.LanguageOpts.FormatContent("has_discriminator.go", buf.Bytes()) 264 require.NoErrorf(t, err, buf.String()) 265 266 res := string(b) 267 assertNotInCode(t, "for i := 0; i < len(m.PriceExplanation()); i++", res) 268 } 269 270 func TestGenerateModel_Bitbucket_Repository(t *testing.T) { 271 specDoc, err := loads.Spec("../fixtures/codegen/bitbucket.json") 272 require.NoError(t, err) 273 274 definitions := specDoc.Spec().Definitions 275 k := "repository" 276 schema := definitions[k] 277 opts := opts() 278 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 279 require.NoError(t, err) 280 281 assert.True(t, genModel.IsNullable) 282 for _, gm := range genModel.AllOf { 283 for _, p := range gm.Properties { 284 if p.Name == "parent" { 285 assert.True(t, p.IsNullable) 286 } 287 } 288 } 289 290 buf := bytes.NewBuffer(nil) 291 err = opts.templates.MustGet("model").Execute(buf, genModel) 292 require.NoError(t, err) 293 294 b, err := opts.LanguageOpts.FormatContent("repository.go", buf.Bytes()) 295 require.NoErrorf(t, err, buf.String()) 296 297 res := string(b) 298 assertInCode(t, "Parent *Repository", res) 299 assertNotInCode(t, "Parent Repository", res) 300 } 301 302 func TestGenerateModel_Bitbucket_WebhookSubscription(t *testing.T) { 303 specDoc, err := loads.Spec("../fixtures/codegen/bitbucket.json") 304 require.NoError(t, err) 305 306 definitions := specDoc.Spec().Definitions 307 k := "webhook_subscription" 308 schema := definitions[k] 309 opts := opts() 310 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 311 require.NoError(t, err) 312 313 buf := bytes.NewBuffer(nil) 314 err = opts.templates.MustGet("model").Execute(buf, genModel) 315 require.NoError(t, err) 316 317 b, err := opts.LanguageOpts.FormatContent("webhook_subscription.go", buf.Bytes()) 318 require.NoErrorf(t, err, buf.String()) 319 320 res := string(b) 321 assertInCode(t, "result.subjectField", res) 322 assertInCode(t, "Subject: m.Subject()", res) 323 } 324 325 func TestGenerateModel_Issue319(t *testing.T) { 326 specDoc, err := loads.Spec("../fixtures/bugs/319/swagger.yml") 327 require.NoError(t, err) 328 329 definitions := specDoc.Spec().Definitions 330 k := "Container" 331 schema := definitions[k] 332 opts := opts() 333 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 334 require.NoError(t, err) 335 require.Equal(t, "map[string]Base", genModel.Properties[0].GoType) 336 337 buf := bytes.NewBuffer(nil) 338 err = opts.templates.MustGet("model").Execute(buf, genModel) 339 require.NoError(t, err) 340 341 b, err := opts.LanguageOpts.FormatContent("ifacedmap.go", buf.Bytes()) 342 require.NoErrorf(t, err, buf.String()) 343 344 res := string(b) 345 assertInCode(t, "MapNoWorky map[string]Base", res) 346 } 347 348 func TestGenerateModel_Issue541(t *testing.T) { 349 specDoc, err := loads.Spec("../fixtures/bugs/541/swagger.json") 350 require.NoError(t, err) 351 352 definitions := specDoc.Spec().Definitions 353 k := "Lion" 354 schema := definitions[k] 355 opts := opts() 356 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 357 require.NoError(t, err) 358 require.NotEmpty(t, genModel.AllOf) 359 360 buf := bytes.NewBuffer(nil) 361 err = opts.templates.MustGet("model").Execute(buf, genModel) 362 require.NoError(t, err) 363 364 b, err := opts.LanguageOpts.FormatContent("lion.go", buf.Bytes()) 365 require.NoErrorf(t, err, buf.String()) 366 367 res := string(b) 368 assertInCode(t, "Cat", res) 369 assertInCode(t, "m.Cat.Validate(formats)", res) 370 } 371 372 func TestGenerateModel_Issue436(t *testing.T) { 373 specDoc, err := loads.Spec("../fixtures/bugs/436/swagger.yml") 374 require.NoError(t, err) 375 376 definitions := specDoc.Spec().Definitions 377 k := "Image" 378 schema := definitions[k] 379 opts := opts() 380 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 381 require.NoError(t, err) 382 require.NotEmpty(t, genModel.AllOf) 383 384 buf := bytes.NewBuffer(nil) 385 err = opts.templates.MustGet("model").Execute(buf, genModel) 386 require.NoError(t, err) 387 388 b, err := opts.LanguageOpts.FormatContent("lion.go", buf.Bytes()) 389 require.NoErrorf(t, err, buf.String()) 390 391 res := string(b) 392 assertInCode(t, "Links", res) 393 assertInCode(t, "m.Links.Validate(formats)", res) 394 assertInCode(t, "Created *strfmt.DateTime `json:\"created\"`", res) 395 assertInCode(t, "ImageID *string `json:\"imageId\"`", res) 396 assertInCode(t, "Size *int64 `json:\"size\"`", res) 397 } 398 399 func TestGenerateModel_Issue740(t *testing.T) { 400 specDoc, err := loads.Spec("../fixtures/bugs/740/swagger.yml") 401 require.NoError(t, err) 402 403 definitions := specDoc.Spec().Definitions 404 k := "Bar" 405 schema := definitions[k] 406 opts := opts() 407 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 408 require.NoError(t, err) 409 require.NotEmpty(t, genModel.AllOf) 410 411 buf := bytes.NewBuffer(nil) 412 err = opts.templates.MustGet("model").Execute(buf, genModel) 413 require.NoError(t, err) 414 415 b, err := opts.LanguageOpts.FormatContent("bar.go", buf.Bytes()) 416 require.NoErrorf(t, err, buf.String()) 417 418 res := string(b) 419 assertInCode(t, "Foo", res) 420 assertInCode(t, "m.Foo.Validate(formats)", res) 421 } 422 423 func TestGenerateModel_Issue743(t *testing.T) { 424 specDoc, err := loads.Spec("../fixtures/bugs/743/swagger.yml") 425 require.NoError(t, err) 426 427 definitions := specDoc.Spec().Definitions 428 k := "Awol" 429 schema := definitions[k] 430 opts := opts() 431 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 432 require.NoError(t, err) 433 require.NotEmpty(t, genModel.AllOf) 434 435 buf := bytes.NewBuffer(nil) 436 err = opts.templates.MustGet("model").Execute(buf, genModel) 437 require.NoError(t, err) 438 439 b, err := opts.LanguageOpts.FormatContent("awol.go", buf.Bytes()) 440 require.NoErrorf(t, err, buf.String()) 441 442 res := string(b) 443 assertInCode(t, "Foo", res) 444 assertInCode(t, "Bar", res) 445 assertInCode(t, "m.Foo.Validate(formats)", res) 446 assertInCode(t, "m.Bar.Validate(formats)", res) 447 assertInCode(t, "swag.WriteJSON(m.Foo)", res) 448 assertInCode(t, "swag.WriteJSON(m.Bar)", res) 449 assertInCode(t, "swag.ReadJSON(raw, &aO0)", res) 450 assertInCode(t, "swag.ReadJSON(raw, &aO1)", res) 451 assertInCode(t, "m.Foo = aO0", res) 452 assertInCode(t, "m.Bar = aO1", res) 453 }