do not fire events when feature or scenario is empty
Этот коммит содержится в:
родитель
df188464c6
коммит
272624afcc
4 изменённых файлов: 131 добавлений и 12 удалений
|
@ -51,3 +51,50 @@ Feature: suite events
|
|||
| AfterFeature | 2 |
|
||||
| AfterSuite | 1 |
|
||||
|
||||
Scenario: should not trigger events on empty feature
|
||||
Given a feature "normal.feature" file:
|
||||
"""
|
||||
Feature: empty
|
||||
|
||||
Scenario: one
|
||||
|
||||
Scenario: two
|
||||
"""
|
||||
When I run feature suite
|
||||
Then these events had to be fired for a number of times:
|
||||
| BeforeSuite | 1 |
|
||||
| BeforeFeature | 0 |
|
||||
| BeforeScenario | 0 |
|
||||
| BeforeStep | 0 |
|
||||
| AfterStep | 0 |
|
||||
| AfterScenario | 0 |
|
||||
| AfterFeature | 0 |
|
||||
| AfterSuite | 1 |
|
||||
|
||||
Scenario: should not trigger events on empty scenarios
|
||||
Given a feature "normal.feature" file:
|
||||
"""
|
||||
Feature: half empty
|
||||
|
||||
Scenario: one
|
||||
|
||||
Scenario: two
|
||||
Then passing step
|
||||
|
||||
Scenario Outline: three
|
||||
Then passing step
|
||||
|
||||
Examples:
|
||||
| a |
|
||||
| 1 |
|
||||
"""
|
||||
When I run feature suite
|
||||
Then these events had to be fired for a number of times:
|
||||
| BeforeSuite | 1 |
|
||||
| BeforeFeature | 1 |
|
||||
| BeforeScenario | 2 |
|
||||
| BeforeStep | 2 |
|
||||
| AfterStep | 2 |
|
||||
| AfterScenario | 2 |
|
||||
| AfterFeature | 1 |
|
||||
| AfterSuite | 1 |
|
||||
|
|
|
@ -89,6 +89,9 @@ func (f *pretty) Node(node interface{}) {
|
|||
f.outline = nil
|
||||
f.steps = len(t.Steps) + f.totalBgSteps
|
||||
f.scenarioKeyword = false
|
||||
if isEmptyScenario(t) {
|
||||
f.printUndefinedScenario(t)
|
||||
}
|
||||
case *gherkin.ScenarioOutline:
|
||||
f.outline = t
|
||||
f.scenario = nil
|
||||
|
@ -100,6 +103,21 @@ func (f *pretty) Node(node interface{}) {
|
|||
}
|
||||
}
|
||||
|
||||
func (f *pretty) printUndefinedScenario(sc *gherkin.Scenario) {
|
||||
if f.bgSteps > 0 {
|
||||
f.commentPos = f.longestStep(f.feature.Background.Steps, f.length(f.feature.Background))
|
||||
fmt.Fprintln(f.out, "\n"+s(f.indent)+whiteb(f.feature.Background.Keyword+": "+f.feature.Background.Name))
|
||||
|
||||
for _, step := range f.feature.Background.Steps {
|
||||
f.bgSteps--
|
||||
f.printStep(step, nil, colors.Cyan)
|
||||
}
|
||||
}
|
||||
text := s(f.indent) + whiteb(f.scenario.Keyword+": ") + sc.Name
|
||||
text += s(f.commentPos-f.length(f.scenario)+1) + f.line(sc.Location)
|
||||
fmt.Fprintln(f.out, "\n"+text)
|
||||
}
|
||||
|
||||
// Summary sumarize the feature formatter output
|
||||
func (f *pretty) Summary() {
|
||||
// failed steps on background are not scenarios
|
||||
|
@ -284,6 +302,7 @@ func (f *pretty) printStepKind(res *stepResult) {
|
|||
if f.outline != nil {
|
||||
f.outlineSteps = append(f.outlineSteps, res)
|
||||
}
|
||||
var bgStep bool
|
||||
|
||||
// if has not printed background yet
|
||||
switch {
|
||||
|
@ -292,9 +311,11 @@ func (f *pretty) printStepKind(res *stepResult) {
|
|||
f.commentPos = f.longestStep(f.feature.Background.Steps, f.length(f.feature.Background))
|
||||
fmt.Fprintln(f.out, "\n"+s(f.indent)+whiteb(f.feature.Background.Keyword+": "+f.feature.Background.Name))
|
||||
f.bgSteps--
|
||||
bgStep = true
|
||||
// subsequent background steps
|
||||
case f.bgSteps > 0:
|
||||
f.bgSteps--
|
||||
bgStep = true
|
||||
// first step of scenario, print header and calculate comment position
|
||||
case f.scenario != nil:
|
||||
// print scenario keyword and value if first example
|
||||
|
@ -333,7 +354,9 @@ func (f *pretty) printStepKind(res *stepResult) {
|
|||
return
|
||||
}
|
||||
|
||||
if !f.isBackgroundStep(res.step) || bgStep {
|
||||
f.printStep(res.step, res.def, res.typ.clr())
|
||||
}
|
||||
if res.err != nil {
|
||||
fmt.Fprintln(f.out, s(f.indent*2)+redb(fmt.Sprintf("%+v", res.err)))
|
||||
}
|
||||
|
@ -342,6 +365,19 @@ func (f *pretty) printStepKind(res *stepResult) {
|
|||
}
|
||||
}
|
||||
|
||||
func (f *pretty) isBackgroundStep(step *gherkin.Step) bool {
|
||||
if f.feature.Background == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, bstep := range f.feature.Background.Steps {
|
||||
if bstep.Location.Line == step.Location.Line {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// print table with aligned table cells
|
||||
func (f *pretty) printTable(t *gherkin.DataTable, c colors.ColorFunc) {
|
||||
var l = longest(t, c)
|
||||
|
|
25
gherkin.go
25
gherkin.go
|
@ -9,3 +9,28 @@ func examples(ex interface{}) (*gherkin.Examples, bool) {
|
|||
t, ok := ex.(*gherkin.Examples)
|
||||
return t, ok
|
||||
}
|
||||
|
||||
// means there are no scenarios or they do not have steps
|
||||
func isEmptyFeature(ft *gherkin.Feature) bool {
|
||||
for _, def := range ft.ScenarioDefinitions {
|
||||
if !isEmptyScenario(def) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// means scenario dooes not have steps
|
||||
func isEmptyScenario(def interface{}) bool {
|
||||
switch t := def.(type) {
|
||||
case *gherkin.Scenario:
|
||||
if len(t.Steps) > 0 {
|
||||
return false
|
||||
}
|
||||
case *gherkin.ScenarioOutline:
|
||||
if len(t.Steps) > 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
15
suite.go
15
suite.go
|
@ -425,9 +425,11 @@ func (s *Suite) runOutline(outline *gherkin.ScenarioOutline, b *gherkin.Backgrou
|
|||
groups := example.TableBody
|
||||
|
||||
for _, group := range groups {
|
||||
if !isEmptyScenario(outline) {
|
||||
for _, f := range s.beforeScenarioHandlers {
|
||||
f(outline)
|
||||
}
|
||||
}
|
||||
var steps []*gherkin.Step
|
||||
for _, outlineStep := range outline.Steps {
|
||||
text := outlineStep.Text
|
||||
|
@ -493,9 +495,11 @@ func (s *Suite) runOutline(outline *gherkin.ScenarioOutline, b *gherkin.Backgrou
|
|||
|
||||
err := s.runSteps(steps)
|
||||
|
||||
if !isEmptyScenario(outline) {
|
||||
for _, f := range s.afterScenarioHandlers {
|
||||
f(outline, err)
|
||||
}
|
||||
}
|
||||
|
||||
if s.shouldFail(err) {
|
||||
failErr = err
|
||||
|
@ -521,9 +525,11 @@ func (s *Suite) shouldFail(err error) bool {
|
|||
}
|
||||
|
||||
func (s *Suite) runFeature(f *feature) {
|
||||
if !isEmptyFeature(f.Feature) {
|
||||
for _, fn := range s.beforeFeatureHandlers {
|
||||
fn(f.Feature)
|
||||
}
|
||||
}
|
||||
|
||||
s.fmt.Feature(f.Feature, f.Path, f.Content)
|
||||
|
||||
|
@ -541,9 +547,11 @@ func (s *Suite) runFeature(f *feature) {
|
|||
}
|
||||
|
||||
defer func() {
|
||||
if !isEmptyFeature(f.Feature) {
|
||||
for _, fn := range s.afterFeatureHandlers {
|
||||
fn(f.Feature)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for _, scenario := range scenarios {
|
||||
|
@ -567,6 +575,11 @@ func (s *Suite) runFeature(f *feature) {
|
|||
}
|
||||
|
||||
func (s *Suite) runScenario(scenario *gherkin.Scenario, b *gherkin.Background) (err error) {
|
||||
if isEmptyScenario(scenario) {
|
||||
s.fmt.Node(scenario)
|
||||
return ErrUndefined
|
||||
}
|
||||
|
||||
// run before scenario handlers
|
||||
for _, f := range s.beforeScenarioHandlers {
|
||||
f(scenario)
|
||||
|
@ -704,10 +717,8 @@ func filterFeatures(tags string, collected map[string]*feature) (features []*fea
|
|||
ft.ScenarioDefinitions = scenarios
|
||||
applyTagFilter(tags, ft.Feature)
|
||||
|
||||
if len(ft.ScenarioDefinitions) > 0 {
|
||||
features = append(features, ft)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(sortByOrderGiven(features))
|
||||
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче