test table node and events fired
Этот коммит содержится в:
		
							родитель
							
								
									00fab00e22
								
							
						
					
					
						коммит
						49130c8b08
					
				
					 9 изменённых файлов: 140 добавлений и 70 удалений
				
			
		
							
								
								
									
										34
									
								
								features/events.feature
									
										
									
									
									
										Обычный файл
									
								
							
							
						
						
									
										34
									
								
								features/events.feature
									
										
									
									
									
										Обычный файл
									
								
							| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					Feature: suite events
 | 
				
			||||||
 | 
					  In order to run tasks before and after important events
 | 
				
			||||||
 | 
					  As a test suite
 | 
				
			||||||
 | 
					  I need to provide a way to hook into these events
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Background:
 | 
				
			||||||
 | 
					    Given I'm listening to suite events
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: triggers before scenario event
 | 
				
			||||||
 | 
					    Given a feature path "features/load_features.feature:6"
 | 
				
			||||||
 | 
					    When I run feature suite
 | 
				
			||||||
 | 
					    Then there was event triggered before scenario "load features within path"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: triggers appropriate events for a single scenario
 | 
				
			||||||
 | 
					    Given a feature path "features/load_features.feature:6"
 | 
				
			||||||
 | 
					    When I run feature suite
 | 
				
			||||||
 | 
					    Then these events had to be fired for a number of times:
 | 
				
			||||||
 | 
					      | BeforeSuite    | 1 |
 | 
				
			||||||
 | 
					      | BeforeScenario | 1 |
 | 
				
			||||||
 | 
					      | BeforeStep     | 3 |
 | 
				
			||||||
 | 
					      | AfterStep      | 3 |
 | 
				
			||||||
 | 
					      | AfterScenario  | 1 |
 | 
				
			||||||
 | 
					      | AfterSuite     | 1 |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Scenario: triggers appropriate events whole feature
 | 
				
			||||||
 | 
					    Given a feature path "features/load_features.feature"
 | 
				
			||||||
 | 
					    When I run feature suite
 | 
				
			||||||
 | 
					    Then these events had to be fired for a number of times:
 | 
				
			||||||
 | 
					      | BeforeSuite    | 1  |
 | 
				
			||||||
 | 
					      | BeforeScenario | 4  |
 | 
				
			||||||
 | 
					      | BeforeStep     | 13 |
 | 
				
			||||||
 | 
					      | AfterStep      | 13 |
 | 
				
			||||||
 | 
					      | AfterScenario  | 4  |
 | 
				
			||||||
 | 
					      | AfterSuite     | 1  |
 | 
				
			||||||
| 
						 | 
					@ -1,12 +0,0 @@
 | 
				
			||||||
