Skip to content

Commit

Permalink
Add isNumber predicate
Browse files Browse the repository at this point in the history
Signed-off-by: Federico Guerinoni <guerinoni.federico@gmail.com>
  • Loading branch information
guerinoni committed Mar 27, 2024
1 parent 1b39431 commit f70d849
Show file tree
Hide file tree
Showing 19 changed files with 67 additions and 6 deletions.
4 changes: 2 additions & 2 deletions integration/hurl/tests_failed/assert_base64.err
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
error: Assert body value
--> tests_failed/assert_base64.hurl:12:8
--> tests_failed/assert_base64.hurl:12:9
|
| GET http://localhost:8000/assert-base64
| ...
12 | base64,bGluZTEKbGluZTIKbGluZTMK;
| ^^^^^^^^^^^^^^^^^^^^^^^^ actual value is <hex, 6c696e65310a6c696e65320d0a6c696e65330a;>
| ^^^^^^^^^^^^^^^^^^^^^^^^ actual value is <hex, 6c696e65310a6c696e65320d0a6c696e65330a;>
|

10 changes: 10 additions & 0 deletions integration/hurl/tests_failed/predicate.err
Original file line number Diff line number Diff line change
Expand Up @@ -431,3 +431,13 @@ error: Assert failure
| expected: not string with format YYYY-MM-DDTHH:mm:ss.sssZ
|

error: Assert failure
--> tests_failed/predicate.hurl:47:0
|
| GET http://localhost:8000/predicate/error/type
| ...
47 | jsonpath "$.not_a_date" isNumber
| actual: string <2018>
| expected: number
|

1 change: 1 addition & 0 deletions integration/hurl/tests_failed/predicate.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@ jsonpath "$.not-exist" exists
jsonpath "$.not-exist" isEmpty
jsonpath "$.not_a_date" isIsoDate
jsonpath "$.is_a_date" not isIsoDate
jsonpath "$.not_a_date" isNumber
2 changes: 2 additions & 0 deletions integration/hurl/tests_ok/assert_json.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jsonpath "$.duration" <= 2.0
jsonpath "$.duration" < 2
jsonpath "$.duration" < {{two}}
jsonpath "$.duration" isFloat
jsonpath "$.duration" isNumber
jsonpath "$.duration" not isInteger
jsonpath "$.nullable" == null
jsonpath "$.tags[0]" == "test"
Expand All @@ -67,6 +68,7 @@ jsonpath "$..id" count == 3
jsonpath "$.dates[0]" isIsoDate
jsonpath "$.dates[1]" isIsoDate
jsonpath "$.tags[0]" not isIsoDate
jsonpath "$.tags[0]" not isNumber


