github.com/goldeneggg/goa@v1.3.1/goagen/gen_main/generator_test.go (about) 1 package genmain_test 2 3 import ( 4 "bytes" 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "strings" 9 10 "github.com/goadesign/goa/design" 11 "github.com/goadesign/goa/goagen/gen_main" 12 "github.com/goadesign/goa/version" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 "github.com/onsi/gomega/gexec" 16 ) 17 18 var _ = Describe("Generate", func() { 19 const testgenPackagePath = "github.com/goadesign/goa/goagen/gen_main/goatest" 20 21 var outDir string 22 var files []string 23 var genErr error 24 25 BeforeEach(func() { 26 gopath := filepath.SplitList(os.Getenv("GOPATH"))[0] 27 outDir = filepath.Join(gopath, "src", testgenPackagePath) 28 err := os.MkdirAll(outDir, 0777) 29 Ω(err).ShouldNot(HaveOccurred()) 30 os.Args = []string{"goagen", "--out=" + outDir, "--design=foo", "--version=" + version.String()} 31 }) 32 33 JustBeforeEach(func() { 34 files, genErr = genmain.Generate() 35 }) 36 37 AfterEach(func() { 38 os.RemoveAll(outDir) 39 }) 40 41 Context("with a dummy API", func() { 42 BeforeEach(func() { 43 design.Design = &design.APIDefinition{ 44 Name: "test api", 45 Title: "dummy API with no resource", 46 Description: "I told you it's dummy", 47 } 48 }) 49 50 It("generates a dummy app", func() { 51 Ω(genErr).Should(BeNil()) 52 Ω(files).Should(HaveLen(1)) 53 content, err := ioutil.ReadFile(filepath.Join(outDir, "main.go")) 54 Ω(err).ShouldNot(HaveOccurred()) 55 Ω(len(strings.Split(string(content), "\n"))).Should(BeNumerically(">=", 16)) 56 _, err = gexec.Build(testgenPackagePath) 57 Ω(err).ShouldNot(HaveOccurred()) 58 }) 59 }) 60 61 Context("with resources", func() { 62 var resource *design.ResourceDefinition 63 64 BeforeEach(func() { 65 resource = &design.ResourceDefinition{ 66 Name: "first", 67 Description: "first stuff", 68 Actions: map[string]*design.ActionDefinition{}, 69 } 70 alpha := &design.ActionDefinition{ 71 Parent: resource, 72 Name: "alpha", 73 Schemes: []string{"http"}, 74 Description: "Alpha-like things", 75 } 76 resource.Actions[alpha.Name] = alpha 77 design.Design = &design.APIDefinition{ 78 Name: "whatever", 79 Title: "test API", 80 Description: "Ain't matter none", 81 Resources: map[string]*design.ResourceDefinition{ 82 "first": resource, 83 }, 84 } 85 }) 86 87 It("generates controllers ready for regeneration", func() { 88 Ω(genErr).Should(BeNil()) 89 Ω(files).Should(HaveLen(2)) 90 content, err := ioutil.ReadFile(filepath.Join(outDir, "first.go")) 91 Ω(err).ShouldNot(HaveOccurred()) 92 Ω(content).Should(MatchRegexp("FirstController_Alpha: start_implement")) 93 Ω(content).Should(MatchRegexp(`// FirstController_Alpha: start_implement\s*// Put your logic here\s*return nil\s*// FirstController_Alpha: end_implement`)) 94 }) 95 96 Context("regenerated with a new resource", func() { 97 BeforeEach(func() { 98 // Perform a first generation 99 files, genErr = genmain.Generate() 100 101 // Put some impl in the existing controller 102 existing, err := ioutil.ReadFile(filepath.Join(outDir, "first.go")) 103 Ω(err).ShouldNot(HaveOccurred()) 104 105 // First add an import for fmt, to make sure it remains 106 existing = bytes.Replace(existing, []byte("import ("), []byte("import (\n\t\"fmt\")"), 1) 107 108 // Next add some body that uses fmt 109 existing = bytes.Replace(existing, []byte("// Put your logic here"), []byte("fmt.Println(\"I did it first\")"), 1) 110 111 err = ioutil.WriteFile(filepath.Join(outDir, "first.go"), existing, os.ModePerm) 112 Ω(err).ShouldNot(HaveOccurred()) 113 114 // Add an action to the existing resource 115 beta := &design.ActionDefinition{ 116 Parent: resource, 117 Name: "beta", 118 Schemes: []string{"http"}, 119 Description: "Beta-like things", 120 } 121 resource.Actions[beta.Name] = beta 122 123 // Add a new resource 124 resource2 := &design.ResourceDefinition{ 125 Name: "second", 126 Description: "second stuff", 127 Actions: map[string]*design.ActionDefinition{}, 128 } 129 gamma := &design.ActionDefinition{ 130 Parent: resource2, 131 Name: "gamma", 132 Schemes: []string{"http"}, 133 Description: "Gamma-like things", 134 } 135 resource2.Actions[gamma.Name] = gamma 136 137 design.Design.Resources[resource2.Name] = resource2 138 139 // Set up the regeneration for the JustBeforeEach 140 os.Args = append(os.Args, "--regen") 141 }) 142 143 It("generates scaffolding for new and existing resources", func() { 144 Ω(genErr).Should(BeNil()) 145 Ω(files).Should(HaveLen(2)) 146 Ω(files).Should(ConsistOf(filepath.Join(outDir, "first.go"), filepath.Join(outDir, "second.go"))) 147 148 content, err := ioutil.ReadFile(filepath.Join(outDir, "second.go")) 149 Ω(err).ShouldNot(HaveOccurred()) 150 Ω(content).Should(ContainSubstring("SecondController_Gamma: start_implement")) 151 152 }) 153 154 It("regenerates controllers without modifying existing impls", func() { 155 content, err := ioutil.ReadFile(filepath.Join(outDir, "first.go")) 156 Ω(err).ShouldNot(HaveOccurred()) 157 158 // First make sure the new controller is in place 159 Ω(content).Should(ContainSubstring("FirstController_Beta: start_implement")) 160 161 // Check the fmt import 162 Ω(string(content)).Should(MatchRegexp(`import \(\s*[^)]*\"fmt\"`)) 163 164 // Check the body is in place 165 Ω(content).Should(MatchRegexp(`// FirstController_Alpha: start_implement\s*fmt.Println\("I did it first"\)\s*return nil\s*// FirstController_Alpha: end_implement`)) 166 }) 167 }) 168 169 }) 170 }) 171 172 var _ = Describe("NewGenerator", func() { 173 var generator *genmain.Generator 174 175 var args = struct { 176 api *design.APIDefinition 177 outDir string 178 designPkg string 179 target string 180 force bool 181 regen bool 182 noExample bool 183 }{ 184 api: &design.APIDefinition{ 185 Name: "test api", 186 }, 187 outDir: "out_dir", 188 designPkg: "design", 189 target: "app", 190 force: false, 191 regen: false, 192 } 193 194 Context("with options all options set", func() { 195 BeforeEach(func() { 196 197 generator = genmain.NewGenerator( 198 genmain.API(args.api), 199 genmain.OutDir(args.outDir), 200 genmain.DesignPkg(args.designPkg), 201 genmain.Target(args.target), 202 genmain.Force(args.force), 203 genmain.Regen(args.regen), 204 ) 205 }) 206 207 It("has all public properties set with expected value", func() { 208 Ω(generator).ShouldNot(BeNil()) 209 Ω(generator.API.Name).Should(Equal(args.api.Name)) 210 Ω(generator.OutDir).Should(Equal(args.outDir)) 211 Ω(generator.DesignPkg).Should(Equal(args.designPkg)) 212 Ω(generator.Target).Should(Equal(args.target)) 213 Ω(generator.Force).Should(Equal(args.force)) 214 Ω(generator.Regen).Should(Equal(args.regen)) 215 }) 216 217 }) 218 })