github.com/blp1526/goa@v1.4.0/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  	"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.String,
  1173  									},
  1174  									"icon": &design.AttributeDefinition{
  1175  										Type: design.File,
  1176  									},
  1177  								},
  1178  								Validation: required,
  1179  							},
  1180  						},
  1181  					}
  1182  					multipart = true
  1183  				})
  1184  
  1185  				It("writes the payload unmarshal function", func() {
  1186  					err := writer.Execute(data)
  1187  					Ω(err).ShouldNot(HaveOccurred())
  1188  					b, err := ioutil.ReadFile(filename)
  1189  					Ω(err).ShouldNot(HaveOccurred())
  1190  					written := string(b)
  1191  					Ω(written).Should(ContainSubstring(payloadMultipartObjUnmarshal))
  1192  				})
  1193  			})
  1194  
  1195  			Context("with multiple controllers", func() {
  1196  				BeforeEach(func() {
  1197  					actions = []string{"list", "show"}
  1198  					verbs = []string{"GET", "GET"}
  1199  					paths = []string{"/accounts/:accountID/bottles", "/accounts/:accountID/bottles/:id"}
  1200  					contexts = []string{"ListBottleContext", "ShowBottleContext"}
  1201  				})
  1202  
  1203  				It("writes the controllers code", func() {
  1204  					err := writer.Execute(data)
  1205  					Ω(err).ShouldNot(HaveOccurred())
  1206  					b, err := ioutil.ReadFile(filename)
  1207  					Ω(err).ShouldNot(HaveOccurred())
  1208  					written := string(b)
  1209  					Ω(written).ShouldNot(BeEmpty())
  1210  					Ω(written).Should(ContainSubstring(multiController))
  1211  					Ω(written).Should(ContainSubstring(multiMount))
  1212  				})
  1213  			})
  1214  
  1215  			Context("with encoder and decoder maps", func() {
  1216  				BeforeEach(func() {
  1217  					actions = []string{"list"}
  1218  					verbs = []string{"GET"}
  1219  					paths = []string{"/accounts/:accountID/bottles"}
  1220  					contexts = []string{"ListBottleContext"}
  1221  					encoders = []*genapp.EncoderTemplateData{
  1222  						{
  1223  							PackageName: "goa",
  1224  							Function:    "NewEncoder",
  1225  							MIMETypes:   []string{"application/json"},
  1226  						},
  1227  					}
  1228  					decoders = []*genapp.EncoderTemplateData{
  1229  						{
  1230  							PackageName: "goa",
  1231  							Function:    "NewDecoder",
  1232  							MIMETypes:   []string{"application/json"},
  1233  						},
  1234  					}
  1235  				})
  1236  
  1237  				It("writes the controllers code", func() {
  1238  					err := writer.Execute(data)
  1239  					Ω(err).ShouldNot(HaveOccurred())
  1240  					b, err := ioutil.ReadFile(filename)
  1241  					Ω(err).ShouldNot(HaveOccurred())
  1242  					written := string(b)
  1243  					Ω(written).ShouldNot(BeEmpty())
  1244  					Ω(written).Should(ContainSubstring(encoderController))
  1245  				})
  1246  			})
  1247  
  1248  			Context("with multiple origins", func() {
  1249  				BeforeEach(func() {
  1250  					actions = []string{"list"}
  1251  					verbs = []string{"GET"}
  1252  					paths = []string{"/accounts"}
  1253  					contexts = []string{"ListBottleContext"}
  1254  					origins = []*design.CORSDefinition{
  1255  						{
  1256  							Origin:      "here.example.com",
  1257  							Headers:     []string{"X-One", "X-Two"},
  1258  							Methods:     []string{"GET", "POST"},
  1259  							Exposed:     []string{"X-Three"},
  1260  							Credentials: true,
  1261  						},
  1262  						{
  1263  							Origin:  "there.example.com",
  1264  							Headers: []string{"*"},
  1265  							Methods: []string{"*"},
  1266  						},
  1267  					}
  1268  
  1269  				})
  1270  
  1271  				It("writes the controller code", func() {
  1272  					err := writer.Execute(data)
  1273  					Ω(err).ShouldNot(HaveOccurred())
  1274  					b, err := ioutil.ReadFile(filename)
  1275  					Ω(err).ShouldNot(HaveOccurred())
  1276  					written := string(b)
  1277  					Ω(written).ShouldNot(BeEmpty())
  1278  					Ω(written).Should(ContainSubstring(originsIntegration))
  1279  					Ω(written).Should(ContainSubstring(originsHandler))
  1280  				})
  1281  			})
  1282  
  1283  			Context("with regexp origins", func() {
  1284  				BeforeEach(func() {
  1285  					actions = []string{"list"}
  1286  					verbs = []string{"GET"}
  1287  					paths = []string{"/accounts"}
  1288  					contexts = []string{"ListBottleContext"}
  1289  					origins = []*design.CORSDefinition{
  1290  						{
  1291  							Origin:      "[here|there].example.com",
  1292  							Headers:     []string{"X-One", "X-Two"},
  1293  							Methods:     []string{"GET", "POST"},
  1294  							Exposed:     []string{"X-Three"},
  1295  							Credentials: true,
  1296  							Regexp:      true,
  1297  						},
  1298  						{
  1299  							Origin:  "there.example.com",
  1300  							Headers: []string{"*"},
  1301  							Methods: []string{"*"},
  1302  						},
  1303  					}
  1304  
  1305  				})
  1306  
  1307  				It("writes the controller code", func() {
  1308  					err := writer.Execute(data)
  1309  					Ω(err).ShouldNot(HaveOccurred())
  1310  					b, err := ioutil.ReadFile(filename)
  1311  					Ω(err).ShouldNot(HaveOccurred())
  1312  					written := string(b)
  1313  					Ω(written).ShouldNot(BeEmpty())
  1314  					Ω(written).Should(ContainSubstring(originsIntegration))
  1315  					Ω(written).Should(ContainSubstring(regexpOriginsHandler))
  1316  				})
  1317  			})
  1318  
  1319  		})
  1320  	})
  1321  })
  1322  
  1323  var _ = Describe("HrefWriter", func() {
  1324  	var writer *genapp.ResourcesWriter
  1325  	var workspace *codegen.Workspace
  1326  	var filename string
  1327  
  1328  	BeforeEach(func() {
  1329  		var err error
  1330  		workspace, err = codegen.NewWorkspace("test")
  1331  		Ω(err).ShouldNot(HaveOccurred())
  1332  		pkg, err := workspace.NewPackage("controllers")
  1333  		Ω(err).ShouldNot(HaveOccurred())
  1334  		src, err := pkg.CreateSourceFile("test.go")
  1335  		Ω(err).ShouldNot(HaveOccurred())
  1336  		defer src.Close()
  1337  		filename = src.Abs()
  1338  	})
  1339  
  1340  	JustBeforeEach(func() {
  1341  		var err error
  1342  		writer, err = genapp.NewResourcesWriter(filename)
  1343  		Ω(err).ShouldNot(HaveOccurred())
  1344  	})
  1345  
  1346  	AfterEach(func() {
  1347  		workspace.Delete()
  1348  	})
  1349  
  1350  	Context("correctly configured", func() {
  1351  		Context("with data", func() {
  1352  			var canoTemplate string
  1353  			var canoParams []string
  1354  			var mediaType *design.MediaTypeDefinition
  1355  
  1356  			var data *genapp.ResourceData
  1357  
  1358  			BeforeEach(func() {
  1359  				mediaType = nil
  1360  				canoTemplate = ""
  1361  				canoParams = nil
  1362  				data = nil
  1363  			})
  1364  
  1365  			JustBeforeEach(func() {
  1366  				data = &genapp.ResourceData{
  1367  					Name:              "Bottle",
  1368  					Identifier:        "vnd.acme.com/resources",
  1369  					Description:       "A bottle resource",
  1370  					Type:              mediaType,
  1371  					CanonicalTemplate: canoTemplate,
  1372  					CanonicalParams:   canoParams,
  1373  				}
  1374  			})
  1375  
  1376  			Context("with missing resource type definition", func() {
  1377  				It("does not return an error", func() {
  1378  					err := writer.Execute(data)
  1379  					Ω(err).ShouldNot(HaveOccurred())
  1380  				})
  1381  			})
  1382  
  1383  			Context("with a string resource", func() {
  1384  				BeforeEach(func() {
  1385  					attDef := &design.AttributeDefinition{
  1386  						Type: design.String,
  1387  					}
  1388  					mediaType = &design.MediaTypeDefinition{
  1389  						UserTypeDefinition: &design.UserTypeDefinition{
  1390  							AttributeDefinition: attDef,
  1391  							TypeName:            "Bottle",
  1392  						},
  1393  					}
  1394  				})
  1395  				It("does not return an error", func() {
  1396  					err := writer.Execute(data)
  1397  					Ω(err).ShouldNot(HaveOccurred())
  1398  				})
  1399  			})
  1400  
  1401  			Context("with a user type resource", func() {
  1402  				BeforeEach(func() {
  1403  					intParam := &design.AttributeDefinition{Type: design.Integer}
  1404  					strParam := &design.AttributeDefinition{Type: design.String}
  1405  					dataType := design.Object{
  1406  						"int": intParam,
  1407  						"str": strParam,
  1408  					}
  1409  					attDef := &design.AttributeDefinition{
  1410  						Type: dataType,
  1411  					}
  1412  					mediaType = &design.MediaTypeDefinition{
  1413  						UserTypeDefinition: &design.UserTypeDefinition{
  1414  							AttributeDefinition: attDef,
  1415  							TypeName:            "Bottle",
  1416  						},
  1417  					}
  1418  				})
  1419  
  1420  				Context("and a canonical action", func() {
  1421  					BeforeEach(func() {
  1422  						canoTemplate = "/bottles/%v"
  1423  						canoParams = []string{"id"}
  1424  					})
  1425  
  1426  					It("writes the href method", func() {
  1427  						err := writer.Execute(data)
  1428  						Ω(err).ShouldNot(HaveOccurred())
  1429  						b, err := ioutil.ReadFile(filename)
  1430  						Ω(err).ShouldNot(HaveOccurred())
  1431  						written := string(b)
  1432  						Ω(written).ShouldNot(BeEmpty())
  1433  						Ω(written).Should(ContainSubstring(simpleResourceHref))
  1434  					})
  1435  				})
  1436  
  1437  				Context("and a canonical action with no param", func() {
  1438  					BeforeEach(func() {
  1439  						canoTemplate = "/bottles"
  1440  					})
  1441  
  1442  					It("writes the href method", func() {
  1443  						err := writer.Execute(data)
  1444  						Ω(err).ShouldNot(HaveOccurred())
  1445  						b, err := ioutil.ReadFile(filename)
  1446  						Ω(err).ShouldNot(HaveOccurred())
  1447  						written := string(b)
  1448  						Ω(written).ShouldNot(BeEmpty())
  1449  						Ω(written).Should(ContainSubstring(noParamHref))
  1450  					})
  1451  				})
  1452  			})
  1453  		})
  1454  	})
  1455  })
  1456  
  1457  var _ = Describe("UserTypesWriter", func() {
  1458  	var writer *genapp.UserTypesWriter
  1459  	var workspace *codegen.Workspace
  1460  	var filename string
  1461  
  1462  	BeforeEach(func() {
  1463  		var err error
  1464  		workspace, err = codegen.NewWorkspace("test")
  1465  		Ω(err).ShouldNot(HaveOccurred())
  1466  		pkg, err := workspace.NewPackage("controllers")
  1467  		Ω(err).ShouldNot(HaveOccurred())
  1468  		src, err := pkg.CreateSourceFile("test.go")
  1469  		Ω(err).ShouldNot(HaveOccurred())
  1470  		defer src.Close()
  1471  		filename = src.Abs()
  1472  	})
  1473  
  1474  	JustBeforeEach(func() {
  1475  		var err error
  1476  		writer, err = genapp.NewUserTypesWriter(filename)
  1477  		Ω(err).ShouldNot(HaveOccurred())
  1478  	})
  1479  
  1480  	AfterEach(func() {
  1481  		workspace.Delete()
  1482  	})
  1483  
  1484  	Context("correctly configured", func() {
  1485  		Context("with data", func() {
  1486  			var data *design.UserTypeDefinition
  1487  			var attDef *design.AttributeDefinition
  1488  			var typeName string
  1489  
  1490  			BeforeEach(func() {
  1491  				data = nil
  1492  				attDef = nil
  1493  				typeName = ""
  1494  			})
  1495  
  1496  			JustBeforeEach(func() {
  1497  				data = &design.UserTypeDefinition{
  1498  					AttributeDefinition: attDef,
  1499  					TypeName:            typeName,
  1500  				}
  1501  			})
  1502  
  1503  			Context("with a simple user type", func() {
  1504  				BeforeEach(func() {
  1505  					attDef = &design.AttributeDefinition{
  1506  						Type: design.Object{
  1507  							"name": &design.AttributeDefinition{
  1508  								Type: design.String,
  1509  							},
  1510  						},
  1511  					}
  1512  					typeName = "SimplePayload"
  1513  				})
  1514  				It("writes the simple user type code", func() {
  1515  					err := writer.Execute(data)
  1516  					Ω(err).ShouldNot(HaveOccurred())
  1517  					b, err := ioutil.ReadFile(filename)
  1518  					Ω(err).ShouldNot(HaveOccurred())
  1519  					written := string(b)
  1520  					Ω(written).ShouldNot(BeEmpty())
  1521  					Ω(written).Should(ContainSubstring(simpleUserType))
  1522  				})
  1523  			})
  1524  
  1525  			Context("with a user type including hash", func() {
  1526  				BeforeEach(func() {
  1527  					attDef = &design.AttributeDefinition{
  1528  						Type: design.Object{
  1529  							"name": &design.AttributeDefinition{
  1530  								Type: design.String,
  1531  							},
  1532  							"misc": &design.AttributeDefinition{
  1533  								Type: &design.Hash{
  1534  									KeyType: &design.AttributeDefinition{
  1535  										Type: design.Integer,
  1536  									},
  1537  									ElemType: &design.AttributeDefinition{
  1538  										Type: &design.UserTypeDefinition{
  1539  											AttributeDefinition: &design.AttributeDefinition{
  1540  												Type: &design.UserTypeDefinition{
  1541  													AttributeDefinition: &design.AttributeDefinition{
  1542  														Type: design.Object{},
  1543  													},
  1544  													TypeName: "Misc",
  1545  												},
  1546  											},
  1547  											TypeName: "MiscPayload",
  1548  										},
  1549  									},
  1550  								},
  1551  							},
  1552  						},
  1553  					}
  1554  					typeName = "ComplexPayload"
  1555  				})
  1556  				It("writes the user type including hash", func() {
  1557  					err := writer.Execute(data)
  1558  					Ω(err).ShouldNot(HaveOccurred())
  1559  					b, err := ioutil.ReadFile(filename)
  1560  					Ω(err).ShouldNot(HaveOccurred())
  1561  					written := string(b)
  1562  					Ω(written).ShouldNot(BeEmpty())
  1563  					Ω(written).Should(ContainSubstring(userTypeIncludingHash))
  1564  				})
  1565  			})
  1566  		})
  1567  	})
  1568  })
  1569  
  1570  const (
  1571  	emptyContext = `
  1572  type ListBottleContext struct {
  1573  	context.Context
  1574  	*goa.ResponseData
  1575  	*goa.RequestData
  1576  }
  1577  `
  1578  
  1579  	emptyContextFactory = `
  1580  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1581  	var err error
  1582  	resp := goa.ContextResponse(ctx)
  1583  	resp.Service = service
  1584  	req := goa.ContextRequest(ctx)
  1585  	req.Request = r
  1586  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1587  	return &rctx, err
  1588  }
  1589  `
  1590  
  1591  	intContext = `
  1592  type ListBottleContext struct {
  1593  	context.Context
  1594  	*goa.ResponseData
  1595  	*goa.RequestData
  1596  	Param *int
  1597  }
  1598  `
  1599  
  1600  	intContextFactory = `
  1601  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1602  	var err error
  1603  	resp := goa.ContextResponse(ctx)
  1604  	resp.Service = service
  1605  	req := goa.ContextRequest(ctx)
  1606  	req.Request = r
  1607  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1608  	paramParam := req.Params["param"]
  1609  	if len(paramParam) > 0 {
  1610  		rawParam := paramParam[0]
  1611  		if param, err2 := strconv.Atoi(rawParam); err2 == nil {
  1612  			tmp2 := param
  1613  			tmp1 := &tmp2
  1614  			rctx.Param = tmp1
  1615  		} else {
  1616  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer"))
  1617  		}
  1618  	}
  1619  	return &rctx, err
  1620  }
  1621  `
  1622  
  1623  	intDefaultContext = `
  1624  type ListBottleContext struct {
  1625  	context.Context
  1626  	*goa.ResponseData
  1627  	*goa.RequestData
  1628  	Param int
  1629  }
  1630  `
  1631  
  1632  	intDefaultContextFactory = `
  1633  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1634  	var err error
  1635  	resp := goa.ContextResponse(ctx)
  1636  	resp.Service = service
  1637  	req := goa.ContextRequest(ctx)
  1638  	req.Request = r
  1639  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1640  	paramParam := req.Params["param"]
  1641  	if len(paramParam) == 0 {
  1642  		rctx.Param = 2
  1643  	} else {
  1644  		rawParam := paramParam[0]
  1645  		if param, err2 := strconv.Atoi(rawParam); err2 == nil {
  1646  			rctx.Param = param
  1647  		} else {
  1648  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer"))
  1649  		}
  1650  	}
  1651  	return &rctx, err
  1652  }
  1653  `
  1654  
  1655  	intRequiredDefaultContext = `
  1656  type ListBottleContext struct {
  1657  	context.Context
  1658  	*goa.ResponseData
  1659  	*goa.RequestData
  1660  	Param int
  1661  }
  1662  `
  1663  
  1664  	intRequiredDefaultContextFactory = `
  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  		rctx.Param = 2
  1675  	} else {
  1676  		rawParam := paramParam[0]
  1677  		if param, err2 := strconv.Atoi(rawParam); err2 == nil {
  1678  			rctx.Param = param
  1679  		} else {
  1680  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer"))
  1681  		}
  1682  	}
  1683  	return &rctx, err
  1684  }
  1685  `
  1686  
  1687  	intRequiredContext = `
  1688  type ListBottleContext struct {
  1689  	context.Context
  1690  	*goa.ResponseData
  1691  	*goa.RequestData
  1692  	Param int
  1693  }
  1694  `
  1695  	intRequiredContextFactory = `
  1696  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1697  	var err error
  1698  	resp := goa.ContextResponse(ctx)
  1699  	resp.Service = service
  1700  	req := goa.ContextRequest(ctx)
  1701  	req.Request = r
  1702  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1703  	paramParam := req.Params["param"]
  1704  	if len(paramParam) == 0 {
  1705  		err = goa.MergeErrors(err, goa.MissingParamError("param"))
  1706  	} else {
  1707  		rawParam := paramParam[0]
  1708  		if param, err2 := strconv.Atoi(rawParam); err2 == nil {
  1709  			rctx.Param = param
  1710  		} else {
  1711  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer"))
  1712  		}
  1713  	}
  1714  	return &rctx, err
  1715  }
  1716  `
  1717  
  1718  	strContext = `
  1719  type ListBottleContext struct {
  1720  	context.Context
  1721  	*goa.ResponseData
  1722  	*goa.RequestData
  1723  	Param *string
  1724  }
  1725  `
  1726  
  1727  	strContextFactory = `
  1728  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1729  	var err error
  1730  	resp := goa.ContextResponse(ctx)
  1731  	resp.Service = service
  1732  	req := goa.ContextRequest(ctx)
  1733  	req.Request = r
  1734  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1735  	paramParam := req.Params["param"]
  1736  	if len(paramParam) > 0 {
  1737  		rawParam := paramParam[0]
  1738  		rctx.Param = &rawParam
  1739  	}
  1740  	return &rctx, err
  1741  }
  1742  `
  1743  
  1744  	strNonOptionalContext = `
  1745  type ListBottleContext struct {
  1746  	context.Context
  1747  	*goa.ResponseData
  1748  	*goa.RequestData
  1749  	Param string
  1750  }
  1751  `
  1752  
  1753  	strDefaultContextFactory = `
  1754  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1755  	var err error
  1756  	resp := goa.ContextResponse(ctx)
  1757  	resp.Service = service
  1758  	req := goa.ContextRequest(ctx)
  1759  	req.Request = r
  1760  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1761  	paramParam := req.Params["param"]
  1762  	if len(paramParam) == 0 {
  1763  		rctx.Param = "foo"
  1764  	} else {
  1765  		rawParam := paramParam[0]
  1766  		rctx.Param = rawParam
  1767  	}
  1768  	return &rctx, err
  1769  }
  1770  `
  1771  
  1772  	strRequiredContextFactory = `
  1773  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1774  	var err error
  1775  	resp := goa.ContextResponse(ctx)
  1776  	resp.Service = service
  1777  	req := goa.ContextRequest(ctx)
  1778  	req.Request = r
  1779  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1780  	paramParam := req.Params["param"]
  1781  	if len(paramParam) == 0 {
  1782  		err = goa.MergeErrors(err, goa.MissingParamError("param"))
  1783  	} else {
  1784  		rawParam := paramParam[0]
  1785  		rctx.Param = rawParam
  1786  	}
  1787  	return &rctx, err
  1788  }
  1789  `
  1790  
  1791  	strHeaderContext = `
  1792  type ListBottleContext struct {
  1793  	context.Context
  1794  	*goa.ResponseData
  1795  	*goa.RequestData
  1796  	Header *string
  1797  }
  1798  `
  1799  
  1800  	strHeaderContextFactory = `
  1801  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1802  	var err error
  1803  	resp := goa.ContextResponse(ctx)
  1804  	resp.Service = service
  1805  	req := goa.ContextRequest(ctx)
  1806  	req.Request = r
  1807  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1808  	headerHeader := req.Header["Header"]
  1809  	if len(headerHeader) > 0 {
  1810  		rawHeader := headerHeader[0]
  1811  		req.Params["Header"] = []string{rawHeader}
  1812  		rctx.Header = &rawHeader
  1813  	}
  1814  	return &rctx, err
  1815  }
  1816  `
  1817  
  1818  	strHeaderParamContextFactory = `
  1819  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1820  	var err error
  1821  	resp := goa.ContextResponse(ctx)
  1822  	resp.Service = service
  1823  	req := goa.ContextRequest(ctx)
  1824  	req.Request = r
  1825  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1826  	headerParam := req.Header["Param"]
  1827  	if len(headerParam) > 0 {
  1828  		rawParam := headerParam[0]
  1829  		req.Params["param"] = []string{rawParam}
  1830  		rctx.Param = &rawParam
  1831  	}
  1832  	paramParam := req.Params["param"]
  1833  	if len(paramParam) > 0 {
  1834  		rawParam := paramParam[0]
  1835  		rctx.Param = &rawParam
  1836  	}
  1837  	return &rctx, err
  1838  }
  1839  `
  1840  
  1841  	numContext = `
  1842  type ListBottleContext struct {
  1843  	context.Context
  1844  	*goa.ResponseData
  1845  	*goa.RequestData
  1846  	Param *float64
  1847  }
  1848  `
  1849  
  1850  	numContextFactory = `
  1851  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1852  	var err error
  1853  	resp := goa.ContextResponse(ctx)
  1854  	resp.Service = service
  1855  	req := goa.ContextRequest(ctx)
  1856  	req.Request = r
  1857  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1858  	paramParam := req.Params["param"]
  1859  	if len(paramParam) > 0 {
  1860  		rawParam := paramParam[0]
  1861  		if param, err2 := strconv.ParseFloat(rawParam, 64); err2 == nil {
  1862  			tmp1 := &param
  1863  			rctx.Param = tmp1
  1864  		} else {
  1865  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "number"))
  1866  		}
  1867  	}
  1868  	return &rctx, err
  1869  }
  1870  `
  1871  
  1872  	numNonOptionalContext = `
  1873  type ListBottleContext struct {
  1874  	context.Context
  1875  	*goa.ResponseData
  1876  	*goa.RequestData
  1877  	Param float64
  1878  }
  1879  `
  1880  
  1881  	numDefaultContextFactory = `
  1882  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1883  	var err error
  1884  	resp := goa.ContextResponse(ctx)
  1885  	resp.Service = service
  1886  	req := goa.ContextRequest(ctx)
  1887  	req.Request = r
  1888  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1889  	paramParam := req.Params["param"]
  1890  	if len(paramParam) == 0 {
  1891  		rctx.Param = 2.300000
  1892  	} else {
  1893  		rawParam := paramParam[0]
  1894  		if param, err2 := strconv.ParseFloat(rawParam, 64); err2 == nil {
  1895  			rctx.Param = param
  1896  		} else {
  1897  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "number"))
  1898  		}
  1899  	}
  1900  	return &rctx, err
  1901  }
  1902  `
  1903  
  1904  	numRequiredContextFactory = `
  1905  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1906  	var err error
  1907  	resp := goa.ContextResponse(ctx)
  1908  	resp.Service = service
  1909  	req := goa.ContextRequest(ctx)
  1910  	req.Request = r
  1911  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1912  	paramParam := req.Params["param"]
  1913  	if len(paramParam) == 0 {
  1914  		err = goa.MergeErrors(err, goa.MissingParamError("param"))
  1915  	} else {
  1916  		rawParam := paramParam[0]
  1917  		if param, err2 := strconv.ParseFloat(rawParam, 64); err2 == nil {
  1918  			rctx.Param = param
  1919  		} else {
  1920  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "number"))
  1921  		}
  1922  	}
  1923  	return &rctx, err
  1924  }
  1925  `
  1926  
  1927  	boolContext = `
  1928  type ListBottleContext struct {
  1929  	context.Context
  1930  	*goa.ResponseData
  1931  	*goa.RequestData
  1932  	Param *bool
  1933  }
  1934  `
  1935  
  1936  	boolContextFactory = `
  1937  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1938  	var err error
  1939  	resp := goa.ContextResponse(ctx)
  1940  	resp.Service = service
  1941  	req := goa.ContextRequest(ctx)
  1942  	req.Request = r
  1943  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1944  	paramParam := req.Params["param"]
  1945  	if len(paramParam) > 0 {
  1946  		rawParam := paramParam[0]
  1947  		if param, err2 := strconv.ParseBool(rawParam); err2 == nil {
  1948  			tmp1 := &param
  1949  			rctx.Param = tmp1
  1950  		} else {
  1951  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "boolean"))
  1952  		}
  1953  	}
  1954  	return &rctx, err
  1955  }
  1956  `
  1957  
  1958  	boolNonOptionalContext = `
  1959  type ListBottleContext struct {
  1960  	context.Context
  1961  	*goa.ResponseData
  1962  	*goa.RequestData
  1963  	Param bool
  1964  }
  1965  `
  1966  
  1967  	boolDefaultContextFactory = `
  1968  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1969  	var err error
  1970  	resp := goa.ContextResponse(ctx)
  1971  	resp.Service = service
  1972  	req := goa.ContextRequest(ctx)
  1973  	req.Request = r
  1974  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1975  	paramParam := req.Params["param"]
  1976  	if len(paramParam) == 0 {
  1977  		rctx.Param = true
  1978  	} else {
  1979  		rawParam := paramParam[0]
  1980  		if param, err2 := strconv.ParseBool(rawParam); err2 == nil {
  1981  			rctx.Param = param
  1982  		} else {
  1983  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "boolean"))
  1984  		}
  1985  	}
  1986  	return &rctx, err
  1987  }
  1988  `
  1989  
  1990  	boolRequiredContextFactory = `
  1991  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  1992  	var err error
  1993  	resp := goa.ContextResponse(ctx)
  1994  	resp.Service = service
  1995  	req := goa.ContextRequest(ctx)
  1996  	req.Request = r
  1997  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  1998  	paramParam := req.Params["param"]
  1999  	if len(paramParam) == 0 {
  2000  		err = goa.MergeErrors(err, goa.MissingParamError("param"))
  2001  	} else {
  2002  		rawParam := paramParam[0]
  2003  		if param, err2 := strconv.ParseBool(rawParam); err2 == nil {
  2004  			rctx.Param = param
  2005  		} else {
  2006  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "boolean"))
  2007  		}
  2008  	}
  2009  	return &rctx, err
  2010  }
  2011  `
  2012  
  2013  	arrayContext = `
  2014  type ListBottleContext struct {
  2015  	context.Context
  2016  	*goa.ResponseData
  2017  	*goa.RequestData
  2018  	Param []string
  2019  }
  2020  `
  2021  
  2022  	arrayContextFactory = `
  2023  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  2024  	var err error
  2025  	resp := goa.ContextResponse(ctx)
  2026  	resp.Service = service
  2027  	req := goa.ContextRequest(ctx)
  2028  	req.Request = r
  2029  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  2030  	paramParam := req.Params["param"]
  2031  	if len(paramParam) > 0 {
  2032  		params := paramParam
  2033  		rctx.Param = params
  2034  	}
  2035  	return &rctx, err
  2036  }
  2037  `
  2038  
  2039  	arrayParamContextFactory = `
  2040  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  2041  	var err error
  2042  	resp := goa.ContextResponse(ctx)
  2043  	resp.Service = service
  2044  	req := goa.ContextRequest(ctx)
  2045  	req.Request = r
  2046  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  2047  	paramParam := req.Params["param"]
  2048  	if len(paramParam) > 0 {
  2049  		params := paramParam
  2050  		rctx.Param = params
  2051  	}
  2052  	return &rctx, err
  2053  }
  2054  `
  2055  
  2056  	arrayDefaultContextFactory = `
  2057  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  2058  	var err error
  2059  	resp := goa.ContextResponse(ctx)
  2060  	resp.Service = service
  2061  	req := goa.ContextRequest(ctx)
  2062  	req.Request = r
  2063  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  2064  	paramParam := req.Params["param"]
  2065  	if len(paramParam) == 0 {
  2066  		rctx.Param = []string{"foo", "bar", "baz"}
  2067  	} else {
  2068  		params := paramParam
  2069  		rctx.Param = params
  2070  	}
  2071  	return &rctx, err
  2072  }
  2073  `
  2074  
  2075  	arrayRequiredContextFactory = `
  2076  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  2077  	var err error
  2078  	resp := goa.ContextResponse(ctx)
  2079  	resp.Service = service
  2080  	req := goa.ContextRequest(ctx)
  2081  	req.Request = r
  2082  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  2083  	paramParam := req.Params["param"]
  2084  	if len(paramParam) == 0 {
  2085  		err = goa.MergeErrors(err, goa.MissingParamError("param"))
  2086  	} else {
  2087  		params := paramParam
  2088  		rctx.Param = params
  2089  	}
  2090  	return &rctx, err
  2091  }
  2092  `
  2093  
  2094  	intArrayContext = `
  2095  type ListBottleContext struct {
  2096  	context.Context
  2097  	*goa.ResponseData
  2098  	*goa.RequestData
  2099  	Param []int
  2100  }
  2101  `
  2102  
  2103  	intArrayContextFactory = `
  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 := make([]int, len(paramParam))
  2114  		for i, rawParam := range paramParam {
  2115  			if param, err2 := strconv.Atoi(rawParam); err2 == nil {
  2116  				params[i] = param
  2117  			} else {
  2118  				err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer"))
  2119  			}
  2120  		}
  2121  		rctx.Param = params
  2122  	}
  2123  	return &rctx, err
  2124  }
  2125  `
  2126  
  2127  	intArrayDefaultContextFactory = `
  2128  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  2129  	var err error
  2130  	resp := goa.ContextResponse(ctx)
  2131  	resp.Service = service
  2132  	req := goa.ContextRequest(ctx)
  2133  	req.Request = r
  2134  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  2135  	paramParam := req.Params["param"]
  2136  	if len(paramParam) == 0 {
  2137  		rctx.Param = []int{1, 1, 2, 3, 5, 8}
  2138  	} else {
  2139  		params := make([]int, len(paramParam))
  2140  		for i, rawParam := range paramParam {
  2141  			if param, err2 := strconv.Atoi(rawParam); err2 == nil {
  2142  				params[i] = param
  2143  			} else {
  2144  				err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer"))
  2145  			}
  2146  		}
  2147  		rctx.Param = params
  2148  	}
  2149  	return &rctx, err
  2150  }
  2151  `
  2152  
  2153  	intArrayRequiredContextFactory = `
  2154  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  2155  	var err error
  2156  	resp := goa.ContextResponse(ctx)
  2157  	resp.Service = service
  2158  	req := goa.ContextRequest(ctx)
  2159  	req.Request = r
  2160  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  2161  	paramParam := req.Params["param"]
  2162  	if len(paramParam) == 0 {
  2163  		err = goa.MergeErrors(err, goa.MissingParamError("param"))
  2164  	} else {
  2165  		params := make([]int, len(paramParam))
  2166  		for i, rawParam := range paramParam {
  2167  			if param, err2 := strconv.Atoi(rawParam); err2 == nil {
  2168  				params[i] = param
  2169  			} else {
  2170  				err = goa.MergeErrors(err, goa.InvalidParamTypeError("param", rawParam, "integer"))
  2171  			}
  2172  		}
  2173  		rctx.Param = params
  2174  	}
  2175  	return &rctx, err
  2176  }
  2177  `
  2178  
  2179  	resContext = `
  2180  type ListBottleContext struct {
  2181  	context.Context
  2182  	*goa.ResponseData
  2183  	*goa.RequestData
  2184  	Int *int
  2185  }
  2186  `
  2187  
  2188  	resContextFactory = `
  2189  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  2190  	var err error
  2191  	resp := goa.ContextResponse(ctx)
  2192  	resp.Service = service
  2193  	req := goa.ContextRequest(ctx)
  2194  	req.Request = r
  2195  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  2196  	paramInt := req.Params["int"]
  2197  	if len(paramInt) > 0 {
  2198  		rawInt := paramInt[0]
  2199  		if int_, err2 := strconv.Atoi(rawInt); err2 == nil {
  2200  			tmp2 := int_
  2201  			tmp1 := &tmp2
  2202  			rctx.Int = tmp1
  2203  		} else {
  2204  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("int", rawInt, "integer"))
  2205  		}
  2206  	}
  2207  	return &rctx, err
  2208  }
  2209  `
  2210  
  2211  	requiredContext = `
  2212  type ListBottleContext struct {
  2213  	context.Context
  2214  	*goa.ResponseData
  2215  	*goa.RequestData
  2216  	Int int
  2217  }
  2218  `
  2219  
  2220  	requiredContextFactory = `
  2221  func NewListBottleContext(ctx context.Context, r *http.Request, service *goa.Service) (*ListBottleContext, error) {
  2222  	var err error
  2223  	resp := goa.ContextResponse(ctx)
  2224  	resp.Service = service
  2225  	req := goa.ContextRequest(ctx)
  2226  	req.Request = r
  2227  	rctx := ListBottleContext{Context: ctx, ResponseData: resp, RequestData: req}
  2228  	paramInt := req.Params["int"]
  2229  	if len(paramInt) == 0 {
  2230  		err = goa.MergeErrors(err, goa.MissingParamError("int"))
  2231  	} else {
  2232  		rawInt := paramInt[0]
  2233  		if int_, err2 := strconv.Atoi(rawInt); err2 == nil {
  2234  			rctx.Int = int_
  2235  		} else {
  2236  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("int", rawInt, "integer"))
  2237  		}
  2238  	}
  2239  	return &rctx, err
  2240  }
  2241  `
  2242  
  2243  	customContext = `
  2244  type ListBottleContext struct {
  2245  	context.Context
  2246  	*goa.ResponseData
  2247  	*goa.RequestData
  2248  	Custom *int
  2249  }
  2250  `
  2251  
  2252  	customContextFactory = `
  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.Custom = tmp1
  2267  		} else {
  2268  			err = goa.MergeErrors(err, goa.InvalidParamTypeError("int", rawInt, "integer"))
  2269  		}
  2270  	}
  2271  	return &rctx, err
  2272  }
  2273  `
  2274  
  2275  	payloadContext = `
  2276  type ListBottleContext struct {
  2277  	context.Context
  2278  	*goa.ResponseData
  2279  	*goa.RequestData
  2280  	Payload ListBottlePayload
  2281  }
  2282  `
  2283  
  2284  	payloadContextFactory = `
  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  	return &rctx, err
  2293  }
  2294  `
  2295  	payloadObjContext = `
  2296  type ListBottleContext struct {
  2297  	context.Context
  2298  	*goa.ResponseData
  2299  	*goa.RequestData
  2300  	Payload *ListBottlePayload
  2301  }
  2302  `
  2303  
  2304  	payloadObjUnmarshal = `
  2305  func unmarshalListBottlePayload(ctx context.Context, service *goa.Service, req *http.Request) error {
  2306  	payload := &listBottlePayload{}
  2307  	if err := service.DecodeRequest(req, payload); err != nil {
  2308  		return err
  2309  	}
  2310  	if err := payload.Validate(); err != nil {
  2311  		// Initialize payload with private data structure so it can be logged
  2312  		goa.ContextRequest(ctx).Payload = payload
  2313  		return err
  2314  	}
  2315  	goa.ContextRequest(ctx).Payload = payload.Publicize()
  2316  	return nil
  2317  }
  2318  `
  2319  
  2320  	payloadMultipartObjUnmarshal = `
  2321  func unmarshalListBottlePayload(ctx context.Context, service *goa.Service, req *http.Request) error {
  2322  	var err error
  2323  	var payload listBottlePayload
  2324  	_, rawIcon, err2 := req.FormFile("icon")
  2325  	if err2 == nil {
  2326  		payload.Icon = rawIcon
  2327  	} else {
  2328  		err = goa.MergeErrors(err, goa.InvalidParamTypeError("icon", "icon", "file"))
  2329  	}
  2330  	rawID := req.FormValue("id")
  2331  	payload.ID = &rawID
  2332  	if err != nil {
  2333  		return err
  2334  	}
  2335  	if err := payload.Validate(); err != nil {
  2336  		// Initialize payload with private data structure so it can be logged
  2337  		goa.ContextRequest(ctx).Payload = payload
  2338  		return err
  2339  	}
  2340  	goa.ContextRequest(ctx).Payload = payload.Publicize()
  2341  	return nil
  2342  }
  2343  `
  2344  
  2345  	payloadNoValidationsObjUnmarshal = `
  2346  func unmarshalListBottlePayload(ctx context.Context, service *goa.Service, req *http.Request) error {
  2347  	payload := &listBottlePayload{}
  2348  	if err := service.DecodeRequest(req, payload); err != nil {
  2349  		return err
  2350  	}
  2351  	goa.ContextRequest(ctx).Payload = payload.Publicize()
  2352  	return nil
  2353  }
  2354  `
  2355  
  2356  	simpleFileServer = `// PublicController is the controller interface for the Public actions.
  2357  type PublicController interface {
  2358  	goa.Muxer
  2359  	goa.FileServer
  2360  }
  2361  `
  2362  
  2363  	fileServerOptionsHandler = `service.Mux.Handle("OPTIONS", "/public/star\\*star/*filepath", ctrl.MuxHandler("preflight", handlePublicOrigin(cors.HandlePreflight()), nil))`
  2364  
  2365  	simpleController = `// BottlesController is the controller interface for the Bottles actions.
  2366  type BottlesController interface {
  2367  	goa.Muxer
  2368  	List(*ListBottleContext) error
  2369  }
  2370  `
  2371  
  2372  	originsIntegration = `}
  2373  	h = handleBottlesOrigin(h)
  2374  	service.Mux.Handle`
  2375  
  2376  	originsHandler = `// handleBottlesOrigin applies the CORS response headers corresponding to the origin.
  2377  func handleBottlesOrigin(h goa.Handler) goa.Handler {
  2378  
  2379  	return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
  2380  		origin := req.Header.Get("Origin")
  2381  		if origin == "" {
  2382  			// Not a CORS request
  2383  			return h(ctx, rw, req)
  2384  		}
  2385  		if cors.MatchOrigin(origin, "here.example.com") {
  2386  			ctx = goa.WithLogContext(ctx, "origin", origin)
  2387  			rw.Header().Set("Access-Control-Allow-Origin", origin)
  2388  			rw.Header().Set("Vary", "Origin")
  2389  			rw.Header().Set("Access-Control-Expose-Headers", "X-Three")
  2390  			rw.Header().Set("Access-Control-Allow-Credentials", "true")
  2391  			if acrm := req.Header.Get("Access-Control-Request-Method"); acrm != "" {
  2392  				// We are handling a preflight request
  2393  				rw.Header().Set("Access-Control-Allow-Methods", "GET, POST")
  2394  				rw.Header().Set("Access-Control-Allow-Headers", "X-One, X-Two")
  2395  			}
  2396  			return h(ctx, rw, req)
  2397  		}
  2398  		if cors.MatchOrigin(origin, "there.example.com") {
  2399  			ctx = goa.WithLogContext(ctx, "origin", origin)
  2400  			rw.Header().Set("Access-Control-Allow-Origin", origin)
  2401  			rw.Header().Set("Vary", "Origin")
  2402  			rw.Header().Set("Access-Control-Allow-Credentials", "false")
  2403  			if acrm := req.Header.Get("Access-Control-Request-Method"); acrm != "" {
  2404  				// We are handling a preflight request
  2405  				rw.Header().Set("Access-Control-Allow-Methods", "*")
  2406  				rw.Header().Set("Access-Control-Allow-Headers", "*")
  2407  			}
  2408  			return h(ctx, rw, req)
  2409  		}
  2410  
  2411  		return h(ctx, rw, req)
  2412  	}
  2413  }
  2414  `
  2415  
  2416  	regexpOriginsHandler = `// handleBottlesOrigin applies the CORS response headers corresponding to the origin.
  2417  func handleBottlesOrigin(h goa.Handler) goa.Handler {
  2418  	spec0 := regexp.MustCompile("[here|there].example.com")
  2419  
  2420  	return func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
  2421  		origin := req.Header.Get("Origin")
  2422  		if origin == "" {
  2423  			// Not a CORS request
  2424  			return h(ctx, rw, req)
  2425  		}
  2426  		if cors.MatchOriginRegexp(origin, spec0) {
  2427  			ctx = goa.WithLogContext(ctx, "origin", origin)
  2428  			rw.Header().Set("Access-Control-Allow-Origin", origin)
  2429  			rw.Header().Set("Vary", "Origin")
  2430  			rw.Header().Set("Access-Control-Expose-Headers", "X-Three")
  2431  			rw.Header().Set("Access-Control-Allow-Credentials", "true")
  2432  			if acrm := req.Header.Get("Access-Control-Request-Method"); acrm != "" {
  2433  				// We are handling a preflight request
  2434  				rw.Header().Set("Access-Control-Allow-Methods", "GET, POST")
  2435  				rw.Header().Set("Access-Control-Allow-Headers", "X-One, X-Two")
  2436  			}
  2437  			return h(ctx, rw, req)
  2438  		}
  2439  		if cors.MatchOrigin(origin, "there.example.com") {
  2440  			ctx = goa.WithLogContext(ctx, "origin", origin)
  2441  			rw.Header().Set("Access-Control-Allow-Origin", origin)
  2442  			rw.Header().Set("Vary", "Origin")
  2443  			rw.Header().Set("Access-Control-Allow-Credentials", "false")
  2444  			if acrm := req.Header.Get("Access-Control-Request-Method"); acrm != "" {
  2445  				// We are handling a preflight request
  2446  				rw.Header().Set("Access-Control-Allow-Methods", "*")
  2447  				rw.Header().Set("Access-Control-Allow-Headers", "*")
  2448  			}
  2449  			return h(ctx, rw, req)
  2450  		}
  2451  
  2452  		return h(ctx, rw, req)
  2453  	}
  2454  }
  2455  `
  2456  
  2457  	encoderController = `
  2458  // MountBottlesController "mounts" a Bottles resource controller on the given service.
  2459  func MountBottlesController(service *goa.Service, ctrl BottlesController) {
  2460  	initService(service)
  2461  	var h goa.Handler
  2462  
  2463  	h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
  2464  		// Check if there was an error loading the request
  2465  		if err := goa.ContextError(ctx); err != nil {
  2466  			return err
  2467  		}
  2468  		// Build the context
  2469  		rctx, err := NewListBottleContext(ctx, req, service)
  2470  		if err != nil {
  2471  			return err
  2472  		}
  2473  		return ctrl.List(rctx)
  2474  	}
  2475  	service.Mux.Handle("GET", "/accounts/:accountID/bottles", ctrl.MuxHandler("list", h, nil))
  2476  	service.LogInfo("mount", "ctrl", "Bottles", "action", "List", "route", "GET /accounts/:accountID/bottles")
  2477  }
  2478  `
  2479  
  2480  	simpleMount = `func MountBottlesController(service *goa.Service, ctrl BottlesController) {
  2481  	initService(service)
  2482  	var h goa.Handler
  2483  
  2484  	h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
  2485  		// Check if there was an error loading the request
  2486  		if err := goa.ContextError(ctx); err != nil {
  2487  			return err
  2488  		}
  2489  		// Build the context
  2490  		rctx, err := NewListBottleContext(ctx, req, service)
  2491  		if err != nil {
  2492  			return err
  2493  		}
  2494  		return ctrl.List(rctx)
  2495  	}
  2496  	service.Mux.Handle("GET", "/accounts/:accountID/bottles", ctrl.MuxHandler("list", h, nil))
  2497  	service.LogInfo("mount", "ctrl", "Bottles", "action", "List", "route", "GET /accounts/:accountID/bottles")
  2498  }
  2499  `
  2500  
  2501  	multiController = `// BottlesController is the controller interface for the Bottles actions.
  2502  type BottlesController interface {
  2503  	goa.Muxer
  2504  	List(*ListBottleContext) error
  2505  	Show(*ShowBottleContext) error
  2506  }
  2507  `
  2508  
  2509  	multiMount = `func MountBottlesController(service *goa.Service, ctrl BottlesController) {
  2510  	initService(service)
  2511  	var h goa.Handler
  2512  
  2513  	h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
  2514  		// Check if there was an error loading the request
  2515  		if err := goa.ContextError(ctx); err != nil {
  2516  			return err
  2517  		}
  2518  		// Build the context
  2519  		rctx, err := NewListBottleContext(ctx, req, service)
  2520  		if err != nil {
  2521  			return err
  2522  		}
  2523  		return ctrl.List(rctx)
  2524  	}
  2525  	service.Mux.Handle("GET", "/accounts/:accountID/bottles", ctrl.MuxHandler("list", h, nil))
  2526  	service.LogInfo("mount", "ctrl", "Bottles", "action", "List", "route", "GET /accounts/:accountID/bottles")
  2527  
  2528  	h = func(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
  2529  		// Check if there was an error loading the request
  2530  		if err := goa.ContextError(ctx); err != nil {
  2531  			return err
  2532  		}
  2533  		// Build the context
  2534  		rctx, err := NewShowBottleContext(ctx, req, service)
  2535  		if err != nil {
  2536  			return err
  2537  		}
  2538  		return ctrl.Show(rctx)
  2539  	}
  2540  	service.Mux.Handle("GET", "/accounts/:accountID/bottles/:id", ctrl.MuxHandler("show", h, nil))
  2541  	service.LogInfo("mount", "ctrl", "Bottles", "action", "Show", "route", "GET /accounts/:accountID/bottles/:id")
  2542  }
  2543  `
  2544  
  2545  	simpleResourceHref = `func BottleHref(id interface{}) string {
  2546  	paramid := strings.TrimLeftFunc(fmt.Sprintf("%v", id), func(r rune) bool { return r == '/' })
  2547  	return fmt.Sprintf("/bottles/%v", paramid)
  2548  }
  2549  `
  2550  	noParamHref = `func BottleHref() string {
  2551  	return "/bottles"
  2552  }
  2553  `
  2554  
  2555  	simpleUserType = `// simplePayload user type.
  2556  type simplePayload struct {
  2557  	Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" yaml:"name,omitempty" xml:"name,omitempty"` + "`" + `
  2558  }
  2559  
  2560  
  2561  
  2562  // Publicize creates SimplePayload from simplePayload
  2563  func (ut *simplePayload) Publicize() *SimplePayload {
  2564  	var pub SimplePayload
  2565  		if ut.Name != nil {
  2566  		pub.Name = ut.Name
  2567  	}
  2568  	return &pub
  2569  }
  2570  
  2571  // SimplePayload user type.
  2572  type SimplePayload struct {
  2573  	Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" yaml:"name,omitempty" xml:"name,omitempty"` + "`" + `
  2574  }
  2575  `
  2576  
  2577  	userTypeIncludingHash = `// complexPayload user type.
  2578  type complexPayload struct {
  2579  	Misc map[int]*miscPayload ` + "`" + `form:"misc,omitempty" json:"misc,omitempty" yaml:"misc,omitempty" xml:"misc,omitempty"` + "`" + `
  2580  	Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" yaml:"name,omitempty" xml:"name,omitempty"` + "`" + `
  2581  }
  2582  
  2583  
  2584  
  2585  // Publicize creates ComplexPayload from complexPayload
  2586  func (ut *complexPayload) Publicize() *ComplexPayload {
  2587  	var pub ComplexPayload
  2588  		if ut.Misc != nil {
  2589  		pub.Misc = make(map[int]*MiscPayload, len(ut.Misc))
  2590  		for k2, v2 := range ut.Misc {
  2591  						pubk2 := k2
  2592  			var pubv2 *MiscPayload
  2593  			if v2 != nil {
  2594  						pubv2 = v2.Publicize()
  2595  			}
  2596  			pub.Misc[pubk2] = pubv2
  2597  		}
  2598  	}
  2599  	if ut.Name != nil {
  2600  		pub.Name = ut.Name
  2601  	}
  2602  	return &pub
  2603  }
  2604  
  2605  // ComplexPayload user type.
  2606  type ComplexPayload struct {
  2607  	Misc map[int]*MiscPayload ` + "`" + `form:"misc,omitempty" json:"misc,omitempty" yaml:"misc,omitempty" xml:"misc,omitempty"` + "`" + `
  2608  	Name *string ` + "`" + `form:"name,omitempty" json:"name,omitempty" yaml:"name,omitempty" xml:"name,omitempty"` + "`" + `
  2609  }
  2610  `
  2611  )