github.com/ryanbennettvoid/go-swagger@v0.18.1-0.20190104015444-3854bbbe2392/generator/operation_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 "errors" 20 "fmt" 21 "io/ioutil" 22 "log" 23 "os" 24 "path/filepath" 25 "testing" 26 27 "github.com/go-openapi/analysis" 28 "github.com/go-openapi/loads" 29 "github.com/go-openapi/spec" 30 "github.com/stretchr/testify/assert" 31 ) 32 33 func TestUniqueOperationNames(t *testing.T) { 34 doc, err := loads.Spec("../fixtures/codegen/todolist.simple.yml") 35 if assert.NoError(t, err) { 36 sp := doc.Spec() 37 sp.Paths.Paths["/tasks"].Post.ID = "saveTask" 38 sp.Paths.Paths["/tasks"].Post.AddExtension("origName", "createTask") 39 sp.Paths.Paths["/tasks/{id}"].Put.ID = "saveTask" 40 sp.Paths.Paths["/tasks/{id}"].Put.AddExtension("origName", "updateTask") 41 analyzed := analysis.New(sp) 42 43 ops := gatherOperations(analyzed, nil) 44 assert.Len(t, ops, 6) 45 _, exists := ops["saveTask"] 46 assert.True(t, exists) 47 _, exists = ops["PutTasksID"] 48 assert.True(t, exists) 49 } 50 } 51 52 func TestEmptyOperationNames(t *testing.T) { 53 doc, err := loads.Spec("../fixtures/codegen/todolist.simple.yml") 54 if assert.NoError(t, err) { 55 sp := doc.Spec() 56 sp.Paths.Paths["/tasks"].Post.ID = "" 57 sp.Paths.Paths["/tasks"].Post.AddExtension("origName", "createTask") 58 sp.Paths.Paths["/tasks/{id}"].Put.ID = "" 59 sp.Paths.Paths["/tasks/{id}"].Put.AddExtension("origName", "updateTask") 60 analyzed := analysis.New(sp) 61 62 ops := gatherOperations(analyzed, nil) 63 assert.Len(t, ops, 6) 64 _, exists := ops["PostTasks"] 65 assert.True(t, exists) 66 _, exists = ops["PutTasksID"] 67 assert.True(t, exists) 68 } 69 } 70 71 func TestMakeResponseHeader(t *testing.T) { 72 b, err := opBuilder("getTasks", "") 73 if assert.NoError(t, err) { 74 hdr := findResponseHeader(&b.Operation, 200, "X-Rate-Limit") 75 gh, er := b.MakeHeader("a", "X-Rate-Limit", *hdr) 76 if assert.NoError(t, er) { 77 assert.True(t, gh.IsPrimitive) 78 assert.Equal(t, "int32", gh.GoType) 79 assert.Equal(t, "X-Rate-Limit", gh.Name) 80 } 81 } 82 } 83 84 func TestMakeResponseHeaderDefaultValues(t *testing.T) { 85 b, err := opBuilder("getTasks", "") 86 if assert.NoError(t, err) { 87 var testCases = []struct { 88 name string // input 89 typeStr string // expected type 90 defaultValue interface{} // expected result 91 }{ 92 {"Access-Control-Allow-Origin", "string", "*"}, 93 {"X-Rate-Limit", "int32", nil}, 94 {"X-Rate-Limit-Remaining", "int32", float64(42)}, 95 {"X-Rate-Limit-Reset", "int32", "1449875311"}, 96 {"X-Rate-Limit-Reset-Human", "string", "3 days"}, 97 {"X-Rate-Limit-Reset-Human-Number", "string", float64(3)}, 98 } 99 100 for _, tc := range testCases { 101 // t.Logf("tc: %+v", tc) 102 hdr := findResponseHeader(&b.Operation, 200, tc.name) 103 assert.NotNil(t, hdr) 104 gh, er := b.MakeHeader("a", tc.name, *hdr) 105 if assert.NoError(t, er) { 106 assert.True(t, gh.IsPrimitive) 107 assert.Equal(t, tc.typeStr, gh.GoType) 108 assert.Equal(t, tc.name, gh.Name) 109 assert.Exactly(t, tc.defaultValue, gh.Default) 110 } 111 } 112 } 113 } 114 115 func TestMakeResponse(t *testing.T) { 116 b, err := opBuilder("getTasks", "") 117 if assert.NoError(t, err) { 118 resolver := &typeResolver{ModelsPackage: b.ModelsPackage, Doc: b.Doc} 119 resolver.KnownDefs = make(map[string]struct{}) 120 for k := range b.Doc.Spec().Definitions { 121 resolver.KnownDefs[k] = struct{}{} 122 } 123 gO, err := b.MakeResponse("a", "getTasksSuccess", true, resolver, 200, b.Operation.Responses.StatusCodeResponses[200]) 124 if assert.NoError(t, err) { 125 assert.Len(t, gO.Headers, 6) 126 assert.NotNil(t, gO.Schema) 127 assert.True(t, gO.Schema.IsArray) 128 assert.NotNil(t, gO.Schema.Items) 129 assert.False(t, gO.Schema.IsAnonymous) 130 assert.Equal(t, "[]*models.Task", gO.Schema.GoType) 131 } 132 } 133 } 134 135 func TestMakeResponse_WithAllOfSchema(t *testing.T) { 136 b, err := methodPathOpBuilder("get", "/media/search", "../fixtures/codegen/instagram.yml") 137 if assert.NoError(t, err) { 138 resolver := &typeResolver{ModelsPackage: b.ModelsPackage, Doc: b.Doc} 139 resolver.KnownDefs = make(map[string]struct{}) 140 for k := range b.Doc.Spec().Definitions { 141 resolver.KnownDefs[k] = struct{}{} 142 } 143 gO, err := b.MakeResponse("a", "get /media/search", true, resolver, 200, b.Operation.Responses.StatusCodeResponses[200]) 144 if assert.NoError(t, err) { 145 if assert.NotNil(t, gO.Schema) { 146 assert.Equal(t, "GetMediaSearchBody", gO.Schema.GoType) 147 } 148 if assert.NotEmpty(t, b.ExtraSchemas) { 149 body := b.ExtraSchemas["GetMediaSearchBody"] 150 if assert.NotEmpty(t, body.Properties) { 151 prop := body.Properties[0] 152 assert.Equal(t, "data", prop.Name) 153 // is in models only when definition is flattened: otherwise, ExtraSchema is rendered in operations package 154 assert.Equal(t, "[]*DataItems0", prop.GoType) 155 } 156 items := b.ExtraSchemas["DataItems0"] 157 if assert.NotEmpty(t, items.AllOf) { 158 media := items.AllOf[0] 159 // expect #definitions/media to be captured and reused by ExtraSchema 160 assert.Equal(t, "models.Media", media.GoType) 161 } 162 } 163 } 164 } 165 } 166 167 func TestMakeOperationParam(t *testing.T) { 168 b, err := opBuilder("getTasks", "") 169 if assert.NoError(t, err) { 170 resolver := &typeResolver{ModelsPackage: b.ModelsPackage, Doc: b.Doc} 171 gO, err := b.MakeParameter("a", resolver, b.Operation.Parameters[0], nil) 172 if assert.NoError(t, err) { 173 assert.Equal(t, "size", gO.Name) 174 assert.True(t, gO.IsPrimitive) 175 } 176 } 177 } 178 179 func TestMakeOperationParamItem(t *testing.T) { 180 b, err := opBuilder("arrayQueryParams", "../fixtures/codegen/todolist.arrayquery.yml") 181 if assert.NoError(t, err) { 182 resolver := &typeResolver{ModelsPackage: b.ModelsPackage, Doc: b.Doc} 183 gO, err := b.MakeParameterItem("a", "siString", "ii", "siString", "a.SiString", "query", resolver, b.Operation.Parameters[1].Items, nil) 184 if assert.NoError(t, err) { 185 assert.Nil(t, gO.Parent) 186 assert.True(t, gO.IsPrimitive) 187 } 188 } 189 } 190 191 func TestMakeOperation(t *testing.T) { 192 b, err := opBuilder("getTasks", "") 193 if assert.NoError(t, err) { 194 gO, err := b.MakeOperation() 195 if assert.NoError(t, err) { 196 assert.Equal(t, "getTasks", gO.Name) 197 assert.Equal(t, "GET", gO.Method) 198 assert.Equal(t, "/tasks", gO.Path) 199 assert.Len(t, gO.Params, 2) 200 assert.Len(t, gO.Responses, 1) 201 assert.NotNil(t, gO.DefaultResponse) 202 assert.NotNil(t, gO.SuccessResponse) 203 } 204 } 205 } 206 207 func TestRenderOperation_InstagramSearch(t *testing.T) { 208 log.SetOutput(ioutil.Discard) 209 defer log.SetOutput(os.Stdout) 210 211 b, err := methodPathOpBuilder("get", "/media/search", "../fixtures/codegen/instagram.yml") 212 if assert.NoError(t, err) { 213 gO, ero := b.MakeOperation() 214 if assert.NoError(t, ero) { 215 buf := bytes.NewBuffer(nil) 216 opts := opts() 217 ert := templates.MustGet("serverOperation").Execute(buf, gO) 218 if assert.NoError(t, ert) { 219 ff, erf := opts.LanguageOpts.FormatContent("operation.go", buf.Bytes()) 220 if assert.NoError(t, erf) { 221 res := string(ff) 222 assertInCode(t, "type GetMediaSearchOKBody struct {", res) 223 // codegen does not assumes objects are only in models 224 // this is inlined 225 assertInCode(t, "Data []*DataItems0 `json:\"data\"`", res) 226 assertInCode(t, "type DataItems0 struct {", res) 227 // this is a definition: expect this definition to be reused from the models pkg 228 assertInCode(t, "models.Media", res) 229 } else { 230 fmt.Println(buf.String()) 231 t.FailNow() 232 } 233 } else { 234 t.FailNow() 235 } 236 237 buf = bytes.NewBuffer(nil) 238 ert = templates.MustGet("serverResponses").Execute(buf, gO) 239 if assert.NoError(t, ert) { 240 ff, erf := opts.LanguageOpts.FormatContent("response.go", buf.Bytes()) 241 if assert.NoError(t, erf) { 242 res := string(ff) 243 // codegen does not assumes objects are only in models 244 assertInCode(t, "type GetMediaSearchOK struct {", res) 245 assertInCode(t, "GetMediaSearchOKBody", res) 246 } else { 247 fmt.Println(buf.String()) 248 t.FailNow() 249 } 250 } else { 251 t.FailNow() 252 } 253 } 254 } 255 b, err = methodPathOpBuilderWithFlatten("get", "/media/search", "../fixtures/codegen/instagram.yml") 256 if assert.NoError(t, err) { 257 gO, ero := b.MakeOperation() 258 if assert.NoError(t, ero) { 259 buf := bytes.NewBuffer(nil) 260 opts := opts() 261 ert := templates.MustGet("serverOperation").Execute(buf, gO) 262 if assert.NoError(t, ert) { 263 ff, erf := opts.LanguageOpts.FormatContent("operation.go", buf.Bytes()) 264 if assert.NoError(t, erf) { 265 res := string(ff) 266 assertNotInCode(t, "DataItems0", res) 267 assertNotInCode(t, "models", res) 268 } else { 269 fmt.Println(buf.String()) 270 t.FailNow() 271 } 272 } else { 273 t.FailNow() 274 } 275 buf = bytes.NewBuffer(nil) 276 ert = templates.MustGet("serverResponses").Execute(buf, gO) 277 if assert.NoError(t, ert) { 278 ff, erf := opts.LanguageOpts.FormatContent("operation.go", buf.Bytes()) 279 if assert.NoError(t, erf) { 280 res := string(ff) 281 assertInCode(t, "Payload *models.GetMediaSearchOKBody", res) 282 } else { 283 fmt.Println(buf.String()) 284 } 285 } 286 } 287 } 288 } 289 290 func methodPathOpBuilder(method, path, fname string) (codeGenOpBuilder, error) { 291 if fname == "" { 292 fname = "../fixtures/codegen/todolist.simple.yml" 293 } 294 295 specDoc, err := loads.Spec(fname) 296 if err != nil { 297 return codeGenOpBuilder{}, err 298 } 299 300 analyzed := analysis.New(specDoc.Spec()) 301 op, ok := analyzed.OperationFor(method, path) 302 if !ok { 303 return codeGenOpBuilder{}, errors.New("No operation could be found for " + method + " " + path) 304 } 305 306 return codeGenOpBuilder{ 307 Name: method + " " + path, 308 Method: method, 309 Path: path, 310 APIPackage: "restapi", 311 ModelsPackage: "models", 312 Principal: "models.User", 313 Target: ".", 314 Operation: *op, 315 Doc: specDoc, 316 Analyzed: analyzed, 317 Authed: false, 318 ExtraSchemas: make(map[string]GenSchema), 319 GenOpts: opts(), 320 }, nil 321 } 322 323 // methodPathOpBuilderWithFlatten prepares an operation build based on method and path, with spec full flattening 324 func methodPathOpBuilderWithFlatten(method, path, fname string) (codeGenOpBuilder, error) { 325 if fname == "" { 326 fname = "../fixtures/codegen/todolist.simple.yml" 327 } 328 329 specDoc, err := loads.Spec(fname) 330 if err != nil { 331 return codeGenOpBuilder{}, err 332 } 333 334 o := opBuildGetOpts(fname, true, false) // flatten: true, minimal: false 335 336 specDoc, err = validateAndFlattenSpec(o, specDoc) 337 if err != nil { 338 return codeGenOpBuilder{}, err 339 } 340 341 analyzed := analysis.New(specDoc.Spec()) 342 op, ok := analyzed.OperationFor(method, path) 343 if !ok { 344 return codeGenOpBuilder{}, errors.New("No operation could be found for " + method + " " + path) 345 } 346 347 return codeGenOpBuilder{ 348 Name: method + " " + path, 349 Method: method, 350 Path: path, 351 APIPackage: "restapi", 352 ModelsPackage: "models", 353 Principal: "models.User", 354 Target: ".", 355 Operation: *op, 356 Doc: specDoc, 357 Analyzed: analyzed, 358 Authed: false, 359 ExtraSchemas: make(map[string]GenSchema), 360 GenOpts: opts(), 361 }, nil 362 } 363 364 // opBuilderWithOpts prepares the making of an operation with spec flattening options 365 func opBuilderWithOpts(name, fname string, o *GenOpts) (codeGenOpBuilder, error) { 366 if fname == "" { 367 // default fixture 368 fname = "../fixtures/codegen/todolist.simple.yml" 369 } 370 371 if !filepath.IsAbs(fname) { 372 cwd, _ := os.Getwd() 373 fname = filepath.Join(cwd, fname) 374 } 375 376 specDoc, err := loads.Spec(fname) 377 if err != nil { 378 return codeGenOpBuilder{}, err 379 } 380 o.Spec = fname 381 382 log.SetOutput(ioutil.Discard) 383 defer log.SetOutput(os.Stdout) 384 specDoc, err = validateAndFlattenSpec(o, specDoc) 385 if err != nil { 386 return codeGenOpBuilder{}, err 387 } 388 log.SetOutput(os.Stdout) 389 390 analyzed := analysis.New(specDoc.Spec()) 391 392 method, path, op, ok := analyzed.OperationForName(name) 393 if !ok { 394 return codeGenOpBuilder{}, errors.New("No operation could be found for " + name) 395 } 396 397 return codeGenOpBuilder{ 398 Name: name, 399 Method: method, 400 Path: path, 401 BasePath: specDoc.BasePath(), 402 APIPackage: "restapi", 403 ModelsPackage: "models", 404 Principal: "models.User", 405 Target: ".", 406 Operation: *op, 407 Doc: specDoc, 408 Analyzed: analyzed, 409 Authed: false, 410 ExtraSchemas: make(map[string]GenSchema), 411 GenOpts: o, // opts()?? 412 }, nil 413 } 414 415 func opBuildGetOpts(specName string, withFlatten bool, withMinimalFlatten bool) (opts *GenOpts) { 416 opts = &GenOpts{} 417 if erd := opts.EnsureDefaults(); erd != nil { 418 panic("Cannot initialize GenOpts") 419 } 420 opts.ValidateSpec = true 421 opts.FlattenOpts.Expand = !withFlatten 422 opts.FlattenOpts.Minimal = withMinimalFlatten 423 opts.Spec = specName 424 return 425 } 426 427 // opBuilderWithFlatten prepares the making of an operation with spec full flattening prior to rendering 428 func opBuilderWithFlatten(name, fname string) (codeGenOpBuilder, error) { 429 o := opBuildGetOpts(fname, true, false) // flatten: true, minimal: false 430 return opBuilderWithOpts(name, fname, o) 431 } 432 433 // opBuilderWithExpand prepares the making of an operation with spec expansion prior to rendering 434 func opBuilderWithExpand(name, fname string) (codeGenOpBuilder, error) { 435 o := opBuildGetOpts(fname, false, false) // flatten: false => expand 436 return opBuilderWithOpts(name, fname, o) 437 } 438 439 // opBuilder prepares the making of an operation with spec minimal flattening (default for CLI) 440 func opBuilder(name, fname string) (codeGenOpBuilder, error) { 441 o := opBuildGetOpts(fname, true, true) // flatten:true, minimal: true 442 // some fixtures do not fully validate - skip this 443 o.ValidateSpec = false 444 return opBuilderWithOpts(name, fname, o) 445 /* 446 if fname == "" { 447 fname = "../fixtures/codegen/todolist.simple.yml" 448 } 449 450 if !filepath.IsAbs(fname) { 451 cwd, _ := os.Getwd() 452 fname = filepath.Join(cwd, fname) 453 } 454 455 specDoc, err := loads.Spec(fname) 456 if err != nil { 457 return codeGenOpBuilder{}, err 458 } 459 if err != nil { 460 return codeGenOpBuilder{}, err 461 } 462 463 analyzed := analysis.New(specDoc.Spec()) 464 465 method, path, op, ok := analyzed.OperationForName(name) 466 if !ok { 467 return codeGenOpBuilder{}, errors.New("No operation could be found for " + name) 468 } 469 470 return codeGenOpBuilder{ 471 Name: name, 472 Method: method, 473 Path: path, 474 BasePath: specDoc.BasePath(), 475 APIPackage: "restapi", 476 ModelsPackage: "models", 477 Principal: "models.User", 478 Target: ".", 479 Operation: *op, 480 Doc: specDoc, 481 Analyzed: analyzed, 482 Authed: false, 483 ExtraSchemas: make(map[string]GenSchema), 484 GenOpts: opts(), 485 }, nil 486 */ 487 } 488 489 func findResponseHeader(op *spec.Operation, code int, name string) *spec.Header { 490 resp := op.Responses.Default 491 if code > 0 { 492 bb, ok := op.Responses.StatusCodeResponses[code] 493 if ok { 494 resp = &bb 495 } 496 } 497 498 if resp == nil { 499 return nil 500 } 501 502 hdr, ok := resp.Headers[name] 503 if !ok { 504 return nil 505 } 506 507 return &hdr 508 } 509 510 func TestDateFormat_Spec1(t *testing.T) { 511 b, err := opBuilder("putTesting", "../fixtures/bugs/193/spec1.json") 512 if assert.NoError(t, err) { 513 op, err := b.MakeOperation() 514 if assert.NoError(t, err) { 515 buf := bytes.NewBuffer(nil) 516 opts := opts() 517 opts.defaultsEnsured = false 518 opts.IsClient = true 519 err = opts.EnsureDefaults() 520 assert.NoError(t, err) 521 err = templates.MustGet("clientParameter").Execute(buf, op) 522 if assert.NoError(t, err) { 523 ff, err := opts.LanguageOpts.FormatContent("put_testing.go", buf.Bytes()) 524 if assert.NoError(t, err) { 525 res := string(ff) 526 assertInCode(t, "frTestingThis.String()", res) 527 } else { 528 fmt.Println(buf.String()) 529 } 530 } 531 } 532 } 533 } 534 535 func TestDateFormat_Spec2(t *testing.T) { 536 b, err := opBuilder("putTesting", "../fixtures/bugs/193/spec2.json") 537 if assert.NoError(t, err) { 538 op, err := b.MakeOperation() 539 if assert.NoError(t, err) { 540 buf := bytes.NewBuffer(nil) 541 opts := opts() 542 opts.defaultsEnsured = false 543 opts.IsClient = true 544 err = opts.EnsureDefaults() 545 assert.NoError(t, err) 546 err = templates.MustGet("clientParameter").Execute(buf, op) 547 if assert.NoError(t, err) { 548 ff, err := opts.LanguageOpts.FormatContent("put_testing.go", buf.Bytes()) 549 if assert.NoError(t, err) { 550 res := string(ff) 551 assertInCode(t, "valuesTestingThis = append(valuesTestingThis, v.String())", res) 552 } else { 553 fmt.Println(buf.String()) 554 } 555 } 556 } 557 } 558 } 559 560 func TestBuilder_Issue1703(t *testing.T) { 561 log.SetOutput(ioutil.Discard) 562 defer log.SetOutput(os.Stdout) 563 dr, err := os.Getwd() 564 assert.NoError(t, err) 565 566 opts := &GenOpts{ 567 Spec: filepath.FromSlash("../fixtures/codegen/existing-model.yml"), 568 IncludeModel: true, 569 IncludeValidator: true, 570 IncludeHandler: true, 571 IncludeParameters: true, 572 IncludeResponses: true, 573 IncludeMain: true, 574 APIPackage: "restapi", 575 ModelPackage: "model", 576 ServerPackage: "server", 577 ClientPackage: "client", 578 Target: dr, 579 } 580 err = opts.EnsureDefaults() 581 assert.NoError(t, err) 582 appGen, err := newAppGenerator("x-go-type-import-bug", nil, nil, opts) 583 if assert.NoError(t, err) { 584 op, err := appGen.makeCodegenApp() 585 if assert.NoError(t, err) { 586 for _, o := range op.Operations { 587 buf := bytes.NewBuffer(nil) 588 err := templates.MustGet("serverResponses").Execute(buf, o) 589 if assert.NoError(t, err) { 590 ff, err := appGen.GenOpts.LanguageOpts.FormatContent("response.go", buf.Bytes()) 591 if assert.NoError(t, err) { 592 res := string(ff) 593 assertInCode(t, "jwk \"github.com/user/package\"", res) 594 } else { 595 fmt.Println(buf.String()) 596 } 597 } 598 } 599 } 600 } 601 } 602 603 func TestBuilder_Issue287(t *testing.T) { 604 log.SetOutput(ioutil.Discard) 605 defer log.SetOutput(os.Stdout) 606 dr, _ := os.Getwd() 607 608 opts := &GenOpts{ 609 Spec: filepath.FromSlash("../fixtures/bugs/287/swagger.yml"), 610 IncludeModel: true, 611 IncludeValidator: true, 612 IncludeHandler: true, 613 IncludeParameters: true, 614 IncludeResponses: true, 615 IncludeMain: true, 616 APIPackage: "restapi", 617 ModelPackage: "model", 618 ServerPackage: "server", 619 ClientPackage: "client", 620 Target: dr, 621 } 622 err := opts.EnsureDefaults() 623 assert.NoError(t, err) 624 appGen, err := newAppGenerator("plainTexter", nil, nil, opts) 625 if assert.NoError(t, err) { 626 op, err := appGen.makeCodegenApp() 627 if assert.NoError(t, err) { 628 buf := bytes.NewBuffer(nil) 629 err := templates.MustGet("serverBuilder").Execute(buf, op) 630 if assert.NoError(t, err) { 631 ff, err := appGen.GenOpts.LanguageOpts.FormatContent("put_testing.go", buf.Bytes()) 632 if assert.NoError(t, err) { 633 res := string(ff) 634 assertInCode(t, "case \"text/plain\":", res) 635 } else { 636 fmt.Println(buf.String()) 637 } 638 } 639 } 640 } 641 } 642 643 func TestBuilder_Issue465(t *testing.T) { 644 log.SetOutput(ioutil.Discard) 645 defer log.SetOutput(os.Stdout) 646 dr, _ := os.Getwd() 647 opts := &GenOpts{ 648 Spec: filepath.FromSlash("../fixtures/bugs/465/swagger.yml"), 649 IncludeModel: true, 650 IncludeValidator: true, 651 IncludeHandler: true, 652 IncludeParameters: true, 653 IncludeResponses: true, 654 IncludeMain: true, 655 APIPackage: "restapi", 656 ModelPackage: "model", 657 ServerPackage: "server", 658 ClientPackage: "client", 659 Target: dr, 660 IsClient: true, 661 } 662 err := opts.EnsureDefaults() 663 assert.NoError(t, err) 664 appGen, err := newAppGenerator("plainTexter", nil, nil, opts) 665 666 if assert.NoError(t, err) { 667 op, err := appGen.makeCodegenApp() 668 if assert.NoError(t, err) { 669 buf := bytes.NewBuffer(nil) 670 err := templates.MustGet("clientFacade").Execute(buf, op) 671 if assert.NoError(t, err) { 672 ff, err := appGen.GenOpts.LanguageOpts.FormatContent("put_testing.go", buf.Bytes()) 673 if assert.NoError(t, err) { 674 res := string(ff) 675 assertInCode(t, "/v1/fancyAPI", res) 676 } else { 677 fmt.Println(buf.String()) 678 } 679 } 680 } 681 } 682 } 683 684 func TestBuilder_Issue500(t *testing.T) { 685 log.SetOutput(ioutil.Discard) 686 defer log.SetOutput(os.Stdout) 687 dr, _ := os.Getwd() 688 opts := &GenOpts{ 689 Spec: filepath.FromSlash("../fixtures/bugs/500/swagger.yml"), 690 IncludeModel: true, 691 IncludeValidator: true, 692 IncludeHandler: true, 693 IncludeParameters: true, 694 IncludeResponses: true, 695 IncludeMain: true, 696 APIPackage: "restapi", 697 ModelPackage: "model", 698 ServerPackage: "server", 699 ClientPackage: "client", 700 Target: dr, 701 } 702 err := opts.EnsureDefaults() 703 assert.NoError(t, err) 704 appGen, err := newAppGenerator("multiTags", nil, nil, opts) 705 if assert.NoError(t, err) { 706 op, err := appGen.makeCodegenApp() 707 if assert.NoError(t, err) { 708 buf := bytes.NewBuffer(nil) 709 err := templates.MustGet("serverBuilder").Execute(buf, op) 710 if assert.NoError(t, err) { 711 ff, err := appGen.GenOpts.LanguageOpts.FormatContent("put_testing.go", buf.Bytes()) 712 if assert.NoError(t, err) { 713 res := string(ff) 714 assertNotInCode(t, `o.handlers["GET"]["/payment/{invoice_id}/payments/{payment_id}"] = invoices.NewGetPaymentByID(o.context, o.InvoicesGetPaymentByIDHandler)`, res) 715 assertInCode(t, `o.handlers["GET"]["/payment/{invoice_id}/payments/{payment_id}"] = NewGetPaymentByID(o.context, o.GetPaymentByIDHandler)`, res) 716 } else { 717 fmt.Println(buf.String()) 718 } 719 } 720 } 721 } 722 } 723 724 func TestGenClient_IllegalBOM(t *testing.T) { 725 b, err := methodPathOpBuilder("get", "/v3/attachments/{attachmentId}", "../fixtures/bugs/727/swagger.json") 726 if assert.NoError(t, err) { 727 op, err := b.MakeOperation() 728 if assert.NoError(t, err) { 729 buf := bytes.NewBuffer(nil) 730 opts := opts() 731 opts.defaultsEnsured = false 732 opts.IsClient = true 733 err = opts.EnsureDefaults() 734 assert.NoError(t, err) 735 err = templates.MustGet("clientResponse").Execute(buf, op) 736 assert.NoError(t, err) 737 } 738 } 739 } 740 741 func TestGenClient_CustomFormatPath(t *testing.T) { 742 b, err := methodPathOpBuilder("get", "/mosaic/experimental/series/{SeriesId}/mosaics", "../fixtures/bugs/789/swagger.yml") 743 if assert.NoError(t, err) { 744 op, err := b.MakeOperation() 745 if assert.NoError(t, err) { 746 buf := bytes.NewBuffer(nil) 747 opts := opts() 748 opts.defaultsEnsured = false 749 opts.IsClient = true 750 err = opts.EnsureDefaults() 751 assert.NoError(t, err) 752 err = templates.MustGet("clientParameter").Execute(buf, op) 753 if assert.NoError(t, err) { 754 assertInCode(t, `if err := r.SetPathParam("SeriesId", o.SeriesID.String()); err != nil`, buf.String()) 755 } 756 } 757 } 758 } 759 760 func TestGenClient_Issue733(t *testing.T) { 761 b, err := opBuilder("get_characters_character_id_mail_mail_id", "../fixtures/bugs/733/swagger.json") 762 if assert.NoError(t, err) { 763 op, err := b.MakeOperation() 764 if assert.NoError(t, err) { 765 buf := bytes.NewBuffer(nil) 766 opts := opts() 767 opts.defaultsEnsured = false 768 opts.IsClient = true 769 err = opts.EnsureDefaults() 770 assert.NoError(t, err) 771 err = templates.MustGet("clientResponse").Execute(buf, op) 772 if assert.NoError(t, err) { 773 assertInCode(t, "Labels []*int64 `json:\"labels\"`", buf.String()) 774 } 775 } 776 } 777 } 778 779 func TestGenServerIssue890_ValidationTrueFlatteningTrue(t *testing.T) { 780 log.SetOutput(ioutil.Discard) 781 defer log.SetOutput(os.Stdout) 782 dr, _ := os.Getwd() 783 opts := &GenOpts{ 784 Spec: filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"), 785 IncludeModel: true, 786 IncludeValidator: true, 787 IncludeHandler: true, 788 IncludeParameters: true, 789 IncludeResponses: true, 790 IncludeMain: true, 791 ValidateSpec: true, 792 APIPackage: "restapi", 793 ModelPackage: "model", 794 ServerPackage: "server", 795 ClientPackage: "client", 796 Target: dr, 797 IsClient: true, 798 } 799 800 //Testing Server Generation 801 err := opts.EnsureDefaults() 802 // Full flattening 803 opts.FlattenOpts.Expand = false 804 opts.FlattenOpts.Minimal = false 805 assert.NoError(t, err) 806 appGen, err := newAppGenerator("JsonRefOperation", nil, nil, opts) 807 if assert.NoError(t, err) { 808 op, err := appGen.makeCodegenApp() 809 if assert.NoError(t, err) { 810 buf := bytes.NewBuffer(nil) 811 err := templates.MustGet("serverOperation").Execute(buf, op.Operations[0]) 812 if assert.NoError(t, err) { 813 filecontent, err := appGen.GenOpts.LanguageOpts.FormatContent("operation.go", buf.Bytes()) 814 if assert.NoError(t, err) { 815 res := string(filecontent) 816 assertInCode(t, "GetHealthCheck", res) 817 } else { 818 fmt.Println(buf.String()) 819 } 820 } 821 } 822 } 823 } 824 825 func TestGenClientIssue890_ValidationTrueFlatteningTrue(t *testing.T) { 826 log.SetOutput(ioutil.Discard) 827 defer func() { 828 log.SetOutput(os.Stdout) 829 dr, _ := os.Getwd() 830 _ = os.RemoveAll(filepath.Join(filepath.FromSlash(dr), "restapi")) 831 }() 832 opts := testGenOpts() 833 opts.Spec = "../fixtures/bugs/890/swagger.yaml" 834 opts.ValidateSpec = true 835 opts.FlattenOpts.Minimal = false 836 // Testing this is enough as there is only one operation which is specified as $ref. 837 // If this doesn't get resolved then there will be an error definitely. 838 assert.NoError(t, GenerateClient("foo", nil, nil, &opts)) 839 } 840 841 func TestGenServerIssue890_ValidationFalseFlattenTrue(t *testing.T) { 842 log.SetOutput(ioutil.Discard) 843 defer log.SetOutput(os.Stdout) 844 dr, _ := os.Getwd() 845 opts := &GenOpts{ 846 Spec: filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"), 847 IncludeModel: true, 848 IncludeValidator: true, 849 IncludeHandler: true, 850 IncludeParameters: true, 851 IncludeResponses: true, 852 IncludeMain: true, 853 APIPackage: "restapi", 854 ModelPackage: "model", 855 ServerPackage: "server", 856 ClientPackage: "client", 857 Target: dr, 858 IsClient: true, 859 } 860 861 //Testing Server Generation 862 err := opts.EnsureDefaults() 863 // full flattening 864 opts.FlattenOpts.Minimal = false 865 assert.NoError(t, err) 866 appGen, err := newAppGenerator("JsonRefOperation", nil, nil, opts) 867 if assert.NoError(t, err) { 868 op, err := appGen.makeCodegenApp() 869 if assert.NoError(t, err) { 870 buf := bytes.NewBuffer(nil) 871 err := templates.MustGet("serverOperation").Execute(buf, op.Operations[0]) 872 if assert.NoError(t, err) { 873 filecontent, err := appGen.GenOpts.LanguageOpts.FormatContent("operation.go", buf.Bytes()) 874 if assert.NoError(t, err) { 875 res := string(filecontent) 876 assertInCode(t, "GetHealthCheck", res) 877 } else { 878 fmt.Println(buf.String()) 879 } 880 } 881 } 882 } 883 } 884 885 func TestGenClientIssue890_ValidationFalseFlatteningTrue(t *testing.T) { 886 log.SetOutput(ioutil.Discard) 887 defer func() { 888 log.SetOutput(os.Stdout) 889 dr, _ := os.Getwd() 890 _ = os.RemoveAll(filepath.Join(filepath.FromSlash(dr), "restapi")) 891 }() 892 opts := testGenOpts() 893 opts.Spec = "../fixtures/bugs/890/swagger.yaml" 894 opts.ValidateSpec = false 895 // full flattening 896 opts.FlattenOpts.Minimal = false 897 // Testing this is enough as there is only one operation which is specified as $ref. 898 // If this doesn't get resolved then there will be an error definitely. 899 assert.NoError(t, GenerateClient("foo", nil, nil, &opts)) 900 } 901 902 func TestGenServerIssue890_ValidationFalseFlattenFalse(t *testing.T) { 903 log.SetOutput(ioutil.Discard) 904 defer log.SetOutput(os.Stdout) 905 dr, _ := os.Getwd() 906 opts := &GenOpts{ 907 Spec: filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"), 908 IncludeModel: true, 909 IncludeValidator: true, 910 IncludeHandler: true, 911 IncludeParameters: true, 912 IncludeResponses: true, 913 IncludeMain: true, 914 ValidateSpec: false, 915 APIPackage: "restapi", 916 ModelPackage: "model", 917 ServerPackage: "server", 918 ClientPackage: "client", 919 Target: dr, 920 IsClient: true, 921 } 922 923 //Testing Server Generation 924 err := opts.EnsureDefaults() 925 // minimal flattening 926 opts.FlattenOpts.Minimal = true 927 assert.NoError(t, err) 928 _, err = newAppGenerator("JsonRefOperation", nil, nil, opts) 929 // if flatten is not set, expand takes over so this would resume normally 930 assert.NoError(t, err) 931 } 932 933 func TestGenClientIssue890_ValidationFalseFlattenFalse(t *testing.T) { 934 log.SetOutput(ioutil.Discard) 935 defer func() { 936 dr, _ := os.Getwd() 937 _ = os.RemoveAll(filepath.Join(filepath.FromSlash(dr), "restapi")) 938 log.SetOutput(os.Stdout) 939 }() 940 opts := testGenOpts() 941 opts.Spec = "../fixtures/bugs/890/swagger.yaml" 942 opts.ValidateSpec = false 943 // minimal flattening 944 opts.FlattenOpts.Minimal = true 945 // Testing this is enough as there is only one operation which is specified as $ref. 946 // If this doesn't get resolved then there will be an error definitely. 947 // New: Now if flatten is false, expand takes over so server generation should resume normally 948 assert.NoError(t, GenerateClient("foo", nil, nil, &opts)) 949 } 950 951 func TestGenServerIssue890_ValidationTrueFlattenFalse(t *testing.T) { 952 log.SetOutput(ioutil.Discard) 953 defer log.SetOutput(os.Stdout) 954 dr, _ := os.Getwd() 955 opts := &GenOpts{ 956 Spec: filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"), 957 IncludeModel: true, 958 IncludeValidator: true, 959 IncludeHandler: true, 960 IncludeParameters: true, 961 IncludeResponses: true, 962 IncludeMain: true, 963 ValidateSpec: true, 964 APIPackage: "restapi", 965 ModelPackage: "model", 966 ServerPackage: "server", 967 ClientPackage: "client", 968 Target: dr, 969 IsClient: true, 970 } 971 972 //Testing Server Generation 973 err := opts.EnsureDefaults() 974 // minimal flattening 975 opts.FlattenOpts.Minimal = true 976 assert.NoError(t, err) 977 _, err = newAppGenerator("JsonRefOperation", nil, nil, opts) 978 // now if flatten is false, expand takes over so server generation should resume normally 979 assert.NoError(t, err) 980 } 981 982 func TestGenServerWithTemplate(t *testing.T) { 983 log.SetOutput(ioutil.Discard) 984 defer log.SetOutput(os.Stdout) 985 dr, _ := os.Getwd() 986 987 tests := []struct { 988 name string 989 opts *GenOpts 990 wantError bool 991 }{ 992 { 993 name: "None_existing_contributor_tempalte", 994 opts: &GenOpts{ 995 Spec: filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"), 996 IncludeModel: true, 997 IncludeValidator: true, 998 IncludeHandler: true, 999 IncludeParameters: true, 1000 IncludeResponses: true, 1001 IncludeMain: true, 1002 ValidateSpec: true, 1003 APIPackage: "restapi", 1004 ModelPackage: "model", 1005 ServerPackage: "server", 1006 ClientPackage: "client", 1007 Target: dr, 1008 IsClient: true, 1009 Template: "InvalidTemplate", 1010 }, 1011 wantError: true, 1012 }, 1013 { 1014 name: "Existing_contributor", 1015 opts: &GenOpts{ 1016 Spec: filepath.FromSlash("../fixtures/bugs/890/swagger.yaml"), 1017 IncludeModel: true, 1018 IncludeValidator: true, 1019 IncludeHandler: true, 1020 IncludeParameters: true, 1021 IncludeResponses: true, 1022 IncludeMain: true, 1023 ValidateSpec: true, 1024 APIPackage: "restapi", 1025 ModelPackage: "model", 1026 ServerPackage: "server", 1027 ClientPackage: "client", 1028 Target: dr, 1029 IsClient: true, 1030 Template: "stratoscale", 1031 }, 1032 wantError: false, 1033 }, 1034 } 1035 1036 for _, tt := range tests { 1037 t.Run(tt.name, func(t *testing.T) { 1038 //Testing Server Generation 1039 err := tt.opts.EnsureDefaults() 1040 // minimal flattening 1041 tt.opts.FlattenOpts.Minimal = true 1042 assert.NoError(t, err) 1043 _, err = newAppGenerator("JsonRefOperation", nil, nil, tt.opts) 1044 if tt.wantError { 1045 assert.Error(t, err) 1046 } else { 1047 assert.NoError(t, err) 1048 } 1049 }) 1050 } 1051 } 1052 1053 func TestGenClientIssue890_ValidationTrueFlattenFalse(t *testing.T) { 1054 log.SetOutput(ioutil.Discard) 1055 defer func() { 1056 log.SetOutput(os.Stdout) 1057 dr, _ := os.Getwd() 1058 _ = os.RemoveAll(filepath.Join(filepath.FromSlash(dr), "restapi")) 1059 }() 1060 opts := testGenOpts() 1061 opts.Spec = filepath.FromSlash("../fixtures/bugs/890/swagger.yaml") 1062 opts.ValidateSpec = true 1063 // Testing this is enough as there is only one operation which is specified as $ref. 1064 // If this doesn't get resolved then there will be an error definitely. 1065 // same here: now if flatten doesn't resume, expand takes over 1066 assert.NoError(t, GenerateClient("foo", nil, nil, &opts)) 1067 } 1068 1069 // This tests that securityDefinitions generate stable code 1070 func TestBuilder_Issue1214(t *testing.T) { 1071 const any = `(.|\n)+` 1072 log.SetOutput(ioutil.Discard) 1073 defer log.SetOutput(os.Stdout) 1074 dr, _ := os.Getwd() 1075 opts := &GenOpts{ 1076 Spec: filepath.FromSlash("../fixtures/bugs/1214/fixture-1214.yaml"), 1077 IncludeModel: true, 1078 IncludeValidator: true, 1079 IncludeHandler: true, 1080 IncludeParameters: true, 1081 IncludeResponses: true, 1082 IncludeMain: true, 1083 APIPackage: "restapi", 1084 ModelPackage: "model", 1085 ServerPackage: "server", 1086 ClientPackage: "client", 1087 Target: dr, 1088 IsClient: false, 1089 } 1090 err := opts.EnsureDefaults() 1091 assert.NoError(t, err) 1092 appGen, err := newAppGenerator("fixture-1214", nil, nil, opts) 1093 if assert.NoError(t, err) { 1094 op, err := appGen.makeCodegenApp() 1095 if assert.NoError(t, err) { 1096 for i := 0; i < 5; i++ { 1097 buf := bytes.NewBuffer(nil) 1098 ert := templates.MustGet("serverConfigureapi").Execute(buf, op) 1099 if assert.NoError(t, ert) { 1100 ff, erf := appGen.GenOpts.LanguageOpts.FormatContent("fixture_1214_configure_api.go", buf.Bytes()) 1101 if assert.NoError(t, erf) { 1102 res := string(ff) 1103 assertRegexpInCode(t, any+ 1104 `api\.AAuth = func\(user string, pass string\)`+any+ 1105 `api\.BAuth = func\(token string\)`+any+ 1106 `api\.CAuth = func\(token string\)`+any+ 1107 `api\.DAuth = func\(token string\)`+any+ 1108 `api\.EAuth = func\(token string, scopes \[\]string\)`+any, res) 1109 } else { 1110 fmt.Println(buf.String()) 1111 break 1112 } 1113 } else { 1114 break 1115 } 1116 buf = bytes.NewBuffer(nil) 1117 err = templates.MustGet("serverBuilder").Execute(buf, op) 1118 if assert.NoError(t, err) { 1119 ff, err := appGen.GenOpts.LanguageOpts.FormatContent("fixture_1214_server.go", buf.Bytes()) 1120 if assert.NoError(t, err) { 1121 res := string(ff) 1122 assertRegexpInCode(t, any+ 1123 `AAuth: func\(user string, pass string\) \(interface{}, error\) {`+any+ 1124 `BAuth: func\(token string\) \(interface{}, error\) {`+any+ 1125 `CAuth: func\(token string\) \(interface{}, error\) {`+any+ 1126 `DAuth: func\(token string\) \(interface{}, error\) {`+any+ 1127 `EAuth: func\(token string, scopes \[\]string\) \(interface{}, error\) {`+any+ 1128 1129 `AAuth func\(string, string\) \(interface{}, error\)`+any+ 1130 `BAuth func\(string\) \(interface{}, error\)`+any+ 1131 `CAuth func\(string\) \(interface{}, error\)`+any+ 1132 `DAuth func\(string\) \(interface{}, error\)`+any+ 1133 `EAuth func\(string, \[\]string\) \(interface{}, error\)`+any+ 1134 1135 `if o\.AAuth == nil {`+any+ 1136 `unregistered = append\(unregistered, "AAuth"\)`+any+ 1137 `if o\.BAuth == nil {`+any+ 1138 `unregistered = append\(unregistered, "K1Auth"\)`+any+ 1139 `if o\.CAuth == nil {`+any+ 1140 `unregistered = append\(unregistered, "K2Auth"\)`+any+ 1141 `if o\.DAuth == nil {`+any+ 1142 `unregistered = append\(unregistered, "K3Auth"\)`+any+ 1143 `if o\.EAuth == nil {`+any+ 1144 `unregistered = append\(unregistered, "EAuth"\)`+any+ 1145 1146 `case "A":`+any+ 1147 `case "B":`+any+ 1148 `case "C":`+any+ 1149 `case "D":`+any+ 1150 `case "E":`+any, res) 1151 } else { 1152 fmt.Println(buf.String()) 1153 break 1154 } 1155 } else { 1156 break 1157 } 1158 } 1159 } 1160 } 1161 } 1162 1163 func TestGenSecurityRequirements(t *testing.T) { 1164 for i := 0; i < 5; i++ { 1165 operation := "asecOp" 1166 b, err := opBuilder(operation, "../fixtures/bugs/1214/fixture-1214.yaml") 1167 if !assert.NoError(t, err) { 1168 t.FailNow() 1169 return 1170 } 1171 b.Security = b.Analyzed.SecurityRequirementsFor(&b.Operation) 1172 genRequirements := b.makeSecurityRequirements("o") 1173 assert.Len(t, genRequirements, 2) 1174 assert.Equal(t, []GenSecurityRequirements{ 1175 { 1176 GenSecurityRequirement{ 1177 Name: "A", 1178 Scopes: []string{}, 1179 }, 1180 GenSecurityRequirement{ 1181 Name: "B", 1182 Scopes: []string{}, 1183 }, 1184 GenSecurityRequirement{ 1185 Name: "E", 1186 Scopes: []string{"s0", "s1", "s2", "s3", "s4"}, 1187 }, 1188 }, 1189 { 1190 GenSecurityRequirement{ 1191 Name: "C", 1192 Scopes: []string{}, 1193 }, 1194 GenSecurityRequirement{ 1195 Name: "D", 1196 Scopes: []string{}, 1197 }, 1198 GenSecurityRequirement{ 1199 Name: "E", 1200 Scopes: []string{"s5", "s6", "s7", "s8", "s9"}, 1201 }, 1202 }, 1203 }, genRequirements) 1204 1205 operation = "bsecOp" 1206 b, err = opBuilder(operation, "../fixtures/bugs/1214/fixture-1214.yaml") 1207 if !assert.NoError(t, err) { 1208 t.FailNow() 1209 return 1210 } 1211 b.Security = b.Analyzed.SecurityRequirementsFor(&b.Operation) 1212 genRequirements = b.makeSecurityRequirements("o") 1213 assert.Len(t, genRequirements, 2) 1214 assert.Equal(t, []GenSecurityRequirements{ 1215 { 1216 GenSecurityRequirement{ 1217 Name: "A", 1218 Scopes: []string{}, 1219 }, 1220 GenSecurityRequirement{ 1221 Name: "E", 1222 Scopes: []string{"s0", "s1", "s2", "s3", "s4"}, 1223 }, 1224 }, 1225 { 1226 GenSecurityRequirement{ 1227 Name: "D", 1228 Scopes: []string{}, 1229 }, 1230 GenSecurityRequirement{ 1231 Name: "E", 1232 Scopes: []string{"s5", "s6", "s7", "s8", "s9"}, 1233 }, 1234 }, 1235 }, genRequirements) 1236 } 1237 1238 operation := "csecOp" 1239 b, err := opBuilder(operation, "../fixtures/bugs/1214/fixture-1214.yaml") 1240 if !assert.NoError(t, err) { 1241 t.FailNow() 1242 return 1243 } 1244 b.Security = b.Analyzed.SecurityRequirementsFor(&b.Operation) 1245 genRequirements := b.makeSecurityRequirements("o") 1246 assert.NotNil(t, genRequirements) 1247 assert.Len(t, genRequirements, 0) 1248 1249 operation = "nosecOp" 1250 b, err = opBuilder(operation, "../fixtures/bugs/1214/fixture-1214-2.yaml") 1251 if !assert.NoError(t, err) { 1252 t.FailNow() 1253 return 1254 } 1255 b.Security = b.Analyzed.SecurityRequirementsFor(&b.Operation) 1256 genRequirements = b.makeSecurityRequirements("o") 1257 assert.Nil(t, genRequirements) 1258 } 1259 1260 func TestGenerateServerOperation(t *testing.T) { 1261 log.SetOutput(ioutil.Discard) 1262 defer log.SetOutput(os.Stdout) 1263 fname := "../fixtures/codegen/todolist.simple.yml" 1264 1265 tgt, _ := ioutil.TempDir(filepath.Dir(fname), "generated") 1266 defer func() { 1267 _ = os.RemoveAll(tgt) 1268 }() 1269 o := &GenOpts{ 1270 IncludeValidator: true, 1271 ValidateSpec: false, 1272 IncludeModel: true, 1273 IncludeHandler: true, 1274 IncludeParameters: true, 1275 IncludeResponses: true, 1276 ModelPackage: "models", 1277 Spec: fname, 1278 Target: tgt, 1279 } 1280 if err := o.EnsureDefaults(); err != nil { 1281 panic(err) 1282 } 1283 1284 err := GenerateServerOperation([]string{"createTask"}, nil) 1285 assert.Error(t, err) 1286 1287 d := o.TemplateDir 1288 o.TemplateDir = "./nowhere" 1289 err = GenerateServerOperation([]string{"notFound"}, o) 1290 assert.Error(t, err) 1291 o.TemplateDir = d 1292 1293 d = o.Spec 1294 o.Spec = "nowhere.yaml" 1295 err = GenerateServerOperation([]string{"notFound"}, o) 1296 assert.Error(t, err) 1297 o.Spec = d 1298 1299 err = GenerateServerOperation([]string{"notFound"}, o) 1300 assert.Error(t, err) 1301 1302 err = GenerateServerOperation([]string{"createTask"}, o) 1303 if !assert.NoError(t, err) { 1304 t.FailNow() 1305 return 1306 } 1307 // check expected files are generated and that's it 1308 _, err = os.Stat(filepath.Join(tgt, "tasks", "create_task.go")) 1309 assert.NoError(t, err) 1310 _, err = os.Stat(filepath.Join(tgt, "tasks", "create_task_parameters.go")) 1311 assert.NoError(t, err) 1312 _, err = os.Stat(filepath.Join(tgt, "tasks", "create_task_responses.go")) 1313 assert.NoError(t, err) 1314 1315 origStdout := os.Stdout 1316 defer func() { 1317 os.Stdout = origStdout 1318 }() 1319 os.Stdout, _ = os.Create(filepath.Join(tgt, "stdout")) 1320 o.DumpData = true 1321 // just checks this does not fail 1322 err = GenerateServerOperation([]string{"createTask"}, o) 1323 assert.NoError(t, err) 1324 _, err = os.Stat(filepath.Join(tgt, "stdout")) 1325 assert.NoError(t, err) 1326 } 1327 1328 // This tests that mimetypes generate stable code 1329 func TestBuilder_Issue1646(t *testing.T) { 1330 log.SetOutput(ioutil.Discard) 1331 defer log.SetOutput(os.Stdout) 1332 dr, _ := os.Getwd() 1333 opts := &GenOpts{ 1334 Spec: filepath.FromSlash("../fixtures/bugs/1646/fixture-1646.yaml"), 1335 IncludeModel: true, 1336 IncludeValidator: true, 1337 IncludeHandler: true, 1338 IncludeParameters: true, 1339 IncludeResponses: true, 1340 IncludeMain: true, 1341 APIPackage: "restapi", 1342 ModelPackage: "model", 1343 ServerPackage: "server", 1344 ClientPackage: "client", 1345 Target: dr, 1346 IsClient: false, 1347 } 1348 err := opts.EnsureDefaults() 1349 assert.NoError(t, err) 1350 appGen, err := newAppGenerator("fixture-1646", nil, nil, opts) 1351 1352 if assert.NoError(t, err) { 1353 preCons, preConj := appGen.makeConsumes() 1354 preProds, preProdj := appGen.makeProduces() 1355 assert.True(t, preConj) 1356 assert.True(t, preProdj) 1357 for i := 0; i < 5; i++ { 1358 cons, conj := appGen.makeConsumes() 1359 prods, prodj := appGen.makeProduces() 1360 assert.True(t, conj) 1361 assert.True(t, prodj) 1362 assert.Equal(t, preConj, conj) 1363 assert.Equal(t, preProdj, prodj) 1364 assert.Equal(t, preCons, cons) 1365 assert.Equal(t, preProds, prods) 1366 } 1367 } 1368 }