diff --git a/features/outline.feature b/features/outline.feature index 21ebd8d..7c4f92e 100644 --- a/features/outline.feature +++ b/features/outline.feature @@ -98,3 +98,55 @@ Feature: run outline """ a failing step """ + + Scenario: should translate step table body + Given a feature "normal.feature" file: + """ + Feature: outline + + Background: + Given I'm listening to suite events + + Scenario Outline: run with events + Given a feature path "" + When I run feature suite + Then these events had to be fired for a number of times: + | BeforeScenario | | + | BeforeStep | | + + Examples: + | path | scen | step | + | features/load.feature:6 | 1 | 3 | + | features/load.feature | 6 | 19 | + """ + When I run feature suite + Then the suite should have passed + And the following steps should be passed: + """ + I'm listening to suite events + I run feature suite + a feature path "features/load.feature:6" + a feature path "features/load.feature" + """ + + Scenario Outline: should translate step doc string argument + Given a feature "normal.feature" file: + """ + Feature: scenario events + + Background: + Given I'm listening to suite events + + Scenario: run with events + Given a feature path "" + When I run feature suite + Then these events had to be fired for a number of times: + | BeforeScenario | | + """ + When I run feature suite + Then the suite should have passed + + Examples: + | path | scen | + | features/load.feature:6 | 1 | + | features/load.feature | 6 | diff --git a/fmt_pretty.go b/fmt_pretty.go index 7b713df..1bfdba1 100644 --- a/fmt_pretty.go +++ b/fmt_pretty.go @@ -38,9 +38,10 @@ type pretty struct { outline *gherkin.ScenarioOutline // state - bgSteps int - steps int - commentPos int + bgSteps int + totalBgSteps int + steps int + commentPos int // whether scenario or scenario outline keyword was printed scenarioKeyword bool @@ -68,8 +69,10 @@ func (f *pretty) Feature(ft *gherkin.Feature, p string, c []byte) { f.scenario = nil f.outline = nil f.bgSteps = 0 + f.totalBgSteps = 0 if ft.Background != nil { f.bgSteps = len(ft.Background.Steps) + f.totalBgSteps = len(ft.Background.Steps) } } @@ -84,7 +87,7 @@ func (f *pretty) Node(node interface{}) { case *gherkin.Scenario: f.scenario = t f.outline = nil - f.steps = len(t.Steps) + f.bgSteps + f.steps = len(t.Steps) + f.totalBgSteps f.scenarioKeyword = false case *gherkin.ScenarioOutline: f.outline = t @@ -92,7 +95,7 @@ func (f *pretty) Node(node interface{}) { f.outlineNumExample = -1 f.scenarioKeyword = false case *gherkin.TableRow: - f.steps = len(f.outline.Steps) + f.bgSteps + f.steps = len(f.outline.Steps) + f.totalBgSteps f.outlineSteps = []*stepResult{} } } @@ -157,10 +160,10 @@ func (f *pretty) printOutlineExample(outline *gherkin.ScenarioOutline) { case res.typ == skipped && clr == nil: clr = cyan } - if printSteps { + if printSteps && i >= f.totalBgSteps { // in first example, we need to print steps var text string - ostep := outline.Steps[i] + ostep := outline.Steps[i-f.totalBgSteps] if res.def != nil { if m := outlinePlaceholderRegexp.FindAllStringIndex(ostep.Text, -1); len(m) > 0 { var pos int @@ -180,6 +183,23 @@ func (f *pretty) printOutlineExample(outline *gherkin.ScenarioOutline) { } // print the step outline fmt.Fprintln(f.out, s(f.indent*2)+cyan(strings.TrimSpace(ostep.Keyword))+" "+text) + + // print step argument + // @TODO: need to make example header cells bold + switch t := ostep.Argument.(type) { + case *gherkin.DataTable: + f.printTable(t, cyan) + case *gherkin.DocString: + var ct string + if len(t.ContentType) > 0 { + ct = " " + cyan(t.ContentType) + } + fmt.Fprintln(f.out, s(f.indent*3)+cyan(t.Delimitter)+ct) + for _, ln := range strings.Split(t.Content, "\n") { + fmt.Fprintln(f.out, s(f.indent*3)+cyan(ln)) + } + fmt.Fprintln(f.out, s(f.indent*3)+cyan(t.Delimitter)) + } } } @@ -256,6 +276,11 @@ func (f *pretty) printStep(step *gherkin.Step, def *StepDef, c colors.ColorFunc) } func (f *pretty) printStepKind(res *stepResult) { + f.steps-- + if f.outline != nil { + f.outlineSteps = append(f.outlineSteps, res) + } + // if has not printed background yet switch { // first background step @@ -281,12 +306,8 @@ func (f *pretty) printStepKind(res *stepResult) { fmt.Fprintln(f.out, "\n"+text) f.scenarioKeyword = true } - f.steps-- // first step of outline scenario, print header and calculate comment position case f.outline != nil: - f.outlineSteps = append(f.outlineSteps, res) - f.steps-- - // print scenario keyword and value if first example if !f.scenarioKeyword { f.commentPos = f.longestStep(f.outline.Steps, f.length(f.outline)) @@ -300,7 +321,7 @@ func (f *pretty) printStepKind(res *stepResult) { fmt.Fprintln(f.out, "\n"+text) f.scenarioKeyword = true } - if len(f.outlineSteps) == len(f.outline.Steps)+f.bgSteps { + if len(f.outlineSteps) == len(f.outline.Steps)+f.totalBgSteps { // an outline example steps has went through f.printOutlineExample(f.outline) f.outlineNumExamples-- diff --git a/godog.go b/godog.go index 1cc603b..8d093a4 100644 --- a/godog.go +++ b/godog.go @@ -39,4 +39,4 @@ Godog was inspired by Behat and Cucumber the above description is taken from it' package godog // Version of package - based on Semantic Versioning 2.0.0 http://semver.org/ -const Version = "v0.7.2" +const Version = "v0.7.3" diff --git a/suite.go b/suite.go index d3739b3..9f3ad81 100644 --- a/suite.go +++ b/suite.go @@ -405,12 +405,52 @@ func (s *Suite) runOutline(outline *gherkin.ScenarioOutline, b *gherkin.Backgrou for i, placeholder := range placeholders { text = strings.Replace(text, "<"+placeholder.Value+">", group.Cells[i].Value, -1) } + + // translate argument + arg := outlineStep.Argument + switch t := outlineStep.Argument.(type) { + case *gherkin.DataTable: + tbl := &gherkin.DataTable{ + Node: t.Node, + Rows: make([]*gherkin.TableRow, len(t.Rows)), + } + for i, row := range t.Rows { + cells := make([]*gherkin.TableCell, len(row.Cells)) + for j, cell := range row.Cells { + trans := cell.Value + for i, placeholder := range placeholders { + trans = strings.Replace(trans, "<"+placeholder.Value+">", group.Cells[i].Value, -1) + } + cells[j] = &gherkin.TableCell{ + Node: cell.Node, + Value: trans, + } + } + tbl.Rows[i] = &gherkin.TableRow{ + Node: row.Node, + Cells: cells, + } + } + arg = tbl + case *gherkin.DocString: + trans := t.Content + for i, placeholder := range placeholders { + trans = strings.Replace(trans, "<"+placeholder.Value+">", group.Cells[i].Value, -1) + } + arg = &gherkin.DocString{ + Node: t.Node, + Content: trans, + ContentType: t.ContentType, + Delimitter: t.Delimitter, + } + } + // clone a step step := &gherkin.Step{ Node: outlineStep.Node, Text: text, Keyword: outlineStep.Keyword, - Argument: outlineStep.Argument, + Argument: arg, } steps = append(steps, step) }