Feature: suite hooks
 | 
					 | 
				
			||||||
  In order to run tasks before and after important events
 | 
					 | 
				
			||||||
  As a test suite
 | 
					 | 
				
			||||||
  I need to provide a way to hook into these events
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Background:
 | 
					 | 
				
			||||||
    Given I'm listening to suite events
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Scenario: triggers before scenario hook
 | 
					 | 
				
			||||||
    Given a feature path "features/load_features.feature:6"
 | 
					 | 
				
			||||||
    When I run feature suite
 | 
					 | 
				
			||||||
    Then there was event triggered before scenario "load features within path"
 | 
					 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,7 @@ Feature: load features
 | 
				
			||||||
    When I parse features
 | 
					    When I parse features
 | 
				
			||||||
    Then I should have 2 feature files:
 | 
					    Then I should have 2 feature files:
 | 
				
			||||||
      """
 | 
					      """
 | 
				
			||||||
      features/hooks.feature
 | 
					      features/events.feature
 | 
				
			||||||
      features/load_features.feature
 | 
					      features/load_features.feature
 | 
				
			||||||
      """
 | 
					      """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,10 +27,10 @@ Feature: load features
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Scenario: load a number of feature files
 | 
					  Scenario: load a number of feature files
 | 
				
			||||||
    Given a feature path "features/load_features.feature"
 | 
					    Given a feature path "features/load_features.feature"
 | 
				
			||||||
    And a feature path "features/hooks.feature"
 | 
					    And a feature path "features/events.feature"
 | 
				
			||||||
    When I parse features
 | 
					    When I parse features
 | 
				
			||||||
    Then I should have 2 feature files:
 | 
					    Then I should have 2 feature files:
 | 
				
			||||||
      """
 | 
					      """
 | 
				
			||||||
      features/load_features.feature
 | 
					      features/load_features.feature
 | 
				
			||||||
      features/hooks.feature
 | 
					      features/events.feature
 | 
				
			||||||
      """
 | 
					      """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@ type pretty struct {
 | 
				
			||||||
	commentPos     int
 | 
						commentPos     int
 | 
				
			||||||
	doneBackground bool
 | 
						doneBackground bool
 | 
				
			||||||
	background     *gherkin.Background
 | 
						background     *gherkin.Background
 | 
				
			||||||
 | 
						scenario       *gherkin.Scenario
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// summary
 | 
						// summary
 | 
				
			||||||
	started   time.Time
 | 
						started   time.Time
 | 
				
			||||||
| 
						 | 
					@ -38,20 +39,6 @@ func (f *pretty) line(tok *gherkin.Token) string {
 | 
				
			||||||
	return cl(fmt.Sprintf("# %s:%d", f.feature.Path, tok.Line), black)
 | 
						return cl(fmt.Sprintf("# %s:%d", f.feature.Path, tok.Line), black)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// checks whether it should not print a background step once again
 | 
					 | 
				
			||||||
func (f *pretty) canPrintStep(step *gherkin.Step) bool {
 | 
					 | 
				
			||||||
	if f.background == nil {
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if step.Background == nil {
 | 
					 | 
				
			||||||
		f.doneBackground = true
 | 
					 | 
				
			||||||
		return true
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return !f.doneBackground
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Node takes a gherkin node for formatting
 | 
					// Node takes a gherkin node for formatting
 | 
				
			||||||
func (f *pretty) Node(node interface{}) {
 | 
					func (f *pretty) Node(node interface{}) {
 | 
				
			||||||
	switch t := node.(type) {
 | 
						switch t := node.(type) {
 | 
				
			||||||
| 
						 | 
					@ -61,12 +48,15 @@ func (f *pretty) Node(node interface{}) {
 | 
				
			||||||
			fmt.Println("")
 | 
								fmt.Println("")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		f.feature = t
 | 
							f.feature = t
 | 
				
			||||||
		f.doneBackground = false
 | 
							f.scenario = nil
 | 
				
			||||||
		f.background = nil
 | 
							f.background = nil
 | 
				
			||||||
		f.features = append(f.features, t)
 | 
							f.features = append(f.features, t)
 | 
				
			||||||
		fmt.Println(bcl("Feature: ", white) + t.Title)
 | 
							fmt.Println(bcl("Feature: ", white) + t.Title)
 | 
				
			||||||
		fmt.Println(t.Description)
 | 
							fmt.Println(t.Description)
 | 
				
			||||||
	case *gherkin.Background:
 | 
						case *gherkin.Background:
 | 
				
			||||||
 | 
							// do not repeat background for the same feature
 | 
				
			||||||
 | 
							if f.background == nil && f.scenario == nil {
 | 
				
			||||||
 | 
								f.background = t
 | 
				
			||||||
			// determine comment position based on step length
 | 
								// determine comment position based on step length
 | 
				
			||||||
			f.commentPos = len(t.Token.Text)
 | 
								f.commentPos = len(t.Token.Text)
 | 
				
			||||||
			for _, step := range t.Steps {
 | 
								for _, step := range t.Steps {
 | 
				
			||||||
| 
						 | 
					@ -74,12 +64,11 @@ func (f *pretty) Node(node interface{}) {
 | 
				
			||||||
					f.commentPos = len(step.Token.Text)
 | 
										f.commentPos = len(step.Token.Text)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		// do not repeat background
 | 
								// print background node
 | 
				
			||||||
		if !f.doneBackground {
 | 
					 | 
				
			||||||
			f.background = t
 | 
					 | 
				
			||||||
			fmt.Println("\n" + s(t.Token.Indent) + bcl("Background:", white))
 | 
								fmt.Println("\n" + s(t.Token.Indent) + bcl("Background:", white))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	case *gherkin.Scenario:
 | 
						case *gherkin.Scenario:
 | 
				
			||||||
 | 
							f.scenario = t
 | 
				
			||||||
		// determine comment position based on step length
 | 
							// determine comment position based on step length
 | 
				
			||||||
		f.commentPos = len(t.Token.Text)
 | 
							f.commentPos = len(t.Token.Text)
 | 
				
			||||||
		for _, step := range t.Steps {
 | 
							for _, step := range t.Steps {
 | 
				
			||||||
| 
						 | 
					@ -180,7 +169,8 @@ func (f *pretty) printStep(stepAction interface{}) {
 | 
				
			||||||
		fatal(fmt.Errorf("unexpected step type received: %T", typ))
 | 
							fatal(fmt.Errorf("unexpected step type received: %T", typ))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !f.canPrintStep(step) {
 | 
						// do not print background more than once
 | 
				
			||||||
 | 
						if f.scenario == nil && step.Background != f.background {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -225,11 +215,33 @@ func (f *pretty) printStep(stepAction interface{}) {
 | 
				
			||||||
		fmt.Println(cl(step.PyString.Raw, c))
 | 
							fmt.Println(cl(step.PyString.Raw, c))
 | 
				
			||||||
		fmt.Println(s(step.Token.Indent+2) + cl(`"""`, c))
 | 
							fmt.Println(s(step.Token.Indent+2) + cl(`"""`, c))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if step.Table != nil {
 | 
				
			||||||
 | 
							f.printTable(step.Table, c)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println(s(step.Token.Indent) + bcl(err, red))
 | 
							fmt.Println(s(step.Token.Indent) + bcl(err, red))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// print table with aligned table cells
 | 
				
			||||||
 | 
					func (f *pretty) printTable(t *gherkin.Table, c color) {
 | 
				
			||||||
 | 
						var longest = make([]int, len(t.Rows[0]))
 | 
				
			||||||
 | 
						var cols = make([]string, len(t.Rows[0]))
 | 
				
			||||||
 | 
						for _, row := range t.Rows {
 | 
				
			||||||
 | 
							for i, col := range row {
 | 
				
			||||||
 | 
								if longest[i] < len(col) {
 | 
				
			||||||
 | 
									longest[i] = len(col)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, row := range t.Rows {
 | 
				
			||||||
 | 
							for i, col := range row {
 | 
				
			||||||
 | 
								cols[i] = col + s(longest[i]-len(col))
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							fmt.Println(s(t.Token.Indent) + cl("| "+strings.Join(cols, " | ")+" |", c))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Passed is called to represent a passed step
 | 
					// Passed is called to represent a passed step
 | 
				
			||||||
func (f *pretty) Passed(step *gherkin.Step, match *stepMatchHandler) {
 | 
					func (f *pretty) Passed(step *gherkin.Step, match *stepMatchHandler) {
 | 
				
			||||||
	s := &passed{step: step, handler: match}
 | 
						s := &passed{step: step, handler: match}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -155,7 +155,7 @@ type Table struct {
 | 
				
			||||||
	*Token
 | 
						*Token
 | 
				
			||||||
	OutlineScenario *Scenario
 | 
						OutlineScenario *Scenario
 | 
				
			||||||
	Step            *Step
 | 
						Step            *Step
 | 
				
			||||||
	rows            [][]string
 | 
						Rows            [][]string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var allSteps = []TokenType{
 | 
					var allSteps = []TokenType{
 | 
				
			||||||
| 
						 | 
					@ -369,17 +369,17 @@ func (p *parser) parsePystring() (*PyString, error) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *parser) parseTable() (*Table, error) {
 | 
					func (p *parser) parseTable() (*Table, error) {
 | 
				
			||||||
	tbl := &Table{}
 | 
						tbl := &Table{Token: p.peek()}
 | 
				
			||||||
	for row := p.peek(); row.Type == TABLE_ROW; row = p.peek() {
 | 
						for row := p.peek(); row.Type == TABLE_ROW; row = p.peek() {
 | 
				
			||||||
		var cols []string
 | 
							var cols []string
 | 
				
			||||||
		for _, r := range strings.Split(strings.Trim(row.Value, "|"), "|") {
 | 
							for _, r := range strings.Split(strings.Trim(row.Value, "|"), "|") {
 | 
				
			||||||
			cols = append(cols, strings.TrimFunc(r, unicode.IsSpace))
 | 
								cols = append(cols, strings.TrimFunc(r, unicode.IsSpace))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		// ensure the same colum number for each row
 | 
							// ensure the same colum number for each row
 | 
				
			||||||
		if len(tbl.rows) > 0 && len(tbl.rows[0]) != len(cols) {
 | 
							if len(tbl.Rows) > 0 && len(tbl.Rows[0]) != len(cols) {
 | 
				
			||||||
			return tbl, p.err("table row has not the same number of columns compared to previous row", row.Line)
 | 
								return tbl, p.err("table row has not the same number of columns compared to previous row", row.Line)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		tbl.rows = append(tbl.rows, cols)
 | 
							tbl.Rows = append(tbl.Rows, cols)
 | 
				
			||||||
		p.next() // jump over the peeked token
 | 
							p.next() // jump over the peeked token
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return tbl, nil
 | 
						return tbl, nil
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,13 +25,13 @@ func (s *Scenario) assertExampleRow(t *testing.T, num int, cols ...string) {
 | 
				
			||||||
	if s.Examples == nil {
 | 
						if s.Examples == nil {
 | 
				
			||||||
		t.Fatalf("outline scenario '%s' has no examples", s.Title)
 | 
							t.Fatalf("outline scenario '%s' has no examples", s.Title)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(s.Examples.rows) <= num {
 | 
						if len(s.Examples.Rows) <= num {
 | 
				
			||||||
		t.Fatalf("outline scenario '%s' table has no row: %d", s.Title, num)
 | 
							t.Fatalf("outline scenario '%s' table has no row: %d", s.Title, num)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(s.Examples.rows[num]) != len(cols) {
 | 
						if len(s.Examples.Rows[num]) != len(cols) {
 | 
				
			||||||
		t.Fatalf("outline scenario '%s' table row length, does not match expected: %d", s.Title, len(cols))
 | 
							t.Fatalf("outline scenario '%s' table row length, does not match expected: %d", s.Title, len(cols))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for i, col := range s.Examples.rows[num] {
 | 
						for i, col := range s.Examples.Rows[num] {
 | 
				
			||||||
		if col != cols[i] {
 | 
							if col != cols[i] {
 | 
				
			||||||
			t.Fatalf("outline scenario '%s' table row %d, column %d - value '%s', does not match expected: %s", s.Title, num, i, col, cols[i])
 | 
								t.Fatalf("outline scenario '%s' table row %d, column %d - value '%s', does not match expected: %s", s.Title, num, i, col, cols[i])
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,13 +69,13 @@ func (s *Step) assertTableRow(t *testing.T, num int, cols ...string) {
 | 
				
			||||||
	if s.Table == nil {
 | 
						if s.Table == nil {
 | 
				
			||||||
		t.Fatalf("step '%s %s' has no table", s.Type, s.Text)
 | 
							t.Fatalf("step '%s %s' has no table", s.Type, s.Text)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(s.Table.rows) <= num {
 | 
						if len(s.Table.Rows) <= num {
 | 
				
			||||||
		t.Fatalf("step '%s %s' table has no row: %d", s.Type, s.Text, num)
 | 
							t.Fatalf("step '%s %s' table has no row: %d", s.Type, s.Text, num)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(s.Table.rows[num]) != len(cols) {
 | 
						if len(s.Table.Rows[num]) != len(cols) {
 | 
				
			||||||
		t.Fatalf("step '%s %s' table row length, does not match expected: %d", s.Type, s.Text, len(cols))
 | 
							t.Fatalf("step '%s %s' table row length, does not match expected: %d", s.Type, s.Text, len(cols))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for i, col := range s.Table.rows[num] {
 | 
						for i, col := range s.Table.Rows[num] {
 | 
				
			||||||
		if col != cols[i] {
 | 
							if col != cols[i] {
 | 
				
			||||||
			t.Fatalf("step '%s %s' table row %d, column %d - value '%s', does not match expected: %s", s.Type, s.Text, num, i, col, cols[i])
 | 
								t.Fatalf("step '%s %s' table row %d, column %d - value '%s', does not match expected: %s", s.Type, s.Text, num, i, col, cols[i])
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								suite.go
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								suite.go
									
										
									
									
									
								
							| 
						 | 
					@ -11,9 +11,10 @@ import (
 | 
				
			||||||
	"github.com/DATA-DOG/godog/gherkin"
 | 
						"github.com/DATA-DOG/godog/gherkin"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Status represents a step status
 | 
					// Status represents a step or scenario status
 | 
				
			||||||
type Status int
 | 
					type Status int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// step or scenario status constants
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	invalid Status = iota
 | 
						invalid Status = iota
 | 
				
			||||||
	Passed
 | 
						Passed
 | 
				
			||||||
| 
						 | 
					@ -303,7 +304,7 @@ func (s *suite) runFeature(f *gherkin.Feature) {
 | 
				
			||||||
			s.skipSteps(scenario.Steps)
 | 
								s.skipSteps(scenario.Steps)
 | 
				
			||||||
		case status == Undefined:
 | 
							case status == Undefined:
 | 
				
			||||||
			s.skipSteps(scenario.Steps)
 | 
								s.skipSteps(scenario.Steps)
 | 
				
			||||||
		case status == invalid:
 | 
							case status == Passed || status == invalid:
 | 
				
			||||||
			status = s.runSteps(scenario.Steps)
 | 
								status = s.runSteps(scenario.Steps)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,24 +14,39 @@ type firedEvent struct {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type suiteFeature struct {
 | 
					type suiteFeature struct {
 | 
				
			||||||
	suite
 | 
						testedSuite *suite
 | 
				
			||||||
	events      []*firedEvent
 | 
						events      []*firedEvent
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *suiteFeature) HandleBeforeScenario(scenario *gherkin.Scenario) {
 | 
					func (s *suiteFeature) HandleBeforeScenario(scenario *gherkin.Scenario) {
 | 
				
			||||||
 | 
						// reset whole suite with the state
 | 
				
			||||||
 | 
						s.testedSuite = &suite{fmt: &testFormatter{}}
 | 
				
			||||||
 | 
						// our tested suite will have the same context registered
 | 
				
			||||||
 | 
						SuiteContext(s.testedSuite)
 | 
				
			||||||
	// reset feature paths
 | 
						// reset feature paths
 | 
				
			||||||
	cfg.paths = []string{}
 | 
						cfg.paths = []string{}
 | 
				
			||||||
	// reset event stack
 | 
						// reset all fired events
 | 
				
			||||||
	s.events = []*firedEvent{}
 | 
						s.events = []*firedEvent{}
 | 
				
			||||||
	// reset formatter, which collects all details
 | 
					 | 
				
			||||||
	s.fmt = &testFormatter{}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *suiteFeature) iAmListeningToSuiteEvents(args ...*Arg) error {
 | 
					func (s *suiteFeature) iAmListeningToSuiteEvents(args ...*Arg) error {
 | 
				
			||||||
	s.BeforeScenario(BeforeScenarioHandlerFunc(func(scenario *gherkin.Scenario) {
 | 
						s.testedSuite.BeforeSuite(BeforeSuiteHandlerFunc(func() {
 | 
				
			||||||
		s.events = append(s.events, &firedEvent{"BeforeScenario", []interface{}{
 | 
							s.events = append(s.events, &firedEvent{"BeforeSuite", []interface{}{}})
 | 
				
			||||||
			scenario,
 | 
						}))
 | 
				
			||||||
		}})
 | 
						s.testedSuite.AfterSuite(AfterSuiteHandlerFunc(func() {
 | 
				
			||||||
 | 
							s.events = append(s.events, &firedEvent{"AfterSuite", []interface{}{}})
 | 
				
			||||||
 | 
						}))
 | 
				
			||||||
 | 
						s.testedSuite.BeforeScenario(BeforeScenarioHandlerFunc(func(scenario *gherkin.Scenario) {
 | 
				
			||||||
 | 
							s.events = append(s.events, &firedEvent{"BeforeScenario", []interface{}{scenario}})
 | 
				
			||||||
 | 
						}))
 | 
				
			||||||
 | 
						s.testedSuite.AfterScenario(AfterScenarioHandlerFunc(func(scenario *gherkin.Scenario, status Status) {
 | 
				
			||||||
 | 
							s.events = append(s.events, &firedEvent{"AfterScenario", []interface{}{scenario, status}})
 | 
				
			||||||
 | 
						}))
 | 
				
			||||||
 | 
						s.testedSuite.BeforeStep(BeforeStepHandlerFunc(func(step *gherkin.Step) {
 | 
				
			||||||
 | 
							s.events = append(s.events, &firedEvent{"BeforeStep", []interface{}{step}})
 | 
				
			||||||
 | 
						}))
 | 
				
			||||||
 | 
						s.testedSuite.AfterStep(AfterStepHandlerFunc(func(step *gherkin.Step, status Status) {
 | 
				
			||||||
 | 
							s.events = append(s.events, &firedEvent{"AfterStep", []interface{}{step, status}})
 | 
				
			||||||
	}))
 | 
						}))
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -42,17 +57,17 @@ func (s *suiteFeature) featurePath(args ...*Arg) error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *suiteFeature) parseFeatures(args ...*Arg) (err error) {
 | 
					func (s *suiteFeature) parseFeatures(args ...*Arg) (err error) {
 | 
				
			||||||
	s.features, err = cfg.features()
 | 
						s.testedSuite.features, err = cfg.features()
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *suiteFeature) iShouldHaveNumFeatureFiles(args ...*Arg) error {
 | 
					func (s *suiteFeature) iShouldHaveNumFeatureFiles(args ...*Arg) error {
 | 
				
			||||||
	if len(s.features) != args[0].Int() {
 | 
						if len(s.testedSuite.features) != args[0].Int() {
 | 
				
			||||||
		return fmt.Errorf("expected %d features to be parsed, but have %d", args[0].Int(), len(s.features))
 | 
							return fmt.Errorf("expected %d features to be parsed, but have %d", args[0].Int(), len(s.testedSuite.features))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	expected := args[1].PyString().Lines
 | 
						expected := args[1].PyString().Lines
 | 
				
			||||||
	var actual []string
 | 
						var actual []string
 | 
				
			||||||
	for _, ft := range s.features {
 | 
						for _, ft := range s.testedSuite.features {
 | 
				
			||||||
		actual = append(actual, ft.Path)
 | 
							actual = append(actual, ft.Path)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(expected) != len(actual) {
 | 
						if len(expected) != len(actual) {
 | 
				
			||||||
| 
						 | 
					@ -70,13 +85,13 @@ func (s *suiteFeature) iRunFeatureSuite(args ...*Arg) error {
 | 
				
			||||||
	if err := s.parseFeatures(); err != nil {
 | 
						if err := s.parseFeatures(); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	s.run()
 | 
						s.testedSuite.run()
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *suiteFeature) numScenariosRegistered(args ...*Arg) (err error) {
 | 
					func (s *suiteFeature) numScenariosRegistered(args ...*Arg) (err error) {
 | 
				
			||||||
	var num int
 | 
						var num int
 | 
				
			||||||
	for _, ft := range s.features {
 | 
						for _, ft := range s.testedSuite.features {
 | 
				
			||||||
		num += len(ft.Scenarios)
 | 
							num += len(ft.Scenarios)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if num != args[0].Int() {
 | 
						if num != args[0].Int() {
 | 
				
			||||||
| 
						 | 
					@ -120,11 +135,28 @@ func (s *suiteFeature) thereWasEventTriggeredBeforeScenario(args ...*Arg) error
 | 
				
			||||||
	return fmt.Errorf(`expected "%s" scenario, but got these fired %s`, args[0].String(), `"`+strings.Join(found, `", "`)+`"`)
 | 
						return fmt.Errorf(`expected "%s" scenario, but got these fired %s`, args[0].String(), `"`+strings.Join(found, `", "`)+`"`)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func SuiteContext(g Suite) {
 | 
					func (s *suiteFeature) theseEventsHadToBeFiredForNumberOfTimes(args ...*Arg) error {
 | 
				
			||||||
	s := &suiteFeature{
 | 
						tbl := args[0].Table()
 | 
				
			||||||
		suite: suite{},
 | 
						if len(tbl.Rows[0]) != 2 {
 | 
				
			||||||
 | 
							return fmt.Errorf("expected two columns for event table row, got: %d", len(tbl.Rows[0]))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, row := range tbl.Rows {
 | 
				
			||||||
 | 
							args := []*Arg{
 | 
				
			||||||
 | 
								StepArgument(""), // ignored
 | 
				
			||||||
 | 
								StepArgument(row[1]),
 | 
				
			||||||
 | 
								StepArgument(row[0]),
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err := s.thereWereNumEventsFired(args...); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func SuiteContext(g Suite) {
 | 
				
			||||||
 | 
						s := &suiteFeature{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	g.BeforeScenario(s)
 | 
						g.BeforeScenario(s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	g.Step(
 | 
						g.Step(
 | 
				
			||||||
| 
						 | 
					@ -151,4 +183,7 @@ func SuiteContext(g Suite) {
 | 
				
			||||||
	g.Step(
 | 
						g.Step(
 | 
				
			||||||
		regexp.MustCompile(`^there was event triggered before scenario "([^"]*)"$`),
 | 
							regexp.MustCompile(`^there was event triggered before scenario "([^"]*)"$`),
 | 
				
			||||||
		StepHandlerFunc(s.thereWasEventTriggeredBeforeScenario))
 | 
							StepHandlerFunc(s.thereWasEventTriggeredBeforeScenario))
 | 
				
			||||||
 | 
						g.Step(
 | 
				
			||||||
 | 
							regexp.MustCompile(`^these events had to be fired for a number of times:$`),
 | 
				
			||||||
 | 
							StepHandlerFunc(s.theseEventsHadToBeFiredForNumberOfTimes))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Загрузка…
	
	Создание таблицы
		
		Сослаться в новой задаче