Move filters outside query

This commit is contained in:
Fabrice Reix 2022-10-27 21:09:10 +02:00
parent 22c17ee998
commit 8666229edf
No known key found for this signature in database
GPG Key ID: BF5213154B2E7155
29 changed files with 222 additions and 226 deletions

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/predicate/error/type"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.status"},"predicate":{"type":"equal","value":"true"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":0}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"type":"equal","value":0}},{"query":{"type":"jsonpath","expr":"$.empty"},"predicate":{"type":"equal","value":0}},{"query":{"type":"jsonpath","expr":"$.number"},"predicate":{"type":"equal","value":1.1}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"type":"start-with","value":"hi"}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"type":"end-with","value":"hi"}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"type":"contain","value":"hi"}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"type":"match","value":"hi"}},{"query":{"type":"jsonpath","expr":"$.message","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":1}},{"query":{"type":"jsonpath","expr":"$.toto"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.list","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":2}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/predicate/error/type"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.status"},"predicate":{"type":"equal","value":"true"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":0}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"type":"equal","value":0}},{"query":{"type":"jsonpath","expr":"$.empty"},"predicate":{"type":"equal","value":0}},{"query":{"type":"jsonpath","expr":"$.number"},"predicate":{"type":"equal","value":1.1}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"type":"start-with","value":"hi"}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"type":"end-with","value":"hi"}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"type":"contain","value":"hi"}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"type":"match","value":"hi"}},{"query":{"type":"jsonpath","expr":"$.message"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":1}},{"query":{"type":"jsonpath","expr":"$.toto"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.message"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.list"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":2}}]}}]}

View File

@ -2,6 +2,6 @@ error: Invalid JSON
--> tests_failed/query_invalid_json.hurl:4:1
|
4 | jsonpath "$.errors" count == 2
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the HTTP response is not a valid JSON
| ^^^^^^^^^^^^^^^^^^^ the HTTP response is not a valid JSON
|

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/error-query-invalid-json"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.errors","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":2}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/error-query-invalid-json"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.errors"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":2}}]}}]}

View File

@ -2,6 +2,6 @@ error: Invalid decoding
--> tests_failed/query_invalid_utf8.hurl:4:1
|
4 | jsonpath "$.errors" count == 2
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the body can not be decoded with charset 'utf-8'
| ^^^^^^^^^^^^^^^^^^^ the body can not be decoded with charset 'utf-8'
|

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/error-query-invalid-utf8"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.errors","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":2}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/error-query-invalid-utf8"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.errors"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":2}}]}}]}

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-header"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Content-Type","value":"text/html; charset=utf-8"},{"name":"Set-Cookie","value":"cookie1=value1; Path=/"},{"name":"Set-Cookie","value":"cookie2=value2; Path=/"}],"asserts":[{"query":{"type":"header","name":"Custom"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"header","name":"Content-Type"},"predicate":{"type":"exist"}},{"query":{"type":"header","name":"Header1"},"predicate":{"type":"equal","value":"value1"}},{"query":{"type":"header","name":"ETag"},"predicate":{"type":"equal","value":"\"33a64df551425fcc55e4d42a148795d9f25f89d4\""}},{"query":{"type":"header","name":"Set-Cookie"},"predicate":{"type":"exist"}},{"query":{"type":"header","name":"Set-Cookie","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":3}},{"query":{"type":"header","name":"Set-Cookie"},"predicate":{"type":"include","value":"cookie1=value1; Path=/"}},{"query":{"type":"header","name":"Set-Cookie"},"predicate":{"not":true,"type":"include","value":"cookie4=value4; Path=/"}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-header"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Content-Type","value":"text/html; charset=utf-8"},{"name":"Set-Cookie","value":"cookie1=value1; Path=/"},{"name":"Set-Cookie","value":"cookie2=value2; Path=/"}],"asserts":[{"query":{"type":"header","name":"Custom"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"header","name":"Content-Type"},"predicate":{"type":"exist"}},{"query":{"type":"header","name":"Header1"},"predicate":{"type":"equal","value":"value1"}},{"query":{"type":"header","name":"ETag"},"predicate":{"type":"equal","value":"\"33a64df551425fcc55e4d42a148795d9f25f89d4\""}},{"query":{"type":"header","name":"Set-Cookie"},"predicate":{"type":"exist"}},{"query":{"type":"header","name":"Set-Cookie"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":3}},{"query":{"type":"header","name":"Set-Cookie"},"predicate":{"type":"include","value":"cookie1=value1; Path=/"}},{"query":{"type":"header","name":"Set-Cookie"},"predicate":{"not":true,"type":"include","value":"cookie4=value4; Path=/"}}]}}]}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-xpath"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"xpath","expr":"normalize-space(//data)"},"predicate":{"type":"equal","value":"café"}},{"query":{"type":"xpath","expr":"normalize-space(//data)"},"predicate":{"type":"equal","value":"café"}},{"query":{"type":"xpath","expr":"normalize-space(//data)"},"predicate":{"type":"greater","value":"CAFÉ"}},{"query":{"type":"xpath","expr":"//toto"},"predicate":{"not":true,"type":"exist"}}],"body":{"type":"xml","value":"<data>café</data>"}}},{"request":{"method":"GET","url":"http://localhost:8000/assert-xpath-simple-namespaces"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"xpath","expr":"string(//bk:book/bk:title)"},"predicate":{"type":"equal","value":"Cheaper by the Dozen"}},{"query":{"type":"xpath","expr":"string(//*[name()='bk:book']/*[name()='bk:title'])"},"predicate":{"type":"equal","value":"Cheaper by the Dozen"}},{"query":{"type":"xpath","expr":"string(//*[local-name()='book']/*[local-name()='title'])"},"predicate":{"type":"equal","value":"Cheaper by the Dozen"}},{"query":{"type":"xpath","expr":"string(//bk:book/isbn:number)"},"predicate":{"type":"equal","value":"1568491379"}},{"query":{"type":"xpath","expr":"string(//*[name()='bk:book']/*[name()='isbn:number'])"},"predicate":{"type":"equal","value":"1568491379"}},{"query":{"type":"xpath","expr":"string(//*[local-name()='book']/*[local-name()='number'])"},"predicate":{"type":"equal","value":"1568491379"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-xpath-svg"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"xpath","expr":"//_:svg/_:g/_:circle","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":3}},{"query":{"type":"xpath","expr":"//*[local-name()='svg']/*[local-name()='g']/*[local-name()='circle']","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":3}},{"query":{"type":"xpath","expr":"//*[name()='svg']/*[name()='g']/*[name()='circle']","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":3}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-xpath-namespaces"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"xpath","expr":"string(//_:book/_:title)"},"predicate":{"type":"equal","value":"Cheaper by the Dozen"}},{"query":{"type":"xpath","expr":"string(//_:book/_:title)"},"predicate":{"type":"greater","value":"Cheaper"}},{"query":{"type":"xpath","expr":"string(//_:book/isbn:number)"},"predicate":{"type":"equal","value":"1568491379"}},{"query":{"type":"xpath","expr":"//*[name()='book']/*[name()='notes']","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":1}},{"query":{"type":"xpath","expr":"//*[local-name()='book']/*[local-name()='notes']","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":1}},{"query":{"type":"xpath","expr":"//_:book/_:notes/*[local-name()='p']","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":1}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-xpath"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"xpath","expr":"normalize-space(//data)"},"predicate":{"type":"equal","value":"café"}},{"query":{"type":"xpath","expr":"normalize-space(//data)"},"predicate":{"type":"equal","value":"café"}},{"query":{"type":"xpath","expr":"normalize-space(//data)"},"predicate":{"type":"greater","value":"CAFÉ"}},{"query":{"type":"xpath","expr":"//toto"},"predicate":{"not":true,"type":"exist"}}],"body":{"type":"xml","value":"<data>café</data>"}}},{"request":{"method":"GET","url":"http://localhost:8000/assert-xpath-simple-namespaces"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"xpath","expr":"string(//bk:book/bk:title)"},"predicate":{"type":"equal","value":"Cheaper by the Dozen"}},{"query":{"type":"xpath","expr":"string(//*[name()='bk:book']/*[name()='bk:title'])"},"predicate":{"type":"equal","value":"Cheaper by the Dozen"}},{"query":{"type":"xpath","expr":"string(//*[local-name()='book']/*[local-name()='title'])"},"predicate":{"type":"equal","value":"Cheaper by the Dozen"}},{"query":{"type":"xpath","expr":"string(//bk:book/isbn:number)"},"predicate":{"type":"equal","value":"1568491379"}},{"query":{"type":"xpath","expr":"string(//*[name()='bk:book']/*[name()='isbn:number'])"},"predicate":{"type":"equal","value":"1568491379"}},{"query":{"type":"xpath","expr":"string(//*[local-name()='book']/*[local-name()='number'])"},"predicate":{"type":"equal","value":"1568491379"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-xpath-svg"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"xpath","expr":"//_:svg/_:g/_:circle"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":3}},{"query":{"type":"xpath","expr":"//*[local-name()='svg']/*[local-name()='g']/*[local-name()='circle']"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":3}},{"query":{"type":"xpath","expr":"//*[name()='svg']/*[name()='g']/*[name()='circle']"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":3}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-xpath-namespaces"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"xpath","expr":"string(//_:book/_:title)"},"predicate":{"type":"equal","value":"Cheaper by the Dozen"}},{"query":{"type":"xpath","expr":"string(//_:book/_:title)"},"predicate":{"type":"greater","value":"Cheaper"}},{"query":{"type":"xpath","expr":"string(//_:book/isbn:number)"},"predicate":{"type":"equal","value":"1568491379"}},{"query":{"type":"xpath","expr":"//*[name()='book']/*[name()='notes']"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":1}},{"query":{"type":"xpath","expr":"//*[local-name()='book']/*[local-name()='notes']"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":1}},{"query":{"type":"xpath","expr":"//_:book/_:notes/*[local-name()='p']"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":1}}]}}]}

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/bytes"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Content-Type","value":"application/octet-stream"}],"asserts":[{"query":{"type":"bytes"},"predicate":{"type":"equal","value":"AQID","encoding":"base64"}},{"query":{"type":"bytes"},"predicate":{"type":"equal","value":"AQID","encoding":"base64"}},{"query":{"type":"bytes","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":3}},{"query":{"type":"bytes"},"predicate":{"type":"start-with","value":"AQ==","encoding":"base64"}},{"query":{"type":"bytes"},"predicate":{"type":"end-with","value":"Aw==","encoding":"base64"}},{"query":{"type":"bytes"},"predicate":{"type":"contain","value":"Ag==","encoding":"base64"}},{"query":{"type":"sha256"},"predicate":{"type":"equal","value":"A5BYxvLAy0ksUzsKTRTvd8wPeKvMztUofYShogEc+4E=","encoding":"base64"}},{"query":{"type":"md5"},"predicate":{"type":"equal","value":"Uonfc331cyb83SJZevsfrA==","encoding":"base64"}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/bytes"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Content-Type","value":"application/octet-stream"}],"asserts":[{"query":{"type":"bytes"},"predicate":{"type":"equal","value":"AQID","encoding":"base64"}},{"query":{"type":"bytes"},"predicate":{"type":"equal","value":"AQID","encoding":"base64"}},{"query":{"type":"bytes"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":3}},{"query":{"type":"bytes"},"predicate":{"type":"start-with","value":"AQ==","encoding":"base64"}},{"query":{"type":"bytes"},"predicate":{"type":"end-with","value":"Aw==","encoding":"base64"}},{"query":{"type":"bytes"},"predicate":{"type":"contain","value":"Ag==","encoding":"base64"}},{"query":{"type":"sha256"},"predicate":{"type":"equal","value":"A5BYxvLAy0ksUzsKTRTvd8wPeKvMztUofYShogEc+4E=","encoding":"base64"}},{"query":{"type":"md5"},"predicate":{"type":"equal","value":"Uonfc331cyb83SJZevsfrA==","encoding":"base64"}}]}}]}

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/captures"},"response":{"version":"HTTP/1.0","status":200,"captures":[{"name":"param1","query":{"type":"header","name":"header1"}},{"name":"param2","query":{"type":"header","name":"header2","filters":[{"type":"regex","expr":"Hello (.*)!"}]}},{"name":"param3","query":{"type":"header","name":"header2","filters":[{"type":"regex","expr":{"type":"regex","value":"Hello (.*)!"}}]}}],"asserts":[{"query":{"type":"variable","name":"param1"},"predicate":{"type":"equal","value":"value1"}},{"query":{"type":"variable","name":"param2"},"predicate":{"type":"equal","value":"Bob"}},{"query":{"type":"variable","name":"param3"},"predicate":{"type":"equal","value":"Bob"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/captures-check","query_string_params":[{"name":"param1","value":"{{param1}}"},{"name":"param2","value":"{{param2}}"}]},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/captures-json"},"response":{"version":"HTTP/1.0","status":200,"captures":[{"name":"an_object","query":{"type":"jsonpath","expr":"$['an_object']"}},{"name":"a_list","query":{"type":"jsonpath","expr":"$['a_list']"}},{"name":"a_null","query":{"type":"jsonpath","expr":"$['a_null']"}},{"name":"an_integer","query":{"type":"jsonpath","expr":"$['an_integer']"}},{"name":"a_float","query":{"type":"jsonpath","expr":"$['a_float']"}},{"name":"a_bool","query":{"type":"jsonpath","expr":"$['a_bool']"}},{"name":"a_string","query":{"type":"jsonpath","expr":"$['a_string']"}},{"name":"all","query":{"type":"jsonpath","expr":"$"}}],"asserts":[{"query":{"type":"variable","name":"a_null"},"predicate":{"type":"exist"}},{"query":{"type":"variable","name":"undefined"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"variable","name":"a_null"},"predicate":{"type":"equal","value":"a_null"}},{"query":{"type":"variable","name":"an_integer"},"predicate":{"type":"equal","value":"an_integer"}},{"query":{"type":"variable","name":"a_float"},"predicate":{"type":"equal","value":"a_float"}},{"query":{"type":"variable","name":"a_bool"},"predicate":{"type":"equal","value":"a_bool"}},{"query":{"type":"variable","name":"a_string"},"predicate":{"type":"equal","value":"a_string"}},{"query":{"type":"variable","name":"a_string"},"predicate":{"type":"equal","value":"{{a_string}}"}},{"query":{"type":"variable","name":"a_list"},"predicate":{"type":"equal","value":"a_list"}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/captures"},"response":{"version":"HTTP/1.0","status":200,"captures":[{"name":"param1","query":{"type":"header","name":"header1"}},{"name":"param2","query":{"type":"header","name":"header2"},"filters":[{"type":"regex","expr":"Hello (.*)!"}]},{"name":"param3","query":{"type":"header","name":"header2"},"filters":[{"type":"regex","expr":{"type":"regex","value":"Hello (.*)!"}}]}],"asserts":[{"query":{"type":"variable","name":"param1"},"predicate":{"type":"equal","value":"value1"}},{"query":{"type":"variable","name":"param2"},"predicate":{"type":"equal","value":"Bob"}},{"query":{"type":"variable","name":"param3"},"predicate":{"type":"equal","value":"Bob"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/captures-check","query_string_params":[{"name":"param1","value":"{{param1}}"},{"name":"param2","value":"{{param2}}"}]},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/captures-json"},"response":{"version":"HTTP/1.0","status":200,"captures":[{"name":"an_object","query":{"type":"jsonpath","expr":"$['an_object']"}},{"name":"a_list","query":{"type":"jsonpath","expr":"$['a_list']"}},{"name":"a_null","query":{"type":"jsonpath","expr":"$['a_null']"}},{"name":"an_integer","query":{"type":"jsonpath","expr":"$['an_integer']"}},{"name":"a_float","query":{"type":"jsonpath","expr":"$['a_float']"}},{"name":"a_bool","query":{"type":"jsonpath","expr":"$['a_bool']"}},{"name":"a_string","query":{"type":"jsonpath","expr":"$['a_string']"}},{"name":"all","query":{"type":"jsonpath","expr":"$"}}],"asserts":[{"query":{"type":"variable","name":"a_null"},"predicate":{"type":"exist"}},{"query":{"type":"variable","name":"undefined"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"variable","name":"a_null"},"predicate":{"type":"equal","value":"a_null"}},{"query":{"type":"variable","name":"an_integer"},"predicate":{"type":"equal","value":"an_integer"}},{"query":{"type":"variable","name":"a_float"},"predicate":{"type":"equal","value":"a_float"}},{"query":{"type":"variable","name":"a_bool"},"predicate":{"type":"equal","value":"a_bool"}},{"query":{"type":"variable","name":"a_string"},"predicate":{"type":"equal","value":"a_string"}},{"query":{"type":"variable","name":"a_string"},"predicate":{"type":"equal","value":"{{a_string}}"}},{"query":{"type":"variable","name":"a_list"},"predicate":{"type":"equal","value":"a_list"}}]}}]}

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/cookies/set-request-cookie1-valueA","cookies":[{"name":"cookie1","value":"valueA"}]},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/assert-that-cookie1-is-not-in-session"},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/set-multiple-request-cookies","cookies":[{"name":"user1","value":"Bob"},{"name":"user2","value":"Bill"},{"name":"user3","value":"{{name}}"}]},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/set-session-cookie2-valueA"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"cookie","expr":"cookie2"},"predicate":{"type":"equal","value":"valueA"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/assert-that-cookie2-is-valueA"},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/assert-that-cookie2-is-valueA-and-valueB","cookies":[{"name":"cookie2","value":"valueB"}]},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/delete-cookie2"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"cookie","expr":"cookie2"},"predicate":{"type":"equal","value":""}},{"query":{"type":"cookie","expr":"cookie2[Max-Age]"},"predicate":{"type":"equal","value":0}}]}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/assert-that-cookie2-is-not-in-session"},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/set"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Set-Cookie","value":"LSID=DQAAAKEaem_vYg; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly; Path=/accounts"},{"name":"Set-Cookie","value":"HSID=AYQEVnDKrdst; Domain=.localhost; Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; Path=/"},{"name":"Set-Cookie","value":"SSID=Ap4PGTEq; Domain=.localhost; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly; Path=/"}],"asserts":[{"query":{"type":"header","name":"Set-Cookie","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":3}},{"query":{"type":"cookie","expr":"LSID"},"predicate":{"type":"equal","value":"DQAAAKEaem_vYg"}},{"query":{"type":"cookie","expr":"LSID[Value]"},"predicate":{"type":"equal","value":"DQAAAKEaem_vYg"}},{"query":{"type":"cookie","expr":"LSID[Expires]"},"predicate":{"type":"exist"}},{"query":{"type":"cookie","expr":"LSID[Expires]"},"predicate":{"type":"equal","value":"Wed, 13 Jan 2021 22:23:01 GMT"}},{"query":{"type":"cookie","expr":"LSID[Max-Age]"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"cookie","expr":"LSID[Domain]"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"cookie","expr":"LSID[Path]"},"predicate":{"type":"equal","value":"/accounts"}},{"query":{"type":"cookie","expr":"LSID[Secure]"},"predicate":{"type":"exist"}},{"query":{"type":"cookie","expr":"LSID[HttpOnly]"},"predicate":{"type":"exist"}},{"query":{"type":"cookie","expr":"LSID[SameSite]"},"predicate":{"not":true,"type":"exist"}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/cookies/set-request-cookie1-valueA","cookies":[{"name":"cookie1","value":"valueA"}]},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/assert-that-cookie1-is-not-in-session"},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/set-multiple-request-cookies","cookies":[{"name":"user1","value":"Bob"},{"name":"user2","value":"Bill"},{"name":"user3","value":"{{name}}"}]},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/set-session-cookie2-valueA"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"cookie","expr":"cookie2"},"predicate":{"type":"equal","value":"valueA"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/assert-that-cookie2-is-valueA"},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/assert-that-cookie2-is-valueA-and-valueB","cookies":[{"name":"cookie2","value":"valueB"}]},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/delete-cookie2"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"cookie","expr":"cookie2"},"predicate":{"type":"equal","value":""}},{"query":{"type":"cookie","expr":"cookie2[Max-Age]"},"predicate":{"type":"equal","value":0}}]}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/assert-that-cookie2-is-not-in-session"},"response":{"version":"HTTP/1.0","status":200}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/set"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Set-Cookie","value":"LSID=DQAAAKEaem_vYg; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly; Path=/accounts"},{"name":"Set-Cookie","value":"HSID=AYQEVnDKrdst; Domain=.localhost; Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; Path=/"},{"name":"Set-Cookie","value":"SSID=Ap4PGTEq; Domain=.localhost; Expires=Wed, 13 Jan 2021 22:23:01 GMT; Secure; HttpOnly; Path=/"}],"asserts":[{"query":{"type":"header","name":"Set-Cookie"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":3}},{"query":{"type":"cookie","expr":"LSID"},"predicate":{"type":"equal","value":"DQAAAKEaem_vYg"}},{"query":{"type":"cookie","expr":"LSID[Value]"},"predicate":{"type":"equal","value":"DQAAAKEaem_vYg"}},{"query":{"type":"cookie","expr":"LSID[Expires]"},"predicate":{"type":"exist"}},{"query":{"type":"cookie","expr":"LSID[Expires]"},"predicate":{"type":"equal","value":"Wed, 13 Jan 2021 22:23:01 GMT"}},{"query":{"type":"cookie","expr":"LSID[Max-Age]"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"cookie","expr":"LSID[Domain]"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"cookie","expr":"LSID[Path]"},"predicate":{"type":"equal","value":"/accounts"}},{"query":{"type":"cookie","expr":"LSID[Secure]"},"predicate":{"type":"exist"}},{"query":{"type":"cookie","expr":"LSID[HttpOnly]"},"predicate":{"type":"exist"}},{"query":{"type":"cookie","expr":"LSID[SameSite]"},"predicate":{"not":true,"type":"exist"}}]}}]}

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"HEAD","url":"http://localhost:8000/head"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Content-Type","value":"text/html; charset=utf-8"},{"name":"Content-Length","value":"10"},{"name":"Server","value":"Flask Server"}],"asserts":[{"query":{"type":"bytes","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":0}}]}}]}
{"entries":[{"request":{"method":"HEAD","url":"http://localhost:8000/head"},"response":{"version":"HTTP/1.0","status":200,"headers":[{"name":"Content-Type","value":"text/html; charset=utf-8"},{"name":"Content-Length","value":"10"},{"name":"Server","value":"Flask Server"}],"asserts":[{"query":{"type":"bytes"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":0}}]}}]}

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"type":"raw-string","value":"Hello World!"}}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/set-session-cookie2-valueA"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"cookie","expr":"cookie2"},"predicate":{"type":"equal","value":"valueA"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect"},"response":{"version":"HTTP/1.0","status":302,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"type":"equal","value":"http://localhost:8000/following-redirect"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"not":true,"type":"exist"}}],"body":{"type":"raw-string","value":"Followed redirect!"}}},{"request":{"method":"GET","url":"http://localhost:8000/captures"},"response":{"version":"HTTP/1.0","status":200,"captures":[{"name":"param1","query":{"type":"header","name":"header1"}},{"name":"param2","query":{"type":"header","name":"header2","filters":[{"type":"regex","expr":"Hello (.*)!"}]}},{"name":"param3","query":{"type":"header","name":"header2","filters":[{"type":"regex","expr":{"type":"regex","value":"Hello (.*)!"}}]}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.errors[1].id"},"predicate":{"type":"equal","value":"error2"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"type":"include","value":"test"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"not":true,"type":"include","value":"prod"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"not":true,"type":"include","value":null}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/hello"},"response":{"version":"HTTP/1.0","status":200,"body":{"type":"raw-string","value":"Hello World!"}}},{"request":{"method":"GET","url":"http://localhost:8000/cookies/set-session-cookie2-valueA"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"cookie","expr":"cookie2"},"predicate":{"type":"equal","value":"valueA"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect"},"response":{"version":"HTTP/1.0","status":302,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"type":"equal","value":"http://localhost:8000/following-redirect"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/follow-redirect"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"header","name":"Location"},"predicate":{"not":true,"type":"exist"}}],"body":{"type":"raw-string","value":"Followed redirect!"}}},{"request":{"method":"GET","url":"http://localhost:8000/captures"},"response":{"version":"HTTP/1.0","status":200,"captures":[{"name":"param1","query":{"type":"header","name":"header1"}},{"name":"param2","query":{"type":"header","name":"header2"},"filters":[{"type":"regex","expr":"Hello (.*)!"}]},{"name":"param3","query":{"type":"header","name":"header2"},"filters":[{"type":"regex","expr":{"type":"regex","value":"Hello (.*)!"}}]}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.errors[1].id"},"predicate":{"type":"equal","value":"error2"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"type":"include","value":"test"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"not":true,"type":"include","value":"prod"}},{"query":{"type":"jsonpath","expr":"$.tags"},"predicate":{"not":true,"type":"include","value":null}}]}}]}

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/predicates-string"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"body"},"predicate":{"type":"equal","value":"Hello World!"}},{"query":{"type":"body"},"predicate":{"type":"start-with","value":"Hello"}},{"query":{"type":"body"},"predicate":{"type":"end-with","value":"!"}},{"query":{"type":"body"},"predicate":{"type":"contain","value":"llo"}},{"query":{"type":"body"},"predicate":{"type":"match","value":"Hello [a-zA-Z]+!"}},{"query":{"type":"body"},"predicate":{"type":"match","value":"Hello [a-zA-Z]+!","encoding":"regex"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/predicates-string-empty"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"body"},"predicate":{"type":"equal","value":""}},{"query":{"type":"body"},"predicate":{"type":"exist"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/predicates-string-unicode"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"body"},"predicate":{"type":"equal","value":"✈"}},{"query":{"type":"bytes","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":3}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/predicates-string"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"body"},"predicate":{"type":"equal","value":"Hello World!"}},{"query":{"type":"body"},"predicate":{"type":"start-with","value":"Hello"}},{"query":{"type":"body"},"predicate":{"type":"end-with","value":"!"}},{"query":{"type":"body"},"predicate":{"type":"contain","value":"llo"}},{"query":{"type":"body"},"predicate":{"type":"match","value":"Hello [a-zA-Z]+!"}},{"query":{"type":"body"},"predicate":{"type":"match","value":"Hello [a-zA-Z]+!","encoding":"regex"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/predicates-string-empty"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"body"},"predicate":{"type":"equal","value":""}},{"query":{"type":"body"},"predicate":{"type":"exist"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/predicates-string-unicode"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"body"},"predicate":{"type":"equal","value":"✈"}},{"query":{"type":"bytes"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":3}}]}}]}

View File

@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/subquery-count"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.users","filters":[{"type":"count"}]},"predicate":{"type":"equal","value":3}},{"query":{"type":"jsonpath","expr":"$.users","filters":[{"type":"count"}]},"predicate":{"type":"greater","value":1}},{"query":{"type":"jsonpath","expr":"$.users","filters":[{"type":"count"}]},"predicate":{"type":"less-or-equal","value":10}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/subquery-count"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.users"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":3}},{"query":{"type":"jsonpath","expr":"$.users"},"filters":[{"type":"count"}],"predicate":{"type":"greater","value":1}},{"query":{"type":"jsonpath","expr":"$.users"},"filters":[{"type":"count"}],"predicate":{"type":"less-or-equal","value":10}}]}}]}

View File

@ -19,6 +19,7 @@
use std::collections::HashMap;
use crate::http;
use crate::runner::filter::eval_filters;
use hurl_core::ast::*;
use super::core::*;
@ -130,7 +131,35 @@ pub fn eval_assert(
variables: &HashMap<String, Value>,
http_response: &http::Response,
) -> AssertResult {
let actual = eval_query(&assert.query, variables, http_response);
let query_result = eval_query(&assert.query, variables, http_response);
let actual = if assert.filters.is_empty() {
query_result
} else if let Ok(optional_value) = query_result {
match optional_value {
None => Err(Error {
source_info: assert
.filters
.first()
.expect("at least one filter")
.1
.source_info
.clone(),
inner: RunnerError::FilterMissingInput {},
assert: true,
}),
Some(value) => {
let filters = assert.filters.iter().map(|(_, f)| f.clone()).collect();
match eval_filters(&filters, &value, variables) {
Ok(value) => Ok(Some(value)),
Err(e) => Err(e),
}
}
}
} else {
query_result
};
let source_info = &assert.predicate.predicate_func.source_info;
let predicate_result = match &actual {
Err(_) => None,
@ -172,6 +201,7 @@ pub mod tests {
line_terminators: vec![],
space0: whitespace.clone(),
query: query::tests::xpath_users(),
filters: vec![],
space1: whitespace.clone(),
predicate,
line_terminator0: LineTerminator {

View File

@ -19,6 +19,7 @@
use std::collections::HashMap;
use crate::http;
use crate::runner::filter::eval_filters;
use hurl_core::ast::*;
use super::core::RunnerError;
@ -43,7 +44,10 @@ pub fn eval_capture(
assert: false,
});
}
Some(value) => value,
Some(value) => {
let filters = capture.filters.iter().map(|(_, f)| f.clone()).collect();
eval_filters(&filters, &value, variables)?
}
};
Ok(CaptureResult {
name: name.clone(),
@ -79,6 +83,7 @@ pub mod tests {
// xpath count(//user)
query: query::tests::xpath_count_user_query(),
filters: vec![],
line_terminator0: LineTerminator {
space0: whitespace.clone(),
comment: None,
@ -107,6 +112,7 @@ pub mod tests {
// xpath count(//user)
query: query::tests::jsonpath_duration(),
filters: vec![],
line_terminator0: LineTerminator {
space0: whitespace.clone(),
comment: None,
@ -131,6 +137,7 @@ pub mod tests {
encoded: "count".to_string(),
source_info: SourceInfo::new(0, 0, 0, 0),
},
filters: vec![],
space1: whitespace.clone(),
space2: whitespace.clone(),
@ -182,9 +189,8 @@ pub mod tests {
source_info: SourceInfo::new(1, 7, 1, 13),
},
},
filters: vec![],
},
filters: vec![],
line_terminator0: LineTerminator {
space0: whitespace.clone(),
comment: None,

View File

@ -208,6 +208,7 @@ pub enum RunnerError {
// Filter
FilterMissingInput {},
FilterInvalidInput(String),
FilterRegexNoCapture {},
}
// endregion

View File

@ -65,6 +65,7 @@ impl Error for runner::Error {
RunnerError::UnauthorizedFileAccess { .. } => "Unauthorized file access".to_string(),
RunnerError::FilterMissingInput { .. } => "Filter Error".to_string(),
RunnerError::FilterInvalidInput { .. } => "Filter Error".to_string(),
RunnerError::FilterRegexNoCapture { .. } => "Filter Error".to_string(),
}
}
@ -163,6 +164,7 @@ impl Error for runner::Error {
RunnerError::FilterInvalidInput(message) => {
format!("Invalid Filter Input <{}>", message)
}
RunnerError::FilterRegexNoCapture { .. } => "Capture not found".to_string(),
}
}
}

View File

@ -21,11 +21,23 @@ use hurl_core::ast::{Filter, FilterValue, RegexValue, SourceInfo};
use regex::Regex;
use std::collections::HashMap;
pub fn eval_filter(
pub fn eval_filters(
filters: &Vec<Filter>,
value: &Value,
variables: &HashMap<String, Value>,
) -> Result<Value, Error> {
let mut value = value.clone();
for filter in filters {
value = eval_filter(filter, &value, variables)?;
}
Ok(value)
}
fn eval_filter(
filter: &Filter,
value: &Value,
variables: &HashMap<String, Value>,
) -> Result<Option<Value>, Error> {
) -> Result<Value, Error> {
match &filter.value {
FilterValue::Regex {
value: regex_value, ..
@ -41,7 +53,7 @@ fn eval_regex(
regex_value: &RegexValue,
variables: &HashMap<String, Value>,
source_info: &SourceInfo,
) -> Result<Option<Value>, Error> {
) -> Result<Value, Error> {
let re = match regex_value {
RegexValue::Template(t) => {
let value = eval_template(t, variables)?;
@ -52,7 +64,7 @@ fn eval_regex(
source_info: t.source_info.clone(),
inner: RunnerError::InvalidRegex(),
assert: false,
})
});
}
}
}
@ -62,10 +74,18 @@ fn eval_regex(
match value {
Value::String(s) => match re.captures(s.as_str()) {
Some(captures) => match captures.get(1) {
Some(v) => Ok(Some(Value::String(v.as_str().to_string()))),
None => Ok(None),
Some(v) => Ok(Value::String(v.as_str().to_string())),
None => Err(Error {
source_info: source_info.clone(),
inner: RunnerError::FilterRegexNoCapture {},
assert: false,
}),
},
None => Ok(None),
None => Err(Error {
source_info: source_info.clone(),
inner: RunnerError::FilterRegexNoCapture {},
assert: false,
}),
},
v => Err(Error {
source_info: source_info.clone(),
@ -75,11 +95,11 @@ fn eval_regex(
}
}
fn eval_count(value: &Value, source_info: &SourceInfo) -> Result<Option<Value>, Error> {
fn eval_count(value: &Value, source_info: &SourceInfo) -> Result<Value, Error> {
match value {
Value::List(values) => Ok(Some(Value::Integer(values.len() as i64))),
Value::Bytes(values) => Ok(Some(Value::Integer(values.len() as i64))),
Value::Nodeset(size) => Ok(Some(Value::Integer(*size as i64))),
Value::List(values) => Ok(Value::Integer(values.len() as i64)),
Value::Bytes(values) => Ok(Value::Integer(values.len() as i64)),
Value::Nodeset(size) => Ok(Value::Integer(*size as i64)),
v => Err(Error {
source_info: source_info.clone(),
inner: RunnerError::FilterInvalidInput(v._type()),
@ -93,30 +113,51 @@ pub mod tests {
use super::*;
use hurl_core::ast::{FilterValue, SourceInfo, Template, TemplateElement, Whitespace};
#[test]
pub fn filter_count() {
// count
let filter = Filter {
pub fn filter_count() -> Filter {
Filter {
source_info: SourceInfo::new(1, 1, 1, 6),
value: FilterValue::Count {},
};
}
}
#[test]
pub fn test_filters() {
let variables = HashMap::new();
assert_eq!(
eval_filter(
&filter,
eval_filters(
&vec![filter_count()],
&Value::List(vec![
Value::Integer(1),
Value::Integer(2),
Value::Integer(2)
Value::Integer(2),
]),
&variables,
)
.unwrap(),
Some(Value::Integer(3))
Value::Integer(3)
);
}
#[test]
pub fn eval_filter_count() {
let variables = HashMap::new();
assert_eq!(
eval_filter(
&filter_count(),
&Value::List(vec![
Value::Integer(1),
Value::Integer(2),
Value::Integer(2),
]),
&variables,
)
.unwrap(),
Value::Integer(3)
);
let error = eval_filter(&filter, &Value::Bool(true), &variables)
let error = eval_filter(&filter_count(), &Value::Bool(true), &variables)
.err()
.unwrap();
assert_eq!(error.source_info, SourceInfo::new(1, 1, 1, 6));
@ -127,7 +168,7 @@ pub mod tests {
}
#[test]
fn test_filter_regex() {
fn eval_filter_regex() {
// regex "Hello (.*)!"
let variables = HashMap::new();
let whitespace = Whitespace {
@ -154,7 +195,6 @@ pub mod tests {
&Value::String("Hello Bob!".to_string()),
&variables,
)
.unwrap()
.unwrap(),
Value::String("Bob".to_string())
);
@ -170,7 +210,7 @@ pub mod tests {
}
#[test]
fn test_filter_invalid_regex() {
fn eval_filter_invalid_regex() {
let variables = HashMap::new();
let whitespace = Whitespace {
value: String::from(""),

View File

@ -25,7 +25,6 @@ use super::value::Value;
use super::xpath;
use crate::http;
use crate::jsonpath;
use crate::runner::filter::eval_filter;
use hurl_core::ast::*;
use sha2::Digest;
@ -35,25 +34,6 @@ pub fn eval_query(
query: &Query,
variables: &HashMap<String, Value>,
http_response: &http::Response,
) -> QueryResult {
let mut value = eval_query_value(query, variables, http_response)?;
for (_, filter) in &query.filters {
if let Some(existing_value) = value {
value = eval_filter(filter, &existing_value, variables)?;
} else {
return Err(Error {
source_info: filter.source_info.clone(),
inner: RunnerError::CouldNotResolveProxyName,
assert: false,
});
}
}
Ok(value)
}
pub fn eval_query_value(
query: &Query,
variables: &HashMap<String, Value>,
http_response: &http::Response,
) -> QueryResult {
match query.value.clone() {
QueryValue::Status {} => Ok(Some(Value::Integer(i64::from(http_response.status)))),
@ -354,7 +334,6 @@ pub mod tests {
source_info: SourceInfo::new(1, 7, 1, 10),
},
},
filters: vec![],
}
}
@ -376,7 +355,6 @@ pub mod tests {
source_info: SourceInfo::new(0, 0, 0, 0),
},
},
filters: vec![],
}
}
@ -398,7 +376,6 @@ pub mod tests {
source_info: SourceInfo::new(0, 0, 0, 0),
},
},
filters: vec![],
}
}
@ -443,7 +420,6 @@ pub mod tests {
source_info: SourceInfo::new(1, 10, 1, 19),
},
},
filters: vec![],
}
}
@ -466,39 +442,6 @@ pub mod tests {
source_info: SourceInfo::new(1, 10, 1, 18),
},
},
filters: vec![],
}
}
pub fn jsonpath_errors_count() -> Query {
// jsonpath "$.errors" count
Query {
source_info: SourceInfo::new(1, 1, 1, 19),
value: QueryValue::Jsonpath {
space0: Whitespace {
value: String::from(""),
source_info: SourceInfo::new(1, 9, 1, 10),
},
expr: Template {
elements: vec![TemplateElement::String {
value: String::from("$.errors"),
encoded: String::from("$.errors"),
}],
quotes: true,
// delimiter: "".to_string(),
source_info: SourceInfo::new(1, 10, 1, 18),
},
},
filters: vec![(
Whitespace {
value: "".to_string(),
source_info: SourceInfo::new(0, 0, 0, 0),
},
Filter {
source_info: SourceInfo::new(0, 0, 0, 0),
value: FilterValue::Count {},
},
)],
}
}
@ -521,7 +464,6 @@ pub mod tests {
source_info: SourceInfo::new(1, 10, 1, 18),
},
},
filters: vec![],
}
}
@ -543,7 +485,6 @@ pub mod tests {
source_info: SourceInfo::new(1, 7, 1, 26),
}),
},
filters: vec![],
}
}
@ -565,7 +506,6 @@ pub mod tests {
source_info: SourceInfo::new(1, 7, 1, 10),
}),
},
filters: vec![],
}
}
@ -577,7 +517,6 @@ pub mod tests {
&Query {
source_info: SourceInfo::new(0, 0, 0, 0),
value: QueryValue::Status {},
filters: vec![]
},
&variables,
&http::hello_http_response(),
@ -608,7 +547,6 @@ pub mod tests {
source_info: SourceInfo::new(2, 8, 2, 14),
},
},
filters: vec![],
};
// let error = query_header.eval(http::hello_http_response()).err().unwrap();
// assert_eq!(error.source_info.start, Pos { line: 1, column: 8 });
@ -639,7 +577,6 @@ pub mod tests {
source_info: SourceInfo::new(1, 8, 1, 16),
},
},
filters: vec![],
};
assert_eq!(
eval_query(&query_header, &variables, &http::hello_http_response())
@ -667,7 +604,7 @@ pub mod tests {
],
body: vec![],
duration: Default::default(),
url: "".to_string()
url: "".to_string(),
};
// cookie "LSID"
@ -687,7 +624,6 @@ pub mod tests {
attribute: None,
},
},
filters: vec![],
};
assert_eq!(
eval_query(&query, &variables, &response.clone())
@ -717,7 +653,6 @@ pub mod tests {
}),
},
},
filters: vec![],
};
assert_eq!(
eval_query(&query, &variables, &response.clone())
@ -747,7 +682,6 @@ pub mod tests {
}),
},
},
filters: vec![],
};
assert_eq!(
eval_query(&query, &variables, &response.clone())
@ -777,7 +711,6 @@ pub mod tests {
}),
},
},
filters: vec![],
};
assert_eq!(eval_query(&query, &variables, &response).unwrap(), None);
}
@ -868,7 +801,6 @@ pub mod tests {
&Query {
source_info: SourceInfo::new(0, 0, 0, 0),
value: QueryValue::Body {},
filters: vec![]
},
&variables,
&http::hello_http_response(),
@ -881,7 +813,6 @@ pub mod tests {
&Query {
source_info: SourceInfo::new(1, 1, 1, 2),
value: QueryValue::Body {},
filters: vec![],
},
&variables,
&http::bytes_http_response(),
@ -940,7 +871,6 @@ pub mod tests {
source_info: SourceInfo::new(1, 7, 1, 10),
},
},
filters: vec![],
};
let error = eval_query(&query, &variables, &http::xml_two_users_http_response())
.err()
@ -995,7 +925,6 @@ pub mod tests {
source_info: SourceInfo::new(0, 0, 0, 0),
},
},
filters: vec![],
}
}
@ -1006,7 +935,7 @@ pub mod tests {
eval_query(
&xpath_html_charset(),
&variables,
&http::html_http_response()
&http::html_http_response(),
)
.unwrap()
.unwrap(),
@ -1036,7 +965,6 @@ pub mod tests {
source_info: SourceInfo::new(1, 10, 1, 13),
},
},
filters: vec![],
};
let error = eval_query(&jsonpath_query, &variables, &json_http_response())
@ -1117,13 +1045,6 @@ pub mod tests {
)])
])
);
assert_eq!(
eval_query(&jsonpath_errors_count(), &variables, &json_http_response())
.unwrap()
.unwrap(),
Value::Integer(2)
);
}
#[test]
@ -1151,7 +1072,6 @@ pub mod tests {
&Query {
source_info: SourceInfo::new(0, 0, 0, 0),
value: QueryValue::Bytes {},
filters: vec![]
},
&variables,
&http::hello_http_response(),
@ -1170,7 +1090,6 @@ pub mod tests {
&Query {
source_info: SourceInfo::new(0, 0, 0, 0),
value: QueryValue::Sha256 {},
filters: vec![]
},
&variables,
&http::Response {
@ -1180,7 +1099,7 @@ pub mod tests {
body: vec![0xff],
duration: Default::default(),
url: "".to_string()
},
}
)
.unwrap()
.unwrap(),

View File

@ -284,6 +284,7 @@ pub struct Capture {
pub space1: Whitespace,
pub space2: Whitespace,
pub query: Query,
pub filters: Vec<(Whitespace, Filter)>,
pub line_terminator0: LineTerminator,
}
@ -292,6 +293,7 @@ pub struct Assert {
pub line_terminators: Vec<LineTerminator>,
pub space0: Whitespace,
pub query: Query,
pub filters: Vec<(Whitespace, Filter)>,
pub space1: Whitespace,
pub predicate: Predicate,
pub line_terminator0: LineTerminator,
@ -301,7 +303,6 @@ pub struct Assert {
pub struct Query {
pub source_info: SourceInfo,
pub value: QueryValue,
pub filters: Vec<(Whitespace, Filter)>,
}
#[derive(Clone, Debug, PartialEq, Eq)]

View File

@ -540,6 +540,10 @@ impl Htmlable for Capture {
buffer.push_str("<span>:</span>");
buffer.push_str(self.space2.to_html().as_str());
buffer.push_str(self.query.to_html().as_str());
for (space, filter) in self.clone().filters {
buffer.push_str(space.to_html().as_str());
buffer.push_str(filter.to_html().as_str());
}
buffer.push_str("</span>");
buffer.push_str(self.line_terminator0.to_html().as_str());
buffer
@ -548,12 +552,7 @@ impl Htmlable for Capture {
impl Htmlable for Query {
fn to_html(&self) -> String {
let mut buffer = self.value.clone().to_html();
for (space, filter) in self.clone().filters {
buffer.push_str(space.to_html().as_str());
buffer.push_str(filter.to_html().as_str());
}
buffer
self.value.clone().to_html()
}
}
@ -667,6 +666,10 @@ impl Htmlable for Assert {
buffer.push_str("<span class=\"line\">");
buffer.push_str(self.space0.to_html().as_str());
buffer.push_str(self.query.to_html().as_str());
for (space, filter) in self.clone().filters {
buffer.push_str(space.to_html().as_str());
buffer.push_str(filter.to_html().as_str());
}
buffer.push_str(self.space1.to_html().as_str());
buffer.push_str(self.predicate.to_html().as_str());
buffer.push_str("</span>");

View File

@ -15,12 +15,37 @@
* limitations under the License.
*
*/
use crate::ast::{Filter, FilterValue, SourceInfo};
use crate::ast::{Filter, FilterValue, SourceInfo, Whitespace};
use crate::parser::combinators::choice;
use crate::parser::primitives::{one_or_more_spaces, try_literal};
use crate::parser::primitives::{one_or_more_spaces, try_literal, zero_or_more_spaces};
use crate::parser::query::regex_value;
use crate::parser::{Error, ParseError, ParseResult, Reader};
pub fn filters(reader: &mut Reader) -> ParseResult<'static, Vec<(Whitespace, Filter)>> {
let mut filters = vec![];
loop {
let save = reader.state.clone();
let space = zero_or_more_spaces(reader)?;
if space.value.is_empty() {
break;
}
match filter(reader) {
Ok(f) => {
filters.push((space, f));
}
Err(e) => {
if e.recoverable {
reader.state = save;
break;
} else {
return Err(e);
}
}
}
}
Ok(filters)
}
pub fn filter(reader: &mut Reader) -> ParseResult<'static, Filter> {
let start = reader.state.pos.clone();
let value = choice(

View File

@ -16,7 +16,6 @@
*
*/
use crate::ast::*;
use crate::parser::filter::filter;
use crate::parser::{Error, ParseError};
use super::combinators::*;
@ -29,33 +28,10 @@ use super::ParseResult;
pub fn query(reader: &mut Reader) -> ParseResult<'static, Query> {
let start = reader.state.pos.clone();
let value = query_value(reader)?;
let mut filters = vec![];
loop {
let save = reader.state.clone();
let space = zero_or_more_spaces(reader)?;
if space.value.is_empty() {
break;
}
match filter(reader) {
Ok(f) => {
filters.push((space, f));
}
Err(e) => {
if e.recoverable {
reader.state = save;
break;
} else {
return Err(e);
}
}
}
}
let end = reader.state.pos.clone();
Ok(Query {
source_info: SourceInfo { start, end },
value,
filters,
})
}
@ -208,6 +184,7 @@ fn md5_query(reader: &mut Reader) -> ParseResult<'static, QueryValue> {
#[cfg(test)]
mod tests {
use super::*;
use crate::parser::filter::filters;
#[test]
fn test_query() {
@ -217,7 +194,6 @@ mod tests {
Query {
source_info: SourceInfo::new(1, 1, 1, 7),
value: QueryValue::Status {},
filters: vec![],
}
);
}
@ -230,7 +206,6 @@ mod tests {
Query {
source_info: SourceInfo::new(1, 1, 1, 7),
value: QueryValue::Status {},
filters: vec![],
}
);
}
@ -382,9 +357,13 @@ mod tests {
assert_eq!(
query(&mut reader).unwrap(),
Query {
source_info: SourceInfo::new(1, 1, 1, 17),
source_info: SourceInfo::new(1, 1, 1, 5),
value: QueryValue::Body {},
filters: vec![(
}
);
assert_eq!(
filters(&mut reader).unwrap(),
vec![(
Whitespace {
value: " ".to_string(),
source_info: SourceInfo::new(1, 5, 1, 6)
@ -393,8 +372,7 @@ mod tests {
source_info: SourceInfo::new(1, 6, 1, 17),
value: FilterValue::UnEscapeUrl {},
}
)],
}
)]
);
assert_eq!(reader.state.cursor, 16);
}

View File

@ -16,6 +16,7 @@
*
*/
use crate::ast::*;
use crate::parser::filter::filters;
use super::combinators::*;
use super::error::*;
@ -286,7 +287,7 @@ fn capture(reader: &mut Reader) -> ParseResult<'static, Capture> {
recover(|p1| literal(":", p1), reader)?;
let space2 = zero_or_more_spaces(reader)?;
let q = query(reader)?;
let filters = filters(reader)?;
let line_terminator0 = line_terminator(reader)?;
Ok(Capture {
line_terminators,
@ -295,6 +296,7 @@ fn capture(reader: &mut Reader) -> ParseResult<'static, Capture> {
space1,
space2,
query: q,
filters,
line_terminator0,
})
}
@ -303,6 +305,7 @@ fn assert(reader: &mut Reader) -> ParseResult<'static, Assert> {
let line_terminators = optional_line_terminators(reader)?;
let space0 = zero_or_more_spaces(reader)?;
let query0 = query(reader)?;
let filters = filters(reader)?;
let space1 = one_or_more_spaces(reader)?;
let predicate0 = predicate(reader)?;
@ -335,6 +338,7 @@ fn assert(reader: &mut Reader) -> ParseResult<'static, Assert> {
line_terminators,
space0,
query: query0,
filters,
space1,
predicate: predicate0,
line_terminator0,
@ -729,8 +733,8 @@ mod tests {
source_info: SourceInfo::new(2, 8, 2, 18),
},
},
filters: vec![],
},
filters: vec![],
space1: Whitespace {
value: String::from(" "),
source_info: SourceInfo::new(2, 18, 2, 19),
@ -1177,7 +1181,6 @@ mod tests {
source_info: SourceInfo::new(1, 13, 1, 23),
},
},
filters: vec![],
}
);
}
@ -1190,7 +1193,7 @@ mod tests {
assert_eq!(
capture0.query,
Query {
source_info: SourceInfo::new(1, 8, 1, 44),
source_info: SourceInfo::new(1, 8, 1, 25),
value: QueryValue::Header {
space0: Whitespace {
value: String::from(" "),
@ -1205,30 +1208,6 @@ mod tests {
source_info: SourceInfo::new(1, 15, 1, 25),
},
},
filters: vec![(
Whitespace {
value: " ".to_string(),
source_info: SourceInfo::new(1, 25, 1, 26),
},
Filter {
source_info: SourceInfo::new(1, 26, 1, 44),
value: FilterValue::Regex {
space0: Whitespace {
value: " ".to_string(),
source_info: SourceInfo::new(1, 31, 1, 32),
},
value: RegexValue::Template(Template {
quotes: true,
elements: vec![TemplateElement::String {
value: "token=(.*)".to_string(),
encoded: "token=(.*)".to_string(),
}],
source_info: SourceInfo::new(1, 32, 1, 44),
}),
},
}
)],
}
);
assert_eq!(reader.state.cursor, 43);
@ -1294,7 +1273,6 @@ mod tests {
source_info: SourceInfo::new(1, 8, 1, 18),
},
},
filters: vec![],
}
);
}

View File

@ -247,31 +247,33 @@ impl ToJson for Cookie {
impl ToJson for Capture {
fn to_json(&self) -> JValue {
let attributes = vec![
let mut attributes = vec![
("name".to_string(), JValue::String(self.name.value.clone())),
("query".to_string(), self.query.to_json()),
];
if !self.filters.is_empty() {
let filters = JValue::List(self.filters.iter().map(|(_, f)| f.to_json()).collect());
attributes.push(("filters".to_string(), filters));
}
JValue::Object(attributes)
}
}
impl ToJson for Assert {
fn to_json(&self) -> JValue {
let attributes = vec![
("query".to_string(), self.query.to_json()),
("predicate".to_string(), self.predicate.to_json()),
];
let mut attributes = vec![("query".to_string(), self.query.to_json())];
if !self.filters.is_empty() {
let filters = JValue::List(self.filters.iter().map(|(_, f)| f.to_json()).collect());
attributes.push(("filters".to_string(), filters));
}
attributes.push(("predicate".to_string(), self.predicate.to_json()));
JValue::Object(attributes)
}
}
impl ToJson for Query {
fn to_json(&self) -> JValue {
let mut attributes = query_value_attributes(&self.value);
if !self.filters.is_empty() {
let filters = JValue::List(self.filters.iter().map(|(_, f)| f.to_json()).collect());
attributes.push(("filters".to_string(), filters));
}
let attributes = query_value_attributes(&self.value);
JValue::Object(attributes)
}
}
@ -471,7 +473,7 @@ impl ToJson for RawString {
}
}
impl ToJson for hurl_core::ast::JsonValue {
impl ToJson for JsonValue {
fn to_json(&self) -> JValue {
match self {
JsonValue::Null {} => JValue::Null {},
@ -492,7 +494,7 @@ impl ToJson for hurl_core::ast::JsonValue {
}
}
impl ToJson for hurl_core::ast::JsonListElement {
impl ToJson for JsonListElement {
fn to_json(&self) -> JValue {
self.value.to_json()
}
@ -676,7 +678,6 @@ pub mod tests {
source_info: SourceInfo::new(0, 0, 0, 0),
},
},
filters: vec![],
}
}
@ -693,6 +694,7 @@ pub mod tests {
space1: whitespace(),
space2: whitespace(),
query: header_query(),
filters: vec![],
line_terminator0: line_terminator(),
}
}
@ -702,6 +704,7 @@ pub mod tests {
line_terminators: vec![],
space0: whitespace(),
query: header_query(),
filters: vec![],
space1: whitespace(),
predicate: equal_int_predicate(10),
line_terminator0: line_terminator(),

View File

@ -369,6 +369,10 @@ impl Tokenizable for Capture {
tokens.push(Token::Colon(String::from(":")));
tokens.append(&mut self.space2.tokenize());
tokens.append(&mut self.query.tokenize());
for (space, filter) in &self.filters {
tokens.append(&mut space.clone().tokenize());
tokens.append(&mut filter.tokenize());
}
tokens.append(&mut self.line_terminator0.tokenize());
tokens
}
@ -386,6 +390,10 @@ impl Tokenizable for Assert {
);
tokens.append(&mut self.space0.tokenize());
tokens.append(&mut self.query.tokenize());
for (space, filter) in &self.filters {
tokens.append(&mut space.clone().tokenize());
tokens.append(&mut filter.tokenize());
}
tokens.append(&mut self.space1.tokenize());
// TODO reconvert back your first predicate for jsonpath
// so that you can use your firstX predicate for other query
@ -397,12 +405,7 @@ impl Tokenizable for Assert {
impl Tokenizable for Query {
fn tokenize(&self) -> Vec<Token> {
let mut tokens: Vec<Token> = self.value.clone().tokenize();
for (space, filter) in &self.filters {
tokens.append(&mut space.clone().tokenize());
tokens.append(&mut filter.tokenize());
}
tokens
self.value.clone().tokenize()
}
}

View File

@ -214,10 +214,16 @@ impl Lintable<Assert> for Assert {
}
fn lint(&self) -> Assert {
let filters = self
.filters
.iter()
.map(|(_, f)| (one_whitespace(), f.lint()))
.collect();
Assert {
line_terminators: self.line_terminators.clone(),
space0: empty_whitespace(),
query: self.query.lint(),
filters,
space1: one_whitespace(),
predicate: self.predicate.lint(),
line_terminator0: self.line_terminator0.clone(),
@ -232,6 +238,11 @@ impl Lintable<Capture> for Capture {
}
fn lint(&self) -> Capture {
let filters = self
.filters
.iter()
.map(|(_, f)| (one_whitespace(), f.lint()))
.collect();
Capture {
line_terminators: self.clone().line_terminators,
space0: empty_whitespace(),
@ -239,6 +250,7 @@ impl Lintable<Capture> for Capture {
space1: empty_whitespace(),
space2: one_whitespace(),
query: self.query.lint(),
filters,
line_terminator0: self.line_terminator0.lint(),
}
}
@ -254,11 +266,6 @@ impl Lintable<Query> for Query {
Query {
source_info: SourceInfo::new(0, 0, 0, 0),
value: self.value.lint(),
filters: self
.filters
.iter()
.map(|(_, f)| (one_whitespace(), f.lint()))
.collect(),
}
}
}