Skip to content

Commit

Permalink
Add parameter types (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
Bartłomiej Klimczak authored Jun 1, 2020
1 parent cd7c600 commit b30291a
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 17 deletions.
2 changes: 2 additions & 0 deletions docs/_data/navigation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ main:
url: /creating-steps.html
- title: "Suite's options"
url: /suite-options.html
- title: "Parameter types"
url: /parameter-types.html
- title: "GitHub"
url: https://github.com/go-bdd/gobdd
27 changes: 27 additions & 0 deletions docs/parameter-types.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
layout: default
title: Parameter types
---

# Parameter types

GoBDD has support for [parameter types](https://cucumber.io/docs/cucumber/cucumber-expressions/). There are a few predefined parameter types:

* `{int}` - integer (-1 or 56)
* `{float}` - float (0.4 or 234.4)
* `{word}` - single word (`hello` or `pizza`)
* `{text}` - single-quoted or double-quoted strings (`'I like pizza'` or `"I like pizza"`)

You can add your own parameter types using `AddParameterTypes()` function. Here are a few examples

```go
s := gobdd.NewSuite(t)
s.AddParameterTypes(`{int}`, []string{`(\d)`})
s.AddParameterTypes(`{float}`, []string{`([-+]?\d*\.?\d*)`})
s.AddParameterTypes(`{word}`, []string{`([\d\w]+)`})
s.AddParameterTypes(`{text}`, []string{`"([\d\w\-\s]+)"`, `'([\d\w\-\s]+)'`})
```

The first argument accepts the parameter types. As the second parameter provides list of regular expressions that should replace the parameter.

Parameter types should be added Before adding any step.
13 changes: 13 additions & 0 deletions features/parameter-types.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Feature: parameter types
Scenario: add two digits
When I add 1 and 2
Then the result should equal 3
Scenario: simple word
When I use word pizza
Scenario: simple text with double quotes
When I use text "I like pizza"
Scenario: simple text with single quotes
When I use text 'I like pizza'
Scenario: add two floats
When I add floats 1 and 2
Then the result should equal float 3
80 changes: 63 additions & 17 deletions gobdd.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import (

// Holds all the information about the suite (options, steps to execute etc)
type Suite struct {
t TestingT
steps []stepDef
options SuiteOptions
hasStepErrors bool
t TestingT
steps []stepDef
options SuiteOptions
hasStepErrors bool
parameterTypes map[string][]string
}

// Holds all the information about how the suite or features/steps should be configured
Expand Down Expand Up @@ -123,10 +124,37 @@ func NewSuite(t TestingT, optionClosures ...func(*SuiteOptions)) *Suite {
optionClosures[i](&options)
}

return &Suite{
t: t,
steps: []stepDef{},
options: options,
s := &Suite{
t: t,
steps: []stepDef{},
options: options,
parameterTypes: map[string][]string{},
}

s.AddParameterTypes(`{int}`, []string{`(\d)`})
s.AddParameterTypes(`{float}`, []string{`([-+]?\d*\.?\d*)`})
s.AddParameterTypes(`{word}`, []string{`([\d\w]+)`})
s.AddParameterTypes(`{text}`, []string{`"([\d\w\-\s]+)"`, `'([\d\w\-\s]+)'`})

return s
}

// AddParameterTypes adds a list of parameter types that will be used to simplify step definitions.
//
// The first argument is the parameter type and the second parameter is a list of regular expressions
// that should replace the parameter type.
//
// s.AddParameterTypes(`{int}`, []string{`(\d)`})
//
// The regular expression should compile, otherwise will produce an error and stop executing.
func (s *Suite) AddParameterTypes(from string, to []string) {
for _, to := range to {
_, err := regexp.Compile(to)
if err != nil {
s.t.Fatalf(`the regular expresion for key %s doesn't compile: %s`, from, to)
}

s.parameterTypes[from] = append(s.parameterTypes[from], to)
}
}

Expand All @@ -149,18 +177,36 @@ func (s *Suite) AddStep(expr string, step interface{}) {
return
}

compiled, err := regexp.Compile(expr)
if err != nil {
s.t.Errorf("the step function is incorrect: %w", err)
s.hasStepErrors = true
exprs := s.applyParameterTypes(expr)

return
for _, expr := range exprs {
compiled, err := regexp.Compile(expr)
if err != nil {
s.t.Errorf("the step function is incorrect: %w", err)
s.hasStepErrors = true

return
}

s.steps = append(s.steps, stepDef{
expr: compiled,
f: step,
})
}
}

s.steps = append(s.steps, stepDef{
expr: compiled,
f: step,
})
func (s *Suite) applyParameterTypes(expr string) []string {
exprs := []string{expr}

for from, to := range s.parameterTypes {
for _, t := range to {
if strings.Contains(expr, from) {
exprs = append(exprs, strings.Replace(expr, from, t, -1))
}
}
}

return exprs
}

// AddRegexStep registers a step in the suite.
Expand Down
19 changes: 19 additions & 0 deletions gobdd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ func TestScenarioOutline(t *testing.T) {

suite.Run()
}
func TestParameterTypes(t *testing.T) {
suite := NewSuite(t, WithFeaturesPath("features/parameter-types.feature"))
suite.AddStep(`I add {int} and {int}`, add)
suite.AddStep(`the result should equal {int}`, check)
suite.AddStep(`I add floats {float} and {float}`, addf)
suite.AddStep(`the result should equal float {float}`, checkf)
suite.AddStep(`I use word {word}`, func(t StepTest, ctx Context, word string) {
if word != "pizza" {
t.Fatal("it should be pizza")
}
})
suite.AddStep(`I use text {text}`, func(t StepTest, ctx Context, text string) {
if text != "I like pizza" {
t.Fatal("it should say that I like pizza")
}
})

suite.Run()
}

func TestScenarioOutlineExecutesAllTests(t *testing.T) {
c := 0
Expand Down

0 comments on commit b30291a

Please sign in to comment.