start to describing godog itself with godog

Этот коммит содержится в:
gedi 2015-06-13 00:02:10 +03:00
родитель 54e8ddb5db
коммит fa9419c2d3
5 изменённых файлов: 141 добавлений и 37 удалений

Просмотреть файл

@ -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 Обычный файл
Просмотреть файл

@ -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))
}

Просмотреть файл

@ -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 Обычный файл
Просмотреть файл

@ -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))
}