# FIXME do we accept count filter on object?
Expand Down
2 changes: 1 addition & 1 deletion integration/hurl/tests_ok/help.out.pattern
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,4 @@ Options:
-h, --help
Print help
-V, --version
Print version
Print version
1 change: 1 addition & 0 deletions integration/hurlfmt/tests_export/predicate.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@
<span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.release"</span> <span class="predicate-type">matches</span> <span class="regex">/\d{4}/</span></span> <span class="comment"># matches</span>
<span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.movie"</span> <span class="predicate-type">startsWith</span> <span class="string">"The"</span></span> <span class="comment"># startsWith</span>
<span class="line"><span class="query-type">bytes</span> <span class="predicate-type">startsWith</span> hex,<span class="hex">efbbbf</span>;</span> <span class="comment"># startsWith</span>
<span class="line"><span class="query-type">jsonpath</span> <span class="string">"$.count"</span> <span class="predicate-type">isNumber</span></span> <span class="comment"># isNumber</span>
</span></span></code></pre>
1 change: 1 addition & 0 deletions integration/hurlfmt/tests_export/predicate.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ jsonpath "$.release" matches "\\d{4}" # matches
jsonpath "$.release" matches /\d{4}/ # matches
jsonpath "$.movie" startsWith "The" # startsWith
bytes startsWith hex,efbbbf; # startsWith
jsonpath "$.count" isNumber # isNumber
2 changes: 1 addition & 1 deletion integration/hurlfmt/tests_export/predicate.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/dummy"},"response":{"status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.book"},"predicate":{"not":true,"type":"equal","value":"Dune"}},{"query":{"type":"jsonpath","expr":"$.book"},"predicate":{"type":"equal","value":"Dune"}},{"query":{"type":"jsonpath","expr":"$.color"},"predicate":{"type":"not-equal","value":"red"}},{"query":{"type":"jsonpath","expr":"$.year"},"predicate":{"type":"greater","value":1978}},{"query":{"type":"jsonpath","expr":"$.year"},"predicate":{"type":"greater-or-equal","value":1978}},{"query":{"type":"jsonpath","expr":"$.year"},"predicate":{"type":"less","value":1978}},{"query":{"type":"jsonpath","expr":"$.year"},"predicate":{"type":"less-or-equal","value":1978}},{"query":{"type":"jsonpath","expr":"$.movie"},"predicate":{"type":"contain","value":"Empire"}},{"query":{"type":"bytes"},"predicate":{"type":"contain","value":"vu8=","encoding":"base64"}},{"query":{"type":"jsonpath","expr":"$.movie"},"predicate":{"type":"end-with","value":"Back"}},{"query":{"type":"bytes"},"predicate":{"type":"end-with","value":"qxI0Vg==","encoding":"base64"}},{"query":{"type":"jsonpath","expr":"$.book"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.nooks"},"predicate":{"type":"include","value":"Dune"}},{"query":{"type":"jsonpath","expr":"$.succeeded"},"predicate":{"type":"isBoolean"}},{"query":{"type":"jsonpath","expr":"$.books"},"predicate":{"type":"isCollection"}},{"query":{"type":"certificate","expr":"Expire-Date"},"predicate":{"type":"isDate"}},{"query":{"type":"jsonpath","expr":"$.publication_date"},"predicate":{"type":"isIsoDate"}},{"query":{"type":"jsonpath","expr":"$.movies"},"predicate":{"type":"isEmpty"}},{"query":{"type":"jsonpath","expr":"$.height"},"predicate":{"type":"isFloat"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"isInteger"}},{"query":{"type":"jsonpath","expr":"$.name"},"predicate":{"type":"isString"}},{"query":{"type":"jsonpath","expr":"$.release"},"predicate":{"type":"match","value":"\\d{4}"}},{"query":{"type":"jsonpath","expr":"$.release"},"predicate":{"type":"match","value":"\\d{4}","encoding":"regex"}},{"query":{"type":"jsonpath","expr":"$.movie"},"predicate":{"type":"start-with","value":"The"}},{"query":{"type":"bytes"},"predicate":{"type":"start-with","value":"77u/","encoding":"base64"}}]}}]}
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/dummy"},"response":{"status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.book"},"predicate":{"not":true,"type":"equal","value":"Dune"}},{"query":{"type":"jsonpath","expr":"$.book"},"predicate":{"type":"equal","value":"Dune"}},{"query":{"type":"jsonpath","expr":"$.color"},"predicate":{"type":"not-equal","value":"red"}},{"query":{"type":"jsonpath","expr":"$.year"},"predicate":{"type":"greater","value":1978}},{"query":{"type":"jsonpath","expr":"$.year"},"predicate":{"type":"greater-or-equal","value":1978}},{"query":{"type":"jsonpath","expr":"$.year"},"predicate":{"type":"less","value":1978}},{"query":{"type":"jsonpath","expr":"$.year"},"predicate":{"type":"less-or-equal","value":1978}},{"query":{"type":"jsonpath","expr":"$.movie"},"predicate":{"type":"contain","value":"Empire"}},{"query":{"type":"bytes"},"predicate":{"type":"contain","value":"vu8=","encoding":"base64"}},{"query":{"type":"jsonpath","expr":"$.movie"},"predicate":{"type":"end-with","value":"Back"}},{"query":{"type":"bytes"},"predicate":{"type":"end-with","value":"qxI0Vg==","encoding":"base64"}},{"query":{"type":"jsonpath","expr":"$.book"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.nooks"},"predicate":{"type":"include","value":"Dune"}},{"query":{"type":"jsonpath","expr":"$.succeeded"},"predicate":{"type":"isBoolean"}},{"query":{"type":"jsonpath","expr":"$.books"},"predicate":{"type":"isCollection"}},{"query":{"type":"certificate","expr":"Expire-Date"},"predicate":{"type":"isDate"}},{"query":{"type":"jsonpath","expr":"$.publication_date"},"predicate":{"type":"isIsoDate"}},{"query":{"type":"jsonpath","expr":"$.movies"},"predicate":{"type":"isEmpty"}},{"query":{"type":"jsonpath","expr":"$.height"},"predicate":{"type":"isFloat"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"isInteger"}},{"query":{"type":"jsonpath","expr":"$.name"},"predicate":{"type":"isString"}},{"query":{"type":"jsonpath","expr":"$.release"},"predicate":{"type":"match","value":"\\d{4}"}},{"query":{"type":"jsonpath","expr":"$.release"},"predicate":{"type":"match","value":"\\d{4}","encoding":"regex"}},{"query":{"type":"jsonpath","expr":"$.movie"},"predicate":{"type":"start-with","value":"The"}},{"query":{"type":"bytes"},"predicate":{"type":"start-with","value":"77u/","encoding":"base64"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"isNumber"}}]}}]}
1 change: 1 addition & 0 deletions integration/hurlfmt/tests_export/predicate.lint.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ jsonpath "$.release" matches "\\d{4}" # matches
jsonpath "$.release" matches /\d{4}/ # matches
jsonpath "$.movie" startsWith "The" # startsWith
bytes startsWith hex,efbbbf; # startsWith
jsonpath "$.count" isNumber # isNumber
2 changes: 1 addition & 1 deletion integration/hurlfmt/tests_ok/help.out.pattern
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ Options:
--out <FORMAT> Specify output format: hurl, json or html [default: hurl]
--standalone Standalone HTML
-h, --help Print help
-V, --version Print version
-V, --version Print version
29 changes: 29 additions & 0 deletions packages/hurl/src/runner/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ fn expected_no_value(
PredicateFuncValue::IsIsoDate => Ok("date".to_string()),
PredicateFuncValue::Exist => Ok("something".to_string()),
PredicateFuncValue::IsEmpty => Ok("empty".to_string()),
PredicateFuncValue::IsNumber => Ok("number".to_string()),
}
}

