Merge pull request #310 from cucumber/remove-fmt-states

Refactored some states in the formatters and feature struct
Этот коммит содержится в:
Fredrik Lönnblad 2020-06-14 12:12:48 +02:00 коммит произвёл GitHub
родитель a03a1b8d2c b717039e16
коммит 57422f2015
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
13 изменённых файлов: 84 добавлений и 122 удалений

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

@ -7,9 +7,7 @@ import (
type feature struct {
*messages.GherkinDocument
pickles []*messages.Pickle
content []byte
order int
}
type sortFeaturesByName []*feature
@ -18,12 +16,6 @@ func (s sortFeaturesByName) Len() int { return len(s) }
func (s sortFeaturesByName) Less(i, j int) bool { return s[i].Feature.Name < s[j].Feature.Name }
func (s sortFeaturesByName) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type sortFeaturesByOrder []*feature
func (s sortFeaturesByOrder) Len() int { return len(s) }
func (s sortFeaturesByOrder) Less(i, j int) bool { return s[i].order < s[j].order }
func (s sortFeaturesByOrder) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (f feature) findScenario(astScenarioID string) *messages.GherkinDocument_Feature_Scenario {
for _, child := range f.GherkinDocument.Feature.Children {
if sc := child.GetScenario(); sc != nil && sc.Id == astScenarioID {

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

@ -9,7 +9,6 @@ import (
"strconv"
"strings"
"sync"
"time"
"unicode"
"github.com/cucumber/messages-go/v10"
@ -20,7 +19,6 @@ import (
func newBaseFmt(suite string, out io.Writer) *basefmt {
return &basefmt{
suiteName: suite,
startedAt: timeNowFunc(),
indent: 2,
out: out,
lock: new(sync.Mutex),
@ -29,42 +27,24 @@ func newBaseFmt(suite string, out io.Writer) *basefmt {
type basefmt struct {
suiteName string
out io.Writer
owner interface{}
indent int
storage *storage
startedAt time.Time
firstFeature *bool
lock *sync.Mutex
}
func (f *basefmt) setStorage(st *storage) {
f.lock.Lock()
defer f.lock.Unlock()
f.storage = st
}
func (f *basefmt) TestRunStarted() {
f.lock.Lock()
defer f.lock.Unlock()
firstFeature := true
f.firstFeature = &firstFeature
}
func (f *basefmt) TestRunStarted() {}
func (f *basefmt) Feature(ft *messages.GherkinDocument, p string, c []byte) {}
func (f *basefmt) Pickle(p *messages.Pickle) {}
func (f *basefmt) Defined(*messages.Pickle, *messages.Pickle_PickleStep, *StepDefinition) {}
func (f *basefmt) Feature(ft *messages.GherkinDocument, p string, c []byte) {
f.lock.Lock()
defer f.lock.Unlock()
*f.firstFeature = false
}
func (f *basefmt) Passed(pickle *messages.Pickle, step *messages.Pickle_PickleStep, match *StepDefinition) {
}
func (f *basefmt) Skipped(pickle *messages.Pickle, step *messages.Pickle_PickleStep, match *StepDefinition) {
@ -145,7 +125,9 @@ func (f *basefmt) Summary() {
scenarios = append(scenarios, green(fmt.Sprintf("%d passed", passedSc)))
}
scenarios = append(scenarios, parts...)
elapsed := timeNowFunc().Sub(f.startedAt)
testRunStartedAt := f.storage.mustGetTestRunStarted().StartedAt
elapsed := timeNowFunc().Sub(testRunStartedAt)
fmt.Fprintln(f.out, "")
@ -182,15 +164,6 @@ func (f *basefmt) Summary() {
}
}
func (f *basefmt) Sync(cf ConcurrentFormatter) {
if source, ok := cf.(*basefmt); ok {
f.lock = source.lock
f.firstFeature = source.firstFeature
}
}
func (f *basefmt) Copy(cf ConcurrentFormatter) {}
func (f *basefmt) snippets() string {
undefinedStepResults := f.storage.mustGetPickleStepResultsByStatus(undefined)
if len(undefinedStepResults) == 0 {

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

@ -46,18 +46,6 @@ func (f *cukefmt) Summary() {
fmt.Fprintf(f.out, "%s\n", string(dat))
}
func (f *cukefmt) Sync(cf ConcurrentFormatter) {
if source, ok := cf.(*cukefmt); ok {
f.basefmt.Sync(source.basefmt)
}
}
func (f *cukefmt) Copy(cf ConcurrentFormatter) {
if source, ok := cf.(*cukefmt); ok {
f.basefmt.Copy(source.basefmt)
}
}
func (f *cukefmt) buildCukeFeatures(features []*feature) (res []cukeFeatureJSON) {
sort.Sort(sortFeaturesByName(features))

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

@ -136,18 +136,6 @@ func (f *events) Summary() {
})
}
func (f *events) Sync(cf ConcurrentFormatter) {
if source, ok := cf.(*events); ok {
f.basefmt.Sync(source.basefmt)
}
}
func (f *events) Copy(cf ConcurrentFormatter) {
if source, ok := cf.(*events); ok {
f.basefmt.Copy(source.basefmt)
}
}
func (f *events) step(pickle *messages.Pickle, pickleStep *messages.Pickle_PickleStep) {
feature := f.storage.mustGetFeature(pickle.Uri)
pickleStepResult := f.storage.mustGetPickleStepResult(pickleStep.Id)

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

@ -37,18 +37,6 @@ func (f *junitFormatter) Summary() {
}
}
func (f *junitFormatter) Sync(cf ConcurrentFormatter) {
if source, ok := cf.(*junitFormatter); ok {
f.basefmt.Sync(source.basefmt)
}
}
func (f *junitFormatter) Copy(cf ConcurrentFormatter) {
if source, ok := cf.(*junitFormatter); ok {
f.basefmt.Copy(source.basefmt)
}
}
func junitTimeDuration(from, to time.Time) string {
return strconv.FormatFloat(to.Sub(from).Seconds(), 'f', -1, 64)
}
@ -57,10 +45,12 @@ func (f *junitFormatter) buildJUNITPackageSuite() junitPackageSuite {
features := f.storage.mustGetFeatures()
sort.Sort(sortFeaturesByName(features))
testRunStartedAt := f.storage.mustGetTestRunStarted().StartedAt
suite := junitPackageSuite{
Name: f.suiteName,
TestSuites: make([]*junitTestSuite, len(features)),
Time: junitTimeDuration(f.startedAt, timeNowFunc()),
Time: junitTimeDuration(testRunStartedAt, timeNowFunc()),
}
for idx, feature := range features {
@ -77,8 +67,8 @@ func (f *junitFormatter) buildJUNITPackageSuite() junitPackageSuite {
testcaseNames[pickle.Name] = testcaseNames[pickle.Name] + 1
}
firstPickleStartedAt := f.startedAt
lastPickleFinishedAt := f.startedAt
firstPickleStartedAt := testRunStartedAt
lastPickleFinishedAt := testRunStartedAt
var outlineNo = make(map[string]int)
for idx, pickle := range pickles {

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

@ -26,6 +26,17 @@ var outlinePlaceholderRegexp = regexp.MustCompile("<[^>]+>")
// a built in default pretty formatter
type pretty struct {
*basefmt
firstFeature *bool
}
func (f *pretty) TestRunStarted() {
f.basefmt.TestRunStarted()
f.lock.Lock()
defer f.lock.Unlock()
firstFeature := true
f.firstFeature = &firstFeature
}
func (f *pretty) Feature(gd *messages.GherkinDocument, p string, c []byte) {
@ -33,6 +44,8 @@ func (f *pretty) Feature(gd *messages.GherkinDocument, p string, c []byte) {
if !*f.firstFeature {
fmt.Fprintln(f.out, "")
}
*f.firstFeature = false
f.lock.Unlock()
f.basefmt.Feature(gd, p, c)
@ -101,18 +114,6 @@ func (f *pretty) Pending(pickle *messages.Pickle, step *messages.Pickle_PickleSt
f.printStep(pickle, step)
}
func (f *pretty) Sync(cf ConcurrentFormatter) {
if source, ok := cf.(*pretty); ok {
f.basefmt.Sync(source.basefmt)
}
}
func (f *pretty) Copy(cf ConcurrentFormatter) {
if source, ok := cf.(*pretty); ok {
f.basefmt.Copy(source.basefmt)
}
}
func (f *pretty) printFeature(feature *messages.GherkinDocument_Feature) {
fmt.Fprintln(f.out, keywordAndName(feature.Keyword, feature.Name))
if strings.TrimSpace(feature.Description) != "" {

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

@ -144,16 +144,3 @@ func (f *progress) Pending(pickle *messages.Pickle, step *messages.Pickle_Pickle
f.step(step.Id)
}
func (f *progress) Sync(cf ConcurrentFormatter) {
if source, ok := cf.(*progress); ok {
f.basefmt.Sync(source.basefmt)
f.steps = source.steps
}
}
func (f *progress) Copy(cf ConcurrentFormatter) {
if source, ok := cf.(*progress); ok {
f.basefmt.Copy(source.basefmt)
}
}

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

@ -7,7 +7,6 @@ import (
"os"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
@ -113,6 +112,7 @@ func parsePath(path string) ([]*feature, error) {
func parseFeatures(filter string, paths []string) ([]*feature, error) {
var order int
featureIdxs := make(map[string]int)
uniqueFeatureURI := make(map[string]*feature)
for _, path := range paths {
feats, err := parsePath(path)
@ -131,27 +131,34 @@ func parseFeatures(filter string, paths []string) ([]*feature, error) {
continue
}
ft.order = order
order++
uniqueFeatureURI[ft.Uri] = ft
featureIdxs[ft.Uri] = order
order++
}
}
return filterFeatures(filter, uniqueFeatureURI), nil
var features = make([]*feature, len(uniqueFeatureURI))
for uri, feature := range uniqueFeatureURI {
idx := featureIdxs[uri]
features[idx] = feature
}
features = filterFeatures(filter, features)
return features, nil
}
func filterFeatures(tags string, collected map[string]*feature) (features []*feature) {
for _, ft := range collected {
func filterFeatures(tags string, features []*feature) (result []*feature) {
for _, ft := range features {
ft.pickles = applyTagFilter(tags, ft.pickles)
if ft.Feature != nil {
features = append(features, ft)
result = append(result, ft)
}
}
sort.Sort(sortFeaturesByOrder(features))
return features
return
}
func applyTagFilter(tags string, pickles []*messages.Pickle) (result []*messages.Pickle) {

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

@ -6,6 +6,10 @@ import (
"github.com/cucumber/godog/colors"
)
type testRunStarted struct {
StartedAt time.Time
}
type pickleResult struct {
PickleID string
StartedAt time.Time

2
run.go
Просмотреть файл

@ -55,6 +55,8 @@ func (r *runner) concurrent(rate int, formatterFn func() Formatter) (failed bool
r.testSuiteInitializer(&testSuiteContext)
}
testRunStarted := testRunStarted{StartedAt: timeNowFunc()}
r.storage.mustInsertTestRunStarted(testRunStarted)
r.fmt.TestRunStarted()
// run before suite handlers

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

@ -2,6 +2,7 @@ package godog
import (
"fmt"
"sync"
"github.com/cucumber/messages-go/v10"
"github.com/hashicorp/go-memdb"
@ -32,6 +33,9 @@ const (
type storage struct {
db *memdb.MemDB
testRunStarted testRunStarted
lock *sync.Mutex
}
func newStorage() *storage {
@ -112,7 +116,7 @@ func newStorage() *storage {
panic(err)
}
return &storage{db}
return &storage{db: db, lock: new(sync.Mutex)}
}
func (s *storage) mustInsertPickle(p *messages.Pickle) {
@ -150,6 +154,20 @@ func (s *storage) mustGetPickleStep(id string) *messages.Pickle_PickleStep {
return v.(*messages.Pickle_PickleStep)
}
func (s *storage) mustInsertTestRunStarted(trs testRunStarted) {
s.lock.Lock()
defer s.lock.Unlock()
s.testRunStarted = trs
}
func (s *storage) mustGetTestRunStarted() testRunStarted {
s.lock.Lock()
defer s.lock.Unlock()
return s.testRunStarted
}
func (s *storage) mustInsertPickleResult(pr pickleResult) {
s.mustInsert(tablePickleResult, pr)
}

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

@ -195,6 +195,9 @@ func (s *suiteContext) iRunFeatureSuiteWithTags(tags string) error {
fmt.setStorage(s.testedSuite.storage)
s.testedSuite.fmt = fmt
testRunStarted := testRunStarted{StartedAt: timeNowFunc()}
s.testedSuite.storage.mustInsertTestRunStarted(testRunStarted)
s.testedSuite.fmt.TestRunStarted()
s.testedSuite.run()
s.testedSuite.fmt.Summary()
@ -226,6 +229,9 @@ func (s *suiteContext) iRunFeatureSuiteWithFormatter(name string) error {
fmt.setStorage(s.testedSuite.storage)
}
testRunStarted := testRunStarted{StartedAt: timeNowFunc()}
s.testedSuite.storage.mustInsertTestRunStarted(testRunStarted)
s.testedSuite.fmt.TestRunStarted()
s.testedSuite.run()
s.testedSuite.fmt.Summary()

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

@ -157,6 +157,9 @@ func (tc *godogFeaturesScenario) iRunFeatureSuiteWithTags(tags string) error {
fmt.setStorage(tc.testedSuite.storage)
tc.testedSuite.fmt = fmt
testRunStarted := testRunStarted{StartedAt: timeNowFunc()}
tc.testedSuite.storage.mustInsertTestRunStarted(testRunStarted)
tc.testedSuite.fmt.TestRunStarted()
tc.testedSuite.run()
tc.testedSuite.fmt.Summary()
@ -188,6 +191,9 @@ func (tc *godogFeaturesScenario) iRunFeatureSuiteWithFormatter(name string) erro
fmt.setStorage(tc.testedSuite.storage)
}
testRunStarted := testRunStarted{StartedAt: timeNowFunc()}
tc.testedSuite.storage.mustInsertTestRunStarted(testRunStarted)
tc.testedSuite.fmt.TestRunStarted()
tc.testedSuite.run()
tc.testedSuite.fmt.Summary()