Merge pull request #271 from cucumber/broke-out-snippets-gen

Broke out snippets gen and added sorting on method name
Этот коммит содержится в:
Fredrik Lönnblad 2020-03-24 10:59:13 +01:00 коммит произвёл GitHub
родитель 5afad4dee9 0d1fb60ba0
коммит 4d5024dc24
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 134 добавлений и 103 удалений

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

@ -105,17 +105,17 @@ Feature: undefined step snippets
When I run feature suite When I run feature suite
And the undefined step snippets should be: And the undefined step snippets should be:
""" """
func thereIsAWhichCosts(arg1 string, arg2 int) error {
return godog.ErrPending
}
func iAddTheToTheBasket(arg1 string) error { func iAddTheToTheBasket(arg1 string) error {
return godog.ErrPending return godog.ErrPending
} }
func thereIsAWhichCosts(arg1 string, arg2 int) error {
return godog.ErrPending
}
func FeatureContext(s *godog.Suite) { func FeatureContext(s *godog.Suite) {
s.Step(`^there is a "([^"]*)", which costs £(\d+)$`, thereIsAWhichCosts)
s.Step(`^I add the "([^"]*)" to the basket$`, iAddTheToTheBasket) s.Step(`^I add the "([^"]*)" to the basket$`, iAddTheToTheBasket)
s.Step(`^there is a "([^"]*)", which costs £(\d+)$`, thereIsAWhichCosts)
} }
""" """
@ -131,16 +131,16 @@ Feature: undefined step snippets
When I run feature suite When I run feature suite
And the undefined step snippets should be: And the undefined step snippets should be:
""" """
func whichCosts(arg1 string, arg2 int) error {
return godog.ErrPending
}
func godogs(arg1 int) error { func godogs(arg1 int) error {
return godog.ErrPending return godog.ErrPending
} }
func whichCosts(arg1 string, arg2 int) error {
return godog.ErrPending
}
func FeatureContext(s *godog.Suite) { func FeatureContext(s *godog.Suite) {
s.Step(`^"([^"]*)", which costs £(\d+)$`, whichCosts)
s.Step(`^(\d+) godogs$`, godogs) s.Step(`^(\d+) godogs$`, godogs)
s.Step(`^"([^"]*)", which costs £(\d+)$`, whichCosts)
} }
""" """

91
fmt.go
Просмотреть файл

@ -5,48 +5,18 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"reflect" "sort"
"regexp"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"text/template"
"time" "time"
"unicode" "unicode"
"github.com/cucumber/godog/colors"
"github.com/cucumber/messages-go/v10" "github.com/cucumber/messages-go/v10"
"github.com/cucumber/godog/colors"
) )
// some snippet formatting regexps
var snippetExprCleanup = regexp.MustCompile("([\\/\\[\\]\\(\\)\\\\^\\$\\.\\|\\?\\*\\+\\'])")
var snippetExprQuoted = regexp.MustCompile("(\\W|^)\"(?:[^\"]*)\"(\\W|$)")
var snippetMethodName = regexp.MustCompile("[^a-zA-Z\\_\\ ]")
var snippetNumbers = regexp.MustCompile("(\\d+)")
var snippetHelperFuncs = template.FuncMap{
"backticked": func(s string) string {
return "`" + s + "`"
},
}
var undefinedSnippetsTpl = template.Must(template.New("snippets").Funcs(snippetHelperFuncs).Parse(`
{{ range . }}func {{ .Method }}({{ .Args }}) error {
return godog.ErrPending
}
{{end}}func FeatureContext(s *godog.Suite) { {{ range . }}
s.Step({{ backticked .Expr }}, {{ .Method }}){{end}}
}
`))
type undefinedSnippet struct {
Method string
Expr string
argument *messages.PickleStepArgument
}
type registeredFormatter struct { type registeredFormatter struct {
name string name string
fmt FormatterFunc fmt FormatterFunc
@ -438,55 +408,6 @@ func (f *basefmt) Copy(cf ConcurrentFormatter) {
} }
} }
func (s *undefinedSnippet) Args() (ret string) {
var (
args []string
pos int
breakLoop bool
)
for !breakLoop {
part := s.Expr[pos:]
ipos := strings.Index(part, "(\\d+)")
spos := strings.Index(part, "\"([^\"]*)\"")
switch {
case spos == -1 && ipos == -1:
breakLoop = true
case spos == -1:
pos += ipos + len("(\\d+)")
args = append(args, reflect.Int.String())
case ipos == -1:
pos += spos + len("\"([^\"]*)\"")
args = append(args, reflect.String.String())
case ipos < spos:
pos += ipos + len("(\\d+)")
args = append(args, reflect.Int.String())
case spos < ipos:
pos += spos + len("\"([^\"]*)\"")
args = append(args, reflect.String.String())
}
}
if s.argument != nil {
if s.argument.GetDocString() != nil {
args = append(args, "*messages.PickleStepArgument_PickleDocString")
}
if s.argument.GetDataTable() != nil {
args = append(args, "*messages.PickleStepArgument_PickleTable")
}
}
var last string
for i, arg := range args {
if last == "" || last == arg {
ret += fmt.Sprintf("arg%d, ", i+1)
} else {
ret = strings.TrimRight(ret, ", ") + fmt.Sprintf(" %s, arg%d, ", last, i+1)
}
last = arg
}
return strings.TrimSpace(strings.TrimRight(ret, ", ") + " " + last)
}
func (f *basefmt) findStepResults(status stepResultStatus) (res []*stepResult) { func (f *basefmt) findStepResults(status stepResultStatus) (res []*stepResult) {
for _, feat := range f.features { for _, feat := range f.features {
for _, pr := range feat.pickleResults { for _, pr := range feat.pickleResults {
@ -508,7 +429,7 @@ func (f *basefmt) snippets() string {
} }
var index int var index int
var snips []*undefinedSnippet var snips []undefinedSnippet
// build snippets // build snippets
for _, u := range undefinedStepResults { for _, u := range undefinedStepResults {
steps := []string{u.step.Text} steps := []string{u.step.Text}
@ -550,11 +471,13 @@ func (f *basefmt) snippets() string {
} }
} }
if !found { if !found {
snips = append(snips, &undefinedSnippet{Method: name, Expr: expr, argument: arg}) snips = append(snips, undefinedSnippet{Method: name, Expr: expr, argument: arg})
} }
} }
} }
sort.Sort(snippetSortByMethod(snips))
var buf bytes.Buffer var buf bytes.Buffer
if err := undefinedSnippetsTpl.Execute(&buf, snips); err != nil { if err := undefinedSnippetsTpl.Execute(&buf, snips); err != nil {
panic(err) panic(err)

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

@ -67,17 +67,17 @@ func TestProgressFormatterOutput(t *testing.T) {
You can implement step definitions for undefined steps with these snippets: You can implement step definitions for undefined steps with these snippets:
func undefined() error {
return godog.ErrPending
}
func nextUndefined() error { func nextUndefined() error {
return godog.ErrPending return godog.ErrPending
} }
func undefined() error {
return godog.ErrPending
}
func FeatureContext(s *godog.Suite) { func FeatureContext(s *godog.Suite) {
s.Step(` + "`^undefined$`" + `, undefined)
s.Step(` + "`^next undefined$`" + `, nextUndefined) s.Step(` + "`^next undefined$`" + `, nextUndefined)
s.Step(` + "`^undefined$`" + `, undefined)
} }
` `
@ -237,7 +237,7 @@ func TestProgressFormatterMultistepTemplates(t *testing.T) {
You can implement step definitions for undefined steps with these snippets: You can implement step definitions for undefined steps with these snippets:
func undef() error { func three() error {
return godog.ErrPending return godog.ErrPending
} }
@ -245,14 +245,14 @@ func unavailableCost(arg1 string, arg2 int) error {
return godog.ErrPending return godog.ErrPending
} }
func three() error { func undef() error {
return godog.ErrPending return godog.ErrPending
} }
func FeatureContext(s *godog.Suite) { func FeatureContext(s *godog.Suite) {
s.Step(` + "`^undef$`" + `, undef)
s.Step(` + "`^unavailable \"([^\"]*)\" cost (\\d+)$`" + `, unavailableCost)
s.Step(` + "`^three$`" + `, three) s.Step(` + "`^three$`" + `, three)
s.Step(` + "`^unavailable \"([^\"]*)\" cost (\\d+)$`" + `, unavailableCost)
s.Step(` + "`^undef$`" + `, undef)
} }
` `

108
undefined_snippets_gen.go Обычный файл
Просмотреть файл

@ -0,0 +1,108 @@
package godog
import (
"fmt"
"reflect"
"regexp"
"strings"
"text/template"
"github.com/cucumber/messages-go/v10"
)
// some snippet formatting regexps
var snippetExprCleanup = regexp.MustCompile("([\\/\\[\\]\\(\\)\\\\^\\$\\.\\|\\?\\*\\+\\'])")
var snippetExprQuoted = regexp.MustCompile("(\\W|^)\"(?:[^\"]*)\"(\\W|$)")
var snippetMethodName = regexp.MustCompile("[^a-zA-Z\\_\\ ]")
var snippetNumbers = regexp.MustCompile("(\\d+)")
var snippetHelperFuncs = template.FuncMap{
"backticked": func(s string) string {
return "`" + s + "`"
},
}
var undefinedSnippetsTpl = template.Must(template.New("snippets").Funcs(snippetHelperFuncs).Parse(`
{{ range . }}func {{ .Method }}({{ .Args }}) error {
return godog.ErrPending
}
{{end}}func FeatureContext(s *godog.Suite) { {{ range . }}
s.Step({{ backticked .Expr }}, {{ .Method }}){{end}}
}
`))
type undefinedSnippet struct {
Method string
Expr string
argument *messages.PickleStepArgument
}
func (s undefinedSnippet) Args() (ret string) {
var (
args []string
pos int
breakLoop bool
)
for !breakLoop {
part := s.Expr[pos:]
ipos := strings.Index(part, "(\\d+)")
spos := strings.Index(part, "\"([^\"]*)\"")
switch {
case spos == -1 && ipos == -1:
breakLoop = true
case spos == -1:
pos += ipos + len("(\\d+)")
args = append(args, reflect.Int.String())
case ipos == -1:
pos += spos + len("\"([^\"]*)\"")
args = append(args, reflect.String.String())
case ipos < spos:
pos += ipos + len("(\\d+)")
args = append(args, reflect.Int.String())
case spos < ipos:
pos += spos + len("\"([^\"]*)\"")
args = append(args, reflect.String.String())
}
}
if s.argument != nil {
if s.argument.GetDocString() != nil {
args = append(args, "*messages.PickleStepArgument_PickleDocString")
}
if s.argument.GetDataTable() != nil {
args = append(args, "*messages.PickleStepArgument_PickleTable")
}
}
var last string
for i, arg := range args {
if last == "" || last == arg {
ret += fmt.Sprintf("arg%d, ", i+1)
} else {
ret = strings.TrimRight(ret, ", ") + fmt.Sprintf(" %s, arg%d, ", last, i+1)
}
last = arg
}
return strings.TrimSpace(strings.TrimRight(ret, ", ") + " " + last)
}
type snippetSortByMethod []undefinedSnippet
func (s snippetSortByMethod) Len() int {
return len(s)
}
func (s snippetSortByMethod) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
func (s snippetSortByMethod) Less(i, j int) bool {
return s[i].Method < s[j].Method
}