Skip to content

Commit

Permalink
Merge pull request #66 from wklken/ft_contains_support_array
Browse files Browse the repository at this point in the history
  • Loading branch information
wklken committed Nov 2, 2023
2 parents 9306d95 + f6aa0af commit d8fcebf
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 17 deletions.
29 changes: 29 additions & 0 deletions docs/Usage/assert.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ nav_order: 4
---

# Assert

{: .no_toc }

Some examples show how to assert the response.
{: .fs-6 .fw-300 }


## Table of contents

{: .no_toc .text-delta }

1. TOC
Expand Down Expand Up @@ -75,6 +77,23 @@ assert:
protoMinor: 0
```

note: the `*contains` support a single string or a list of strings, if the value is a list, it's `AND` relationship.

```yaml
assert:
# body should both contains Hello and world
body_contains:
- Hello
- world
# body should not contains Hello and world
body_not_contains:
- Hello
- world
body_icontains:
- hello
- world
```

## assert header

```yaml
Expand Down Expand Up @@ -140,6 +159,16 @@ assert:
error_contains: context deadline exceeded
```

note: the `error_contains` support a single string or a list of strings, if the value is a list, it's `AND` relationship.

```yaml
assert:
# error should both contains Hello and world
error_contains:
- Hello
- world
```

## assert json

```yaml
Expand Down
36 changes: 36 additions & 0 deletions pkg/assert/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,39 @@ func NotEndsWith(s, suffix interface{}) (bool, string) {

return true, "OK"
}

// StringContainsAll string a should contains all elements
func StringContainsAll(s, elements interface{}) (bool, string) {
listValue := reflect.ValueOf(elements)
if reflect.TypeOf(elements).Kind() != reflect.Slice {
return false, fmt.Sprintf("contains_all | `%v` should be slice", prettyLine(elements))
}

for i := 0; i < listValue.Len(); i++ {
element := listValue.Index(i).Interface()
if !test(s, element, strings.Contains) {
// FIXME: add index in error info
return false, fmt.Sprintf("contains | `%v` should contains `%v`", prettyLine(s), element)
}
}

return true, "OK"
}

