github.com/rzurga/go-swagger@v0.28.1-0.20211109195225-5d1f453ffa3a/generator/model_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 "os" 21 "path/filepath" 22 "regexp" 23 "strconv" 24 "strings" 25 "testing" 26 "text/template" 27 28 "github.com/go-openapi/loads" 29 "github.com/go-openapi/swag" 30 "github.com/stretchr/testify/assert" 31 "github.com/stretchr/testify/require" 32 ) 33 34 type templateTest struct { 35 t testing.TB 36 template *template.Template 37 } 38 39 func (tt *templateTest) assertRender(data interface{}, expected string) (success bool) { 40 buf := bytes.NewBuffer(nil) 41 defer func() { 42 success = !tt.t.Failed() 43 }() 44 45 require.NoError(tt.t, tt.template.Execute(buf, data)) 46 47 trimmed := strings.TrimLeft(buf.String(), "\n\t ") 48 exp := strings.TrimLeft(expected, "\n\t ") 49 assert.Equal(tt.t, exp, trimmed) 50 51 return 52 } 53 54 func TestGenerateModel_Sanity(t *testing.T) { 55 t.Parallel() 56 57 // just checks if it can render and format these things 58 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 59 require.NoError(t, err) 60 61 definitions := specDoc.Spec().Definitions 62 63 t.Run("mode sanity check", func(t *testing.T) { 64 for k, schema := range definitions { 65 opts := opts() 66 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 67 require.NoError(t, err) 68 69 rendered := bytes.NewBuffer(nil) 70 71 require.NoErrorf(t, opts.templates.MustGet("model").Execute(rendered, genModel), 72 "Unexpected error while rendering models for fixtures/codegen/todolist.models.yml: %v", err) 73 74 _, err = opts.LanguageOpts.FormatContent(strings.ToLower(k)+".go", rendered.Bytes()) 75 require.NoError(t, err) 76 } 77 }) 78 } 79 80 func TestGenerateModel_DocString(t *testing.T) { 81 funcMap := FuncMapFunc(DefaultLanguageFunc()) 82 templ := template.Must(template.New("docstring").Funcs(funcMap).Parse(string(assets["docstring.gotmpl"]))) 83 tt := templateTest{t, templ} 84 85 var gmp GenSchema 86 gmp.Title = "The title of the property" 87 gmp.Description = "The description of the property" 88 var expected = `The title of the property 89 // 90 // The description of the property` 91 tt.assertRender(gmp, expected) 92 93 gmp.Title = "" 94 expected = `The description of the property` 95 tt.assertRender(gmp, expected) 96 97 gmp.Description = "" 98 gmp.Name = "theModel" 99 expected = `the model` 100 tt.assertRender(gmp, expected) 101 } 102 103 func TestGenerateModel_PropertyValidation(t *testing.T) { 104 funcMap := FuncMapFunc(DefaultLanguageFunc()) 105 templ := template.Must(template.New("propertyValidationDocString").Funcs(funcMap).Parse(string(assets["validation/structfield.gotmpl"]))) 106 tt := templateTest{t, templ} 107 108 var gmp GenSchema 109 gmp.Required = true 110 tt.assertRender(gmp, ` 111 // Required: true`) 112 var fl float64 = 10 113 var in1 int64 = 20 114 var in2 int64 = 30 115 gmp.Maximum = &fl 116 gmp.ExclusiveMaximum = true 117 gmp.Minimum = &fl 118 gmp.ExclusiveMinimum = true 119 gmp.MaxLength = &in1 120 gmp.MinLength = &in1 121 gmp.Pattern = "\\w[\\w- ]+" 122 gmp.MaxItems = &in2 123 gmp.MinItems = &in2 124 gmp.UniqueItems = true 125 126 tt.assertRender(gmp, ` 127 // Required: true 128 // Maximum: < 10 129 // Minimum: > 10 130 // Max Length: 20 131 // Min Length: 20 132 // Pattern: \w[\w- ]+ 133 // Max Items: 30 134 // Min Items: 30 135 // Unique: true`) 136 137 gmp.Required = false 138 gmp.ExclusiveMaximum = false 139 gmp.ExclusiveMinimum = false 140 tt.assertRender(gmp, ` 141 // Maximum: 10 142 // Minimum: 10 143 // Max Length: 20 144 // Min Length: 20 145 // Pattern: \w[\w- ]+ 146 // Max Items: 30 147 // Min Items: 30 148 // Unique: true`) 149 150 } 151 152 func TestGenerateModel_SchemaField(t *testing.T) { 153 tt := templateTest{t, templates.MustGet("model").Lookup("structfield")} 154 155 var gmp GenSchema 156 gmp.Name = "some name" 157 gmp.OriginalName = "some name" 158 gmp.resolvedType = resolvedType{GoType: "string", IsPrimitive: true, IsEmptyOmitted: true} 159 gmp.Title = "The title of the property" 160 gmp.CustomTag = "mytag:\"foobar,foobaz\"" 161 162 tt.assertRender(&gmp, `// The title of the property 163 `+"SomeName string `json:\"some name,omitempty\" mytag:\"foobar,foobaz\"`\n") 164 165 var fl float64 = 10 166 var in1 int64 = 20 167 var in2 int64 = 30 168 169 gmp.Description = "The description of the property" 170 gmp.Required = true 171 gmp.Maximum = &fl 172 gmp.ExclusiveMaximum = true 173 gmp.Minimum = &fl 174 gmp.ExclusiveMinimum = true 175 gmp.MaxLength = &in1 176 gmp.MinLength = &in1 177 gmp.Pattern = "\\w[\\w- ]+" 178 gmp.MaxItems = &in2 179 gmp.MinItems = &in2 180 gmp.UniqueItems = true 181 gmp.ReadOnly = true 182 gmp.StructTags = []string{"json", "db", "example"} 183 gmp.Example = "some example\"" 184 tt.assertRender(&gmp, `// The title of the property 185 // 186 // The description of the property 187 // Example: some example" 188 // Required: true 189 // Read Only: true 190 // Maximum: < 10 191 // Minimum: > 10 192 // Max Length: 20 193 // Min Length: 20 194 // Pattern: \w[\w- ]+ 195 // Max Items: 30 196 // Min Items: 30 197 // Unique: true 198 `+"SomeName string `json:\"some name\" db:\"some name\" example:\"some example\\\"\" mytag:\"foobar,foobaz\"`\n") 199 200 gmp.Example = "some example``" 201 tt.assertRender(&gmp, `// The title of the property 202 // 203 // The description of the property 204 // Example: some example`+"``"+` 205 // Required: true 206 // Read Only: true 207 // Maximum: < 10 208 // Minimum: > 10 209 // Max Length: 20 210 // Min Length: 20 211 // Pattern: \w[\w- ]+ 212 // Max Items: 30 213 // Min Items: 30 214 // Unique: true 215 `+"SomeName string \"json:\\\"some name\\\" db:\\\"some name\\\" example:\\\"some example``\\\" mytag:\\\"foobar,foobaz\\\"\"\n") 216 } 217 218 var schTypeGenDataSimple = []struct { 219 Value GenSchema 220 Expected string 221 }{ 222 {GenSchema{resolvedType: resolvedType{GoType: "string", IsPrimitive: true}}, "string"}, 223 {GenSchema{resolvedType: resolvedType{GoType: "string", IsPrimitive: true, IsNullable: true}}, "*string"}, 224 {GenSchema{resolvedType: resolvedType{GoType: "bool", IsPrimitive: true}}, "bool"}, 225 {GenSchema{resolvedType: resolvedType{GoType: "int32", IsPrimitive: true}}, "int32"}, 226 {GenSchema{resolvedType: resolvedType{GoType: "int64", IsPrimitive: true}}, "int64"}, 227 {GenSchema{resolvedType: resolvedType{GoType: "float32", IsPrimitive: true}}, "float32"}, 228 {GenSchema{resolvedType: resolvedType{GoType: "float64", IsPrimitive: true}}, "float64"}, 229 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.Base64", IsPrimitive: true}}, "strfmt.Base64"}, 230 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.Date", IsPrimitive: true}}, "strfmt.Date"}, 231 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.DateTime", IsPrimitive: true}}, "strfmt.DateTime"}, 232 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.URI", IsPrimitive: true}}, "strfmt.URI"}, 233 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.Email", IsPrimitive: true}}, "strfmt.Email"}, 234 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.Hostname", IsPrimitive: true}}, "strfmt.Hostname"}, 235 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.IPv4", IsPrimitive: true}}, "strfmt.IPv4"}, 236 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.IPv6", IsPrimitive: true}}, "strfmt.IPv6"}, 237 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.UUID", IsPrimitive: true}}, "strfmt.UUID"}, 238 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.UUID3", IsPrimitive: true}}, "strfmt.UUID3"}, 239 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.UUID4", IsPrimitive: true}}, "strfmt.UUID4"}, 240 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.UUID5", IsPrimitive: true}}, "strfmt.UUID5"}, 241 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.ISBN", IsPrimitive: true}}, "strfmt.ISBN"}, 242 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.ISBN10", IsPrimitive: true}}, "strfmt.ISBN10"}, 243 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.ISBN13", IsPrimitive: true}}, "strfmt.ISBN13"}, 244 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.CreditCard", IsPrimitive: true}}, "strfmt.CreditCard"}, 245 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.SSN", IsPrimitive: true}}, "strfmt.SSN"}, 246 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.HexColor", IsPrimitive: true}}, "strfmt.HexColor"}, 247 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.RGBColor", IsPrimitive: true}}, "strfmt.RGBColor"}, 248 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.Duration", IsPrimitive: true}}, "strfmt.Duration"}, 249 {GenSchema{resolvedType: resolvedType{GoType: "strfmt.Password", IsPrimitive: true}}, "strfmt.Password"}, 250 {GenSchema{resolvedType: resolvedType{GoType: "io.ReadCloser", IsStream: true}}, "io.ReadCloser"}, 251 {GenSchema{resolvedType: resolvedType{GoType: "interface{}", IsInterface: true}}, "interface{}"}, 252 {GenSchema{resolvedType: resolvedType{GoType: "[]int32", IsArray: true}}, "[]int32"}, 253 {GenSchema{resolvedType: resolvedType{GoType: "[]string", IsArray: true}}, "[]string"}, 254 {GenSchema{resolvedType: resolvedType{GoType: "map[string]int32", IsMap: true}}, "map[string]int32"}, 255 {GenSchema{resolvedType: resolvedType{GoType: "models.Task", IsComplexObject: true, IsNullable: true, IsAnonymous: false}}, "*models.Task"}, 256 } 257 258 func TestGenSchemaType(t *testing.T) { 259 tt := templateTest{t, templates.MustGet("model").Lookup("schemaType")} 260 for _, v := range schTypeGenDataSimple { 261 tt.assertRender(v.Value, v.Expected) 262 } 263 } 264 func TestGenerateModel_Primitives(t *testing.T) { 265 tt := templateTest{t, templates.MustGet("model").Lookup("schema")} 266 for _, v := range schTypeGenDataSimple { 267 v.Value.IncludeValidator = true 268 v.Value.IncludeModel = true 269 val := v.Value 270 val.ReceiverName = "o" 271 if val.IsComplexObject { 272 continue 273 } 274 val.Name = "theType" 275 exp := v.Expected 276 if val.IsInterface || val.IsStream { 277 tt.assertRender(&val, "type TheType "+exp+"\n \n") 278 continue 279 } 280 tt.assertRender(&val, "type TheType "+exp+"\n \n// Validate validates this the type\nfunc (o theType) Validate(formats strfmt.Registry) error {\n return nil\n}\n// ContextValidate validates this the type based on context it is used \nfunc (o theType) ContextValidate(ctx context.Context, formats strfmt.Registry) error {\n return nil\n}\n") 281 } 282 } 283 284 func TestGenerateModel_Zeroes(t *testing.T) { 285 for _, v := range schTypeGenDataSimple { 286 switch v.Value.GoType { 287 // verifying Zero for primitive 288 case "string": 289 assert.Equal(t, `""`, v.Value.Zero()) 290 case "bool": 291 assert.Equal(t, `false`, v.Value.Zero()) 292 case "int32", "int64", "float32", "float64": 293 assert.Equal(t, `0`, v.Value.Zero()) 294 // verifying Zero for primitive formatters 295 case "strfmt.Date", "strfmt.DateTime", "strfmt.OjbectId": // akin to structs 296 rex := regexp.MustCompile(regexp.QuoteMeta(v.Value.GoType) + `{}`) 297 assert.True(t, rex.MatchString(v.Value.Zero())) 298 k := v.Value 299 k.IsAliased = true 300 k.AliasedType = k.GoType 301 k.GoType = "myAliasedType" 302 rex = regexp.MustCompile(regexp.QuoteMeta(k.GoType+"("+k.AliasedType) + `{}` + `\)`) 303 assert.True(t, rex.MatchString(k.Zero())) 304 case "strfmt.Duration": // akin to integer 305 rex := regexp.MustCompile(regexp.QuoteMeta(v.Value.GoType) + `\(\d*\)`) 306 assert.True(t, rex.MatchString(v.Value.Zero())) 307 k := v.Value 308 k.IsAliased = true 309 k.AliasedType = k.GoType 310 k.GoType = "myAliasedType" 311 rex = regexp.MustCompile(regexp.QuoteMeta(k.GoType+"("+k.AliasedType) + `\(\d*\)` + `\)`) 312 assert.True(t, rex.MatchString(k.Zero())) 313 case "strfmt.Base64": // akin to []byte 314 rex := regexp.MustCompile(regexp.QuoteMeta(v.Value.GoType) + `\(\[\]byte.*\)`) 315 assert.True(t, rex.MatchString(v.Value.Zero())) 316 k := v.Value 317 k.IsAliased = true 318 k.AliasedType = k.GoType 319 k.GoType = "myAliasedType" 320 rex = regexp.MustCompile(regexp.QuoteMeta(k.GoType+"("+k.AliasedType) + `\(\[\]byte.*\)` + `\)`) 321 assert.True(t, rex.MatchString(k.Zero())) 322 case "interface{}": 323 assert.Equal(t, `nil`, v.Value.Zero()) 324 case "io.ReadCloser": 325 continue 326 default: 327 switch { 328 case strings.HasPrefix(v.Value.GoType, "[]") || strings.HasPrefix(v.Value.GoType, "map["): // akin to slice or map 329 assert.True(t, strings.HasPrefix(v.Value.Zero(), "make(")) 330 331 case strings.HasPrefix(v.Value.GoType, "models."): 332 assert.True(t, strings.HasPrefix(v.Value.Zero(), "new(")) 333 334 default: // akin to string 335 rex := regexp.MustCompile(regexp.QuoteMeta(v.Value.GoType) + `\(".*"\)`) 336 assert.True(t, rex.MatchString(v.Value.Zero())) 337 k := v.Value 338 k.IsAliased = true 339 k.AliasedType = k.GoType 340 k.GoType = "myAliasedType" 341 rex = regexp.MustCompile(regexp.QuoteMeta(k.GoType+"("+k.AliasedType) + `\(".*"\)` + `\)`) 342 assert.True(t, rex.MatchString(k.Zero())) 343 } 344 } 345 } 346 } 347 func TestGenerateModel_Nota(t *testing.T) { 348 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 349 require.NoError(t, err) 350 351 definitions := specDoc.Spec().Definitions 352 k := "Nota" 353 schema := definitions[k] 354 opts := opts() 355 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 356 require.NoError(t, err) 357 358 buf := bytes.NewBuffer(nil) 359 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 360 361 res := buf.String() 362 assertInCode(t, "type Nota map[string]int32", res) 363 } 364 365 func TestGenerateModel_NotaWithRef(t *testing.T) { 366 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 367 require.NoError(t, err) 368 369 definitions := specDoc.Spec().Definitions 370 k := "NotaWithRef" 371 schema := definitions[k] 372 opts := opts() 373 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 374 require.NoError(t, err) 375 376 buf := bytes.NewBuffer(nil) 377 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 378 379 ff, err := opts.LanguageOpts.FormatContent("nota_with_ref.go", buf.Bytes()) 380 require.NoError(t, err) 381 382 res := string(ff) 383 assertInCode(t, "type NotaWithRef map[string]Notable", res) 384 } 385 386 func TestGenerateModel_NotaWithMeta(t *testing.T) { 387 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 388 require.NoError(t, err) 389 390 definitions := specDoc.Spec().Definitions 391 k := "NotaWithMeta" 392 schema := definitions[k] 393 opts := opts() 394 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 395 require.NoError(t, err) 396 397 buf := bytes.NewBuffer(nil) 398 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 399 400 ff, err := opts.LanguageOpts.FormatContent("nota_with_meta.go", buf.Bytes()) 401 require.NoError(t, err) 402 403 res := string(ff) 404 assertInCode(t, "type NotaWithMeta map[string]NotaWithMetaAnon", res) 405 assertInCode(t, "type NotaWithMetaAnon struct {", res) 406 assertInCode(t, "Comment *string `json:\"comment\"`", res) 407 assertInCode(t, "Count int32 `json:\"count,omitempty\"`", res) 408 } 409 410 func TestGenerateModel_RunParameters(t *testing.T) { 411 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 412 require.NoError(t, err) 413 414 definitions := specDoc.Spec().Definitions 415 k := "RunParameters" 416 schema := definitions[k] 417 opts := opts() 418 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 419 require.NoError(t, err) 420 421 assert.False(t, genModel.IsAdditionalProperties) 422 assert.True(t, genModel.IsComplexObject) 423 assert.False(t, genModel.IsMap) 424 assert.False(t, genModel.IsAnonymous) 425 buf := bytes.NewBuffer(nil) 426 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 427 428 res := buf.String() 429 assertInCode(t, "type "+k+" struct {", res) 430 assertInCode(t, "BranchName string `json:\"branch_name,omitempty\"`", res) 431 assertInCode(t, "CommitSha string `json:\"commit_sha,omitempty\"`", res) 432 assertInCode(t, "Refs interface{} `json:\"refs,omitempty\"`", res) 433 } 434 435 func TestGenerateModel_NotaWithName(t *testing.T) { 436 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 437 require.NoError(t, err) 438 439 definitions := specDoc.Spec().Definitions 440 k := "NotaWithName" 441 schema := definitions[k] 442 opts := opts() 443 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 444 require.NoError(t, err) 445 446 assert.True(t, genModel.IsAdditionalProperties) 447 assert.False(t, genModel.IsComplexObject) 448 assert.False(t, genModel.IsMap) 449 assert.False(t, genModel.IsAnonymous) 450 buf := bytes.NewBuffer(nil) 451 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 452 453 res := buf.String() 454 assertInCode(t, "type "+k+" struct {", res) 455 assertInCode(t, k+" map[string]int32 `json:\"-\"`", res) 456 assertInCode(t, "Name *string `json:\"name\"`", res) 457 assertInCode(t, k+") UnmarshalJSON", res) 458 assertInCode(t, k+") MarshalJSON", res) 459 assertInCode(t, "json.Marshal(stage1)", res) 460 assertInCode(t, "stage1.Name = m.Name", res) 461 assertInCode(t, "json.Marshal(m."+k+")", res) 462 assertInCode(t, "json.Unmarshal(data, &stage1)", res) 463 assertInCode(t, "json.Unmarshal(data, &stage2)", res) 464 assertInCode(t, "json.Unmarshal(v, &toadd)", res) 465 assertInCode(t, "result[k] = toadd", res) 466 assertInCode(t, "m."+k+" = result", res) 467 for _, p := range genModel.Properties { 468 assertInCode(t, "delete(stage2, \""+p.Name+"\")", res) 469 } 470 } 471 472 func TestGenerateModel_NotaWithRefRegistry(t *testing.T) { 473 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 474 require.NoError(t, err) 475 476 definitions := specDoc.Spec().Definitions 477 k := "NotaWithRefRegistry" 478 schema := definitions[k] 479 opts := opts() 480 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 481 require.NoError(t, err) 482 483 buf := bytes.NewBuffer(nil) 484 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 485 486 ff, err := opts.LanguageOpts.FormatContent("nota_with_ref_registry.go", buf.Bytes()) 487 require.NoError(t, err) 488 489 assertInCode(t, "type "+k+" map[string]map[string]map[string]Notable", string(ff)) 490 } 491 492 func TestGenerateModel_WithCustomTag(t *testing.T) { 493 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 494 require.NoError(t, err) 495 496 definitions := specDoc.Spec().Definitions 497 k := "WithCustomTag" 498 schema := definitions[k] 499 opts := opts() 500 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 501 require.NoError(t, err) 502 503 buf := bytes.NewBuffer(nil) 504 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 505 506 assertInCode(t, "mytag:\"foo,bar\"", buf.String()) 507 } 508 509 func TestGenerateModel_NotaWithMetaRegistry(t *testing.T) { 510 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 511 require.NoError(t, err) 512 513 definitions := specDoc.Spec().Definitions 514 k := "NotaWithMetaRegistry" 515 schema := definitions[k] 516 opts := opts() 517 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 518 require.NoError(t, err) 519 520 buf := bytes.NewBuffer(nil) 521 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 522 523 ff, err := opts.LanguageOpts.FormatContent("nota_with_meta_registry.go", buf.Bytes()) 524 require.NoError(t, err) 525 526 res := string(ff) 527 assertInCode(t, "type "+k+" map[string]map[string]map[string]NotaWithMetaRegistryAnon", res) 528 assertInCode(t, "type NotaWithMetaRegistryAnon struct {", res) 529 assertInCode(t, "Comment *string `json:\"comment\"`", res) 530 assertInCode(t, "Count int32 `json:\"count,omitempty\"`", res) 531 } 532 533 func TestGenerateModel_WithMap(t *testing.T) { 534 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 535 require.NoError(t, err) 536 537 definitions := specDoc.Spec().Definitions 538 schema := definitions["WithMap"] 539 opts := opts() 540 genModel, err := makeGenDefinition("WithMap", "models", schema, specDoc, opts) 541 require.NoError(t, err) 542 543 assert.False(t, genModel.HasAdditionalProperties) 544 prop := getDefinitionProperty(genModel, "data") 545 assert.True(t, prop.HasAdditionalProperties) 546 assert.True(t, prop.IsMap) 547 assert.False(t, prop.IsComplexObject) 548 buf := bytes.NewBuffer(nil) 549 require.NoError(t, templates.MustGet("model").Execute(buf, genModel)) 550 551 res := buf.String() 552 assertInCode(t, "type WithMap struct {", res) 553 assertInCode(t, "Data map[string]string `json:\"data,omitempty\"`", res) 554 } 555 556 func TestGenerateModel_WithMapInterface(t *testing.T) { 557 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 558 require.NoError(t, err) 559 560 definitions := specDoc.Spec().Definitions 561 schema := definitions["WithMapInterface"] 562 opts := opts() 563 genModel, err := makeGenDefinition("WithMapInterface", "models", schema, specDoc, opts) 564 require.NoError(t, err) 565 566 assert.False(t, genModel.HasAdditionalProperties) 567 prop := getDefinitionProperty(genModel, "extraInfo") 568 assert.True(t, prop.HasAdditionalProperties) 569 assert.True(t, prop.IsMap) 570 assert.False(t, prop.IsComplexObject) 571 assert.Equal(t, "map[string]interface{}", prop.GoType) 572 assert.True(t, prop.Required) 573 assert.True(t, prop.HasValidations) 574 575 buf := bytes.NewBuffer(nil) 576 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 577 578 res := buf.String() 579 assertInCode(t, "type WithMapInterface struct {", res) 580 assertInCode(t, "ExtraInfo map[string]interface{} `json:\"extraInfo\"`", res) 581 } 582 583 func TestGenerateModel_WithMapRef(t *testing.T) { 584 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 585 require.NoError(t, err) 586 587 definitions := specDoc.Spec().Definitions 588 k := "WithMapRef" 589 schema := definitions[k] 590 opts := opts() 591 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 592 require.NoError(t, err) 593 594 assert.False(t, genModel.HasAdditionalProperties) 595 prop := getDefinitionProperty(genModel, "data") 596 assert.True(t, prop.HasAdditionalProperties) 597 assert.True(t, prop.IsMap) 598 assert.False(t, prop.IsComplexObject) 599 buf := bytes.NewBuffer(nil) 600 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 601 602 res := buf.String() 603 assertInCode(t, "type "+k+" struct {", res) 604 assertInCode(t, "Data map[string]Notable `json:\"data,omitempty\"`", res) 605 } 606 607 func TestGenerateModel_WithMapComplex(t *testing.T) { 608 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 609 require.NoError(t, err) 610 611 definitions := specDoc.Spec().Definitions 612 k := "WithMapComplex" 613 schema := definitions[k] 614 opts := opts() 615 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 616 require.NoError(t, err) 617 618 assert.False(t, genModel.HasAdditionalProperties) 619 prop := getDefinitionProperty(genModel, "data") 620 assert.True(t, prop.HasAdditionalProperties) 621 assert.True(t, prop.IsMap) 622 assert.False(t, prop.IsComplexObject) 623 buf := bytes.NewBuffer(nil) 624 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 625 626 res := buf.String() 627 assertInCode(t, "type "+k+" struct {", res) 628 assertInCode(t, "Data map[string]"+k+"DataAnon `json:\"data,omitempty\"`", res) 629 } 630 631 func TestGenerateModel_WithMapRegistry(t *testing.T) { 632 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 633 require.NoError(t, err) 634 635 definitions := specDoc.Spec().Definitions 636 schema := definitions["WithMapRegistry"] 637 opts := opts() 638 genModel, err := makeGenDefinition("WithMap", "models", schema, specDoc, opts) 639 require.NoError(t, err) 640 641 assert.False(t, genModel.HasAdditionalProperties) 642 prop := getDefinitionProperty(genModel, "data") 643 assert.True(t, prop.HasAdditionalProperties) 644 assert.True(t, prop.IsMap) 645 assert.False(t, prop.IsComplexObject) 646 buf := bytes.NewBuffer(nil) 647 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 648 649 res := buf.String() 650 assertInCode(t, "type WithMap struct {", res) 651 assertInCode(t, "Data map[string]map[string]map[string]string `json:\"data,omitempty\"`", res) 652 } 653 654 func TestGenerateModel_WithMapRegistryRef(t *testing.T) { 655 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 656 require.NoError(t, err) 657 658 definitions := specDoc.Spec().Definitions 659 k := "WithMapRegistryRef" 660 schema := definitions[k] 661 opts := opts() 662 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 663 require.NoError(t, err) 664 665 assert.False(t, genModel.HasAdditionalProperties) 666 prop := getDefinitionProperty(genModel, "data") 667 assert.True(t, prop.HasAdditionalProperties) 668 assert.True(t, prop.IsMap) 669 assert.False(t, prop.IsComplexObject) 670 buf := bytes.NewBuffer(nil) 671 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 672 673 res := buf.String() 674 assertInCode(t, "type "+k+" struct {", res) 675 assertInCode(t, "Data map[string]map[string]map[string]Notable `json:\"data,omitempty\"`", res) 676 } 677 678 func TestGenerateModel_WithMapComplexRegistry(t *testing.T) { 679 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 680 require.NoError(t, err) 681 682 definitions := specDoc.Spec().Definitions 683 k := "WithMapComplexRegistry" 684 schema := definitions[k] 685 opts := opts() 686 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 687 require.NoError(t, err) 688 689 assert.False(t, genModel.HasAdditionalProperties) 690 prop := getDefinitionProperty(genModel, "data") 691 assert.True(t, prop.HasAdditionalProperties) 692 assert.True(t, prop.IsMap) 693 assert.False(t, prop.IsComplexObject) 694 buf := bytes.NewBuffer(nil) 695 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 696 697 res := buf.String() 698 assertInCode(t, "type "+k+" struct {", res) 699 assertInCode(t, "Data map[string]map[string]map[string]"+k+"DataAnon `json:\"data,omitempty\"`", res) 700 } 701 702 func TestGenerateModel_WithAdditional(t *testing.T) { 703 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 704 require.NoError(t, err) 705 706 definitions := specDoc.Spec().Definitions 707 k := "WithAdditional" 708 schema := definitions[k] 709 opts := opts() 710 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 711 require.NoError(t, err) 712 require.NotEmpty(t, genModel.ExtraSchemas) 713 714 assert.False(t, genModel.HasAdditionalProperties) 715 assert.False(t, genModel.IsMap) 716 assert.False(t, genModel.IsAdditionalProperties) 717 assert.True(t, genModel.IsComplexObject) 718 719 sch := genModel.ExtraSchemas[0] 720 assert.True(t, sch.HasAdditionalProperties) 721 assert.False(t, sch.IsMap) 722 assert.True(t, sch.IsAdditionalProperties) 723 assert.False(t, sch.IsComplexObject) 724 725 require.NotNil(t, sch.AdditionalProperties) 726 727 prop := findProperty(genModel.Properties, "data") 728 assert.False(t, prop.HasAdditionalProperties) 729 assert.False(t, prop.IsMap) 730 assert.False(t, prop.IsAdditionalProperties) 731 assert.True(t, prop.IsComplexObject) 732 buf := bytes.NewBuffer(nil) 733 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 734 735 res := buf.String() 736 assertInCode(t, "type "+k+" struct {", res) 737 assertInCode(t, "Data *"+k+"Data `json:\"data,omitempty\"`", res) 738 assertInCode(t, "type "+k+"Data struct {", res) 739 assertInCode(t, k+"Data map[string]string `json:\"-\"`", res) 740 assertInCode(t, "Name *string `json:\"name\"`", res) 741 assertInCode(t, k+"Data) UnmarshalJSON", res) 742 assertInCode(t, k+"Data) MarshalJSON", res) 743 assertInCode(t, "json.Marshal(stage1)", res) 744 assertInCode(t, "stage1.Name = m.Name", res) 745 assertInCode(t, "json.Marshal(m."+k+"Data)", res) 746 assertInCode(t, "json.Unmarshal(data, &stage1)", res) 747 assertInCode(t, "json.Unmarshal(data, &stage2)", res) 748 assertInCode(t, "json.Unmarshal(v, &toadd)", res) 749 assertInCode(t, "result[k] = toadd", res) 750 assertInCode(t, "m."+k+"Data = result", res) 751 752 for _, p := range sch.Properties { 753 assertInCode(t, "delete(stage2, \""+p.Name+"\")", res) 754 } 755 } 756 757 func TestGenerateModel_JustRef(t *testing.T) { 758 tt := templateTest{t, templates.MustGet("model").Lookup("schema")} 759 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 760 require.NoError(t, err) 761 762 definitions := specDoc.Spec().Definitions 763 schema := definitions["JustRef"] 764 opts := opts() 765 genModel, err := makeGenDefinition("JustRef", "models", schema, specDoc, opts) 766 require.NoError(t, err) 767 768 assert.NotEmpty(t, genModel.AllOf) 769 assert.True(t, genModel.IsComplexObject) 770 assert.Equal(t, "JustRef", genModel.Name) 771 assert.Equal(t, "JustRef", genModel.GoType) 772 buf := bytes.NewBuffer(nil) 773 require.NoError(t, tt.template.Execute(buf, genModel)) 774 775 res := buf.String() 776 assertInCode(t, "type JustRef struct {", res) 777 assertInCode(t, "Notable", res) 778 } 779 780 func TestGenerateModel_WithRef(t *testing.T) { 781 tt := templateTest{t, templates.MustGet("model").Lookup("schema")} 782 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 783 require.NoError(t, err) 784 785 definitions := specDoc.Spec().Definitions 786 schema := definitions["WithRef"] 787 opts := opts() 788 genModel, err := makeGenDefinition("WithRef", "models", schema, specDoc, opts) 789 require.NoError(t, err) 790 791 assert.True(t, genModel.IsComplexObject) 792 assert.Equal(t, "WithRef", genModel.Name) 793 assert.Equal(t, "WithRef", genModel.GoType) 794 buf := bytes.NewBuffer(nil) 795 require.NoError(t, tt.template.Execute(buf, genModel)) 796 797 res := buf.String() 798 assertInCode(t, "type WithRef struct {", res) 799 assertInCode(t, "Notes *Notable `json:\"notes,omitempty\"`", res) 800 } 801 802 func TestGenerateModel_WithNullableRef(t *testing.T) { 803 tt := templateTest{t, templates.MustGet("model").Lookup("schema")} 804 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 805 require.NoError(t, err) 806 807 definitions := specDoc.Spec().Definitions 808 schema := definitions["WithNullableRef"] 809 opts := opts() 810 genModel, err := makeGenDefinition("WithNullableRef", "models", schema, specDoc, opts) 811 require.NoError(t, err) 812 813 assert.True(t, genModel.IsComplexObject) 814 assert.Equal(t, "WithNullableRef", genModel.Name) 815 assert.Equal(t, "WithNullableRef", genModel.GoType) 816 prop := getDefinitionProperty(genModel, "notes") 817 assert.True(t, prop.IsNullable) 818 assert.True(t, prop.IsComplexObject) 819 buf := bytes.NewBuffer(nil) 820 require.NoError(t, tt.template.Execute(buf, genModel)) 821 822 res := buf.String() 823 assertInCode(t, "type WithNullableRef struct {", res) 824 assertInCode(t, "Notes *Notable `json:\"notes,omitempty\"`", res) 825 } 826 827 func TestGenerateModel_Scores(t *testing.T) { 828 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 829 require.NoError(t, err) 830 831 definitions := specDoc.Spec().Definitions 832 k := "Scores" 833 schema := definitions[k] 834 opts := opts() 835 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 836 require.NoError(t, err) 837 838 buf := bytes.NewBuffer(nil) 839 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 840 841 ff, err := opts.LanguageOpts.FormatContent("scores.go", buf.Bytes()) 842 require.NoError(t, err) 843 844 assertInCode(t, "type Scores []float32", string(ff)) 845 } 846 847 func TestGenerateModel_JaggedScores(t *testing.T) { 848 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 849 require.NoError(t, err) 850 851 definitions := specDoc.Spec().Definitions 852 k := "JaggedScores" 853 schema := definitions[k] 854 opts := opts() 855 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 856 require.NoError(t, err) 857 858 buf := bytes.NewBuffer(nil) 859 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 860 861 ff, err := opts.LanguageOpts.FormatContent("jagged_scores.go", buf.Bytes()) 862 require.NoError(t, err) 863 864 assertInCode(t, "type JaggedScores [][][]float32", string(ff)) 865 } 866 867 func TestGenerateModel_Notables(t *testing.T) { 868 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 869 require.NoError(t, err) 870 871 definitions := specDoc.Spec().Definitions 872 k := "Notables" 873 schema := definitions[k] 874 opts := opts() 875 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 876 require.NoError(t, err) 877 require.Equal(t, "[]*Notable", genModel.GoType) 878 879 buf := bytes.NewBuffer(nil) 880 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 881 require.NoError(t, err) 882 883 ff, err := opts.LanguageOpts.FormatContent("notables.go", buf.Bytes()) 884 require.NoError(t, err) 885 886 res := string(ff) 887 assertInCode(t, "type Notables []*Notable", res) 888 } 889 890 func TestGenerateModel_Notablix(t *testing.T) { 891 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 892 require.NoError(t, err) 893 894 definitions := specDoc.Spec().Definitions 895 k := "Notablix" 896 schema := definitions[k] 897 opts := opts() 898 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 899 require.NoError(t, err) 900 901 buf := bytes.NewBuffer(nil) 902 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 903 904 ff, err := opts.LanguageOpts.FormatContent("notablix.go", buf.Bytes()) 905 require.NoError(t, err) 906 907 res := string(ff) 908 assertInCode(t, "type Notablix [][][]*Notable", res) 909 } 910 911 func TestGenerateModel_Stats(t *testing.T) { 912 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 913 require.NoError(t, err) 914 915 definitions := specDoc.Spec().Definitions 916 k := "Stats" 917 schema := definitions[k] 918 opts := opts() 919 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 920 require.NoError(t, err) 921 922 buf := bytes.NewBuffer(nil) 923 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 924 925 ff, err := opts.LanguageOpts.FormatContent("stats.go", buf.Bytes()) 926 require.NoError(t, err) 927 928 res := string(ff) 929 assertInCode(t, "type Stats []*StatsItems0", res) 930 assertInCode(t, "type StatsItems0 struct {", res) 931 assertInCode(t, "Points []int64 `json:\"points\"`", res) 932 } 933 934 func TestGenerateModel_Statix(t *testing.T) { 935 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 936 require.NoError(t, err) 937 938 definitions := specDoc.Spec().Definitions 939 k := "Statix" 940 schema := definitions[k] 941 opts := opts() 942 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 943 require.NoError(t, err) 944 945 buf := bytes.NewBuffer(nil) 946 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 947 948 ff, err := opts.LanguageOpts.FormatContent("statix.go", buf.Bytes()) 949 require.NoError(t, err) 950 951 res := string(ff) 952 assertInCode(t, "type Statix [][][]*StatixItems0", res) 953 assertInCode(t, "type StatixItems0 struct {", res) 954 assertInCode(t, "Points []int64 `json:\"points\"`", res) 955 } 956 957 func TestGenerateModel_WithItems(t *testing.T) { 958 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 959 require.NoError(t, err) 960 961 definitions := specDoc.Spec().Definitions 962 schema := definitions["WithItems"] 963 opts := opts() 964 tt := templateTest{t, opts.templates.MustGet("model").Lookup("schema")} 965 966 genModel, err := makeGenDefinition("WithItems", "models", schema, specDoc, opts) 967 require.NoError(t, err) 968 969 assert.Nil(t, genModel.Items) 970 assert.True(t, genModel.IsComplexObject) 971 prop := getDefinitionProperty(genModel, "tags") 972 973 assert.NotNil(t, prop.Items) 974 assert.True(t, prop.IsArray) 975 assert.False(t, prop.IsComplexObject) 976 977 buf := bytes.NewBuffer(nil) 978 require.NoError(t, tt.template.Execute(buf, genModel)) 979 980 res := buf.String() 981 assertInCode(t, "type WithItems struct {", res) 982 assertInCode(t, "Tags []string `json:\"tags\"`", res) 983 } 984 985 func TestGenerateModel_WithComplexItems(t *testing.T) { 986 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 987 require.NoError(t, err) 988 989 definitions := specDoc.Spec().Definitions 990 k := "WithComplexItems" 991 schema := definitions[k] 992 opts := opts() 993 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 994 require.NoError(t, err) 995 996 assert.Nil(t, genModel.Items) 997 assert.True(t, genModel.IsComplexObject) 998 prop := getDefinitionProperty(genModel, "tags") 999 assert.NotNil(t, prop.Items) 1000 assert.True(t, prop.IsArray) 1001 assert.False(t, prop.IsComplexObject) 1002 buf := bytes.NewBuffer(nil) 1003 1004 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1005 1006 b, err := opts.LanguageOpts.FormatContent("with_complex_items.go", buf.Bytes()) 1007 require.NoError(t, err) 1008 1009 res := string(b) 1010 assertInCode(t, "type WithComplexItems struct {", res) 1011 assertInCode(t, "type WithComplexItemsTagsItems0 struct {", res) 1012 assertInCode(t, "Tags []*WithComplexItemsTagsItems0 `json:\"tags\"`", res) 1013 } 1014 1015 func TestGenerateModel_WithItemsAndAdditional(t *testing.T) { 1016 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1017 require.NoError(t, err) 1018 1019 definitions := specDoc.Spec().Definitions 1020 k := "WithItemsAndAdditional" 1021 schema := definitions[k] 1022 opts := opts() 1023 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 1024 require.NoError(t, err) 1025 1026 assert.Nil(t, genModel.Items) 1027 assert.True(t, genModel.IsComplexObject) 1028 prop := getDefinitionProperty(genModel, "tags") 1029 assert.True(t, prop.IsComplexObject) 1030 buf := bytes.NewBuffer(nil) 1031 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1032 1033 b, err := opts.LanguageOpts.FormatContent("with_complex_items.go", buf.Bytes()) 1034 require.NoError(t, err) 1035 1036 res := string(b) 1037 assertInCode(t, "type "+k+" struct {", res) 1038 assertInCode(t, "type "+k+"TagsTuple0 struct {", res) 1039 // this would fail if it accepts additionalItems because it would come out as []interface{} 1040 assertInCode(t, "Tags *"+k+"TagsTuple0 `json:\"tags,omitempty\"`", res) 1041 assertInCode(t, "P0 *string `json:\"-\"`", res) 1042 assertInCode(t, k+"TagsTuple0Items []interface{} `json:\"-\"`", res) 1043 } 1044 1045 func TestGenerateModel_WithItemsAndAdditional2(t *testing.T) { 1046 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1047 require.NoError(t, err) 1048 1049 definitions := specDoc.Spec().Definitions 1050 k := "WithItemsAndAdditional2" 1051 schema := definitions[k] 1052 opts := opts() 1053 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 1054 require.NoError(t, err) 1055 1056 assert.Nil(t, genModel.Items) 1057 assert.True(t, genModel.IsComplexObject) 1058 prop := getDefinitionProperty(genModel, "tags") 1059 assert.True(t, prop.IsComplexObject) 1060 buf := bytes.NewBuffer(nil) 1061 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1062 1063 b, err := opts.LanguageOpts.FormatContent("with_complex_items.go", buf.Bytes()) 1064 require.NoError(t, err) 1065 1066 res := string(b) 1067 assertInCode(t, "type "+k+" struct {", res) 1068 assertInCode(t, "type "+k+"TagsTuple0 struct {", res) 1069 // this would fail if it accepts additionalItems because it would come out as []interface{} 1070 assertInCode(t, "P0 *string `json:\"-\"`", res) 1071 assertInCode(t, "Tags *"+k+"TagsTuple0 `json:\"tags,omitempty\"`", res) 1072 assertInCode(t, k+"TagsTuple0Items []int32 `json:\"-\"`", res) 1073 } 1074 1075 func TestGenerateModel_WithComplexAdditional(t *testing.T) { 1076 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1077 require.NoError(t, err) 1078 1079 definitions := specDoc.Spec().Definitions 1080 k := "WithComplexAdditional" 1081 schema := definitions[k] 1082 opts := opts() 1083 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 1084 require.NoError(t, err) 1085 1086 assert.Nil(t, genModel.Items) 1087 assert.True(t, genModel.IsComplexObject) 1088 prop := getDefinitionProperty(genModel, "tags") 1089 assert.True(t, prop.IsComplexObject) 1090 buf := bytes.NewBuffer(nil) 1091 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1092 1093 b, err := opts.LanguageOpts.FormatContent("with_complex_additional.go", buf.Bytes()) 1094 require.NoError(t, err) 1095 1096 res := string(b) 1097 assertInCode(t, "type WithComplexAdditional struct {", res) 1098 assertInCode(t, "type WithComplexAdditionalTagsTuple0 struct {", res) 1099 assertInCode(t, "Tags *WithComplexAdditionalTagsTuple0 `json:\"tags,omitempty\"`", res) 1100 assertInCode(t, "P0 *string `json:\"-\"`", res) 1101 assertInCode(t, "WithComplexAdditionalTagsTuple0Items []*WithComplexAdditionalTagsItems `json:\"-\"`", res) 1102 } 1103 1104 func TestGenerateModel_SimpleTuple(t *testing.T) { 1105 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1106 require.NoError(t, err) 1107 1108 definitions := specDoc.Spec().Definitions 1109 k := "SimpleTuple" 1110 schema := definitions[k] 1111 opts := opts() 1112 1113 tt := templateTest{t, opts.templates.MustGet("model")} 1114 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 1115 require.NoError(t, err) 1116 require.Len(t, genModel.ExtraSchemas, 1) 1117 1118 // NOTE: with PR#1592, an extra schema is added here because of the allOf tuple element. 1119 // This uncovers another issue with special AllOfs (e.g. allOf [ ..., x-nullable:true ]) 1120 // TODO(fredbi): fix liftSpecialAllOf() to revert to: assert.Empty(t, genModel.ExtraSchemas) 1121 assert.True(t, genModel.IsTuple) 1122 assert.False(t, genModel.IsComplexObject) 1123 assert.False(t, genModel.IsArray) 1124 assert.False(t, genModel.IsAnonymous) 1125 assert.Equal(t, k, genModel.Name) 1126 assert.Equal(t, k, genModel.GoType) 1127 assert.Len(t, genModel.Properties, 5) 1128 buf := bytes.NewBuffer(nil) 1129 require.NoError(t, tt.template.Execute(buf, genModel)) 1130 1131 res := buf.String() 1132 assertInCode(t, "swagger:model "+k, res) 1133 assertInCode(t, "type "+k+" struct {", res) 1134 assertInCode(t, "P0 *int64 `json:\"-\"`", res) 1135 assertInCode(t, "P1 *string `json:\"-\"`", res) 1136 assertInCode(t, "P2 *strfmt.DateTime `json:\"-\"`", res) 1137 assertInCode(t, "P3 *Notable `json:\"-\"`", res) 1138 // NOTE: with PR#1592, an extra schema is added here because of the allOf tuple element. 1139 // This uncovers another issue with special AllOfs (e.g. allOf [ ..., x-nullable:true ]) 1140 // TODO(fredbi): fix liftSpecialAllOf() to revert to: assert.Empty(t, genModel.ExtraSchemas) 1141 // assertInCode(t, "P4 *Notable `json:\"-\"`", res) 1142 assertInCode(t, "P4 *SimpleTupleItems4 `json:\"-\"`", res) 1143 assertInCode(t, k+") UnmarshalJSON", res) 1144 assertInCode(t, k+") MarshalJSON", res) 1145 assertInCode(t, "json.Marshal(data)", res) 1146 assert.NotRegexp(t, regexp.MustCompile("lastIndex"), res) 1147 1148 for i, p := range genModel.Properties { 1149 m := "m.P" + strconv.Itoa(i) 1150 r := "&dataP" + strconv.Itoa(i) 1151 var rr string 1152 if !p.IsNullable { 1153 rr = "dataP" + strconv.Itoa(i) 1154 } else { 1155 rr = r 1156 } 1157 assertInCode(t, fmt.Sprintf("buf = bytes.NewBuffer(stage1[%d])", i), res) 1158 assertInCode(t, fmt.Sprintf("dec.Decode(%s)", r), res) 1159 assertInCode(t, "P"+strconv.Itoa(i)+",", res) 1160 assertInCode(t, fmt.Sprintf("%s = %s", m, rr), res) 1161 } 1162 } 1163 1164 func TestGenerateModel_TupleWithExtra(t *testing.T) { 1165 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1166 require.NoError(t, err) 1167 1168 definitions := specDoc.Spec().Definitions 1169 k := "TupleWithExtra" 1170 schema := definitions[k] 1171 opts := opts() 1172 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 1173 require.NoError(t, err) 1174 require.Empty(t, genModel.ExtraSchemas) 1175 1176 assert.True(t, genModel.IsTuple) 1177 assert.False(t, genModel.IsComplexObject) 1178 assert.False(t, genModel.IsArray) 1179 assert.False(t, genModel.IsAnonymous) 1180 assert.True(t, genModel.HasAdditionalItems) 1181 assert.NotNil(t, genModel.AdditionalItems) 1182 assert.Equal(t, k, genModel.Name) 1183 assert.Equal(t, k, genModel.GoType) 1184 assert.Len(t, genModel.Properties, 4) 1185 buf := bytes.NewBuffer(nil) 1186 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1187 1188 ff, err := opts.LanguageOpts.FormatContent("tuple_with_extra.go", buf.Bytes()) 1189 require.NoError(t, err) 1190 1191 res := string(ff) 1192 assertInCode(t, "swagger:model "+k, res) 1193 assertInCode(t, "type "+k+" struct {", res) 1194 assertInCode(t, "P0 *int64 `json:\"-\"`", res) 1195 assertInCode(t, "P1 *string `json:\"-\"`", res) 1196 assertInCode(t, "P2 *strfmt.DateTime `json:\"-\"`", res) 1197 assertInCode(t, "P3 *Notable `json:\"-\"`", res) 1198 assertInCode(t, k+"Items []float64 `json:\"-\"`", res) 1199 assertInCode(t, k+") UnmarshalJSON", res) 1200 assertInCode(t, k+") MarshalJSON", res) 1201 1202 for i, p := range genModel.Properties { 1203 m := "m.P" + strconv.Itoa(i) 1204 r := "&dataP" + strconv.Itoa(i) 1205 var rr string 1206 if !p.IsNullable { 1207 rr = "dataP" + strconv.Itoa(i) 1208 } else { 1209 rr = r 1210 } 1211 assertInCode(t, fmt.Sprintf("lastIndex = %d", i), res) 1212 assertInCode(t, fmt.Sprintf("buf = bytes.NewBuffer(stage1[%d])", i), res) 1213 assertInCode(t, "dec := json.NewDecoder(buf)", res) 1214 assertInCode(t, fmt.Sprintf("dec.Decode(%s)", r), res) 1215 assertInCode(t, "P"+strconv.Itoa(i)+",", res) 1216 assertInCode(t, fmt.Sprintf("%s = %s", m, rr), res) 1217 } 1218 1219 assertInCode(t, "var lastIndex int", res) 1220 assertInCode(t, "var toadd float64", res) 1221 assertInCode(t, "for _, val := range stage1[lastIndex+1:]", res) 1222 assertInCode(t, "buf = bytes.NewBuffer(val)", res) 1223 assertInCode(t, "dec := json.NewDecoder(buf)", res) 1224 assertInCode(t, "dec.Decode(&toadd)", res) 1225 assertInCode(t, "json.Marshal(data)", res) 1226 assertInCode(t, "for _, v := range m."+k+"Items", res) 1227 } 1228 1229 func TestGenerateModel_TupleWithComplex(t *testing.T) { 1230 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1231 require.NoError(t, err) 1232 1233 definitions := specDoc.Spec().Definitions 1234 k := "TupleWithComplex" 1235 schema := definitions[k] 1236 opts := opts() 1237 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 1238 require.NoError(t, err) 1239 1240 assert.True(t, genModel.IsTuple) 1241 assert.False(t, genModel.IsComplexObject) 1242 assert.False(t, genModel.IsArray) 1243 assert.False(t, genModel.IsAnonymous) 1244 assert.True(t, genModel.HasAdditionalItems) 1245 assert.NotNil(t, genModel.AdditionalItems) 1246 assert.Equal(t, k, genModel.Name) 1247 assert.Equal(t, k, genModel.GoType) 1248 assert.Len(t, genModel.Properties, 4) 1249 buf := bytes.NewBuffer(nil) 1250 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1251 1252 ff, err := opts.LanguageOpts.FormatContent("tuple_with_extra.go", buf.Bytes()) 1253 require.NoError(t, err) 1254 1255 res := string(ff) 1256 assertInCode(t, "swagger:model "+k, res) 1257 assertInCode(t, "type "+k+" struct {", res) 1258 assertInCode(t, "P0 *int64 `json:\"-\"`", res) 1259 assertInCode(t, "P1 *string `json:\"-\"`", res) 1260 assertInCode(t, "P2 *strfmt.DateTime `json:\"-\"`", res) 1261 assertInCode(t, "P3 *Notable `json:\"-\"`", res) 1262 assertInCode(t, k+"Items []*TupleWithComplexItems `json:\"-\"`", res) 1263 assertInCode(t, k+") UnmarshalJSON", res) 1264 assertInCode(t, k+") MarshalJSON", res) 1265 1266 for i, p := range genModel.Properties { 1267 m := "m.P" + strconv.Itoa(i) 1268 r := "&dataP" + strconv.Itoa(i) 1269 var rr string 1270 if !p.IsNullable { 1271 rr = "dataP" + strconv.Itoa(i) 1272 } else { 1273 rr = r 1274 } 1275 assertInCode(t, fmt.Sprintf("lastIndex = %d", i), res) 1276 assertInCode(t, fmt.Sprintf("buf = bytes.NewBuffer(stage1[%d])", i), res) 1277 assertInCode(t, "dec := json.NewDecoder(buf)", res) 1278 assertInCode(t, fmt.Sprintf("dec.Decode(%s)", r), res) 1279 assertInCode(t, "P"+strconv.Itoa(i)+",", res) 1280 assertInCode(t, fmt.Sprintf("%s = %s", m, rr), res) 1281 } 1282 1283 assertInCode(t, "var lastIndex int", res) 1284 assertInCode(t, "var toadd *TupleWithComplexItems", res) 1285 assertInCode(t, "for _, val := range stage1[lastIndex+1:]", res) 1286 assertInCode(t, "buf = bytes.NewBuffer(val)", res) 1287 assertInCode(t, "dec := json.NewDecoder(buf)", res) 1288 assertInCode(t, "dec.Decode(toadd)", res) 1289 assertInCode(t, "json.Marshal(data)", res) 1290 assertInCode(t, "for _, v := range m."+k+"Items", res) 1291 } 1292 1293 func TestGenerateModel_WithTuple(t *testing.T) { 1294 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1295 require.NoError(t, err) 1296 1297 definitions := specDoc.Spec().Definitions 1298 k := "WithTuple" 1299 schema := definitions[k] 1300 opts := opts() 1301 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 1302 require.NoError(t, err) 1303 require.NotEmpty(t, genModel.ExtraSchemas) 1304 require.NotEmpty(t, genModel.Properties) 1305 1306 assert.False(t, genModel.IsTuple) 1307 assert.True(t, genModel.IsComplexObject) 1308 assert.False(t, genModel.IsArray) 1309 assert.False(t, genModel.IsAnonymous) 1310 1311 sch := genModel.ExtraSchemas[0] 1312 assert.True(t, sch.IsTuple) 1313 assert.False(t, sch.IsComplexObject) 1314 assert.False(t, sch.IsArray) 1315 assert.False(t, sch.IsAnonymous) 1316 assert.Equal(t, k+"FlagsTuple0", sch.Name) 1317 assert.False(t, sch.HasAdditionalItems) 1318 assert.Nil(t, sch.AdditionalItems) 1319 1320 prop := genModel.Properties[0] 1321 assert.False(t, genModel.IsTuple) 1322 assert.True(t, genModel.IsComplexObject) 1323 assert.False(t, prop.IsArray) 1324 assert.False(t, prop.IsAnonymous) 1325 assert.Equal(t, k+"FlagsTuple0", prop.GoType) 1326 assert.Equal(t, "flags", prop.Name) 1327 buf := bytes.NewBuffer(nil) 1328 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1329 1330 ff, err := opts.LanguageOpts.FormatContent("with_tuple.go", buf.Bytes()) 1331 require.NoError(t, err) 1332 1333 res := string(ff) 1334 assertInCode(t, "swagger:model "+k+"Flags", res) 1335 assertInCode(t, "type "+k+"FlagsTuple0 struct {", res) 1336 assertInCode(t, "P0 *int64 `json:\"-\"`", res) 1337 assertInCode(t, "P1 *string `json:\"-\"`", res) 1338 assertInCode(t, k+"FlagsTuple0) UnmarshalJSON", res) 1339 assertInCode(t, k+"FlagsTuple0) MarshalJSON", res) 1340 assertInCode(t, "json.Marshal(data)", res) 1341 assert.NotRegexp(t, regexp.MustCompile("lastIndex"), res) 1342 1343 for i, p := range sch.Properties { 1344 m := "m.P" + strconv.Itoa(i) 1345 r := "&dataP" + strconv.Itoa(i) 1346 var rr string 1347 if !p.IsNullable { 1348 rr = "dataP" + strconv.Itoa(i) 1349 } else { 1350 rr = r 1351 } 1352 assertInCode(t, fmt.Sprintf("buf = bytes.NewBuffer(stage1[%d])", i), res) 1353 assertInCode(t, "dec := json.NewDecoder(buf)", res) 1354 assertInCode(t, fmt.Sprintf("dec.Decode(%s)", r), res) 1355 assertInCode(t, "P"+strconv.Itoa(i)+",", res) 1356 assertInCode(t, fmt.Sprintf("%s = %s", m, rr), res) 1357 } 1358 } 1359 1360 func TestGenerateModel_WithTupleWithExtra(t *testing.T) { 1361 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1362 require.NoError(t, err) 1363 1364 definitions := specDoc.Spec().Definitions 1365 k := "WithTupleWithExtra" 1366 schema := definitions[k] 1367 opts := opts() 1368 tt := templateTest{t, opts.templates.MustGet("model")} 1369 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 1370 require.NoError(t, err) 1371 require.NotEmpty(t, genModel.ExtraSchemas) 1372 require.NotEmpty(t, genModel.Properties) 1373 1374 assert.False(t, genModel.IsTuple) 1375 assert.True(t, genModel.IsComplexObject) 1376 assert.False(t, genModel.IsArray) 1377 assert.False(t, genModel.IsAnonymous) 1378 1379 sch := genModel.ExtraSchemas[0] 1380 assert.True(t, sch.IsTuple) 1381 assert.False(t, sch.IsComplexObject) 1382 assert.False(t, sch.IsArray) 1383 assert.False(t, sch.IsAnonymous) 1384 assert.Equal(t, k+"FlagsTuple0", sch.Name) 1385 assert.True(t, sch.HasAdditionalItems) 1386 assert.NotEmpty(t, sch.AdditionalItems) 1387 1388 prop := genModel.Properties[0] 1389 assert.False(t, genModel.IsTuple) 1390 assert.True(t, genModel.IsComplexObject) 1391 assert.False(t, prop.IsArray) 1392 assert.False(t, prop.IsAnonymous) 1393 assert.Equal(t, k+"FlagsTuple0", prop.GoType) 1394 assert.Equal(t, "flags", prop.Name) 1395 buf := bytes.NewBuffer(nil) 1396 require.NoError(t, tt.template.Execute(buf, genModel)) 1397 1398 ff, err := opts.LanguageOpts.FormatContent("with_tuple.go", buf.Bytes()) 1399 require.NoError(t, err) 1400 1401 res := string(ff) 1402 assertInCode(t, "swagger:model "+k+"Flags", res) 1403 assertInCode(t, "type "+k+"FlagsTuple0 struct {", res) 1404 assertInCode(t, "P0 *int64 `json:\"-\"`", res) 1405 assertInCode(t, "P1 *string `json:\"-\"`", res) 1406 assertInCode(t, k+"FlagsTuple0Items []float32 `json:\"-\"`", res) 1407 assertInCode(t, k+"FlagsTuple0) UnmarshalJSON", res) 1408 assertInCode(t, k+"FlagsTuple0) MarshalJSON", res) 1409 assertInCode(t, "json.Marshal(data)", res) 1410 1411 for i, p := range sch.Properties { 1412 m := "m.P" + strconv.Itoa(i) 1413 r := "&dataP" + strconv.Itoa(i) 1414 var rr string 1415 if !p.IsNullable { 1416 rr = "dataP" + strconv.Itoa(i) 1417 } else { 1418 rr = r 1419 } 1420 assertInCode(t, fmt.Sprintf("lastIndex = %d", i), res) 1421 assertInCode(t, fmt.Sprintf("buf = bytes.NewBuffer(stage1[%d])", i), res) 1422 assertInCode(t, "dec := json.NewDecoder(buf)", res) 1423 assertInCode(t, fmt.Sprintf("dec.Decode(%s)", r), res) 1424 assertInCode(t, "P"+strconv.Itoa(i)+",", res) 1425 assertInCode(t, fmt.Sprintf("%s = %s", m, rr), res) 1426 } 1427 1428 assertInCode(t, "var lastIndex int", res) 1429 assertInCode(t, "var toadd float32", res) 1430 assertInCode(t, "for _, val := range stage1[lastIndex+1:]", res) 1431 assertInCode(t, "buf = bytes.NewBuffer(val)", res) 1432 assertInCode(t, "dec := json.NewDecoder(buf)", res) 1433 assertInCode(t, "dec.Decode(&toadd)", res) 1434 assertInCode(t, "json.Marshal(data)", res) 1435 assertInCode(t, "for _, v := range m."+k+"FlagsTuple0Items", res) 1436 } 1437 1438 func TestGenerateModel_WithAllOfAndDiscriminator(t *testing.T) { 1439 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1440 require.NoError(t, err) 1441 1442 definitions := specDoc.Spec().Definitions 1443 schema := definitions["Cat"] 1444 opts := opts() 1445 genModel, err := makeGenDefinition("Cat", "models", schema, specDoc, opts) 1446 require.NoError(t, err) 1447 require.Len(t, genModel.AllOf, 2) 1448 1449 assert.True(t, genModel.IsComplexObject) 1450 assert.Equal(t, "Cat", genModel.Name) 1451 assert.Equal(t, "Cat", genModel.GoType) 1452 buf := bytes.NewBuffer(nil) 1453 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1454 1455 ct, err := opts.LanguageOpts.FormatContent("cat.go", buf.Bytes()) 1456 require.NoError(t, err) 1457 1458 res := string(ct) 1459 assertInCode(t, "type Cat struct {", res) 1460 assertInCode(t, "Pet", res) 1461 assertInCode(t, "HuntingSkill *string `json:\"huntingSkill\"`", res) 1462 } 1463 1464 func TestGenerateModel_WithAllOfAndDiscriminatorAndArrayOfPolymorphs(t *testing.T) { 1465 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1466 require.NoError(t, err) 1467 1468 definitions := specDoc.Spec().Definitions 1469 schema := definitions["PetWithPets"] 1470 opts := opts() 1471 genModel, err := makeGenDefinition("PetWithPets", "models", schema, specDoc, opts) 1472 require.NoError(t, err) 1473 require.Len(t, genModel.AllOf, 2) 1474 1475 assert.True(t, genModel.IsComplexObject) 1476 assert.Equal(t, "PetWithPets", genModel.Name) 1477 assert.Equal(t, "PetWithPets", genModel.GoType) 1478 buf := bytes.NewBuffer(nil) 1479 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1480 1481 ct, err := opts.LanguageOpts.FormatContent("PetWithPets.go", buf.Bytes()) 1482 require.NoError(t, err) 1483 1484 res := string(ct) 1485 assertInCode(t, "type PetWithPets struct {", res) 1486 assertInCode(t, "UnmarshalPetSlice", res) 1487 } 1488 1489 func TestGenerateModel_WithAllOf(t *testing.T) { 1490 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1491 require.NoError(t, err) 1492 1493 definitions := specDoc.Spec().Definitions 1494 schema := definitions["WithAllOf"] 1495 opts := opts() 1496 genModel, err := makeGenDefinition("WithAllOf", "models", schema, specDoc, opts) 1497 require.NoError(t, err) 1498 1499 assert.Len(t, genModel.AllOf, 7) 1500 assert.True(t, genModel.AllOf[1].HasAdditionalProperties) 1501 assert.True(t, genModel.IsComplexObject) 1502 assert.Equal(t, "WithAllOf", genModel.Name) 1503 assert.Equal(t, "WithAllOf", genModel.GoType) 1504 buf := bytes.NewBuffer(nil) 1505 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1506 1507 ct, err := opts.LanguageOpts.FormatContent("all_of_schema.go", buf.Bytes()) 1508 require.NoError(t, err) 1509 1510 res := string(ct) 1511 assertInCode(t, "type WithAllOf struct {", res) 1512 assertInCode(t, "type WithAllOfAO2P2 struct {", res) 1513 assertInCode(t, "type WithAllOfAO3P3 struct {", res) 1514 assertInCode(t, "type WithAllOfParamsAnon struct {", res) 1515 assertInCode(t, "type WithAllOfAO4Tuple4 struct {", res) 1516 assertInCode(t, "type WithAllOfAO5Tuple5 struct {", res) 1517 assertInCode(t, "Notable", res) 1518 assertInCode(t, "Title string `json:\"title,omitempty\"`", res) 1519 assertInCode(t, "Body string `json:\"body,omitempty\"`", res) 1520 assertInCode(t, "Name string `json:\"name,omitempty\"`", res) 1521 assertInCode(t, "P0 *float32 `json:\"-\"`", res) 1522 assertInCode(t, "P0 *float64 `json:\"-\"`", res) 1523 assertInCode(t, "P1 *strfmt.DateTime `json:\"-\"`", res) 1524 assertInCode(t, "P1 *strfmt.Date `json:\"-\"`", res) 1525 assertInCode(t, "Opinion string `json:\"opinion,omitempty\"`", res) 1526 assertInCode(t, "WithAllOfAO5Tuple5Items []strfmt.Password `json:\"-\"`", res) 1527 assertInCode(t, "AO1 map[string]int32 `json:\"-\"`", res) 1528 assertInCode(t, "WithAllOfAO2P2 map[string]int64 `json:\"-\"`", res) 1529 } 1530 1531 func findProperty(properties []GenSchema, name string) *GenSchema { 1532 for _, p := range properties { 1533 if p.Name == name { 1534 return &p 1535 } 1536 } 1537 return nil 1538 } 1539 1540 func getDefinitionProperty(genModel *GenDefinition, name string) *GenSchema { 1541 return findProperty(genModel.Properties, name) 1542 } 1543 1544 func TestNumericKeys(t *testing.T) { 1545 specDoc, err := loads.Spec("../fixtures/bugs/162/swagger.yml") 1546 require.NoError(t, err) 1547 1548 definitions := specDoc.Spec().Definitions 1549 schema := definitions["AvatarUrls"] 1550 opts := opts() 1551 genModel, err := makeGenDefinition("AvatarUrls", "models", schema, specDoc, opts) 1552 require.NoError(t, err) 1553 1554 buf := bytes.NewBuffer(nil) 1555 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1556 1557 ct, err := opts.LanguageOpts.FormatContent("all_of_schema.go", buf.Bytes()) 1558 require.NoError(t, err) 1559 1560 res := string(ct) 1561 assertInCode(t, "Nr16x16 string `json:\"16x16,omitempty\"`", res) 1562 } 1563 1564 func TestGenModel_Issue196(t *testing.T) { 1565 specDoc, err := loads.Spec("../fixtures/bugs/196/swagger.yml") 1566 require.NoError(t, err) 1567 1568 definitions := specDoc.Spec().Definitions 1569 schema := definitions["Event"] 1570 opts := opts() 1571 genModel, err := makeGenDefinition("Event", "models", schema, specDoc, opts) 1572 require.NoError(t, err) 1573 1574 buf := bytes.NewBuffer(nil) 1575 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1576 1577 ct, err := opts.LanguageOpts.FormatContent("primitive_event.go", buf.Bytes()) 1578 require.NoError(t, err) 1579 1580 res := string(ct) 1581 assertInCode(t, "Event) Validate(formats strfmt.Registry) error", res) 1582 } 1583 1584 func TestGenModel_Issue222(t *testing.T) { 1585 specDoc, err := loads.Spec("../fixtures/codegen/tasklist.basic.yml") 1586 require.NoError(t, err) 1587 1588 definitions := specDoc.Spec().Definitions 1589 k := "Price" 1590 opts := opts() 1591 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1592 require.NoError(t, err) 1593 require.True(t, genModel.HasValidations) 1594 1595 buf := bytes.NewBuffer(nil) 1596 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1597 1598 ct, err := opts.LanguageOpts.FormatContent("price.go", buf.Bytes()) 1599 require.NoError(t, err) 1600 1601 res := string(ct) 1602 assertInCode(t, "Price) Validate(formats strfmt.Registry) error", res) 1603 assertInCode(t, "Currency Currency `json:\"currency,omitempty\"`", res) 1604 assertInCode(t, "m.Currency.Validate(formats); err != nil", res) 1605 } 1606 1607 func TestGenModel_Issue243(t *testing.T) { 1608 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1609 require.NoError(t, err) 1610 1611 definitions := specDoc.Spec().Definitions 1612 k := "HasDynMeta" 1613 opts := opts() 1614 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1615 require.NoError(t, err) 1616 1617 buf := bytes.NewBuffer(nil) 1618 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1619 1620 ct, err := opts.LanguageOpts.FormatContent("has_dyn_meta.go", buf.Bytes()) 1621 require.NoError(t, err) 1622 1623 res := string(ct) 1624 assertInCode(t, "Metadata DynamicMetaData `json:\"metadata,omitempty\"`", res) 1625 } 1626 1627 func TestGenModel_Issue252(t *testing.T) { 1628 specDoc, err := loads.Spec("../fixtures/bugs/252/swagger.json") 1629 require.NoError(t, err) 1630 1631 definitions := specDoc.Spec().Definitions 1632 k := "SodaBrand" 1633 opts := opts() 1634 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1635 require.NoError(t, err) 1636 require.False(t, genModel.IsNullable) 1637 1638 buf := bytes.NewBuffer(nil) 1639 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1640 1641 ct, err := opts.LanguageOpts.FormatContent("soda_brand.go", buf.Bytes()) 1642 require.NoError(t, err) 1643 1644 res := string(ct) 1645 assertInCode(t, "type "+k+" string", res) 1646 assertInCode(t, "(m "+k+") validateSodaBrand", res) 1647 assertInCode(t, "(m "+k+") Validate", res) 1648 } 1649 1650 func TestGenModel_Issue251(t *testing.T) { 1651 specDoc, err := loads.Spec("../fixtures/bugs/251/swagger.yml") 1652 require.NoError(t, err) 1653 1654 definitions := specDoc.Spec().Definitions 1655 k := "example" 1656 opts := opts() 1657 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1658 require.NoError(t, err) 1659 1660 buf := bytes.NewBuffer(nil) 1661 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1662 1663 ct, err := opts.LanguageOpts.FormatContent("example.go", buf.Bytes()) 1664 require.NoError(t, err) 1665 1666 res := string(ct) 1667 1668 assertInCode(t, "type "+swag.ToGoName(k)+" struct", res) 1669 assertInCode(t, "Begin *strfmt.DateTime `json:\"begin\"`", res) 1670 assertInCode(t, "End strfmt.DateTime `json:\"end,omitempty\"`", res) 1671 assertInCode(t, "Name string `json:\"name,omitempty\"`", res) 1672 assertInCode(t, "(m *"+swag.ToGoName(k)+") validateBegin", res) 1673 assertInCode(t, "(m *"+swag.ToGoName(k)+") Validate", res) 1674 } 1675 1676 func TestGenModel_Issue257(t *testing.T) { 1677 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1678 require.NoError(t, err) 1679 1680 definitions := specDoc.Spec().Definitions 1681 k := "HasSpecialCharProp" 1682 opts := opts() 1683 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1684 require.NoError(t, err) 1685 1686 buf := bytes.NewBuffer(nil) 1687 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1688 1689 ct, err := opts.LanguageOpts.FormatContent("example.go", buf.Bytes()) 1690 require.NoError(t, err) 1691 1692 res := string(ct) 1693 1694 assertInCode(t, "type "+swag.ToGoName(k)+" struct", res) 1695 assertInCode(t, "AtType string `json:\"@type,omitempty\"`", res) 1696 assertInCode(t, "Type string `json:\"type,omitempty\"`", res) 1697 } 1698 1699 func TestGenModel_Issue340(t *testing.T) { 1700 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1701 require.NoError(t, err) 1702 1703 definitions := specDoc.Spec().Definitions 1704 k := "ImageTar" 1705 opts := opts() 1706 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1707 require.NoError(t, err) 1708 1709 buf := bytes.NewBuffer(nil) 1710 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1711 1712 ct, err := opts.LanguageOpts.FormatContent("image_tar.go", buf.Bytes()) 1713 require.NoError(t, err) 1714 1715 res := string(ct) 1716 1717 assertInCode(t, "type "+swag.ToGoName(k)+" io.ReadCloser", res) 1718 assertNotInCode(t, "func (m ImageTar) Validate(formats strfmt.Registry) error", res) 1719 } 1720 1721 func TestGenModel_Issue381(t *testing.T) { 1722 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1723 require.NoError(t, err) 1724 1725 definitions := specDoc.Spec().Definitions 1726 k := "flags_list" 1727 opts := opts() 1728 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1729 require.NoError(t, err) 1730 1731 buf := bytes.NewBuffer(nil) 1732 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1733 1734 ct, err := opts.LanguageOpts.FormatContent("flags_list.go", buf.Bytes()) 1735 require.NoError(t, err) 1736 1737 res := string(ct) 1738 assertNotInCode(t, "m[i] != nil", res) 1739 } 1740 1741 func TestGenModel_Issue300(t *testing.T) { 1742 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1743 require.NoError(t, err) 1744 1745 definitions := specDoc.Spec().Definitions 1746 k := "ActionItem" 1747 opts := opts() 1748 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1749 require.NoError(t, err) 1750 1751 buf := bytes.NewBuffer(nil) 1752 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1753 1754 ct, err := opts.LanguageOpts.FormatContent("action_item.go", buf.Bytes()) 1755 require.NoError(t, err) 1756 1757 res := string(ct) 1758 assertInCode(t, "Name ActionName `json:\"name\"`", res) 1759 } 1760 1761 func TestGenModel_Issue398(t *testing.T) { 1762 specDoc, err := loads.Spec("../fixtures/codegen/todolist.models.yml") 1763 require.NoError(t, err) 1764 1765 definitions := specDoc.Spec().Definitions 1766 k := "Property" 1767 opts := opts() 1768 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1769 require.NoError(t, err) 1770 1771 buf := bytes.NewBuffer(nil) 1772 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1773 1774 ct, err := opts.LanguageOpts.FormatContent("action_item.go", buf.Bytes()) 1775 require.NoError(t, err) 1776 1777 res := string(ct) 1778 assertInCode(t, "Computed bool `json:\"computed,omitempty\"`", res) 1779 assertInCode(t, "Intval *int64 `json:\"intval\"`", res) 1780 assertInCode(t, "PropType *string `json:\"propType\"`", res) 1781 assertInCode(t, "Strval *string `json:\"strval\"`", res) 1782 } 1783 1784 func TestGenModel_Issue454(t *testing.T) { 1785 specDoc, err := loads.Spec("../fixtures/bugs/454/swagger.yml") 1786 require.NoError(t, err) 1787 1788 definitions := specDoc.Spec().Definitions 1789 schema := definitions["genericResource"] 1790 opts := opts() 1791 genModel, err := makeGenDefinition("genericResource", "models", schema, specDoc, opts) 1792 require.NoError(t, err) 1793 1794 buf := bytes.NewBuffer(nil) 1795 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1796 1797 ct, err := opts.LanguageOpts.FormatContent("generic_resource.go", buf.Bytes()) 1798 require.NoError(t, err) 1799 1800 res := string(ct) 1801 assertInCode(t, "rcv.Meta = stage1.Meta", res) 1802 assertInCode(t, "json.Marshal(stage1)", res) 1803 assertInCode(t, "stage1.Meta = m.Meta", res) 1804 assertInCode(t, "json.Marshal(m.GenericResource)", res) 1805 } 1806 1807 func TestGenModel_Issue423(t *testing.T) { 1808 specDoc, err := loads.Spec("../fixtures/bugs/423/swagger.json") 1809 require.NoError(t, err) 1810 1811 definitions := specDoc.Spec().Definitions 1812 schema := definitions["SRN"] 1813 opts := opts() 1814 genModel, err := makeGenDefinition("SRN", "models", schema, specDoc, opts) 1815 require.NoError(t, err) 1816 1817 buf := bytes.NewBuffer(nil) 1818 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1819 1820 ct, err := opts.LanguageOpts.FormatContent("SRN.go", buf.Bytes()) 1821 require.NoError(t, err) 1822 1823 res := string(ct) 1824 assertInCode(t, "propSite, err := UnmarshalSite(bytes.NewBuffer(data.Site), runtime.JSONConsumer())", res) 1825 assertInCode(t, "result.siteField = propSite", res) 1826 } 1827 1828 func TestGenModel_Issue453(t *testing.T) { 1829 specDoc, err := loads.Spec("../fixtures/bugs/453/swagger.yml") 1830 require.NoError(t, err) 1831 1832 definitions := specDoc.Spec().Definitions 1833 k := "out_obj" 1834 opts := opts() 1835 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1836 require.NoError(t, err) 1837 1838 buf := bytes.NewBuffer(nil) 1839 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1840 1841 ct, err := opts.LanguageOpts.FormatContent("out_obj.go", buf.Bytes()) 1842 require.NoError(t, err) 1843 1844 res := string(ct) 1845 assertInCode(t, `func (m *OutObj) validateFld3(formats strfmt.Registry)`, res) 1846 } 1847 1848 func TestGenModel_Issue455(t *testing.T) { 1849 specDoc, err := loads.Spec("../fixtures/bugs/455/swagger.yml") 1850 require.NoError(t, err) 1851 1852 definitions := specDoc.Spec().Definitions 1853 k := "out_obj" 1854 opts := opts() 1855 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1856 require.NoError(t, err) 1857 1858 buf := bytes.NewBuffer(nil) 1859 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1860 1861 ct, err := opts.LanguageOpts.FormatContent("out_obj.go", buf.Bytes()) 1862 require.NoError(t, err) 1863 1864 res := string(ct) 1865 assertInCode(t, `if err := validate.Required("fld2", "body", m.Fld2); err != nil {`, res) 1866 } 1867 1868 func TestGenModel_Issue763(t *testing.T) { 1869 specDoc, err := loads.Spec("../fixtures/bugs/763/swagger.yml") 1870 require.NoError(t, err) 1871 1872 definitions := specDoc.Spec().Definitions 1873 k := "test_list" 1874 opts := opts() 1875 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1876 require.NoError(t, err) 1877 1878 buf := bytes.NewBuffer(nil) 1879 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1880 1881 ct, err := opts.LanguageOpts.FormatContent("test_list.go", buf.Bytes()) 1882 require.NoError(t, err) 1883 1884 res := string(ct) 1885 assertInCode(t, "TheArray []*int32 `json:\"the_array\"`", res) 1886 assertInCode(t, `validate.MinimumInt("the_array"+"."+strconv.Itoa(i), "body", int64(*m.TheArray[i]), 0, false)`, res) 1887 assertInCode(t, `validate.MaximumInt("the_array"+"."+strconv.Itoa(i), "body", int64(*m.TheArray[i]), 10, false)`, res) 1888 } 1889 1890 func TestGenModel_Issue811_NullType(t *testing.T) { 1891 specDoc, err := loads.Spec("../fixtures/bugs/811/swagger.json") 1892 require.NoError(t, err) 1893 1894 definitions := specDoc.Spec().Definitions 1895 k := "teamRepos" 1896 opts := opts() 1897 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1898 require.NoError(t, err) 1899 1900 buf := bytes.NewBuffer(nil) 1901 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1902 1903 ct, err := opts.LanguageOpts.FormatContent("team_repos.go", buf.Bytes()) 1904 require.NoError(t, err) 1905 1906 res := string(ct) 1907 assertInCode(t, "Language interface{} `json:\"language,omitempty\"`", res) 1908 } 1909 1910 func TestGenModel_Issue811_Emojis(t *testing.T) { 1911 specDoc, err := loads.Spec("../fixtures/bugs/811/swagger.json") 1912 require.NoError(t, err) 1913 1914 definitions := specDoc.Spec().Definitions 1915 k := "emojis" 1916 opts := opts() 1917 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1918 require.NoError(t, err) 1919 1920 buf := bytes.NewBuffer(nil) 1921 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1922 1923 ct, err := opts.LanguageOpts.FormatContent("team_repos.go", buf.Bytes()) 1924 require.NoError(t, err) 1925 1926 res := string(ct) 1927 assertInCode(t, "Plus1 string `json:\"+1,omitempty\"`", res) 1928 assertInCode(t, "Minus1 string `json:\"-1,omitempty\"`", res) 1929 } 1930 1931 func TestGenModel_Issue752_EOFErr(t *testing.T) { 1932 specDoc, err := loads.Spec("../fixtures/codegen/azure-text-analyis.json") 1933 require.NoError(t, err) 1934 1935 definitions := specDoc.Spec().Definitions 1936 k := "OperationResult" 1937 opts := opts() 1938 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1939 require.NoError(t, err) 1940 1941 buf := bytes.NewBuffer(nil) 1942 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1943 1944 ct, err := opts.LanguageOpts.FormatContent("out_obj.go", buf.Bytes()) 1945 require.NoError(t, err) 1946 1947 res := string(ct) 1948 assertInCode(t, `&& err != io.EOF`, res) 1949 } 1950 1951 func TestImports_ExistingModel(t *testing.T) { 1952 specDoc, err := loads.Spec("../fixtures/codegen/existing-model.yml") 1953 require.NoError(t, err) 1954 1955 definitions := specDoc.Spec().Definitions 1956 opts := opts() 1957 1958 k := "JsonWebKeySet" 1959 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1960 require.NoError(t, err) 1961 1962 require.NotNil(t, genModel) 1963 require.NotNil(t, genModel.Imports) 1964 assert.Equal(t, "github.com/user/package", genModel.Imports["jwk"]) 1965 1966 k = "JsonWebKey" 1967 genModel, err = makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1968 require.NoError(t, err) 1969 1970 require.NotNil(t, genModel) 1971 require.NotNil(t, genModel.Imports) 1972 assert.Equal(t, "github.com/user/package", genModel.Imports["jwk"]) 1973 } 1974 1975 func TestGenModel_Issue786(t *testing.T) { 1976 specDoc, err := loads.Spec("../fixtures/bugs/786/swagger.yml") 1977 require.NoError(t, err) 1978 1979 definitions := specDoc.Spec().Definitions 1980 k := "MyFirstObject" 1981 opts := opts() 1982 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 1983 require.NoError(t, err) 1984 1985 require.False(t, genModel.Properties[0].AdditionalProperties.IsNullable) 1986 1987 buf := bytes.NewBuffer(nil) 1988 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 1989 1990 ct, err := opts.LanguageOpts.FormatContent("MyFirstObject.go", buf.Bytes()) 1991 require.NoError(t, err) 1992 1993 res := string(ct) 1994 assertInCode(t, `m.validateEntreeChoiceValueEnum("entree_choice"+"."+k, "body", m.EntreeChoice[k])`, res) 1995 } 1996 1997 func TestGenModel_Issue822(t *testing.T) { 1998 specDoc, err := loads.Spec("../fixtures/bugs/822/swagger.yml") 1999 require.NoError(t, err) 2000 2001 definitions := specDoc.Spec().Definitions 2002 k := "Pet" 2003 opts := opts() 2004 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 2005 require.NoError(t, err) 2006 2007 ap := genModel.AdditionalProperties 2008 require.True(t, genModel.HasAdditionalProperties) 2009 require.NotNil(t, ap) 2010 require.False(t, ap.IsNullable) 2011 2012 buf := bytes.NewBuffer(nil) 2013 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2014 2015 ct, err := opts.LanguageOpts.FormatContent("pet.go", buf.Bytes()) 2016 require.NoError(t, err) 2017 2018 res := string(ct) 2019 assertInCode(t, `PetAdditionalProperties map[string]interface{}`, res) 2020 assertInCode(t, `m.PetAdditionalProperties = result`, res) 2021 assertInCode(t, `additional, err := json.Marshal(m.PetAdditionalProperties)`, res) 2022 } 2023 2024 func TestGenModel_Issue981(t *testing.T) { 2025 specDoc, err := loads.Spec("../fixtures/bugs/981/swagger.json") 2026 require.NoError(t, err) 2027 2028 definitions := specDoc.Spec().Definitions 2029 k := "User" 2030 opts := opts() 2031 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 2032 require.NoError(t, err) 2033 2034 buf := bytes.NewBuffer(nil) 2035 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2036 2037 ct, err := opts.LanguageOpts.FormatContent("user.go", buf.Bytes()) 2038 require.NoError(t, err) 2039 2040 res := string(ct) 2041 assertInCode(t, "FirstName string `json:\"first_name,omitempty\"`", res) 2042 assertInCode(t, "LastName string `json:\"last_name,omitempty\"`", res) 2043 assertInCode(t, "if swag.IsZero(m.Type)", res) 2044 assertInCode(t, `validate.MinimumInt("user_type", "body", m.Type, 1, false)`, res) 2045 assertInCode(t, `validate.MaximumInt("user_type", "body", m.Type, 5, false)`, res) 2046 } 2047 2048 func TestGenModel_Issue1341(t *testing.T) { 2049 specDoc, err := loads.Spec("../fixtures/bugs/1341/swagger.yaml") 2050 require.NoError(t, err) 2051 2052 definitions := specDoc.Spec().Definitions 2053 k := "ExecutableValueString" 2054 schema := definitions[k] 2055 opts := opts() 2056 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2057 require.NoError(t, err) 2058 2059 buf := bytes.NewBuffer(nil) 2060 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2061 2062 ff, err := opts.LanguageOpts.FormatContent("executable_value_string.go", buf.Bytes()) 2063 require.NoError(t, err) 2064 2065 res := string(ff) 2066 assertInCode(t, `return errors.New(422, "invalid ValueType value: %q", base.ValueType`, res) 2067 assertInCode(t, "result.testField = base.Test", res) 2068 assertInCode(t, "Test *string `json:\"Test\"`", res) 2069 assertInCode(t, "Test: m.Test(),", res) 2070 } 2071 2072 // This tests to check that format validation is performed on non required schema properties 2073 func TestGenModel_Issue1347(t *testing.T) { 2074 specDoc, err := loads.Spec("../fixtures/bugs/1347/fixture-1347.yaml") 2075 require.NoError(t, err) 2076 2077 definitions := specDoc.Spec().Definitions 2078 schema := definitions["ContainerConfig"] 2079 opts := opts() 2080 genModel, err := makeGenDefinition("ContainerConfig", "models", schema, specDoc, opts) 2081 require.NoError(t, err) 2082 2083 buf := bytes.NewBuffer(nil) 2084 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2085 2086 ff, err := opts.LanguageOpts.FormatContent("Foo.go", buf.Bytes()) 2087 require.NoError(t, err) 2088 2089 res := string(ff) 2090 // Just verify that the validation call is generated even though we add a non-required property 2091 assertInCode(t, `validate.FormatOf("config1", "body", "hostname", m.Config1.String(), formats)`, res) 2092 } 2093 2094 // This tests to check that format validation is performed on MAC format 2095 func TestGenModel_Issue1348(t *testing.T) { 2096 specDoc, err := loads.Spec("../fixtures/bugs/1348/fixture-1348.yaml") 2097 require.NoError(t, err) 2098 2099 definitions := specDoc.Spec().Definitions 2100 k := "ContainerConfig" 2101 schema := definitions[k] 2102 opts := opts() 2103 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2104 require.NoError(t, err) 2105 2106 buf := bytes.NewBuffer(nil) 2107 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2108 2109 ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes()) 2110 require.NoError(t, err) 2111 2112 res := string(ct) 2113 // Just verify that the validation call is generated with proper format 2114 assertInCode(t, `if err := validate.FormatOf("config1", "body", "mac", m.Config1.String(), formats)`, res) 2115 } 2116 2117 // This tests that additionalProperties with validation is generated properly. 2118 func TestGenModel_Issue1198(t *testing.T) { 2119 specDoc, err := loads.Spec("../fixtures/bugs/1198/fixture-1198.yaml") 2120 require.NoError(t, err) 2121 2122 definitions := specDoc.Spec().Definitions 2123 k := "pet" 2124 schema := definitions[k] 2125 opts := opts() 2126 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2127 require.NoError(t, err) 2128 2129 buf := bytes.NewBuffer(nil) 2130 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2131 2132 ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes()) 2133 require.NoError(t, err) 2134 2135 res := string(ct) 2136 // Just verify that the validation call is generated with proper format 2137 assertInCode(t, `if err := m.validateDate(formats); err != nil {`, res) 2138 } 2139 2140 // This tests that additionalProperties with validation is generated properly. 2141 func TestGenModel_Issue1397a(t *testing.T) { 2142 specDoc, err := loads.Spec("../fixtures/bugs/1397/fixture-1397a.yaml") 2143 require.NoError(t, err) 2144 2145 definitions := specDoc.Spec().Definitions 2146 k := "ContainerConfig" 2147 schema := definitions[k] 2148 opts := opts() 2149 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2150 require.NoError(t, err) 2151 2152 buf := bytes.NewBuffer(nil) 2153 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2154 2155 ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes()) 2156 require.NoError(t, err) 2157 2158 res := string(ct) 2159 // Just verify that the validation call is generated with proper format 2160 assertInCode(t, `if swag.IsZero(m[k]) { // not required`, res) 2161 } 2162 2163 // This tests that an enum of object values validates properly. 2164 func TestGenModel_Issue1397b(t *testing.T) { 2165 specDoc, err := loads.Spec("../fixtures/bugs/1397/fixture-1397b.yaml") 2166 require.NoError(t, err) 2167 2168 definitions := specDoc.Spec().Definitions 2169 k := "ContainerConfig" 2170 schema := definitions[k] 2171 opts := opts() 2172 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2173 require.NoError(t, err) 2174 2175 buf := bytes.NewBuffer(nil) 2176 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2177 2178 ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes()) 2179 require.NoError(t, err) 2180 2181 res := string(ct) 2182 // Just verify that the validation call is generated with proper format 2183 assertInCode(t, `if err := m.validateContainerConfigEnum("", "body", m); err != nil {`, res) 2184 } 2185 2186 // This tests that additionalProperties with an array of polymorphic objects is generated properly. 2187 func TestGenModel_Issue1409(t *testing.T) { 2188 specDoc, err := loads.Spec("../fixtures/bugs/1409/fixture-1409.yaml") 2189 require.NoError(t, err) 2190 2191 definitions := specDoc.Spec().Definitions 2192 k := "Graph" 2193 schema := definitions[k] 2194 opts := opts() 2195 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2196 require.NoError(t, err) 2197 2198 buf := bytes.NewBuffer(nil) 2199 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2200 2201 ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes()) 2202 require.NoError(t, err) 2203 2204 res := string(ct) 2205 // Just verify that the validation call is generated with proper format 2206 assertInCode(t, `nodes, err := UnmarshalNodeSlice(bytes.NewBuffer(data.Nodes), runtime.JSONConsumer())`, res) 2207 assertInCode(t, `if err := json.Unmarshal(raw, &rawProps); err != nil {`, res) 2208 assertInCode(t, `m.GraphAdditionalProperties[k] = toadd`, res) 2209 assertInCode(t, `b3, err = json.Marshal(m.GraphAdditionalProperties)`, res) 2210 } 2211 2212 // This tests makes sure model definitions from inline schema in response are properly flattened and get validation 2213 func TestGenModel_Issue866(t *testing.T) { 2214 defer discardOutput()() 2215 2216 specDoc, err := loads.Spec("../fixtures/bugs/866/fixture-866.yaml") 2217 require.NoError(t, err) 2218 2219 p, ok := specDoc.Spec().Paths.Paths["/"] 2220 require.True(t, ok) 2221 2222 op := p.Get 2223 responses := op.Responses.StatusCodeResponses 2224 for k, r := range responses { 2225 t.Logf("Response: %d", k) 2226 schema := *r.Schema 2227 opts := opts() 2228 genModel, err := makeGenDefinition("GetOKBody", "models", schema, specDoc, opts) 2229 require.NoError(t, err) 2230 2231 buf := bytes.NewBuffer(nil) 2232 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2233 2234 ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes()) 2235 require.NoError(t, err) 2236 2237 res := string(ct) 2238 assertInCode(t, `if err := validate.Required(`, res) 2239 assertInCode(t, `if err := validate.MaxLength(`, res) 2240 assertInCode(t, `if err := m.validateAccessToken(formats); err != nil {`, res) 2241 assertInCode(t, `if err := m.validateAccountID(formats); err != nil {`, res) 2242 } 2243 } 2244 2245 // This tests makes sure marshalling and validation is generated in aliased formatted definitions 2246 func TestGenModel_Issue946(t *testing.T) { 2247 specDoc, err := loads.Spec("../fixtures/bugs/946/fixture-946.yaml") 2248 require.NoError(t, err) 2249 2250 definitions := specDoc.Spec().Definitions 2251 k := "mydate" 2252 schema := definitions[k] 2253 opts := opts() 2254 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2255 require.NoError(t, err) 2256 2257 buf := bytes.NewBuffer(nil) 2258 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2259 2260 ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes()) 2261 require.NoError(t, err) 2262 2263 res := string(ct) 2264 assertInCode(t, `type Mydate strfmt.Date`, res) 2265 assertInCode(t, `func (m *Mydate) UnmarshalJSON(b []byte) error {`, res) 2266 assertInCode(t, `return ((*strfmt.Date)(m)).UnmarshalJSON(b)`, res) 2267 assertInCode(t, `func (m Mydate) MarshalJSON() ([]byte, error) {`, res) 2268 assertInCode(t, `return (strfmt.Date(m)).MarshalJSON()`, res) 2269 assertInCode(t, `if err := validate.FormatOf("", "body", "date", strfmt.Date(m).String(), formats); err != nil {`, res) 2270 } 2271 2272 // This tests makes sure that docstring in inline schema in response properly reflect the Required property 2273 func TestGenModel_Issue910(t *testing.T) { 2274 specDoc, err := loads.Spec("../fixtures/bugs/910/fixture-910.yaml") 2275 require.NoError(t, err) 2276 2277 p, ok := specDoc.Spec().Paths.Paths["/mytest"] 2278 require.True(t, ok) 2279 2280 op := p.Get 2281 responses := op.Responses.StatusCodeResponses 2282 for k, r := range responses { 2283 t.Logf("Response: %d", k) 2284 schema := *r.Schema 2285 opts := opts() 2286 genModel, err := makeGenDefinition("GetMyTestOKBody", "models", schema, specDoc, opts) 2287 require.NoError(t, err) 2288 2289 buf := bytes.NewBuffer(nil) 2290 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2291 2292 ct, err := opts.LanguageOpts.FormatContent("foo.go", buf.Bytes()) 2293 require.NoError(t, err) 2294 2295 res := string(ct) 2296 assertInCode(t, "// bar\n // Required: true\n Bar *int64 `json:\"bar\"`", res) 2297 assertInCode(t, "// foo\n // Required: true\n Foo interface{} `json:\"foo\"`", res) 2298 assertInCode(t, "// baz\n Baz int64 `json:\"baz,omitempty\"`", res) 2299 assertInCode(t, "// quux\n Quux []string `json:\"quux\"`", res) 2300 assertInCode(t, `if err := validate.Required("bar", "body", m.Bar); err != nil {`, res) 2301 assertInCode(t, `if m.Foo == nil {`, res) // interface{} now checked against nil (validate.Required fails on any zero value) 2302 assertNotInCode(t, `if err := validate.Required("baz", "body", m.Baz); err != nil {`, res) 2303 assertNotInCode(t, `if err := validate.Required("quux", "body", m.Quux); err != nil {`, res) 2304 // NOTE(fredbi); fixed Required in slices. This property has actually no validation 2305 } 2306 } 2307 2308 func TestGenerateModel_Xorder(t *testing.T) { 2309 specDoc, err := loads.Spec("../fixtures/codegen/x-order.yml") 2310 require.NoError(t, err) 2311 2312 definitions := specDoc.Spec().Definitions 2313 k := "sessionData" 2314 schema := definitions[k] 2315 opts := opts() 2316 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2317 require.NoError(t, err) 2318 2319 buf := bytes.NewBuffer(nil) 2320 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2321 2322 ff, err := opts.LanguageOpts.FormatContent("x-order.go", buf.Bytes()) 2323 require.NoError(t, err) 2324 2325 res := string(ff) 2326 // if no x-order then alphabetical order, like DeviceID, SessionID, UMain. 2327 // There is x-order 2328 // sessionId 2329 // x-order: 0 2330 // deviceId: 2331 // x-order: 1 2332 // uMain: 2333 // x-order: 2 2334 // This is need for msgpack-array. 2335 foundDeviceID := strings.Index(res, "DeviceID") 2336 foundSessionID := strings.Index(res, "SessionID") 2337 foundUMain := strings.Index(res, "UMain") 2338 foundAaa := strings.Index(res, "Aaa") 2339 foundBbb := strings.Index(res, "Bbb") 2340 foundZzz := strings.Index(res, "Zzz") 2341 assert.True(t, foundSessionID < foundDeviceID) 2342 assert.True(t, foundSessionID < foundUMain) 2343 assert.True(t, foundUMain < foundAaa) 2344 assert.True(t, foundAaa < foundBbb) 2345 assert.True(t, foundBbb < foundZzz) 2346 } 2347 2348 func TestGenModel_Issue1623(t *testing.T) { 2349 specDoc, err := loads.Spec("../fixtures/enhancements/1623/swagger.yml") 2350 require.NoError(t, err) 2351 2352 definitions := specDoc.Spec().Definitions 2353 k := "Foo" 2354 schema := definitions[k] 2355 opts := opts() 2356 2357 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2358 require.NoError(t, err) 2359 2360 buf := bytes.NewBuffer(nil) 2361 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2362 2363 ff, err := opts.LanguageOpts.FormatContent("Foo.go", buf.Bytes()) 2364 require.NoError(t, err) 2365 2366 res := string(ff) 2367 assertInCode(t, "ArrayHasOmitEmptyFalse []string `json:\"arrayHasOmitEmptyFalse\"`", res) 2368 assertInCode(t, "ArrayHasOmitEmptyTrue []string `json:\"arrayHasOmitEmptyTrue,omitempty\"`", res) 2369 assertInCode(t, "ArrayNoOmitEmpty []string `json:\"arrayNoOmitEmpty\"`", res) 2370 assertInCode(t, "GeneralHasOmitEmptyFalse string `json:\"generalHasOmitEmptyFalse\"`", res) 2371 assertInCode(t, "GeneralHasOmitEmptyTrue string `json:\"generalHasOmitEmptyTrue,omitempty\"`", res) 2372 assertInCode(t, "GeneralNoOmitEmpty string `json:\"generalNoOmitEmpty,omitempty\"`", res) 2373 assertInCode(t, "RefHasOmitEmptyFalse Bar `json:\"refHasOmitEmptyFalse,omitempty\"`", res) 2374 assertInCode(t, "RefHasOmitEmptyTrue Bar `json:\"refHasOmitEmptyTrue,omitempty\"`", res) 2375 assertInCode(t, "RefNoOmitEmpty Bar `json:\"refNoOmitEmpty,omitempty\"`", res) 2376 assertInCode(t, "IntHasJSONString int64 `json:\"intHasJsonString,omitempty,string\"`", res) 2377 assertInCode(t, "BoolHasJSONString bool `json:\"boolHasJsonString,omitempty,string\"`", res) 2378 2379 } 2380 2381 func TestGenerateModel_Issue2457(t *testing.T) { 2382 specDoc, err := loads.Spec("../fixtures/bugs/2457/fixture-2457.yaml") 2383 require.NoError(t, err) 2384 2385 definitions := specDoc.Spec().Definitions 2386 k := "ObjWithCustomTag" 2387 schema := definitions[k] 2388 opts := opts() 2389 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2390 require.NoError(t, err) 2391 2392 buf := bytes.NewBuffer(nil) 2393 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2394 2395 assertInCode(t, "myobjtag:\"foo,bar\"", buf.String()) 2396 } 2397 2398 func TestGenModel_Pr2464(t *testing.T) { 2399 specDoc, err := loads.Spec("../fixtures/enhancements/2464/fixture-2464.yaml") 2400 require.NoError(t, err) 2401 2402 definitions := specDoc.Spec().Definitions 2403 2404 tests := map[string]struct { 2405 model string 2406 expected []string 2407 }{ 2408 "withDot": { 2409 model: "band", 2410 expected: []string{ 2411 `BandNr2Dot4Ghz Band = "2.4Ghz"`, 2412 `BandNr24Ghz Band = "24Ghz"`, 2413 }, 2414 }, 2415 "withSigns": { 2416 model: "change", 2417 expected: []string{ 2418 `ChangeDash1 Change = "-1"`, 2419 `ChangeNr0 Change = "0"`, 2420 `ChangePlus1 Change = "+1"`, 2421 }, 2422 }, 2423 "hashtag": { 2424 model: "topic", 2425 expected: []string{ 2426 `TopicHashtagOne Topic = "#one"`, 2427 `TopicTwoHashtagTwo Topic = "two#two"`, 2428 }, 2429 }, 2430 } 2431 2432 for name, spec := range tests { 2433 t.Run(name, func(t *testing.T) { 2434 k := spec.model 2435 schema := definitions[k] 2436 opts := opts() 2437 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2438 require.NoError(t, err) 2439 2440 buf := bytes.NewBuffer(nil) 2441 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2442 2443 for _, expected := range spec.expected { 2444 assertInCode(t, expected, buf.String()) 2445 } 2446 }) 2447 } 2448 } 2449 2450 func TestGenModel_KeepSpecPropertiesOrder(t *testing.T) { 2451 ymlFile := "../fixtures/codegen/keep-spec-order.yml" 2452 opts := opts() 2453 abcType := "abctype" 2454 2455 specDoc, err := loads.Spec(ymlFile) 2456 require.NoError(t, err) 2457 2458 orderedSpecDoc, err := loads.Spec(WithAutoXOrder(ymlFile)) 2459 require.NoError(t, err) 2460 2461 definitions := specDoc.Spec().Definitions 2462 orderedDefinitions := orderedSpecDoc.Spec().Definitions 2463 2464 genModel, err := makeGenDefinition(abcType, "models", definitions[abcType], specDoc, opts) 2465 assert.NoError(t, err) 2466 orderGenModel, err := makeGenDefinition(abcType, "models", orderedDefinitions[abcType], orderedSpecDoc, opts) 2467 require.NoError(t, err) 2468 2469 buf := bytes.NewBuffer(nil) 2470 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2471 2472 orderBuf := bytes.NewBuffer(nil) 2473 require.NoError(t, opts.templates.MustGet("model").Execute(orderBuf, orderGenModel)) 2474 2475 ff, err := opts.LanguageOpts.FormatContent("keepSpecOrder.go", buf.Bytes()) 2476 require.NoError(t, err) 2477 2478 modelCode := string(ff) 2479 ff, err = opts.LanguageOpts.FormatContent("keepSpecOrder-ordered.go", orderBuf.Bytes()) 2480 require.NoError(t, err) 2481 2482 orderModelCode := string(ff) 2483 2484 // without auto order, properties sorted by alphanumeric 2485 foundA := strings.Index(modelCode, "Aaa") 2486 foundB := strings.Index(modelCode, "Bbb") 2487 foundC := strings.Index(modelCode, "Ccc") 2488 assert.True(t, foundA < foundB) 2489 assert.True(t, foundB < foundC) 2490 2491 foundOrderA := strings.Index(orderModelCode, "Aaa") 2492 foundOrderB := strings.Index(orderModelCode, "Bbb") 2493 foundOrderC := strings.Index(orderModelCode, "Ccc") 2494 2495 assert.True(t, foundOrderC < foundOrderB) 2496 assert.True(t, foundOrderB < foundOrderA) 2497 2498 foundInnerA := strings.Index(modelCode, "InnerAaa") 2499 foundInnerB := strings.Index(modelCode, "InnerBbb") 2500 foundInnerC := strings.Index(modelCode, "InnerCcc") 2501 assert.True(t, foundInnerA < foundInnerB) 2502 assert.True(t, foundInnerB < foundInnerC) 2503 2504 foundOrderInnerA := strings.Index(orderModelCode, "InnerAaa") 2505 foundOrderInnerB := strings.Index(orderModelCode, "InnerBbb") 2506 foundOrderInnerC := strings.Index(orderModelCode, "InnerCcc") 2507 2508 assert.True(t, foundOrderInnerC < foundOrderInnerB) 2509 assert.True(t, foundOrderInnerB < foundOrderInnerA) 2510 } 2511 2512 func TestGenModel_StrictAdditionalProperties(t *testing.T) { 2513 specDoc, err := loads.Spec("../fixtures/codegen/strict-additional-properties.yml") 2514 require.NoError(t, err) 2515 2516 definitions := specDoc.Spec().Definitions 2517 k := "Body" 2518 schema := definitions[k] 2519 opts := opts() 2520 2521 opts.StrictAdditionalProperties = true 2522 2523 genModel, err := makeGenDefinition(k, "models", schema, specDoc, opts) 2524 require.NoError(t, err) 2525 2526 buf := bytes.NewBuffer(nil) 2527 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2528 2529 ff, err := opts.LanguageOpts.FormatContent("strictAdditionalProperties.go", buf.Bytes()) 2530 require.NoError(t, err) 2531 2532 res := string(ff) 2533 for _, tt := range []struct { 2534 name string 2535 assertion func(testing.TB, string, string) bool 2536 }{ 2537 {k, assertInCode}, 2538 {k + "Explicit", assertInCode}, 2539 {k + "Implicit", assertInCode}, 2540 {k + "Disabled", assertNotInCode}, 2541 } { 2542 fn := funcBody(res, "*"+tt.name+") UnmarshalJSON(data []byte) error") 2543 if assert.NotEmpty(t, fn, "Method UnmarshalJSON should be defined for type *"+tt.name) { 2544 tt.assertion(t, "dec.DisallowUnknownFields()", fn) 2545 } 2546 } 2547 } 2548 2549 func TestGenModel_XMLStructTags_WithXML(t *testing.T) { 2550 specDoc, err := loads.Spec("../fixtures/codegen/xml-model.yml") 2551 require.NoError(t, err) 2552 2553 definitions := specDoc.Spec().Definitions 2554 k := "XmlWithAttribute" 2555 opts := opts() 2556 opts.WithXML = true 2557 2558 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 2559 require.NoError(t, err) 2560 2561 buf := bytes.NewBuffer(nil) 2562 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2563 2564 ct, err := opts.LanguageOpts.FormatContent("xml_with_attribute.go", buf.Bytes()) 2565 require.NoError(t, err) 2566 2567 res := string(ct) 2568 assertInCode(t, "Author *string `json:\"author\" xml:\"author\"`", res) 2569 assertInCode(t, "Children []*XMLChild `json:\"children\" xml:\"children\"`", res) 2570 assertInCode(t, "ID int64 `json:\"id,omitempty\" xml:\"id,attr,omitempty\"`", res) 2571 assertInCode(t, "IsPublished *bool `json:\"isPublished\" xml:\"published,attr\"`", res) 2572 assertInCode(t, "SingleChild *XMLChild `json:\"singleChild,omitempty\" xml:\"singleChild,omitempty\"`", res) 2573 assertInCode(t, "Title string `json:\"title,omitempty\" xml:\"xml-title,omitempty\"`", res) 2574 } 2575 2576 func TestGenModel_XMLStructTags_Explicit(t *testing.T) { 2577 specDoc, err := loads.Spec("../fixtures/codegen/xml-model.yml") 2578 require.NoError(t, err) 2579 2580 definitions := specDoc.Spec().Definitions 2581 k := "XmlWithAttribute" 2582 opts := opts() 2583 2584 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 2585 require.NoError(t, err) 2586 2587 buf := bytes.NewBuffer(nil) 2588 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2589 2590 ct, err := opts.LanguageOpts.FormatContent("xml_with_attribute.go", buf.Bytes()) 2591 require.NoErrorf(t, err, "format error: %v\n%s", err, buf.String()) 2592 2593 res := string(ct) 2594 assertInCode(t, "Author *string `json:\"author\"`", res) 2595 assertInCode(t, "Children []*XMLChild `json:\"children\"`", res) 2596 assertInCode(t, "ID int64 `json:\"id,omitempty\" xml:\"id,attr,omitempty\"`", res) 2597 assertInCode(t, "IsPublished *bool `json:\"isPublished\" xml:\"published,attr\"`", res) 2598 assertInCode(t, "SingleChild *XMLChild `json:\"singleChild,omitempty\"`", res) 2599 assertInCode(t, "Title string `json:\"title,omitempty\" xml:\"xml-title,omitempty\"`", res) 2600 } 2601 2602 func TestGenerateModels(t *testing.T) { 2603 t.Parallel() 2604 defer discardOutput()() 2605 2606 cwd := testCwd(t) 2607 const root = "generated_models" 2608 defer func() { 2609 _ = os.RemoveAll(filepath.Join(cwd, root)) 2610 }() 2611 2612 t.Run("generate models", func(t *testing.T) { 2613 cases := map[string]generateFixture{ 2614 "allDefinitions": { 2615 spec: "../fixtures/bugs/1042/fixture-1042.yaml", 2616 target: "../fixtures/bugs/1042", 2617 verify: func(t testing.TB, target string) { 2618 target = filepath.Join(target, defaultModelsTarget) 2619 require.True(t, fileExists(target, "")) 2620 assert.True(t, fileExists(target, "a.go")) 2621 assert.True(t, fileExists(target, "b.go")) 2622 }, 2623 }, 2624 "acceptDefinitions": { 2625 spec: "../fixtures/enhancements/2333/fixture-definitions.yaml", 2626 target: "../fixtures/enhancements/2333", 2627 prepare: func(_ testing.TB, opts *GenOpts) { 2628 opts.AcceptDefinitionsOnly = true 2629 }, 2630 verify: func(t testing.TB, target string) { 2631 target = filepath.Join(target, defaultModelsTarget) 2632 require.True(t, fileExists(target, "")) 2633 assert.True(t, fileExists(target, "model_interface.go")) 2634 assert.True(t, fileExists(target, "records_model.go")) 2635 assert.True(t, fileExists(target, "records_model_with_max.go")) 2636 assert.False(t, fileExists(target, "restapi")) 2637 }, 2638 }, 2639 } 2640 for k, cas := range cases { 2641 name := k 2642 thisCas := cas 2643 2644 t.Run(name, func(t *testing.T) { 2645 t.Parallel() 2646 2647 defer thisCas.warnFailed(t) 2648 2649 opts := testGenOpts() 2650 defer thisCas.prepareTarget(t, name, "model_test", root, opts)() 2651 2652 if thisCas.prepare != nil { 2653 thisCas.prepare(t, opts) 2654 } 2655 2656 t.Logf("generating test models at: %s", opts.Target) 2657 2658 err := GenerateModels([]string{"", ""}, opts) // NOTE: generate all models, ignore "" 2659 if thisCas.wantError { 2660 require.Errorf(t, err, "expected an error for models build fixture: %s", opts.Spec) 2661 } else { 2662 require.NoError(t, err, "unexpected error for models build fixture: %s", opts.Spec) 2663 } 2664 2665 if thisCas.verify != nil { 2666 thisCas.verify(t, opts.Target) 2667 } 2668 }) 2669 } 2670 }) 2671 } 2672 2673 func Test_Issue2482(t *testing.T) { 2674 // generation of a pointer converter for enum vars 2675 specDoc, err := loads.Spec("../fixtures/bugs/252/swagger.json") 2676 require.NoError(t, err) 2677 2678 definitions := specDoc.Spec().Definitions 2679 k := "SodaBrand" 2680 opts := opts() 2681 genModel, err := makeGenDefinition(k, "models", definitions[k], specDoc, opts) 2682 require.NoError(t, err) 2683 require.False(t, genModel.IsNullable) 2684 2685 buf := bytes.NewBuffer(nil) 2686 require.NoError(t, opts.templates.MustGet("model").Execute(buf, genModel)) 2687 2688 ct, err := opts.LanguageOpts.FormatContent("soda_brand.go", buf.Bytes()) 2689 require.NoError(t, err) 2690 2691 res := string(ct) 2692 assertInCode(t, "func NewSodaBrand(value SodaBrand) *SodaBrand {", res) 2693 assertInCode(t, "v := value", res) 2694 assertInCode(t, "return &v", res) 2695 }