From 84c5567a10d0fed3b8531b84fa5e3f82af0a851d Mon Sep 17 00:00:00 2001 From: gedi Date: Mon, 15 Jun 2015 17:50:17 +0300 Subject: [PATCH] progress with pretty formatter --- features/suite.feature | 2 +- formatter.go | 89 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/features/suite.feature b/features/suite.feature index 68f7180..71188b0 100644 --- a/features/suite.feature +++ b/features/suite.feature @@ -6,4 +6,4 @@ Feature: godog bdd suite Scenario: parses all features in path Given a feature path "features" When I parse features - Then I should have 1 feature file + Then I should have 5 feature file diff --git a/formatter.go b/formatter.go index 7a54d29..6990849 100644 --- a/formatter.go +++ b/formatter.go @@ -3,6 +3,8 @@ package godog import ( "fmt" "math" + "reflect" + "runtime" "strings" "github.com/DATA-DOG/godog/gherkin" @@ -19,17 +21,51 @@ type Formatter interface { Passed(*gherkin.Step, *stepMatchHandler) Skipped(*gherkin.Step) Pending(*gherkin.Step) + Summary() } type pretty struct { feature *gherkin.Feature scenario *gherkin.Scenario + commentPos int doneBackground bool background *gherkin.Background + + // summary + features []*gherkin.Feature + failures []*failed + passes []*passed + skips []*skipped + pendings []*pending +} + +type failed struct { + feature *gherkin.Feature + scenario *gherkin.Scenario + step *gherkin.Step + err error +} + +type passed struct { + feature *gherkin.Feature + scenario *gherkin.Scenario + step *gherkin.Step +} + +type skipped struct { + feature *gherkin.Feature + scenario *gherkin.Scenario + step *gherkin.Step +} + +type pending struct { + feature *gherkin.Feature + scenario *gherkin.Scenario + step *gherkin.Step } func (f *pretty) line(tok *gherkin.Token) string { - return cl(fmt.Sprintf("#%s:%d", f.feature.Path, tok.Line), magenta) + return cl(fmt.Sprintf("# %s:%d", f.feature.Path, tok.Line), black) } func (f *pretty) canPrintStep(step *gherkin.Step) bool { @@ -53,6 +89,11 @@ func (f *pretty) canPrintStep(step *gherkin.Step) bool { return !f.doneBackground } +func (f *pretty) comment(text, comment string) string { + indent := f.commentPos - len(text) + 1 + return text + strings.Repeat(" ", indent) + comment +} + func (f *pretty) Node(node interface{}) { switch t := node.(type) { case *gherkin.Feature: @@ -60,17 +101,30 @@ func (f *pretty) Node(node interface{}) { f.doneBackground = false f.scenario = nil f.background = nil - fmt.Println("\n"+bcl("Feature: ", white)+t.Title, f.line(t.Token)) + f.features = append(f.features, t) + fmt.Println("\n" + bcl("Feature: ", white) + t.Title) fmt.Println(t.Description) case *gherkin.Background: f.background = t fmt.Println("\n" + bcl("Background:", white)) case *gherkin.Scenario: f.scenario = t - fmt.Println("\n"+strings.Repeat(" ", t.Token.Indent)+bcl("Scenario: ", white)+t.Title, f.line(t.Token)) + f.commentPos = len(t.Token.Text) + for _, step := range t.Steps { + if len(step.Token.Text) > f.commentPos { + f.commentPos = len(step.Token.Text) + } + } + text := strings.Repeat(" ", t.Token.Indent) + bcl("Scenario: ", white) + t.Title + text += strings.Repeat(" ", f.commentPos-len(t.Token.Text)+1) + f.line(t.Token) + fmt.Println("\n" + text) } } +func (f *pretty) Summary() { + +} + func (f *pretty) printMatchedStep(step *gherkin.Step, match *stepMatchHandler, c color) { if !f.canPrintStep(step) { return @@ -91,6 +145,9 @@ func (f *pretty) printMatchedStep(step *gherkin.Step, match *stepMatchHandler, c text = cl(step.Text, c) } + // use reflect to get step handler function name + name := runtime.FuncForPC(reflect.ValueOf(match.handler).Pointer()).Name() + switch step.Token.Type { case gherkin.GIVEN: text = cl("Given", c) + " " + text @@ -103,25 +160,49 @@ func (f *pretty) printMatchedStep(step *gherkin.Step, match *stepMatchHandler, c case gherkin.BUT: text = cl("But", c) + " " + text } - fmt.Println(strings.Repeat(" ", step.Token.Indent) + text) + text = strings.Repeat(" ", step.Token.Indent) + text + text += strings.Repeat(" ", f.commentPos-len(step.Token.Text)+1) + cl(fmt.Sprintf("# %s", name), black) + fmt.Println(text) } func (f *pretty) Passed(step *gherkin.Step, match *stepMatchHandler) { f.printMatchedStep(step, match, green) + f.passes = append(f.passes, &passed{ + feature: f.feature, + scenario: f.scenario, + step: step, + }) } func (f *pretty) Skipped(step *gherkin.Step) { if f.canPrintStep(step) { fmt.Println(cl(step.Token.Text, cyan)) } + f.skips = append(f.skips, &skipped{ + feature: f.feature, + scenario: f.scenario, + step: step, + }) } func (f *pretty) Pending(step *gherkin.Step) { if f.canPrintStep(step) { fmt.Println(cl(step.Token.Text, yellow)) } + f.pendings = append(f.pendings, &pending{ + feature: f.feature, + scenario: f.scenario, + step: step, + }) } func (f *pretty) Failed(step *gherkin.Step, match *stepMatchHandler, err error) { f.printMatchedStep(step, match, red) + fmt.Println(strings.Repeat(" ", step.Token.Indent) + bcl(err, red)) + f.failures = append(f.failures, &failed{ + feature: f.feature, + scenario: f.scenario, + step: step, + err: err, + }) }