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