diff --git a/integration/tests/assert_json.html b/integration/tests/assert_json.html index ecc3ac559..2b49e6fa8 100644 --- a/integration/tests/assert_json.html +++ b/integration/tests/assert_json.html @@ -1 +1 @@ -
GET http://localhost:8000/assert-json
HTTP/1.0 200[Asserts]jsonpath "$.success" equals falsejsonpath "$.success" not equals nulljsonpath "$.success" existsjsonpath "$.success" isBooleanjsonpath "$.errors" equals 2jsonpath "$.errors" isCollectionjsonpath "$.warnings" equals 0jsonpath "$.toto" not existsjsonpath "$.warnings" existsjsonpath "$.warnings" existsjsonpath "$.errors[0]" existsjsonpath "$.errors[0]" isCollectionjsonpath "$.errors[0].id" equals "error1"jsonpath "$.errors[0]['id']" equals "error1"jsonpath "$.duration" equals 1.5jsonpath "$.duration" less-than-or-equal 2.0jsonpath "$.duration" less-than 2jsonpath "$.duration" isFloatjsonpath "$.duration" not isIntegerjsonpath "$.nullable" equals null{ "success": false, "errors": [{"id":"error1"},{"id":"error2"}], "warnings": [], "duration": 1.5, "tags": ["test"], "nullable": null}
GET http://localhost:8000/assert-json/index
HTTP/1.0 200[Captures]index: status
GET http://localhost:8000/assert-json
HTTP/1.0 200[Asserts]jsonpath "$.errors[{{index}}].id" equals "error2"jsonpath "$.tags" includes "test"jsonpath "$.tags" not includes "prod"jsonpath "$.tags" not includes null
GET http://localhost:8000/assert-json/list
HTTP/1.0 200[Asserts]jsonpath "$" equals 2jsonpath "$.[0].name" equals "Bob"jsonpath "$[0].name" equals "Bob"
\ No newline at end of file +
GET http://localhost:8000/assert-json
HTTP/1.0 200[Asserts]jsonpath "$.count" equals 5jsonpath "$.count" equals 5.0jsonpath "$.count" greater-than 1jsonpath "$.count" greater-than 1.0jsonpath "$.success" equals falsejsonpath "$.success" not equals nulljsonpath "$.success" existsjsonpath "$.success" isBooleanjsonpath "$.errors" equals 2jsonpath "$.errors" isCollectionjsonpath "$.warnings" equals 0jsonpath "$.toto" not existsjsonpath "$.warnings" existsjsonpath "$.warnings" existsjsonpath "$.errors[0]" existsjsonpath "$.errors[0]" isCollectionjsonpath "$.errors[0].id" equals "error1"jsonpath "$.errors[0]['id']" equals "error1"jsonpath "$.duration" equals 1.5jsonpath "$.duration" less-than-or-equal 2.0jsonpath "$.duration" less-than 2jsonpath "$.duration" isFloatjsonpath "$.duration" not isIntegerjsonpath "$.nullable" equals null{ "count": 5, "success": false, "errors": [{"id":"error1"},{"id":"error2"}], "warnings": [], "duration": 1.5, "tags": ["test"], "nullable": null}
GET http://localhost:8000/assert-json/index
HTTP/1.0 200[Captures]index: status
GET http://localhost:8000/assert-json
HTTP/1.0 200[Asserts]jsonpath "$.errors[{{index}}].id" equals "error2"jsonpath "$.tags" includes "test"jsonpath "$.tags" not includes "prod"jsonpath "$.tags" not includes null
GET http://localhost:8000/assert-json/list
HTTP/1.0 200[Asserts]jsonpath "$" equals 2jsonpath "$.[0].name" equals "Bob"jsonpath "$[0].name" equals "Bob"
\ No newline at end of file diff --git a/integration/tests/assert_json.hurl b/integration/tests/assert_json.hurl index 840692e81..c93e94b67 100644 --- a/integration/tests/assert_json.hurl +++ b/integration/tests/assert_json.hurl @@ -1,6 +1,10 @@ GET http://localhost:8000/assert-json HTTP/1.0 200 [Asserts] +jsonpath "$.count" equals 5 +jsonpath "$.count" equals 5.0 +jsonpath "$.count" greaterThan 1 +jsonpath "$.count" greaterThan 1.0 jsonpath "$.success" equals false jsonpath "$.success" not equals null jsonpath "$.success" exists @@ -23,6 +27,7 @@ jsonpath "$.duration" not isInteger jsonpath "$.nullable" equals null { + "count": 5, "success": false, "errors": [{"id":"error1"},{"id":"error2"}], "warnings": [], diff --git a/integration/tests/assert_json.json b/integration/tests/assert_json.json index 683deb0fd..5ed0dd4ec 100644 --- a/integration/tests/assert_json.json +++ b/integration/tests/assert_json.json @@ -1 +1 @@ -{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"equal","value":false}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"not":true,"type":"equal","value":null}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"isBoolean"}},{"query":{"type":"jsonpath","expr":"$.errors"},"predicate":{"type":"count","value":2}},{"query":{"type":"jsonpath","expr":"$.errors"},"predicate":{"type":"isCollection"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"count","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":"$.duration"},"predicate":{"type":"equal","value":1.5}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less-than-or-equal","value":"2.0"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"greater-than","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}}],"body":{"type":"json","value":{"success":false,"errors":[{"id":"error1"},{"id":"error2"}],"warnings":[],"duration":1.5,"tags":["test"],"nullable":null}}}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/index"},"response":{"version":"HTTP/1.0","status":200,"captures":[{"name":"index","query":{"type":"body"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"version":"HTTP/1.0","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":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$"},"predicate":{"type":"count","value":2}},{"query":{"type":"jsonpath","expr":"$.[0].name"},"predicate":{"type":"equal","value":"Bob"}},{"query":{"type":"jsonpath","expr":"$[0].name"},"predicate":{"type":"equal","value":"Bob"}}]}}]} \ No newline at end of file +{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"version":"HTTP/1.0","status":200,"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":"greater-than","value":"1"}},{"query":{"type":"jsonpath","expr":"$.count"},"predicate":{"type":"greater-than","value":"1.0"}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"equal","value":false}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"not":true,"type":"equal","value":null}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"exist"}},{"query":{"type":"jsonpath","expr":"$.success"},"predicate":{"type":"isBoolean"}},{"query":{"type":"jsonpath","expr":"$.errors"},"predicate":{"type":"count","value":2}},{"query":{"type":"jsonpath","expr":"$.errors"},"predicate":{"type":"isCollection"}},{"query":{"type":"jsonpath","expr":"$.warnings"},"predicate":{"type":"count","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":"$.duration"},"predicate":{"type":"equal","value":1.5}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"less-than-or-equal","value":"2.0"}},{"query":{"type":"jsonpath","expr":"$.duration"},"predicate":{"type":"greater-than","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}}],"body":{"type":"json","value":{"count":5,"success":false,"errors":[{"id":"error1"},{"id":"error2"}],"warnings":[],"duration":1.5,"tags":["test"],"nullable":null}}}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json/index"},"response":{"version":"HTTP/1.0","status":200,"captures":[{"name":"index","query":{"type":"body"}}]}},{"request":{"method":"GET","url":"http://localhost:8000/assert-json"},"response":{"version":"HTTP/1.0","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":{"version":"HTTP/1.0","status":200,"asserts":[{"query":{"type":"jsonpath","expr":"$"},"predicate":{"type":"count","value":2}},{"query":{"type":"jsonpath","expr":"$.[0].name"},"predicate":{"type":"equal","value":"Bob"}},{"query":{"type":"jsonpath","expr":"$[0].name"},"predicate":{"type":"equal","value":"Bob"}}]}}]} \ No newline at end of file diff --git a/integration/tests/assert_json.py b/integration/tests/assert_json.py index 2a259d652..75ffa9e06 100644 --- a/integration/tests/assert_json.py +++ b/integration/tests/assert_json.py @@ -4,6 +4,7 @@ from flask import Response @app.route("/assert-json") def assert_json(): return Response('''{ + "count": 5, "success": false, "errors": [{"id":"error1"},{"id":"error2"}], "warnings": [], diff --git a/integration/tests/error_assert_value_error.err b/integration/tests/error_assert_value_error.err index 19c05087f..1cb235deb 100644 --- a/integration/tests/error_assert_value_error.err +++ b/integration/tests/error_assert_value_error.err @@ -36,7 +36,7 @@ error: Assert Failure | 8 | jsonpath "$.count" greaterThan 5 | actual: int <2> - | expected: int <5> + | expected: greater than int <5> | error: Assert Failure diff --git a/packages/hurl/src/runner/predicate.rs b/packages/hurl/src/runner/predicate.rs index 5a21824e7..6e8c06488 100644 --- a/packages/hurl/src/runner/predicate.rs +++ b/packages/hurl/src/runner/predicate.rs @@ -582,6 +582,12 @@ fn assert_values_equal(actual: Value, expected: Value) -> Result Ok(AssertResult { + success: int1 == int2 && decimal == 0, + actual: actual.display(), + expected: expected.display(), + type_mismatch: false, + }), (Value::Float(i1, d1), Value::Float(i2, d2)) => Ok(AssertResult { success: i1 == i2 && d1 == d2, actual: actual.display(), @@ -621,93 +627,110 @@ fn assert_values_equal(actual: Value, expected: Value) -> Result Result { - match compare_numbers(actual.clone(), expected.clone()) { +fn assert_values_greater( + actual_value: Value, + expected_value: Value, +) -> Result { + let actual = actual_value.clone().display(); + let expected = format!("greater than {}", expected_value.clone().display()); + match compare_numbers(actual_value, expected_value) { Some(1) => Ok(AssertResult { success: true, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: false, }), Some(0) | Some(-1) => Ok(AssertResult { success: false, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: false, }), _ => Ok(AssertResult { success: false, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: true, }), } } -fn assert_values_greater_or_equal(actual: Value, expected: Value) -> Result { - match compare_numbers(actual.clone(), expected.clone()) { +fn assert_values_greater_or_equal( + actual_value: Value, + expected_value: Value, +) -> Result { + let actual = actual_value.clone().display(); + let expected = format!("greater or equal than {}", expected_value.clone().display()); + match compare_numbers(actual_value, expected_value) { Some(1) | Some(0) => Ok(AssertResult { success: true, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: false, }), Some(-1) => Ok(AssertResult { success: false, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: false, }), _ => Ok(AssertResult { success: false, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: true, }), } } -fn assert_values_less(actual: Value, expected: Value) -> Result { - match compare_numbers(actual.clone(), expected.clone()) { +fn assert_values_less(actual_value: Value, expected_value: Value) -> Result { + let actual = actual_value.clone().display(); + let expected = format!("less than {}", expected_value.clone().display()); + match compare_numbers(actual_value, expected_value) { Some(-1) => Ok(AssertResult { success: true, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: false, }), Some(0) | Some(1) => Ok(AssertResult { success: false, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: false, }), _ => Ok(AssertResult { success: false, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: true, }), } } -fn assert_values_less_or_equal(actual: Value, expected: Value) -> Result { - match compare_numbers(actual.clone(), expected.clone()) { +fn assert_values_less_or_equal( + actual_value: Value, + expected_value: Value, +) -> Result { + let actual = actual_value.clone().display(); + let expected = format!("less or equal than {}", expected_value.clone().display()); + match compare_numbers(actual_value, expected_value) { Some(-1) | Some(0) => Ok(AssertResult { success: true, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: false, }), Some(1) => Ok(AssertResult { success: false, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: false, }), _ => Ok(AssertResult { success: false, - actual: actual.display(), - expected: expected.display(), + actual, + expected, type_mismatch: true, }), } @@ -724,6 +747,7 @@ fn compare_numbers(actual: Value, expected: Value) -> Option { } (Value::Float(i1, d1), Value::Float(i2, d2)) => Some(compare_float((i1, d1), (i2, d2))), (Value::Float(i1, d1), Value::Integer(i2)) => Some(compare_float((i1, d1), (i2, 0))), + (Value::Integer(i1), Value::Float(i2, d2)) => Some(compare_float((i1, 0), (i2, d2))), _ => None, } } @@ -1191,7 +1215,10 @@ mod tests { ); // 1 integer and 1 float - assert!(compare_numbers(Value::Integer(2), Value::Float(2, 0)).is_none()); + assert_eq!( + compare_numbers(Value::Integer(2), Value::Float(2, 0)).unwrap(), + 0 + ); // with a non number assert!(compare_numbers(Value::Integer(-1), Value::String("hello".to_string())).is_none()); @@ -1205,7 +1232,7 @@ mod tests { success: true, type_mismatch: false, actual: "int <2>".to_string(), - expected: "int <1>".to_string(), + expected: "greater than int <1>".to_string(), } ); assert_eq!( @@ -1214,7 +1241,7 @@ mod tests { success: false, type_mismatch: false, actual: "int <1>".to_string(), - expected: "int <1>".to_string(), + expected: "greater than int <1>".to_string(), } ); assert_eq!( @@ -1223,7 +1250,7 @@ mod tests { success: true, type_mismatch: false, actual: "float <1.1>".to_string(), - expected: "int <1>".to_string(), + expected: "greater than int <1>".to_string(), } ); assert_eq!( @@ -1232,7 +1259,7 @@ mod tests { success: false, type_mismatch: false, actual: "float <1.1>".to_string(), - expected: "int <2>".to_string(), + expected: "greater than int <2>".to_string(), } ); }