From c0ebe2ee53a7b925b41e7a94ae77d26146842614 Mon Sep 17 00:00:00 2001 From: buyuxiang <347586493@qq.com> Date: Sun, 20 Feb 2022 13:43:28 +0800 Subject: [PATCH 1/3] fix: extract data using jmespath Change-Id: Icea3b8fa7e71dd610c19c91e21a259104ab2fe30 --- docs/CHANGELOG.md | 4 ++++ examples/demo.json | 24 +++++++++++++++++++++++- examples/demo.yaml | 14 ++++++++++++++ parser.go | 13 +++++++++++-- response.go | 12 +++++++++++- 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index e244f80c..dffc118b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,9 @@ # Release History +## v0.6.2 (2022-02-20) +- change: json unmarshal to json.Number when parsing data +- fix: incorrect data type when extracting data using jmespath + ## v0.6.1 (2022-02-17) - fix: set request Content-Type for posting json only when not specified diff --git a/examples/demo.json b/examples/demo.json index 198bcbaa..2213444a 100644 --- a/examples/demo.json +++ b/examples/demo.json @@ -119,9 +119,13 @@ }, "body": { "foo1": "$varFoo1", - "foo2": "${max($a, $b)}" + "foo2": "${max($a, $b)}", + "time": "${get_timestamp()}" } }, + "extract": { + "varTime": "body.form.time" + }, "validate": [ { "check": "status_code", @@ -142,6 +146,24 @@ "msg": "check args foo2" } ] + }, + { + "name": "final check", + "request": { + "method": "GET", + "url": "/get", + "params": { + "time": "$varTime" + } + }, + "validate": [ + { + "check": "body.args.time", + "assert": "length_equals", + "expect": 13, + "msg": "check extracted var timestamp" + } + ] } ] } \ No newline at end of file diff --git a/examples/demo.yaml b/examples/demo.yaml index ed6131dc..650c97c8 100644 --- a/examples/demo.yaml +++ b/examples/demo.yaml @@ -80,6 +80,9 @@ teststeps: body: foo1: $varFoo1 foo2: ${max($a, $b)} + time: ${get_timestamp()} + extract: + varTime: body.form.time validate: - check: status_code assert: equals @@ -93,3 +96,14 @@ teststeps: assert: equals expect: "12.3" msg: check args foo2 + - name: final check + request: + method: GET + url: /get + params: + time: $varTime + validate: + - check: body.args.time + assert: length_equals + expect: 13 + msg: check extracted var timestamp diff --git a/parser.go b/parser.go index 692faf75..ce2a8fe3 100644 --- a/parser.go +++ b/parser.go @@ -69,8 +69,7 @@ func (p *parser) parseData(raw interface{}, variablesMapping map[string]interfac case reflect.String: // json.Number if rawValue, ok := raw.(json.Number); ok { - // use the same rule as json.Unmarshal (float64, for JSON numbers) - return rawValue.Float64() + return parseJSONNumber(rawValue) } // other string value := rawValue.String() @@ -109,6 +108,16 @@ func (p *parser) parseData(raw interface{}, variablesMapping map[string]interfac } } +func parseJSONNumber(raw json.Number) (interface{}, error) { + if strings.Contains(raw.String(), ".") { + // float64 + return raw.Float64() + } else { + // int64 + return raw.Int64() + } +} + const ( regexVariable = `[a-zA-Z_]\w*` // variable name should start with a letter or underscore regexFunctionName = `[a-zA-Z_]\w*` // function name should start with a letter or underscore diff --git a/response.go b/response.go index 29619160..9fc5fbaa 100644 --- a/response.go +++ b/response.go @@ -1,6 +1,7 @@ package hrp import ( + "bytes" "encoding/json" "fmt" "io/ioutil" @@ -53,7 +54,9 @@ func newResponseObject(t *testing.T, parser *parser, resp *http.Response) (*resp // convert respObjMeta to interface{} respObjMetaBytes, _ := json.Marshal(respObjMeta) var data interface{} - if err := json.Unmarshal(respObjMetaBytes, &data); err != nil { + decoder := json.NewDecoder(bytes.NewReader(respObjMetaBytes)) + decoder.UseNumber() + if err := decoder.Decode(&data); err != nil { log.Error(). Str("respObjMeta", string(respObjMetaBytes)). Err(err). @@ -167,5 +170,12 @@ func (v *responseObject) searchJmespath(expr string) interface{} { log.Error().Str("expr", expr).Err(err).Msg("search jmespath failed") return expr // jmespath not found, return the expression } + if number, ok := checkValue.(json.Number); ok { + checkNumber, err := parseJSONNumber(number) + if err != nil { + log.Error().Interface("json number", number).Err(err).Msg("convert json number failed") + } + return checkNumber + } return checkValue } From 50c43842073c1807b10e3041d25549c567a05794 Mon Sep 17 00:00:00 2001 From: buyuxiang <347586493@qq.com> Date: Sun, 20 Feb 2022 13:56:03 +0800 Subject: [PATCH 2/3] regenerate examples/demo Change-Id: I02a6704c65f28ef73b16e1da437e2a05494182ca --- examples/demo.json | 4 ++-- examples/demo.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/demo.json b/examples/demo.json index 2213444a..4a084edc 100644 --- a/examples/demo.json +++ b/examples/demo.json @@ -148,7 +148,7 @@ ] }, { - "name": "final check", + "name": "get with timestamp", "request": { "method": "GET", "url": "/get", @@ -166,4 +166,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/examples/demo.yaml b/examples/demo.yaml index 650c97c8..ac157382 100644 --- a/examples/demo.yaml +++ b/examples/demo.yaml @@ -96,7 +96,7 @@ teststeps: assert: equals expect: "12.3" msg: check args foo2 - - name: final check + - name: get with timestamp request: method: GET url: /get From 2ba1d5829e2a74963f14fa1d1d193468196d5197 Mon Sep 17 00:00:00 2001 From: buyuxiang <347586493@qq.com> Date: Sun, 20 Feb 2022 14:00:27 +0800 Subject: [PATCH 3/3] add: test timestamp extraction Change-Id: I4aba2b7d387d8cb7b9c1baec997e59b1b594c34d --- internal/scaffold/demo.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/scaffold/demo.go b/internal/scaffold/demo.go index 7ea63b5a..19a62fac 100644 --- a/internal/scaffold/demo.go +++ b/internal/scaffold/demo.go @@ -48,11 +48,18 @@ var demoTestCase = &hrp.TestCase{ WithBody(map[string]interface{}{ "foo1": "$varFoo1", // reference former extracted variable "foo2": "${max($a, $b)}", // 12.3; step level variables are independent, variable b is 3.45 here + "time": "${get_timestamp()}", }). + Extract(). + WithJmesPath("body.form.time", "varTime"). Validate(). AssertEqual("status_code", 200, "check status code"). AssertLengthEqual("body.form.foo1", 5, "check args foo1"). AssertEqual("body.form.foo2", "12.3", "check args foo2"), // form data will be converted to string + hrp.NewStep("get with timestamp"). + GET("/get").WithParams(map[string]interface{}{"time": "$varTime"}). + Validate(). + AssertLengthEqual("body.args.time", 13, "check extracted var timestamp"), }, }