From 6f7275ccfd4f2072a47ad675144aec568f1591d8 Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Tue, 22 Nov 2022 15:21:40 -0500 Subject: [PATCH 1/7] task: improving test command --- internal/cmd/test/find_test_packages.go | 32 +++++++++++++++++++++++++ internal/cmd/test/test.go | 27 ++------------------- 2 files changed, 34 insertions(+), 25 deletions(-) create mode 100644 internal/cmd/test/find_test_packages.go diff --git a/internal/cmd/test/find_test_packages.go b/internal/cmd/test/find_test_packages.go new file mode 100644 index 00000000..c5d7bbdc --- /dev/null +++ b/internal/cmd/test/find_test_packages.go @@ -0,0 +1,32 @@ +package test + +import "golang.org/x/tools/go/packages" + +// findTestPackages in the current directory using the go/packages API. +func findTestPackages(givenArgs []string) ([]string, error) { + // If there are args, then assume these are the packages to test. + if len(givenArgs) > 0 { + return givenArgs, nil + } + + cfg := &packages.Config{ + Mode: packages.NeedName, + Dir: ".", + } + + pkgs, err := packages.Load(cfg, "./...") + if err != nil { + return []string{}, err + } + + if packages.PrintErrors(pkgs) > 0 { + return []string{}, err + } + + xx := []string{} + for _, pkg := range pkgs { + xx = append(xx, pkg.ID) + } + + return xx, nil +} diff --git a/internal/cmd/test/test.go b/internal/cmd/test/test.go index 91aac5bb..fb3933e1 100644 --- a/internal/cmd/test/test.go +++ b/internal/cmd/test/test.go @@ -122,7 +122,7 @@ func testRunner(args []string) error { }.Run() } - pkgs, err := testPackages(packageArgs) + pkgs, err := findTestPackages(packageArgs) if err != nil { return err } @@ -143,7 +143,7 @@ func (m mFlagRunner) Run() error { pwd, _ := os.Getwd() defer os.Chdir(pwd) - pkgs, err := testPackages(m.pargs) + pkgs, err := findTestPackages(m.pargs) if err != nil { return err } @@ -186,29 +186,6 @@ func hasTestify(args []string) bool { return bytes.Contains(b, []byte("-testify.m")) } -func testPackages(givenArgs []string) ([]string, error) { - // If there are args, then assume these are the packages to test. - // - // Instead of always returning all packages from 'go list ./...', just - // return the given packages in this case - if len(givenArgs) > 0 { - return givenArgs, nil - } - - args := []string{} - out, err := exec.Command(envy.Get("GO_BIN", "go"), "list", "./...").Output() - if err != nil { - return args, err - } - pkgs := bytes.Split(bytes.TrimSpace(out), []byte("\n")) - for _, p := range pkgs { - if !strings.Contains(string(p), "/vendor/") { - args = append(args, string(p)) - } - } - return args, nil -} - func newTestCmd(args []string) *exec.Cmd { cargs := []string{"test", "-p", "1"} app := meta.New(".") From 3e7f5d40ffd0b5c5316e0ff784b6f414b1f22ba7 Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Fri, 25 Nov 2022 09:46:54 -0500 Subject: [PATCH 2/7] task: rewriting our test command --- internal/cmd/test/build_cmd.go | 67 ++++++ internal/cmd/test/build_cmd_test.go | 69 ++++++ internal/cmd/test/cmd.go | 14 -- ...find_test_packages.go => find_packages.go} | 9 +- internal/cmd/test/setup_database.go | 77 +++++++ internal/cmd/test/test.go | 208 ++---------------- internal/cmd/test/test_test.go | 27 --- 7 files changed, 233 insertions(+), 238 deletions(-) create mode 100644 internal/cmd/test/build_cmd.go create mode 100644 internal/cmd/test/build_cmd_test.go delete mode 100644 internal/cmd/test/cmd.go rename internal/cmd/test/{find_test_packages.go => find_packages.go} (59%) create mode 100644 internal/cmd/test/setup_database.go delete mode 100644 internal/cmd/test/test_test.go diff --git a/internal/cmd/test/build_cmd.go b/internal/cmd/test/build_cmd.go new file mode 100644 index 00000000..a4ff2cd2 --- /dev/null +++ b/internal/cmd/test/build_cmd.go @@ -0,0 +1,67 @@ +package test + +import ( + "os" + "os/exec" + "strings" + + "github.com/gobuffalo/envy" + "github.com/gobuffalo/meta" +) + +var ( + // if GO_BIN is set, use it, otherwise use "go" + goBinary = envy.Get("GO_BIN", "go") + + // testValuedFlags are the flags on the go test command that + // receive a value, we use this to determine if the last argument + // is a flag or a package path + testValuedFlags = strings.Join([]string{ + `-p`, `-asmflags`, `-buildmode`, `-compiler`, `-gccgoflags`, + `-gcflags`, `-installsuffix`, `-mod`, `-modfile`, `-overlay`, + `-pkgdir`, `-tags`, `-trimpath`, `-toolexec`, `-o`, `-exec`, + `-bench`, `-benchtime`, `-blockprofile`, `-blockprofilerate`, + `-count`, `-coverprofile`, `-cpu`, `-cpuprofile`, `-fuzz `, + `-fuzzcachedir`, `-fuzzminimizetime`, `-fuzztime`, `-list`, + `-memprofile`, `-memprofilerate`, `-mutexprofile`, `-mutexprofilefraction`, + `-outputdir`, `-parallel`, `-run`, `-shuffle`, `-testlogfile`, + `-timeout`, `-trace`, + }, "|") +) + +// buildCmd builds the test command to be passed to the go test command +// after cutting some of the arguments that are specific to buffalo and adding +// packages if missing. +// TODO: -run -testify.m -testify.m +func buildCmd(args []string) *exec.Cmd { + app := meta.New(".") + + if len(args) > 0 { + // Cleanup --force-migrations flag + args = strings.Split(strings.Replace(strings.Join(args, " "), "--force-migrations ", "", -1), " ") + } + + cargs := append([]string{ + "test", + // run sequentially + "-p", "1", + // add build tags + "-tags", app.BuildTags("development").String(), + //TODO: Should we merge it with passed tags? + }, args...) + + // if no packages are specified, add the current directory + lastIsFlag := len(args) > 0 && strings.HasPrefix(args[len(args)-1], "-") + lastIsFlagValue := len(args) >= 2 && strings.Contains(testValuedFlags, args[len(args)-2]) + if len(args) == 0 || lastIsFlag || lastIsFlagValue { + // TODO: Should we run one by one the packages? + cargs = append(cargs, "./...") + } + + cmd := exec.Command(goBinary, cargs...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + return cmd +} diff --git a/internal/cmd/test/build_cmd_test.go b/internal/cmd/test/build_cmd_test.go new file mode 100644 index 00000000..b08c6b80 --- /dev/null +++ b/internal/cmd/test/build_cmd_test.go @@ -0,0 +1,69 @@ +package test + +import ( + "reflect" + "testing" +) + +func TestBuildCmd(t *testing.T) { + tcases := []struct { + name string + args []string + want []string + }{ + { + name: "no args", + args: []string{}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "./..."}, + }, + + { + name: "path specified", + args: []string{"./cmd/..."}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "./cmd/..."}, + }, + + { + name: "path specified and flags", + args: []string{"--count=1", "./cmd/..."}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "--count=1", "./cmd/..."}, + }, + + { + name: "flags but no path", + args: []string{"--count=1", "-v"}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "--count=1", "-v", "./..."}, + }, + + { + name: "flags but no path", + args: []string{"--count=1", "-v"}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "--count=1", "-v", "./..."}, + }, + + { + name: "flags no path with -tags", + args: []string{"--count=1", "-tags", "foo,bar"}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "--count=1", "-tags", "foo,bar", "./..."}, + }, + + { + name: "force migrations should be removed", + args: []string{"--force-migrations", "-tags", "foo,bar"}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "-tags", "foo,bar", "./..."}, + }, + } + + for _, tc := range tcases { + t.Run(tc.name, func(t *testing.T) { + cmd := buildCmd(tc.args) + if len(cmd.Args) != len(tc.want) { + t.Errorf("want %d args, got %d", len(tc.want), len(cmd.Args)) + } + + if !reflect.DeepEqual(cmd.Args, tc.want) { + t.Errorf("want %s, got %s", tc.want, cmd.Args) + } + }) + } +} diff --git a/internal/cmd/test/cmd.go b/internal/cmd/test/cmd.go deleted file mode 100644 index fbadaafb..00000000 --- a/internal/cmd/test/cmd.go +++ /dev/null @@ -1,14 +0,0 @@ -package test - -import "github.com/spf13/cobra" - -func Cmd() *cobra.Command { - cmd := &cobra.Command{ - Use: "test", - Short: "Run the tests for the Buffalo app. Use --force-migrations to skip schema load.", - DisableFlagParsing: true, - RunE: runE, - } - - return cmd -} diff --git a/internal/cmd/test/find_test_packages.go b/internal/cmd/test/find_packages.go similarity index 59% rename from internal/cmd/test/find_test_packages.go rename to internal/cmd/test/find_packages.go index c5d7bbdc..cc4abb05 100644 --- a/internal/cmd/test/find_test_packages.go +++ b/internal/cmd/test/find_packages.go @@ -2,13 +2,8 @@ package test import "golang.org/x/tools/go/packages" -// findTestPackages in the current directory using the go/packages API. -func findTestPackages(givenArgs []string) ([]string, error) { - // If there are args, then assume these are the packages to test. - if len(givenArgs) > 0 { - return givenArgs, nil - } - +// findPackages in the current directory using the x/tools/go/packages API. +func findPackages() ([]string, error) { cfg := &packages.Config{ Mode: packages.NeedName, Dir: ".", diff --git a/internal/cmd/test/setup_database.go b/internal/cmd/test/setup_database.go new file mode 100644 index 00000000..7547e477 --- /dev/null +++ b/internal/cmd/test/setup_database.go @@ -0,0 +1,77 @@ +package test + +import ( + "bytes" + "fmt" + "io" + "os" + "path/filepath" + "strings" + + "github.com/gobuffalo/pop/v6" +) + +func setupDatabase(args []string) error { + if _, err := os.Stat("database.yml"); err != nil { + return err + } + + test, err := pop.Connect("test") + if err != nil { + return err + } + + // drop the test db: + if err := test.Dialect.DropDB(); err != nil { + // not an error, since the database will be created in the next step anyway + fmt.Println("INFO: no test database to drop.") + } + + // create the test db: + err = test.Dialect.CreateDB() + if err != nil { + return err + } + + forceMigrations := strings.Contains(strings.Join(args, " "), "--force-migrations") + if forceMigrations { + fm, err := pop.NewFileMigrator("./migrations", test) + if err != nil { + return err + } + + return fm.Up() + } + + if schema := findSchema(); schema != nil { + return test.Dialect.LoadSchema(schema) + } + + return nil +} + +func findSchema() io.Reader { + if f, err := os.Open(filepath.Join("migrations", "schema.sql")); err == nil { + return f + } + + if dev, err := pop.Connect("development"); err == nil { + schema := &bytes.Buffer{} + if err = dev.Dialect.DumpSchema(schema); err == nil { + return schema + } + } + + if test, err := pop.Connect("test"); err == nil { + fm, err := pop.NewFileMigrator("./migrations", test) + if err != nil { + return nil + } + + if err := fm.Up(); err == nil { + return nil + } + } + + return nil +} diff --git a/internal/cmd/test/test.go b/internal/cmd/test/test.go index fb3933e1..e48fc1ef 100644 --- a/internal/cmd/test/test.go +++ b/internal/cmd/test/test.go @@ -1,209 +1,37 @@ package test import ( - "bytes" - "fmt" - "io" "os" - "os/exec" - "path/filepath" - "strings" - "github.com/gobuffalo/envy" - "github.com/gobuffalo/meta" - "github.com/gobuffalo/pop/v6" - "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) -func runE(c *cobra.Command, args []string) error { - os.Setenv("GO_ENV", "test") - if _, err := os.Stat("database.yml"); err == nil { - // there's a database - test, err := pop.Connect("test") - if err != nil { - return err - } +var cmd = &cobra.Command{ + Use: "test", + Short: "Runs tests for your Buffalo app", + Long: ``, - // drop the test db: - if err := test.Dialect.DropDB(); err != nil { - // not an error, since the database will be created in the next step anyway - logrus.Info("no test database to drop") - } + // DisableFlagParsing is set to true since we will need to allow undefined + // flags to be passed to the go test command. + DisableFlagParsing: true, - // create the test db: - err = test.Dialect.CreateDB() - if err != nil { + RunE: func(c *cobra.Command, args []string) error { + // Set the environment to be test so that the rest of the tooling + // understands we're in testing mode. + if err := os.Setenv("GO_ENV", "test"); err != nil { return err } - // Read and remove --force-migrations flag from args: - forceMigrations := strings.Contains(strings.Join(args, ""), "--force-migrations") - args = cutArg("--force-migrations", args) - if forceMigrations { - fm, err := pop.NewFileMigrator("./migrations", test) - if err != nil { - return err - } - - if err := fm.Up(); err != nil { - return err - } - - return testRunner(args) - } - - if schema := findSchema(); schema != nil { - err = test.Dialect.LoadSchema(schema) - if err != nil { - return err - } - } - } - return testRunner(args) -} - -func findSchema() io.Reader { - if f, err := os.Open(filepath.Join("migrations", "schema.sql")); err == nil { - return f - } - if dev, err := pop.Connect("development"); err == nil { - schema := &bytes.Buffer{} - if err = dev.Dialect.DumpSchema(schema); err == nil { - return schema - } - } - - if test, err := pop.Connect("test"); err == nil { - fm, err := pop.NewFileMigrator("./migrations", test) - if err != nil { - return nil - } - - if err := fm.Up(); err == nil { - return nil - } - } - return nil -} - -func testRunner(args []string) error { - var mFlag bool - var query string - - commandArgs := []string{} - packageArgs := []string{} - - var lastArg string - for index, arg := range args { - switch arg { - case "-run", "-m": - query = args[index+1] - mFlag = true - case "-v", "-timeout": - commandArgs = append(commandArgs, arg) - default: - if lastArg == "-timeout" { - commandArgs = append(commandArgs, arg) - } else if lastArg != "-run" && lastArg != "-m" { - packageArgs = append(packageArgs, arg) - } - } - - lastArg = arg - } - - cmd := newTestCmd(commandArgs) - if mFlag { - return mFlagRunner{ - query: query, - args: commandArgs, - pargs: packageArgs, - }.Run() - } - - pkgs, err := findTestPackages(packageArgs) - if err != nil { - return err - } - - cmd.Args = append(cmd.Args, pkgs...) - logrus.Info(strings.Join(cmd.Args, " ")) - return cmd.Run() -} - -type mFlagRunner struct { - query string - args []string - pargs []string -} - -func (m mFlagRunner) Run() error { - app := meta.New(".") - pwd, _ := os.Getwd() - defer os.Chdir(pwd) - - pkgs, err := findTestPackages(m.pargs) - if err != nil { - return err - } - - var errs bool - for _, p := range pkgs { - os.Chdir(pwd) - - if p == app.PackagePkg { - continue - } - - cmd := newTestCmd(m.args) - - p = strings.TrimPrefix(p, app.PackagePkg+string(filepath.Separator)) - os.Chdir(p) - - if hasTestify(cmd.Args) { - cmd.Args = append(cmd.Args, "-testify.m", m.query) - } else { - cmd.Args = append(cmd.Args, "-run", m.query) + // Setup the database before running the tests. + if err := setupDatabase(args); err != nil { + return err } - logrus.Info(strings.Join(cmd.Args, " ")) - - if err := cmd.Run(); err != nil { - errs = true - } - } - if errs { - return fmt.Errorf("errors running tests") - } - return nil + return buildCmd(args).Run() + }, } -func hasTestify(args []string) bool { - cmd := exec.Command(args[0], args[1:]...) - cmd.Args = append(cmd.Args, "-unknownflag") - b, _ := cmd.Output() - return bytes.Contains(b, []byte("-testify.m")) -} - -func newTestCmd(args []string) *exec.Cmd { - cargs := []string{"test", "-p", "1"} - app := meta.New(".") - cargs = append(cargs, "-tags", app.BuildTags("development").String()) - cargs = append(cargs, args...) - cmd := exec.Command(envy.Get("GO_BIN", "go"), cargs...) - cmd.Stdin = os.Stdin - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr +// TODO: Remove me +func Cmd() *cobra.Command { return cmd } - -func cutArg(arg string, args []string) []string { - for i, v := range args { - if v == arg { - return append(args[:i], args[i+1:]...) - } - } - - return args -} diff --git a/internal/cmd/test/test_test.go b/internal/cmd/test/test_test.go deleted file mode 100644 index 01856922..00000000 --- a/internal/cmd/test/test_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package test - -import ( - "reflect" - "testing" -) - -func Test_CutArg(t *testing.T) { - tests := []struct { - arg string - args []string - expected []string - }{ - {"b", []string{"a", "b", "c"}, []string{"a", "c"}}, - {"--is-not-in-args", []string{"a", "b", "c"}, []string{"a", "b", "c"}}, - {"--foo", []string{"--foo", "--bar", "--baz"}, []string{"--bar", "--baz"}}, - {"--force-migrations", []string{"./actions/", "--force-migrations"}, []string{"./actions/"}}, - {"--force-migrations", []string{"./actions/", "--force-migrations", "-m", "Test_HomeHandler"}, []string{"./actions/", "-m", "Test_HomeHandler"}}, - } - - for _, tt := range tests { - result := cutArg(tt.arg, tt.args) - if !reflect.DeepEqual(result, tt.expected) { - t.Errorf("got %s, want %s when cutting %s from %s", result, tt.expected, tt.arg, tt.args) - } - } -} From 36cbb2c847fd4dcd717080a13a11ee4f46aa7c2a Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Fri, 25 Nov 2022 11:21:54 -0500 Subject: [PATCH 3/7] feature: adding -testify.m flag --- internal/cmd/test/build_cmd.go | 73 +++++++++++++++++++++++------ internal/cmd/test/build_cmd_test.go | 50 ++++++++++++++------ internal/cmd/test/find_packages.go | 13 +++-- internal/cmd/test/test.go | 10 +++- 4 files changed, 114 insertions(+), 32 deletions(-) diff --git a/internal/cmd/test/build_cmd.go b/internal/cmd/test/build_cmd.go index a4ff2cd2..10deaec2 100644 --- a/internal/cmd/test/build_cmd.go +++ b/internal/cmd/test/build_cmd.go @@ -32,15 +32,10 @@ var ( // buildCmd builds the test command to be passed to the go test command // after cutting some of the arguments that are specific to buffalo and adding // packages if missing. -// TODO: -run -testify.m -testify.m -func buildCmd(args []string) *exec.Cmd { +func buildCmd(args []string) (*exec.Cmd, error) { app := meta.New(".") - if len(args) > 0 { - // Cleanup --force-migrations flag - args = strings.Split(strings.Replace(strings.Join(args, " "), "--force-migrations ", "", -1), " ") - } - + ccar := clean(args) cargs := append([]string{ "test", // run sequentially @@ -48,20 +43,70 @@ func buildCmd(args []string) *exec.Cmd { // add build tags "-tags", app.BuildTags("development").String(), //TODO: Should we merge it with passed tags? - }, args...) + }, ccar...) // if no packages are specified, add the current directory - lastIsFlag := len(args) > 0 && strings.HasPrefix(args[len(args)-1], "-") - lastIsFlagValue := len(args) >= 2 && strings.Contains(testValuedFlags, args[len(args)-2]) - if len(args) == 0 || lastIsFlag || lastIsFlagValue { - // TODO: Should we run one by one the packages? - cargs = append(cargs, "./...") + lastIsFlag := len(ccar) > 0 && strings.HasPrefix(args[len(ccar)-1], "-") + lastIsFlagValue := len(ccar) >= 2 && strings.Contains(testValuedFlags, ccar[len(ccar)-2]) + if len(ccar) == 0 || lastIsFlag || lastIsFlagValue { + pkgs, err := findPackages() + if err != nil { + return nil, err + } + + cargs = append(cargs, pkgs...) } + // Add extra args (-testify.m) to the command + cargs = append(cargs, extraArgs(args)...) + cmd := exec.Command(goBinary, cargs...) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - return cmd + return cmd, nil +} + +// Removes flags that are only used by the Buffalo test command and should not be passed to +// the Go test command. Those flags are: +// * --force-migrations +// * -m +// * -testify.m +func clean(args []string) []string { + var cleaned []string + for ix, v := range args { + if v == "--force-migrations" { + continue + } + + if v == "-m" || (ix > 0 && !strings.HasPrefix(v, "-") && args[ix-1] == "-m") { + continue + } + + if v == "-testify.m" || (ix > 0 && !strings.HasPrefix(v, "-") && args[ix-1] == "-testify.m") { + continue + } + + cleaned = append(cleaned, v) + } + + return cleaned +} + +// Adds extra flags to the go test command for the testify functionality if the +// -testify.m or -m flags are passed. +func extraArgs(args []string) []string { + var extra []string + for ix, v := range args { + if ix >= len(args)-1 || strings.HasPrefix(args[ix+1], "-") { + continue + } + + if v == "-m" || v == "-testify.m" || v == "--run" { + extra = append(extra, "-testify.m", args[ix+1]) + } + } + + return extra } diff --git a/internal/cmd/test/build_cmd_test.go b/internal/cmd/test/build_cmd_test.go index b08c6b80..9b8376c7 100644 --- a/internal/cmd/test/build_cmd_test.go +++ b/internal/cmd/test/build_cmd_test.go @@ -1,20 +1,21 @@ package test import ( - "reflect" + "strings" "testing" ) func TestBuildCmd(t *testing.T) { tcases := []struct { - name string - args []string - want []string + name string + args []string + want []string + contains string }{ { name: "no args", args: []string{}, - want: []string{"go", "test", "-p", "1", "-tags", "development", "./..."}, + want: []string{"go", "test", "-p", "1", "-tags", "development"}, }, { @@ -32,37 +33,58 @@ func TestBuildCmd(t *testing.T) { { name: "flags but no path", args: []string{"--count=1", "-v"}, - want: []string{"go", "test", "-p", "1", "-tags", "development", "--count=1", "-v", "./..."}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "--count=1", "-v"}, }, { name: "flags but no path", args: []string{"--count=1", "-v"}, - want: []string{"go", "test", "-p", "1", "-tags", "development", "--count=1", "-v", "./..."}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "--count=1", "-v"}, }, { name: "flags no path with -tags", args: []string{"--count=1", "-tags", "foo,bar"}, - want: []string{"go", "test", "-p", "1", "-tags", "development", "--count=1", "-tags", "foo,bar", "./..."}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "--count=1", "-tags", "foo,bar"}, }, { name: "force migrations should be removed", args: []string{"--force-migrations", "-tags", "foo,bar"}, - want: []string{"go", "test", "-p", "1", "-tags", "development", "-tags", "foo,bar", "./..."}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "-tags", "foo,bar"}, + }, + + { + name: "force migrations should be removed", + args: []string{"--force-migrations", "-m", "Something"}, + want: []string{"go", "test", "-p", "1", "-tags", "development"}, + }, + + { + name: "testify.m should go at the end", + args: []string{"--force-migrations", "-testify.m", "Something"}, + want: []string{"go", "test", "-p", "1", "-tags", "development"}, + contains: "-testify.m Something", }, } for _, tc := range tcases { t.Run(tc.name, func(t *testing.T) { - cmd := buildCmd(tc.args) - if len(cmd.Args) != len(tc.want) { - t.Errorf("want %d args, got %d", len(tc.want), len(cmd.Args)) + cmd, err := buildCmd(tc.args) + if err != nil { + t.Fatal(err) + } + + wantcmd := strings.Join(tc.want, " ") + resultcmd := strings.Join(cmd.Args, " ") + + prefixMatches := strings.HasPrefix(resultcmd, wantcmd) + if !prefixMatches { + t.Errorf("prefix `%s` not found in `%s`", wantcmd, resultcmd) } - if !reflect.DeepEqual(cmd.Args, tc.want) { - t.Errorf("want %s, got %s", tc.want, cmd.Args) + if tc.contains != "" && !strings.Contains(resultcmd, tc.contains) { + t.Errorf("string `%s` not found in `%s`", tc.contains, resultcmd) } }) } diff --git a/internal/cmd/test/find_packages.go b/internal/cmd/test/find_packages.go index cc4abb05..951ff3ce 100644 --- a/internal/cmd/test/find_packages.go +++ b/internal/cmd/test/find_packages.go @@ -1,8 +1,10 @@ package test -import "golang.org/x/tools/go/packages" +import ( + "golang.org/x/tools/go/packages" +) -// findPackages in the current directory using the x/tools/go/packages API. +// findPackages in the current directory using the x/tools/go/packages API func findPackages() ([]string, error) { cfg := &packages.Config{ Mode: packages.NeedName, @@ -20,7 +22,12 @@ func findPackages() ([]string, error) { xx := []string{} for _, pkg := range pkgs { - xx = append(xx, pkg.ID) + xx = append( + xx, + + // Trim the prefix of the application root module + pkg.ID, + ) } return xx, nil diff --git a/internal/cmd/test/test.go b/internal/cmd/test/test.go index e48fc1ef..6e8a139d 100644 --- a/internal/cmd/test/test.go +++ b/internal/cmd/test/test.go @@ -1,7 +1,9 @@ package test import ( + "fmt" "os" + "strings" "github.com/spf13/cobra" ) @@ -27,7 +29,13 @@ var cmd = &cobra.Command{ return err } - return buildCmd(args).Run() + tcmd, err := buildCmd(args) + if err != nil { + return err + } + + fmt.Println("[INFO]", strings.Join(tcmd.Args, " ")) + return tcmd.Run() }, } From c6274144d8f9f479ca5906d1af2289d554c248e3 Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Fri, 25 Nov 2022 11:22:18 -0500 Subject: [PATCH 4/7] task: should be -run --- internal/cmd/test/build_cmd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/test/build_cmd.go b/internal/cmd/test/build_cmd.go index 10deaec2..fbd54936 100644 --- a/internal/cmd/test/build_cmd.go +++ b/internal/cmd/test/build_cmd.go @@ -103,7 +103,7 @@ func extraArgs(args []string) []string { continue } - if v == "-m" || v == "-testify.m" || v == "--run" { + if v == "-m" || v == "-testify.m" || v == "-run" { extra = append(extra, "-testify.m", args[ix+1]) } } From 41198dfd0dac7b85e67d2a2b3282232952799f01 Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Fri, 25 Nov 2022 11:24:25 -0500 Subject: [PATCH 5/7] task: adding a few tests --- internal/cmd/test/build_cmd_test.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/internal/cmd/test/build_cmd_test.go b/internal/cmd/test/build_cmd_test.go index 9b8376c7..d0fc987b 100644 --- a/internal/cmd/test/build_cmd_test.go +++ b/internal/cmd/test/build_cmd_test.go @@ -55,9 +55,17 @@ func TestBuildCmd(t *testing.T) { }, { - name: "force migrations should be removed", - args: []string{"--force-migrations", "-m", "Something"}, - want: []string{"go", "test", "-p", "1", "-tags", "development"}, + name: "testify.m through -m", + args: []string{"--force-migrations", "-m", "Something"}, + want: []string{"go", "test", "-p", "1", "-tags", "development"}, + contains: "-testify.m Something", + }, + + { + name: "testify.m through -run", + args: []string{"--force-migrations", "-run", "Something"}, + want: []string{"go", "test", "-p", "1", "-tags", "development", "-run", "Something"}, + contains: "-testify.m Something", }, { From f835bf6590f466a919331078cdf452c55862ddd1 Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Fri, 25 Nov 2022 11:28:04 -0500 Subject: [PATCH 6/7] cleaning --- internal/cmd/test/find_packages.go | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/internal/cmd/test/find_packages.go b/internal/cmd/test/find_packages.go index 951ff3ce..7918227b 100644 --- a/internal/cmd/test/find_packages.go +++ b/internal/cmd/test/find_packages.go @@ -22,12 +22,7 @@ func findPackages() ([]string, error) { xx := []string{} for _, pkg := range pkgs { - xx = append( - xx, - - // Trim the prefix of the application root module - pkg.ID, - ) + xx = append(xx, pkg.ID) } return xx, nil From 6782c95e9c671c253273ff8b17f9aefd1857195a Mon Sep 17 00:00:00 2001 From: Antonio Pagano Date: Fri, 25 Nov 2022 11:44:09 -0500 Subject: [PATCH 7/7] task: adding some help on the test command --- internal/cmd/root.go | 2 +- internal/cmd/test/longhelp.txt | 13 +++++++ internal/cmd/test/test.go | 71 +++++++++++++++++----------------- 3 files changed, 50 insertions(+), 36 deletions(-) create mode 100644 internal/cmd/test/longhelp.txt diff --git a/internal/cmd/root.go b/internal/cmd/root.go index 402dae51..a47f7326 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -100,7 +100,7 @@ func cmd() *cobra.Command { generateCmd := generate.Cmd() destroyCmd := destroy.Cmd() versionCmd := version.Cmd() - testCmd := test.Cmd() + testCmd := test.Cmd devCmd := dev.Cmd() taskCmd := task.Cmd() routesCmd := routes.Cmd() diff --git a/internal/cmd/test/longhelp.txt b/internal/cmd/test/longhelp.txt new file mode 100644 index 00000000..d1204210 --- /dev/null +++ b/internal/cmd/test/longhelp.txt @@ -0,0 +1,13 @@ +Runs the Buffalo tests. This command sets the GO_ENV to be `test` +and sets up the database in preparation for the tests. + + --force-migrations forces the migrations to run even if the schema.sql is found + in the migrations folder + + -testify.m Only run tests matching the regular expression + -m Only run tests matching the regular expression + +The value passed to the -run flag is also passed to the -testify.m flag. +Any other flag is directly passed to the `go test` command. + + \ No newline at end of file diff --git a/internal/cmd/test/test.go b/internal/cmd/test/test.go index 6e8a139d..ba5219ef 100644 --- a/internal/cmd/test/test.go +++ b/internal/cmd/test/test.go @@ -1,6 +1,8 @@ package test import ( + _ "embed" + "fmt" "os" "strings" @@ -8,38 +10,37 @@ import ( "github.com/spf13/cobra" ) -var cmd = &cobra.Command{ - Use: "test", - Short: "Runs tests for your Buffalo app", - Long: ``, - - // DisableFlagParsing is set to true since we will need to allow undefined - // flags to be passed to the go test command. - DisableFlagParsing: true, - - RunE: func(c *cobra.Command, args []string) error { - // Set the environment to be test so that the rest of the tooling - // understands we're in testing mode. - if err := os.Setenv("GO_ENV", "test"); err != nil { - return err - } - - // Setup the database before running the tests. - if err := setupDatabase(args); err != nil { - return err - } - - tcmd, err := buildCmd(args) - if err != nil { - return err - } - - fmt.Println("[INFO]", strings.Join(tcmd.Args, " ")) - return tcmd.Run() - }, -} - -// TODO: Remove me -func Cmd() *cobra.Command { - return cmd -} +var ( + //go:embed longhelp.txt + longHelp string + Cmd = &cobra.Command{ + Use: "test", + Short: "Runs tests for your Buffalo app", + Long: longHelp, + + // DisableFlagParsing is set to true since we will need to allow undefined + // flags to be passed to the go test command. + DisableFlagParsing: true, + + RunE: func(c *cobra.Command, args []string) error { + // Set the environment to be test so that the rest of the tooling + // understands we're in testing mode. + if err := os.Setenv("GO_ENV", "test"); err != nil { + return err + } + + // Setup the database before running the tests. + if err := setupDatabase(args); err != nil { + return err + } + + tcmd, err := buildCmd(args) + if err != nil { + return err + } + + fmt.Println("[INFO]", strings.Join(tcmd.Args, " ")) + return tcmd.Run() + }, + } +)