Expand Down Expand Up @@ -306,6 +307,7 @@ fn eval_predicate_func(
PredicateFuncValue::IsIsoDate => eval_is_iso_date(value),
PredicateFuncValue::Exist => eval_exist(value),
PredicateFuncValue::IsEmpty => eval_is_empty(value),
PredicateFuncValue::IsNumber => eval_is_number(value),
}
}

Expand Down Expand Up @@ -670,6 +672,16 @@ fn eval_is_empty(actual: &Value) -> Result<AssertResult, Error> {
}
}

/// Evaluates if an `actual` value is a number.
fn eval_is_number(actual: &Value) -> Result<AssertResult, Error> {
Ok(AssertResult {
success: matches!(actual, Value::Number(_)),
actual: actual.display(),
expected: "number".to_string(),
type_mismatch: false,
})
}

fn assert_values_equal(actual: &Value, expected: &Value) -> AssertResult {
let actual_display = actual.display();
let expected_display = expected.display();
Expand Down Expand Up @@ -1590,4 +1602,21 @@ mod tests {
assert_eq!(res.actual, "bool <true>");
assert_eq!(res.expected, "string");
}

#[test]
fn test_predicate_is_number() {
let value = Value::Number(Number::Integer(1));
let res = eval_is_number(&value).unwrap();
assert!(res.success);
assert!(!res.type_mismatch);
assert_eq!(res.actual, "int <1>");
assert_eq!(res.expected, "number");

let value = Value::Number(Number::Float(1.0));
let res = eval_is_number(&value).unwrap();
assert!(res.success);
assert!(!res.type_mismatch);
assert_eq!(res.actual, "float <1.0>");
assert_eq!(res.expected, "number");
}
}
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 @@ -493,6 +493,7 @@ pub enum PredicateFuncValue {
IsIsoDate,
Exist,
IsEmpty,
IsNumber,
}

//
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 @@ -273,6 +273,7 @@ impl PredicateFuncValue {
PredicateFuncValue::IsIsoDate => "isIsoDate".to_string(),
PredicateFuncValue::Exist => "exists".to_string(),
PredicateFuncValue::IsEmpty => "isEmpty".to_string(),
PredicateFuncValue::IsNumber => "isNumber".to_string(),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/hurl_core/src/format/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ impl HtmlFormatter {
PredicateFuncValue::IsIsoDate => {}
PredicateFuncValue::Exist => {}
PredicateFuncValue::IsEmpty => {}
PredicateFuncValue::IsNumber => {}
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/hurl_core/src/parser/parsers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ fn version(reader: &mut Reader) -> ParseResult<Version> {
let next_c = reader.peek();
match next_c {
Some('/') => {
let available_version = vec![
let available_version = [
("/1.0", VersionValue::Version1),
("/1.1", VersionValue::Version11),
("/2", VersionValue::Version2),
Expand Down
6 changes: 6 additions & 0 deletions packages/hurl_core/src/parser/predicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ fn predicate_func_value(reader: &mut Reader) -> ParseResult<PredicateFuncValue>
iso_date_predicate,
exist_predicate,
is_empty_predicate,
is_number_predicate,
],
reader,
) {
Expand Down Expand Up @@ -341,6 +342,11 @@ fn is_empty_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
Ok(PredicateFuncValue::IsEmpty)
}

fn is_number_predicate(reader: &mut Reader) -> ParseResult<PredicateFuncValue> {
try_literal("isNumber", reader)?;
Ok(PredicateFuncValue::IsNumber)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
3 changes: 3 additions & 0 deletions packages/hurlfmt/src/format/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,9 @@ impl ToJson for Predicate {
PredicateFuncValue::IsEmpty => {
attributes.push(("type".to_string(), JValue::String("isEmpty".to_string())));
}
PredicateFuncValue::IsNumber => {
attributes.push(("type".to_string(), JValue::String("isNumber".to_string())));
}
}
JValue::Object(attributes)
}
Expand Down
3 changes: 3 additions & 0 deletions packages/hurlfmt/src/format/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,9 @@ impl Tokenizable for PredicateFuncValue {
PredicateFuncValue::IsEmpty => {
tokens.push(Token::PredicateType(self.name()));
}
PredicateFuncValue::IsNumber => {
tokens.push(Token::PredicateType(self.name()));
}
}
tokens
}
Expand Down
1 change: 1 addition & 0 deletions packages/hurlfmt/src/linter/rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ fn lint_predicate_func_value(predicate_func_value: &PredicateFuncValue) -> Predi
PredicateFuncValue::IsIsoDate => PredicateFuncValue::IsIsoDate,
PredicateFuncValue::Exist => PredicateFuncValue::Exist,
PredicateFuncValue::IsEmpty => PredicateFuncValue::IsEmpty,
PredicateFuncValue::IsNumber => PredicateFuncValue::IsNumber,
}
}

Expand Down

0 comments on commit f70d849

Please sign in to comment.