diff --git a/fmt.go b/fmt.go index 0123969..a51a47f 100644 --- a/fmt.go +++ b/fmt.go @@ -53,20 +53,13 @@ type registeredFormatter struct { var formatters []*registeredFormatter -func findFmt(format string) (f FormatterFunc, err error) { - var names []string +func findFmt(format string) FormatterFunc { for _, el := range formatters { if el.name == format { - f = el.fmt - break + return el.fmt } - names = append(names, el.name) } - - if f == nil { - err = fmt.Errorf(`unregistered formatter name: "%s", use one of: %s`, format, strings.Join(names, ", ")) - } - return + return nil } // Format registers a feature suite output diff --git a/fmt_test.go b/fmt_test.go index a6604bb..8eae1e5 100644 --- a/fmt_test.go +++ b/fmt_test.go @@ -2,6 +2,7 @@ package godog import ( "io" + "testing" "github.com/DATA-DOG/godog/gherkin" ) @@ -32,3 +33,25 @@ func (f *testFormatter) Node(node interface{}) { } func (f *testFormatter) Summary() {} + +func TestShouldFindFormatter(t *testing.T) { + cases := map[string]bool{ + "progress": true, // true means should be available + "unknown": false, + "junit": true, + "cucumber": true, + "pretty": true, + "custom": true, // is available for test purposes only + "undef": false, + } + + for name, shouldFind := range cases { + actual := findFmt(name) + if actual == nil && shouldFind { + t.Fatalf("expected %s formatter should be available", name) + } + if actual != nil && !shouldFind { + t.Fatalf("expected %s formatter should not be available", name) + } + } +} diff --git a/run.go b/run.go index 7ab39e8..2fb9c21 100644 --- a/run.go +++ b/run.go @@ -5,6 +5,7 @@ import ( "io" "os" "strconv" + "strings" "github.com/DATA-DOG/godog/colors" ) @@ -93,7 +94,7 @@ func RunWithOptions(suite string, contextInitializer func(suite *Suite), opt Opt s := &Suite{} contextInitializer(s) s.printStepDefinitions(output) - return 0 + return 2 // showing help or printing definitions, results exit code - 2 } if len(opt.Paths) == 0 { @@ -104,13 +105,28 @@ func RunWithOptions(suite string, contextInitializer func(suite *Suite), opt Opt } if opt.Concurrency > 1 && !supportsConcurrency(opt.Format) { - fatal(fmt.Errorf("format \"%s\" does not support concurrent execution", opt.Format)) + fmt.Fprintln(os.Stderr, fmt.Errorf("format \"%s\" does not support concurrent execution", opt.Format)) + return 1 + } + formatter := findFmt(opt.Format) + if nil == formatter { + var names []string + for name := range AvailableFormatters() { + names = append(names, name) + } + fmt.Fprintln(os.Stderr, fmt.Errorf( + `unregistered formatter name: "%s", use one of: %s`, + opt.Format, + strings.Join(names, ", "), + )) + return 1 } - formatter, err := findFmt(opt.Format) - fatal(err) features, err := parseFeatures(opt.Tags, opt.Paths) - fatal(err) + if err != nil { + fmt.Fprintln(os.Stderr, err) + return 1 + } r := runner{ fmt: formatter(suite, output), @@ -152,8 +168,10 @@ func Run(suite string, contextInitializer func(suite *Suite)) int { var opt Options opt.Output = colors.Colored(os.Stdout) flagSet := FlagSet(&opt) - err := flagSet.Parse(os.Args[1:]) - fatal(err) + if err := flagSet.Parse(os.Args[1:]); err != nil { + fmt.Fprintln(os.Stderr, err) + return 1 + } opt.Paths = flagSet.Args() diff --git a/suite_test.go b/suite_test.go index 29db82f..ba68784 100644 --- a/suite_test.go +++ b/suite_test.go @@ -137,9 +137,9 @@ func (s *suiteContext) ResetBeforeEachScenario(interface{}) { } func (s *suiteContext) iRunFeatureSuiteWithFormatter(name string) error { - f, err := findFmt(name) - if err != nil { - return err + f := findFmt(name) + if f == nil { + return fmt.Errorf(`formatter "%s" is not available`, name) } s.testedSuite.fmt = f("godog", &s.out) if err := s.parseFeatures(); err != nil { diff --git a/utils.go b/utils.go index 989427f..3fb1588 100644 --- a/utils.go +++ b/utils.go @@ -1,8 +1,6 @@ package godog import ( - "fmt" - "os" "strings" "time" @@ -27,14 +25,6 @@ func s(n int) string { return strings.Repeat(" ", n) } -// checks the error and exits with error status code -func fatal(err error) { - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } -} - var timeNowFunc = func() time.Time { return time.Now() }