Export internal formatters (#372)
Этот коммит содержится в:
родитель
ad7feb3298
коммит
c6c2a0885b
19 изменённых файлов: 584 добавлений и 304 удалений
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -13,11 +13,12 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for step definitions without return ([364](https://github.com/cucumber/godog/pull/364) - [titouanfreville])
|
- Support for step definitions without return ([364](https://github.com/cucumber/godog/pull/364) - [titouanfreville])
|
||||||
- Contextualized hooks for scenarios and steps ([409](https://github.com/cucumber/godog/pull/409)) - [vearutop])
|
- Contextualized hooks for scenarios and steps ([409](https://github.com/cucumber/godog/pull/409) - [vearutop])
|
||||||
- Step result status in After hook ([409](https://github.com/cucumber/godog/pull/409)) - [vearutop])
|
- Step result status in After hook ([409](https://github.com/cucumber/godog/pull/409) - [vearutop])
|
||||||
- Support auto converting doc strings to plain strings ([380](https://github.com/cucumber/godog/pull/380)) - [chirino])
|
- Support auto converting doc strings to plain strings ([380](https://github.com/cucumber/godog/pull/380) - [chirino])
|
||||||
- Use multiple formatters in the same test run ([392](https://github.com/cucumber/godog/pull/392)) - [vearutop])
|
- Use multiple formatters in the same test run ([392](https://github.com/cucumber/godog/pull/392) - [vearutop])
|
||||||
- Added `RetrieveFeatures()` method to `godog.TestSuite` ([276](https://github.com/cucumber/godog/pull/276)) - [radtriste])
|
- Added `RetrieveFeatures()` method to `godog.TestSuite` ([276](https://github.com/cucumber/godog/pull/276) - [radtriste])
|
||||||
|
- Added support to create custom formatters ([372](https://github.com/cucumber/godog/pull/372) - [leviable])
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|
19
_examples/custom-formatter/README.md
Обычный файл
19
_examples/custom-formatter/README.md
Обычный файл
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
# Custom Formatter Example
|
||||||
|
|
||||||
|
This example custom formatter demonstrates some ways to build and use custom formatters with godog
|
||||||
|
|
||||||
|
|
||||||
|
## Emoji Progress
|
||||||
|
|
||||||
|
The first example is the Emoji formatter, built on top of the Progress formatter that is included with godog.
|
||||||
|
|
||||||
|
To run it:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ godog -f emoji
|
||||||
|
```
|
||||||
|
|
||||||
|
Which would output step progress as emojis rather than text:
|
||||||
|
|
||||||
|

|
|
@ -1,32 +0,0 @@
|
||||||
package customformatter
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/cucumber/godog"
|
|
||||||
"github.com/cucumber/messages-go/v16"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
godog.Format("custom", "Custom formatter", customFormatterFunc)
|
|
||||||
}
|
|
||||||
|
|
||||||
func customFormatterFunc(suite string, out io.Writer) godog.Formatter {
|
|
||||||
return &customFmt{suiteName: suite, out: out}
|
|
||||||
}
|
|
||||||
|
|
||||||
type customFmt struct {
|
|
||||||
suiteName string
|
|
||||||
out io.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *customFmt) TestRunStarted() {}
|
|
||||||
func (f *customFmt) Feature(*messages.GherkinDocument, string, []byte) {}
|
|
||||||
func (f *customFmt) Pickle(*godog.Scenario) {}
|
|
||||||
func (f *customFmt) Defined(*godog.Scenario, *godog.Step, *godog.StepDefinition) {}
|
|
||||||
func (f *customFmt) Passed(*godog.Scenario, *godog.Step, *godog.StepDefinition) {}
|
|
||||||
func (f *customFmt) Skipped(*godog.Scenario, *godog.Step, *godog.StepDefinition) {}
|
|
||||||
func (f *customFmt) Undefined(*godog.Scenario, *godog.Step, *godog.StepDefinition) {}
|
|
||||||
func (f *customFmt) Failed(*godog.Scenario, *godog.Step, *godog.StepDefinition, error) {}
|
|
||||||
func (f *customFmt) Pending(*godog.Scenario, *godog.Step, *godog.StepDefinition) {}
|
|
||||||
func (f *customFmt) Summary() {}
|
|
122
_examples/custom-formatter/emoji.go
Обычный файл
122
_examples/custom-formatter/emoji.go
Обычный файл
|
@ -0,0 +1,122 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/cucumber/godog"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
passedEmoji = "✅"
|
||||||
|
skippedEmoji = "➖"
|
||||||
|
failedEmoji = "❌"
|
||||||
|
undefinedEmoji = "❓"
|
||||||
|
pendingEmoji = "🚧"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
godog.Format("emoji", "Progress formatter with emojis", emojiFormatterFunc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func emojiFormatterFunc(suite string, out io.Writer) godog.Formatter {
|
||||||
|
return newEmojiFmt(suite, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newEmojiFmt(suite string, out io.Writer) *emojiFmt {
|
||||||
|
return &emojiFmt{
|
||||||
|
ProgressFmt: godog.NewProgressFmt(suite, out),
|
||||||
|
out: out,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type emojiFmt struct {
|
||||||
|
*godog.ProgressFmt
|
||||||
|
|
||||||
|
out io.Writer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *emojiFmt) TestRunStarted() {}
|
||||||
|
|
||||||
|
func (f *emojiFmt) Passed(scenario *godog.Scenario, step *godog.Step, match *godog.StepDefinition) {
|
||||||
|
f.ProgressFmt.Base.Passed(scenario, step, match)
|
||||||
|
|
||||||
|
f.ProgressFmt.Base.Lock.Lock()
|
||||||
|
defer f.ProgressFmt.Base.Lock.Unlock()
|
||||||
|
|
||||||
|
f.step(step.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *emojiFmt) Skipped(scenario *godog.Scenario, step *godog.Step, match *godog.StepDefinition) {
|
||||||
|
f.ProgressFmt.Base.Skipped(scenario, step, match)
|
||||||
|
|
||||||
|
f.ProgressFmt.Base.Lock.Lock()
|
||||||
|
defer f.ProgressFmt.Base.Lock.Unlock()
|
||||||
|
|
||||||
|
f.step(step.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *emojiFmt) Undefined(scenario *godog.Scenario, step *godog.Step, match *godog.StepDefinition) {
|
||||||
|
f.ProgressFmt.Base.Undefined(scenario, step, match)
|
||||||
|
|
||||||
|
f.ProgressFmt.Base.Lock.Lock()
|
||||||
|
defer f.ProgressFmt.Base.Lock.Unlock()
|
||||||
|
|
||||||
|
f.step(step.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *emojiFmt) Failed(scenario *godog.Scenario, step *godog.Step, match *godog.StepDefinition, err error) {
|
||||||
|
f.ProgressFmt.Base.Failed(scenario, step, match, err)
|
||||||
|
|
||||||
|
f.ProgressFmt.Base.Lock.Lock()
|
||||||
|
defer f.ProgressFmt.Base.Lock.Unlock()
|
||||||
|
|
||||||
|
f.step(step.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *emojiFmt) Pending(scenario *godog.Scenario, step *godog.Step, match *godog.StepDefinition) {
|
||||||
|
f.ProgressFmt.Base.Pending(scenario, step, match)
|
||||||
|
|
||||||
|
f.ProgressFmt.Base.Lock.Lock()
|
||||||
|
defer f.ProgressFmt.Base.Lock.Unlock()
|
||||||
|
|
||||||
|
f.step(step.Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *emojiFmt) Summary() {
|
||||||
|
f.printSummaryLegend()
|
||||||
|
f.ProgressFmt.Summary()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *emojiFmt) printSummaryLegend() {
|
||||||
|
fmt.Fprint(f.out, "\n\nOutput Legend:\n")
|
||||||
|
fmt.Fprint(f.out, fmt.Sprintf("\t%s Passed\n", passedEmoji))
|
||||||
|
fmt.Fprint(f.out, fmt.Sprintf("\t%s Failed\n", failedEmoji))
|
||||||
|
fmt.Fprint(f.out, fmt.Sprintf("\t%s Skipped\n", skippedEmoji))
|
||||||
|
fmt.Fprint(f.out, fmt.Sprintf("\t%s Undefined\n", undefinedEmoji))
|
||||||
|
fmt.Fprint(f.out, fmt.Sprintf("\t%s Pending\n", pendingEmoji))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *emojiFmt) step(pickleStepID string) {
|
||||||
|
pickleStepResult := f.Storage.MustGetPickleStepResult(pickleStepID)
|
||||||
|
|
||||||
|
switch pickleStepResult.Status {
|
||||||
|
case godog.StepPassed:
|
||||||
|
fmt.Fprint(f.out, fmt.Sprintf(" %s", passedEmoji))
|
||||||
|
case godog.StepSkipped:
|
||||||
|
fmt.Fprint(f.out, fmt.Sprintf(" %s", skippedEmoji))
|
||||||
|
case godog.StepFailed:
|
||||||
|
fmt.Fprint(f.out, fmt.Sprintf(" %s", failedEmoji))
|
||||||
|
case godog.StepUndefined:
|
||||||
|
fmt.Fprint(f.out, fmt.Sprintf(" %s", undefinedEmoji))
|
||||||
|
case godog.StepPending:
|
||||||
|
fmt.Fprint(f.out, fmt.Sprintf(" %s", pendingEmoji))
|
||||||
|
}
|
||||||
|
|
||||||
|
*f.Steps++
|
||||||
|
|
||||||
|
if math.Mod(float64(*f.Steps), float64(f.StepsPerRow)) == 0 {
|
||||||
|
fmt.Fprintf(f.out, " %d\n", *f.Steps)
|
||||||
|
}
|
||||||
|
}
|
26
_examples/custom-formatter/features/emoji.feature
Обычный файл
26
_examples/custom-formatter/features/emoji.feature
Обычный файл
|
@ -0,0 +1,26 @@
|
||||||
|
# file: $GOPATH/godogs/features/godogs.feature
|
||||||
|
Feature: Custom emoji formatter examples
|
||||||
|
In order to be happy
|
||||||
|
As a hungry gopher
|
||||||
|
I need to be able to eat godogs
|
||||||
|
|
||||||
|
Scenario: Passing test
|
||||||
|
Given there are 12 godogs
|
||||||
|
When I eat 5
|
||||||
|
Then there should be 7 remaining
|
||||||
|
|
||||||
|
Scenario: Failing and Skipped test
|
||||||
|
Given there are 12 godogs
|
||||||
|
When I eat 5
|
||||||
|
Then there should be 6 remaining
|
||||||
|
And there should be 4 remaining
|
||||||
|
|
||||||
|
Scenario: Undefined steps
|
||||||
|
Given there are 12 godogs
|
||||||
|
When I eat 5
|
||||||
|
Then this step is not defined
|
||||||
|
|
||||||
|
Scenario: Pending step
|
||||||
|
Given there are 12 godogs
|
||||||
|
When I eat 5
|
||||||
|
Then this step is pending
|
|
@ -3,10 +3,11 @@ module custom-formatter
|
||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/cucumber/gherkin-go/v11 v11.0.0 // indirect
|
|
||||||
github.com/cucumber/godog v0.10.1-0.20210705192606-df8c6e49b40b
|
github.com/cucumber/godog v0.10.1-0.20210705192606-df8c6e49b40b
|
||||||
github.com/cucumber/messages-go/v10 v10.0.3 // indirect
|
|
||||||
github.com/cucumber/messages-go/v16 v16.0.1
|
|
||||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||||
github.com/hashicorp/go-memdb v1.3.2 // indirect
|
github.com/hashicorp/go-memdb v1.3.2 // indirect
|
||||||
|
github.com/kr/text v0.2.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace github.com/cucumber/godog => ../..
|
||||||
|
|
|
@ -19,7 +19,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
github.com/aslakhellesoy/gox v1.0.100/go.mod h1:AJl542QsKKG96COVsv0N74HHzVQgDIQPceVUh1aeU2M=
|
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
|
@ -33,19 +32,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/cucumber/gherkin-go/v11 v11.0.0 h1:cwVwN1Qn2VRSfHZNLEh5x00tPBmZcjATBWDpxsR5Xug=
|
|
||||||
github.com/cucumber/gherkin-go/v11 v11.0.0/go.mod h1:CX33k2XU2qog4e+TFjOValoq6mIUq0DmVccZs238R9w=
|
|
||||||
github.com/cucumber/gherkin-go/v19 v19.0.3 h1:mMSKu1077ffLbTJULUfM5HPokgeBcIGboyeNUof1MdE=
|
github.com/cucumber/gherkin-go/v19 v19.0.3 h1:mMSKu1077ffLbTJULUfM5HPokgeBcIGboyeNUof1MdE=
|
||||||
github.com/cucumber/gherkin-go/v19 v19.0.3/go.mod h1:jY/NP6jUtRSArQQJ5h1FXOUgk5fZK24qtE7vKi776Vw=
|
github.com/cucumber/gherkin-go/v19 v19.0.3/go.mod h1:jY/NP6jUtRSArQQJ5h1FXOUgk5fZK24qtE7vKi776Vw=
|
||||||
github.com/cucumber/godog v0.10.1-0.20210705192606-df8c6e49b40b h1:TthfOM7c3wz2M5kUvktCU27WXufvUSV/YtcxQk2yaq8=
|
|
||||||
github.com/cucumber/godog v0.10.1-0.20210705192606-df8c6e49b40b/go.mod h1:ql2U1OH5nlLZ2UDD/3fDJ1+0vkib0XGgEn8NYXCwDZQ=
|
|
||||||
github.com/cucumber/godog v0.11.0 h1:xgaWyJuAD6A+aW4TfVGNDBhuMyKW0jjl0cvY3KNxEak=
|
|
||||||
github.com/cucumber/godog v0.11.0/go.mod h1:GyxCIrsg1sgEgpL2GD/rMr3fIoNHpgkjm9nANw/89XY=
|
|
||||||
github.com/cucumber/messages-go/v10 v10.0.1/go.mod h1:kA5T38CBlBbYLU12TIrJ4fk4wSkVVOgyh7Enyy8WnSg=
|
|
||||||
github.com/cucumber/messages-go/v10 v10.0.3/go.mod h1:9jMZ2Y8ZxjLY6TG2+x344nt5rXstVVDYSdS5ySfI1WY=
|
|
||||||
github.com/cucumber/messages-go/v16 v10.0.1/go.mod h1:kA5T38CBlBbYLU12TIrJ4fk4wSkVVOgyh7Enyy8WnSg=
|
|
||||||
github.com/cucumber/messages-go/v16 v10.0.3 h1:m/9SD/K/A15WP7i1aemIv7cwvUw+viS51Ui5HBw1cdE=
|
|
||||||
github.com/cucumber/messages-go/v16 v10.0.3/go.mod h1:9jMZ2Y8ZxjLY6TG2+x344nt5rXstVVDYSdS5ySfI1WY=
|
|
||||||
github.com/cucumber/messages-go/v16 v16.0.0/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g=
|
github.com/cucumber/messages-go/v16 v16.0.0/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g=
|
||||||
github.com/cucumber/messages-go/v16 v16.0.1 h1:fvkpwsLgnIm0qugftrw2YwNlio+ABe2Iu94Ap8GMYIY=
|
github.com/cucumber/messages-go/v16 v16.0.1 h1:fvkpwsLgnIm0qugftrw2YwNlio+ABe2Iu94Ap8GMYIY=
|
||||||
github.com/cucumber/messages-go/v16 v16.0.1/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g=
|
github.com/cucumber/messages-go/v16 v16.0.1/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g=
|
||||||
|
@ -62,14 +50,10 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
|
||||||
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
|
||||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
|
||||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
|
@ -88,6 +72,7 @@ github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OI
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
|
@ -98,11 +83,9 @@ github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyN
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
github.com/hashicorp/go-immutable-radix v1.3.0 h1:8exGP7ego3OmkfksihtSouGMZ+hQrhxx+FVELeXpVPE=
|
|
||||||
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
github.com/hashicorp/go-memdb v1.3.0 h1:xdXq34gBOMEloa9rlGStLxmfX/dyIK8htOv36dQUwHU=
|
|
||||||
github.com/hashicorp/go-memdb v1.3.0/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g=
|
github.com/hashicorp/go-memdb v1.3.0/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g=
|
||||||
github.com/hashicorp/go-memdb v1.3.2 h1:RBKHOsnSszpU6vxq80LzC2BaQjuuvoyaQbkLTf7V7g8=
|
github.com/hashicorp/go-memdb v1.3.2 h1:RBKHOsnSszpU6vxq80LzC2BaQjuuvoyaQbkLTf7V7g8=
|
||||||
github.com/hashicorp/go-memdb v1.3.2/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g=
|
github.com/hashicorp/go-memdb v1.3.2/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g=
|
||||||
|
@ -115,7 +98,6 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
|
||||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE=
|
||||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
|
||||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
|
@ -130,15 +112,14 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
|
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
|
||||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
|
@ -161,7 +142,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||||
|
@ -186,7 +166,9 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
|
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
@ -202,9 +184,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
|
@ -281,7 +260,6 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
|
@ -322,8 +300,6 @@ google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
|
@ -331,7 +307,6 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
6
_examples/custom-formatter/godogs.go
Обычный файл
6
_examples/custom-formatter/godogs.go
Обычный файл
|
@ -0,0 +1,6 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
// Godogs available to eat
|
||||||
|
var Godogs int
|
||||||
|
|
||||||
|
func main() { /* usual main func */ }
|
75
_examples/custom-formatter/godogs_test.go
Обычный файл
75
_examples/custom-formatter/godogs_test.go
Обычный файл
|
@ -0,0 +1,75 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/cucumber/godog"
|
||||||
|
"github.com/cucumber/godog/colors"
|
||||||
|
flag "github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
var opts = godog.Options{
|
||||||
|
Output: colors.Colored(os.Stdout),
|
||||||
|
Format: "emoji",
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
godog.BindCommandLineFlags("godog.", &opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
flag.Parse()
|
||||||
|
opts.Paths = flag.Args()
|
||||||
|
|
||||||
|
status := godog.TestSuite{
|
||||||
|
Name: "godogs",
|
||||||
|
TestSuiteInitializer: InitializeTestSuite,
|
||||||
|
ScenarioInitializer: InitializeScenario,
|
||||||
|
Options: &opts,
|
||||||
|
}.Run()
|
||||||
|
|
||||||
|
os.Exit(status)
|
||||||
|
}
|
||||||
|
|
||||||
|
func thereAreGodogs(available int) error {
|
||||||
|
Godogs = available
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func iEat(num int) error {
|
||||||
|
if Godogs < num {
|
||||||
|
return fmt.Errorf("you cannot eat %d godogs, there are %d available", num, Godogs)
|
||||||
|
}
|
||||||
|
Godogs -= num
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func thereShouldBeRemaining(remaining int) error {
|
||||||
|
if Godogs != remaining {
|
||||||
|
return fmt.Errorf("expected %d godogs to be remaining, but there is %d", remaining, Godogs)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func thisStepIsPending() error {
|
||||||
|
return godog.ErrPending
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitializeTestSuite(ctx *godog.TestSuiteContext) {
|
||||||
|
ctx.BeforeSuite(func() { Godogs = 0 })
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||||
|
ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) {
|
||||||
|
Godogs = 0 // clean the state before every scenario
|
||||||
|
|
||||||
|
return ctx, nil
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx.Step(`^there are (\d+) godogs$`, thereAreGodogs)
|
||||||
|
ctx.Step(`^I eat (\d+)$`, iEat)
|
||||||
|
ctx.Step(`^there should be (\d+) remaining$`, thereShouldBeRemaining)
|
||||||
|
ctx.Step(`^this step is pending$`, thisStepIsPending)
|
||||||
|
}
|
Двоичные данные
_examples/custom-formatter/imgs/emoji-output-example.png
Обычный файл
Двоичные данные
_examples/custom-formatter/imgs/emoji-output-example.png
Обычный файл
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 87 КиБ |
48
fmt.go
48
fmt.go
|
@ -74,3 +74,51 @@ func printStepDefinitions(steps []*models.StepDefinition, w io.Writer) {
|
||||||
fmt.Fprintln(w, "there were no contexts registered, could not find any step definition..")
|
fmt.Fprintln(w, "there were no contexts registered, could not find any step definition..")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewBaseFmt creates a new base formatter.
|
||||||
|
func NewBaseFmt(suite string, out io.Writer) *BaseFmt {
|
||||||
|
return internal_fmt.NewBase(suite, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProgressFmt creates a new progress formatter.
|
||||||
|
func NewProgressFmt(suite string, out io.Writer) *ProgressFmt {
|
||||||
|
return internal_fmt.NewProgress(suite, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPrettyFmt creates a new pretty formatter.
|
||||||
|
func NewPrettyFmt(suite string, out io.Writer) *PrettyFmt {
|
||||||
|
return &PrettyFmt{Base: NewBaseFmt(suite, out)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEventsFmt creates a new event streaming formatter.
|
||||||
|
func NewEventsFmt(suite string, out io.Writer) *EventsFmt {
|
||||||
|
return &EventsFmt{Base: NewBaseFmt(suite, out)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewCukeFmt creates a new Cucumber JSON formatter.
|
||||||
|
func NewCukeFmt(suite string, out io.Writer) *CukeFmt {
|
||||||
|
return &CukeFmt{Base: NewBaseFmt(suite, out)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewJUnitFmt creates a new JUnit formatter.
|
||||||
|
func NewJUnitFmt(suite string, out io.Writer) *JUnitFmt {
|
||||||
|
return &JUnitFmt{Base: NewBaseFmt(suite, out)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BaseFmt exports Base formatter.
|
||||||
|
type BaseFmt = internal_fmt.Base
|
||||||
|
|
||||||
|
// ProgressFmt exports Progress formatter.
|
||||||
|
type ProgressFmt = internal_fmt.Progress
|
||||||
|
|
||||||
|
// PrettyFmt exports Pretty formatter.
|
||||||
|
type PrettyFmt = internal_fmt.Pretty
|
||||||
|
|
||||||
|
// EventsFmt exports Events formatter.
|
||||||
|
type EventsFmt = internal_fmt.Events
|
||||||
|
|
||||||
|
// CukeFmt exports Cucumber JSON formatter.
|
||||||
|
type CukeFmt = internal_fmt.Cuke
|
||||||
|
|
||||||
|
// JUnitFmt exports JUnit formatter.
|
||||||
|
type JUnitFmt = internal_fmt.JUnit
|
||||||
|
|
|
@ -20,82 +20,82 @@ import (
|
||||||
"github.com/cucumber/godog/internal/utils"
|
"github.com/cucumber/godog/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BaseFormatterFunc implements the FormatterFunc for the base formatter
|
// BaseFormatterFunc implements the FormatterFunc for the base formatter.
|
||||||
func BaseFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
func BaseFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
||||||
return NewBaseFmt(suite, out)
|
return NewBase(suite, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBaseFmt creates a new base formatter
|
// NewBase creates a new base formatter.
|
||||||
func NewBaseFmt(suite string, out io.Writer) *Basefmt {
|
func NewBase(suite string, out io.Writer) *Base {
|
||||||
return &Basefmt{
|
return &Base{
|
||||||
suiteName: suite,
|
suiteName: suite,
|
||||||
indent: 2,
|
indent: 2,
|
||||||
out: out,
|
out: out,
|
||||||
lock: new(sync.Mutex),
|
Lock: new(sync.Mutex),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basefmt ...
|
// Base is a base formatter.
|
||||||
type Basefmt struct {
|
type Base struct {
|
||||||
suiteName string
|
suiteName string
|
||||||
out io.Writer
|
out io.Writer
|
||||||
indent int
|
indent int
|
||||||
|
|
||||||
storage *storage.Storage
|
Storage *storage.Storage
|
||||||
lock *sync.Mutex
|
Lock *sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetStorage ...
|
// SetStorage assigns gherkin data storage.
|
||||||
func (f *Basefmt) SetStorage(st *storage.Storage) {
|
func (f *Base) SetStorage(st *storage.Storage) {
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.storage = st
|
f.Storage = st
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestRunStarted ...
|
// TestRunStarted is triggered on test start.
|
||||||
func (f *Basefmt) TestRunStarted() {}
|
func (f *Base) TestRunStarted() {}
|
||||||
|
|
||||||
// Feature ...
|
// Feature receives gherkin document.
|
||||||
func (f *Basefmt) Feature(*messages.GherkinDocument, string, []byte) {}
|
func (f *Base) Feature(*messages.GherkinDocument, string, []byte) {}
|
||||||
|
|
||||||
// Pickle ...
|
// Pickle receives scenario.
|
||||||
func (f *Basefmt) Pickle(*messages.Pickle) {}
|
func (f *Base) Pickle(*messages.Pickle) {}
|
||||||
|
|
||||||
// Defined ...
|
// Defined receives step definition.
|
||||||
func (f *Basefmt) Defined(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {
|
func (f *Base) Defined(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passed ...
|
// Passed captures passed step.
|
||||||
func (f *Basefmt) Passed(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {}
|
func (f *Base) Passed(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {}
|
||||||
|
|
||||||
// Skipped ...
|
// Skipped captures skipped step.
|
||||||
func (f *Basefmt) Skipped(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {
|
func (f *Base) Skipped(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undefined ...
|
// Undefined captures undefined step.
|
||||||
func (f *Basefmt) Undefined(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {
|
func (f *Base) Undefined(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failed ...
|
// Failed captures failed step.
|
||||||
func (f *Basefmt) Failed(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition, error) {
|
func (f *Base) Failed(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pending ...
|
// Pending captures pending step.
|
||||||
func (f *Basefmt) Pending(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {
|
func (f *Base) Pending(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Summary ...
|
// Summary renders summary information.
|
||||||
func (f *Basefmt) Summary() {
|
func (f *Base) Summary() {
|
||||||
var totalSc, passedSc, undefinedSc int
|
var totalSc, passedSc, undefinedSc int
|
||||||
var totalSt, passedSt, failedSt, skippedSt, pendingSt, undefinedSt int
|
var totalSt, passedSt, failedSt, skippedSt, pendingSt, undefinedSt int
|
||||||
|
|
||||||
pickleResults := f.storage.MustGetPickleResults()
|
pickleResults := f.Storage.MustGetPickleResults()
|
||||||
for _, pr := range pickleResults {
|
for _, pr := range pickleResults {
|
||||||
var prStatus models.StepResultStatus
|
var prStatus models.StepResultStatus
|
||||||
totalSc++
|
totalSc++
|
||||||
|
|
||||||
pickleStepResults := f.storage.MustGetPickleStepResultsByPickleID(pr.PickleID)
|
pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleID(pr.PickleID)
|
||||||
|
|
||||||
if len(pickleStepResults) == 0 {
|
if len(pickleStepResults) == 0 {
|
||||||
prStatus = undefined
|
prStatus = undefined
|
||||||
|
@ -156,7 +156,7 @@ func (f *Basefmt) Summary() {
|
||||||
}
|
}
|
||||||
scenarios = append(scenarios, parts...)
|
scenarios = append(scenarios, parts...)
|
||||||
|
|
||||||
testRunStartedAt := f.storage.MustGetTestRunStarted().StartedAt
|
testRunStartedAt := f.Storage.MustGetTestRunStarted().StartedAt
|
||||||
elapsed := utils.TimeNowFunc().Sub(testRunStartedAt)
|
elapsed := utils.TimeNowFunc().Sub(testRunStartedAt)
|
||||||
|
|
||||||
fmt.Fprintln(f.out, "")
|
fmt.Fprintln(f.out, "")
|
||||||
|
@ -194,9 +194,9 @@ func (f *Basefmt) Summary() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Snippets ...
|
// Snippets returns code suggestions for undefined steps.
|
||||||
func (f *Basefmt) Snippets() string {
|
func (f *Base) Snippets() string {
|
||||||
undefinedStepResults := f.storage.MustGetPickleStepResultsByStatus(undefined)
|
undefinedStepResults := f.Storage.MustGetPickleStepResultsByStatus(undefined)
|
||||||
if len(undefinedStepResults) == 0 {
|
if len(undefinedStepResults) == 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ func (f *Basefmt) Snippets() string {
|
||||||
var snips []undefinedSnippet
|
var snips []undefinedSnippet
|
||||||
// build snippets
|
// build snippets
|
||||||
for _, u := range undefinedStepResults {
|
for _, u := range undefinedStepResults {
|
||||||
pickleStep := f.storage.MustGetPickleStep(u.PickleStepID)
|
pickleStep := f.Storage.MustGetPickleStep(u.PickleStepID)
|
||||||
|
|
||||||
steps := []string{pickleStep.Text}
|
steps := []string{pickleStep.Text}
|
||||||
arg := pickleStep.Argument
|
arg := pickleStep.Argument
|
||||||
|
|
|
@ -30,15 +30,17 @@ func init() {
|
||||||
|
|
||||||
// CucumberFormatterFunc implements the FormatterFunc for the cucumber formatter
|
// CucumberFormatterFunc implements the FormatterFunc for the cucumber formatter
|
||||||
func CucumberFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
func CucumberFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
||||||
return &cukefmt{Basefmt: NewBaseFmt(suite, out)}
|
return &Cuke{Base: NewBase(suite, out)}
|
||||||
}
|
}
|
||||||
|
|
||||||
type cukefmt struct {
|
// Cuke ...
|
||||||
*Basefmt
|
type Cuke struct {
|
||||||
|
*Base
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *cukefmt) Summary() {
|
// Summary renders test result as Cucumber JSON.
|
||||||
features := f.storage.MustGetFeatures()
|
func (f *Cuke) Summary() {
|
||||||
|
features := f.Storage.MustGetFeatures()
|
||||||
|
|
||||||
res := f.buildCukeFeatures(features)
|
res := f.buildCukeFeatures(features)
|
||||||
|
|
||||||
|
@ -50,7 +52,7 @@ func (f *cukefmt) Summary() {
|
||||||
fmt.Fprintf(f.out, "%s\n", string(dat))
|
fmt.Fprintf(f.out, "%s\n", string(dat))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *cukefmt) buildCukeFeatures(features []*models.Feature) (res []CukeFeatureJSON) {
|
func (f *Cuke) buildCukeFeatures(features []*models.Feature) (res []CukeFeatureJSON) {
|
||||||
sort.Sort(sortFeaturesByName(features))
|
sort.Sort(sortFeaturesByName(features))
|
||||||
|
|
||||||
res = make([]CukeFeatureJSON, len(features))
|
res = make([]CukeFeatureJSON, len(features))
|
||||||
|
@ -58,7 +60,7 @@ func (f *cukefmt) buildCukeFeatures(features []*models.Feature) (res []CukeFeatu
|
||||||
for idx, feat := range features {
|
for idx, feat := range features {
|
||||||
cukeFeature := buildCukeFeature(feat)
|
cukeFeature := buildCukeFeature(feat)
|
||||||
|
|
||||||
pickles := f.storage.MustGetPickles(feat.Uri)
|
pickles := f.Storage.MustGetPickles(feat.Uri)
|
||||||
sort.Sort(sortPicklesByID(pickles))
|
sort.Sort(sortPicklesByID(pickles))
|
||||||
|
|
||||||
cukeFeature.Elements = f.buildCukeElements(pickles)
|
cukeFeature.Elements = f.buildCukeElements(pickles)
|
||||||
|
@ -75,12 +77,12 @@ func (f *cukefmt) buildCukeFeatures(features []*models.Feature) (res []CukeFeatu
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *cukefmt) buildCukeElements(pickles []*messages.Pickle) (res []cukeElement) {
|
func (f *Cuke) buildCukeElements(pickles []*messages.Pickle) (res []cukeElement) {
|
||||||
res = make([]cukeElement, len(pickles))
|
res = make([]cukeElement, len(pickles))
|
||||||
|
|
||||||
for idx, pickle := range pickles {
|
for idx, pickle := range pickles {
|
||||||
pickleResult := f.storage.MustGetPickleResult(pickle.Id)
|
pickleResult := f.Storage.MustGetPickleResult(pickle.Id)
|
||||||
pickleStepResults := f.storage.MustGetPickleStepResultsByPickleID(pickle.Id)
|
pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleID(pickle.Id)
|
||||||
|
|
||||||
cukeElement := f.buildCukeElement(pickle)
|
cukeElement := f.buildCukeElement(pickle)
|
||||||
|
|
||||||
|
@ -201,8 +203,8 @@ func buildCukeFeature(feat *models.Feature) CukeFeatureJSON {
|
||||||
return cukeFeature
|
return cukeFeature
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *cukefmt) buildCukeElement(pickle *messages.Pickle) (cukeElement cukeElement) {
|
func (f *Cuke) buildCukeElement(pickle *messages.Pickle) (cukeElement cukeElement) {
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
scenario := feature.FindScenario(pickle.AstNodeIds[0])
|
scenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||||
|
|
||||||
cukeElement.Name = pickle.Name
|
cukeElement.Name = pickle.Name
|
||||||
|
@ -245,9 +247,9 @@ func (f *cukefmt) buildCukeElement(pickle *messages.Pickle) (cukeElement cukeEle
|
||||||
return cukeElement
|
return cukeElement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *cukefmt) buildCukeStep(pickle *messages.Pickle, stepResult models.PickleStepResult) (cukeStep cukeStep) {
|
func (f *Cuke) buildCukeStep(pickle *messages.Pickle, stepResult models.PickleStepResult) (cukeStep cukeStep) {
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
pickleStep := f.storage.MustGetPickleStep(stepResult.PickleStepID)
|
pickleStep := f.Storage.MustGetPickleStep(stepResult.PickleStepID)
|
||||||
step := feature.FindStep(pickleStep.AstNodeIds[0])
|
step := feature.FindStep(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
line := step.Location.Line
|
line := step.Location.Line
|
||||||
|
|
|
@ -20,14 +20,15 @@ func init() {
|
||||||
|
|
||||||
// EventsFormatterFunc implements the FormatterFunc for the events formatter
|
// EventsFormatterFunc implements the FormatterFunc for the events formatter
|
||||||
func EventsFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
func EventsFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
||||||
return &eventsFormatter{Basefmt: NewBaseFmt(suite, out)}
|
return &Events{Base: NewBase(suite, out)}
|
||||||
}
|
}
|
||||||
|
|
||||||
type eventsFormatter struct {
|
// Events - Events formatter
|
||||||
*Basefmt
|
type Events struct {
|
||||||
|
*Base
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) event(ev interface{}) {
|
func (f *Events) event(ev interface{}) {
|
||||||
data, err := json.Marshal(ev)
|
data, err := json.Marshal(ev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("failed to marshal stream event: %+v - %v", ev, err))
|
panic(fmt.Sprintf("failed to marshal stream event: %+v - %v", ev, err))
|
||||||
|
@ -35,11 +36,12 @@ func (f *eventsFormatter) event(ev interface{}) {
|
||||||
fmt.Fprintln(f.out, string(data))
|
fmt.Fprintln(f.out, string(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) Pickle(pickle *messages.Pickle) {
|
// Pickle receives scenario.
|
||||||
f.Basefmt.Pickle(pickle)
|
func (f *Events) Pickle(pickle *messages.Pickle) {
|
||||||
|
f.Base.Pickle(pickle)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.event(&struct {
|
f.event(&struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
|
@ -68,11 +70,12 @@ func (f *eventsFormatter) Pickle(pickle *messages.Pickle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) TestRunStarted() {
|
// TestRunStarted is triggered on test start.
|
||||||
f.Basefmt.TestRunStarted()
|
func (f *Events) TestRunStarted() {
|
||||||
|
f.Base.TestRunStarted()
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.event(&struct {
|
f.event(&struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
|
@ -87,11 +90,12 @@ func (f *eventsFormatter) TestRunStarted() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) Feature(ft *messages.GherkinDocument, p string, c []byte) {
|
// Feature receives gherkin document.
|
||||||
f.Basefmt.Feature(ft, p, c)
|
func (f *Events) Feature(ft *messages.GherkinDocument, p string, c []byte) {
|
||||||
|
f.Base.Feature(ft, p, c)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.event(&struct {
|
f.event(&struct {
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
|
@ -104,16 +108,17 @@ func (f *eventsFormatter) Feature(ft *messages.GherkinDocument, p string, c []by
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) Summary() {
|
// Summary pushes summary information to JSON stream.
|
||||||
|
func (f *Events) Summary() {
|
||||||
// @TODO: determine status
|
// @TODO: determine status
|
||||||
status := passed
|
status := passed
|
||||||
|
|
||||||
f.storage.MustGetPickleStepResultsByStatus(failed)
|
f.Storage.MustGetPickleStepResultsByStatus(failed)
|
||||||
|
|
||||||
if len(f.storage.MustGetPickleStepResultsByStatus(failed)) > 0 {
|
if len(f.Storage.MustGetPickleStepResultsByStatus(failed)) > 0 {
|
||||||
status = failed
|
status = failed
|
||||||
} else if len(f.storage.MustGetPickleStepResultsByStatus(passed)) == 0 {
|
} else if len(f.Storage.MustGetPickleStepResultsByStatus(passed)) == 0 {
|
||||||
if len(f.storage.MustGetPickleStepResultsByStatus(undefined)) > len(f.storage.MustGetPickleStepResultsByStatus(pending)) {
|
if len(f.Storage.MustGetPickleStepResultsByStatus(undefined)) > len(f.Storage.MustGetPickleStepResultsByStatus(pending)) {
|
||||||
status = undefined
|
status = undefined
|
||||||
} else {
|
} else {
|
||||||
status = pending
|
status = pending
|
||||||
|
@ -140,9 +145,9 @@ func (f *eventsFormatter) Summary() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) step(pickle *messages.Pickle, pickleStep *messages.PickleStep) {
|
func (f *Events) step(pickle *messages.Pickle, pickleStep *messages.PickleStep) {
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
pickleStepResult := f.storage.MustGetPickleStepResult(pickleStep.Id)
|
pickleStepResult := f.Storage.MustGetPickleStepResult(pickleStep.Id)
|
||||||
step := feature.FindStep(pickleStep.AstNodeIds[0])
|
step := feature.FindStep(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
var errMsg string
|
var errMsg string
|
||||||
|
@ -166,7 +171,7 @@ func (f *eventsFormatter) step(pickle *messages.Pickle, pickleStep *messages.Pic
|
||||||
if isLastStep(pickle, pickleStep) {
|
if isLastStep(pickle, pickleStep) {
|
||||||
var status string
|
var status string
|
||||||
|
|
||||||
pickleStepResults := f.storage.MustGetPickleStepResultsByPickleID(pickle.Id)
|
pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleID(pickle.Id)
|
||||||
for _, stepResult := range pickleStepResults {
|
for _, stepResult := range pickleStepResults {
|
||||||
switch stepResult.Status {
|
switch stepResult.Status {
|
||||||
case passed, failed, undefined, pending:
|
case passed, failed, undefined, pending:
|
||||||
|
@ -188,17 +193,18 @@ func (f *eventsFormatter) step(pickle *messages.Pickle, pickleStep *messages.Pic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) Defined(pickle *messages.Pickle, pickleStep *messages.PickleStep, def *formatters.StepDefinition) {
|
// Defined receives step definition.
|
||||||
f.Basefmt.Defined(pickle, pickleStep, def)
|
func (f *Events) Defined(pickle *messages.Pickle, pickleStep *messages.PickleStep, def *formatters.StepDefinition) {
|
||||||
|
f.Base.Defined(pickle, pickleStep, def)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
step := feature.FindStep(pickleStep.AstNodeIds[0])
|
step := feature.FindStep(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
if def != nil {
|
if def != nil {
|
||||||
matchedDef := f.storage.MustGetStepDefintionMatch(pickleStep.AstNodeIds[0])
|
matchedDef := f.Storage.MustGetStepDefintionMatch(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
m := def.Expr.FindStringSubmatchIndex(pickleStep.Text)[2:]
|
m := def.Expr.FindStringSubmatchIndex(pickleStep.Text)[2:]
|
||||||
var args [][2]int
|
var args [][2]int
|
||||||
|
@ -238,53 +244,58 @@ func (f *eventsFormatter) Defined(pickle *messages.Pickle, pickleStep *messages.
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) Passed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Passed captures passed step.
|
||||||
f.Basefmt.Passed(pickle, step, match)
|
func (f *Events) Passed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Passed(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.step(pickle, step)
|
f.step(pickle, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) Skipped(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Skipped captures skipped step.
|
||||||
f.Basefmt.Skipped(pickle, step, match)
|
func (f *Events) Skipped(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Skipped(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.step(pickle, step)
|
f.step(pickle, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) Undefined(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Undefined captures undefined step.
|
||||||
f.Basefmt.Undefined(pickle, step, match)
|
func (f *Events) Undefined(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Undefined(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.step(pickle, step)
|
f.step(pickle, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) Failed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
// Failed captures failed step.
|
||||||
f.Basefmt.Failed(pickle, step, match, err)
|
func (f *Events) Failed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
||||||
|
f.Base.Failed(pickle, step, match, err)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.step(pickle, step)
|
f.step(pickle, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Pending captures pending step.
|
||||||
f.Basefmt.Pending(pickle, step, match)
|
func (f *Events) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Pending(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.step(pickle, step)
|
f.step(pickle, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *eventsFormatter) scenarioLocation(pickle *messages.Pickle) string {
|
func (f *Events) scenarioLocation(pickle *messages.Pickle) string {
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
scenario := feature.FindScenario(pickle.AstNodeIds[0])
|
scenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||||
|
|
||||||
line := scenario.Location.Line
|
line := scenario.Location.Line
|
||||||
|
|
|
@ -19,14 +19,16 @@ func init() {
|
||||||
|
|
||||||
// JUnitFormatterFunc implements the FormatterFunc for the junit formatter
|
// JUnitFormatterFunc implements the FormatterFunc for the junit formatter
|
||||||
func JUnitFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
func JUnitFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
||||||
return &junitFormatter{Basefmt: NewBaseFmt(suite, out)}
|
return &JUnit{Base: NewBase(suite, out)}
|
||||||
}
|
}
|
||||||
|
|
||||||
type junitFormatter struct {
|
// JUnit renders test results in JUnit format.
|
||||||
*Basefmt
|
type JUnit struct {
|
||||||
|
*Base
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *junitFormatter) Summary() {
|
// Summary renders summary information.
|
||||||
|
func (f *JUnit) Summary() {
|
||||||
suite := f.buildJUNITPackageSuite()
|
suite := f.buildJUNITPackageSuite()
|
||||||
|
|
||||||
_, err := io.WriteString(f.out, xml.Header)
|
_, err := io.WriteString(f.out, xml.Header)
|
||||||
|
@ -45,11 +47,11 @@ func junitTimeDuration(from, to time.Time) string {
|
||||||
return strconv.FormatFloat(to.Sub(from).Seconds(), 'f', -1, 64)
|
return strconv.FormatFloat(to.Sub(from).Seconds(), 'f', -1, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *junitFormatter) buildJUNITPackageSuite() JunitPackageSuite {
|
func (f *JUnit) buildJUNITPackageSuite() JunitPackageSuite {
|
||||||
features := f.storage.MustGetFeatures()
|
features := f.Storage.MustGetFeatures()
|
||||||
sort.Sort(sortFeaturesByName(features))
|
sort.Sort(sortFeaturesByName(features))
|
||||||
|
|
||||||
testRunStartedAt := f.storage.MustGetTestRunStarted().StartedAt
|
testRunStartedAt := f.Storage.MustGetTestRunStarted().StartedAt
|
||||||
|
|
||||||
suite := JunitPackageSuite{
|
suite := JunitPackageSuite{
|
||||||
Name: f.suiteName,
|
Name: f.suiteName,
|
||||||
|
@ -58,7 +60,7 @@ func (f *junitFormatter) buildJUNITPackageSuite() JunitPackageSuite {
|
||||||
}
|
}
|
||||||
|
|
||||||
for idx, feature := range features {
|
for idx, feature := range features {
|
||||||
pickles := f.storage.MustGetPickles(feature.Uri)
|
pickles := f.Storage.MustGetPickles(feature.Uri)
|
||||||
sort.Sort(sortPicklesByID(pickles))
|
sort.Sort(sortPicklesByID(pickles))
|
||||||
|
|
||||||
ts := junitTestSuite{
|
ts := junitTestSuite{
|
||||||
|
@ -78,7 +80,7 @@ func (f *junitFormatter) buildJUNITPackageSuite() JunitPackageSuite {
|
||||||
for idx, pickle := range pickles {
|
for idx, pickle := range pickles {
|
||||||
tc := junitTestCase{}
|
tc := junitTestCase{}
|
||||||
|
|
||||||
pickleResult := f.storage.MustGetPickleResult(pickle.Id)
|
pickleResult := f.Storage.MustGetPickleResult(pickle.Id)
|
||||||
|
|
||||||
if idx == 0 {
|
if idx == 0 {
|
||||||
firstPickleStartedAt = pickleResult.StartedAt
|
firstPickleStartedAt = pickleResult.StartedAt
|
||||||
|
@ -88,7 +90,7 @@ func (f *junitFormatter) buildJUNITPackageSuite() JunitPackageSuite {
|
||||||
|
|
||||||
if len(pickle.Steps) > 0 {
|
if len(pickle.Steps) > 0 {
|
||||||
lastStep := pickle.Steps[len(pickle.Steps)-1]
|
lastStep := pickle.Steps[len(pickle.Steps)-1]
|
||||||
lastPickleStepResult := f.storage.MustGetPickleStepResult(lastStep.Id)
|
lastPickleStepResult := f.Storage.MustGetPickleStepResult(lastStep.Id)
|
||||||
lastPickleFinishedAt = lastPickleStepResult.FinishedAt
|
lastPickleFinishedAt = lastPickleStepResult.FinishedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,9 +105,9 @@ func (f *junitFormatter) buildJUNITPackageSuite() JunitPackageSuite {
|
||||||
ts.Tests++
|
ts.Tests++
|
||||||
suite.Tests++
|
suite.Tests++
|
||||||
|
|
||||||
pickleStepResults := f.storage.MustGetPickleStepResultsByPickleID(pickle.Id)
|
pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleID(pickle.Id)
|
||||||
for _, stepResult := range pickleStepResults {
|
for _, stepResult := range pickleStepResults {
|
||||||
pickleStep := f.storage.MustGetPickleStep(stepResult.PickleStepID)
|
pickleStep := f.Storage.MustGetPickleStep(stepResult.PickleStepID)
|
||||||
|
|
||||||
switch stepResult.Status {
|
switch stepResult.Status {
|
||||||
case passed:
|
case passed:
|
||||||
|
|
|
@ -20,50 +20,52 @@ func init() {
|
||||||
|
|
||||||
// PrettyFormatterFunc implements the FormatterFunc for the pretty formatter
|
// PrettyFormatterFunc implements the FormatterFunc for the pretty formatter
|
||||||
func PrettyFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
func PrettyFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
||||||
return &pretty{Basefmt: NewBaseFmt(suite, out)}
|
return &Pretty{Base: NewBase(suite, out)}
|
||||||
}
|
}
|
||||||
|
|
||||||
var outlinePlaceholderRegexp = regexp.MustCompile("<[^>]+>")
|
var outlinePlaceholderRegexp = regexp.MustCompile("<[^>]+>")
|
||||||
|
|
||||||
// a built in default pretty formatter
|
// Pretty is a formatter for readable output.
|
||||||
type pretty struct {
|
type Pretty struct {
|
||||||
*Basefmt
|
*Base
|
||||||
firstFeature *bool
|
firstFeature *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) TestRunStarted() {
|
// TestRunStarted is triggered on test start.
|
||||||
f.Basefmt.TestRunStarted()
|
func (f *Pretty) TestRunStarted() {
|
||||||
|
f.Base.TestRunStarted()
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
firstFeature := true
|
firstFeature := true
|
||||||
f.firstFeature = &firstFeature
|
f.firstFeature = &firstFeature
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) Feature(gd *messages.GherkinDocument, p string, c []byte) {
|
// Feature receives gherkin document.
|
||||||
f.lock.Lock()
|
func (f *Pretty) Feature(gd *messages.GherkinDocument, p string, c []byte) {
|
||||||
|
f.Lock.Lock()
|
||||||
if !*f.firstFeature {
|
if !*f.firstFeature {
|
||||||
fmt.Fprintln(f.out, "")
|
fmt.Fprintln(f.out, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
*f.firstFeature = false
|
*f.firstFeature = false
|
||||||
f.lock.Unlock()
|
f.Lock.Unlock()
|
||||||
|
|
||||||
f.Basefmt.Feature(gd, p, c)
|
f.Base.Feature(gd, p, c)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.printFeature(gd.Feature)
|
f.printFeature(gd.Feature)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pickle takes a gherkin node for formatting
|
// Pickle takes a gherkin node for formatting.
|
||||||
func (f *pretty) Pickle(pickle *messages.Pickle) {
|
func (f *Pretty) Pickle(pickle *messages.Pickle) {
|
||||||
f.Basefmt.Pickle(pickle)
|
f.Base.Pickle(pickle)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
if len(pickle.Steps) == 0 {
|
if len(pickle.Steps) == 0 {
|
||||||
f.printUndefinedPickle(pickle)
|
f.printUndefinedPickle(pickle)
|
||||||
|
@ -71,52 +73,57 @@ func (f *pretty) Pickle(pickle *messages.Pickle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) Passed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Passed captures passed step.
|
||||||
f.Basefmt.Passed(pickle, step, match)
|
func (f *Pretty) Passed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Passed(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.printStep(pickle, step)
|
f.printStep(pickle, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) Skipped(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Skipped captures skipped step.
|
||||||
f.Basefmt.Skipped(pickle, step, match)
|
func (f *Pretty) Skipped(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Skipped(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.printStep(pickle, step)
|
f.printStep(pickle, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) Undefined(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Undefined captures undefined step.
|
||||||
f.Basefmt.Undefined(pickle, step, match)
|
func (f *Pretty) Undefined(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Undefined(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.printStep(pickle, step)
|
f.printStep(pickle, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) Failed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
// Failed captures failed step.
|
||||||
f.Basefmt.Failed(pickle, step, match, err)
|
func (f *Pretty) Failed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
||||||
|
f.Base.Failed(pickle, step, match, err)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.printStep(pickle, step)
|
f.printStep(pickle, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Pending captures pending step.
|
||||||
f.Basefmt.Pending(pickle, step, match)
|
func (f *Pretty) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Pending(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.printStep(pickle, step)
|
f.printStep(pickle, step)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printFeature(feature *messages.Feature) {
|
func (f *Pretty) printFeature(feature *messages.Feature) {
|
||||||
fmt.Fprintln(f.out, keywordAndName(feature.Keyword, feature.Name))
|
fmt.Fprintln(f.out, keywordAndName(feature.Keyword, feature.Name))
|
||||||
if strings.TrimSpace(feature.Description) != "" {
|
if strings.TrimSpace(feature.Description) != "" {
|
||||||
for _, line := range strings.Split(feature.Description, "\n") {
|
for _, line := range strings.Split(feature.Description, "\n") {
|
||||||
|
@ -133,8 +140,8 @@ func keywordAndName(keyword, name string) string {
|
||||||
return title
|
return title
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) scenarioLengths(pickle *messages.Pickle) (scenarioHeaderLength int, maxLength int) {
|
func (f *Pretty) scenarioLengths(pickle *messages.Pickle) (scenarioHeaderLength int, maxLength int) {
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||||
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
||||||
|
|
||||||
|
@ -148,15 +155,15 @@ func (f *pretty) scenarioLengths(pickle *messages.Pickle) (scenarioHeaderLength
|
||||||
return scenarioHeaderLength, maxLength
|
return scenarioHeaderLength, maxLength
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printScenarioHeader(pickle *messages.Pickle, astScenario *messages.Scenario, spaceFilling int) {
|
func (f *Pretty) printScenarioHeader(pickle *messages.Pickle, astScenario *messages.Scenario, spaceFilling int) {
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
text := s(f.indent) + keywordAndName(astScenario.Keyword, astScenario.Name)
|
text := s(f.indent) + keywordAndName(astScenario.Keyword, astScenario.Name)
|
||||||
text += s(spaceFilling) + line(feature.Uri, astScenario.Location)
|
text += s(spaceFilling) + line(feature.Uri, astScenario.Location)
|
||||||
fmt.Fprintln(f.out, "\n"+text)
|
fmt.Fprintln(f.out, "\n"+text)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printUndefinedPickle(pickle *messages.Pickle) {
|
func (f *Pretty) printUndefinedPickle(pickle *messages.Pickle) {
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||||
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
||||||
|
|
||||||
|
@ -197,18 +204,18 @@ func (f *pretty) printUndefinedPickle(pickle *messages.Pickle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Summary sumarize the feature formatter output
|
// Summary renders summary information.
|
||||||
func (f *pretty) Summary() {
|
func (f *Pretty) Summary() {
|
||||||
failedStepResults := f.storage.MustGetPickleStepResultsByStatus(failed)
|
failedStepResults := f.Storage.MustGetPickleStepResultsByStatus(failed)
|
||||||
if len(failedStepResults) > 0 {
|
if len(failedStepResults) > 0 {
|
||||||
fmt.Fprintln(f.out, "\n--- "+red("Failed steps:")+"\n")
|
fmt.Fprintln(f.out, "\n--- "+red("Failed steps:")+"\n")
|
||||||
|
|
||||||
sort.Sort(sortPickleStepResultsByPickleStepID(failedStepResults))
|
sort.Sort(sortPickleStepResultsByPickleStepID(failedStepResults))
|
||||||
|
|
||||||
for _, fail := range failedStepResults {
|
for _, fail := range failedStepResults {
|
||||||
pickle := f.storage.MustGetPickle(fail.PickleID)
|
pickle := f.Storage.MustGetPickle(fail.PickleID)
|
||||||
pickleStep := f.storage.MustGetPickleStep(fail.PickleStepID)
|
pickleStep := f.Storage.MustGetPickleStep(fail.PickleStepID)
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
|
|
||||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||||
scenarioDesc := fmt.Sprintf("%s: %s", astScenario.Keyword, pickle.Name)
|
scenarioDesc := fmt.Sprintf("%s: %s", astScenario.Keyword, pickle.Name)
|
||||||
|
@ -222,14 +229,14 @@ func (f *pretty) Summary() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Basefmt.Summary()
|
f.Base.Summary()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps int) {
|
func (f *Pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps int) {
|
||||||
var errorMsg string
|
var errorMsg string
|
||||||
var clr = green
|
var clr = green
|
||||||
|
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||||
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle)
|
scenarioHeaderLength, maxLength := f.scenarioLengths(pickle)
|
||||||
|
|
||||||
|
@ -237,7 +244,7 @@ func (f *pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps in
|
||||||
printExampleHeader := exampleTable.TableBody[0].Id == exampleRow.Id
|
printExampleHeader := exampleTable.TableBody[0].Id == exampleRow.Id
|
||||||
firstExamplesTable := astScenario.Examples[0].Location.Line == exampleTable.Location.Line
|
firstExamplesTable := astScenario.Examples[0].Location.Line == exampleTable.Location.Line
|
||||||
|
|
||||||
pickleStepResults := f.storage.MustGetPickleStepResultsByPickleID(pickle.Id)
|
pickleStepResults := f.Storage.MustGetPickleStepResultsByPickleID(pickle.Id)
|
||||||
|
|
||||||
firstExecutedScenarioStep := len(pickleStepResults) == backgroundSteps+1
|
firstExecutedScenarioStep := len(pickleStepResults) == backgroundSteps+1
|
||||||
if firstExamplesTable && printExampleHeader && firstExecutedScenarioStep {
|
if firstExamplesTable && printExampleHeader && firstExecutedScenarioStep {
|
||||||
|
@ -270,7 +277,7 @@ func (f *pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps in
|
||||||
if firstExamplesTable && printExampleHeader {
|
if firstExamplesTable && printExampleHeader {
|
||||||
// in first example, we need to print steps
|
// in first example, we need to print steps
|
||||||
|
|
||||||
pickleStep := f.storage.MustGetPickleStep(result.PickleStepID)
|
pickleStep := f.Storage.MustGetPickleStep(result.PickleStepID)
|
||||||
astStep := feature.FindStep(pickleStep.AstNodeIds[0])
|
astStep := feature.FindStep(pickleStep.AstNodeIds[0])
|
||||||
|
|
||||||
var text = ""
|
var text = ""
|
||||||
|
@ -327,7 +334,7 @@ func (f *pretty) printOutlineExample(pickle *messages.Pickle, backgroundSteps in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printTableRow(row *messages.TableRow, max []int, clr colors.ColorFunc) {
|
func (f *Pretty) printTableRow(row *messages.TableRow, max []int, clr colors.ColorFunc) {
|
||||||
cells := make([]string, len(row.Cells))
|
cells := make([]string, len(row.Cells))
|
||||||
|
|
||||||
for i, cell := range row.Cells {
|
for i, cell := range row.Cells {
|
||||||
|
@ -339,12 +346,12 @@ func (f *pretty) printTableRow(row *messages.TableRow, max []int, clr colors.Col
|
||||||
fmt.Fprintln(f.out, s(f.indent*3)+"| "+strings.Join(cells, " | ")+" |")
|
fmt.Fprintln(f.out, s(f.indent*3)+"| "+strings.Join(cells, " | ")+" |")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printTableHeader(row *messages.TableRow, max []int) {
|
func (f *Pretty) printTableHeader(row *messages.TableRow, max []int) {
|
||||||
f.printTableRow(row, max, cyan)
|
f.printTableRow(row, max, cyan)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printStep(pickle *messages.Pickle, pickleStep *messages.PickleStep) {
|
func (f *Pretty) printStep(pickle *messages.Pickle, pickleStep *messages.PickleStep) {
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
astBackground := feature.FindBackground(pickle.AstNodeIds[0])
|
||||||
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
astScenario := feature.FindScenario(pickle.AstNodeIds[0])
|
||||||
astStep := feature.FindStep(pickleStep.AstNodeIds[0])
|
astStep := feature.FindStep(pickleStep.AstNodeIds[0])
|
||||||
|
@ -387,7 +394,7 @@ func (f *pretty) printStep(pickle *messages.Pickle, pickleStep *messages.PickleS
|
||||||
f.printScenarioHeader(pickle, astScenario, maxLength-scenarioHeaderLength)
|
f.printScenarioHeader(pickle, astScenario, maxLength-scenarioHeaderLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
pickleStepResult := f.storage.MustGetPickleStepResult(pickleStep.Id)
|
pickleStepResult := f.Storage.MustGetPickleStepResult(pickleStep.Id)
|
||||||
text := s(f.indent*2) + pickleStepResult.Status.Color()(strings.TrimSpace(astStep.Keyword)) + " " + pickleStepResult.Status.Color()(pickleStep.Text)
|
text := s(f.indent*2) + pickleStepResult.Status.Color()(strings.TrimSpace(astStep.Keyword)) + " " + pickleStepResult.Status.Color()(pickleStep.Text)
|
||||||
if pickleStepResult.Def != nil {
|
if pickleStepResult.Def != nil {
|
||||||
text += s(maxLength - stepLength + 1)
|
text += s(maxLength - stepLength + 1)
|
||||||
|
@ -414,7 +421,7 @@ func (f *pretty) printStep(pickle *messages.Pickle, pickleStep *messages.PickleS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) printDocString(docString *messages.DocString) {
|
func (f *Pretty) printDocString(docString *messages.DocString) {
|
||||||
var ct string
|
var ct string
|
||||||
|
|
||||||
if len(docString.MediaType) > 0 {
|
if len(docString.MediaType) > 0 {
|
||||||
|
@ -432,7 +439,7 @@ func (f *pretty) printDocString(docString *messages.DocString) {
|
||||||
|
|
||||||
// print table with aligned table cells
|
// print table with aligned table cells
|
||||||
// @TODO: need to make example header cells bold
|
// @TODO: need to make example header cells bold
|
||||||
func (f *pretty) printTable(t *messages.PickleTable, c colors.ColorFunc) {
|
func (f *Pretty) printTable(t *messages.PickleTable, c colors.ColorFunc) {
|
||||||
maxColLengths := maxColLengths(t, c)
|
maxColLengths := maxColLengths(t, c)
|
||||||
var cols = make([]string, len(t.Rows[0].Cells))
|
var cols = make([]string, len(t.Rows[0].Cells))
|
||||||
|
|
||||||
|
@ -512,7 +519,7 @@ func longestExampleRow(t *messages.Examples, clrs ...colors.ColorFunc) []int {
|
||||||
return longest
|
return longest
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) longestStep(steps []*messages.Step, pickleLength int) int {
|
func (f *Pretty) longestStep(steps []*messages.Step, pickleLength int) int {
|
||||||
max := pickleLength
|
max := pickleLength
|
||||||
|
|
||||||
for _, step := range steps {
|
for _, step := range steps {
|
||||||
|
@ -533,10 +540,10 @@ func line(path string, loc *messages.Location) string {
|
||||||
return " " + blackb(fmt.Sprintf("# %s:%d", path, loc.Line))
|
return " " + blackb(fmt.Sprintf("# %s:%d", path, loc.Line))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) lengthPickleStep(keyword, text string) int {
|
func (f *Pretty) lengthPickleStep(keyword, text string) int {
|
||||||
return f.indent*2 + utf8.RuneCountInString(strings.TrimSpace(keyword)+" "+text)
|
return f.indent*2 + utf8.RuneCountInString(strings.TrimSpace(keyword)+" "+text)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *pretty) lengthPickle(keyword, name string) int {
|
func (f *Pretty) lengthPickle(keyword, name string) int {
|
||||||
return f.indent + utf8.RuneCountInString(strings.TrimSpace(keyword)+": "+name)
|
return f.indent + utf8.RuneCountInString(strings.TrimSpace(keyword)+": "+name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,42 +16,49 @@ func init() {
|
||||||
formatters.Format("progress", "Prints a character per step.", ProgressFormatterFunc)
|
formatters.Format("progress", "Prints a character per step.", ProgressFormatterFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProgressFormatterFunc implements the FormatterFunc for the progress formatter
|
// ProgressFormatterFunc implements the FormatterFunc for the progress formatter.
|
||||||
func ProgressFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
func ProgressFormatterFunc(suite string, out io.Writer) formatters.Formatter {
|
||||||
|
return NewProgress(suite, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProgress creates a new progress formatter.
|
||||||
|
func NewProgress(suite string, out io.Writer) *Progress {
|
||||||
steps := 0
|
steps := 0
|
||||||
return &progress{
|
return &Progress{
|
||||||
Basefmt: NewBaseFmt(suite, out),
|
Base: NewBase(suite, out),
|
||||||
stepsPerRow: 70,
|
StepsPerRow: 70,
|
||||||
steps: &steps,
|
Steps: &steps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type progress struct {
|
// Progress is a minimalistic formatter.
|
||||||
*Basefmt
|
type Progress struct {
|
||||||
stepsPerRow int
|
*Base
|
||||||
steps *int
|
StepsPerRow int
|
||||||
|
Steps *int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *progress) Summary() {
|
// Summary renders summary information.
|
||||||
left := math.Mod(float64(*f.steps), float64(f.stepsPerRow))
|
func (f *Progress) Summary() {
|
||||||
|
left := math.Mod(float64(*f.Steps), float64(f.StepsPerRow))
|
||||||
if left != 0 {
|
if left != 0 {
|
||||||
if *f.steps > f.stepsPerRow {
|
if *f.Steps > f.StepsPerRow {
|
||||||
fmt.Fprintf(f.out, s(f.stepsPerRow-int(left))+fmt.Sprintf(" %d\n", *f.steps))
|
fmt.Fprintf(f.out, s(f.StepsPerRow-int(left))+fmt.Sprintf(" %d\n", *f.Steps))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(f.out, " %d\n", *f.steps)
|
fmt.Fprintf(f.out, " %d\n", *f.Steps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var failedStepsOutput []string
|
var failedStepsOutput []string
|
||||||
|
|
||||||
failedSteps := f.storage.MustGetPickleStepResultsByStatus(failed)
|
failedSteps := f.Storage.MustGetPickleStepResultsByStatus(failed)
|
||||||
sort.Sort(sortPickleStepResultsByPickleStepID(failedSteps))
|
sort.Sort(sortPickleStepResultsByPickleStepID(failedSteps))
|
||||||
|
|
||||||
for _, sr := range failedSteps {
|
for _, sr := range failedSteps {
|
||||||
if sr.Status == failed {
|
if sr.Status == failed {
|
||||||
pickle := f.storage.MustGetPickle(sr.PickleID)
|
pickle := f.Storage.MustGetPickle(sr.PickleID)
|
||||||
pickleStep := f.storage.MustGetPickleStep(sr.PickleStepID)
|
pickleStep := f.Storage.MustGetPickleStep(sr.PickleStepID)
|
||||||
feature := f.storage.MustGetFeature(pickle.Uri)
|
feature := f.Storage.MustGetFeature(pickle.Uri)
|
||||||
|
|
||||||
sc := feature.FindScenario(pickle.AstNodeIds[0])
|
sc := feature.FindScenario(pickle.AstNodeIds[0])
|
||||||
scenarioDesc := fmt.Sprintf("%s: %s", sc.Keyword, pickle.Name)
|
scenarioDesc := fmt.Sprintf("%s: %s", sc.Keyword, pickle.Name)
|
||||||
|
@ -77,11 +84,11 @@ func (f *progress) Summary() {
|
||||||
}
|
}
|
||||||
fmt.Fprintln(f.out, "")
|
fmt.Fprintln(f.out, "")
|
||||||
|
|
||||||
f.Basefmt.Summary()
|
f.Base.Summary()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *progress) step(pickleStepID string) {
|
func (f *Progress) step(pickleStepID string) {
|
||||||
pickleStepResult := f.storage.MustGetPickleStepResult(pickleStepID)
|
pickleStepResult := f.Storage.MustGetPickleStepResult(pickleStepID)
|
||||||
|
|
||||||
switch pickleStepResult.Status {
|
switch pickleStepResult.Status {
|
||||||
case passed:
|
case passed:
|
||||||
|
@ -96,54 +103,59 @@ func (f *progress) step(pickleStepID string) {
|
||||||
fmt.Fprint(f.out, yellow("P"))
|
fmt.Fprint(f.out, yellow("P"))
|
||||||
}
|
}
|
||||||
|
|
||||||
*f.steps++
|
*f.Steps++
|
||||||
|
|
||||||
if math.Mod(float64(*f.steps), float64(f.stepsPerRow)) == 0 {
|
if math.Mod(float64(*f.Steps), float64(f.StepsPerRow)) == 0 {
|
||||||
fmt.Fprintf(f.out, " %d\n", *f.steps)
|
fmt.Fprintf(f.out, " %d\n", *f.Steps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *progress) Passed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Passed captures passed step.
|
||||||
f.Basefmt.Passed(pickle, step, match)
|
func (f *Progress) Passed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Passed(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.step(step.Id)
|
f.step(step.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *progress) Skipped(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Skipped captures skipped step.
|
||||||
f.Basefmt.Skipped(pickle, step, match)
|
func (f *Progress) Skipped(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Skipped(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.step(step.Id)
|
f.step(step.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *progress) Undefined(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Undefined captures undefined step.
|
||||||
f.Basefmt.Undefined(pickle, step, match)
|
func (f *Progress) Undefined(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Undefined(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.step(step.Id)
|
f.step(step.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *progress) Failed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
// Failed captures failed step.
|
||||||
f.Basefmt.Failed(pickle, step, match, err)
|
func (f *Progress) Failed(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition, err error) {
|
||||||
|
f.Base.Failed(pickle, step, match, err)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.step(step.Id)
|
f.step(step.Id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *progress) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
// Pending captures pending step.
|
||||||
f.Basefmt.Pending(pickle, step, match)
|
func (f *Progress) Pending(pickle *messages.Pickle, step *messages.PickleStep, match *formatters.StepDefinition) {
|
||||||
|
f.Base.Pending(pickle, step, match)
|
||||||
|
|
||||||
f.lock.Lock()
|
f.Lock.Lock()
|
||||||
defer f.lock.Unlock()
|
defer f.Lock.Unlock()
|
||||||
|
|
||||||
f.step(step.Id)
|
f.step(step.Id)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,11 @@ Now `godog` is able to use multiple formatters simultaneously with comma-separat
|
||||||
`--format pretty,junit:report.xml,cucumber:report.json` will write `pretty` format to stdout, `junit` to report.xml
|
`--format pretty,junit:report.xml,cucumber:report.json` will write `pretty` format to stdout, `junit` to report.xml
|
||||||
and `cucumber` to report.json.
|
and `cucumber` to report.json.
|
||||||
|
|
||||||
|
### Extensible formatters
|
||||||
|
|
||||||
|
Standard formatters are now exported with type aliases so that a custom formatter can be built on top of it.
|
||||||
|
Please check [an example](../_examples/custom-formatter).
|
||||||
|
|
||||||
### Contextualized hooks
|
### Contextualized hooks
|
||||||
|
|
||||||
Scenario and Step hooks are now passing context to allow custom state communication. Returned context should generally
|
Scenario and Step hooks are now passing context to allow custom state communication. Returned context should generally
|
||||||
|
|
|
@ -324,9 +324,9 @@ func (tc *godogFeaturesScenario) cleanupSnippet(snip string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *godogFeaturesScenario) theUndefinedStepSnippetsShouldBe(body *DocString) error {
|
func (tc *godogFeaturesScenario) theUndefinedStepSnippetsShouldBe(body *DocString) error {
|
||||||
f, ok := tc.testedSuite.fmt.(*formatters.Basefmt)
|
f, ok := tc.testedSuite.fmt.(*formatters.Base)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("this step requires *formatters.Basefmt, but there is: %T", tc.testedSuite.fmt)
|
return fmt.Errorf("this step requires *formatters.Base, but there is: %T", tc.testedSuite.fmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
actual := tc.cleanupSnippet(f.Snippets())
|
actual := tc.cleanupSnippet(f.Snippets())
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче