properly filters features by line and tags given
Этот коммит содержится в:
родитель
0093943021
коммит
df188464c6
1 изменённых файлов: 72 добавлений и 26 удалений
98
suite.go
98
suite.go
|
@ -9,6 +9,7 @@ import (
|
|||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
@ -21,8 +22,10 @@ var typeOfBytes = reflect.TypeOf([]byte(nil))
|
|||
|
||||
type feature struct {
|
||||
*gherkin.Feature
|
||||
Content []byte `json:"-"`
|
||||
Path string `json:"path"`
|
||||
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,40 +638,80 @@ 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()})
|
||||
// filter scenario by line number
|
||||
if line != -1 {
|
||||
var scenarios []interface{}
|
||||
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 ln == line {
|
||||
scenarios = append(scenarios, def)
|
||||
break
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
}
|
||||
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)
|
||||
return nil, fmt.Errorf(`feature path "%s" is not available`, path)
|
||||
case os.IsPermission(err):
|
||||
return features, fmt.Errorf(`feature path "%s" is not accessible`, path)
|
||||
return nil, fmt.Errorf(`feature path "%s" is not accessible`, path)
|
||||
case err != nil:
|
||||
return features, err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return
|
||||
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
|
||||
switch t := def.(type) {
|
||||
case *gherkin.Scenario:
|
||||
ln = t.Location.Line
|
||||
case *gherkin.ScenarioOutline:
|
||||
ln = t.Location.Line
|
||||
}
|
||||
if ft.scenarios[ln] {
|
||||
scenarios = append(scenarios, def)
|
||||
}
|
||||
}
|
||||
ft.ScenarioDefinitions = scenarios
|
||||
applyTagFilter(tags, ft.Feature)
|
||||
|
||||
if len(ft.ScenarioDefinitions) > 0 {
|
||||
features = append(features, ft)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Sort(sortByOrderGiven(features))
|
||||
|
||||
return features
|
||||
}
|
||||
|
||||
func applyTagFilter(tags string, ft *gherkin.Feature) {
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче