properly filters features by line and tags given

Этот коммит содержится в:
gedi 2017-10-24 16:02:18 +03:00
родитель 0093943021
коммит df188464c6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 56604CDCCC201556

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

@ -9,6 +9,7 @@ import (
"path/filepath"
"reflect"
"regexp"
"sort"
"strconv"
"strings"
"unicode/utf8"
@ -23,6 +24,8 @@ type feature struct {
*gherkin.Feature
Content []byte `json:"-"`
Path string `json:"path"`
scenarios map[int]bool
order int
}
// ErrUndefined is returned in case if step definition was not found
@ -607,16 +610,19 @@ func (s *Suite) printStepDefinitions(w io.Writer) {
}
}
func parseFeatures(filter string, paths []string) (features []*feature, err error) {
func parseFeatures(filter string, paths []string) ([]*feature, error) {
byPath := make(map[string]*feature)
var order int
for _, pat := range paths {
// check if line number is specified
parts := strings.Split(pat, ":")
path := parts[0]
line := -1
var err error
if len(parts) > 1 {
line, err = strconv.Atoi(parts[1])
if err != nil {
return features, fmt.Errorf("line number should follow after colon path delimiter")
return nil, fmt.Errorf("line number should follow after colon path delimiter")
}
}
// parse features
@ -632,9 +638,56 @@ func parseFeatures(filter string, paths []string) (features []*feature, err erro
if err != nil {
return fmt.Errorf("%s - %v", p, err)
}
features = append(features, &feature{Path: p, Feature: ft, Content: buf.Bytes()})
feat := byPath[p]
if feat == nil {
feat = &feature{
Path: p,
Feature: ft,
Content: buf.Bytes(),
scenarios: make(map[int]bool),
order: order,
}
order++
byPath[p] = feat
}
// filter scenario by line number
if line != -1 {
for _, def := range ft.ScenarioDefinitions {
var ln int
switch t := def.(type) {
case *gherkin.Scenario:
ln = t.Location.Line
case *gherkin.ScenarioOutline:
ln = t.Location.Line
}
if line == -1 || ln == line {
feat.scenarios[ln] = true
}
}
}
return err
})
// check error
switch {
case os.IsNotExist(err):
return nil, fmt.Errorf(`feature path "%s" is not available`, path)
case os.IsPermission(err):
return nil, fmt.Errorf(`feature path "%s" is not accessible`, path)
case err != nil:
return nil, err
}
}
return filterFeatures(filter, byPath), nil
}
type sortByOrderGiven []*feature
func (s sortByOrderGiven) Len() int { return len(s) }
func (s sortByOrderGiven) Less(i, j int) bool { return s[i].order < s[j].order }
func (s sortByOrderGiven) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func filterFeatures(tags string, collected map[string]*feature) (features []*feature) {
for _, ft := range collected {
var scenarios []interface{}
for _, def := range ft.ScenarioDefinitions {
var ln int
@ -644,28 +697,21 @@ func parseFeatures(filter string, paths []string) (features []*feature, err erro
case *gherkin.ScenarioOutline:
ln = t.Location.Line
}
if ln == line {
if ft.scenarios[ln] {
scenarios = append(scenarios, def)
break
}
}
ft.ScenarioDefinitions = scenarios
}
applyTagFilter(filter, ft)
}
return err
})
// check error
switch {
case os.IsNotExist(err):
return features, fmt.Errorf(`feature path "%s" is not available`, path)
case os.IsPermission(err):
return features, fmt.Errorf(`feature path "%s" is not accessible`, path)
case err != nil:
return features, err
applyTagFilter(tags, ft.Feature)
if len(ft.ScenarioDefinitions) > 0 {
features = append(features, ft)
}
}
return
sort.Sort(sortByOrderGiven(features))
return features
}
func applyTagFilter(tags string, ft *gherkin.Feature) {