Skip to content

Commit c6c2a08

Browse files
authored
Export internal formatters (cucumber#372)
1 parent ad7feb3 commit c6c2a08

19 files changed

+584
-304
lines changed

CHANGELOG.md

+6-5
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
1313
### Added
1414

1515
- Support for step definitions without return ([364](https://github.com/cucumber/godog/pull/364) - [titouanfreville])
16-
- Contextualized hooks for scenarios and steps ([409](https://github.com/cucumber/godog/pull/409)) - [vearutop])
17-
- Step result status in After hook ([409](https://github.com/cucumber/godog/pull/409)) - [vearutop])
18-
- Support auto converting doc strings to plain strings ([380](https://github.com/cucumber/godog/pull/380)) - [chirino])
19-
- Use multiple formatters in the same test run ([392](https://github.com/cucumber/godog/pull/392)) - [vearutop])
20-
- Added `RetrieveFeatures()` method to `godog.TestSuite` ([276](https://github.com/cucumber/godog/pull/276)) - [radtriste])
16+
- Contextualized hooks for scenarios and steps ([409](https://github.com/cucumber/godog/pull/409) - [vearutop])
17+
- Step result status in After hook ([409](https://github.com/cucumber/godog/pull/409) - [vearutop])
18+
- Support auto converting doc strings to plain strings ([380](https://github.com/cucumber/godog/pull/380) - [chirino])
19+
- Use multiple formatters in the same test run ([392](https://github.com/cucumber/godog/pull/392) - [vearutop])
20+
- Added `RetrieveFeatures()` method to `godog.TestSuite` ([276](https://github.com/cucumber/godog/pull/276) - [radtriste])
21+
- Added support to create custom formatters ([372](https://github.com/cucumber/godog/pull/372) - [leviable])
2122

2223
### Changed
2324

_examples/custom-formatter/README.md

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
# Custom Formatter Example
3+
4+
This example custom formatter demonstrates some ways to build and use custom formatters with godog
5+
6+
7+
## Emoji Progress
8+
9+
The first example is the Emoji formatter, built on top of the Progress formatter that is included with godog.
10+
11+
To run it:
12+
13+
```
14+
$ godog -f emoji
15+
```
16+
17+
Which would output step progress as emojis rather than text:
18+
19+
![](imgs/emoji-output-example.png)

_examples/custom-formatter/custom.go

-32
This file was deleted.

_examples/custom-formatter/emoji.go

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"io"
6+
"math"
7+
8+
"github.com/cucumber/godog"
9+
)
10+
11+
const (
12+
passedEmoji = "✅"
13+
skippedEmoji = "➖"
14+
failedEmoji = "❌"
15+
undefinedEmoji = "❓"
16+
pendingEmoji = "🚧"
17+
)
18+
19+
func init() {
20+
godog.Format("emoji", "Progress formatter with emojis", emojiFormatterFunc)
21+
}
22+
23+
func emojiFormatterFunc(suite string, out io.Writer) godog.Formatter {
24+
return newEmojiFmt(suite, out)
25+
}
26+
27+
func newEmojiFmt(suite string, out io.Writer) *emojiFmt {
28+
return &emojiFmt{
29+
ProgressFmt: godog.NewProgressFmt(suite, out),
30+
out: out,
31+
}
32+
}
33+
34+
type emojiFmt struct {
35+
*godog.ProgressFmt
36+
37+
out io.Writer
38+
}
39+
40+
func (f *emojiFmt) TestRunStarted() {}
41+
42+
func (f *emojiFmt) Passed(scenario *godog.Scenario, step *godog.Step, match *godog.StepDefinition) {
43+
f.ProgressFmt.Base.Passed(scenario, step, match)
44+
45+
f.ProgressFmt.Base.Lock.Lock()
46+
defer f.ProgressFmt.Base.Lock.Unlock()
47+
48+
f.step(step.Id)
49+
}
50+
51+
func (f *emojiFmt) Skipped(scenario *godog.Scenario, step *godog.Step, match *godog.StepDefinition) {
52+
f.ProgressFmt.Base.Skipped(scenario, step, match)
53+
54+
f.ProgressFmt.Base.Lock.Lock()
55+
defer f.ProgressFmt.Base.Lock.Unlock()
56+
57+
f.step(step.Id)
58+
}
59+
60+
func (f *emojiFmt) Undefined(scenario *godog.Scenario, step *godog.Step, match *godog.StepDefinition) {
61+
f.ProgressFmt.Base.Undefined(scenario, step, match)
62+
63+
f.ProgressFmt.Base.Lock.Lock()
64+
defer f.ProgressFmt.Base.Lock.Unlock()
65+
66+
f.step(step.Id)
67+
}
68+
69+
func (f *emojiFmt) Failed(scenario *godog.Scenario, step *godog.Step, match *godog.StepDefinition, err error) {
70+
f.ProgressFmt.Base.Failed(scenario, step, match, err)
71+
72+
f.ProgressFmt.Base.Lock.Lock()
73+
defer f.ProgressFmt.Base.Lock.Unlock()
74+
75+
f.step(step.Id)
76+
}
77+
78+
func (f *emojiFmt) Pending(scenario *godog.Scenario, step *godog.Step, match *godog.StepDefinition) {
79+
f.ProgressFmt.Base.Pending(scenario, step, match)
80+
81+
f.ProgressFmt.Base.Lock.Lock()
82+
defer f.ProgressFmt.Base.Lock.Unlock()
83+
84+
f.step(step.Id)
85+
}
86+
87+
func (f *emojiFmt) Summary() {
88+
f.printSummaryLegend()
89+
f.ProgressFmt.Summary()
90+
}
91+
92+
func (f *emojiFmt) printSummaryLegend() {
93+
fmt.Fprint(f.out, "\n\nOutput Legend:\n")
94+
fmt.Fprint(f.out, fmt.Sprintf("\t%s Passed\n", passedEmoji))
95+
fmt.Fprint(f.out, fmt.Sprintf("\t%s Failed\n", failedEmoji))
96+
fmt.Fprint(f.out, fmt.Sprintf("\t%s Skipped\n", skippedEmoji))
97+
fmt.Fprint(f.out, fmt.Sprintf("\t%s Undefined\n", undefinedEmoji))
98+
fmt.Fprint(f.out, fmt.Sprintf("\t%s Pending\n", pendingEmoji))
99+
}
100+
101+
func (f *emojiFmt) step(pickleStepID string) {
102+
pickleStepResult := f.Storage.MustGetPickleStepResult(pickleStepID)
103+
104+
switch pickleStepResult.Status {
105+
case godog.StepPassed:
106+
fmt.Fprint(f.out, fmt.Sprintf(" %s", passedEmoji))
107+
case godog.StepSkipped:
108+
fmt.Fprint(f.out, fmt.Sprintf(" %s", skippedEmoji))
109+
case godog.StepFailed:
110+
fmt.Fprint(f.out, fmt.Sprintf(" %s", failedEmoji))
111+
case godog.StepUndefined:
112+
fmt.Fprint(f.out, fmt.Sprintf(" %s", undefinedEmoji))
113+
case godog.StepPending:
114+
fmt.Fprint(f.out, fmt.Sprintf(" %s", pendingEmoji))
115+
}
116+
117+
*f.Steps++
118+
119+
if math.Mod(float64(*f.Steps), float64(f.StepsPerRow)) == 0 {
120+
fmt.Fprintf(f.out, " %d\n", *f.Steps)
121+
}
122+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# file: $GOPATH/godogs/features/godogs.feature
2+
Feature: Custom emoji formatter examples
3+
In order to be happy
4+
As a hungry gopher
5+
I need to be able to eat godogs
6+
7+
Scenario: Passing test
8+
Given there are 12 godogs
9+
When I eat 5
10+
Then there should be 7 remaining
11+
12+
Scenario: Failing and Skipped test
13+
Given there are 12 godogs
14+
When I eat 5
15+
Then there should be 6 remaining
16+
And there should be 4 remaining
17+
18+
Scenario: Undefined steps
19+
Given there are 12 godogs
20+
When I eat 5
21+
Then this step is not defined
22+
23+
Scenario: Pending step
24+
Given there are 12 godogs
25+
When I eat 5
26+
Then this step is pending

_examples/custom-formatter/go.mod

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ module custom-formatter
33
go 1.14
44

55
require (
6-
github.com/cucumber/gherkin-go/v11 v11.0.0 // indirect
76
github.com/cucumber/godog v0.10.1-0.20210705192606-df8c6e49b40b
8-
github.com/cucumber/messages-go/v10 v10.0.3 // indirect
9-
github.com/cucumber/messages-go/v16 v16.0.1
107
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
118
github.com/hashicorp/go-memdb v1.3.2 // indirect
9+
github.com/kr/text v0.2.0 // indirect
10+
github.com/spf13/pflag v1.0.5
1211
)
12+
13+
replace github.com/cucumber/godog => ../..

0 commit comments

Comments
 (0)