Skip to content

Commit

Permalink
feat: new assertion ShouldMatchRegex
Browse files Browse the repository at this point in the history
Signed-off-by: Fokion Sotiropoulos <fokion.s@gmail.com>
  • Loading branch information
fokion committed Jun 1, 2023
1 parent 0b4842d commit d21895e
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 91 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ Builtin variables:
* ShouldHappenOnOrAfter - [example](https://github.com/ovh/venom/tree/master/tests/assertions/ShouldHappenOnOrAfter.yml)
* ShouldHappenBetween - [example](https://github.com/ovh/venom/tree/master/tests/assertions/ShouldHappenBetween.yml)
* ShouldTimeEqual - [example](https://github.com/ovh/venom/tree/master/tests/assertions/ShouldTimeEqual.yml)
* ShouldMatchRegex - [example](https://github.com/ovh/venom/tree/master/tests/assertions/ShouldMatchRegex.yml)

#### `Must` keywords

Expand Down
204 changes: 113 additions & 91 deletions assertions/assertions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"math"
"reflect"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -60,6 +61,7 @@ var assertMap = map[string]AssertFunc{
"ShouldTimeEqual": ShouldTimeEqual,
"ShouldBeArray": ShouldBeArray,
"ShouldBeMap": ShouldBeMap,
"ShouldMatchRegex": ShouldMatchRegex,
}

func Get(s string) (AssertFunc, bool) {
Expand Down Expand Up @@ -100,14 +102,13 @@ func ShouldBeMap(actual interface{}, expected ...interface{}) error {
//
// Example of testsuite file:
//
// name: Assertions testsuite
// testcases:
// - name: test assertion
// steps:
// - script: echo 'foo'
// assertions:
// - result.code ShouldEqual 0
//
// name: Assertions testsuite
// testcases:
// - name: test assertion
// steps:
// - script: echo 'foo'
// assertions:
// - result.code ShouldEqual 0
func ShouldEqual(actual interface{}, expected ...interface{}) error {
// if expected is an array, we consider that this array is an array of string
// so, we concat all values before doing the comparison
Expand Down Expand Up @@ -135,6 +136,29 @@ func ShouldEqual(actual interface{}, expected ...interface{}) error {
return fmt.Errorf("expected: %v got: %v", expected[0], actual)
}

// ShouldMatchRegex receives exactly two parameters and does a regex match check.
func ShouldMatchRegex(actual interface{}, expected ...interface{}) error {
if need(1, expected) != nil {
return fmt.Errorf("expected one regex pattern")
}
expectedAsString, regexNotString := cast.ToStringE(expected[0])
if regexNotString != nil {
return fmt.Errorf("expected a string for regex pattern")
}
reg, err := regexp.Compile(expectedAsString)
if err != nil {
return err
}
actualAsString, castingErr := cast.ToStringE(actual)
if castingErr != nil {
return castingErr
}
if !reg.MatchString(actualAsString) {
return fmt.Errorf("value %v not matching pattern : %v", actual, expected[0])
}
return nil
}

// ShouldNotEqual receives exactly two parameters and does an inequality check.
func ShouldNotEqual(actual interface{}, expected ...interface{}) error {
if err := ShouldEqual(actual, expected...); err == nil {
Expand Down Expand Up @@ -625,14 +649,13 @@ func ShouldNotContainKey(actual interface{}, expected ...interface{}) error {
//
// Example of testsuite file:
//
// name: Assertions testsuite
// testcases:
// - name: ShouldBeIn
// steps:
// - script: echo 1
// assertions:
// - result.systemoutjson ShouldBeIn 1 2
//
// name: Assertions testsuite
// testcases:
// - name: ShouldBeIn
// steps:
// - script: echo 1
// assertions:
// - result.systemoutjson ShouldBeIn 1 2
func ShouldBeIn(actual interface{}, expected ...interface{}) error {
if err := atLeast(1, expected); err != nil {
return err
Expand All @@ -657,14 +680,13 @@ func ShouldBeIn(actual interface{}, expected ...interface{}) error {
//
// Example of testsuite file:
//
// name: Assertions testsuite
// testcases:
// - name: ShouldNotBeIn
// steps:
// - script: echo 3
// assertions:
// - result.systemoutjson ShouldNotBeIn 1 2
//
// name: Assertions testsuite
// testcases:
// - name: ShouldNotBeIn
// steps:
// - script: echo 3
// assertions:
// - result.systemoutjson ShouldNotBeIn 1 2
func ShouldNotBeIn(actual interface{}, expected ...interface{}) error {
if err := atLeast(1, expected); err != nil {
return err
Expand Down Expand Up @@ -936,17 +958,17 @@ func ShouldEqualTrimSpace(actual interface{}, expected ...interface{}) error {
//
// Example of testsuite file:
//
// name: test ShouldHappenBefore
// vars:
// time: 2006-01-02T15:04:05+07:00
// time_with_5s_after: 2006-01-02T15:04:10+07:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenBefore "{{.time_with_5s_after}}"
// name: test ShouldHappenBefore
// vars:
// time: 2006-01-02T15:04:05+07:00
// time_with_5s_after: 2006-01-02T15:04:10+07:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenBefore "{{.time_with_5s_after}}"
func ShouldHappenBefore(actual interface{}, expected ...interface{}) error {
if err := need(1, expected); err != nil {
return err
Expand All @@ -973,17 +995,17 @@ func ShouldHappenBefore(actual interface{}, expected ...interface{}) error {
//
// Example of testsuite file:
//
// name: test ShouldHappenOnOrBefore
// vars:
// time: 2006-01-02T15:04:05+07:00
// time_with_5s_after: 2006-01-02T15:04:10+07:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenOnOrBefore "{{.time_with_5s_after}}"
// name: test ShouldHappenOnOrBefore
// vars:
// time: 2006-01-02T15:04:05+07:00
// time_with_5s_after: 2006-01-02T15:04:10+07:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenOnOrBefore "{{.time_with_5s_after}}"
func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) error {
if err := need(1, expected); err != nil {
return err
Expand All @@ -1009,17 +1031,17 @@ func ShouldHappenOnOrBefore(actual interface{}, expected ...interface{}) error {
//
// Example of testsuite file:
//
// name: test ShouldHappenAfter
// vars:
// time_with_5s_before: 2006-01-02T15:04:00+07:00
// time: 2006-01-02T15:04:05+07:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenAfter "{{.time_with_5s_before}}"
// name: test ShouldHappenAfter
// vars:
// time_with_5s_before: 2006-01-02T15:04:00+07:00
// time: 2006-01-02T15:04:05+07:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenAfter "{{.time_with_5s_before}}"
func ShouldHappenAfter(actual interface{}, expected ...interface{}) error {
if err := need(1, expected); err != nil {
return err
Expand All @@ -1045,17 +1067,17 @@ func ShouldHappenAfter(actual interface{}, expected ...interface{}) error {
//
// Example of testsuite file:
//
// name: test ShouldHappenOnOrAfter
// vars:
// time_with_5s_before: 2006-01-02T15:04:00+07:00
// time: 2006-01-02T15:04:05+07:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenOnOrAfter "{{.time_with_5s_before}}"
// name: test ShouldHappenOnOrAfter
// vars:
// time_with_5s_before: 2006-01-02T15:04:00+07:00
// time: 2006-01-02T15:04:05+07:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenOnOrAfter "{{.time_with_5s_before}}"
func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) error {
if err := need(1, expected); err != nil {
return err
Expand All @@ -1081,18 +1103,18 @@ func ShouldHappenOnOrAfter(actual interface{}, expected ...interface{}) error {
//
// Example of testsuite file:
//
// name: test ShouldHappenBetween
// vars:
// time_with_5s_before: 2006-01-02T15:04:00+07:00
// time: 2006-01-02T15:04:05+07:00
// time_with_5s_after: 2006-01-02T15:04:10+07:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenBetween "{{.time_with_5s_before}}" "{{.time_with_5s_after}}"
// name: test ShouldHappenBetween
// vars:
// time_with_5s_before: 2006-01-02T15:04:00+07:00
// time: 2006-01-02T15:04:05+07:00
// time_with_5s_after: 2006-01-02T15:04:10+07:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldHappenBetween "{{.time_with_5s_before}}" "{{.time_with_5s_after}}"
func ShouldHappenBetween(actual interface{}, expected ...interface{}) error {
if err := need(2, expected); err != nil {
return err
Expand Down Expand Up @@ -1122,17 +1144,17 @@ func ShouldHappenBetween(actual interface{}, expected ...interface{}) error {
//
// Example of testsuite file:
//
// name: test ShouldTimeEqual
// vars:
// time_expected: 2006-01-02T13:04:00Z
// time: 2006-01-02T15:04:00+02:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldTimeEqual "{{.time_expected}}"
// name: test ShouldTimeEqual
// vars:
// time_expected: 2006-01-02T13:04:00Z
// time: 2006-01-02T15:04:00+02:00
// testcases:
// - name: test assertion
// steps:
// - type: exec
// script: "echo {{.time}}"
// assertions:
// - result.systemout ShouldTimeEqual "{{.time_expected}}"
func ShouldTimeEqual(actual interface{}, expected ...interface{}) error {
if err := need(1, expected); err != nil {
return err
Expand Down
53 changes: 53 additions & 0 deletions assertions/assertions_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package assertions

import (
"fmt"
"github.com/stretchr/testify/assert"
"testing"
"time"
)
Expand Down Expand Up @@ -1405,3 +1407,54 @@ func TestShouldTimeEqual(t *testing.T) {
})
}
}

func TestShouldMatchRegex(t *testing.T) {
type args struct {
actual interface{}
expected []interface{}
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "with string",
args: args{
actual: `a`,
expected: []interface{}{`a`},
},
},
{
name: "with string regex",
args: args{
actual: `abc`,
expected: []interface{}{`a.*c$`},
},
},
{
name: "with number regex",
args: args{
actual: `abc-123`,
expected: []interface{}{`.*[0-9]{3}$`},
},
},
{
name: "with regex throwing error",
args: args{
actual: `abc-123`,
expected: []interface{}{`.*[0-9]{6}$`},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := ShouldMatchRegex(tt.args.actual, tt.args.expected...); (err != nil) != tt.wantErr {
msg := fmt.Sprintf("value %v not matching pattern : %v", tt.args.actual, tt.args.expected[0])
assert.ErrorContainsf(t, err, msg, "Contains message")
t.Errorf("ShouldMatchRegex() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
22 changes: 22 additions & 0 deletions tests/assertions/ShouldMatchRegex.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Assertions only tests suite

vars:
fiveARegex: "a{5}"
customVariable : '123456-abcd-end'

testcases:
- name: ShouldMatchRegex on global variable
steps:
- type: exec
script: |
echo "aaaaa"
assertions:
- result.systemout ShouldMatchRegex '{{.fiveARegex}}'
- script: echo '{{.customVariable}}'
assertion:
- result.systemout ShouldMatchRegex '^[0-9]{2,}-[a-z]{4}-end$'
- type: exec
script: |
echo "{\"key\":\"testing\"}"
assertions:
- result.systemoutjson.key ShouldMatchRegex [a-z]{6,}
15 changes: 15 additions & 0 deletions tests/failing/assertions_regex.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Assertions only tests suite

vars:
fiveARegex: "a{5}"

testcases:
- name: ShouldMatchRegex on global variable
steps:
- type: exec
script: |
echo "1234"
assertions:
- result.systemout ShouldMatchRegex '{{.fiveARegex}}'


0 comments on commit d21895e

Please sign in to comment.