Repository: go-bdd/gobdd
Pull request #148 (2023-11-15 13:24:47)

fix: cannot have multiple parameter type on the same line (go-bdd#147)
see #147 

vlalanne: Hello @sagikazarmark,
You are the last contributor on this project.
Do you know if it still alive ?
Is it worth it to propose pull requests?

Patch:
diff --git a/docs/parameter-types.md b/docs/parameter-types.md
index 073b98c..5764530 100644
--- a/docs/parameter-types.md
+++ b/docs/parameter-types.md
@@ -10,16 +10,16 @@ GoBDD has support for [parameter types](https://cucumber.io/docs/cucumber/cucumb
  * `{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"`)
+ * `{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]+)'`})
+	s.AddParameterTypes(`{int}`, []string{`(-?\d+)`})
+	s.AddParameterTypes(`{float}`, []string{`([-+]?\d*\.?\d+)`})
+	s.AddParameterTypes(`{word}`, []string{`([^\s]+)`})
+	s.AddParameterTypes(`{text}`, []string{`"([^"\\]*(?:\\.[^"\\]*)*)"`, `'([^'\\]*(?:\\.[^'\\]*)*)'`})
 ```
 
 The first argument accepts the parameter types. As the second parameter provides list of regular expressions that should replace the parameter.
diff --git a/features/parameter-types.feature b/features/parameter-types.feature
index 56539e6..a8de558 100644
--- a/features/parameter-types.feature
+++ b/features/parameter-types.feature
@@ -5,9 +5,20 @@ Feature: parameter types
   Scenario: simple word
     When I use word pizza
   Scenario: simple text with double quotes
-    When I use text "I like pizza"
+    When I use text "I like pizza!"
+    Then the result should equal text 'I like pizza!'
   Scenario: simple text with single quotes
-    When I use text 'I like pizza'
+    When I use text 'I like pizza!'
+    Then the result should equal text 'I like pizza!'
   Scenario: add two floats
-    When I add floats 1 and 2
-    Then the result should equal float 3
\ No newline at end of file
+    When I add floats -1.2 and 2.4
+    Then the result should equal float 1.2
+  Scenario: concat a word and a text with single quotes
+    When I concat word Hello and text ' World!'
+    Then the result should equal text 'Hello World!'
+  Scenario: concat a word and a text with double quotes
+    When I concat word Hello and text " World!"
+    Then the result should equal text "Hello World!"
+  Scenario: format text
+    When I format text "counter %d" with int -12
+    Then the result should equal text "counter -12"
diff --git a/gobdd.go b/gobdd.go
index d9f8527..28edfe8 100644
--- a/gobdd.go
+++ b/gobdd.go
@@ -193,10 +193,11 @@ func NewSuite(t TestingT, optionClosures ...func(*SuiteOptions)) *Suite {
 		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]+)'`})
+	// see https://github.com/cucumber/cucumber-expressions/blob/main/go/parameter_type_registry.go
+	s.AddParameterTypes(`{int}`, []string{`(-?\d+)`})
+	s.AddParameterTypes(`{float}`, []string{`([-+]?\d*\.?\d+)`})
+	s.AddParameterTypes(`{word}`, []string{`([^\s]+)`})
+	s.AddParameterTypes(`{text}`, []string{`"([^"\\]*(?:\\.[^"\\]*)*)"`, `'([^'\\]*(?:\\.[^'\\]*)*)'`})
 
 	return s
 }
@@ -206,7 +207,7 @@ func NewSuite(t TestingT, optionClosures ...func(*SuiteOptions)) *Suite {
 // 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)`})
+//	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) {
@@ -228,8 +229,8 @@ func (s *Suite) AddParameterTypes(from string, to []string) {
 // A step function can have any number of parameters (even zero),
 // but it MUST accept a gobdd.StepTest and gobdd.Context as the first parameters (if there is any):
 //
-// 	func myStepFunction(t gobdd.StepTest, ctx gobdd.Context, first int, second int) {
-// 	}
+//	func myStepFunction(t gobdd.StepTest, ctx gobdd.Context, first int, second int) {
+//	}
 func (s *Suite) AddStep(expr string, step interface{}) {
 	err := validateStepFunc(step)
 	if err != nil {
@@ -263,7 +264,7 @@ func (s *Suite) applyParameterTypes(expr string) []string {
 	for from, to := range s.parameterTypes {
 		for _, t := range to {
 			if strings.Contains(expr, from) {
-				exprs = append(exprs, strings.ReplaceAll(expr, from, t))
+				exprs = append(exprs, s.applyParameterTypes(strings.ReplaceAll(expr, from, t))...)
 			}
 		}
 	}
@@ -279,8 +280,8 @@ func (s *Suite) applyParameterTypes(expr string) []string {
 // A step function can have any number of parameters (even zero),
 // but it MUST accept a gobdd.StepTest and gobdd.Context as the first parameters (if there is any):
 //
-// 	func myStepFunction(t gobdd.StepTest, ctx gobdd.Context, first int, second int) {
-// 	}
+//	func myStepFunction(t gobdd.StepTest, ctx gobdd.Context, first int, second int) {
+//	}
 func (s *Suite) AddRegexStep(expr *regexp.Regexp, step interface{}) {
 	err := validateStepFunc(step)
 	if err != nil {
@@ -322,14 +323,14 @@ func (s *Suite) Run() {
 }
 
 func (s *Suite) executeFeature(feature feature) error {
-  f, err := feature.Open()
+	f, err := feature.Open()
 	if err != nil {
 		return err
 	}
 
-  if closer, ok := f.(io.Closer); ok {
-    defer closer.Close()
-  }
+	if closer, ok := f.(io.Closer); ok {
+		defer closer.Close()
+	}
 
 	featureIO := bufio.NewReader(f)
 


Test patch:
diff --git a/gobdd_test.go b/gobdd_test.go
index 79eb05c..0b915d8 100644
--- a/gobdd_test.go
+++ b/gobdd_test.go
@@ -51,15 +51,18 @@ func TestParameterTypes(t *testing.T) {
 	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(`the result should equal text {text}`, checkt)
 	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")
-		}
+		ctx.Set("stringRes", text)
+	})
+	suite.AddStep(`I concat word {word} and text {text}`, concat)
+	suite.AddStep(`I format text {text} with int {int}`, func(t StepTest, ctx Context, format string, value int) {
+		ctx.Set("stringRes", fmt.Sprintf(format, value))
 	})
 
 	suite.Run()
@@ -275,6 +278,23 @@ func add(_ StepTest, ctx Context, var1, var2 int) {
 	ctx.Set("sumRes", res)
 }
 
+func concat(_ StepTest, ctx Context, var1, var2 string) {
+	ctx.Set("stringRes", var1+var2)
+}
+
+func checkt(t StepTest, ctx Context, text string) {
+	received, err := ctx.GetString("stringRes")
+	if err != nil {
+		t.Error(err.Error())
+
+		return
+	}
+
+	if text != received {
+		t.Errorf("expected %s but %s received", text, received)
+	}
+}
+
 func checkf(t StepTest, ctx Context, sum float32) {
 	received, err := ctx.Get("sumRes")
 	if err != nil {
@@ -284,7 +304,7 @@ func checkf(t StepTest, ctx Context, sum float32) {
 	}
 
 	if sum != received {
-		t.Error("the sum doesn't match")
+		t.Errorf("expected %f but %f received", sum, received)
 	}
 }