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