Skip to content

Commit

Permalink
Implement isEmpty predicate
Browse files Browse the repository at this point in the history
Signed-off-by: Rached Mejri <rached.mejri@orange.com>
  • Loading branch information
Reachip authored and jcamiel committed Mar 10, 2023
1 parent 05c54e9 commit 077807e
Show file tree
Hide file tree
Showing 18 changed files with 123 additions and 2 deletions.
1 change: 1 addition & 0 deletions integration/tests_failed/assert_xpath.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
<span class="line section-header">[Asserts]</span>
<span class="line"><span class="query-type">xpath</span> <span class="string">"strong(//head/title)"</span> <span class="predicate-type">equals</span> <span class="string">"Welcome to Quiz!"</span></span>
<span class="line"><span class="query-type">xpath</span> <span class="string">"strong(//head/title)"</span> <span class="predicate-type">isEmpty</span></span>
</span></span></code></pre>
1 change: 1 addition & 0 deletions integration/tests_failed/assert_xpath.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion integration/tests_failed/assert_xpath.json
Original file line number Diff line number Diff line change
@@ -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"}}]}}]}
1 change: 1 addition & 0 deletions integration/tests_ok/assert_json.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.errors"</span> <span class="filter-type">count</span> <span class="predicate-type">==</span> <span class="number">2</span></span>
<span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.errors"</span> <span class="predicate-type">isCollection</span></span>
<span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.warnings"</span> <span class="filter-type">count</span> <span class="predicate-type">==</span> <span class="number">0</span></span>
<span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.warnings"</span> <span class="predicate-type">isEmpty</span></span>
<span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.toto"</span> <span class="not">not</span> <span class="predicate-type">exists</span></span>
<span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.warnings"</span> <span class="predicate-type">exists</span></span>
<span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.warnings"</span> <span class="predicate-type">exists</span></span>
Expand Down
1 change: 1 addition & 0 deletions integration/tests_ok/assert_json.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion integration/tests_ok/assert_json.json
Original file line number Diff line number Diff line change
@@ -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"}}]}}]}
10 changes: 10 additions & 0 deletions integration/tests_ok/bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 7 additions & 0 deletions integration/tests_ok/bytes_empty.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<pre><code class="language-hurl"><span class="hurl-entry"><span class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/empty_bytes</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
<span class="line"><span class="string">Content-Type</span><span>:</span> <span class="string">application/octet-stream</span></span>
<span class="line section-header">[Asserts]</span>
<span class="line"><span class="query-type">bytes</span> <span class="predicate-type">isEmpty</span></span>
<span class="line"><span class="query-type">bytes</span> <span class="filter-type">count</span> <span class="predicate-type">==</span> <span class="number">0</span></span>
</span></span></code></pre>
6 changes: 6 additions & 0 deletions integration/tests_ok/bytes_empty.hurl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
GET http://localhost:8000/empty_bytes
HTTP 200
Content-Type: application/octet-stream
[Asserts]
bytes isEmpty
bytes count == 0
1 change: 1 addition & 0 deletions integration/tests_ok/bytes_empty.json
Original file line number Diff line number Diff line change
@@ -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}}]}}]}
73 changes: 73 additions & 0 deletions packages/hurl/src/runner/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
}
}

Expand Down Expand Up @@ -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!(),
}
}
Expand Down Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions packages/hurl_core/src/ast/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ pub enum PredicateFuncValue {
IsString {},
IsCollection {},
Exist {},
IsEmpty {},
}

//
Expand Down
1 change: 1 addition & 0 deletions packages/hurl_core/src/ast/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions packages/hurl_core/src/format/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,11 @@ impl Htmlable for PredicateFuncValue {
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
}
PredicateFuncValue::IsEmpty {} => {
buffer.push_str(
format!("<span class=\"predicate-type\">{}</span>", self.name()).as_str(),
);
}
}
buffer
}
Expand Down
Loading

0 comments on commit 077807e

Please sign in to comment.