github.com/JarrahG/buffalocli@v0.0.0-20230801092127-b85bfd5d395a/internal/genny/resource/resource_test.go (about)

     1  package resource
     2  
     3  import (
     4  	"fmt"
     5  	"io/fs"
     6  	"os"
     7  	"path"
     8  	"path/filepath"
     9  	"regexp"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/gobuffalo/attrs"
    14  	"github.com/JarrahG/buffalocli/internal/genny/newapp/api"
    15  	"github.com/JarrahG/buffalocli/internal/genny/newapp/core"
    16  	"github.com/JarrahG/buffalocli/internal/genny/newapp/web"
    17  	"github.com/JarrahG/buffalocli/internal/genny/testrunner"
    18  	"github.com/gobuffalo/flect/name"
    19  	"github.com/gobuffalo/meta"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  type pass struct {
    24  	Name    string
    25  	Options Options
    26  }
    27  
    28  func Test_New(t *testing.T) {
    29  	ats, err := attrs.ParseArgs("name", "desc:nulls.Text")
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	}
    33  
    34  	tt := []pass{
    35  		{"default", Options{Name: "widget", Attrs: ats}},
    36  		{"nested", Options{Name: "admin/widget", Attrs: ats}},
    37  	}
    38  
    39  	app := meta.New(".")
    40  	app.PackageRoot("github.com/markbates/coke")
    41  
    42  	for _, tc := range tt {
    43  		t.Run(tc.Name, func(st *testing.T) {
    44  			r := require.New(st)
    45  
    46  			opts := &web.Options{}
    47  			opts.Options = &core.Options{App: app}
    48  			run, err := testrunner.WebApp(opts)
    49  			r.NoError(err)
    50  
    51  			tc.Options.App = app
    52  			g, err := New(&tc.Options)
    53  			r.NoError(err)
    54  
    55  			r.NoError(run.With(g))
    56  			r.NoError(run.Run())
    57  
    58  			res := run.Results()
    59  			r.Len(res.Commands, 1)
    60  
    61  			c := res.Commands[0]
    62  			r.Equal("buffalo-pop pop g model widget name desc:nulls.Text", strings.Join(c.Args, " "))
    63  			r.Len(res.Files, 30)
    64  
    65  			nn := name.New(tc.Options.Name).Pluralize().String()
    66  			actions := []string{"_form", "index", "show", "new", "edit"}
    67  			for _, s := range actions {
    68  				p := path.Join("templates", nn, s+".plush.html")
    69  				_, err = res.Find(p)
    70  				r.NoError(err)
    71  			}
    72  
    73  			fsys := os.DirFS(filepath.Join("_fixtures", tc.Name))
    74  			err = fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
    75  				if err != nil {
    76  					return err
    77  				}
    78  				if d.IsDir() {
    79  					return nil
    80  				}
    81  
    82  				f, err := res.Find(strings.TrimSuffix(path, ".tmpl"))
    83  				r.NoError(err)
    84  
    85  				s, err := fs.ReadFile(fsys, path)
    86  				r.NoError(err)
    87  
    88  				clean := func(s string) string {
    89  					s = strings.TrimSpace(s)
    90  					s = strings.ReplaceAll(s, "\n", "")
    91  					s = strings.ReplaceAll(s, "\t", "")
    92  					s = strings.ReplaceAll(s, "\r", "")
    93  
    94  					spaces := regexp.MustCompile(`\s+`)
    95  					return spaces.ReplaceAllString(s, " ")
    96  				}
    97  
    98  				r.Equal(clean(string(s)), clean(f.String()))
    99  				return nil
   100  			})
   101  			r.NoError(err)
   102  		})
   103  	}
   104  }
   105  
   106  func Test_New_SkipTemplates(t *testing.T) {
   107  	ats, err := attrs.ParseArgs("name", "desc:nulls.Text")
   108  	if err != nil {
   109  		t.Fatal(err)
   110  	}
   111  	table := []pass{
   112  		{"default", Options{Name: "widget", Attrs: ats}},
   113  		{"nested", Options{Name: "admin/widget", Attrs: ats}},
   114  	}
   115  
   116  	app := meta.New(".")
   117  	app.PackageRoot("github.com/markbates/coke")
   118  
   119  	for _, tt := range table {
   120  		t.Run(tt.Name, func(st *testing.T) {
   121  			r := require.New(st)
   122  
   123  			opts := &web.Options{}
   124  			opts.Options = &core.Options{App: app}
   125  			run, err := testrunner.WebApp(opts)
   126  			r.NoError(err)
   127  
   128  			tt.Options.App = app
   129  			tt.Options.SkipTemplates = true
   130  			g, err := New(&tt.Options)
   131  			r.NoError(err)
   132  
   133  			r.NoError(run.With(g))
   134  			r.NoError(run.Run())
   135  
   136  			res := run.Results()
   137  
   138  			r.Len(res.Commands, 1)
   139  			for _, s := range []string{"_form", "edit", "index", "new", "show"} {
   140  				p := path.Join("templates", tt.Name, s+".html")
   141  				_, err = res.Find(p)
   142  				r.Error(err)
   143  			}
   144  
   145  			r.Len(res.Files, 24)
   146  		})
   147  	}
   148  }
   149  
   150  func Test_New_API(t *testing.T) {
   151  	ats, err := attrs.ParseArgs("name", "desc:nulls.Text")
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  	table := []pass{
   156  		{"default", Options{Name: "widget", Attrs: ats}},
   157  		{"nested", Options{Name: "admin/widget", Attrs: ats}},
   158  	}
   159  
   160  	app := meta.New(".")
   161  	app.PackageRoot("github.com/markbates/coke")
   162  	app.AsAPI = true
   163  
   164  	for _, tt := range table {
   165  		t.Run(tt.Name, func(st *testing.T) {
   166  			r := require.New(st)
   167  
   168  			opts := &api.Options{}
   169  			opts.Options = &core.Options{App: app}
   170  			run, err := testrunner.ApiApp(opts)
   171  			r.NoError(err)
   172  
   173  			tt.Options.App = app
   174  			g, err := New(&tt.Options)
   175  			r.NoError(err)
   176  
   177  			r.NoError(run.With(g))
   178  			r.NoError(run.Run())
   179  
   180  			res := run.Results()
   181  
   182  			r.Len(res.Commands, 1)
   183  
   184  			nn := name.New(tt.Options.Name).Pluralize().String()
   185  			for _, s := range []string{"_form", "edit", "index", "new", "show"} {
   186  				p := path.Join("templates", nn, s+".html")
   187  				_, err = res.Find(p)
   188  				r.Error(err)
   189  			}
   190  
   191  			r.Len(res.Files, 18)
   192  		})
   193  	}
   194  }
   195  
   196  func Test_New_UseModel(t *testing.T) {
   197  	r := require.New(t)
   198  
   199  	app := meta.New(".")
   200  	app.PackageRoot("github.com/markbates/coke")
   201  
   202  	opts := &web.Options{}
   203  	opts.Options = &core.Options{App: app}
   204  	run, err := testrunner.WebApp(opts)
   205  	r.NoError(err)
   206  
   207  	ats, err := attrs.ParseArgs("name", "desc:nulls.Text")
   208  	r.NoError(err)
   209  
   210  	g, err := New(&Options{
   211  		App:   app,
   212  		Name:  "Widget",
   213  		Model: "User",
   214  		Attrs: ats,
   215  	})
   216  	r.NoError(err)
   217  	r.NoError(run.With(g))
   218  	r.NoError(run.Run())
   219  
   220  	res := run.Results()
   221  	r.Len(res.Commands, 1)
   222  
   223  	c := res.Commands[0]
   224  	r.Equal("buffalo-pop pop g model user name desc:nulls.Text", strings.Join(c.Args, " "))
   225  	r.Len(res.Files, 30)
   226  
   227  	for _, s := range []string{"_form", "edit", "index", "new", "show"} {
   228  		p := path.Join("templates", "widgets", s+".plush.html")
   229  		_, err = res.Find(p)
   230  		r.NoError(err)
   231  	}
   232  
   233  	f, err := res.Find("actions/widgets.go")
   234  	r.NoError(err)
   235  	r.Contains(f.String(), "users := &models.Users{}")
   236  }
   237  
   238  func Test_New_SkipModel(t *testing.T) {
   239  	r := require.New(t)
   240  
   241  	app := meta.New(".")
   242  	app.PackageRoot("github.com/markbates/coke")
   243  
   244  	opts := &web.Options{}
   245  	opts.Options = &core.Options{App: app}
   246  	run, err := testrunner.WebApp(opts)
   247  	r.NoError(err)
   248  
   249  	g, err := New(&Options{
   250  		App:       app,
   251  		Name:      "Widget",
   252  		SkipModel: true,
   253  	})
   254  	r.NoError(err)
   255  	r.NoError(run.With(g))
   256  	r.NoError(run.Run())
   257  
   258  	res := run.Results()
   259  	r.Len(res.Commands, 0)
   260  	r.Len(res.Files, 30)
   261  
   262  	f, err := res.Find("actions/widgets.go")
   263  	r.NoError(err)
   264  	actions := []string{"List", "Show", "Create", "Update", "Destroy", "New", "Edit"}
   265  	for _, action := range actions {
   266  		r.Contains(f.String(), fmt.Sprintf("func (v WidgetsResource) %v(c buffalo.Context) error {", action))
   267  	}
   268  }