From f9aabcdc5814beeba3111b7a7931f9acc57a7bbc Mon Sep 17 00:00:00 2001 From: gedi Date: Sun, 4 Mar 2018 12:17:12 +0200 Subject: [PATCH] common failed scenario output for progress and pretty format: #113 --- fmt.go | 48 ++++++++++++++++++++++++++++++++++++++++++++ fmt_pretty.go | 34 ++++++------------------------- fmt_progress.go | 1 + fmt_progress_test.go | 8 ++++++-- 4 files changed, 61 insertions(+), 30 deletions(-) diff --git a/fmt.go b/fmt.go index f1241ec..5251bb2 100644 --- a/fmt.go +++ b/fmt.go @@ -161,6 +161,54 @@ func (f stepResult) line() string { return fmt.Sprintf("%s:%d", f.feature.Path, f.step.Location.Line) } +func (f stepResult) scenarioDesc() string { + if sc, ok := f.owner.(*gherkin.Scenario); ok { + return fmt.Sprintf("%s: %s", sc.Keyword, sc.Name) + } + + if row, ok := f.owner.(*gherkin.TableRow); ok { + for _, def := range f.feature.Feature.ScenarioDefinitions { + out, ok := def.(*gherkin.ScenarioOutline) + if !ok { + continue + } + + for _, ex := range out.Examples { + for _, rw := range ex.TableBody { + if rw.Location.Line == row.Location.Line { + return fmt.Sprintf("%s: %s", out.Keyword, out.Name) + } + } + } + } + } + return f.line() // was not expecting different owner +} + +func (f stepResult) scenarioLine() string { + if sc, ok := f.owner.(*gherkin.Scenario); ok { + return fmt.Sprintf("%s:%d", f.feature.Path, sc.Location.Line) + } + + if row, ok := f.owner.(*gherkin.TableRow); ok { + for _, def := range f.feature.Feature.ScenarioDefinitions { + out, ok := def.(*gherkin.ScenarioOutline) + if !ok { + continue + } + + for _, ex := range out.Examples { + for _, rw := range ex.TableBody { + if rw.Location.Line == row.Location.Line { + return fmt.Sprintf("%s:%d", f.feature.Path, out.Location.Line) + } + } + } + } + } + return f.line() // was not expecting different owner +} + type basefmt struct { out io.Writer owner interface{} diff --git a/fmt_pretty.go b/fmt_pretty.go index 8718cc9..d304769 100644 --- a/fmt_pretty.go +++ b/fmt_pretty.go @@ -120,34 +120,12 @@ func (f *pretty) printUndefinedScenario(sc *gherkin.Scenario) { // Summary sumarize the feature formatter output func (f *pretty) Summary() { - // failed steps on background are not scenarios - var failedScenarios []*stepResult - for _, fail := range f.failed { - switch fail.owner.(type) { - case *gherkin.Scenario: - failedScenarios = append(failedScenarios, fail) - case *gherkin.TableRow: - failedScenarios = append(failedScenarios, fail) - } - } - if len(failedScenarios) > 0 { - fmt.Fprintln(f.out, "\n--- "+red("Failed scenarios:")+"\n") - var unique []string - for _, fail := range failedScenarios { - var found bool - for _, in := range unique { - if in == fail.line() { - found = true - break - } - } - if !found { - unique = append(unique, fail.line()) - } - } - - for _, fail := range unique { - fmt.Fprintln(f.out, " "+red(fail)) + if len(f.failed) > 0 { + fmt.Fprintln(f.out, "\n--- "+red("Failed steps:")+"\n") + for _, fail := range f.failed { + fmt.Fprintln(f.out, s(2)+red(fail.scenarioDesc())+black(" # "+fail.scenarioLine())) + fmt.Fprintln(f.out, s(4)+red(strings.TrimSpace(fail.step.Keyword)+" "+fail.step.Text)+black(" # "+fail.line())) + fmt.Fprintln(f.out, s(6)+red("Error: ")+redb(fmt.Sprintf("%+v", fail.err))+"\n") } } f.basefmt.Summary() diff --git a/fmt_progress.go b/fmt_progress.go index 7bb8650..a63e474 100644 --- a/fmt_progress.go +++ b/fmt_progress.go @@ -58,6 +58,7 @@ func (f *progress) Summary() { if len(f.failed) > 0 { fmt.Fprintln(f.out, "\n--- "+red("Failed steps:")+"\n") for _, fail := range f.failed { + fmt.Fprintln(f.out, s(2)+red(fail.scenarioDesc())+black(" # "+fail.scenarioLine())) fmt.Fprintln(f.out, s(4)+red(strings.TrimSpace(fail.step.Keyword)+" "+fail.step.Text)+black(" # "+fail.line())) fmt.Fprintln(f.out, s(6)+red("Error: ")+redb(fmt.Sprintf("%+v", fail.err))+"\n") } diff --git a/fmt_progress_test.go b/fmt_progress_test.go index d34a3af..e55983d 100644 --- a/fmt_progress_test.go +++ b/fmt_progress_test.go @@ -41,10 +41,12 @@ func TestProgressFormatterOutput(t *testing.T) { --- Failed steps: + Scenario: failing scenario # any.feature:10 When failing # any.feature:11 Error: errored - When failing # any.feature:24 + Scenario Outline: outline # any.feature:22 + When failing # any.feature:24 Error: errored @@ -118,7 +120,7 @@ func TestProgressFormatterWhenStepPanics(t *testing.T) { } out := buf.String() - if idx := strings.Index(out, "github.com/DATA-DOG/godog/fmt_progress_test.go:116"); idx == -1 { + if idx := strings.Index(out, "github.com/DATA-DOG/godog/fmt_progress_test.go:114"); idx == -1 { t.Fatalf("expected to find panic stacktrace, actual:\n%s", out) } } @@ -178,6 +180,7 @@ func TestProgressFormatterWithFailingMultisteps(t *testing.T) { --- Failed steps: +Scenario: passing scenario # some.feature:4 Then two # some.feature:6 Error: sub2: sub-sub: errored @@ -385,6 +388,7 @@ Feature: basic --- Failed steps: + Scenario: passing scenario # :4 Then two # :6 Error: nested steps cannot be multiline and have table or content body argument