Skip to content

Commit bcf6bce

Browse files
Johnlonvearutop
andauthored
ambiguous step def detection akin to cucumber jvm (#636)
* added basic detection for ambiguous steps, but causes an error and not yet recorded in the reports as 'Ambiguous', and no test cases figured out yet * added initial support for detection of ambiguous steps - further work take a look at how cuke jvm report ambiguous steps and sets the step status to 'ambiguous' rather than my current solution which just blows the test up as a regular step error * added suite_context_test and also introduced missing 'ambiguous' status to make cucumber jvm' * update CHANGELOG for ambiguous step defs * missed file from commit * added internal/formatters/fmt_multi_test.go * add tests for other peoples code * added "ambigous" to the help text * tests * added some more tests for attachments * Update internal/flags/flags.go Co-authored-by: Viacheslav Poturaev <[email protected]> --------- Co-authored-by: Viacheslav Poturaev <[email protected]>
1 parent 3abb346 commit bcf6bce

File tree

15 files changed

+442
-118
lines changed

15 files changed

+442
-118
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
88

99
## Unreleased
1010

11+
- Ambiguous step definitions will now be detected when strit mode is activated - ([636](https://github.com/cucumber/godog/pull/636) - [johnlon](https://github.com/johnlon))
1112
- Provide support for attachments / embeddings including a new example in the examples dir - ([623](https://github.com/cucumber/godog/pull/623) - [johnlon](https://github.com/johnlon))
1213

1314
## [v0.14.1]

attachment_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package godog
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestAttach(t *testing.T) {
11+
12+
ctx := context.Background()
13+
14+
ctx = Attach(ctx, Attachment{Body: []byte("body1"), FileName: "fileName1", MediaType: "mediaType1"})
15+
ctx = Attach(ctx, Attachment{Body: []byte("body2"), FileName: "fileName2", MediaType: "mediaType2"})
16+
17+
attachments := Attachments(ctx)
18+
19+
assert.Equal(t, 2, len(attachments))
20+
21+
assert.Equal(t, []byte("body1"), attachments[0].Body)
22+
assert.Equal(t, "fileName1", attachments[0].FileName)
23+
assert.Equal(t, "mediaType1", attachments[0].MediaType)
24+
25+
assert.Equal(t, []byte("body2"), attachments[1].Body)
26+
assert.Equal(t, "fileName2", attachments[1].FileName)
27+
assert.Equal(t, "mediaType2", attachments[1].MediaType)
28+
}

flags.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func BindFlags(prefix string, set *flag.FlagSet, opt *Options) {
121121
set.BoolVar(&opt.ShowStepDefinitions, prefix+"definitions", defShowStepDefinitions, "Print all available step definitions.")
122122
set.BoolVar(&opt.ShowStepDefinitions, prefix+"d", defShowStepDefinitions, "Print all available step definitions.")
123123
set.BoolVar(&opt.StopOnFailure, prefix+"stop-on-failure", defStopOnFailure, "Stop processing on first failed scenario.")
124-
set.BoolVar(&opt.Strict, prefix+"strict", defStrict, "Fail suite when there are pending or undefined steps.")
124+
set.BoolVar(&opt.Strict, prefix+"strict", defStrict, "Fail suite when there are pending or undefined or ambiguous steps.")
125125
set.BoolVar(&opt.NoColors, prefix+"no-colors", defNoColors, "Disable ansi colors.")
126126
set.Var(&randomSeed{&opt.Randomize}, prefix+"random", descRandomOption)
127127
set.BoolVar(&opt.ShowHelp, "godog.help", false, "Show usage help.")

formatters/fmt.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ type Formatter interface {
7070
Skipped(*messages.Pickle, *messages.PickleStep, *StepDefinition)
7171
Undefined(*messages.Pickle, *messages.PickleStep, *StepDefinition)
7272
Pending(*messages.Pickle, *messages.PickleStep, *StepDefinition)
73+
Ambiguous(*messages.Pickle, *messages.PickleStep, *StepDefinition, error)
7374
Summary()
7475
}
7576

internal/flags/flags.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ built-in formatters are:
3939

4040
flagSet.BoolVarP(&opts.ShowStepDefinitions, prefix+"definitions", "d", opts.ShowStepDefinitions, "print all available step definitions")
4141
flagSet.BoolVar(&opts.StopOnFailure, prefix+"stop-on-failure", opts.StopOnFailure, "stop processing on first failed scenario")
42-
flagSet.BoolVar(&opts.Strict, prefix+"strict", opts.Strict, "fail suite when there are pending or undefined steps")
42+
flagSet.BoolVar(&opts.Strict, prefix+"strict", opts.Strict, "fail suite when there are pending or undefined or ambiguous steps")
4343

4444
flagSet.Int64Var(&opts.Randomize, prefix+"random", opts.Randomize, `randomly shuffle the scenario execution order
4545
--random

internal/flags/options.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ type Options struct {
3838
// Stops on the first failure
3939
StopOnFailure bool
4040

41-
// Fail suite when there are pending or undefined steps
41+
// Fail suite when there are pending or undefined or ambiguous steps
4242
Strict bool
4343

4444
// Forces ansi color stripping

internal/formatters/fmt.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ var (
3636
skipped = models.Skipped
3737
undefined = models.Undefined
3838
pending = models.Pending
39+
ambiguous = models.Skipped
3940
)
4041

4142
type sortFeaturesByName []*models.Feature

internal/formatters/fmt_base.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ func (f *Base) Failed(*messages.Pickle, *messages.PickleStep, *formatters.StepDe
8585
func (f *Base) Pending(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition) {
8686
}
8787

88+
// Ambiguous captures ambiguous step.
89+
func (f *Base) Ambiguous(*messages.Pickle, *messages.PickleStep, *formatters.StepDefinition, error) {
90+
}
91+
8892
// Summary renders summary information.
8993
func (f *Base) Summary() {
9094
var totalSc, passedSc, undefinedSc int

internal/formatters/fmt_cucumber.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ func (f *Cuke) buildCukeElements(pickles []*messages.Pickle) (res []cukeElement)
101101
cukeStep.Result.Duration = &d
102102
if stepResult.Status == undefined ||
103103
stepResult.Status == pending ||
104-
stepResult.Status == skipped {
104+
stepResult.Status == skipped ||
105+
stepResult.Status == ambiguous {
105106
cukeStep.Result.Duration = nil
106107
}
107108

internal/formatters/fmt_multi.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ func (r repeater) Pending(pickle *messages.Pickle, step *messages.PickleStep, de
9797
}
9898
}
9999

100+
// Ambiguous triggers Ambiguous for all added formatters.
101+
func (r repeater) Ambiguous(pickle *messages.Pickle, step *messages.PickleStep, definition *formatters.StepDefinition, err error) {
102+
for _, f := range r {
103+
f.Ambiguous(pickle, step, definition, err)
104+
}
105+
}
106+
100107
// Summary triggers Summary for all added formatters.
101108
func (r repeater) Summary() {
102109
for _, f := range r {

internal/formatters/fmt_multi_test.go

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
package formatters
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/cucumber/godog/formatters"
8+
messages "github.com/cucumber/messages/go/v21"
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
var (
13+
mock = DummyFormatter{}
14+
base = BaseFormatter{}
15+
16+
document = &messages.GherkinDocument{}
17+
str = "theString"
18+
byt = []byte("bytes")
19+
pickle = &messages.Pickle{}
20+
step = &messages.PickleStep{}
21+
definition = &formatters.StepDefinition{}
22+
err = errors.New("expected")
23+
)
24+
25+
// TestRepeater tests the delegation of the repeater functions.
26+
func TestRepeater(t *testing.T) {
27+
28+
mock.tt = t
29+
f := make(repeater, 0)
30+
f = append(f, &mock)
31+
f = append(f, &mock)
32+
f = append(f, &base)
33+
34+
f.Feature(document, str, byt)
35+
f.TestRunStarted()
36+
f.Pickle(pickle)
37+
f.Defined(pickle, step, definition)
38+
f.Passed(pickle, step, definition)
39+
f.Skipped(pickle, step, definition)
40+
f.Undefined(pickle, step, definition)
41+
f.Failed(pickle, step, definition, err)
42+
f.Pending(pickle, step, definition)
43+
f.Ambiguous(pickle, step, definition, err)
44+
45+
assert.Equal(t, 2, mock.CountFeature)
46+
assert.Equal(t, 2, mock.CountTestRunStarted)
47+
assert.Equal(t, 2, mock.CountPickle)
48+
assert.Equal(t, 2, mock.CountDefined)
49+
assert.Equal(t, 2, mock.CountPassed)
50+
assert.Equal(t, 2, mock.CountSkipped)
51+
assert.Equal(t, 2, mock.CountUndefined)
52+
assert.Equal(t, 2, mock.CountFailed)
53+
assert.Equal(t, 2, mock.CountPending)
54+
assert.Equal(t, 2, mock.CountAmbiguous)
55+
56+
}
57+
58+
type BaseFormatter struct {
59+
*Base
60+
}
61+
62+
type DummyFormatter struct {
63+
*Base
64+
65+
tt *testing.T
66+
CountFeature int
67+
CountTestRunStarted int
68+
CountPickle int
69+
CountDefined int
70+
CountPassed int
71+
CountSkipped int
72+
CountUndefined int
73+
CountFailed int
74+
CountPending int
75+
CountAmbiguous int
76+
}
77+
78+
// SetStorage assigns gherkin data storage.
79+
// func (f *DummyFormatter) SetStorage(st *storage.Storage) {
80+
// }
81+
82+
// TestRunStarted is triggered on test start.
83+
func (f *DummyFormatter) TestRunStarted() {
84+
f.CountTestRunStarted++
85+
}
86+
87+
// Feature receives gherkin document.
88+
func (f *DummyFormatter) Feature(d *messages.GherkinDocument, s string, b []byte) {
89+
assert.Equal(f.tt, document, d)
90+
assert.Equal(f.tt, str, s)
91+
assert.Equal(f.tt, byt, b)
92+
f.CountFeature++
93+
}
94+
95+
// Pickle receives scenario.
96+
func (f *DummyFormatter) Pickle(p *messages.Pickle) {
97+
assert.Equal(f.tt, pickle, p)
98+
f.CountPickle++
99+
}
100+
101+
// Defined receives step definition.
102+
func (f *DummyFormatter) Defined(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition) {
103+
assert.Equal(f.tt, pickle, p)
104+
assert.Equal(f.tt, s, step)
105+
assert.Equal(f.tt, d, definition)
106+
f.CountDefined++
107+
}
108+
109+
// Passed captures passed step.
110+
func (f *DummyFormatter) Passed(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition) {
111+
assert.Equal(f.tt, pickle, p)
112+
assert.Equal(f.tt, s, step)
113+
assert.Equal(f.tt, d, definition)
114+
f.CountPassed++
115+
}
116+
117+
// Skipped captures skipped step.
118+
func (f *DummyFormatter) Skipped(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition) {
119+
assert.Equal(f.tt, pickle, p)
120+
assert.Equal(f.tt, s, step)
121+
assert.Equal(f.tt, d, definition)
122+
123+
f.CountSkipped++
124+
}
125+
126+
// Undefined captures undefined step.
127+
func (f *DummyFormatter) Undefined(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition) {
128+
assert.Equal(f.tt, pickle, p)
129+
assert.Equal(f.tt, s, step)
130+
assert.Equal(f.tt, d, definition)
131+
132+
f.CountUndefined++
133+
}
134+
135+
// Failed captures failed step.
136+
func (f *DummyFormatter) Failed(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition, e error) {
137+
assert.Equal(f.tt, pickle, p)
138+
assert.Equal(f.tt, s, step)
139+
assert.Equal(f.tt, d, definition)
140+
assert.Equal(f.tt, err, e)
141+
142+
f.CountFailed++
143+
}
144+
145+
// Pending captures pending step.
146+
func (f *DummyFormatter) Pending(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition) {
147+
assert.Equal(f.tt, pickle, p)
148+
assert.Equal(f.tt, s, step)
149+
assert.Equal(f.tt, d, definition)
150+
151+
f.CountPending++
152+
}
153+
154+
// Ambiguous captures ambiguous step.
155+
func (f *DummyFormatter) Ambiguous(p *messages.Pickle, s *messages.PickleStep, d *formatters.StepDefinition, e error) {
156+
assert.Equal(f.tt, pickle, p)
157+
assert.Equal(f.tt, s, step)
158+
assert.Equal(f.tt, d, definition)
159+
f.CountAmbiguous++
160+
}

internal/models/results.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ const (
7272
Undefined
7373
// Pending ...
7474
Pending
75+
// Ambiguous ...
76+
Ambiguous
7577
)
7678

7779
// Color ...
@@ -101,6 +103,8 @@ func (st StepResultStatus) String() string {
101103
return "undefined"
102104
case Pending:
103105
return "pending"
106+
case Ambiguous:
107+
return "ambiguous"
104108
default:
105109
return "unknown"
106110
}

internal/models/results_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package models_test
22

33
import (
4+
"fmt"
45
"testing"
56

67
"github.com/stretchr/testify/assert"
@@ -21,6 +22,7 @@ var stepResultStatusTestCases = []stepResultStatusTestCase{
2122
{st: models.Skipped, str: "skipped", clr: colors.Cyan},
2223
{st: models.Undefined, str: "undefined", clr: colors.Yellow},
2324
{st: models.Pending, str: "pending", clr: colors.Yellow},
25+
{st: models.Ambiguous, str: "ambiguous", clr: colors.Yellow},
2426
{st: -1, str: "unknown", clr: colors.Yellow},
2527
}
2628

@@ -32,3 +34,21 @@ func Test_StepResultStatus(t *testing.T) {
3234
})
3335
}
3436
}
37+
38+
func Test_NewStepResuklt(t *testing.T) {
39+
status := models.StepResultStatus(123)
40+
pickleID := "pickleId"
41+
pickleStepID := "pickleStepID"
42+
match := &models.StepDefinition{}
43+
attachments := make([]models.PickleAttachment, 0)
44+
err := fmt.Errorf("intentional")
45+
46+
results := models.NewStepResult(status, pickleID, pickleStepID, match, attachments, err)
47+
48+
assert.Equal(t, status, results.Status)
49+
assert.Equal(t, pickleID, results.PickleID)
50+
assert.Equal(t, pickleStepID, results.PickleStepID)
51+
assert.Equal(t, match, results.Def)
52+
assert.Equal(t, attachments, results.Attachments)
53+
assert.Equal(t, err, results.Err)
54+
}

0 commit comments

Comments
 (0)