Skip to content

Commit

Permalink
Merge pull request #310 from cucumber/remove-fmt-states
Browse files Browse the repository at this point in the history
Refactored some states in the formatters and feature struct
  • Loading branch information
lonnblad authored Jun 14, 2020
2 parents a03a1b8 + b717039 commit 57422f2
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 120 deletions.
8 changes: 0 additions & 8 deletions feature.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import (
type feature struct {
*messages.GherkinDocument
pickles []*messages.Pickle

content []byte
order int
}

type sortFeaturesByName []*feature
Expand All @@ -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 {
Expand Down
47 changes: 10 additions & 37 deletions fmt_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strconv"
"strings"
"sync"
"time"
"unicode"

"github.com/cucumber/messages-go/v10"
Expand All @@ -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),
Expand All @@ -29,42 +27,24 @@ func newBaseFmt(suite string, out io.Writer) *basefmt {

type basefmt struct {
suiteName string

out io.Writer
owner interface{}
indent int
out io.Writer
indent int

storage *storage

startedAt time.Time

firstFeature *bool
lock *sync.Mutex
lock *sync.Mutex
}

func (f *basefmt) setStorage(st *storage) {
f.storage = st
}

func (f *basefmt) TestRunStarted() {
f.lock.Lock()
defer f.lock.Unlock()

firstFeature := true
f.firstFeature = &firstFeature
f.storage = st
}

func (f *basefmt) Pickle(p *messages.Pickle) {}

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) {
Expand Down Expand Up @@ -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, "")

Expand Down Expand Up @@ -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 {
Expand Down
12 changes: 0 additions & 12 deletions fmt_cucumber.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down
12 changes: 0 additions & 12 deletions fmt_events.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
20 changes: 5 additions & 15 deletions fmt_junit.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down
25 changes: 13 additions & 12 deletions fmt_pretty.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,26 @@ 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) {
f.lock.Lock()
if !*f.firstFeature {
fmt.Fprintln(f.out, "")
}

*f.firstFeature = false
f.lock.Unlock()

f.basefmt.Feature(gd, p, c)
Expand Down Expand Up @@ -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) != "" {
Expand Down
13 changes: 0 additions & 13 deletions fmt_progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
27 changes: 17 additions & 10 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"os"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"

Expand Down Expand Up @@ -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)
Expand All @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions results.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import (
"github.com/cucumber/godog/colors"
)

type testRunStarted struct {
StartedAt time.Time
}

type pickleResult struct {
PickleID string
StartedAt time.Time
Expand Down
2 changes: 2 additions & 0 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 19 additions & 1 deletion storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package godog

import (
"fmt"
"sync"

"github.com/cucumber/messages-go/v10"
"github.com/hashicorp/go-memdb"
Expand Down Expand Up @@ -32,6 +33,9 @@ const (

type storage struct {
db *memdb.MemDB

testRunStarted testRunStarted
lock *sync.Mutex
}

func newStorage() *storage {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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)
}
Expand Down
Loading

0 comments on commit 57422f2

Please sign in to comment.