github.com/blp1526/goa@v1.4.0/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  })