github.com/brycereitano/goa@v0.0.0-20170315073847-8ffa6c85e265/goagen/gen_app/test_generator_test.go (about) 1 package genapp_test 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 8 "github.com/goadesign/goa/design" 9 "github.com/goadesign/goa/dslengine" 10 "github.com/goadesign/goa/goagen/codegen" 11 "github.com/goadesign/goa/goagen/gen_app" 12 "github.com/goadesign/goa/version" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 ) 16 17 var _ = Describe("Generate", func() { 18 const testgenPackagePath = "github.com/goadesign/goa/goagen/gen_app/test_" 19 20 var outDir string 21 var files []string 22 var genErr error 23 24 BeforeEach(func() { 25 gopath := filepath.SplitList(os.Getenv("GOPATH"))[0] 26 outDir = filepath.Join(gopath, "src", testgenPackagePath) 27 err := os.MkdirAll(outDir, 0777) 28 Ω(err).ShouldNot(HaveOccurred()) 29 os.Args = []string{"goagen", "--out=" + outDir, "--design=foo", "--version=" + version.String()} 30 design.GeneratedMediaTypes = make(design.MediaTypeRoot) 31 design.ProjectedMediaTypes = make(design.MediaTypeRoot) 32 }) 33 34 JustBeforeEach(func() { 35 files, genErr = genapp.Generate() 36 }) 37 38 AfterEach(func() { 39 os.RemoveAll(outDir) 40 delete(codegen.Reserved, "app") 41 }) 42 43 Context("with notest flag", func() { 44 BeforeEach(func() { 45 os.Args = []string{"goagen", "--out=" + outDir, "--design=foo", "--notest", "--version=" + version.String()} 46 }) 47 48 It("does not generate tests", func() { 49 _, err := os.Stat(filepath.Join(outDir, "app", "test")) 50 Expect(err).To(HaveOccurred()) 51 Expect(os.IsNotExist(err)).To(BeTrue()) 52 }) 53 }) 54 55 Context("with an basic action", func() { 56 BeforeEach(func() { 57 codegen.TempCount = 0 58 59 userType := &design.UserTypeDefinition{ 60 AttributeDefinition: &design.AttributeDefinition{Type: &design.Array{ElemType: &design.AttributeDefinition{Type: design.String}}}, 61 TypeName: "CustomName", 62 } 63 64 intAttr := &design.AttributeDefinition{ 65 Type: design.Object{"foo": &design.AttributeDefinition{Type: design.Integer}}, 66 Validation: &dslengine.ValidationDefinition{Required: []string{"foo"}}, 67 } 68 69 intMedia := &design.MediaTypeDefinition{ 70 Identifier: "application/vnd.goa.test.int", 71 UserTypeDefinition: &design.UserTypeDefinition{ 72 AttributeDefinition: intAttr, 73 TypeName: "IntContainer", 74 }, 75 } 76 77 defaultView := &design.ViewDefinition{ 78 AttributeDefinition: intAttr, 79 Name: "default", 80 Parent: intMedia, 81 } 82 83 intMedia.Views = map[string]*design.ViewDefinition{"default": defaultView} 84 85 design.Design = &design.APIDefinition{ 86 Name: "testapi", 87 Title: "dummy API with no resource", 88 Description: "I told you it's dummy", 89 MediaTypes: map[string]*design.MediaTypeDefinition{ 90 design.ErrorMedia.Identifier: design.ErrorMedia, 91 intMedia.Identifier: intMedia, 92 }, 93 Resources: map[string]*design.ResourceDefinition{ 94 "foo": { 95 Name: "foo", 96 Actions: map[string]*design.ActionDefinition{ 97 "show": { 98 Name: "show", 99 Params: &design.AttributeDefinition{ 100 Type: design.Object{ 101 "param": &design.AttributeDefinition{Type: design.Integer}, 102 "time": &design.AttributeDefinition{Type: design.DateTime}, 103 "uuid": &design.AttributeDefinition{Type: design.UUID}, 104 "optional": &design.AttributeDefinition{Type: design.Integer}, 105 "required": &design.AttributeDefinition{Type: design.DateTime}, 106 "query": &design.AttributeDefinition{Type: design.String}, 107 }, 108 Validation: &dslengine.ValidationDefinition{Required: []string{"required"}}, 109 }, 110 Headers: &design.AttributeDefinition{ 111 Type: design.Object{ 112 "optionalHeader": &design.AttributeDefinition{Type: design.Integer}, 113 "requiredHeader": &design.AttributeDefinition{Type: design.String}, 114 }, 115 Validation: &dslengine.ValidationDefinition{Required: []string{"requiredHeader"}}, 116 }, 117 QueryParams: &design.AttributeDefinition{ 118 Type: design.Object{ 119 "optional": &design.AttributeDefinition{Type: design.Integer}, 120 "required": &design.AttributeDefinition{Type: design.DateTime}, 121 "query": &design.AttributeDefinition{Type: design.String}, 122 }, 123 Validation: &dslengine.ValidationDefinition{Required: []string{"required"}}, 124 }, 125 Routes: []*design.RouteDefinition{ 126 { 127 Verb: "GET", 128 Path: "p/:param/u/:uuid/:required", 129 }, 130 { 131 Verb: "POST", 132 Path: "", 133 }, 134 }, 135 Responses: map[string]*design.ResponseDefinition{ 136 "ok": { 137 Name: "ok", 138 Status: 200, 139 MediaType: intMedia.Identifier, 140 }, 141 }, 142 }, 143 "get": { 144 Name: "get", 145 Params: &design.AttributeDefinition{ 146 Type: design.Object{ 147 "param": &design.AttributeDefinition{Type: design.Integer}, 148 "time": &design.AttributeDefinition{Type: design.DateTime}, 149 "uuid": &design.AttributeDefinition{Type: design.UUID}, 150 }, 151 }, 152 Routes: []*design.RouteDefinition{ 153 { 154 Verb: "GET", 155 Path: "", 156 }, 157 }, 158 Payload: userType, 159 Responses: map[string]*design.ResponseDefinition{ 160 "ok": { 161 Name: "ok", 162 Type: design.ErrorMedia, 163 MediaType: "application/vnd.goa.error", 164 }, 165 }, 166 }, 167 }, 168 }, 169 }, 170 } 171 fooRes := design.Design.Resources["foo"] 172 for _, a := range fooRes.Actions { 173 a.Parent = fooRes 174 a.Routes[0].Parent = a 175 } 176 }) 177 178 It("does not call Validate on the resulting media type when it does not exist", func() { 179 Ω(genErr).Should(BeNil()) 180 Ω(files).Should(HaveLen(8)) 181 content, err := ioutil.ReadFile(filepath.Join(outDir, "app", "test", "foo_testing.go")) 182 Ω(err).ShouldNot(HaveOccurred()) 183 184 Ω(content).ShouldNot(ContainSubstring("err = mt.Validate()")) 185 }) 186 187 It("generates the ActionRouteResponse test methods ", func() { 188 Ω(genErr).Should(BeNil()) 189 Ω(files).Should(HaveLen(8)) 190 content, err := ioutil.ReadFile(filepath.Join(outDir, "app", "test", "foo_testing.go")) 191 Ω(err).ShouldNot(HaveOccurred()) 192 193 Ω(content).Should(ContainSubstring("ShowFooOK(")) 194 // Multiple Routes 195 Ω(content).Should(ContainSubstring("ShowFooOK1(")) 196 // Get returns an error media type 197 Ω(content).Should(ContainSubstring("GetFooOK(t goatest.TInterface, ctx context.Context, service *goa.Service, ctrl app.FooController, payload app.CustomName) (http.ResponseWriter, error)")) 198 }) 199 200 It("generates the route path parameters", func() { 201 content, err := ioutil.ReadFile(filepath.Join(outDir, "app", "test", "foo_testing.go")) 202 Ω(err).ShouldNot(HaveOccurred()) 203 204 Ω(content).Should(ContainSubstring(`["param"] = []string{`)) 205 Ω(content).Should(ContainSubstring(`["uuid"] = []string{`)) 206 Ω(content).Should(ContainSubstring(`["required"] = []string{`)) 207 Ω(content).ShouldNot(ContainSubstring(`["time"] = []string{`)) 208 }) 209 210 It("properly handles query parameters", func() { 211 content, err := ioutil.ReadFile(filepath.Join(outDir, "app", "test", "foo_testing.go")) 212 Ω(err).ShouldNot(HaveOccurred()) 213 214 Ω(content).Should(ContainSubstring(`if optional != nil`)) 215 Ω(content).ShouldNot(ContainSubstring(`if required != nil`)) 216 Ω(content).Should(ContainSubstring(`if query != nil`)) 217 }) 218 219 It("properly handles headers", func() { 220 content, err := ioutil.ReadFile(filepath.Join(outDir, "app", "test", "foo_testing.go")) 221 Ω(err).ShouldNot(HaveOccurred()) 222 223 Ω(content).Should(ContainSubstring(`if optionalHeader != nil`)) 224 Ω(content).ShouldNot(ContainSubstring(`if requiredHeader != nil`)) 225 Ω(content).Should(ContainSubstring(`req.Header["requiredHeader"] = sliceVal`)) 226 }) 227 228 It("generates calls to new Context ", func() { 229 content, err := ioutil.ReadFile(filepath.Join(outDir, "app", "test", "foo_testing.go")) 230 Ω(err).ShouldNot(HaveOccurred()) 231 232 Ω(content).Should(ContainSubstring("app.NewShowFooContext(")) 233 }) 234 235 It("generates calls controller action method", func() { 236 content, err := ioutil.ReadFile(filepath.Join(outDir, "app", "test", "foo_testing.go")) 237 Ω(err).ShouldNot(HaveOccurred()) 238 239 Ω(content).Should(ContainSubstring("ctrl.Show(")) 240 }) 241 242 It("generates non pointer references to primitive/array/hash payloads", func() { 243 content, err := ioutil.ReadFile(filepath.Join(outDir, "app", "test", "foo_testing.go")) 244 Ω(err).ShouldNot(HaveOccurred()) 245 246 Ω(content).Should(ContainSubstring(", payload app.CustomName)")) 247 }) 248 It("generates header with DO NOT MODIFY", func() { 249 content, err := ioutil.ReadFile(filepath.Join(outDir, "app", "test", "foo_testing.go")) 250 Ω(err).ShouldNot(HaveOccurred()) 251 252 Ω(content).Should(ContainSubstring("DO NOT MODIFY")) 253 }) 254 255 }) 256 })