improve scenario outline tests and behavior
Этот коммит содержится в:
		
							родитель
							
								
									996d3d2725
								
							
						
					
					
						коммит
						5829b59e80
					
				
					 10 изменённых файлов: 312 добавлений и 161 удалений
				
			
		
							
								
								
									
										4
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -2,8 +2,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# runs all necessary tests
 | 
					# runs all necessary tests
 | 
				
			||||||
test:
 | 
					test:
 | 
				
			||||||
	@sh -c 'if [ ! -z "$(go fmt ./...)" ]; then exit 1; fi'
 | 
						@sh -c 'if [ ! -z "$(go fmt ./...)" ]; then exit 1; else echo "go fmt OK"; fi'
 | 
				
			||||||
	golint ./...
 | 
						@sh -c 'if [ ! -z "$(golint ./...)" ]; then exit 1; else echo "golint OK"; fi'
 | 
				
			||||||
	go vet ./...
 | 
						go vet ./...
 | 
				
			||||||
	go test ./...
 | 
						go test ./...
 | 
				
			||||||
	go run cmd/godog/main.go -f progress
 | 
						go run cmd/godog/main.go -f progress
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										75
									
								
								features/background.feature
									
										
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										75
									
								
								features/background.feature
									
										
									
									
									
										Обычный файл
									
								
							| 
						 | 
					@ -0,0 +1,75 @@
 | 
				
			||||||
 | 
					Feature: run background
 | 
				
			||||||
 | 
					  In order to test application behavior
 | 
				
			||||||
 | 
					  As a test suite
 | 
				
			||||||
 | 
					  I need to be able to run background correctly
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: should run background steps
 | 
				
			||||||
 | 
					    Given a feature "normal.feature" file:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      Feature: with background
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Background:
 | 
				
			||||||
 | 
					          Given a feature path "features/load.feature:6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Scenario: parse a scenario
 | 
				
			||||||
 | 
					          When I parse features
 | 
				
			||||||
 | 
					          Then I should have 1 scenario registered
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					    When I run feature suite
 | 
				
			||||||
 | 
					    Then the suite should have passed
 | 
				
			||||||
 | 
					    And the following steps should be passed:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      a feature path "features/load.feature:6"
 | 
				
			||||||
 | 
					      I parse features
 | 
				
			||||||
 | 
					      I should have 1 scenario registered
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: should skip all consequent steps on failure
 | 
				
			||||||
 | 
					    Given a feature "normal.feature" file:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      Feature: with background
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Background:
 | 
				
			||||||
 | 
					          Given a failing step
 | 
				
			||||||
 | 
					          And a feature path "features/load.feature:6"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Scenario: parse a scenario
 | 
				
			||||||
 | 
					          When I parse features
 | 
				
			||||||
 | 
					          Then I should have 1 scenario registered
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					    When I run feature suite
 | 
				
			||||||
 | 
					    Then the suite should have failed
 | 
				
			||||||
 | 
					    And the following steps should be failed:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      a failing step
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					    And the following steps should be skipped:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      a feature path "features/load.feature:6"
 | 
				
			||||||
 | 
					      I parse features
 | 
				
			||||||
 | 
					      I should have 1 scenario registered
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: should continue undefined steps
 | 
				
			||||||
 | 
					    Given a feature "normal.feature" file:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      Feature: with background
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Background:
 | 
				
			||||||
 | 
					          Given an undefined step
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Scenario: parse a scenario
 | 
				
			||||||
 | 
					          When I do undefined action
 | 
				
			||||||
 | 
					          Then I should have 1 scenario registered
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					    When I run feature suite
 | 
				
			||||||
 | 
					    Then the suite should have passed
 | 
				
			||||||
 | 
					    And the following steps should be undefined:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      an undefined step
 | 
				
			||||||
 | 
					      I do undefined action
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					    And the following steps should be skipped:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      I should have 1 scenario registered
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
| 
						 | 
					@ -8,10 +8,12 @@ Savybė: užkrauti savybes
 | 
				
			||||||
  Scenarijus: savybių užkrovimas iš aplanko
 | 
					  Scenarijus: savybių užkrovimas iš aplanko
 | 
				
			||||||
    Duota savybių aplankas "features"
 | 
					    Duota savybių aplankas "features"
 | 
				
			||||||
    Kai aš išskaitau savybes
 | 
					    Kai aš išskaitau savybes
 | 
				
			||||||
    Tada aš turėčiau turėti 4 savybių failus:
 | 
					    Tada aš turėčiau turėti 6 savybių failus:
 | 
				
			||||||
      """
 | 
					      """
 | 
				
			||||||
 | 
					      features/background.feature
 | 
				
			||||||
      features/events.feature
 | 
					      features/events.feature
 | 
				
			||||||
      features/lang.feature
 | 
					      features/lang.feature
 | 
				
			||||||
      features/load.feature
 | 
					      features/load.feature
 | 
				
			||||||
 | 
					      features/outline.feature
 | 
				
			||||||
      features/run.feature
 | 
					      features/run.feature
 | 
				
			||||||
      """
 | 
					      """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,11 +6,13 @@ Feature: load features
 | 
				
			||||||
  Scenario: load features within path
 | 
					  Scenario: load features within path
 | 
				
			||||||
    Given a feature path "features"
 | 
					    Given a feature path "features"
 | 
				
			||||||
    When I parse features
 | 
					    When I parse features
 | 
				
			||||||
    Then I should have 4 feature files:
 | 
					    Then I should have 6 feature files:
 | 
				
			||||||
      """
 | 
					      """
 | 
				
			||||||
 | 
					      features/background.feature
 | 
				
			||||||
      features/events.feature
 | 
					      features/events.feature
 | 
				
			||||||
      features/lang.feature
 | 
					      features/lang.feature
 | 
				
			||||||
      features/load.feature
 | 
					      features/load.feature
 | 
				
			||||||
 | 
					      features/outline.feature
 | 
				
			||||||
      features/run.feature
 | 
					      features/run.feature
 | 
				
			||||||
      """
 | 
					      """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										100
									
								
								features/outline.feature
									
										
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										100
									
								
								features/outline.feature
									
										
									
									
									
										Обычный файл
									
								
							| 
						 | 
					@ -0,0 +1,100 @@
 | 
				
			||||||
 | 
					Feature: run outline
 | 
				
			||||||
 | 
					  In order to test application behavior
 | 
				
			||||||
 | 
					  As a test suite
 | 
				
			||||||
 | 
					  I need to be able to run outline scenarios
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: should run a normal outline
 | 
				
			||||||
 | 
					    Given a feature "normal.feature" file:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      Feature: outline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Background:
 | 
				
			||||||
 | 
					          Given passing step
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Scenario Outline: parse a scenario
 | 
				
			||||||
 | 
					          Given a feature path "<path>"
 | 
				
			||||||
 | 
					          When I parse features
 | 
				
			||||||
 | 
					          Then I should have <num> scenario registered
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          Examples:
 | 
				
			||||||
 | 
					            | path                    | num |
 | 
				
			||||||
 | 
					            | features/load.feature:6 | 1   |
 | 
				
			||||||
 | 
					            | features/load.feature:3 | 0   |
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					    When I run feature suite
 | 
				
			||||||
 | 
					    Then the suite should have passed
 | 
				
			||||||
 | 
					    And the following steps should be passed:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      a passing step
 | 
				
			||||||
 | 
					      I parse features
 | 
				
			||||||
 | 
					      a feature path "features/load.feature:6"
 | 
				
			||||||
 | 
					      a feature path "features/load.feature:3"
 | 
				
			||||||
 | 
					      I should have 1 scenario registered
 | 
				
			||||||
 | 
					      I should have 0 scenario registered
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: should continue through examples on failure
 | 
				
			||||||
 | 
					    Given a feature "normal.feature" file:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      Feature: outline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Background:
 | 
				
			||||||
 | 
					          Given passing step
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Scenario Outline: parse a scenario
 | 
				
			||||||
 | 
					          Given a feature path "<path>"
 | 
				
			||||||
 | 
					          When I parse features
 | 
				
			||||||
 | 
					          Then I should have <num> scenario registered
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          Examples:
 | 
				
			||||||
 | 
					            | path                    | num |
 | 
				
			||||||
 | 
					            | features/load.feature:6 | 5   |
 | 
				
			||||||
 | 
					            | features/load.feature:3 | 0   |
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					    When I run feature suite
 | 
				
			||||||
 | 
					    Then the suite should have failed
 | 
				
			||||||
 | 
					    And the following steps should be passed:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      a passing step
 | 
				
			||||||
 | 
					      I parse features
 | 
				
			||||||
 | 
					      a feature path "features/load.feature:6"
 | 
				
			||||||
 | 
					      a feature path "features/load.feature:3"
 | 
				
			||||||
 | 
					      I should have 0 scenario registered
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					    And the following steps should be failed:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      I should have 5 scenario registered
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: should skip examples on background failure
 | 
				
			||||||
 | 
					    Given a feature "normal.feature" file:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      Feature: outline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Background:
 | 
				
			||||||
 | 
					          Given a failing step
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Scenario Outline: parse a scenario
 | 
				
			||||||
 | 
					          Given a feature path "<path>"
 | 
				
			||||||
 | 
					          When I parse features
 | 
				
			||||||
 | 
					          Then I should have <num> scenario registered
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          Examples:
 | 
				
			||||||
 | 
					            | path                    | num |
 | 
				
			||||||
 | 
					            | features/load.feature:6 | 1   |
 | 
				
			||||||
 | 
					            | features/load.feature:3 | 0   |
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					    When I run feature suite
 | 
				
			||||||
 | 
					    Then the suite should have failed
 | 
				
			||||||
 | 
					    And the following steps should be skipped:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      I parse features
 | 
				
			||||||
 | 
					      a feature path "features/load.feature:6"
 | 
				
			||||||
 | 
					      a feature path "features/load.feature:3"
 | 
				
			||||||
 | 
					      I should have 0 scenario registered
 | 
				
			||||||
 | 
					      I should have 1 scenario registered
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					    And the following steps should be failed:
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
 | 
					      a failing step
 | 
				
			||||||
 | 
					      """
 | 
				
			||||||
							
								
								
									
										113
									
								
								fmt.go
									
										
									
									
									
								
							
							
						
						
									
										113
									
								
								fmt.go
									
										
									
									
									
								
							| 
						 | 
					@ -77,9 +77,31 @@ type Formatter interface {
 | 
				
			||||||
	Summary()
 | 
						Summary()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// failed represents a failed step data structure
 | 
					type stepType int
 | 
				
			||||||
// with all necessary references
 | 
					
 | 
				
			||||||
type failed struct {
 | 
					const (
 | 
				
			||||||
 | 
						passed stepType = iota
 | 
				
			||||||
 | 
						failed
 | 
				
			||||||
 | 
						skipped
 | 
				
			||||||
 | 
						undefined
 | 
				
			||||||
 | 
						pending
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (st stepType) clr() color {
 | 
				
			||||||
 | 
						switch st {
 | 
				
			||||||
 | 
						case passed:
 | 
				
			||||||
 | 
							return green
 | 
				
			||||||
 | 
						case failed:
 | 
				
			||||||
 | 
							return red
 | 
				
			||||||
 | 
						case skipped:
 | 
				
			||||||
 | 
							return cyan
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return yellow
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type stepResult struct {
 | 
				
			||||||
 | 
						typ     stepType
 | 
				
			||||||
	feature *feature
 | 
						feature *feature
 | 
				
			||||||
	owner   interface{}
 | 
						owner   interface{}
 | 
				
			||||||
	step    *gherkin.Step
 | 
						step    *gherkin.Step
 | 
				
			||||||
| 
						 | 
					@ -87,55 +109,21 @@ type failed struct {
 | 
				
			||||||
	err     error
 | 
						err     error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f failed) line() string {
 | 
					func (f stepResult) line() string {
 | 
				
			||||||
	return fmt.Sprintf("%s:%d", f.feature.Path, f.step.Location.Line)
 | 
						return fmt.Sprintf("%s:%d", f.feature.Path, f.step.Location.Line)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// passed represents a successful step data structure
 | 
					 | 
				
			||||||
// with all necessary references
 | 
					 | 
				
			||||||
type passed struct {
 | 
					 | 
				
			||||||
	feature *feature
 | 
					 | 
				
			||||||
	owner   interface{}
 | 
					 | 
				
			||||||
	step    *gherkin.Step
 | 
					 | 
				
			||||||
	def     *StepDef
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// skipped represents a skipped step data structure
 | 
					 | 
				
			||||||
// with all necessary references
 | 
					 | 
				
			||||||
type skipped struct {
 | 
					 | 
				
			||||||
	feature *feature
 | 
					 | 
				
			||||||
	owner   interface{}
 | 
					 | 
				
			||||||
	step    *gherkin.Step
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// undefined represents an undefined step data structure
 | 
					 | 
				
			||||||
// with all necessary references
 | 
					 | 
				
			||||||
type undefined struct {
 | 
					 | 
				
			||||||
	feature *feature
 | 
					 | 
				
			||||||
	owner   interface{}
 | 
					 | 
				
			||||||
	step    *gherkin.Step
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// pending represents a pending step data structure
 | 
					 | 
				
			||||||
// with all necessary references
 | 
					 | 
				
			||||||
type pending struct {
 | 
					 | 
				
			||||||
	feature *feature
 | 
					 | 
				
			||||||
	owner   interface{}
 | 
					 | 
				
			||||||
	step    *gherkin.Step
 | 
					 | 
				
			||||||
	def     *StepDef
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type basefmt struct {
 | 
					type basefmt struct {
 | 
				
			||||||
	owner  interface{}
 | 
						owner  interface{}
 | 
				
			||||||
	indent int
 | 
						indent int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	started   time.Time
 | 
						started   time.Time
 | 
				
			||||||
	features  []*feature
 | 
						features  []*feature
 | 
				
			||||||
	failed    []*failed
 | 
						failed    []*stepResult
 | 
				
			||||||
	passed    []*passed
 | 
						passed    []*stepResult
 | 
				
			||||||
	skipped   []*skipped
 | 
						skipped   []*stepResult
 | 
				
			||||||
	undefined []*undefined
 | 
						undefined []*stepResult
 | 
				
			||||||
	pending   []*pending
 | 
						pending   []*stepResult
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *basefmt) Node(n interface{}) {
 | 
					func (f *basefmt) Node(n interface{}) {
 | 
				
			||||||
| 
						 | 
					@ -154,27 +142,56 @@ func (f *basefmt) Feature(ft *gherkin.Feature, p string) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *basefmt) Passed(step *gherkin.Step, match *StepDef) {
 | 
					func (f *basefmt) Passed(step *gherkin.Step, match *StepDef) {
 | 
				
			||||||
	s := &passed{owner: f.owner, feature: f.features[len(f.features)-1], step: step, def: match}
 | 
						s := &stepResult{
 | 
				
			||||||
 | 
							owner:   f.owner,
 | 
				
			||||||
 | 
							feature: f.features[len(f.features)-1],
 | 
				
			||||||
 | 
							step:    step,
 | 
				
			||||||
 | 
							def:     match,
 | 
				
			||||||
 | 
							typ:     passed,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	f.passed = append(f.passed, s)
 | 
						f.passed = append(f.passed, s)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *basefmt) Skipped(step *gherkin.Step) {
 | 
					func (f *basefmt) Skipped(step *gherkin.Step) {
 | 
				
			||||||
	s := &skipped{owner: f.owner, feature: f.features[len(f.features)-1], step: step}
 | 
						s := &stepResult{
 | 
				
			||||||
 | 
							owner:   f.owner,
 | 
				
			||||||
 | 
							feature: f.features[len(f.features)-1],
 | 
				
			||||||
 | 
							step:    step,
 | 
				
			||||||
 | 
							typ:     skipped,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	f.skipped = append(f.skipped, s)
 | 
						f.skipped = append(f.skipped, s)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *basefmt) Undefined(step *gherkin.Step) {
 | 
					func (f *basefmt) Undefined(step *gherkin.Step) {
 | 
				
			||||||
	s := &undefined{owner: f.owner, feature: f.features[len(f.features)-1], step: step}
 | 
						s := &stepResult{
 | 
				
			||||||
 | 
							owner:   f.owner,
 | 
				
			||||||
 | 
							feature: f.features[len(f.features)-1],
 | 
				
			||||||
 | 
							step:    step,
 | 
				
			||||||
 | 
							typ:     undefined,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	f.undefined = append(f.undefined, s)
 | 
						f.undefined = append(f.undefined, s)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *basefmt) Failed(step *gherkin.Step, match *StepDef, err error) {
 | 
					func (f *basefmt) Failed(step *gherkin.Step, match *StepDef, err error) {
 | 
				
			||||||
	s := &failed{owner: f.owner, feature: f.features[len(f.features)-1], step: step, def: match, err: err}
 | 
						s := &stepResult{
 | 
				
			||||||
 | 
							owner:   f.owner,
 | 
				
			||||||
 | 
							feature: f.features[len(f.features)-1],
 | 
				
			||||||
 | 
							step:    step,
 | 
				
			||||||
 | 
							def:     match,
 | 
				
			||||||
 | 
							err:     err,
 | 
				
			||||||
 | 
							typ:     failed,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	f.failed = append(f.failed, s)
 | 
						f.failed = append(f.failed, s)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *basefmt) Pending(step *gherkin.Step, match *StepDef) {
 | 
					func (f *basefmt) Pending(step *gherkin.Step, match *StepDef) {
 | 
				
			||||||
	s := &pending{owner: f.owner, feature: f.features[len(f.features)-1], step: step, def: match}
 | 
						s := &stepResult{
 | 
				
			||||||
 | 
							owner:   f.owner,
 | 
				
			||||||
 | 
							feature: f.features[len(f.features)-1],
 | 
				
			||||||
 | 
							step:    step,
 | 
				
			||||||
 | 
							def:     match,
 | 
				
			||||||
 | 
							typ:     pending,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	f.pending = append(f.pending, s)
 | 
						f.pending = append(f.pending, s)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ type pretty struct {
 | 
				
			||||||
	backgroundSteps int
 | 
						backgroundSteps int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// outline
 | 
						// outline
 | 
				
			||||||
	outlineSteps       []interface{}
 | 
						outlineSteps       []*stepResult
 | 
				
			||||||
	outlineNumExample  int
 | 
						outlineNumExample  int
 | 
				
			||||||
	outlineNumExamples int
 | 
						outlineNumExamples int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -96,7 +96,7 @@ func (f *pretty) Node(node interface{}) {
 | 
				
			||||||
// Summary sumarize the feature formatter output
 | 
					// Summary sumarize the feature formatter output
 | 
				
			||||||
func (f *pretty) Summary() {
 | 
					func (f *pretty) Summary() {
 | 
				
			||||||
	// failed steps on background are not scenarios
 | 
						// failed steps on background are not scenarios
 | 
				
			||||||
	var failedScenarios []*failed
 | 
						var failedScenarios []*stepResult
 | 
				
			||||||
	for _, fail := range f.failed {
 | 
						for _, fail := range f.failed {
 | 
				
			||||||
		switch fail.owner.(type) {
 | 
							switch fail.owner.(type) {
 | 
				
			||||||
		case *gherkin.Scenario:
 | 
							case *gherkin.Scenario:
 | 
				
			||||||
| 
						 | 
					@ -129,31 +129,29 @@ func (f *pretty) Summary() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *pretty) printOutlineExample(outline *gherkin.ScenarioOutline) {
 | 
					func (f *pretty) printOutlineExample(outline *gherkin.ScenarioOutline) {
 | 
				
			||||||
	var failed error
 | 
						var msg string
 | 
				
			||||||
	clr := green
 | 
						clr := green
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	example := outline.Examples[f.outlineNumExample]
 | 
						example := outline.Examples[f.outlineNumExample]
 | 
				
			||||||
	firstExample := f.outlineNumExamples == len(example.TableBody)
 | 
						firstExample := f.outlineNumExamples == len(example.TableBody)
 | 
				
			||||||
	printSteps := firstExample && f.outlineNumExample == 0
 | 
						printSteps := firstExample && f.outlineNumExample == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// var replace make(map[])
 | 
						for i, res := range f.outlineSteps {
 | 
				
			||||||
	for i, act := range f.outlineSteps {
 | 
					 | 
				
			||||||
		_, _, def, c, err := f.stepDetails(act)
 | 
					 | 
				
			||||||
		// determine example row status
 | 
							// determine example row status
 | 
				
			||||||
		switch {
 | 
							switch {
 | 
				
			||||||
		case err != nil:
 | 
							case res.typ == failed:
 | 
				
			||||||
			failed = err
 | 
								msg = res.err.Error()
 | 
				
			||||||
			clr = red
 | 
								clr = res.typ.clr()
 | 
				
			||||||
		case c == yellow:
 | 
							case res.typ == undefined || res.typ == pending:
 | 
				
			||||||
			clr = yellow
 | 
								clr = res.typ.clr()
 | 
				
			||||||
		case c == cyan && clr == green:
 | 
							case res.typ == skipped && clr == green:
 | 
				
			||||||
			clr = cyan
 | 
								clr = cyan
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if printSteps {
 | 
							if printSteps {
 | 
				
			||||||
			// in first example, we need to print steps
 | 
								// in first example, we need to print steps
 | 
				
			||||||
			var text string
 | 
								var text string
 | 
				
			||||||
			ostep := outline.Steps[i]
 | 
								ostep := outline.Steps[i]
 | 
				
			||||||
			if def != nil {
 | 
								if res.def != nil {
 | 
				
			||||||
				if m := outlinePlaceholderRegexp.FindAllStringIndex(ostep.Text, -1); len(m) > 0 {
 | 
									if m := outlinePlaceholderRegexp.FindAllStringIndex(ostep.Text, -1); len(m) > 0 {
 | 
				
			||||||
					var pos int
 | 
										var pos int
 | 
				
			||||||
					for i := 0; i < len(m); i++ {
 | 
										for i := 0; i < len(m); i++ {
 | 
				
			||||||
| 
						 | 
					@ -166,7 +164,7 @@ func (f *pretty) printOutlineExample(outline *gherkin.ScenarioOutline) {
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					text = cl(ostep.Text, cyan)
 | 
										text = cl(ostep.Text, cyan)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				text += s(f.commentPos-f.length(ostep)+1) + cl(fmt.Sprintf("# %s", def.funcName()), black)
 | 
									text += s(f.commentPos-f.length(ostep)+1) + cl(fmt.Sprintf("# %s", res.def.funcName()), black)
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				text = cl(ostep.Text, cyan)
 | 
									text = cl(ostep.Text, cyan)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -196,8 +194,8 @@ func (f *pretty) printOutlineExample(outline *gherkin.ScenarioOutline) {
 | 
				
			||||||
	fmt.Println(s(f.indent*3) + "| " + strings.Join(cells, " | ") + " |")
 | 
						fmt.Println(s(f.indent*3) + "| " + strings.Join(cells, " | ") + " |")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// if there is an error
 | 
						// if there is an error
 | 
				
			||||||
	if failed != nil {
 | 
						if msg != "" {
 | 
				
			||||||
		fmt.Println(s(f.indent*3) + bcl(failed, red))
 | 
							fmt.Println(s(f.indent*4) + bcl(msg, red))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -241,43 +239,9 @@ func (f *pretty) printStep(step *gherkin.Step, def *StepDef, c color) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *pretty) stepDetails(stepAction interface{}) (owner interface{}, step *gherkin.Step, def *StepDef, c color, err error) {
 | 
					func (f *pretty) printStepKind(res *stepResult) {
 | 
				
			||||||
	switch typ := stepAction.(type) {
 | 
					 | 
				
			||||||
	case *passed:
 | 
					 | 
				
			||||||
		step = typ.step
 | 
					 | 
				
			||||||
		def = typ.def
 | 
					 | 
				
			||||||
		owner = typ.owner
 | 
					 | 
				
			||||||
		c = green
 | 
					 | 
				
			||||||
	case *failed:
 | 
					 | 
				
			||||||
		step = typ.step
 | 
					 | 
				
			||||||
		def = typ.def
 | 
					 | 
				
			||||||
		owner = typ.owner
 | 
					 | 
				
			||||||
		err = typ.err
 | 
					 | 
				
			||||||
		c = red
 | 
					 | 
				
			||||||
	case *skipped:
 | 
					 | 
				
			||||||
		step = typ.step
 | 
					 | 
				
			||||||
		owner = typ.owner
 | 
					 | 
				
			||||||
		c = cyan
 | 
					 | 
				
			||||||
	case *undefined:
 | 
					 | 
				
			||||||
		step = typ.step
 | 
					 | 
				
			||||||
		owner = typ.owner
 | 
					 | 
				
			||||||
		c = yellow
 | 
					 | 
				
			||||||
	case *pending:
 | 
					 | 
				
			||||||
		step = typ.step
 | 
					 | 
				
			||||||
		def = typ.def
 | 
					 | 
				
			||||||
		owner = typ.owner
 | 
					 | 
				
			||||||
		c = yellow
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		fatal(fmt.Errorf("unexpected step type received: %T", typ))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (f *pretty) printStepKind(stepAction interface{}) {
 | 
					 | 
				
			||||||
	owner, step, def, c, err := f.stepDetails(stepAction)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// do not print background more than once
 | 
						// do not print background more than once
 | 
				
			||||||
	if _, ok := owner.(*gherkin.Background); ok {
 | 
						if _, ok := res.owner.(*gherkin.Background); ok {
 | 
				
			||||||
		switch {
 | 
							switch {
 | 
				
			||||||
		case f.backgroundSteps == 0:
 | 
							case f.backgroundSteps == 0:
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
| 
						 | 
					@ -286,22 +250,22 @@ func (f *pretty) printStepKind(stepAction interface{}) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if outline, ok := owner.(*gherkin.ScenarioOutline); ok {
 | 
						if outline, ok := res.owner.(*gherkin.ScenarioOutline); ok {
 | 
				
			||||||
		f.outlineSteps = append(f.outlineSteps, stepAction)
 | 
							f.outlineSteps = append(f.outlineSteps, res)
 | 
				
			||||||
		if len(f.outlineSteps) == len(outline.Steps) {
 | 
							if len(f.outlineSteps) == len(outline.Steps) {
 | 
				
			||||||
			// an outline example steps has went through
 | 
								// an outline example steps has went through
 | 
				
			||||||
			f.printOutlineExample(outline)
 | 
								f.printOutlineExample(outline)
 | 
				
			||||||
			f.outlineSteps = []interface{}{}
 | 
								f.outlineSteps = []*stepResult{}
 | 
				
			||||||
			f.outlineNumExamples--
 | 
								f.outlineNumExamples--
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f.printStep(step, def, c)
 | 
						f.printStep(res.step, res.def, res.typ.clr())
 | 
				
			||||||
	if err != nil {
 | 
						if res.err != nil {
 | 
				
			||||||
		fmt.Println(s(f.indent*2) + bcl(err, red))
 | 
							fmt.Println(s(f.indent*2) + bcl(res.err, red))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if _, ok := stepAction.(*pending); ok {
 | 
						if res.typ == pending {
 | 
				
			||||||
		fmt.Println(s(f.indent*3) + cl("TODO: write pending definition", yellow))
 | 
							fmt.Println(s(f.indent*3) + cl("TODO: write pending definition", yellow))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,17 +45,17 @@ func (f *progress) Summary() {
 | 
				
			||||||
	f.basefmt.Summary()
 | 
						f.basefmt.Summary()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *progress) step(step interface{}) {
 | 
					func (f *progress) step(res *stepResult) {
 | 
				
			||||||
	switch step.(type) {
 | 
						switch res.typ {
 | 
				
			||||||
	case *passed:
 | 
						case passed:
 | 
				
			||||||
		fmt.Print(cl(".", green))
 | 
							fmt.Print(cl(".", green))
 | 
				
			||||||
	case *skipped:
 | 
						case skipped:
 | 
				
			||||||
		fmt.Print(cl("-", cyan))
 | 
							fmt.Print(cl("-", cyan))
 | 
				
			||||||
	case *failed:
 | 
						case failed:
 | 
				
			||||||
		fmt.Print(cl("F", red))
 | 
							fmt.Print(cl("F", red))
 | 
				
			||||||
	case *undefined:
 | 
						case undefined:
 | 
				
			||||||
		fmt.Print(cl("U", yellow))
 | 
							fmt.Print(cl("U", yellow))
 | 
				
			||||||
	case *pending:
 | 
						case pending:
 | 
				
			||||||
		fmt.Print(cl("P", yellow))
 | 
							fmt.Print(cl("P", yellow))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	f.steps++
 | 
						f.steps++
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										57
									
								
								suite.go
									
										
									
									
									
								
							
							
						
						
									
										57
									
								
								suite.go
									
										
									
									
									
								
							| 
						 | 
					@ -298,6 +298,11 @@ func (s *suite) runStep(step *gherkin.Step, prevStepErr error) (err error) {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// run before step handlers
 | 
				
			||||||
 | 
						for _, f := range s.beforeStepHandlers {
 | 
				
			||||||
 | 
							f(step)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if e := recover(); e != nil {
 | 
							if e := recover(); e != nil {
 | 
				
			||||||
			err, ok := e.(error)
 | 
								err, ok := e.(error)
 | 
				
			||||||
| 
						 | 
					@ -317,16 +322,17 @@ func (s *suite) runStep(step *gherkin.Step, prevStepErr error) (err error) {
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		s.fmt.Failed(step, match, err)
 | 
							s.fmt.Failed(step, match, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// run after step handlers
 | 
				
			||||||
 | 
						for _, f := range s.afterStepHandlers {
 | 
				
			||||||
 | 
							f(step, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *suite) runSteps(steps []*gherkin.Step) (err error) {
 | 
					func (s *suite) runSteps(steps []*gherkin.Step, prevErr error) (err error) {
 | 
				
			||||||
 | 
						err = prevErr
 | 
				
			||||||
	for _, step := range steps {
 | 
						for _, step := range steps {
 | 
				
			||||||
		// run before step handlers
 | 
					 | 
				
			||||||
		for _, f := range s.beforeStepHandlers {
 | 
					 | 
				
			||||||
			f(step)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		stepErr := s.runStep(step, err)
 | 
							stepErr := s.runStep(step, err)
 | 
				
			||||||
		switch stepErr {
 | 
							switch stepErr {
 | 
				
			||||||
		case ErrUndefined:
 | 
							case ErrUndefined:
 | 
				
			||||||
| 
						 | 
					@ -337,11 +343,6 @@ func (s *suite) runSteps(steps []*gherkin.Step) (err error) {
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			err = stepErr
 | 
								err = stepErr
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		// run after step handlers
 | 
					 | 
				
			||||||
		for _, f := range s.afterStepHandlers {
 | 
					 | 
				
			||||||
			f(step, err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -352,7 +353,7 @@ func (s *suite) skipSteps(steps []*gherkin.Step) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *suite) runOutline(outline *gherkin.ScenarioOutline, b *gherkin.Background) (err error) {
 | 
					func (s *suite) runOutline(outline *gherkin.ScenarioOutline, b *gherkin.Background) (failErr error) {
 | 
				
			||||||
	s.fmt.Node(outline)
 | 
						s.fmt.Node(outline)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, example := range outline.Examples {
 | 
						for _, example := range outline.Examples {
 | 
				
			||||||
| 
						 | 
					@ -381,24 +382,21 @@ func (s *suite) runOutline(outline *gherkin.ScenarioOutline, b *gherkin.Backgrou
 | 
				
			||||||
				steps = append(steps, step)
 | 
									steps = append(steps, step)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// run background
 | 
								// run background
 | 
				
			||||||
 | 
								var err error
 | 
				
			||||||
			if b != nil {
 | 
								if b != nil {
 | 
				
			||||||
				err = s.runSteps(b.Steps)
 | 
									err = s.runSteps(b.Steps, err)
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			switch err {
 | 
					 | 
				
			||||||
			case ErrUndefined:
 | 
					 | 
				
			||||||
				s.skipSteps(steps)
 | 
					 | 
				
			||||||
			case nil:
 | 
					 | 
				
			||||||
				err = s.runSteps(steps)
 | 
					 | 
				
			||||||
			default:
 | 
					 | 
				
			||||||
				s.skipSteps(steps)
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								err = s.runSteps(steps, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for _, f := range s.afterScenarioHandlers {
 | 
								for _, f := range s.afterScenarioHandlers {
 | 
				
			||||||
				f(outline, err)
 | 
									f(outline, err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if s.stopOnFailure && err != ErrUndefined {
 | 
								if err != nil && err != ErrUndefined && err != ErrPending {
 | 
				
			||||||
				return
 | 
									failErr = err
 | 
				
			||||||
 | 
									if s.stopOnFailure {
 | 
				
			||||||
 | 
										return
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -435,21 +433,12 @@ func (s *suite) runScenario(scenario *gherkin.Scenario, b *gherkin.Background) (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// background
 | 
						// background
 | 
				
			||||||
	if b != nil {
 | 
						if b != nil {
 | 
				
			||||||
		err = s.runSteps(b.Steps)
 | 
							err = s.runSteps(b.Steps, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// scenario
 | 
						// scenario
 | 
				
			||||||
	s.fmt.Node(scenario)
 | 
						s.fmt.Node(scenario)
 | 
				
			||||||
	switch err {
 | 
						err = s.runSteps(scenario.Steps, err)
 | 
				
			||||||
	case ErrPending:
 | 
					 | 
				
			||||||
		s.skipSteps(scenario.Steps)
 | 
					 | 
				
			||||||
	case ErrUndefined:
 | 
					 | 
				
			||||||
		s.skipSteps(scenario.Steps)
 | 
					 | 
				
			||||||
	case nil:
 | 
					 | 
				
			||||||
		err = s.runSteps(scenario.Steps)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		s.skipSteps(scenario.Steps)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// run after scenario handlers
 | 
						// run after scenario handlers
 | 
				
			||||||
	for _, f := range s.afterScenarioHandlers {
 | 
						for _, f := range s.afterScenarioHandlers {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,9 @@ func SuiteContext(s Suite) {
 | 
				
			||||||
	s.Step(`^pending step$`, func() error {
 | 
						s.Step(`^pending step$`, func() error {
 | 
				
			||||||
		return ErrPending
 | 
							return ErrPending
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
						s.Step(`^passing step$`, func() error {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type firedEvent struct {
 | 
					type firedEvent struct {
 | 
				
			||||||
| 
						 | 
					@ -63,8 +66,7 @@ func (s *suiteContext) ResetBeforeEachScenario(interface{}) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *suiteContext) followingStepsShouldHave(status string, steps *gherkin.DocString) error {
 | 
					func (s *suiteContext) followingStepsShouldHave(status string, steps *gherkin.DocString) error {
 | 
				
			||||||
	var expected = strings.Split(steps.Content, "\n")
 | 
						var expected = strings.Split(steps.Content, "\n")
 | 
				
			||||||
	var actual, unmatched []string
 | 
						var actual, unmatched, matched []string
 | 
				
			||||||
	var matched []int
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch status {
 | 
						switch status {
 | 
				
			||||||
	case "passed":
 | 
						case "passed":
 | 
				
			||||||
| 
						 | 
					@ -96,23 +98,23 @@ func (s *suiteContext) followingStepsShouldHave(status string, steps *gherkin.Do
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, a := range actual {
 | 
						for _, a := range actual {
 | 
				
			||||||
		for i, e := range expected {
 | 
							for _, e := range expected {
 | 
				
			||||||
			if a == e {
 | 
								if a == e {
 | 
				
			||||||
				matched = append(matched, i)
 | 
									matched = append(matched, e)
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(matched) == len(expected) {
 | 
						if len(matched) >= len(expected) {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						for _, s := range expected {
 | 
				
			||||||
	for i, s := range expected {
 | 
					 | 
				
			||||||
		var found bool
 | 
							var found bool
 | 
				
			||||||
		for _, m := range matched {
 | 
							for _, m := range matched {
 | 
				
			||||||
			if i == m {
 | 
								if s == m {
 | 
				
			||||||
				found = true
 | 
									found = true
 | 
				
			||||||
 | 
									break
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if !found {
 | 
							if !found {
 | 
				
			||||||
| 
						 | 
					@ -120,7 +122,7 @@ func (s *suiteContext) followingStepsShouldHave(status string, steps *gherkin.Do
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return fmt.Errorf("the steps: %s - is not %s", strings.Join(unmatched, ", "), status)
 | 
						return fmt.Errorf("the steps: %s - are not %s", strings.Join(unmatched, ", "), status)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *suiteContext) iAmListeningToSuiteEvents() error {
 | 
					func (s *suiteContext) iAmListeningToSuiteEvents() error {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче