diff --git a/features/snippets.feature b/features/snippets.feature index e5119f79..92f6a6e6 100644 --- a/features/snippets.feature +++ b/features/snippets.feature @@ -3,7 +3,7 @@ Feature: undefined step snippets As a test suite user I need to be able to get undefined step snippets - Scenario: should generate snippets + Scenario: should generate snippets with step_func snippet func when snippet func is not found Given a feature "undefined.feature" file: """ Feature: undefined steps @@ -12,6 +12,7 @@ Feature: undefined step snippets When I send "GET" request to "/version" Then the response code should be 200 """ + And snippet function is: " " When I run feature suite Then the following steps should be undefined: """ @@ -34,6 +35,70 @@ Feature: undefined step snippets } """ + Scenario: should generate snippets with step_func snippet func + Given a feature "undefined.feature" file: + """ + Feature: undefined steps + + Scenario: get version number from api + When I send "GET" request to "/version" + Then the response code should be 200 + """ + And snippet function is: "step_func" + When I run feature suite + Then the following steps should be undefined: + """ + I send "GET" request to "/version" + the response code should be 200 + """ + And the undefined step snippets should be: + """ + func iSendRequestTo(arg1, arg2 string) error { + return godog.ErrPending + } + + func theResponseCodeShouldBe(arg1 int) error { + return godog.ErrPending + } + + func InitializeScenario(ctx *godog.ScenarioContext) { + ctx.Step(`^I send "([^"]*)" request to "([^"]*)"$`, iSendRequestTo) + ctx.Step(`^the response code should be (\d+)$`, theResponseCodeShouldBe) + } + """ + + Scenario: should generate snippets with gwt_func snippet func + Given a feature "undefined.feature" file: + """ + Feature: undefined steps + + Scenario: get version number from api + When I send "GET" request to "/version" + Then the response code should be 200 + """ + And snippet function is: "gwt_func" + When I run feature suite + Then the following steps should be undefined: + """ + I send "GET" request to "/version" + the response code should be 200 + """ + And the undefined step snippets should be: + """ + func iSendRequestTo(arg1, arg2 string) error { + return godog.ErrPending + } + + func theResponseCodeShouldBe(arg1 int) error { + return godog.ErrPending + } + + func InitializeScenario(ctx *godog.ScenarioContext) { + ctx.When(`^I send "([^"]*)" request to "([^"]*)"$`, iSendRequestTo) + ctx.Then(`^the response code should be (\d+)$`, theResponseCodeShouldBe) + } + """ + Scenario: should generate snippets with more arguments Given a feature "undefined.feature" file: """ @@ -71,6 +136,44 @@ Feature: undefined step snippets } """ + Scenario: should generate snippets with more arguments with gwt_func snippet func + Given a feature "undefined.feature" file: + """ + Feature: undefined steps + + Scenario: get version number from api + When I send "GET" request to "/version" with: + | col1 | val1 | + | col2 | val2 | + Then the response code should be 200 and header "X-Powered-By" should be "godog" + And the response body should be: + \"\"\" + Hello World + \"\"\" + """ + And snippet function is: "gwt_func" + When I run feature suite + Then the undefined step snippets should be: + """ + func iSendRequestToWith(arg1, arg2 string, arg3 *godog.Table) error { + return godog.ErrPending + } + + func theResponseBodyShouldBe(arg1 *godog.DocString) error { + return godog.ErrPending + } + + func theResponseCodeShouldBeAndHeaderShouldBe(arg1 int, arg2, arg3 string) error { + return godog.ErrPending + } + + func InitializeScenario(ctx *godog.ScenarioContext) { + ctx.When(`^I send "([^"]*)" request to "([^"]*)" with:$`, iSendRequestToWith) + ctx.Then(`^the response body should be:$`, theResponseBodyShouldBe) + ctx.Then(`^the response code should be (\d+) and header "([^"]*)" should be "([^"]*)"$`, theResponseCodeShouldBeAndHeaderShouldBe) + } + """ + Scenario: should handle escaped symbols Given a feature "undefined.feature" file: """ @@ -102,6 +205,38 @@ Feature: undefined step snippets } """ + Scenario: should handle escaped symbols with gwt_func snippet func + Given a feature "undefined.feature" file: + """ + Feature: undefined steps + + Scenario: get version number from api + When I pull from github.com + Then the project should be there + """ + And snippet function is: "gwt_func" + When I run feature suite + Then the following steps should be undefined: + """ + I pull from github.com + the project should be there + """ + And the undefined step snippets should be: + """ + func iPullFromGithubcom() error { + return godog.ErrPending + } + + func theProjectShouldBeThere() error { + return godog.ErrPending + } + + func InitializeScenario(ctx *godog.ScenarioContext) { + ctx.When(`^I pull from github\.com$`, iPullFromGithubcom) + ctx.Then(`^the project should be there$`, theProjectShouldBeThere) + } + """ + Scenario: should handle string argument followed by comma Given a feature "undefined.feature" file: """ @@ -128,7 +263,34 @@ Feature: undefined step snippets } """ - Scenario: should handle arguments in the beggining or end of the step + Scenario: should handle string argument followed by comma with gwt_func snippet func + Given a feature "undefined.feature" file: + """ + Feature: undefined + + Scenario: add item to basket + Given there is a "Sith Lord Lightsaber", which costs £5 + When I add the "Sith Lord Lightsaber" to the basket + """ + And snippet function is: "gwt_func" + When I run feature suite + And the undefined step snippets should be: + """ + func iAddTheToTheBasket(arg1 string) error { + return godog.ErrPending + } + + func thereIsAWhichCosts(arg1 string, arg2 int) error { + return godog.ErrPending + } + + func InitializeScenario(ctx *godog.ScenarioContext) { + ctx.When(`^I add the "([^"]*)" to the basket$`, iAddTheToTheBasket) + ctx.Given(`^there is a "([^"]*)", which costs £(\d+)$`, thereIsAWhichCosts) + } + """ + + Scenario: should handle arguments in the beginning or end of the step Given a feature "undefined.feature" file: """ Feature: undefined @@ -153,3 +315,30 @@ Feature: undefined step snippets ctx.Step(`^"([^"]*)", which costs £(\d+)$`, whichCosts) } """ + + Scenario: should handle arguments in the beginning or end of the step with gwt_func snippet func + Given a feature "undefined.feature" file: + """ + Feature: undefined + + Scenario: add item to basket + Given "Sith Lord Lightsaber", which costs £5 + And 12 godogs + """ + And snippet function is: "gwt_func" + When I run feature suite + And the undefined step snippets should be: + """ + func godogs(arg1 int) error { + return godog.ErrPending + } + + func whichCosts(arg1 string, arg2 int) error { + return godog.ErrPending + } + + func InitializeScenario(ctx *godog.ScenarioContext) { + ctx.Given(`^(\d+) godogs$`, godogs) + ctx.Given(`^"([^"]*)", which costs £(\d+)$`, whichCosts) + } + """ diff --git a/internal/snippets/snippets.go b/internal/snippets/snippets.go index 5654bb1d..b3c901e0 100644 --- a/internal/snippets/snippets.go +++ b/internal/snippets/snippets.go @@ -23,5 +23,5 @@ func Find(name string) Func { if ok { return f } - return StepFunction + return StepFunc } diff --git a/internal/snippets/step_func_snippet.go b/internal/snippets/step_func_snippet.go index 00743693..51804d3c 100644 --- a/internal/snippets/step_func_snippet.go +++ b/internal/snippets/step_func_snippet.go @@ -8,14 +8,24 @@ import ( messages "github.com/cucumber/messages/go/v21" "sort" "strings" + "text/template" "unicode" ) func init() { - register("step_func", StepFunction) + register("step_func", StepFunc) + register("gwt_func", GwtFunc) } -func StepFunction(s *storage.Storage) string { +func StepFunc(s *storage.Storage) string { + return BaseFunc(s, undefinedStepFuncSnippetsTpl) +} + +func GwtFunc(s *storage.Storage) string { + return BaseFunc(s, undefinedGwtFuncSnippetsTpl) +} + +func BaseFunc(s *storage.Storage, tpl *template.Template) string { undefinedStepResults := s.MustGetPickleStepResultsByStatus(models.Undefined) if len(undefinedStepResults) == 0 { return "" @@ -89,7 +99,7 @@ func StepFunction(s *storage.Storage) string { sort.Sort(snippetSortByMethod(snips)) var buf bytes.Buffer - if err := undefinedSnippetsTpl.Execute(&buf, snips); err != nil { + if err := tpl.Execute(&buf, snips); err != nil { panic(err) } // there may be trailing spaces diff --git a/internal/snippets/undefined_snippets_gen.go b/internal/snippets/undefined_snippets_gen.go index e7e9d556..634fca16 100644 --- a/internal/snippets/undefined_snippets_gen.go +++ b/internal/snippets/undefined_snippets_gen.go @@ -22,7 +22,7 @@ var snippetHelperFuncs = template.FuncMap{ }, } -var undefinedSnippetsTpl = template.Must(template.New("snippets").Funcs(snippetHelperFuncs).Parse(` +var undefinedStepFuncSnippetsTpl = template.Must(template.New("snippets").Funcs(snippetHelperFuncs).Parse(` {{ range . }}func {{ .Method }}({{ .Args }}) error { return godog.ErrPending } @@ -32,6 +32,16 @@ var undefinedSnippetsTpl = template.Must(template.New("snippets").Funcs(snippetH } `)) +var undefinedGwtFuncSnippetsTpl = template.Must(template.New("snippets").Funcs(snippetHelperFuncs).Parse(` +{{ range . }}func {{ .Method }}({{ .Args }}) error { + return godog.ErrPending +} + +{{end}}func InitializeScenario(ctx *godog.ScenarioContext) { {{ range . }} + ctx.{{ .Type }}({{ backticked .Expr }}, {{ .Method }}){{end}} +} +`)) + type undefinedSnippet struct { Method string Expr string diff --git a/run.go b/run.go index c931aeef..5a47c70f 100644 --- a/run.go +++ b/run.go @@ -153,7 +153,7 @@ func (r *runner) concurrent(rate int) (failed bool) { } // print summary - r.fmt.Summary(snippets.StepFunction) + r.fmt.Summary(snippets.StepFunc) return } diff --git a/run_test.go b/run_test.go index 94f71744..6ff8ebe6 100644 --- a/run_test.go +++ b/run_test.go @@ -525,11 +525,11 @@ func Test_AllFeaturesRun(t *testing.T) { ...................................................................... 210 ...................................................................... 280 ...................................................................... 350 -...... 356 +.................................. 384 -94 scenarios (94 passed) -356 steps (356 passed) +100 scenarios (100 passed) +384 steps (384 passed) 0s ` @@ -553,11 +553,11 @@ func Test_AllFeaturesRunAsSubtests(t *testing.T) { ...................................................................... 210 ...................................................................... 280 ...................................................................... 350 -...... 356 +.................................. 384 -94 scenarios (94 passed) -356 steps (356 passed) +100 scenarios (100 passed) +384 steps (384 passed) 0s ` diff --git a/suite_context_test.go b/suite_context_test.go index f9878942..8ebe7953 100644 --- a/suite_context_test.go +++ b/suite_context_test.go @@ -50,6 +50,7 @@ func InitializeScenario(ctx *ScenarioContext) { ctx.Step(`^I run feature suite with formatter "([^"]*)"$`, tc.iRunFeatureSuiteWithFormatter) ctx.Step(`^(?:I )(allow|disable) variable injection`, tc.iSetVariableInjectionTo) ctx.Step(`^(?:a )?feature "([^"]*)"(?: file)?:$`, tc.aFeatureFile) + ctx.Step(`^snippet function is: "([^"]*)"$`, tc.snippetFunctionIs) ctx.Step(`^the suite should have (passed|failed)$`, tc.theSuiteShouldHave) ctx.Step(`^I should have ([\d]+) features? files?:$`, tc.iShouldHaveNumFeatureFiles) @@ -218,6 +219,7 @@ type godogFeaturesScenario struct { paths []string features []*models.Feature testedSuite *suite + snippetFunc string testSuiteContext TestSuiteContext events []*firedEvent out bytes.Buffer @@ -240,6 +242,10 @@ func (tc *godogFeaturesScenario) ResetBeforeEachScenario(ctx context.Context, sc return ctx, nil } +func (tc *godogFeaturesScenario) snippetFunctionIs(snippetFunc string) { + tc.snippetFunc = snippetFunc +} + func (tc *godogFeaturesScenario) iSetVariableInjectionTo(to string) error { tc.allowInjection = to == "allow" return nil @@ -311,7 +317,7 @@ func (tc *godogFeaturesScenario) iRunFeatureSuiteWithTagsAndFormatter(filter str f() } - tc.testedSuite.fmt.Summary(snippets.StepFunction) + tc.testedSuite.fmt.Summary(snippets.Find(tc.snippetFunc)) return nil } @@ -359,11 +365,11 @@ func (tc *godogFeaturesScenario) theUndefinedStepSnippetsShouldBe(body *DocStrin return fmt.Errorf("this step requires *formatters.Base, but there is: %T", tc.testedSuite.fmt) } - actual := tc.cleanupSnippet(f.Snippets(snippets.StepFunction)) + actual := tc.cleanupSnippet(f.Snippets(snippets.Find(tc.snippetFunc))) expected := tc.cleanupSnippet(body.Content) if actual != expected { - return fmt.Errorf("snippets do not match actual: %s", f.Snippets(snippets.StepFunction)) + return fmt.Errorf("snippets do not match actual: %s", f.Snippets(snippets.Find(tc.snippetFunc))) } return nil