// StringContainsAll string a should not contains all elements
func StringNotContainsAll(s, elements interface{}) (bool, string) {
listValue := reflect.ValueOf(elements)
if reflect.TypeOf(elements).Kind() != reflect.Slice {
return false, fmt.Sprintf("contains_all | `%v` should be slice", prettyLine(elements))
}

for i := 0; i < listValue.Len(); i++ {
element := listValue.Index(i).Interface()
if test(s, element, strings.Contains) {
// FIXME: add index in error info
return false, fmt.Sprintf("contains | `%v` should not contains `%v`", prettyLine(s), element)
}
}

return true, "OK"
}
3 changes: 2 additions & 1 deletion pkg/assertion/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (

func DoErrorAssertions(c *config.Case, err error) (stats util.Stats) {
stats.AddInfofMessage("assert.error_contains: ")
ok, message := assert.Contains(err.Error(), c.Assert.ErrorContains)
// ok, message := assert.Contains(err.Error(), c.Assert.ErrorContains)
ok, message := assert.StringContainsAll(err.Error(), c.Assert.ErrorContains)
if ok {
stats.AddPassMessage()
stats.IncrOkAssertCount()
Expand Down
11 changes: 7 additions & 4 deletions pkg/assertion/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,25 +226,28 @@ func DoKeysAssertion(
{
key: "assert.body_contains",
ctx: Ctx{
f: assert.Contains,
// f: assert.Contains,
f: assert.StringContainsAll,
element1: bodyStr,
element2: c.Assert.BodyContains,
},
},
{
key: "assert.body_not_contains",
ctx: Ctx{
f: assert.NotContains,
// f: assert.NotContains,
f: assert.StringNotContainsAll,
element1: bodyStr,
element2: c.Assert.BodyNotContains,
},
},
{
key: "assert.body_icontains",
ctx: Ctx{
f: assert.Contains,
// f: assert.Contains,
f: assert.StringContainsAll,
element1: strings.ToLower(bodyStr),
element2: strings.ToLower(c.Assert.BodyIContains),
element2: util.StringArrayMapFunc(c.Assert.BodyIContains, strings.ToLower),
},
},
{
Expand Down
35 changes: 23 additions & 12 deletions pkg/config/assert.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ type Assert struct {

Body string `yaml:"body"`

BodyContains string `yaml:"body_contains" mapstructure:"body_contains"`
BodyNotContains string `yaml:"body_not_contains" mapstructure:"body_not_contains"`
BodyIContains string `yaml:"body_icontains" mapstructure:"body_icontains"`
BodyStartsWith string `yaml:"body_startswith" mapstructure:"body_startswith"`
BodyEndsWith string `yaml:"body_endswith" mapstructure:"body_endswith"`
BodyNotStartsWith string `yaml:"body_not_startswith" mapstructure:"body_not_startswith"`
BodyNotEndsWith string `yaml:"body_not_endswith" mapstructure:"body_not_endswith"`
BodyMatches string `yaml:"body_matches" mapstructure:"body_matches"`
BodyNotMatches string `yaml:"body_not_matches" mapstructure:"body_not_matches"`
BodyContains []string `yaml:"body_contains" mapstructure:"body_contains"`
BodyNotContains []string `yaml:"body_not_contains" mapstructure:"body_not_contains"`
BodyIContains []string `yaml:"body_icontains" mapstructure:"body_icontains"`
BodyStartsWith string `yaml:"body_startswith" mapstructure:"body_startswith"`
BodyEndsWith string `yaml:"body_endswith" mapstructure:"body_endswith"`
BodyNotStartsWith string `yaml:"body_not_startswith" mapstructure:"body_not_startswith"`
BodyNotEndsWith string `yaml:"body_not_endswith" mapstructure:"body_not_endswith"`
BodyMatches string `yaml:"body_matches" mapstructure:"body_matches"`
BodyNotMatches string `yaml:"body_not_matches" mapstructure:"body_not_matches"`

Header map[string]interface{} `yaml:"header"`
HeaderExists []string `yaml:"header_exists" mapstructure:"header_exists"`
Expand All @@ -65,7 +65,7 @@ type Assert struct {

// if request fail like dial fail/context deadline exceeded, will do assert error_contains only,
// will pass if the error message contains the string
ErrorContains string `yaml:"error_contains" mapstructure:"error_contains"`
ErrorContains []string `yaml:"error_contains" mapstructure:"error_contains"`

HasRedirect bool `yaml:"has_redirect" mapstructure:"has_redirect"`
RedirectCountLt int64 `yaml:"redirectCount_lt" mapstructure:"redirectCount_lt"`
Expand Down Expand Up @@ -115,8 +115,8 @@ func (a *Assert) Render(ctx map[string]interface{}) {

a.Body = tpl.Render(a.Body, ctx)

a.BodyContains = tpl.Render(a.BodyContains, ctx)
a.BodyNotContains = tpl.Render(a.BodyNotContains, ctx)
a.BodyContains = renderStringArray(a.BodyContains, ctx)
a.BodyNotContains = renderStringArray(a.BodyNotContains, ctx)
a.BodyStartsWith = tpl.Render(a.BodyStartsWith, ctx)
a.BodyEndsWith = tpl.Render(a.BodyEndsWith, ctx)
a.BodyNotStartsWith = tpl.Render(a.BodyNotStartsWith, ctx)
Expand All @@ -127,6 +127,17 @@ func (a *Assert) Render(ctx map[string]interface{}) {
}
}

func renderStringArray(elements []string, ctx map[string]interface{}) []string {
if len(elements) == 0 {
return elements
}
n := make([]string, 0, len(elements))
for _, s := range elements {
n = append(n, tpl.Render(s, ctx))
}
return n
}

type AssertJSON struct {
Path string
Value interface{}
Expand Down
7 changes: 7 additions & 0 deletions pkg/util/string.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,10 @@ func OmitMiddle(s string, head int, tail int) string {
func PrettyStringSlice(s []string) string {
return "[" + strings.Join(s, ", ") + "]"
}

func StringArrayMapFunc(elements []string, f func(string) string) (result []string) {
for _, element := range elements {
result = append(result, f(element))
}
return
}

0 comments on commit d8fcebf

Please sign in to comment.