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
|
files map[string]*ast.File
|
||||||
fset *token.FileSet
|
fset *token.FileSet
|
||||||
Contexts []string
|
Contexts []string
|
||||||
|
Internal bool
|
||||||
tpl *template.Template
|
tpl *template.Template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,15 +27,14 @@ func newBuilder() *builder {
|
||||||
files: make(map[string]*ast.File),
|
files: make(map[string]*ast.File),
|
||||||
fset: token.NewFileSet(),
|
fset: token.NewFileSet(),
|
||||||
tpl: template.Must(template.New("main").Parse(`package main
|
tpl: template.Must(template.New("main").Parse(`package main
|
||||||
|
{{ if not .Internal }}import (
|
||||||
import (
|
|
||||||
"github.com/DATA-DOG/godog"
|
"github.com/DATA-DOG/godog"
|
||||||
)
|
){{ end }}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
suite := godog.New()
|
suite := {{ if not .Internal }}godog.{{ end }}New()
|
||||||
{{range $c := .Contexts}}
|
{{range .Contexts}}
|
||||||
{{$c}}(suite)
|
{{ . }}(suite)
|
||||||
{{end}}
|
{{end}}
|
||||||
suite.Run()
|
suite.Run()
|
||||||
}`)),
|
}`)),
|
||||||
|
@ -46,6 +46,10 @@ func (b *builder) parseFile(path string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// mark godog package as internal
|
||||||
|
if f.Name.Name == "godog" && !b.Internal {
|
||||||
|
b.Internal = true
|
||||||
|
}
|
||||||
b.deleteMainFunc(f)
|
b.deleteMainFunc(f)
|
||||||
b.registerSteps(f)
|
b.registerSteps(f)
|
||||||
b.deleteImports(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
|
// the regexp submatch to handle the step
|
||||||
type Arg string
|
type Arg string
|
||||||
|
|
||||||
// Float converts an argument to float64 value
|
// Float converts an argument to float64
|
||||||
// or panics if it does not know how to convert it
|
// or panics if unable to convert it
|
||||||
func (a Arg) Float() float64 {
|
func (a Arg) Float() float64 {
|
||||||
v, err := strconv.ParseFloat(string(a), 64)
|
v, err := strconv.ParseFloat(string(a), 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return v
|
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
|
// 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("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))
|
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))
|
||||||
|
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче