From 077807ef1cf719775211ca0492121425d6831f96 Mon Sep 17 00:00:00 2001 From: Rached Mejri Date: Fri, 10 Mar 2023 16:23:28 +0100 Subject: [PATCH] Implement isEmpty predicate Signed-off-by: Rached Mejri --- integration/tests_failed/assert_xpath.html | 1 + integration/tests_failed/assert_xpath.hurl | 1 + integration/tests_failed/assert_xpath.json | 2 +- integration/tests_ok/assert_json.html | 1 + integration/tests_ok/assert_json.hurl | 1 + integration/tests_ok/assert_json.json | 2 +- integration/tests_ok/bytes.py | 10 +++ integration/tests_ok/bytes_empty.html | 7 +++ integration/tests_ok/bytes_empty.hurl | 6 ++ integration/tests_ok/bytes_empty.json | 1 + packages/hurl/src/runner/predicate.rs | 73 ++++++++++++++++++++++ packages/hurl_core/src/ast/core.rs | 1 + packages/hurl_core/src/ast/display.rs | 1 + packages/hurl_core/src/format/html.rs | 5 ++ packages/hurl_core/src/parser/predicate.rs | 6 ++ packages/hurlfmt/src/format/json.rs | 3 + packages/hurlfmt/src/format/token.rs | 3 + packages/hurlfmt/src/linter/rules.rs | 1 + 18 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 integration/tests_ok/bytes_empty.html create mode 100644 integration/tests_ok/bytes_empty.hurl create mode 100644 integration/tests_ok/bytes_empty.json diff --git a/integration/tests_failed/assert_xpath.html b/integration/tests_failed/assert_xpath.html index a46bf3832de..450aec99d10 100644 --- a/integration/tests_failed/assert_xpath.html +++ b/integration/tests_failed/assert_xpath.html @@ -2,4 +2,5 @@ HTTP 200 [Asserts] xpath "strong(//head/title)" equals "Welcome to Quiz!" +xpath "strong(//head/title)" isEmpty diff --git a/integration/tests_failed/assert_xpath.hurl b/integration/tests_failed/assert_xpath.hurl index 123f807b631..89b22c9ad7e 100644 --- a/integration/tests_failed/assert_xpath.hurl +++ b/integration/tests_failed/assert_xpath.hurl @@ -2,3 +2,4 @@ GET http://localhost:8000/error-assert-xpath HTTP 200 [Asserts] xpath "strong(//head/title)" equals "Welcome to Quiz!" +xpath "strong(//head/title)" isEmpty diff --git a/integration/tests_failed/assert_xpath.json b/integration/tests_failed/assert_xpath.json index 8afacc09701..2a6513deedf 100644 --- a/integration/tests_failed/assert_xpath.json +++ b/integration/tests_failed/assert_xpath.json @@ -1 +1 @@ -{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/error-assert-xpath"},"response":{"status":200,"asserts":[{"query":{"type":"xpath","expr":"strong(//head/title)"},"predicate":{"type":"equal","value":"Welcome to Quiz!"}}]}}]} +{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/error-assert-xpath"},"response":{"status":200,"asserts":[{"query":{"type":"xpath","expr":"strong(//head/title)"},"predicate":{"type":"equal","value":"Welcome to Quiz!"}},{"query":{"type":"xpath","expr":"strong(//head/title)"},"predicate":{"type":"isEmpty"}}]}}]} diff --git a/integration/tests_ok/assert_json.html b/integration/tests_ok/assert_json.html index a8f3de14167..b3cc2e5a9d7 100644 --- a/integration/tests_ok/assert_json.html +++ b/integration/tests_ok/assert_json.html @@ -30,6 +30,7 @@ jsonpath "$.errors" count == 2 jsonpath "$.errors" isCollection jsonpath "$.warnings" count == 0 +jsonpath "$.warnings" isEmpty jsonpath "$.toto" not exists jsonpath "$.warnings" exists jsonpath "$.warnings" exists diff --git a/integration/tests_ok/assert_json.hurl b/integration/tests_ok/assert_json.hurl index 4fb8585e70a..b8fa4acf747 100644 --- a/integration/tests_ok/assert_json.hurl +++ b/integration/tests_ok/assert_json.hurl @@ -30,6 +30,7 @@ jsonpath "$.success" isBoolean jsonpath "$.errors" count == 2 jsonpath "$.errors" isCollection jsonpath "$.warnings" count == 0 +jsonpath "$.warnings" isEmpty jsonpath "$.toto" not exists jsonpath "$.warnings" exists jsonpath "$.warnings" exists diff --git a/integration/tests_ok/assert_json.json b/integration/tests_ok/assert_json.json index 35531c71f80..73ec5e32fc6 100644 --- a/integration/tests_ok/assert_json.json +++ b/integration/tests_ok/assert_json.json @@ -1 +1 @@ -{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"status":200,"captures":[{"name":"count","query":{"type":"jsonpath","expr":"$.count"}}],"asserts":[{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5.0}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":"five"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"not-equal","value":4}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"not-equal","value":"four"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"not":true,"type":"equal","value":4}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":1}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":"one"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":1.0}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":1.0}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"equal","value":false}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"not-equal","value":null}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"isBoolean"}},{"query":{"type":"jsonpath","expr":"$.errors"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":2}},{"query":{"type":"jsonpath","expr":"$.errors"},"predicate":{"type":"isCollection"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":0}},{"query":{"type":"jsonpath","expr":"$.toto"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.errors[0]"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.errors[0]"},"predicate":{"type":"isCollection"}},{"query":{"type":"jsonpath","expr":"$.errors[0].id"},"predicate":{"type":"equal","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.errors[0]['id']"},"predicate":{"type":"equal","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.errors[*].id"},"predicate":{"type":"include","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.errors[?(@.id=='error1')].id"},"predicate":{"type":"equal","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"equal","value":1.5}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less-or-equal","value":2.0}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less","value":2}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less","value":"two"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less-or-equal","value":2.0}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less","value":2}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"isFloat"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"not":true,"type":"isInteger"}},{"query":{"type":"jsonpath","expr":"$.nullable"},"predicate":{"type":"equal","value":null}},{"query":{"type":"jsonpath","expr":"$.tags[0]"},"predicate":{"type":"equal","value":"test"}},{"query":{"type":"jsonpath","expr":"$.tags[0]"},"predicate":{"type":"greater","value":"te"}},{"query":{"type":"jsonpath","expr":"$.tags[0]"},"predicate":{"type":"less","value":"testabc"}},{"query":{"type":"jsonpath","expr":"$.tags[0]"},"predicate":{"type":"less-or-equal","value":"test"}},{"query":{"type":"jsonpath","expr":"$.tags[0]"},"predicate":{"type":"greater","value":"{{foo}}"}},{"query":{"type":"jsonpath","expr":"$.profile-id"},"predicate":{"type":"equal","value":"123abc"}},{"query":{"type":"jsonpath","expr":"$['profile-id']"},"predicate":{"type":"equal","value":"123abc"}}],"body":{"type":"json","value":{"count":5,"success":false,"errors":[{"id":"error1"},{"id":"error2"}],"warnings":[],"duration":1.5,"tags":["test"],"nullable":null,"profile-id":"123abc"}}}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/index"},"response":{"status":200,"captures":[{"name":"index","query":{"type":"body"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.errors[{{index}}].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}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/list"},"response":{"status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":2}},{"query":{"type":"jsonpath","expr":"$.[0].name"},"predicate":{"type":"equal","value":"Bob"}},{"query":{"type":"jsonpath","expr":"$[0].name"},"predicate":{"type":"equal","value":"Bob"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/filter"},"response":{"status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.fruit[?(@.price.US==200)].name"},"predicate":{"type":"equal","value":"grape"}}]}}]} +{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"status":200,"captures":[{"name":"count","query":{"type":"jsonpath","expr":"$.count"}}],"asserts":[{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5.0}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":"five"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"equal","value":5}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"not-equal","value":4}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"not-equal","value":"four"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"not":true,"type":"equal","value":4}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":1}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":"one"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":1.0}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater","value":1.0}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"equal","value":false}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"not-equal","value":null}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"isBoolean"}},{"query":{"type":"jsonpath","expr":"$.errors"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":2}},{"query":{"type":"jsonpath","expr":"$.errors"},"predicate":{"type":"isCollection"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":0}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"isEmpty"}},{"query":{"type":"jsonpath","expr":"$.toto"},"predicate":{"not":true,"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.errors[0]"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.errors[0]"},"predicate":{"type":"isCollection"}},{"query":{"type":"jsonpath","expr":"$.errors[0].id"},"predicate":{"type":"equal","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.errors[0]['id']"},"predicate":{"type":"equal","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.errors[*].id"},"predicate":{"type":"include","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.errors[?(@.id=='error1')].id"},"predicate":{"type":"equal","value":"error1"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"equal","value":1.5}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less-or-equal","value":2.0}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less","value":2}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less","value":"two"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less-or-equal","value":2.0}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less","value":2}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"isFloat"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"not":true,"type":"isInteger"}},{"query":{"type":"jsonpath","expr":"$.nullable"},"predicate":{"type":"equal","value":null}},{"query":{"type":"jsonpath","expr":"$.tags[0]"},"predicate":{"type":"equal","value":"test"}},{"query":{"type":"jsonpath","expr":"$.tags[0]"},"predicate":{"type":"greater","value":"te"}},{"query":{"type":"jsonpath","expr":"$.tags[0]"},"predicate":{"type":"less","value":"testabc"}},{"query":{"type":"jsonpath","expr":"$.tags[0]"},"predicate":{"type":"less-or-equal","value":"test"}},{"query":{"type":"jsonpath","expr":"$.tags[0]"},"predicate":{"type":"greater","value":"{{foo}}"}},{"query":{"type":"jsonpath","expr":"$.profile-id"},"predicate":{"type":"equal","value":"123abc"}},{"query":{"type":"jsonpath","expr":"$['profile-id']"},"predicate":{"type":"equal","value":"123abc"}}],"body":{"type":"json","value":{"count":5,"success":false,"errors":[{"id":"error1"},{"id":"error2"}],"warnings":[],"duration":1.5,"tags":["test"],"nullable":null,"profile-id":"123abc"}}}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/index"},"response":{"status":200,"captures":[{"name":"index","query":{"type":"body"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.errors[{{index}}].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}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/list"},"response":{"status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":2}},{"query":{"type":"jsonpath","expr":"$.[0].name"},"predicate":{"type":"equal","value":"Bob"}},{"query":{"type":"jsonpath","expr":"$[0].name"},"predicate":{"type":"equal","value":"Bob"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/filter"},"response":{"status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.fruit[?(@.price.US==200)].name"},"predicate":{"type":"equal","value":"grape"}}]}}]} diff --git a/integration/tests_ok/bytes.py b/integration/tests_ok/bytes.py index 396dfad0cc7..2c7b7078ec8 100644 --- a/integration/tests_ok/bytes.py +++ b/integration/tests_ok/bytes.py @@ -11,3 +11,13 @@ def bytes(): resp = make_response(data) resp.content_type = "application/octet-stream" return resp + + +@app.route("/empty_bytes") +def empty_bytes(): + result = BytesIO() + result.write(b"") + data = result.getvalue() + resp = make_response(data) + resp.content_type = "application/octet-stream" + return resp diff --git a/integration/tests_ok/bytes_empty.html b/integration/tests_ok/bytes_empty.html new file mode 100644 index 00000000000..266d392fa2b --- /dev/null +++ b/integration/tests_ok/bytes_empty.html @@ -0,0 +1,7 @@ +
GET http://localhost:8000/empty_bytes
+HTTP 200
+Content-Type: application/octet-stream
+[Asserts]
+bytes isEmpty
+bytes count == 0
+
diff --git a/integration/tests_ok/bytes_empty.hurl b/integration/tests_ok/bytes_empty.hurl new file mode 100644 index 00000000000..f787ee8fbe0 --- /dev/null +++ b/integration/tests_ok/bytes_empty.hurl @@ -0,0 +1,6 @@ +GET http://localhost:8000/empty_bytes +HTTP 200 +Content-Type: application/octet-stream +[Asserts] +bytes isEmpty +bytes count == 0 diff --git a/integration/tests_ok/bytes_empty.json b/integration/tests_ok/bytes_empty.json new file mode 100644 index 00000000000..4ad3af7955f --- /dev/null +++ b/integration/tests_ok/bytes_empty.json @@ -0,0 +1 @@ +{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/empty_bytes"},"response":{"status":200,"headers":[{"name":"Content-Type","value":"application/octet-stream"}],"asserts":[{"query":{"type":"bytes"},"predicate":{"type":"isEmpty"}},{"query":{"type":"bytes"},"filters":[{"type":"count"}],"predicate":{"type":"equal","value":0}}]}}]} diff --git a/packages/hurl/src/runner/predicate.rs b/packages/hurl/src/runner/predicate.rs index 30040df2778..a350a56f9c2 100644 --- a/packages/hurl/src/runner/predicate.rs +++ b/packages/hurl/src/runner/predicate.rs @@ -230,6 +230,7 @@ fn expected( PredicateFuncValue::IsString {} => Ok("string".to_string()), PredicateFuncValue::IsCollection {} => Ok("collection".to_string()), PredicateFuncValue::Exist {} => Ok("something".to_string()), + PredicateFuncValue::IsEmpty {} => Ok("empty".to_string()), } } @@ -495,6 +496,40 @@ fn eval_something( type_mismatch: false, }), }, + + // empty + PredicateFuncValue::IsEmpty {} => match value { + Value::List(values) => Ok(AssertResult { + success: values.len() as i64 == 0, + actual: values.len().to_string(), + expected: 0.to_string(), + type_mismatch: false, + }), + Value::String(data) => Ok(AssertResult { + success: data.len() as i64 == 0, + actual: data.len().to_string(), + expected: 0.to_string(), + type_mismatch: false, + }), + Value::Nodeset(nodeset) => Ok(AssertResult { + success: *nodeset as i64 == 0, + actual: nodeset.to_string(), + expected: 0.to_string(), + type_mismatch: false, + }), + Value::Bytes(data) => Ok(AssertResult { + success: data.len() as i64 == 0, + actual: data.len().to_string(), + expected: 0.to_string(), + type_mismatch: false, + }), + _ => Ok(AssertResult { + success: false, + actual: value.display(), + expected: "count equals to 0".to_string(), + type_mismatch: true, + }), + }, _ => panic!(), } } @@ -1463,6 +1498,44 @@ mod tests { assert_eq!(assert_result.expected.as_str(), "1"); } + #[test] + fn test_predicate_is_empty_are_false() { + let variables = HashMap::new(); + let assert_result = eval_something( + &PredicateFunc { + value: PredicateFuncValue::IsEmpty {}, + source_info: SourceInfo::new(0, 0, 0, 0), + }, + &variables, + &Value::List(vec![Value::Integer(1)]), + ) + .unwrap(); + + assert!(!assert_result.success); + assert!(!assert_result.type_mismatch); + assert_eq!(assert_result.actual.as_str(), "1"); + assert_eq!(assert_result.expected.as_str(), "0"); + } + + #[test] + fn test_predicate_is_empty_are_true() { + let variables = HashMap::new(); + let assert_result = eval_something( + &PredicateFunc { + value: PredicateFuncValue::IsEmpty {}, + source_info: SourceInfo::new(0, 0, 0, 0), + }, + &variables, + &Value::List(vec![]), + ) + .unwrap(); + + assert!(assert_result.success); + assert!(!assert_result.type_mismatch); + assert_eq!(assert_result.actual.as_str(), "0"); + assert_eq!(assert_result.expected.as_str(), "0"); + } + #[test] fn test_predicate_count_equals() { let variables = HashMap::new(); diff --git a/packages/hurl_core/src/ast/core.rs b/packages/hurl_core/src/ast/core.rs index f8cc31004bc..4b505a96c2e 100644 --- a/packages/hurl_core/src/ast/core.rs +++ b/packages/hurl_core/src/ast/core.rs @@ -494,6 +494,7 @@ pub enum PredicateFuncValue { IsString {}, IsCollection {}, Exist {}, + IsEmpty {}, } // diff --git a/packages/hurl_core/src/ast/display.rs b/packages/hurl_core/src/ast/display.rs index 4766c27c517..36cf2e214ad 100644 --- a/packages/hurl_core/src/ast/display.rs +++ b/packages/hurl_core/src/ast/display.rs @@ -233,6 +233,7 @@ impl PredicateFuncValue { PredicateFuncValue::IsString { .. } => "isString".to_string(), PredicateFuncValue::IsCollection { .. } => "isCollection".to_string(), PredicateFuncValue::Exist { .. } => "exists".to_string(), + PredicateFuncValue::IsEmpty { .. } => "isEmpty".to_string(), } } } diff --git a/packages/hurl_core/src/format/html.rs b/packages/hurl_core/src/format/html.rs index 2864efbfd02..a5c4cf1461e 100644 --- a/packages/hurl_core/src/format/html.rs +++ b/packages/hurl_core/src/format/html.rs @@ -881,6 +881,11 @@ impl Htmlable for PredicateFuncValue { format!("{}", self.name()).as_str(), ); } + PredicateFuncValue::IsEmpty {} => { + buffer.push_str( + format!("{}", self.name()).as_str(), + ); + } } buffer } diff --git a/packages/hurl_core/src/parser/predicate.rs b/packages/hurl_core/src/parser/predicate.rs index a51501bb38d..77632f2800f 100644 --- a/packages/hurl_core/src/parser/predicate.rs +++ b/packages/hurl_core/src/parser/predicate.rs @@ -88,6 +88,7 @@ fn predicate_func_value(reader: &mut Reader) -> ParseResult<'static, PredicateFu string_predicate, collection_predicate, exist_predicate, + is_empty_predicate, ], reader, ) { @@ -357,6 +358,11 @@ fn exist_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncVal Ok(PredicateFuncValue::Exist {}) } +fn is_empty_predicate(reader: &mut Reader) -> ParseResult<'static, PredicateFuncValue> { + try_literal("isEmpty", reader)?; + Ok(PredicateFuncValue::IsEmpty {}) +} + #[cfg(test)] mod tests { use super::*; diff --git a/packages/hurlfmt/src/format/json.rs b/packages/hurlfmt/src/format/json.rs index e6110d7b582..d351efea7e8 100644 --- a/packages/hurlfmt/src/format/json.rs +++ b/packages/hurlfmt/src/format/json.rs @@ -474,6 +474,9 @@ impl ToJson for Predicate { PredicateFuncValue::Exist {} => { attributes.push(("type".to_string(), JValue::String("exist".to_string()))); } + PredicateFuncValue::IsEmpty {} => { + attributes.push(("type".to_string(), JValue::String("isEmpty".to_string()))); + } } JValue::Object(attributes) } diff --git a/packages/hurlfmt/src/format/token.rs b/packages/hurlfmt/src/format/token.rs index 379132b7486..f0d956cb494 100644 --- a/packages/hurlfmt/src/format/token.rs +++ b/packages/hurlfmt/src/format/token.rs @@ -592,6 +592,9 @@ impl Tokenizable for PredicateFuncValue { PredicateFuncValue::Exist {} => { tokens.push(Token::PredicateType(self.name())); } + PredicateFuncValue::IsEmpty {} => { + tokens.push(Token::PredicateType(self.name())); + } } tokens } diff --git a/packages/hurlfmt/src/linter/rules.rs b/packages/hurlfmt/src/linter/rules.rs index ebdb86bc9e6..6c844d5beb0 100644 --- a/packages/hurlfmt/src/linter/rules.rs +++ b/packages/hurlfmt/src/linter/rules.rs @@ -400,6 +400,7 @@ fn lint_predicate_func_value(predicate_func_value: &PredicateFuncValue) -> Predi PredicateFuncValue::IsString {} => PredicateFuncValue::IsString {}, PredicateFuncValue::IsCollection {} => PredicateFuncValue::IsCollection {}, PredicateFuncValue::Exist {} => PredicateFuncValue::Exist {}, + PredicateFuncValue::IsEmpty {} => PredicateFuncValue::IsEmpty {}, } }