github.com/ManabuSeki/goa-v1@v1.4.3/goagen/gen_app/writers_test.go (about) 1 package genapp_test 2 3 import ( 4 "io/ioutil" 5 "os" 6 7 "github.com/goadesign/goa/design" 8 "github.com/goadesign/goa/design/apidsl" 9 "github.com/goadesign/goa/dslengine" 10 "github.com/goadesign/goa/goagen/codegen" 11 genapp "github.com/goadesign/goa/goagen/gen_app" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 ) 15 16 var _ = Describe("ContextsWriter", func() { 17 var writer *genapp.ContextsWriter 18 var filename string 19 var workspace *codegen.Workspace 20 21 JustBeforeEach(func() { 22 var err error 23 workspace, err = codegen.NewWorkspace("test") 24 Ω(err).ShouldNot(HaveOccurred()) 25 pkg, err := workspace.NewPackage("contexts") 26 Ω(err).ShouldNot(HaveOccurred()) 27 src, err := pkg.CreateSourceFile("test.go") 28 Ω(err).ShouldNot(HaveOccurred()) 29 defer src.Close() 30 filename = src.Abs() 31 writer, err = genapp.NewContextsWriter(filename) 32 Ω(err).ShouldNot(HaveOccurred()) 33 codegen.TempCount = 0 34 }) 35 36 AfterEach(func() { 37 workspace.Delete() 38 }) 39 40 Context("correctly configured", func() { 41 var f *os.File 42 BeforeEach(func() { 43 dslengine.Reset() 44 f, _ = ioutil.TempFile("", "") 45 filename = f.Name() 46 }) 47 48 AfterEach(func() { 49 os.Remove(filename) 50 }) 51 52 Context("with data", func() { 53 var params, headers *design.AttributeDefinition 54 var payload *design.UserTypeDefinition 55 var responses map[string]*design.ResponseDefinition 56 var routes []*design.RouteDefinition 57 58 var data *genapp.ContextTemplateData 59 60 BeforeEach(func() { 61 params = nil 62 headers = nil 63 payload = nil 64 responses = nil 65 routes = nil 66 data = nil 67 }) 68 69 JustBeforeEach(func() { 70 data = &genapp.ContextTemplateData{ 71 Name: "ListBottleContext", 72 ResourceName: "bottles", 73 ActionName: "list", 74 Params: params, 75 Payload: payload, 76 Headers: headers, 77 Responses: responses, 78 Routes: routes, 79 API: design.Design, 80 DefaultPkg: "", 81 } 82 }) 83 84 Context("with simple data", func() { 85 It("writes the simple contexts code", func() { 86 err := writer.Execute(data) 87 Ω(err).ShouldNot(HaveOccurred()) 88 b, err := ioutil.ReadFile(filename) 89 Ω(err).ShouldNot(HaveOccurred()) 90 written := string(b) 91 Ω(written).ShouldNot(BeEmpty()) 92 Ω(written).Should(ContainSubstring(emptyContext)) 93 Ω(written).Should(ContainSubstring(emptyContextFactory)) 94 }) 95 }) 96 97 Context("with a media type setting a ContentType", func() { 98 var contentType = "application/json" 99 100 BeforeEach(func() { 101 mediaType := &design.MediaTypeDefinition{ 102 UserTypeDefinition: &design.UserTypeDefinition{ 103 AttributeDefinition: &design.AttributeDefinition{ 104 Type: design.Object{"foo": {Type: design.String}}, 105 }, 106 }, 107 Identifier: "application/vnd.goa.test", 108 ContentType: contentType, 109 } 110 defView := &design.ViewDefinition{ 111 AttributeDefinition: mediaType.AttributeDefinition, 112 Name: "default", 113 Parent: mediaType, 114 } 115 mediaType.Views = map[string]*design.ViewDefinition{"default": defView} 116 design.Design = new(design.APIDefinition) 117 design.Design.MediaTypes = map[string]*design.MediaTypeDefinition{ 118 design.CanonicalIdentifier(mediaType.Identifier): mediaType, 119 } 120 design.ProjectedMediaTypes = make(map[string]*design.MediaTypeDefinition) 121 responses = map[string]*design.ResponseDefinition{"OK": { 122 Name: "OK", 123 Status: 200, 124 MediaType: mediaType.Identifier, 125 }} 126 }) 127 128 It("the generated code sets the Content-Type header", func() { 129 err := writer.Execute(data) 130 Ω(err).ShouldNot(HaveOccurred()) 131 b, err := ioutil.ReadFile(filename) 132 Ω(err).ShouldNot(HaveOccurred()) 133 written := string(b) 134 Ω(written).ShouldNot(BeEmpty()) 135 Ω(written).Should(ContainSubstring(`ctx.ResponseData.Header().Set("Content-Type", "` + contentType + `")`)) 136 }) 137 }) 138 139 Context("with a collection media type", func() { 140 BeforeEach(func() { 141 elemType := &design.MediaTypeDefinition{ 142 UserTypeDefinition: &design.UserTypeDefinition{ 143 AttributeDefinition: &design.AttributeDefinition{ 144 Type: design.Object{"foo": {Type: design.String}}, 145 }, 146 }, 147 Identifier: "application/vnd.goa.test", 148 } 149 defView := &design.ViewDefinition{ 150 AttributeDefinition: elemType.AttributeDefinition, 151 Name: "default", 152 Parent: elemType, 153 } 154 elemType.Views = map[string]*design.ViewDefinition{"default": defView} 155 design.Design = new(design.APIDefinition) 156 design.Design.MediaTypes = map[string]*design.MediaTypeDefinition{ 157 design.CanonicalIdentifier(elemType.Identifier): elemType, 158 } 159 design.ProjectedMediaTypes = make(map[string]*design.MediaTypeDefinition) 160 mediaType := apidsl.CollectionOf(elemType) 161 dslengine.Execute(mediaType.DSL(), mediaType) 162 responses = map[string]*design.ResponseDefinition{"OK": { 163 Name: "OK", 164 Status: 200, 165 Type: mediaType, 166 }} 167 }) 168 169 It("the generated code sets the response to an empty collection if value is nil", func() { 170 err := writer.Execute(data) 171 Ω(err).ShouldNot(HaveOccurred()) 172 b, err := ioutil.ReadFile(filename) 173 Ω(err).ShouldNot(HaveOccurred()) 174 written := string(b) 175 Ω(written).ShouldNot(BeEmpty()) 176 Ω(written).Should(ContainSubstring(` if r == nil { 177 r = Collection{} 178 } 179 return ctx.ResponseData.Service.Send(ctx.Context, 200, r)`)) 180 }) 181 }) 182 183 Context("with an integer param", func() { 184 var ( 185 intParam *design.AttributeDefinition 186 dataType design.Object 187 validation *dslengine.ValidationDefinition 188 ) 189 190 BeforeEach(func() { 191 intParam = &design.AttributeDefinition{Type: design.Integer} 192 dataType = design.Object{ 193 "param": intParam, 194 } 195 validation = &dslengine.ValidationDefinition{} 196 params = &design.AttributeDefinition{ 197 Type: dataType, 198 Validation: validation, 199 } 200 }) 201 202 It("writes the integer contexts code", func() { 203 err := writer.Execute(data) 204 Ω(err).ShouldNot(HaveOccurred()) 205 b, err := ioutil.ReadFile(filename) 206 Ω(err).ShouldNot(HaveOccurred()) 207 written := string(b) 208 Ω(written).ShouldNot(BeEmpty()) 209 Ω(written).Should(ContainSubstring(intContext)) 210 Ω(written).Should(ContainSubstring(intContextFactory)) 211 }) 212 213 Context("with a default value", func() { 214 BeforeEach(func() { 215 intParam.SetDefault(2) 216 }) 217 218 It("writes the integer contexts code", func() { 219 err := writer.Execute(data) 220 Ω(err).ShouldNot(HaveOccurred()) 221 b, err := ioutil.ReadFile(filename) 222 Ω(err).ShouldNot(HaveOccurred()) 223 written := string(b) 224 Ω(written).ShouldNot(BeEmpty()) 225 Ω(written).Should(ContainSubstring(intDefaultContext)) 226 Ω(written).Should(ContainSubstring(intDefaultContextFactory)) 227 }) 228 }) 229 230 Context("with required attribute", func() { 231 BeforeEach(func() { 232 validation.Required = []string{"param"} 233 }) 234 235 It("writes the integer contexts code", func() { 236 err := writer.Execute(data) 237 Ω(err).ShouldNot(HaveOccurred()) 238 b, err := ioutil.ReadFile(filename) 239 Ω(err).ShouldNot(HaveOccurred()) 240 written := string(b) 241 Ω(written).ShouldNot(BeEmpty()) 242 Ω(written).Should(ContainSubstring(intRequiredContext)) 243 Ω(written).Should(ContainSubstring(intRequiredContextFactory)) 244 }) 245 246 Context("with a default value", func() { 247 BeforeEach(func() { 248 intParam.SetDefault(2) 249 }) 250 251 It("writes the integer contexts code", func() { 252 err := writer.Execute(data) 253 Ω(err).ShouldNot(HaveOccurred()) 254 b, err := ioutil.ReadFile(filename) 255 Ω(err).ShouldNot(HaveOccurred()) 256 written := string(b) 257 Ω(written).ShouldNot(BeEmpty()) 258 Ω(written).Should(ContainSubstring(intRequiredDefaultContext)) 259 Ω(written).Should(ContainSubstring(intRequiredDefaultContextFactory)) 260 }) 261 }) 262 }) 263 }) 264 265 Context("with an string param", func() { 266 var ( 267 strParam *design.AttributeDefinition 268 dataType design.Object 269 validation *dslengine.ValidationDefinition 270 ) 271 272 BeforeEach(func() { 273 strParam = &design.AttributeDefinition{Type: design.String} 274 dataType = design.Object{ 275 "param": strParam, 276 } 277 validation = &dslengine.ValidationDefinition{} 278 params = &design.AttributeDefinition{ 279 Type: dataType, 280 Validation: validation, 281 } 282 }) 283 284 It("writes the string contexts code", func() { 285 err := writer.Execute(data) 286 Ω(err).ShouldNot(HaveOccurred()) 287 b, err := ioutil.ReadFile(filename) 288 Ω(err).ShouldNot(HaveOccurred()) 289 written := string(b) 290 Ω(written).ShouldNot(BeEmpty()) 291 Ω(written).Should(ContainSubstring(strContext)) 292 Ω(written).Should(ContainSubstring(strContextFactory)) 293 }) 294 295 Context("with a default value", func() { 296 BeforeEach(func() { 297 strParam.SetDefault("foo") 298 }) 299 300 It("writes the string contexts code", func() { 301 err := writer.Execute(data) 302 Ω(err).ShouldNot(HaveOccurred()) 303 b, err := ioutil.ReadFile(filename) 304 Ω(err).ShouldNot(HaveOccurred()) 305 written := string(b) 306 Ω(written).ShouldNot(BeEmpty()) 307 Ω(written).Should(ContainSubstring(strNonOptionalContext)) 308 Ω(written).Should(ContainSubstring(strDefaultContextFactory)) 309 }) 310 }) 311 312 Context("with required attribute", func() { 313 BeforeEach(func() { 314 validation.Required = []string{"param"} 315 }) 316 317 It("writes the String contexts code", func() { 318 err := writer.Execute(data) 319 Ω(err).ShouldNot(HaveOccurred()) 320 b, err := ioutil.ReadFile(filename) 321 Ω(err).ShouldNot(HaveOccurred()) 322 written := string(b) 323 Ω(written).ShouldNot(BeEmpty()) 324 Ω(written).Should(ContainSubstring(strNonOptionalContext)) 325 Ω(written).Should(ContainSubstring(strRequiredContextFactory)) 326 }) 327 328 Context("with a default value", func() { 329 BeforeEach(func() { 330 strParam.SetDefault("foo") 331 }) 332 333 It("writes the integer contexts code", func() { 334 err := writer.Execute(data) 335 Ω(err).ShouldNot(HaveOccurred()) 336 b, err := ioutil.ReadFile(filename) 337 Ω(err).ShouldNot(HaveOccurred()) 338 written := string(b) 339 Ω(written).ShouldNot(BeEmpty()) 340 Ω(written).Should(ContainSubstring(strNonOptionalContext)) 341 Ω(written).Should(ContainSubstring(strDefaultContextFactory)) 342 }) 343 }) 344 }) 345 }) 346 347 Context("with a number param", func() { 348 var ( 349 numParam *design.AttributeDefinition 350 dataType design.Object 351 validation *dslengine.ValidationDefinition 352 ) 353 354 BeforeEach(func() { 355 numParam = &design.AttributeDefinition{Type: design.Number} 356 dataType = design.Object{ 357 "param": numParam, 358 } 359 validation = &dslengine.ValidationDefinition{} 360 params = &design.AttributeDefinition{ 361 Type: dataType, 362 Validation: validation, 363 } 364 }) 365 366 It("writes the number contexts code", func() { 367 err := writer.Execute(data) 368 Ω(err).ShouldNot(HaveOccurred()) 369 b, err := ioutil.ReadFile(filename) 370 Ω(err).ShouldNot(HaveOccurred()) 371 written := string(b) 372 Ω(written).ShouldNot(BeEmpty()) 373 Ω(written).Should(ContainSubstring(numContext)) 374 Ω(written).Should(ContainSubstring(numContextFactory)) 375 }) 376 377 Context("with a default value", func() { 378 BeforeEach(func() { 379 numParam.SetDefault(2.3) 380 }) 381 382 It("writes the number contexts code", func() { 383 err := writer.Execute(data) 384 Ω(err).ShouldNot(HaveOccurred()) 385 b, err := ioutil.ReadFile(filename) 386 Ω(err).ShouldNot(HaveOccurred()) 387 written := string(b) 388 Ω(written).ShouldNot(BeEmpty()) 389 Ω(written).Should(ContainSubstring(numNonOptionalContext)) 390 Ω(written).Should(ContainSubstring(numDefaultContextFactory)) 391 }) 392 }) 393 394 Context("with required attribute", func() { 395 BeforeEach(func() { 396 validation.Required = []string{"param"} 397 }) 398 399 It("writes the number contexts code", func() { 400 err := writer.Execute(data) 401 Ω(err).ShouldNot(HaveOccurred()) 402 b, err := ioutil.ReadFile(filename) 403 Ω(err).ShouldNot(HaveOccurred()) 404 written := string(b) 405 Ω(written).ShouldNot(BeEmpty()) 406 Ω(written).Should(ContainSubstring(numNonOptionalContext)) 407 Ω(written).Should(ContainSubstring(numRequiredContextFactory)) 408 }) 409 410 Context("with a default value", func() { 411 BeforeEach(func() { 412 numParam.SetDefault(2.3) 413 }) 414 415 It("writes the number contexts code", func() { 416 err := writer.Execute(data) 417 Ω(err).ShouldNot(HaveOccurred()) 418 b, err := ioutil.ReadFile(filename) 419 Ω(err).ShouldNot(HaveOccurred()) 420 written := string(b) 421 Ω(written).ShouldNot(BeEmpty()) 422 Ω(written).Should(ContainSubstring(numNonOptionalContext)) 423 Ω(written).Should(ContainSubstring(numDefaultContextFactory)) 424 }) 425 }) 426 }) 427 }) 428 429 Context("with a boolean param", func() { 430 var ( 431 boolParam *design.AttributeDefinition 432 dataType design.Object 433 validation *dslengine.ValidationDefinition 434 ) 435 436 BeforeEach(func() { 437 boolParam = &design.AttributeDefinition{Type: design.Boolean} 438 dataType = design.Object{ 439 "param": boolParam, 440 } 441 validation = &dslengine.ValidationDefinition{} 442 params = &design.AttributeDefinition{ 443 Type: dataType, 444 Validation: validation, 445 } 446 }) 447 448 It("writes the boolean contexts code", func() { 449 err := writer.Execute(data) 450 Ω(err).ShouldNot(HaveOccurred()) 451 b, err := ioutil.ReadFile(filename) 452 Ω(err).ShouldNot(HaveOccurred()) 453 written := string(b) 454 Ω(written).ShouldNot(BeEmpty()) 455 Ω(written).Should(ContainSubstring(boolContext)) 456 Ω(written).Should(ContainSubstring(boolContextFactory)) 457 }) 458 459 Context("with a default value", func() { 460 BeforeEach(func() { 461 boolParam.SetDefault(true) 462 }) 463 464 It("writes the boolean contexts code", func() { 465 err := writer.Execute(data) 466 Ω(err).ShouldNot(HaveOccurred()) 467 b, err := ioutil.ReadFile(filename) 468 Ω(err).ShouldNot(HaveOccurred()) 469 written := string(b) 470 Ω(written).ShouldNot(BeEmpty()) 471 Ω(written).Should(ContainSubstring(boolNonOptionalContext)) 472 Ω(written).Should(ContainSubstring(boolDefaultContextFactory)) 473 }) 474 }) 475 476 Context("with required attribute", func() { 477 BeforeEach(func() { 478 validation.Required = []string{"param"} 479 }) 480 481 It("writes the boolean contexts code", func() { 482 err := writer.Execute(data) 483 Ω(err).ShouldNot(HaveOccurred()) 484 b, err := ioutil.ReadFile(filename) 485 Ω(err).ShouldNot(HaveOccurred()) 486 written := string(b) 487 Ω(written).ShouldNot(BeEmpty()) 488 Ω(written).Should(ContainSubstring(boolNonOptionalContext)) 489 Ω(written).Should(ContainSubstring(boolRequiredContextFactory)) 490 }) 491 492 Context("with a default value", func() { 493 BeforeEach(func() { 494 boolParam.SetDefault(true) 495 }) 496 497 It("writes the boolean contexts code", func() { 498 err := writer.Execute(data) 499 Ω(err).ShouldNot(HaveOccurred()) 500 b, err := ioutil.ReadFile(filename) 501 Ω(err).ShouldNot(HaveOccurred()) 502 written := string(b) 503 Ω(written).ShouldNot(BeEmpty()) 504 Ω(written).Should(ContainSubstring(boolNonOptionalContext)) 505 Ω(written).Should(ContainSubstring(boolDefaultContextFactory)) 506 }) 507 }) 508 }) 509 }) 510 511 Context("with a array param", func() { 512 var ( 513 arrayParam *design.AttributeDefinition 514 dataType design.Object 515 validation *dslengine.ValidationDefinition 516 ) 517 518 BeforeEach(func() { 519 arrayParam = &design.AttributeDefinition{Type: &design.Array{ElemType: &design.AttributeDefinition{Type: design.String}}} 520 dataType = design.Object{ 521 "param": arrayParam, 522 } 523 validation = &dslengine.ValidationDefinition{} 524 params = &design.AttributeDefinition{ 525 Type: dataType, 526 Validation: validation, 527 } 528 }) 529 530 It("writes the array contexts code", func() { 531 err := writer.Execute(data) 532 Ω(err).ShouldNot(HaveOccurred()) 533 b, err := ioutil.ReadFile(filename) 534 Ω(err).ShouldNot(HaveOccurred()) 535 written := string(b) 536 Ω(written).ShouldNot(BeEmpty()) 537 Ω(written).Should(ContainSubstring(arrayContext)) 538 Ω(written).Should(ContainSubstring(arrayContextFactory)) 539 }) 540 541 Context("using a path param", func() { 542 BeforeEach(func() { 543 route := &design.RouteDefinition{Path: "/:param"} 544 routes = append(routes, route) 545 }) 546 547 It("writes the array contexts code", func() { 548 err := writer.Execute(data) 549 Ω(err).ShouldNot(HaveOccurred()) 550 b, err := ioutil.ReadFile(filename) 551 Ω(err).ShouldNot(HaveOccurred()) 552 written := string(b) 553 Ω(written).ShouldNot(BeEmpty()) 554 Ω(written).Should(ContainSubstring(arrayParamContextFactory)) 555 }) 556 }) 557 558 Context("with a default value", func() { 559 BeforeEach(func() { 560 arrayParam.SetDefault([]interface{}{"foo", "bar", "baz"}) 561 }) 562 563 It("writes the array contexts code", func() { 564 err := writer.Execute(data) 565 Ω(err).ShouldNot(HaveOccurred()) 566 b, err := ioutil.ReadFile(filename) 567 Ω(err).ShouldNot(HaveOccurred()) 568 written := string(b) 569 Ω(written).ShouldNot(BeEmpty()) 570 Ω(written).Should(ContainSubstring(arrayContext)) 571 Ω(written).Should(ContainSubstring(arrayDefaultContextFactory)) 572 }) 573 }) 574 575 Context("with required attribute", func() { 576 BeforeEach(func() { 577 validation.Required = []string{"param"} 578 }) 579 580 It("writes the array contexts code", func() { 581 err := writer.Execute(data) 582 Ω(err).ShouldNot(HaveOccurred()) 583 b, err := ioutil.ReadFile(filename) 584 Ω(err).ShouldNot(HaveOccurred()) 585 written := string(b) 586 Ω(written).ShouldNot(BeEmpty()) 587 Ω(written).Should(ContainSubstring(arrayContext)) 588 Ω(written).Should(ContainSubstring(arrayRequiredContextFactory)) 589 }) 590 591 Context("with a default value", func() { 592 BeforeEach(func() { 593 arrayParam.SetDefault([]interface{}{"foo", "bar", "baz"}) 594 }) 595 596 It("writes the array contexts code", func() { 597 err := writer.Execute(data) 598 Ω(err).ShouldNot(HaveOccurred()) 599 b, err := ioutil.ReadFile(filename) 600 Ω(err).ShouldNot(HaveOccurred()) 601 written := string(b) 602 Ω(written).ShouldNot(BeEmpty()) 603 Ω(written).Should(ContainSubstring(arrayContext)) 604 Ω(written).Should(ContainSubstring(arrayDefaultContextFactory)) 605 }) 606 }) 607 }) 608 }) 609 610 Context("with an int array param", func() { 611 var ( 612 arrayParam *design.AttributeDefinition 613 dataType design.Object 614 validation *dslengine.ValidationDefinition 615 ) 616 617 BeforeEach(func() { 618 arrayParam = &design.AttributeDefinition{Type: &design.Array{ElemType: &design.AttributeDefinition{Type: design.Integer}}} 619 dataType = design.Object{ 620 "param": arrayParam, 621 } 622 validation = &dslengine.ValidationDefinition{} 623 params = &design.AttributeDefinition{ 624 Type: dataType, 625 Validation: validation, 626 } 627 }) 628 629 It("writes the array contexts code", func() { 630 err := writer.Execute(data) 631 Ω(err).ShouldNot(HaveOccurred()) 632 b, err := ioutil.ReadFile(filename) 633 Ω(err).ShouldNot(HaveOccurred()) 634 written := string(b) 635 Ω(written).ShouldNot(BeEmpty()) 636 Ω(written).Should(ContainSubstring(intArrayContext)) 637 Ω(written).Should(ContainSubstring(intArrayContextFactory)) 638 }) 639 640 Context("with a default value", func() { 641 BeforeEach(func() { 642 arrayParam.SetDefault([]interface{}{1, 1, 2, 3, 5, 8}) 643 }) 644 645 It("writes the array contexts code", func() { 646 err := writer.Execute(data) 647 Ω(err).ShouldNot(HaveOccurred()) 648 b, err := ioutil.ReadFile(filename) 649 Ω(err).ShouldNot(HaveOccurred()) 650 written := string(b) 651 Ω(written).ShouldNot(BeEmpty()) 652 Ω(written).Should(ContainSubstring(intArrayContext)) 653 Ω(written).Should(ContainSubstring(intArrayDefaultContextFactory)) 654 }) 655 }) 656 657 Context("with required attribute", func() { 658 BeforeEach(func() { 659 validation.Required = []string{"param"} 660 }) 661 662 It("writes the array contexts code", func() { 663 err := writer.Execute(data) 664 Ω(err).ShouldNot(HaveOccurred()) 665 b, err := ioutil.ReadFile(filename) 666 Ω(err).ShouldNot(HaveOccurred()) 667 written := string(b) 668 Ω(written).ShouldNot(BeEmpty()) 669 Ω(written).Should(ContainSubstring(intArrayContext)) 670 Ω(written).Should(ContainSubstring(intArrayRequiredContextFactory)) 671 }) 672 673 Context("with a default value", func() { 674 BeforeEach(func() { 675 arrayParam.SetDefault([]interface{}{1, 1, 2, 3, 5, 8}) 676 }) 677 678 It("writes the array contexts code", func() { 679 err := writer.Execute(data) 680 Ω(err).ShouldNot(HaveOccurred()) 681 b, err := ioutil.ReadFile(filename) 682 Ω(err).ShouldNot(HaveOccurred()) 683 written := string(b) 684 Ω(written).ShouldNot(BeEmpty()) 685 Ω(written).Should(ContainSubstring(intArrayContext)) 686 Ω(written).Should(ContainSubstring(intArrayDefaultContextFactory)) 687 }) 688 }) 689 }) 690 }) 691 692 Context("with an param using a reserved keyword as name", func() { 693 BeforeEach(func() { 694 intParam := &design.AttributeDefinition{Type: design.Integer} 695 dataType := design.Object{ 696 "int": intParam, 697 } 698 params = &design.AttributeDefinition{ 699 Type: dataType, 700 } 701 }) 702 703 It("writes the contexts code", func() { 704 err := writer.Execute(data) 705 Ω(err).ShouldNot(HaveOccurred()) 706 b, err := ioutil.ReadFile(filename) 707 Ω(err).ShouldNot(HaveOccurred()) 708 written := string(b) 709 Ω(written).ShouldNot(BeEmpty()) 710 Ω(written).Should(ContainSubstring(resContext)) 711 Ω(written).Should(ContainSubstring(resContextFactory)) 712 }) 713 }) 714 715 Context("with a required param", func() { 716 BeforeEach(func() { 717 intParam := &design.AttributeDefinition{Type: design.Integer} 718 dataType := design.Object{ 719 "int": intParam, 720 } 721 required := &dslengine.ValidationDefinition{ 722 Required: []string{"int"}, 723 } 724 params = &design.AttributeDefinition{ 725 Type: dataType, 726 Validation: required, 727 } 728 }) 729 730 It("writes the contexts code", func() { 731 err := writer.Execute(data) 732 Ω(err).ShouldNot(HaveOccurred()) 733 b, err := ioutil.ReadFile(filename) 734 Ω(err).ShouldNot(HaveOccurred()) 735 written := string(b) 736 Ω(written).ShouldNot(BeEmpty()) 737 Ω(written).Should(ContainSubstring(requiredContext)) 738 Ω(written).Should(ContainSubstring(requiredContextFactory)) 739 }) 740 }) 741 742 Context("with a custom name param", func() { 743 BeforeEach(func() { 744 intParam := &design.AttributeDefinition{ 745 Type: design.Integer, 746 Metadata: dslengine.MetadataDefinition{ 747 "struct:field:name": []string{"custom"}, 748 }, 749 } 750 dataType := design.Object{ 751 "int": intParam, 752 } 753 params = &design.AttributeDefinition{ 754 Type: dataType, 755 } 756 }) 757 758 It("writes the contexts code", func() { 759 err := writer.Execute(data) 760 Ω(err).ShouldNot(HaveOccurred()) 761 b, err := ioutil.ReadFile(filename) 762 Ω(err).ShouldNot(HaveOccurred()) 763 written := string(b) 764 Ω(written).ShouldNot(BeEmpty()) 765 Ω(written).Should(ContainSubstring(customContext)) 766 Ω(written).Should(ContainSubstring(customContextFactory)) 767 }) 768 }) 769 770 Context("with a string header", func() { 771 BeforeEach(func() { 772 strHeader := &design.AttributeDefinition{Type: design.String} 773 dataType := design.Object{ 774 "Header": strHeader, 775 } 776 headers = &design.AttributeDefinition{ 777 Type: dataType, 778 } 779 }) 780 781 It("writes the contexts code", func() { 782 err := writer.Execute(data) 783 Ω(err).ShouldNot(HaveOccurred()) 784 b, err := ioutil.ReadFile(filename) 785 Ω(err).ShouldNot(HaveOccurred()) 786 written := string(b) 787 Ω(written).ShouldNot(BeEmpty()) 788 Ω(written).Should(ContainSubstring(strHeaderContext)) 789 Ω(written).Should(ContainSubstring(strHeaderContextFactory)) 790 }) 791 }) 792 793 Context("with a string header and param with the same name", func() { 794 BeforeEach(func() { 795 str := &design.AttributeDefinition{Type: design.String} 796 dataType := design.Object{ 797 "param": str, 798 } 799 params = &design.AttributeDefinition{ 800 Type: dataType, 801 } 802 headers = &design.AttributeDefinition{ 803 Type: dataType, 804 } 805 }) 806 807 It("writes the contexts code", func() { 808 err := writer.Execute(data) 809 Ω(err).ShouldNot(HaveOccurred()) 810 b, err := ioutil.ReadFile(filename) 811 Ω(err).ShouldNot(HaveOccurred()) 812 written := string(b) 813 Ω(written).ShouldNot(BeEmpty()) 814 Ω(written).Should(ContainSubstring(strContext)) 815 Ω(written).Should(ContainSubstring(strHeaderParamContextFactory)) 816 }) 817 }) 818 819 Context("with a simple payload", func() { 820 BeforeEach(func() { 821 design.Design = new(design.APIDefinition) 822 payload = &design.UserTypeDefinition{ 823 AttributeDefinition: &design.AttributeDefinition{Type: design.String}, 824 TypeName: "ListBottlePayload", 825 } 826 }) 827 828 It("writes the contexts code", func() { 829 err := writer.Execute(data) 830 Ω(err).ShouldNot(HaveOccurred()) 831 b, err := ioutil.ReadFile(filename) 832 Ω(err).ShouldNot(HaveOccurred()) 833 written := string(b) 834 Ω(written).ShouldNot(BeEmpty()) 835 Ω(written).Should(ContainSubstring(payloadContext)) 836 Ω(written).Should(ContainSubstring(payloadContextFactory)) 837 }) 838 }) 839 840 Context("with a object payload", func() { 841 BeforeEach(func() { 842 design.Design = new(design.APIDefinition) 843 intParam := &design.AttributeDefinition{Type: design.Integer} 844 strParam := &design.AttributeDefinition{Type: design.String} 845 dataType := design.Object{ 846 "int": intParam, 847 "str": strParam, 848 } 849 required := &dslengine.ValidationDefinition{ 850 Required: []string{"int"}, 851 } 852 payload = &design.UserTypeDefinition{ 853 AttributeDefinition: &design.AttributeDefinition{ 854 Type: dataType, 855 Validation: required, 856 }, 857 TypeName: "ListBottlePayload", 858 } 859 }) 860 861 It("writes the contexts code", func() { 862 err := writer.Execute(data) 863 Ω(err).ShouldNot(HaveOccurred()) 864 b, err := ioutil.ReadFile(filename) 865 Ω(err).ShouldNot(HaveOccurred()) 866 written := string(b) 867 Ω(written).ShouldNot(BeEmpty()) 868 Ω(written).Should(ContainSubstring(payloadObjContext)) 869 }) 870 871 var _ = Describe("IterateResponses", func() { 872 var resps []*design.ResponseDefinition 873 var testIt = func(r *design.ResponseDefinition) error { 874 resps = append(resps, r) 875 return nil 876 } 877 Context("with responses", func() { 878 BeforeEach(func() { 879 responses = map[string]*design.ResponseDefinition{ 880 "OK": {Status: 200}, 881 "Created": {Status: 201}, 882 } 883 }) 884 It("iterates responses in order", func() { 885 data.IterateResponses(testIt) 886 Ω(resps).Should(Equal([]*design.ResponseDefinition{ 887 responses["OK"], 888 responses["Created"], 889 })) 890 }) 891 }) 892 }) 893 }) 894 }) 895 }) 896 }) 897 898 var _ = Describe("ControllersWriter", func() { 899 var writer *genapp.ControllersWriter 900 var workspace *codegen.Workspace 901 var filename string 902 903 BeforeEach(func() { 904 var err error 905 workspace, err = codegen.NewWorkspace("test") 906 Ω(err).ShouldNot(HaveOccurred()) 907 pkg, err := workspace.NewPackage("controllers") 908 Ω(err).ShouldNot(HaveOccurred()) 909 src, err := pkg.CreateSourceFile("test.go") 910 Ω(err).ShouldNot(HaveOccurred()) 911 defer src.Close() 912 filename = src.Abs() 913 }) 914 915 JustBeforeEach(func() { 916 var err error 917 writer, err = genapp.NewControllersWriter(filename) 918 Ω(err).ShouldNot(HaveOccurred()) 919 }) 920 921 AfterEach(func() { 922 workspace.Delete() 923 }) 924 925 Context("correctly configured", func() { 926 BeforeEach(func() { 927 os.Create(filename) 928 }) 929 930 Context("with file servers", func() { 931 requestPath := "/swagger.json" 932 filePath := "swagger/swagger.json" 933 var origins []*design.CORSDefinition 934 var preflightPaths []string 935 936 var data []*genapp.ControllerTemplateData 937 938 BeforeEach(func() { 939 origins = nil 940 preflightPaths = nil 941 }) 942 943 JustBeforeEach(func() { 944 codegen.TempCount = 0 945 fileServer := &design.FileServerDefinition{ 946 FilePath: filePath, 947 RequestPath: requestPath, 948 } 949 d := &genapp.ControllerTemplateData{ 950 API: &design.APIDefinition{}, 951 Origins: origins, 952 PreflightPaths: preflightPaths, 953 Resource: "Public", 954 FileServers: []*design.FileServerDefinition{fileServer}, 955 } 956 data = []*genapp.ControllerTemplateData{d} 957 }) 958 959 It("writes the file server code", func() { 960 err := writer.Execute(data) 961 Ω(err).ShouldNot(HaveOccurred()) 962 b, err := ioutil.ReadFile(filename) 963 Ω(err).ShouldNot(HaveOccurred()) 964 written := string(b) 965 Ω(written).ShouldNot(BeEmpty()) 966 Ω(written).Should(ContainSubstring(simpleFileServer)) 967 }) 968 969 Context("with CORS", func() { 970 BeforeEach(func() { 971 origins = []*design.CORSDefinition{ 972 { 973 // NB: including backslash to ensure proper escaping 974 Origin: "here.example.com", 975 Headers: []string{"X-One", "X-Two"}, 976 Methods: []string{"GET", "POST"}, 977 Exposed: []string{"X-Three"}, 978 Credentials: true, 979 }, 980 } 981 preflightPaths = []string{"/public/star\\*star/*filepath"} 982 }) 983 984 It("writes the OPTIONS handler code", func() { 985 err := writer.Execute(data) 986 Ω(err).ShouldNot(HaveOccurred()) 987 b, err := ioutil.ReadFile(filename) 988 Ω(err).ShouldNot(HaveOccurred()) 989 written := string(b) 990 Ω(written).ShouldNot(BeEmpty()) 991 Ω(written).Should(ContainSubstring(fileServerOptionsHandler)) 992 }) 993 }) 994 }) 995 996 Context("with data", func() { 997 var multipart bool 998 var actions, verbs, paths, contexts, unmarshals []string 999 var payloads []*design.UserTypeDefinition 1000 var encoders, decoders []*genapp.EncoderTemplateData 1001 var origins []*design.CORSDefinition 1002 1003 var data []*genapp.ControllerTemplateData 1004 1005 BeforeEach(func() { 1006 multipart = false 1007 actions = nil 1008 verbs = nil 1009 paths = nil 1010 contexts = nil 1011 unmarshals = nil 1012 payloads = nil 1013 encoders = nil 1014 decoders = nil 1015 origins = nil 1016 }) 1017 1018 JustBeforeEach(func() { 1019 codegen.TempCount = 0 1020 api := &design.APIDefinition{} 1021 d := &genapp.ControllerTemplateData{ 1022 Resource: "Bottles", 1023 Origins: origins, 1024 } 1025 as := make([]map[string]interface{}, len(actions)) 1026 for i, a := range actions { 1027 var unmarshal string 1028 var payload *design.UserTypeDefinition 1029 if i < len(unmarshals) { 1030 unmarshal = unmarshals[i] 1031 } 1032 if i < len(payloads) { 1033 payload = payloads[i] 1034 } 1035 as[i] = map[string]interface{}{ 1036 "Name": codegen.Goify(a, true), 1037 "DesignName": a, 1038 "Routes": []*design.RouteDefinition{ 1039 { 1040 Verb: verbs[i], 1041 Path: paths[i], 1042 }}, 1043 "Context": contexts[i], 1044 "Unmarshal": unmarshal, 1045 "Payload": payload, 1046 "PayloadMultipart": multipart, 1047 } 1048 } 1049 if len(as) > 0 { 1050 d.API = api 1051 d.Actions = as 1052 d.Encoders = encoders 1053 d.Decoders = decoders 1054 data = []*genapp.ControllerTemplateData{d} 1055 } else { 1056 data = nil 1057 } 1058 }) 1059 1060 Context("with missing data", func() { 1061 It("returns an empty string", func() { 1062 err := writer.Execute(data) 1063 Ω(err).ShouldNot(HaveOccurred()) 1064 b, err := ioutil.ReadFile(filename) 1065 Ω(err).ShouldNot(HaveOccurred()) 1066 written := string(b) 1067 Ω(written).Should(BeEmpty()) 1068 }) 1069 }) 1070 1071 Context("with a simple controller", func() { 1072 BeforeEach(func() { 1073 actions = []string{"list"} 1074 verbs = []string{"GET"} 1075 paths = []string{"/accounts/:accountID/bottles"} 1076 contexts = []string{"ListBottleContext"} 1077 }) 1078 1079 It("writes the controller code", func() { 1080 err := writer.Execute(data) 1081 Ω(err).ShouldNot(HaveOccurred()) 1082 b, err := ioutil.ReadFile(filename) 1083 Ω(err).ShouldNot(HaveOccurred()) 1084 written := string(b) 1085 Ω(written).ShouldNot(BeEmpty()) 1086 Ω(written).Should(ContainSubstring(simpleController)) 1087 Ω(written).Should(ContainSubstring(simpleMount)) 1088 }) 1089 }) 1090 1091 Context("with actions that take a payload", func() { 1092 BeforeEach(func() { 1093 actions = []string{"list"} 1094 verbs = []string{"GET"} 1095 paths = []string{"/accounts/:accountID/bottles"} 1096 contexts = []string{"ListBottleContext"} 1097 unmarshals = []string{"unmarshalListBottlePayload"} 1098 payloads = []*design.UserTypeDefinition{ 1099 { 1100 TypeName: "ListBottlePayload", 1101 AttributeDefinition: &design.AttributeDefinition{ 1102 Type: design.Object{ 1103 "id": &design.AttributeDefinition{ 1104 Type: design.String, 1105 }, 1106 }, 1107 }, 1108 }, 1109 } 1110 }) 1111 1112 It("writes the payload unmarshal function", func() { 1113 err := writer.Execute(data) 1114 Ω(err).ShouldNot(HaveOccurred()) 1115 b, err := ioutil.ReadFile(filename) 1116 Ω(err).ShouldNot(HaveOccurred()) 1117 written := string(b) 1118 Ω(written).Should(ContainSubstring(payloadNoValidationsObjUnmarshal)) 1119 }) 1120 }) 1121 Context("with actions that take a payload with a required validation", func() { 1122 BeforeEach(func() { 1123 actions = []string{"list"} 1124 required := &dslengine.ValidationDefinition{ 1125 Required: []string{"id"}, 1126 } 1127 verbs = []string{"GET"} 1128 paths = []string{"/accounts/:accountID/bottles"} 1129 contexts = []string{"ListBottleContext"} 1130 unmarshals = []string{"unmarshalListBottlePayload"} 1131 payloads = []*design.UserTypeDefinition{ 1132 { 1133 TypeName: "ListBottlePayload", 1134 AttributeDefinition: &design.AttributeDefinition{ 1135 Type: design.Object{ 1136 "id": &design.AttributeDefinition{ 1137 Type: design.String, 1138 }, 1139 }, 1140 Validation: required, 1141 }, 1142 }, 1143 } 1144 }) 1145 1146 It("writes the payload unmarshal function", func() { 1147 err := writer.Execute(data) 1148 Ω(err).ShouldNot(HaveOccurred()) 1149 b, err := ioutil.ReadFile(filename) 1150 Ω(err).ShouldNot(HaveOccurred()) 1151 written := string(b) 1152 Ω(written).Should(ContainSubstring(payloadObjUnmarshal)) 1153 }) 1154 }) 1155 1156 Context("with actions that take a multipart payload", func() { 1157 BeforeEach(func() { 1158 actions = []string{"list"} 1159 required := &dslengine.ValidationDefinition{ 1160 Required: []string{"id"}, 1161 } 1162 verbs = []string{"GET"} 1163 paths = []string{"/accounts/:accountID/bottles"} 1164 contexts = []string{"ListBottleContext"} 1165 unmarshals = []string{"unmarshalListBottlePayload"} 1166 payloads = []*design.UserTypeDefinition{ 1167 { 1168 TypeName: "ListBottlePayload", 1169 AttributeDefinition: &design.AttributeDefinition{ 1170 Type: design.Object{ 1171 "id": &design.AttributeDefinition{ 1172 Type: design.Integer, 1173 }, 1174 "title": &design.AttributeDefinition{ 1175 Type: design.String, 1176 }, 1177 "icon": &design.AttributeDefinition{ 1178 Type: design.File, 1179 }, 1180 "flags": &design.AttributeDefinition{ 1181 Type: &design.Array{ 1182 ElemType: &design.AttributeDefinition{ 1183 Type: design.Boolean, 1184 }, 1185 }, 1186 }, 1187 "optionCodes": &design.AttributeDefinition{ 1188 Type: &design.Array{ 1189 ElemType: &design.AttributeDefinition{ 1190 Type: design.Integer, 1191 }, 1192 }, 1193 }, 1194 "ratios": &design.AttributeDefinition{ 1195 Type: &design.Array{ 1196 ElemType: &design.AttributeDefinition{ 1197 Type: design.Number, 1198 }, 1199 }, 1200 }, 1201 "commentLines": &design.AttributeDefinition{ 1202 Type: &design.Array{ 1203 ElemType: &design.AttributeDefinition{ 1204 Type: design.String, 1205 }, 1206 }, 1207 }, 1208 "objs": &design.AttributeDefinition{ 1209 Type: &design.Array{ 1210 ElemType: &design.AttributeDefinition{ 1211 Type: &design.Object{}, 1212 }, 1213 }, 1214 }, 1215 "hashObjs": &design.AttributeDefinition{ 1216 Type: &design.Array{ 1217 ElemType: &design.AttributeDefinition{ 1218 Type: &design.Hash{ 1219 KeyType: &design.AttributeDefinition{ 1220 Type: design.String, 1221 }, 1222 ElemType: &design.AttributeDefinition{ 1223 Type: &design.Array{ 1224 ElemType: &design.AttributeDefinition{ 1225 Type: design.String, 1226 }, 1227 }, 1228 }, 1229 }, 1230 }, 1231 }, 1232 }, 1233 }, 1234 Validation: required, 1235 }, 1236 }, 1237 } 1238 multipart = true 1239 }) 1240 1241 It("writes the payload unmarshal function", func() { 1242 err := writer.Execute(data) 1243 Ω(err).ShouldNot(HaveOccurred()) 1244 b, err := ioutil.ReadFile(filename) 1245 Ω(err).ShouldNot(HaveOccurred()) 1246 written := string(b) 1247 Ω(written).Should(ContainSubstring(payloadMultipartObjUnmarshalID)) 1248 Ω(written).Should(ContainSubstring(payloadMultipartObjUnmarshalTitle)) 1249 Ω(written).Should(ContainSubstring(payloadMultipartObjUnmarshalIcon)) 1250 Ω(written).Should(ContainSubstring(payloadMultipartObjUnmarshalFlags)) 1251 Ω(written).Should(ContainSubstring(payloadMultipartObjUnmarshalOptionCodes)) 1252 Ω(written).Should(ContainSubstring(payloadMultipartObjUnmarshalRatios)) 1253 Ω(written).Should(ContainSubstring(payloadMultipartObjUnmarshalCommentLines)) 1254 Ω(written).Should(ContainSubstring(payloadMultipartObjUnmarshalObjs)) 1255 Ω(written).Should(ContainSubstring(payloadMultipartObjUnmarshalHashObjs)) 1256 }) 1257 }) 1258 1259 Context("with multiple controllers", func() { 1260 BeforeEach(func() { 1261 actions = []string{"list", "show"} 1262 verbs = []string{"GET", "GET"} 1263 paths = []string{"/accounts/:accountID/bottles", "/accounts/:accountID/bottles/:id"} 1264 contexts = []string{"ListBottleContext", "ShowBottleContext"} 1265 }) 1266 1267 It("writes the controllers code", func() { 1268 err := writer.Execute(data) 1269 Ω(err).ShouldNot(HaveOccurred()) 1270 b, err := ioutil.ReadFile(filename) 1271 Ω(err).ShouldNot(HaveOccurred()) 1272 written := string(b) 1273 Ω(written).ShouldNot(BeEmpty()) 1274 Ω(written).Should(ContainSubstring(multiController)) 1275 Ω(written).Should(ContainSubstring(multiMount)) 1276 }) 1277 }) 1278 1279 Context("with encoder and decoder maps", func() { 1280 BeforeEach(func() { 1281 actions = []string{"list"} 1282 verbs = []string{"GET"} 1283 paths = []string{"/accounts/:accountID/bottles"} 1284 contexts = []string{"ListBottleContext"} 1285 encoders = []*genapp.EncoderTemplateData{ 1286 { 1287 PackageName: "goa", 1288 Function: "NewEncoder", 1289 MIMETypes: []string{"application/json"}, 1290 }, 1291 } 1292 decoders = []*genapp.EncoderTemplateData{ 1293 { 1294 PackageName: "goa", 1295 Function: "NewDecoder", 1296 MIMETypes: []string{"application/json"}, 1297 }, 1298 } 1299 }) 1300 1301 It("writes the controllers code", func() { 1302 err := writer.Execute(data) 1303 Ω(err).ShouldNot(HaveOccurred()) 1304 b, err := ioutil.ReadFile(filename) 1305 Ω(err).ShouldNot(HaveOccurred()) 1306 written := string(b) 1307 Ω(written).ShouldNot(BeEmpty()) 1308 Ω(written).Should(ContainSubstring(encoderController)) 1309 }) 1310 }) 1311 1312 Context("with multiple origins", func() { 1313 BeforeEach(func() { 1314 actions = []string{"list"} 1315 verbs = []string{"GET"} 1316 paths = []string{"/accounts"} 1317 contexts = []string{"ListBottleContext"} 1318 origins = []*design.CORSDefinition{ 1319 { 1320 Origin: "here.example.com", 1321 Headers: []string{"X-One", "X-Two"}, 1322 Methods: []string{"GET", "POST"}, 1323 Exposed: []string{"X-Three"}, 1324 Credentials: true, 1325 }, 1326 { 1327 Origin: "there.example.com", 1328 Headers: []string{"*"}, 1329 Methods: []string{"*"}, 1330 }, 1331 } 1332 1333 }) 1334 1335 It("writes the controller code", func() { 1336 err := writer.Execute(data) 1337 Ω(err).ShouldNot(HaveOccurred()) 1338 b, err := ioutil.ReadFile(filename) 1339 Ω(err).ShouldNot(HaveOccurred()) 1340 written := string(b) 1341 Ω(written).ShouldNot(BeEmpty()) 1342 Ω(written).Should(ContainSubstring(originsIntegration)) 1343 Ω(written).Should(ContainSubstring(originsHandler)) 1344 }) 1345 }) 1346 1347 Context("with regexp origins", func() { 1348 BeforeEach(func() { 1349 actions = []string{"list"} 1350 verbs = []string{"GET"} 1351 paths = []string{"/accounts"} 1352 contexts = []string{"ListBottleContext"} 1353 origins = []*design.CORSDefinition{ 1354 { 1355 Origin: "[here|there].example.com", 1356 Headers: []string{"X-One", "X-Two"}, 1357 Methods: []string{"GET", "POST"}, 1358 Exposed: []string{"X-Three"}, 1359 Credentials: true, 1360 Regexp: true, 1361 }, 1362 { 1363 Origin: "there.example.com", 1364 Headers: []string{"*"}, 1365 Methods: []string{"*"}, 1366 }, 1367 } 1368 1369 }) 1370 1371 It("writes the controller code", func() { 1372 err := writer.Execute(data) 1373 Ω(err).ShouldNot(HaveOccurred()) 1374 b, err := ioutil.ReadFile(filename) 1375 Ω(err).ShouldNot(HaveOccurred()) 1376 written := string(b) 1377 Ω(written).ShouldNot(BeEmpty()) 1378 Ω(written).Should(ContainSubstring(originsIntegration)) 1379 Ω(written).Should(ContainSubstring(regexpOriginsHandler)) 1380 }) 1381 }) 1382 1383 }) 1384 }) 1385 }) 1386 1387 var _ = Describe("HrefWriter", func() { 1388 var writer *genapp.ResourcesWriter 1389 var workspace *codegen.Workspace 1390 var filename string 1391 1392 BeforeEach(func() { 1393 var err error 1394 workspace, err = codegen.NewWorkspace("test") 1395 Ω(err).ShouldNot(HaveOccurred()) 1396 pkg, err := workspace.NewPackage("controllers") 1397 Ω(err).ShouldNot(HaveOccurred()) 1398 src, err := pkg.CreateSourceFile("test.go") 1399 Ω(err).ShouldNot(HaveOccurred()) 1400 defer src.Close() 1401 filename = src.Abs() 1402 }) 1403 1404 JustBeforeEach(func() { 1405 var err error 1406 writer, err = genapp.NewResourcesWriter(filename) 1407 Ω(err).ShouldNot(HaveOccurred()) 1408 }) 1409 1410 AfterEach(func() { 1411 workspace.Delete() 1412 }) 1413 1414 Context("correctly configured", func() { 1415 Context("with data", func() { 1416 var canoTemplate string 1417 var canoParams []string 1418 var mediaType *design.MediaTypeDefinition 1419 1420 var data *genapp.ResourceData 1421 1422 BeforeEach(func() { 1423 mediaType = nil 1424 canoTemplate = "" 1425 canoParams = nil 1426 data = nil 1427 }) 1428 1429 JustBeforeEach(func() { 1430 data = &genapp.ResourceData{ 1431 Name: "Bottle", 1432 Identifier: "vnd.acme.com/resources", 1433 Description: "A bottle resource", 1434 Type: mediaType, 1435 CanonicalTemplate: canoTemplate, 1436 CanonicalParams: canoParams, 1437 } 1438 }) 1439 1440 Context("with missing resource type definition", func() { 1441 It("does not return an error", func() { 1442 err := writer.Execute(data) 1443 Ω(err).ShouldNot(HaveOccurred()) 1444 }) 1445 }) 1446 1447 Context("with a string resource", func() { 1448 BeforeEach(func() { 1449 attDef := &design.AttributeDefinition{ 1450 Type: design.String, 1451 } 1452 mediaType = &design.MediaTypeDefinition{ 1453 UserTypeDefinition: &design.UserTypeDefinition{ 1454 AttributeDefinition: attDef, 1455 TypeName: "Bottle", 1456 }, 1457 } 1458 }) 1459 It("does not return an error", func() { 1460 err := writer.Execute(data) 1461 Ω(err).ShouldNot(HaveOccurred()) 1462 }) 1463 }) 1464 1465 Context("with a user type resource", func() { 1466 BeforeEach(func() { 1467 intParam := &design.AttributeDefinition{Type: design.Integer} 1468 strParam := &design.AttributeDefinition{Type: design.String} 1469 dataType := design.Object{ 1470 "int": intParam, 1471 "str": strParam, 1472 } 1473 attDef := &design.AttributeDefinition{ 1474 Type: dataType, 1475 } 1476 mediaType = &design.MediaTypeDefinition{ 1477 UserTypeDefinition: &design.UserTypeDefinition{ 1478 AttributeDefinition: attDef, 1479 TypeName: "Bottle", 1480 }, 1481 } 1482 }) 1483 1484 Context("and a canonical action", func() { 1485 BeforeEach(func() { 1486 canoTemplate = "/bottles/%v" 1487 canoParams = []string{"id"} 1488 }) 1489 1490 It("writes the href method", func() { 1491 err := writer.Execute(data) 1492 Ω(err).ShouldNot(HaveOccurred()) 1493 b, err := ioutil.ReadFile(filename) 1494 Ω(err).ShouldNot(HaveOccurred()) 1495 written := string(b) 1496 Ω(written).ShouldNot(BeEmpty()) 1497 Ω(written).Should(ContainSubstring(simpleResourceHref)) 1498 }) 1499 }) 1500 1501 Context("and a canonical action with no param", func() { 1502 BeforeEach(func() { 1503 canoTemplate = "/bottles" 1504 }) 1505 1506 It("writes the href method", func() { 1507 err := writer.Execute(data) 1508 Ω(err).ShouldNot(HaveOccurred()) 1509 b, err := ioutil.ReadFile(filename) 1510 Ω(err).ShouldNot(HaveOccurred()) 1511 written := string(b) 1512 Ω(written).ShouldNot(BeEmpty()) 1513 Ω(written).Should(ContainSubstring(noParamHref)) 1514 }) 1515 }) 1516 }) 1517 }) 1518 }) 1519 }) 1520 1521 var _ = Describe("UserTypesWriter", func() { 1522 var writer *genapp.UserTypesWriter 1523 var workspace *codegen.Workspace 1524 var filename string 1525 1526 BeforeEach(func() { 1527 var err error 1528 workspace, err = codegen.NewWorkspace("test") 1529 Ω(err).ShouldNot(HaveOccurred()) 1530 pkg, err := workspace.NewPackage("controllers") 1531 Ω(err).ShouldNot(HaveOccurred()) 1532 src, err := pkg.CreateSourceFile("test.go") 1533 Ω(err).ShouldNot(HaveOccurred()) 1534 defer src.Close() 1535 filename = src.Abs() 1536 }) 1537 1538 JustBeforeEach(func() { 1539 var err error 1540 writer, err = genapp.NewUserTypesWriter(filename) 1541 Ω(err).ShouldNot(HaveOccurred()) 1542 }) 1543 1544 AfterEach(func() { 1545 workspace.Delete() 1546 }) 1547 1548 Context("correctly configured", func() { 1549 Context("with data", func() { 1550 var data *design.UserTypeDefinition 1551 var attDef *design.AttributeDefinition 1552 var typeName string 1553 1554 BeforeEach(func() { 1555 data = nil 1556 attDef = nil 1557 typeName = "" 1558 }) 1559 1560 JustBeforeEach(func() { 1561 data = &design.UserTypeDefinition{ 1562 AttributeDefinition: attDef, 1563 TypeName: typeName, 1564 } 1565 }) 1566 1567 Context("with a simple user type", func() { 1568 BeforeEach(func() { 1569 attDef = &design.AttributeDefinition{ 1570 Type: design.Object{ 1571 "name": &design.AttributeDefinition{ 1572 Type: design.String, 1573 }, 1574 }, 1575 } 1576 typeName = "SimplePayload" 1577 }) 1578 It("writes the simple user type code", func() { 1579 err := writer.Execute(data) 1580 Ω(err).ShouldNot(HaveOccurred()) 1581 b, err := ioutil.ReadFile(filename) 1582 Ω(err).ShouldNot(HaveOccurred()) 1583 written := string(b) 1584 Ω(written).ShouldNot(BeEmpty()) 1585 Ω(written).Should(ContainSubstring(simpleUserType)) 1586 }) 1587 }) 1588 1589 Context("with a user type including hash", func() { 1590 BeforeEach(func() { 1591 attDef = &design.AttributeDefinition{ 1592 Type: design.Object{ 1593 "name": &design.AttributeDefinition{ 1594 Type: design.String, 1595 }, 1596 "misc": &design.AttributeDefinition{ 1597 Type: &design.Hash{ 1598 KeyType: &design.AttributeDefinition{ 1599 Type: design.Integer, 1600 }, 1601 ElemType: &design.AttributeDefinition{ 1602 Type: &design.UserTypeDefinition{ 1603 AttributeDefinition: &design.AttributeDefinition{ 1604 Type: &design.UserTypeDefinition{ 1605 AttributeDefinition: &design.AttributeDefinition{ 1606 Type: design.Object{}, 1607 }, 1608 TypeName: "Misc", 1609 }, 1610 }, 1611 TypeName: "MiscPayload", 1612 }, 1613 }, 1614 }, 1615 }, 1616 }, 1617 } 1618 typeName = "ComplexPayload" 1619 }) 1620 It("writes the user type including hash", func() { 1621 err := writer.Execute(data) 1622 Ω(err).ShouldNot(HaveOccurred()) 1623 b, err := ioutil.ReadFile(filename) 1624 Ω(err).ShouldNot(HaveOccurred()) 1625 written := string(b) 1626 Ω(written).ShouldNot(BeEmpty()) 1627 Ω(written).Should(ContainSubstring(userTypeIncludingHash)) 1628 }) 1629 }) 1630 }) 1631 }) 1632 }) 1633 1634 const ( 1635 emptyContext = ` 1636 type ListBottleContext struct { 1637 context.Context 1638 *goa.ResponseData 1639 *goa.RequestData 1640 } 1641 ` 1642 1643 emptyContextFactory = ` 1644 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1645 var err error 1646 resp := goa.ContextResponse(ctx) 1647 resp.Service = service 1648 req := goa.ContextRequest(ctx) 1649 req.Request = r 1650 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1651 return &rctx, err 1652 } 1653 ` 1654 1655 intContext = ` 1656 type ListBottleContext struct { 1657 context.Context 1658 *goa.ResponseData 1659 *goa.RequestData 1660 Param *int 1661 } 1662 ` 1663 1664 intContextFactory = ` 1665 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1666 var err error 1667 resp := goa.ContextResponse(ctx) 1668 resp.Service = service 1669 req := goa.ContextRequest(ctx) 1670 req.Request = r 1671 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1672 paramParam := req.Params["param"] 1673 if len(paramParam) > 0 { 1674 rawParam := paramParam[0] 1675 if param, err2 := strconv.Atoi(rawParam); err2 == nil { 1676 tmp2 := param 1677 tmp1 := &tmp2 1678 rctx.Param = tmp1 1679 } else { 1680 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer")) 1681 } 1682 } 1683 return &rctx, err 1684 } 1685 ` 1686 1687 intDefaultContext = ` 1688 type ListBottleContext struct { 1689 context.Context 1690 *goa.ResponseData 1691 *goa.RequestData 1692 Param int 1693 } 1694 ` 1695 1696 intDefaultContextFactory = ` 1697 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1698 var err error 1699 resp := goa.ContextResponse(ctx) 1700 resp.Service = service 1701 req := goa.ContextRequest(ctx) 1702 req.Request = r 1703 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1704 paramParam := req.Params["param"] 1705 if len(paramParam) == 0 { 1706 rctx.Param = 2 1707 } else { 1708 rawParam := paramParam[0] 1709 if param, err2 := strconv.Atoi(rawParam); err2 == nil { 1710 rctx.Param = param 1711 } else { 1712 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer")) 1713 } 1714 } 1715 return &rctx, err 1716 } 1717 ` 1718 1719 intRequiredDefaultContext = ` 1720 type ListBottleContext struct { 1721 context.Context 1722 *goa.ResponseData 1723 *goa.RequestData 1724 Param int 1725 } 1726 ` 1727 1728 intRequiredDefaultContextFactory = ` 1729 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1730 var err error 1731 resp := goa.ContextResponse(ctx) 1732 resp.Service = service 1733 req := goa.ContextRequest(ctx) 1734 req.Request = r 1735 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1736 paramParam := req.Params["param"] 1737 if len(paramParam) == 0 { 1738 rctx.Param = 2 1739 } else { 1740 rawParam := paramParam[0] 1741 if param, err2 := strconv.Atoi(rawParam); err2 == nil { 1742 rctx.Param = param 1743 } else { 1744 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer")) 1745 } 1746 } 1747 return &rctx, err 1748 } 1749 ` 1750 1751 intRequiredContext = ` 1752 type ListBottleContext struct { 1753 context.Context 1754 *goa.ResponseData 1755 *goa.RequestData 1756 Param int 1757 } 1758 ` 1759 intRequiredContextFactory = ` 1760 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1761 var err error 1762 resp := goa.ContextResponse(ctx) 1763 resp.Service = service 1764 req := goa.ContextRequest(ctx) 1765 req.Request = r 1766 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1767 paramParam := req.Params["param"] 1768 if len(paramParam) == 0 { 1769 err = goa.MergeErrors(err, goa.MissingParamError("param")) 1770 } else { 1771 rawParam := paramParam[0] 1772 if param, err2 := strconv.Atoi(rawParam); err2 == nil { 1773 rctx.Param = param 1774 } else { 1775 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer")) 1776 } 1777 } 1778 return &rctx, err 1779 } 1780 ` 1781 1782 strContext = ` 1783 type ListBottleContext struct { 1784 context.Context 1785 *goa.ResponseData 1786 *goa.RequestData 1787 Param *string 1788 } 1789 ` 1790 1791 strContextFactory = ` 1792 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1793 var err error 1794 resp := goa.ContextResponse(ctx) 1795 resp.Service = service 1796 req := goa.ContextRequest(ctx) 1797 req.Request = r 1798 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1799 paramParam := req.Params["param"] 1800 if len(paramParam) > 0 { 1801 rawParam := paramParam[0] 1802 rctx.Param = &rawParam 1803 } 1804 return &rctx, err 1805 } 1806 ` 1807 1808 strNonOptionalContext = ` 1809 type ListBottleContext struct { 1810 context.Context 1811 *goa.ResponseData 1812 *goa.RequestData 1813 Param string 1814 } 1815 ` 1816 1817 strDefaultContextFactory = ` 1818 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1819 var err error 1820 resp := goa.ContextResponse(ctx) 1821 resp.Service = service 1822 req := goa.ContextRequest(ctx) 1823 req.Request = r 1824 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1825 paramParam := req.Params["param"] 1826 if len(paramParam) == 0 { 1827 rctx.Param = "foo" 1828 } else { 1829 rawParam := paramParam[0] 1830 rctx.Param = rawParam 1831 } 1832 return &rctx, err 1833 } 1834 ` 1835 1836 strRequiredContextFactory = ` 1837 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1838 var err error 1839 resp := goa.ContextResponse(ctx) 1840 resp.Service = service 1841 req := goa.ContextRequest(ctx) 1842 req.Request = r 1843 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1844 paramParam := req.Params["param"] 1845 if len(paramParam) == 0 { 1846 err = goa.MergeErrors(err, goa.MissingParamError("param")) 1847 } else { 1848 rawParam := paramParam[0] 1849 rctx.Param = rawParam 1850 } 1851 return &rctx, err 1852 } 1853 ` 1854 1855 strHeaderContext = ` 1856 type ListBottleContext struct { 1857 context.Context 1858 *goa.ResponseData 1859 *goa.RequestData 1860 Header *string 1861 } 1862 ` 1863 1864 strHeaderContextFactory = ` 1865 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1866 var err error 1867 resp := goa.ContextResponse(ctx) 1868 resp.Service = service 1869 req := goa.ContextRequest(ctx) 1870 req.Request = r 1871 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1872 headerHeader := req.Header["Header"] 1873 if len(headerHeader) > 0 { 1874 rawHeader := headerHeader[0] 1875 req.Params["Header"] = []string{rawHeader} 1876 rctx.Header = &rawHeader 1877 } 1878 return &rctx, err 1879 } 1880 ` 1881 1882 strHeaderParamContextFactory = ` 1883 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1884 var err error 1885 resp := goa.ContextResponse(ctx) 1886 resp.Service = service 1887 req := goa.ContextRequest(ctx) 1888 req.Request = r 1889 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1890 headerParam := req.Header["Param"] 1891 if len(headerParam) > 0 { 1892 rawParam := headerParam[0] 1893 req.Params["param"] = []string{rawParam} 1894 rctx.Param = &rawParam 1895 } 1896 paramParam := req.Params["param"] 1897 if len(paramParam) > 0 { 1898 rawParam := paramParam[0] 1899 rctx.Param = &rawParam 1900 } 1901 return &rctx, err 1902 } 1903 ` 1904 1905 numContext = ` 1906 type ListBottleContext struct { 1907 context.Context 1908 *goa.ResponseData 1909 *goa.RequestData 1910 Param *float64 1911 } 1912 ` 1913 1914 numContextFactory = ` 1915 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1916 var err error 1917 resp := goa.ContextResponse(ctx) 1918 resp.Service = service 1919 req := goa.ContextRequest(ctx) 1920 req.Request = r 1921 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1922 paramParam := req.Params["param"] 1923 if len(paramParam) > 0 { 1924 rawParam := paramParam[0] 1925 if param, err2 := strconv.ParseFloat(rawParam, 64); err2 == nil { 1926 tmp1 := ¶m 1927 rctx.Param = tmp1 1928 } else { 1929 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "number")) 1930 } 1931 } 1932 return &rctx, err 1933 } 1934 ` 1935 1936 numNonOptionalContext = ` 1937 type ListBottleContext struct { 1938 context.Context 1939 *goa.ResponseData 1940 *goa.RequestData 1941 Param float64 1942 } 1943 ` 1944 1945 numDefaultContextFactory = ` 1946 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1947 var err error 1948 resp := goa.ContextResponse(ctx) 1949 resp.Service = service 1950 req := goa.ContextRequest(ctx) 1951 req.Request = r 1952 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1953 paramParam := req.Params["param"] 1954 if len(paramParam) == 0 { 1955 rctx.Param = 2.300000 1956 } else { 1957 rawParam := paramParam[0] 1958 if param, err2 := strconv.ParseFloat(rawParam, 64); err2 == nil { 1959 rctx.Param = param 1960 } else { 1961 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "number")) 1962 } 1963 } 1964 return &rctx, err 1965 } 1966 ` 1967 1968 numRequiredContextFactory = ` 1969 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 1970 var err error 1971 resp := goa.ContextResponse(ctx) 1972 resp.Service = service 1973 req := goa.ContextRequest(ctx) 1974 req.Request = r 1975 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 1976 paramParam := req.Params["param"] 1977 if len(paramParam) == 0 { 1978 err = goa.MergeErrors(err, goa.MissingParamError("param")) 1979 } else { 1980 rawParam := paramParam[0] 1981 if param, err2 := strconv.ParseFloat(rawParam, 64); err2 == nil { 1982 rctx.Param = param 1983 } else { 1984 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "number")) 1985 } 1986 } 1987 return &rctx, err 1988 } 1989 ` 1990 1991 boolContext = ` 1992 type ListBottleContext struct { 1993 context.Context 1994 *goa.ResponseData 1995 *goa.RequestData 1996 Param *bool 1997 } 1998 ` 1999 2000 boolContextFactory = ` 2001 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2002 var err error 2003 resp := goa.ContextResponse(ctx) 2004 resp.Service = service 2005 req := goa.ContextRequest(ctx) 2006 req.Request = r 2007 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2008 paramParam := req.Params["param"] 2009 if len(paramParam) > 0 { 2010 rawParam := paramParam[0] 2011 if param, err2 := strconv.ParseBool(rawParam); err2 == nil { 2012 tmp1 := ¶m 2013 rctx.Param = tmp1 2014 } else { 2015 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "boolean")) 2016 } 2017 } 2018 return &rctx, err 2019 } 2020 ` 2021 2022 boolNonOptionalContext = ` 2023 type ListBottleContext struct { 2024 context.Context 2025 *goa.ResponseData 2026 *goa.RequestData 2027 Param bool 2028 } 2029 ` 2030 2031 boolDefaultContextFactory = ` 2032 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2033 var err error 2034 resp := goa.ContextResponse(ctx) 2035 resp.Service = service 2036 req := goa.ContextRequest(ctx) 2037 req.Request = r 2038 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2039 paramParam := req.Params["param"] 2040 if len(paramParam) == 0 { 2041 rctx.Param = true 2042 } else { 2043 rawParam := paramParam[0] 2044 if param, err2 := strconv.ParseBool(rawParam); err2 == nil { 2045 rctx.Param = param 2046 } else { 2047 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "boolean")) 2048 } 2049 } 2050 return &rctx, err 2051 } 2052 ` 2053 2054 boolRequiredContextFactory = ` 2055 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2056 var err error 2057 resp := goa.ContextResponse(ctx) 2058 resp.Service = service 2059 req := goa.ContextRequest(ctx) 2060 req.Request = r 2061 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2062 paramParam := req.Params["param"] 2063 if len(paramParam) == 0 { 2064 err = goa.MergeErrors(err, goa.MissingParamError("param")) 2065 } else { 2066 rawParam := paramParam[0] 2067 if param, err2 := strconv.ParseBool(rawParam); err2 == nil { 2068 rctx.Param = param 2069 } else { 2070 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "boolean")) 2071 } 2072 } 2073 return &rctx, err 2074 } 2075 ` 2076 2077 arrayContext = ` 2078 type ListBottleContext struct { 2079 context.Context 2080 *goa.ResponseData 2081 *goa.RequestData 2082 Param []string 2083 } 2084 ` 2085 2086 arrayContextFactory = ` 2087 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2088 var err error 2089 resp := goa.ContextResponse(ctx) 2090 resp.Service = service 2091 req := goa.ContextRequest(ctx) 2092 req.Request = r 2093 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2094 paramParam := req.Params["param"] 2095 if len(paramParam) > 0 { 2096 params := paramParam 2097 rctx.Param = params 2098 } 2099 return &rctx, err 2100 } 2101 ` 2102 2103 arrayParamContextFactory = ` 2104 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2105 var err error 2106 resp := goa.ContextResponse(ctx) 2107 resp.Service = service 2108 req := goa.ContextRequest(ctx) 2109 req.Request = r 2110 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2111 paramParam := req.Params["param"] 2112 if len(paramParam) > 0 { 2113 params := paramParam 2114 rctx.Param = params 2115 } 2116 return &rctx, err 2117 } 2118 ` 2119 2120 arrayDefaultContextFactory = ` 2121 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2122 var err error 2123 resp := goa.ContextResponse(ctx) 2124 resp.Service = service 2125 req := goa.ContextRequest(ctx) 2126 req.Request = r 2127 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2128 paramParam := req.Params["param"] 2129 if len(paramParam) == 0 { 2130 rctx.Param = []string{"foo", "bar", "baz"} 2131 } else { 2132 params := paramParam 2133 rctx.Param = params 2134 } 2135 return &rctx, err 2136 } 2137 ` 2138 2139 arrayRequiredContextFactory = ` 2140 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2141 var err error 2142 resp := goa.ContextResponse(ctx) 2143 resp.Service = service 2144 req := goa.ContextRequest(ctx) 2145 req.Request = r 2146 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2147 paramParam := req.Params["param"] 2148 if len(paramParam) == 0 { 2149 err = goa.MergeErrors(err, goa.MissingParamError("param")) 2150 } else { 2151 params := paramParam 2152 rctx.Param = params 2153 } 2154 return &rctx, err 2155 } 2156 ` 2157 2158 intArrayContext = ` 2159 type ListBottleContext struct { 2160 context.Context 2161 *goa.ResponseData 2162 *goa.RequestData 2163 Param []int 2164 } 2165 ` 2166 2167 intArrayContextFactory = ` 2168 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2169 var err error 2170 resp := goa.ContextResponse(ctx) 2171 resp.Service = service 2172 req := goa.ContextRequest(ctx) 2173 req.Request = r 2174 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2175 paramParam := req.Params["param"] 2176 if len(paramParam) > 0 { 2177 params := make([]int, len(paramParam)) 2178 for i, rawParam := range paramParam { 2179 if param, err2 := strconv.Atoi(rawParam); err2 == nil { 2180 params[i] = param 2181 } else { 2182 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer")) 2183 } 2184 } 2185 rctx.Param = params 2186 } 2187 return &rctx, err 2188 } 2189 ` 2190 2191 intArrayDefaultContextFactory = ` 2192 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2193 var err error 2194 resp := goa.ContextResponse(ctx) 2195 resp.Service = service 2196 req := goa.ContextRequest(ctx) 2197 req.Request = r 2198 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2199 paramParam := req.Params["param"] 2200 if len(paramParam) == 0 { 2201 rctx.Param = []int{1, 1, 2, 3, 5, 8} 2202 } else { 2203 params := make([]int, len(paramParam)) 2204 for i, rawParam := range paramParam { 2205 if param, err2 := strconv.Atoi(rawParam); err2 == nil { 2206 params[i] = param 2207 } else { 2208 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer")) 2209 } 2210 } 2211 rctx.Param = params 2212 } 2213 return &rctx, err 2214 } 2215 ` 2216 2217 intArrayRequiredContextFactory = ` 2218 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2219 var err error 2220 resp := goa.ContextResponse(ctx) 2221 resp.Service = service 2222 req := goa.ContextRequest(ctx) 2223 req.Request = r 2224 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2225 paramParam := req.Params["param"] 2226 if len(paramParam) == 0 { 2227 err = goa.MergeErrors(err, goa.MissingParamError("param")) 2228 } else { 2229 params := make([]int, len(paramParam)) 2230 for i, rawParam := range paramParam { 2231 if param, err2 := strconv.Atoi(rawParam); err2 == nil { 2232 params[i] = param 2233 } else { 2234 err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer")) 2235 } 2236 } 2237 rctx.Param = params 2238 } 2239 return &rctx, err 2240 } 2241 ` 2242 2243 resContext = ` 2244 type ListBottleContext struct { 2245 context.Context 2246 *goa.ResponseData 2247 *goa.RequestData 2248 Int *int 2249 } 2250 ` 2251 2252 resContextFactory = ` 2253 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2254 var err error 2255 resp := goa.ContextResponse(ctx) 2256 resp.Service = service 2257 req := goa.ContextRequest(ctx) 2258 req.Request = r 2259 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2260 paramInt := req.Params["int"] 2261 if len(paramInt) > 0 { 2262 rawInt := paramInt[0] 2263 if int_, err2 := strconv.Atoi(rawInt); err2 == nil { 2264 tmp2 := int_ 2265 tmp1 := &tmp2 2266 rctx.Int = tmp1 2267 } else { 2268 err = goa.MergeErrors(err, goa.InvalidParamTypeError("int", rawInt, "integer")) 2269 } 2270 } 2271 return &rctx, err 2272 } 2273 ` 2274 2275 requiredContext = ` 2276 type ListBottleContext struct { 2277 context.Context 2278 *goa.ResponseData 2279 *goa.RequestData 2280 Int int 2281 } 2282 ` 2283 2284 requiredContextFactory = ` 2285 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2286 var err error 2287 resp := goa.ContextResponse(ctx) 2288 resp.Service = service 2289 req := goa.ContextRequest(ctx) 2290 req.Request = r 2291 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2292 paramInt := req.Params["int"] 2293 if len(paramInt) == 0 { 2294 err = goa.MergeErrors(err, goa.MissingParamError("int")) 2295 } else { 2296 rawInt := paramInt[0] 2297 if int_, err2 := strconv.Atoi(rawInt); err2 == nil { 2298 rctx.Int = int_ 2299 } else { 2300 err = goa.MergeErrors(err, goa.InvalidParamTypeError("int", rawInt, "integer")) 2301 } 2302 } 2303 return &rctx, err 2304 } 2305 ` 2306 2307 customContext = ` 2308 type ListBottleContext struct { 2309 context.Context 2310 *goa.ResponseData 2311 *goa.RequestData 2312 Custom *int 2313 } 2314 ` 2315 2316 customContextFactory = ` 2317 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2318 var err error 2319 resp := goa.ContextResponse(ctx) 2320 resp.Service = service 2321 req := goa.ContextRequest(ctx) 2322 req.Request = r 2323 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2324 paramInt := req.Params["int"] 2325 if len(paramInt) > 0 { 2326 rawInt := paramInt[0] 2327 if int_, err2 := strconv.Atoi(rawInt); err2 == nil { 2328 tmp2 := int_ 2329 tmp1 := &tmp2 2330 rctx.Custom = tmp1 2331 } else { 2332 err = goa.MergeErrors(err, goa.InvalidParamTypeError("int", rawInt, "integer")) 2333 } 2334 } 2335 return &rctx, err 2336 } 2337 ` 2338 2339 payloadContext = ` 2340 type ListBottleContext struct { 2341 context.Context 2342 *goa.ResponseData 2343 *goa.RequestData 2344 Payload ListBottlePayload 2345 } 2346 ` 2347 2348 payloadContextFactory = ` 2349 func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) { 2350 var err error 2351 resp := goa.ContextResponse(ctx) 2352 resp.Service = service 2353 req := goa.ContextRequest(ctx) 2354 req.Request = r 2355 rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req} 2356 return &rctx, err 2357 } 2358 ` 2359 payloadObjContext = ` 2360 type ListBottleContext struct { 2361 context.Context 2362 *goa.ResponseData 2363 *goa.RequestData 2364 Payload *ListBottlePayload 2365 } 2366 ` 2367 2368 payloadObjUnmarshal = ` 2369 func unmarshalListBottlePayload(ctx context.Context, service *goa.Service, req *http.Request) error { 2370 payload := &listBottlePayload{} 2371 if err := service.DecodeRequest(req, payload); err != nil { 2372 return err 2373 } 2374 if err := payload.Validate(); err != nil { 2375 // Initialize payload with private data structure so it can be logged 2376 goa.ContextRequest(ctx).Payload = payload 2377 return err 2378 } 2379 goa.ContextRequest(ctx).Payload = payload.Publicize() 2380 return nil 2381 } 2382 ` 2383 2384 payloadMultipartObjUnmarshalID = ` 2385 rawID := req.FormValue("id") 2386 if id, err2 := strconv.Atoi(rawID); err2 == nil { 2387 tmp2 := id 2388 tmp1 := &tmp2 2389 payload.ID = tmp1 2390 } else { 2391 err = goa.MergeErrors(err, goa.InvalidParamTypeError("id", rawID, "integer")) 2392 }` 2393 2394 payloadMultipartObjUnmarshalTitle = ` 2395 rawTitle := req.FormValue("title") 2396 payload.Title = &rawTitle` 2397 2398 payloadMultipartObjUnmarshalIcon = ` 2399 _, rawIcon, err2 := req.FormFile("icon") 2400 if err2 == nil { 2401 payload.Icon = rawIcon 2402 } else { 2403 err = goa.MergeErrors(err, goa.InvalidParamTypeError("icon", "icon", "file")) 2404 }` 2405 2406 payloadMultipartObjUnmarshalCommentLines = ` 2407 rawCommentLines := req.Form["commentLines[]"] 2408 tmpCommentLines := make([]string, len(rawCommentLines)) 2409 for i := 0; i < len(rawCommentLines); i++ { 2410 tmp := rawCommentLines[i] 2411 tmpCommentLines[i] = tmp 2412 } 2413 payload.CommentLines = tmpCommentLines` 2414 2415 payloadMultipartObjUnmarshalFlags = ` 2416 rawFlags := req.Form["flags[]"] 2417 tmpFlags := make([]bool, len(rawFlags)) 2418 for i := 0; i < len(rawFlags); i++ { 2419 tmp, err2 := strconv.ParseBool(rawFlags[i]) 2420 if err2 != nil { 2421 err = goa.MergeErrors(err, goa.InvalidParamTypeError("flags", rawFlags, "[]bool")) 2422 break 2423 } 2424 tmpFlags[i] = tmp 2425 } 2426 payload.Flags = tmpFlags` 2427 2428 payloadMultipartObjUnmarshalOptionCodes = ` 2429 rawOptionCodes := req.Form["optionCodes[]"] 2430 tmpOptionCodes := make([]int, len(rawOptionCodes)) 2431 for i := 0; i < len(rawOptionCodes); i++ { 2432 tmp, err2 := strconv.Atoi(rawOptionCodes[i]) 2433 if err2 != nil { 2434 err = goa.MergeErrors(err, goa.InvalidParamTypeError("optionCodes", rawOptionCodes, "[]int")) 2435 break 2436 } 2437 tmpOptionCodes[i] = tmp 2438 } 2439 payload.OptionCodes = tmpOptionCodes` 2440 2441 payloadMultipartObjUnmarshalRatios = ` 2442 rawRatios := req.Form["ratios[]"] 2443 tmpRatios := make([]float, len(rawRatios)) 2444 for i := 0; i < len(rawRatios); i++ { 2445 tmp, err2 := strconv.ParseFloat(rawRatios[i]) 2446 if err2 != nil { 2447 err = goa.MergeErrors(err, goa.InvalidParamTypeError("ratios", rawRatios, "[]float")) 2448 break 2449 } 2450 tmpRatios[i] = tmp 2451 } 2452 payload.Ratios = tmpRatios` 2453 2454 payloadMultipartObjUnmarshalObjs = ` 2455 rawObjs := req.Form["objs[]"] 2456 tmpObjs := make([]interface{}, len(rawObjs)) 2457 for i := 0; i < len(rawObjs); i++ { 2458 tmp, err2 := (interface{})(nil), (error)(nil) 2459 if err2 != nil { 2460 err = goa.MergeErrors(err, goa.InvalidParamTypeError("objs", rawObjs, "[]interface{}")) 2461 break 2462 } 2463 tmpObjs[i] = tmp 2464 } 2465 payload.Objs = tmpObjs` 2466 2467 payloadMultipartObjUnmarshalHashObjs = ` 2468 rawHashObjs := req.Form["hashObjs[]"] 2469 tmpHashObjs := make([]map[string][]string, len(rawHashObjs)) 2470 for i := 0; i < len(rawHashObjs); i++ { 2471 tmp, err2 := map[string][]string{}, (error)(nil) 2472 if err2 != nil { 2473 err = goa.MergeErrors(err, goa.InvalidParamTypeError("hashObjs", rawHashObjs, "[]map[string][]string")) 2474 break 2475 } 2476 tmpHashObjs[i] = tmp 2477 } 2478 payload.HashObjs = tmpHashObjs` 2479 2480 payloadNoValidationsObjUnmarshal = ` 2481 func unmarshalListBottlePayload(ctx context.Context, service *goa.Service, req *http.Request) error { 2482 payload := &listBottlePayload{} 2483 if err := service.DecodeRequest(req, payload); err != nil { 2484 return err 2485 } 2486 goa.ContextRequest(ctx).Payload = payload.Publicize() 2487 return nil 2488 } 2489 ` 2490 2491 simpleFileServer = `// PublicController is the controller interface for the Public actions. 2492 type PublicController interface { 2493 goa.Muxer 2494 goa.FileServer 2495 } 2496 ` 2497 2498 fileServerOptionsHandler = `service.Mux.Handle("OPTIONS", "/public/star\\*star/*filepath", ctrl.MuxHandler("preflight", handlePublicOrigin(cors.HandlePreflight()), nil))` 2499 2500 simpleController = `// BottlesController is the controller interface for the Bottles actions. 2501 type BottlesController interface { 2502 goa.Muxer 2503 List(*ListBottleContext) error 2504 } 2505 ` 2506 2507 originsIntegration = `} 2508 h = handleBottlesOrigin(h) 2509 service.Mux.Handle` 2510 2511 originsHandler = `// handleBottlesOrigin applies the CORS response headers corresponding to the origin. 2512 func handleBottlesOrigin(h goa.Handler) goa.Handler { 2513 2514 return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { 2515 origin := req.Header.Get("Origin") 2516 if origin == "" { 2517 // Not a CORS request 2518 return h(ctx, rw, req) 2519 } 2520 if cors.MatchOrigin(origin, "here.example.com") { 2521 ctx = goa.WithLogContext(ctx, "origin", origin) 2522 rw.Header().Set("Access-Control-Allow-Origin", origin) 2523 rw.Header().Set("Vary", "Origin") 2524 rw.Header().Set("Access-Control-Expose-Headers", "X-Three") 2525 rw.Header().Set("Access-Control-Allow-Credentials", "true") 2526 if acrm := req.Header.Get("Access-Control-Request-Method"); acrm != "" { 2527 // We are handling a preflight request 2528 rw.Header().Set("Access-Control-Allow-Methods", "GET, POST") 2529 rw.Header().Set("Access-Control-Allow-Headers", "X-One, X-Two") 2530 } 2531 return h(ctx, rw, req) 2532 } 2533 if cors.MatchOrigin(origin, "there.example.com") { 2534 ctx = goa.WithLogContext(ctx, "origin", origin) 2535 rw.Header().Set("Access-Control-Allow-Origin", origin) 2536 rw.Header().Set("Vary", "Origin") 2537 rw.Header().Set("Access-Control-Allow-Credentials", "false") 2538 if acrm := req.Header.Get("Access-Control-Request-Method"); acrm != "" { 2539 // We are handling a preflight request 2540 rw.Header().Set("Access-Control-Allow-Methods", "*") 2541 rw.Header().Set("Access-Control-Allow-Headers", "*") 2542 } 2543 return h(ctx, rw, req) 2544 } 2545 2546 return h(ctx, rw, req) 2547 } 2548 } 2549 ` 2550 2551 regexpOriginsHandler = `// handleBottlesOrigin applies the CORS response headers corresponding to the origin. 2552 func handleBottlesOrigin(h goa.Handler) goa.Handler { 2553 spec0 := regexp.MustCompile("[here|there].example.com") 2554 2555 return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { 2556 origin := req.Header.Get("Origin") 2557 if origin == "" { 2558 // Not a CORS request 2559 return h(ctx, rw, req) 2560 } 2561 if cors.MatchOriginRegexp(origin, spec0) { 2562 ctx = goa.WithLogContext(ctx, "origin", origin) 2563 rw.Header().Set("Access-Control-Allow-Origin", origin) 2564 rw.Header().Set("Vary", "Origin") 2565 rw.Header().Set("Access-Control-Expose-Headers", "X-Three") 2566 rw.Header().Set("Access-Control-Allow-Credentials", "true") 2567 if acrm := req.Header.Get("Access-Control-Request-Method"); acrm != "" { 2568 // We are handling a preflight request 2569 rw.Header().Set("Access-Control-Allow-Methods", "GET, POST") 2570 rw.Header().Set("Access-Control-Allow-Headers", "X-One, X-Two") 2571 } 2572 return h(ctx, rw, req) 2573 } 2574 if cors.MatchOrigin(origin, "there.example.com") { 2575 ctx = goa.WithLogContext(ctx, "origin", origin) 2576 rw.Header().Set("Access-Control-Allow-Origin", origin) 2577 rw.Header().Set("Vary", "Origin") 2578 rw.Header().Set("Access-Control-Allow-Credentials", "false") 2579 if acrm := req.Header.Get("Access-Control-Request-Method"); acrm != "" { 2580 // We are handling a preflight request 2581 rw.Header().Set("Access-Control-Allow-Methods", "*") 2582 rw.Header().Set("Access-Control-Allow-Headers", "*") 2583 } 2584 return h(ctx, rw, req) 2585 } 2586 2587 return h(ctx, rw, req) 2588 } 2589 } 2590 ` 2591 2592 encoderController = ` 2593 // MountBottlesController "mounts" a Bottles resource controller on the given service. 2594 func MountBottlesController(service *goa.Service, ctrl BottlesController) { 2595 initService(service) 2596 var h goa.Handler 2597 2598 h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { 2599 // Check if there was an error loading the request 2600 if err := goa.ContextError(ctx); err != nil { 2601 return err 2602 } 2603 // Build the context 2604 rctx, err := NewListBottleContext(ctx, req, service) 2605 if err != nil { 2606 return err 2607 } 2608 return ctrl.List(rctx) 2609 } 2610 service.Mux.Handle("GET", "/accounts/:accountID/bottles", ctrl.MuxHandler("list", h, nil)) 2611 service.LogInfo("mount", "ctrl", "Bottles", "action", "List", "route", "GET /accounts/:accountID/bottles") 2612 } 2613 ` 2614 2615 simpleMount = `func MountBottlesController(service *goa.Service, ctrl BottlesController) { 2616 initService(service) 2617 var h goa.Handler 2618 2619 h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { 2620 // Check if there was an error loading the request 2621 if err := goa.ContextError(ctx); err != nil { 2622 return err 2623 } 2624 // Build the context 2625 rctx, err := NewListBottleContext(ctx, req, service) 2626 if err != nil { 2627 return err 2628 } 2629 return ctrl.List(rctx) 2630 } 2631 service.Mux.Handle("GET", "/accounts/:accountID/bottles", ctrl.MuxHandler("list", h, nil)) 2632 service.LogInfo("mount", "ctrl", "Bottles", "action", "List", "route", "GET /accounts/:accountID/bottles") 2633 } 2634 ` 2635 2636 multiController = `// BottlesController is the controller interface for the Bottles actions. 2637 type BottlesController interface { 2638 goa.Muxer 2639 List(*ListBottleContext) error 2640 Show(*ShowBottleContext) error 2641 } 2642 ` 2643 2644 multiMount = `func MountBottlesController(service *goa.Service, ctrl BottlesController) { 2645 initService(service) 2646 var h goa.Handler 2647 2648 h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { 2649 // Check if there was an error loading the request 2650 if err := goa.ContextError(ctx); err != nil { 2651 return err 2652 } 2653 // Build the context 2654 rctx, err := NewListBottleContext(ctx, req, service) 2655 if err != nil { 2656 return err 2657 } 2658 return ctrl.List(rctx) 2659 } 2660 service.Mux.Handle("GET", "/accounts/:accountID/bottles", ctrl.MuxHandler("list", h, nil)) 2661 service.LogInfo("mount", "ctrl", "Bottles", "action", "List", "route", "GET /accounts/:accountID/bottles") 2662 2663 h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error { 2664 // Check if there was an error loading the request 2665 if err := goa.ContextError(ctx); err != nil { 2666 return err 2667 } 2668 // Build the context 2669 rctx, err := NewShowBottleContext(ctx, req, service) 2670 if err != nil { 2671 return err 2672 } 2673 return ctrl.Show(rctx) 2674 } 2675 service.Mux.Handle("GET", "/accounts/:accountID/bottles/:id", ctrl.MuxHandler("show", h, nil)) 2676 service.LogInfo("mount", "ctrl", "Bottles", "action", "Show", "route", "GET /accounts/:accountID/bottles/:id") 2677 } 2678 ` 2679 2680 simpleResourceHref = `func BottleHref(id interface{}) string { 2681 paramid := strings.TrimLeftFunc(fmt.Sprintf("%v", id), func(r rune) bool { return r == '/' }) 2682 return fmt.Sprintf("/bottles/%v", paramid) 2683 } 2684 ` 2685 noParamHref = `func BottleHref() string { 2686 return "/bottles" 2687 } 2688 ` 2689 2690 simpleUserType = `// simplePayload user type. 2691 type simplePayload struct { 2692 Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" yaml:"name,omitempty" xml:"name,omitempty"` + "`" + ` 2693 } 2694 2695 2696 2697 // Publicize creates SimplePayload from simplePayload 2698 func (ut *simplePayload) Publicize() *SimplePayload { 2699 var pub SimplePayload 2700 if ut.Name != nil { 2701 pub.Name = ut.Name 2702 } 2703 return &pub 2704 } 2705 2706 // SimplePayload user type. 2707 type SimplePayload struct { 2708 Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" yaml:"name,omitempty" xml:"name,omitempty"` + "`" + ` 2709 } 2710 ` 2711 2712 userTypeIncludingHash = `// complexPayload user type. 2713 type complexPayload struct { 2714 Misc map[int]*miscPayload ` + "`" + `form:"misc,omitempty" json:"misc,omitempty" yaml:"misc,omitempty" xml:"misc,omitempty"` + "`" + ` 2715 Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" yaml:"name,omitempty" xml:"name,omitempty"` + "`" + ` 2716 } 2717 2718 2719 2720 // Publicize creates ComplexPayload from complexPayload 2721 func (ut *complexPayload) Publicize() *ComplexPayload { 2722 var pub ComplexPayload 2723 if ut.Misc != nil { 2724 pub.Misc = make(map[int]*MiscPayload, len(ut.Misc)) 2725 for k2, v2 := range ut.Misc { 2726 pubk2 := k2 2727 var pubv2 *MiscPayload 2728 if v2 != nil { 2729 pubv2 = v2.Publicize() 2730 } 2731 pub.Misc[pubk2] = pubv2 2732 } 2733 } 2734 if ut.Name != nil { 2735 pub.Name = ut.Name 2736 } 2737 return &pub 2738 } 2739 2740 // ComplexPayload user type. 2741 type ComplexPayload struct { 2742 Misc map[int]*MiscPayload ` + "`" + `form:"misc,omitempty" json:"misc,omitempty" yaml:"misc,omitempty" xml:"misc,omitempty"` + "`" + ` 2743 Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" yaml:"name,omitempty" xml:"name,omitempty"` + "`" + ` 2744 } 2745 ` 2746 )