start to describing godog itself with godog
Этот коммит содержится в:
родитель
54e8ddb5db
коммит
fa9419c2d3
5 изменённых файлов: 141 добавлений и 37 удалений
16
builder.go
16
builder.go
|
@ -18,6 +18,7 @@ type builder struct {
|
|||
files map[string]*ast.File
|
||||
fset *token.FileSet
|
||||
Contexts []string
|
||||
Internal bool
|
||||
tpl *template.Template
|
||||
}
|
||||
|
||||
|
@ -26,15 +27,14 @@ func newBuilder() *builder {
|
|||
files: make(map[string]*ast.File),
|
||||
fset: token.NewFileSet(),
|
||||
tpl: template.Must(template.New("main").Parse(`package main
|
||||
|
||||
import (
|
||||
{{ if not .Internal }}import (
|
||||
"github.com/DATA-DOG/godog"
|
||||
)
|
||||
){{ end }}
|
||||
|
||||
func main() {
|
||||
suite := godog.New()
|
||||
{{range $c := .Contexts}}
|
||||
{{$c}}(suite)
|
||||
suite := {{ if not .Internal }}godog.{{ end }}New()
|
||||
{{range .Contexts}}
|
||||
{{ . }}(suite)
|
||||
{{end}}
|
||||
suite.Run()
|
||||
}`)),
|
||||
|
@ -46,6 +46,10 @@ func (b *builder) parseFile(path string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// mark godog package as internal
|
||||
if f.Name.Name == "godog" && !b.Internal {
|
||||
b.Internal = true
|
||||
}
|
||||
b.deleteMainFunc(f)
|
||||
b.registerSteps(f)
|
||||
b.deleteImports(f)
|
||||
|
|
9
features/suite.feature
Обычный файл
9
features/suite.feature
Обычный файл
|
@ -0,0 +1,9 @@
|
|||
Feature: godog bdd suite
|
||||
In order to test application behavior
|
||||
As a suite
|
||||
I need to be able to register and run features
|
||||
|
||||
Scenario:
|
||||
Given a feature path "features"
|
||||
When I parse features
|
||||
Then I should have 1 feature file
|
|
@ -1,28 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/DATA-DOG/godog"
|
||||
)
|
||||
|
||||
type lsFeature struct{}
|
||||
|
||||
func (s *lsFeature) inDirectory(args ...godog.Arg) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *lsFeature) haveFile(args ...godog.Arg) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func SuiteContext(g godog.Suite) {
|
||||
f := &lsFeature{}
|
||||
|
||||
g.Step(
|
||||
regexp.MustCompile(`^I am in a directory "([^"]*)"$`),
|
||||
godog.StepHandlerFunc(f.inDirectory))
|
||||
g.Step(
|
||||
regexp.MustCompile(`^I have a file named "([^"]*)"$`),
|
||||
godog.StepHandlerFunc(f.haveFile))
|
||||
}
|
80
suite.go
80
suite.go
|
@ -13,14 +13,29 @@ import (
|
|||
// the regexp submatch to handle the step
|
||||
type Arg string
|
||||
|
||||
// Float converts an argument to float64 value
|
||||
// or panics if it does not know how to convert it
|
||||
// Float converts an argument to float64
|
||||
// or panics if unable to convert it
|
||||
func (a Arg) Float() float64 {
|
||||
v, err := strconv.ParseFloat(string(a), 64)
|
||||
if err == nil {
|
||||
return v
|
||||
}
|
||||
panic(fmt.Sprintf(`cannot convert string "%s" to float64: %s`, a, err))
|
||||
panic(fmt.Sprintf(`cannot convert "%s" to float64: %s`, a, err))
|
||||
}
|
||||
|
||||
// Int converts an argument to int64
|
||||
// or panics if unable to convert it
|
||||
func (a Arg) Int() int64 {
|
||||
v, err := strconv.ParseInt(string(a), 10, 0)
|
||||
if err == nil {
|
||||
return v
|
||||
}
|
||||
panic(fmt.Sprintf(`cannot convert "%s" to int64: %s`, a, err))
|
||||
}
|
||||
|
||||
// String converts an argument to string
|
||||
func (a Arg) String() string {
|
||||
return string(a)
|
||||
}
|
||||
|
||||
// Objects implementing the StepHandler interface can be
|
||||
|
@ -97,4 +112,63 @@ func (s *suite) Run() {
|
|||
|
||||
fmt.Println("running", cl("godog", cyan)+", num registered steps:", cl(len(s.steps), yellow))
|
||||
fmt.Println("have loaded", cl(len(s.features), yellow), "features from path:", cl(cfg.featuresPath, green))
|
||||
|
||||
for _, f := range s.features {
|
||||
s.runFeature(f)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *suite) runFeature(f *gherkin.Feature) {
|
||||
for _, scenario := range f.Scenarios {
|
||||
if f.Background != nil {
|
||||
for _, step := range f.Background.Steps {
|
||||
var handler StepHandler
|
||||
var args []Arg
|
||||
for r, h := range s.steps {
|
||||
if m := r.FindStringSubmatch(step.Text); len(m) > 0 {
|
||||
handler = h
|
||||
for _, a := range m[1:] {
|
||||
args = append(args, Arg(a))
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if handler != nil {
|
||||
if err := handler.HandleStep(args...); err != nil {
|
||||
// @TODO: scenario fails, step failed
|
||||
fmt.Println("ERR")
|
||||
} else {
|
||||
fmt.Println("OK")
|
||||
}
|
||||
// @TODO: handle panic and recover
|
||||
} else {
|
||||
fmt.Println("PENDING")
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, step := range scenario.Steps {
|
||||
var handler StepHandler
|
||||
var args []Arg
|
||||
for r, h := range s.steps {
|
||||
if m := r.FindStringSubmatch(step.Text); len(m) > 0 {
|
||||
handler = h
|
||||
for _, a := range m[1:] {
|
||||
args = append(args, Arg(a))
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if handler != nil {
|
||||
if err := handler.HandleStep(args...); err != nil {
|
||||
// @TODO: scenario fails, step failed
|
||||
fmt.Println("ERR")
|
||||
} else {
|
||||
fmt.Println("OK")
|
||||
}
|
||||
// @TODO: handle panic and recover
|
||||
} else {
|
||||
fmt.Println("PENDING")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
45
suite_test.go
Обычный файл
45
suite_test.go
Обычный файл
|
@ -0,0 +1,45 @@
|
|||
package godog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
type suiteFeature struct {
|
||||
suite
|
||||
}
|
||||
|
||||
func (s *suiteFeature) featurePath(args ...Arg) error {
|
||||
cfg.featuresPath = args[0].String()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *suiteFeature) parseFeatures(args ...Arg) (err error) {
|
||||
s.features, err = cfg.features()
|
||||
return
|
||||
}
|
||||
|
||||
func (s *suiteFeature) numParsed(args ...Arg) (err error) {
|
||||
if len(s.features) != int(args[0].Int()) {
|
||||
err = fmt.Errorf("expected %d features to be parsed, but have %d", args[0].Int(), len(s.features))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func SuiteContext(g Suite) {
|
||||
s := &suiteFeature{
|
||||
suite: suite{
|
||||
steps: make(map[*regexp.Regexp]StepHandler),
|
||||
},
|
||||
}
|
||||
|
||||
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 should have ([\d]+) features? files?$`),
|
||||
StepHandlerFunc(s.numParsed))
|
||||
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче