less strict step registration
Этот коммит содержится в:
родитель
1f4ac0e8ec
коммит
c604d39ac5
5 изменённых файлов: 101 добавлений и 54 удалений
|
@ -7,12 +7,12 @@ Feature: suite events
|
|||
Given I'm listening to suite events
|
||||
|
||||
Scenario: triggers before scenario event
|
||||
Given a feature path "features/load_features.feature:6"
|
||||
Given a feature path "features/load.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"
|
||||
Given a feature path "features/load.feature:6"
|
||||
When I run feature suite
|
||||
Then these events had to be fired for a number of times:
|
||||
| BeforeSuite | 1 |
|
||||
|
@ -23,7 +23,7 @@ Feature: suite events
|
|||
| AfterSuite | 1 |
|
||||
|
||||
Scenario: triggers appropriate events whole feature
|
||||
Given a feature path "features/load_features.feature"
|
||||
Given a feature path "features/load.feature"
|
||||
When I run feature suite
|
||||
Then these events had to be fired for a number of times:
|
||||
| BeforeSuite | 1 |
|
||||
|
|
|
@ -6,31 +6,32 @@ Feature: load features
|
|||
Scenario: load features within path
|
||||
Given a feature path "features"
|
||||
When I parse features
|
||||
Then I should have 2 feature files:
|
||||
Then I should have 3 feature files:
|
||||
"""
|
||||
features/events.feature
|
||||
features/load_features.feature
|
||||
features/load.feature
|
||||
features/run.feature
|
||||
"""
|
||||
|
||||
Scenario: load a specific feature file
|
||||
Given a feature path "features/load_features.feature"
|
||||
Given a feature path "features/load.feature"
|
||||
When I parse features
|
||||
Then I should have 1 feature file:
|
||||
"""
|
||||
features/load_features.feature
|
||||
features/load.feature
|
||||
"""
|
||||
|
||||
Scenario: load a feature file with a specified scenario
|
||||
Given a feature path "features/load_features.feature:6"
|
||||
Given a feature path "features/load.feature:6"
|
||||
When I parse features
|
||||
Then I should have 1 scenario registered
|
||||
|
||||
Scenario: load a number of feature files
|
||||
Given a feature path "features/load_features.feature"
|
||||
Given a feature path "features/load.feature"
|
||||
And a feature path "features/events.feature"
|
||||
When I parse features
|
||||
Then I should have 2 feature files:
|
||||
"""
|
||||
features/load_features.feature
|
||||
features/load.feature
|
||||
features/events.feature
|
||||
"""
|
18
features/run.feature
Обычный файл
18
features/run.feature
Обычный файл
|
@ -0,0 +1,18 @@
|
|||
Feature: run features
|
||||
In order to test application behavior
|
||||
As a test suite
|
||||
I need to be able to run features
|
||||
|
||||
Scenario: should run a normal feature
|
||||
Given a feature "normal.feature" file:
|
||||
"""
|
||||
Feature: normal feature
|
||||
|
||||
Scenario: parse a scenario
|
||||
Given a feature path "features/load.feature:6"
|
||||
When I parse features
|
||||
Then I should have 1 scenario registered
|
||||
"""
|
||||
When I run feature suite
|
||||
Then the suite should have passed successfully
|
||||
|
50
suite.go
50
suite.go
|
@ -11,12 +11,21 @@ import (
|
|||
"github.com/DATA-DOG/godog/gherkin"
|
||||
)
|
||||
|
||||
// Regexp is an unified type for regular expression
|
||||
// it can be either a string or a *regexp.Regexp
|
||||
type Regexp interface{}
|
||||
|
||||
// Handler is an unified type for a StepHandler
|
||||
// interface satisfaction. It may be a function
|
||||
// or a step handler
|
||||
type Handler interface{}
|
||||
|
||||
// Status represents a step or scenario status
|
||||
type Status int
|
||||
|
||||
// step or scenario status constants
|
||||
const (
|
||||
invalid Status = iota
|
||||
Invalid Status = iota
|
||||
Passed
|
||||
Failed
|
||||
Undefined
|
||||
|
@ -71,7 +80,7 @@ type stepMatchHandler struct {
|
|||
// Suite is an interface which allows various contexts
|
||||
// to register step definitions and event handlers
|
||||
type Suite interface {
|
||||
Step(expr *regexp.Regexp, h StepHandler)
|
||||
Step(expr Regexp, h Handler)
|
||||
// suite events
|
||||
BeforeSuite(h BeforeSuiteHandler)
|
||||
BeforeScenario(h BeforeScenarioHandler)
|
||||
|
@ -106,7 +115,10 @@ func New() *suite {
|
|||
|
||||
// Step allows to register a StepHandler in Godog
|
||||
// feature suite, the handler will be applied to all
|
||||
// steps matching the given regexp
|
||||
// steps matching the given regexp expr
|
||||
//
|
||||
// It will panic if expr is not a valid regular expression
|
||||
// or handler does not satisfy StepHandler interface
|
||||
//
|
||||
// Note that if there are two handlers which may match
|
||||
// the same step, then the only first matched handler
|
||||
|
@ -114,10 +126,34 @@ func New() *suite {
|
|||
//
|
||||
// If none of the StepHandlers are matched, then a pending
|
||||
// step error will be raised.
|
||||
func (s *suite) Step(expr *regexp.Regexp, h StepHandler) {
|
||||
func (s *suite) Step(expr Regexp, h Handler) {
|
||||
var handler StepHandler
|
||||
var regex *regexp.Regexp
|
||||
|
||||
switch t := expr.(type) {
|
||||
case *regexp.Regexp:
|
||||
regex = t
|
||||
case string:
|
||||
regex = regexp.MustCompile(t)
|
||||
case []byte:
|
||||
regex = regexp.MustCompile(string(t))
|
||||
default:
|
||||
panic(fmt.Sprintf("expecting expr to be a *regexp.Regexp or a string, got type: %T", expr))
|
||||
}
|
||||
|
||||
switch t := h.(type) {
|
||||
case StepHandlerFunc:
|
||||
handler = t
|
||||
case StepHandler:
|
||||
handler = t
|
||||
case func(...*Arg) error:
|
||||
handler = StepHandlerFunc(t)
|
||||
default:
|
||||
panic(fmt.Sprintf("expecting handler to satisfy StepHandler interface, got type: %T", h))
|
||||
}
|
||||
s.stepHandlers = append(s.stepHandlers, &stepMatchHandler{
|
||||
handler: h,
|
||||
expr: expr,
|
||||
handler: handler,
|
||||
expr: regex,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -304,7 +340,7 @@ func (s *suite) runFeature(f *gherkin.Feature) {
|
|||
s.skipSteps(scenario.Steps)
|
||||
case status == Undefined:
|
||||
s.skipSteps(scenario.Steps)
|
||||
case status == Passed || status == invalid:
|
||||
case status == Passed || status == Invalid:
|
||||
status = s.runSteps(scenario.Steps)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@ package godog
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/DATA-DOG/godog/gherkin"
|
||||
|
@ -15,9 +13,8 @@ type firedEvent struct {
|
|||
}
|
||||
|
||||
type suiteFeature struct {
|
||||
testedSuite *suite
|
||||
events []*firedEvent
|
||||
tempFeatures []string
|
||||
testedSuite *suite
|
||||
events []*firedEvent
|
||||
}
|
||||
|
||||
func (s *suiteFeature) HandleBeforeScenario(*gherkin.Scenario) {
|
||||
|
@ -27,18 +24,10 @@ func (s *suiteFeature) HandleBeforeScenario(*gherkin.Scenario) {
|
|||
SuiteContext(s.testedSuite)
|
||||
// reset feature paths
|
||||
cfg.paths = []string{}
|
||||
s.tempFeatures = []string{}
|
||||
// reset all fired events
|
||||
s.events = []*firedEvent{}
|
||||
}
|
||||
|
||||
func (s *suiteFeature) HandleAfterScenario(*gherkin.Scenario) {
|
||||
// remove temp files
|
||||
for _, f := range s.tempFeatures {
|
||||
os.Remove("/tmp/" + f)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *suiteFeature) iAmListeningToSuiteEvents(args ...*Arg) error {
|
||||
s.testedSuite.BeforeSuite(BeforeSuiteHandlerFunc(func() {
|
||||
s.events = append(s.events, &firedEvent{"BeforeSuite", []interface{}{}})
|
||||
|
@ -65,8 +54,13 @@ func (s *suiteFeature) aFailingStep(...*Arg) error {
|
|||
return fmt.Errorf("intentional failure")
|
||||
}
|
||||
|
||||
func (s *suiteFeature) tempFeatureFile(args ...*Arg) error {
|
||||
return nil
|
||||
// parse a given feature file body as a feature
|
||||
func (s *suiteFeature) aFeatureFile(args ...*Arg) error {
|
||||
name := args[0].String()
|
||||
body := args[1].PyString().Raw
|
||||
feature, err := gherkin.Parse(strings.NewReader(body), name)
|
||||
s.testedSuite.features = append(s.testedSuite.features, feature)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *suiteFeature) featurePath(args ...*Arg) error {
|
||||
|
@ -79,6 +73,13 @@ func (s *suiteFeature) parseFeatures(args ...*Arg) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (s *suiteFeature) theSuitePassedSuccessfully(...*Arg) error {
|
||||
if s.testedSuite.failed {
|
||||
return fmt.Errorf("the feature suite has failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *suiteFeature) iShouldHaveNumFeatureFiles(args ...*Arg) error {
|
||||
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.testedSuite.features))
|
||||
|
@ -177,28 +178,19 @@ func SuiteContext(g Suite) {
|
|||
|
||||
g.BeforeScenario(s)
|
||||
|
||||
g.Step(regexp.MustCompile(`^a feature path "([^"]*)"$`), StepHandlerFunc(s.featurePath))
|
||||
g.Step(regexp.MustCompile(`^I parse features$`), StepHandlerFunc(s.parseFeatures))
|
||||
g.Step(regexp.MustCompile(`^I'm listening to suite events$`), StepHandlerFunc(s.iAmListeningToSuiteEvents))
|
||||
g.Step(regexp.MustCompile(`^I run feature suite$`), StepHandlerFunc(s.iRunFeatureSuite))
|
||||
g.Step(regexp.MustCompile(`^feature "([^"]*)" file:$`), StepHandlerFunc(s.tempFeatureFile))
|
||||
g.Step(`^a feature path "([^"]*)"$`, s.featurePath)
|
||||
g.Step(`^I parse features$`, s.parseFeatures)
|
||||
g.Step(`^I'm listening to suite events$`, s.iAmListeningToSuiteEvents)
|
||||
g.Step(`^I run feature suite$`, s.iRunFeatureSuite)
|
||||
g.Step(`^a feature "([^"]*)" file:$`, s.aFeatureFile)
|
||||
g.Step(`^the suite should have passed successfully$`, s.theSuitePassedSuccessfully)
|
||||
|
||||
g.Step(
|
||||
regexp.MustCompile(`^I should have ([\d]+) features? files?:$`),
|
||||
StepHandlerFunc(s.iShouldHaveNumFeatureFiles))
|
||||
g.Step(
|
||||
regexp.MustCompile(`^I should have ([\d]+) scenarios? registered$`),
|
||||
StepHandlerFunc(s.numScenariosRegistered))
|
||||
g.Step(
|
||||
regexp.MustCompile(`^there (was|were) ([\d]+) "([^"]*)" events? fired$`),
|
||||
StepHandlerFunc(s.thereWereNumEventsFired))
|
||||
g.Step(
|
||||
regexp.MustCompile(`^there was event triggered before scenario "([^"]*)"$`),
|
||||
StepHandlerFunc(s.thereWasEventTriggeredBeforeScenario))
|
||||
g.Step(
|
||||
regexp.MustCompile(`^these events had to be fired for a number of times:$`),
|
||||
StepHandlerFunc(s.theseEventsHadToBeFiredForNumberOfTimes))
|
||||
g.Step(`^I should have ([\d]+) features? files?:$`, s.iShouldHaveNumFeatureFiles)
|
||||
g.Step(`^I should have ([\d]+) scenarios? registered$`, s.numScenariosRegistered)
|
||||
g.Step(`^there (was|were) ([\d]+) "([^"]*)" events? fired$`, s.thereWereNumEventsFired)
|
||||
g.Step(`^there was event triggered before scenario "([^"]*)"$`, s.thereWasEventTriggeredBeforeScenario)
|
||||
g.Step(`^these events had to be fired for a number of times:$`, s.theseEventsHadToBeFiredForNumberOfTimes)
|
||||
|
||||
g.Step(regexp.MustCompile(`^a failing step`), StepHandlerFunc(s.aFailingStep))
|
||||
g.Step(regexp.MustCompile(`^this step should fail`), StepHandlerFunc(s.aFailingStep))
|
||||
g.Step(`^a failing step`, s.aFailingStep)
|
||||
g.Step(`^this step should fail`, s.aFailingStep)
|
||||
}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче