Moved base concurrency support to the basefmt
Этот коммит содержится в:
родитель
3f817c89de
коммит
9b86360854
7 изменённых файлов: 93 добавлений и 155 удалений
66
fmt.go
66
fmt.go
|
@ -9,6 +9,7 @@ import (
|
|||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"text/template"
|
||||
"time"
|
||||
"unicode"
|
||||
|
@ -221,6 +222,16 @@ func (f stepResult) scenarioLine() string {
|
|||
return f.line() // was not expecting different owner
|
||||
}
|
||||
|
||||
func newBaseFmt(suite string, out io.Writer) *basefmt {
|
||||
return &basefmt{
|
||||
suiteName: suite,
|
||||
started: timeNowFunc(),
|
||||
indent: 2,
|
||||
out: out,
|
||||
lock: new(sync.Mutex),
|
||||
}
|
||||
}
|
||||
|
||||
type basefmt struct {
|
||||
suiteName string
|
||||
|
||||
|
@ -235,9 +246,14 @@ type basefmt struct {
|
|||
skipped []*stepResult
|
||||
undefined []*stepResult
|
||||
pending []*stepResult
|
||||
|
||||
lock *sync.Mutex
|
||||
}
|
||||
|
||||
func (f *basefmt) Node(n interface{}) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
switch t := n.(type) {
|
||||
case *gherkin.Scenario:
|
||||
f.owner = t
|
||||
|
@ -265,14 +281,21 @@ func (f *basefmt) Node(n interface{}) {
|
|||
}
|
||||
|
||||
func (f *basefmt) Defined(*gherkin.Step, *StepDef) {
|
||||
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
}
|
||||
|
||||
func (f *basefmt) Feature(ft *gherkin.Feature, p string, c []byte) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
f.features = append(f.features, &feature{Path: p, Feature: ft, time: timeNowFunc()})
|
||||
}
|
||||
|
||||
func (f *basefmt) Passed(step *gherkin.Step, match *StepDef) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
s := &stepResult{
|
||||
owner: f.owner,
|
||||
feature: f.features[len(f.features)-1],
|
||||
|
@ -287,6 +310,9 @@ func (f *basefmt) Passed(step *gherkin.Step, match *StepDef) {
|
|||
}
|
||||
|
||||
func (f *basefmt) Skipped(step *gherkin.Step, match *StepDef) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
s := &stepResult{
|
||||
owner: f.owner,
|
||||
feature: f.features[len(f.features)-1],
|
||||
|
@ -301,6 +327,9 @@ func (f *basefmt) Skipped(step *gherkin.Step, match *StepDef) {
|
|||
}
|
||||
|
||||
func (f *basefmt) Undefined(step *gherkin.Step, match *StepDef) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
s := &stepResult{
|
||||
owner: f.owner,
|
||||
feature: f.features[len(f.features)-1],
|
||||
|
@ -315,6 +344,9 @@ func (f *basefmt) Undefined(step *gherkin.Step, match *StepDef) {
|
|||
}
|
||||
|
||||
func (f *basefmt) Failed(step *gherkin.Step, match *StepDef, err error) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
s := &stepResult{
|
||||
owner: f.owner,
|
||||
feature: f.features[len(f.features)-1],
|
||||
|
@ -330,6 +362,9 @@ func (f *basefmt) Failed(step *gherkin.Step, match *StepDef, err error) {
|
|||
}
|
||||
|
||||
func (f *basefmt) Pending(step *gherkin.Step, match *StepDef) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
|
||||
s := &stepResult{
|
||||
owner: f.owner,
|
||||
feature: f.features[len(f.features)-1],
|
||||
|
@ -438,6 +473,35 @@ func (f *basefmt) Summary() {
|
|||
}
|
||||
}
|
||||
|
||||
func (f *basefmt) Sync(cf ConcurrentFormatter) {
|
||||
if source, ok := cf.(*basefmt); ok {
|
||||
f.lock = source.lock
|
||||
}
|
||||
}
|
||||
|
||||
func (f *basefmt) Copy(cf ConcurrentFormatter) {
|
||||
if source, ok := cf.(*basefmt); ok {
|
||||
for _, v := range source.features {
|
||||
f.features = append(f.features, v)
|
||||
}
|
||||
for _, v := range source.failed {
|
||||
f.failed = append(f.failed, v)
|
||||
}
|
||||
for _, v := range source.passed {
|
||||
f.passed = append(f.passed, v)
|
||||
}
|
||||
for _, v := range source.skipped {
|
||||
f.skipped = append(f.skipped, v)
|
||||
}
|
||||
for _, v := range source.undefined {
|
||||
f.undefined = append(f.undefined, v)
|
||||
}
|
||||
for _, v := range source.pending {
|
||||
f.pending = append(f.pending, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *undefinedSnippet) Args() (ret string) {
|
||||
var (
|
||||
args []string
|
||||
|
|
|
@ -27,15 +27,7 @@ func init() {
|
|||
}
|
||||
|
||||
func cucumberFunc(suite string, out io.Writer) Formatter {
|
||||
formatter := &cukefmt{
|
||||
basefmt: basefmt{
|
||||
started: timeNowFunc(),
|
||||
indent: 2,
|
||||
out: out,
|
||||
},
|
||||
}
|
||||
|
||||
return formatter
|
||||
return &cukefmt{basefmt: newBaseFmt(suite, out)}
|
||||
}
|
||||
|
||||
// Replace spaces with - This function is used to create the "id" fields of the cucumber output.
|
||||
|
@ -108,7 +100,7 @@ type cukeFeatureJSON struct {
|
|||
}
|
||||
|
||||
type cukefmt struct {
|
||||
basefmt
|
||||
*basefmt
|
||||
|
||||
// currently running feature path, to be part of id.
|
||||
// this is sadly not passed by gherkin nodes.
|
||||
|
|
|
@ -16,13 +16,7 @@ func init() {
|
|||
}
|
||||
|
||||
func eventsFunc(suite string, out io.Writer) Formatter {
|
||||
formatter := &events{
|
||||
basefmt: basefmt{
|
||||
started: timeNowFunc(),
|
||||
indent: 2,
|
||||
out: out,
|
||||
},
|
||||
}
|
||||
formatter := &events{basefmt: newBaseFmt(suite, out)}
|
||||
|
||||
formatter.event(&struct {
|
||||
Event string `json:"event"`
|
||||
|
@ -40,7 +34,7 @@ func eventsFunc(suite string, out io.Writer) Formatter {
|
|||
}
|
||||
|
||||
type events struct {
|
||||
basefmt
|
||||
*basefmt
|
||||
|
||||
// currently running feature path, to be part of id.
|
||||
// this is sadly not passed by gherkin nodes.
|
||||
|
|
79
fmt_junit.go
79
fmt_junit.go
|
@ -7,10 +7,7 @@ import (
|
|||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cucumber/godog/gherkin"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -18,32 +15,11 @@ func init() {
|
|||
}
|
||||
|
||||
func junitFunc(suite string, out io.Writer) Formatter {
|
||||
return &junitFormatter{
|
||||
basefmt: basefmt{
|
||||
suiteName: suite,
|
||||
started: timeNowFunc(),
|
||||
indent: 2,
|
||||
out: out,
|
||||
},
|
||||
lock: new(sync.Mutex),
|
||||
}
|
||||
return &junitFormatter{basefmt: newBaseFmt(suite, out)}
|
||||
}
|
||||
|
||||
type junitFormatter struct {
|
||||
basefmt
|
||||
lock *sync.Mutex
|
||||
}
|
||||
|
||||
func (f *junitFormatter) Node(n interface{}) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Node(n)
|
||||
}
|
||||
|
||||
func (f *junitFormatter) Feature(ft *gherkin.Feature, p string, c []byte) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Feature(ft, p, c)
|
||||
*basefmt
|
||||
}
|
||||
|
||||
func (f *junitFormatter) Summary() {
|
||||
|
@ -61,62 +37,15 @@ func (f *junitFormatter) Summary() {
|
|||
}
|
||||
}
|
||||
|
||||
func (f *junitFormatter) Passed(step *gherkin.Step, match *StepDef) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Passed(step, match)
|
||||
}
|
||||
|
||||
func (f *junitFormatter) Skipped(step *gherkin.Step, match *StepDef) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Skipped(step, match)
|
||||
}
|
||||
|
||||
func (f *junitFormatter) Undefined(step *gherkin.Step, match *StepDef) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Undefined(step, match)
|
||||
}
|
||||
|
||||
func (f *junitFormatter) Failed(step *gherkin.Step, match *StepDef, err error) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Failed(step, match, err)
|
||||
}
|
||||
|
||||
func (f *junitFormatter) Pending(step *gherkin.Step, match *StepDef) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Pending(step, match)
|
||||
}
|
||||
|
||||
func (f *junitFormatter) Sync(cf ConcurrentFormatter) {
|
||||
if source, ok := cf.(*junitFormatter); ok {
|
||||
f.lock = source.lock
|
||||
f.basefmt.Sync(source.basefmt)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *junitFormatter) Copy(cf ConcurrentFormatter) {
|
||||
if source, ok := cf.(*junitFormatter); ok {
|
||||
for _, v := range source.features {
|
||||
f.features = append(f.features, v)
|
||||
}
|
||||
for _, v := range source.failed {
|
||||
f.failed = append(f.failed, v)
|
||||
}
|
||||
for _, v := range source.passed {
|
||||
f.passed = append(f.passed, v)
|
||||
}
|
||||
for _, v := range source.skipped {
|
||||
f.skipped = append(f.skipped, v)
|
||||
}
|
||||
for _, v := range source.undefined {
|
||||
f.undefined = append(f.undefined, v)
|
||||
}
|
||||
for _, v := range source.pending {
|
||||
f.pending = append(f.pending, v)
|
||||
}
|
||||
f.basefmt.Copy(source.basefmt)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,20 +17,14 @@ func init() {
|
|||
}
|
||||
|
||||
func prettyFunc(suite string, out io.Writer) Formatter {
|
||||
return &pretty{
|
||||
basefmt: basefmt{
|
||||
started: timeNowFunc(),
|
||||
indent: 2,
|
||||
out: out,
|
||||
},
|
||||
}
|
||||
return &pretty{basefmt: newBaseFmt(suite, out)}
|
||||
}
|
||||
|
||||
var outlinePlaceholderRegexp = regexp.MustCompile("<[^>]+>")
|
||||
|
||||
// a built in default pretty formatter
|
||||
type pretty struct {
|
||||
basefmt
|
||||
*basefmt
|
||||
|
||||
// currently processed
|
||||
feature *gherkin.Feature
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"io"
|
||||
"math"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/cucumber/godog/gherkin"
|
||||
)
|
||||
|
@ -17,36 +16,18 @@ func init() {
|
|||
func progressFunc(suite string, out io.Writer) Formatter {
|
||||
steps := 0
|
||||
return &progress{
|
||||
basefmt: basefmt{
|
||||
started: timeNowFunc(),
|
||||
indent: 2,
|
||||
out: out,
|
||||
},
|
||||
basefmt: newBaseFmt(suite, out),
|
||||
stepsPerRow: 70,
|
||||
lock: new(sync.Mutex),
|
||||
steps: &steps,
|
||||
}
|
||||
}
|
||||
|
||||
type progress struct {
|
||||
basefmt
|
||||
lock *sync.Mutex
|
||||
*basefmt
|
||||
stepsPerRow int
|
||||
steps *int
|
||||
}
|
||||
|
||||
func (f *progress) Node(n interface{}) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Node(n)
|
||||
}
|
||||
|
||||
func (f *progress) Feature(ft *gherkin.Feature, p string, c []byte) {
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Feature(ft, p, c)
|
||||
}
|
||||
|
||||
func (f *progress) Summary() {
|
||||
left := math.Mod(float64(*f.steps), float64(f.stepsPerRow))
|
||||
if left != 0 {
|
||||
|
@ -82,73 +63,63 @@ func (f *progress) step(res *stepResult) {
|
|||
case pending:
|
||||
fmt.Fprint(f.out, yellow("P"))
|
||||
}
|
||||
|
||||
*f.steps++
|
||||
|
||||
if math.Mod(float64(*f.steps), float64(f.stepsPerRow)) == 0 {
|
||||
fmt.Fprintf(f.out, " %d\n", *f.steps)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *progress) Passed(step *gherkin.Step, match *StepDef) {
|
||||
f.basefmt.Passed(step, match)
|
||||
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Passed(step, match)
|
||||
f.step(f.passed[len(f.passed)-1])
|
||||
}
|
||||
|
||||
func (f *progress) Skipped(step *gherkin.Step, match *StepDef) {
|
||||
f.basefmt.Skipped(step, match)
|
||||
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Skipped(step, match)
|
||||
f.step(f.skipped[len(f.skipped)-1])
|
||||
}
|
||||
|
||||
func (f *progress) Undefined(step *gherkin.Step, match *StepDef) {
|
||||
f.basefmt.Undefined(step, match)
|
||||
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Undefined(step, match)
|
||||
f.step(f.undefined[len(f.undefined)-1])
|
||||
}
|
||||
|
||||
func (f *progress) Failed(step *gherkin.Step, match *StepDef, err error) {
|
||||
f.basefmt.Failed(step, match, err)
|
||||
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Failed(step, match, err)
|
||||
f.step(f.failed[len(f.failed)-1])
|
||||
}
|
||||
|
||||
func (f *progress) Pending(step *gherkin.Step, match *StepDef) {
|
||||
f.basefmt.Pending(step, match)
|
||||
|
||||
f.lock.Lock()
|
||||
defer f.lock.Unlock()
|
||||
f.basefmt.Pending(step, match)
|
||||
f.step(f.pending[len(f.pending)-1])
|
||||
}
|
||||
|
||||
func (f *progress) Sync(cf ConcurrentFormatter) {
|
||||
if source, ok := cf.(*progress); ok {
|
||||
f.lock = source.lock
|
||||
f.basefmt.Sync(source.basefmt)
|
||||
f.steps = source.steps
|
||||
}
|
||||
}
|
||||
|
||||
func (f *progress) Copy(cf ConcurrentFormatter) {
|
||||
if source, ok := cf.(*progress); ok {
|
||||
for _, v := range source.features {
|
||||
f.features = append(f.features, v)
|
||||
}
|
||||
for _, v := range source.failed {
|
||||
f.failed = append(f.failed, v)
|
||||
}
|
||||
for _, v := range source.passed {
|
||||
f.passed = append(f.passed, v)
|
||||
}
|
||||
for _, v := range source.skipped {
|
||||
f.skipped = append(f.skipped, v)
|
||||
}
|
||||
for _, v := range source.undefined {
|
||||
f.undefined = append(f.undefined, v)
|
||||
}
|
||||
for _, v := range source.pending {
|
||||
f.pending = append(f.pending, v)
|
||||
}
|
||||
f.basefmt.Copy(source.basefmt)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -529,18 +529,12 @@ func (s *suiteContext) theRenderXMLWillBe(docstring *gherkin.DocString) error {
|
|||
}
|
||||
|
||||
type testFormatter struct {
|
||||
basefmt
|
||||
*basefmt
|
||||
scenarios []interface{}
|
||||
}
|
||||
|
||||
func testFormatterFunc(suite string, out io.Writer) Formatter {
|
||||
return &testFormatter{
|
||||
basefmt: basefmt{
|
||||
started: timeNowFunc(),
|
||||
indent: 2,
|
||||
out: out,
|
||||
},
|
||||
}
|
||||
return &testFormatter{basefmt: newBaseFmt(suite, out)}
|
||||
}
|
||||
|
||||
func (f *testFormatter) Node(node interface{}) {
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче