Skip to content

Commit 80ceae3

Browse files
authored
feat: add conditional verify support (#209)
1 parent 51bfd94 commit 80ceae3

12 files changed

+621
-394
lines changed

docs/api-testing-schema.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,36 @@
133133
"type": "string"
134134
}
135135
},
136+
"conditionalVerify": {
137+
"type": "array",
138+
"items": {
139+
"$ref": "#/definitions/ConditionalVerify"
140+
}
141+
},
136142
"schema": {
137143
"type": "string"
138144
}
139145
},
140146
"title": "Expect"
141147
},
148+
"ConditionalVerify": {
149+
"type": "object",
150+
"additionalProperties": false,
151+
"properties": {
152+
"condition": {
153+
"type": "array",
154+
"items": {
155+
"type": "string"
156+
}
157+
},
158+
"verify":{
159+
"type": "array",
160+
"items": {
161+
"type": "string"
162+
}
163+
}
164+
}
165+
},
142166
"Request": {
143167
"type": "object",
144168
"additionalProperties": false,

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.18
55
require (
66
github.com/Masterminds/sprig/v3 v3.2.3
77
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
8-
github.com/antonmedv/expr v1.14.0
8+
github.com/antonmedv/expr v1.15.0
99
github.com/bufbuild/protocompile v0.6.0
1010
github.com/cucumber/godog v0.12.6
1111
github.com/flopp/go-findfont v0.1.0

go.sum

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj
66
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
77
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
88
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
9-
github.com/antonmedv/expr v1.14.0 h1:C4BHw+0cVyKy/ndU3uqYo6TV5rCtq/SY2Wdlwanvo/Q=
10-
github.com/antonmedv/expr v1.14.0/go.mod h1:FPC8iWArxls7axbVLsW+kpg1mz29A1b2M6jt+hZfDkU=
9+
github.com/antonmedv/expr v1.15.0 h1:sBHNMx1i+b1lZfkBFGhicvSLW6RLnca3R0B7jWrk8iM=
10+
github.com/antonmedv/expr v1.15.0/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE=
1111
github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY=
1212
github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE=
1313
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -115,15 +115,13 @@ github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUq
115115
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
116116
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
117117
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
118-
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
119118
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
120119
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
121120
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
122121
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
123122
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
124123
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
125124
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
126-
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
127125
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
128126
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
129127
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=

pkg/runner/verify.go

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,49 @@ import (
3131

3232
// Verify if the data satisfies the expression.
3333
func Verify(expect testing.Response, data map[string]any) (err error) {
34-
for _, verify := range expect.Verify {
35-
var program *vm.Program
36-
if program, err = expr.Compile(verify, expr.Env(data),
37-
expr.AsBool(), kubernetes.PodValidatorFunc(),
38-
kubernetes.KubernetesValidatorFunc()); err != nil {
39-
return err
34+
for _, verifyExpr := range expect.Verify {
35+
var ok bool
36+
if ok, err = verify(verifyExpr, data); !ok {
37+
err = fmt.Errorf("failed to verify: %q, %v", verifyExpr, err)
38+
return
4039
}
40+
}
4141

42-
var result interface{}
43-
if result, err = expr.Run(program, data); err != nil {
44-
return err
42+
for _, verifyCon := range expect.ConditionalVerify {
43+
pass := true
44+
for _, con := range verifyCon.Condition {
45+
if ok, _ := verify(con, data); !ok {
46+
pass = false
47+
break
48+
}
4549
}
4650

47-
if !result.(bool) {
48-
err = fmt.Errorf("failed to verify: %s", verify)
49-
fmt.Println(err)
50-
break
51+
if pass {
52+
for _, verifyExpr := range verifyCon.Verify {
53+
var ok bool
54+
if ok, err = verify(verifyExpr, data); !ok {
55+
err = fmt.Errorf("failed to verify: %q, %v", verifyExpr, err)
56+
return
57+
}
58+
}
5159
}
5260
}
5361
return
5462
}
63+
64+
func verify(verify string, data map[string]any) (ok bool, err error) {
65+
var program *vm.Program
66+
if program, err = expr.Compile(verify, expr.Env(data),
67+
expr.AsBool(), kubernetes.PodValidatorFunc(),
68+
kubernetes.KubernetesValidatorFunc()); err != nil {
69+
return
70+
}
71+
72+
var result interface{}
73+
if result, err = expr.Run(program, data); err != nil {
74+
return
75+
}
76+
77+
ok = result.(bool)
78+
return
79+
}

pkg/runner/verify_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2023 API Testing Authors.
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
25+
package runner_test
26+
27+
import (
28+
"testing"
29+
30+
"github.com/linuxsuren/api-testing/pkg/runner"
31+
atest "github.com/linuxsuren/api-testing/pkg/testing"
32+
"github.com/stretchr/testify/assert"
33+
)
34+
35+
func TestVerify(t *testing.T) {
36+
t.Run("conditionalVerify", func(t *testing.T) {
37+
err := runner.Verify(atest.Response{
38+
ConditionalVerify: []atest.ConditionalVerify{{
39+
Condition: []string{
40+
"1 == 1",
41+
"2 == 2",
42+
},
43+
Verify: []string{"1 == 2"},
44+
}},
45+
}, nil)
46+
assert.Error(t, err)
47+
48+
err = runner.Verify(atest.Response{
49+
ConditionalVerify: []atest.ConditionalVerify{{
50+
Condition: []string{"1 != 1"},
51+
Verify: []string{"1 == 2"},
52+
}},
53+
}, nil)
54+
assert.NoError(t, err)
55+
})
56+
}

pkg/server/convert.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
MIT License
33
4-
Copyright (c) 2023 Rick
4+
Copyright (c) 2023 API Testing Authors.
55
66
Permission is hereby granted, free of charge, to any person obtaining a copy
77
of this software and associated documentation files (the "Software"), to deal

pkg/server/convert_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
MIT License
33
4-
Copyright (c) 2023 Rick
4+
Copyright (c) 2023 API Testing Authors.
55
66
Permission is hereby granted, free of charge, to any person obtaining a copy
77
of this software and associated documentation files (the "Software"), to deal

pkg/server/remote_server.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,12 +529,27 @@ func convertToTestingTestCase(in *TestCase) (result testing.TestCase) {
529529
result.Expect.Schema = resp.Schema
530530
result.Expect.StatusCode = int(resp.StatusCode)
531531
result.Expect.Verify = resp.Verify
532+
result.Expect.ConditionalVerify = convertConditionalVerify(resp.ConditionalVerify)
532533
result.Expect.BodyFieldsExpect = pairToInterMap(resp.BodyFieldsExpect)
533534
result.Expect.Header = pairToMap(resp.Header)
534535
}
535536
return
536537
}
537538

539+
func convertConditionalVerify(verify []*ConditionalVerify) (result []testing.ConditionalVerify) {
540+
if verify != nil {
541+
result = make([]testing.ConditionalVerify, 0)
542+
543+
for _, item := range verify {
544+
result = append(result, testing.ConditionalVerify{
545+
Condition: item.Condition,
546+
Verify: item.Verify,
547+
})
548+
}
549+
}
550+
return
551+
}
552+
538553
func (s *server) CreateTestCase(ctx context.Context, in *TestCaseWithSuite) (reply *HelloReply, err error) {
539554
reply = &HelloReply{}
540555
loader := s.getLoader(ctx)

pkg/server/remote_server_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
_ "embed"
3939

4040
"github.com/h2non/gock"
41+
atest "github.com/linuxsuren/api-testing/pkg/testing"
4142
atesting "github.com/linuxsuren/api-testing/pkg/testing"
4243
"github.com/linuxsuren/api-testing/sample"
4344
"github.com/stretchr/testify/assert"
@@ -428,6 +429,16 @@ func TestListTestCase(t *testing.T) {
428429
assert.NoError(t, err)
429430
assert.NotNil(t, reply)
430431
})
432+
433+
t.Run("convertConditionalVerify", func(t *testing.T) {
434+
assert.Equal(t, []atest.ConditionalVerify{{
435+
Condition: []string{"1 == 1"},
436+
Verify: []string{"1 == 1"},
437+
}}, convertConditionalVerify([]*ConditionalVerify{{
438+
Condition: []string{"1 == 1"},
439+
Verify: []string{"1 == 1"},
440+
}}))
441+
})
431442
}
432443

433444
func TestRemoteServerSuite(t *testing.T) {

0 commit comments

Comments
 (0)