Merge pull request #43 from Orange-OpenSource/fix/predicate-with-not-qualifier

Fix Predicates with not qualifiers
This commit is contained in:
Fabrice Reix 2020-10-19 20:11:20 +02:00 committed by GitHub
commit 121f83aa31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 295 additions and 157 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,8 @@ GET http://localhost:8000/assert-json
HTTP/1.0 200
[Asserts]
jsonpath "$.success" equals false
jsonpath "$.success" equals false
jsonpath "$.success" not equals null
jsonpath "$.success" exists
jsonpath "$.errors" countEquals 2
jsonpath "$.warnings" countEquals 0
jsonpath "$.toto" not exists

View File

@ -1,16 +1,26 @@
error: Assert Failure
--> tests/error_assert_query_cookie.hurl:4:0
--> tests/error_assert_query_cookie.hurl:7:0
|
4 | cookie "cookie1[Secure]" equals false # This is not valid, Secure attribute exists or not but does have a value
7 | cookie "cookie1[Secure]" equals false # This is not valid, Secure attribute exists or not but does have a value
| actual: none
| expected: bool <false>
|
error: Assert Failure
--> tests/error_assert_query_cookie.hurl:6:0
--> tests/error_assert_query_cookie.hurl:11:0
|
6 | cookie "cookie2[Secure]" equals true # This is not valid, Secure attribute exists or not but does have a value
11 | cookie "cookie2[Secure]" equals true # This is not valid, Secure attribute exists or not but does have a value
| actual: unit
| expected: bool <true>
| >>> types between actual and expected are not consistent
|
error: Assert Failure
--> tests/error_assert_query_cookie.hurl:12:0
|
12 | cookie "cookie2[Secure]" not equals true # This is not valid, Secure attribute exists or not but does have a value
| actual: unit
| expected: not bool <true>
| >>> types between actual and expected are not consistent
|

View File

@ -1,8 +1,15 @@
GET http://localhost:8000/error-assert-query-cookie
HTTP/1.0 200
[Asserts]
cookie "cookie1[Secure]" equals false # This is not valid, Secure attribute exists or not but does have a value
cookie "cookie1[Secure]" not exists
cookie "cookie2[Secure]" equals true # This is not valid, Secure attribute exists or not but does have a value
cookie "cookie2[Secure]" exists
[Asserts]
cookie "cookie1[Secure]" not exists
cookie "cookie1[Secure]" equals false # This is not valid, Secure attribute exists or not but does have a value
cookie "cookie1[Secure]" not equals true
cookie "cookie2[Secure]" exists
cookie "cookie2[Secure]" equals true # This is not valid, Secure attribute exists or not but does have a value
cookie "cookie2[Secure]" not equals true # This is not valid, Secure attribute exists or not but does have a value

View File

@ -22,3 +22,12 @@ error: Assert Failure
| expected: includes int <100>
|
error: Assert Failure
--> tests/error_assert_value_error.hurl:7:0
|
7 | jsonpath "$.values" not contains "Hello"
| actual: [int <1>, int <2>, int <3>]
| expected: not contains string <Hello>
| >>> types between actual and expected are not consistent
|

View File

@ -4,4 +4,4 @@ HTTP/1.0 200
header "content-type" equals "XXX"
jsonpath "$.id" equals "000001"
jsonpath "$.values" includes 100
jsonpath "$.values" not contains "Hello"

View File

@ -68,6 +68,7 @@ error: Assert Failure
13 | jsonpath "$.message" countEquals 1
| actual: string <0>
| expected: count equals to <1>
| >>> types between actual and expected are not consistent
|
error: Assert Failure

View File

@ -189,8 +189,18 @@ impl Error for runner::Error {
format!("The charset '{}' is not valid", charset)
}
RunnerError::AssertFailure {
actual, expected, ..
} => format!("actual: {}\nexpected: {}", actual, expected),
actual,
expected,
type_mismatch,
..
} => {
let additional = if *type_mismatch {
"\n>>> types between actual and expected are not consistent"
} else {
""
};
format!("actual: {}\nexpected: {}{}", actual, expected, additional)
}
RunnerError::VariableNotDefined { name } => {
format!("You must set the variable {}", name)
}

View File

@ -38,11 +38,13 @@ impl Predicate {
},
};
if assert_result.type_mismatch {
let not = if self.not { "not " } else { "" };
let expected = format!("{}{}", not, assert_result.expected);
Err(Error {
source_info,
inner: RunnerError::AssertFailure {
actual: assert_result.actual,
expected: assert_result.expected,
expected,
type_mismatch: true,
},
assert: true,
@ -112,12 +114,12 @@ impl PredicateFunc {
) -> Result<AssertResult, Error> {
match optional_value {
None => {
let type_mismatch = !matches!(self.value, PredicateFuncValue::Exist {});
//let type_mismatch = !matches!(self.value, PredicateFuncValue::Exist {});
Ok(AssertResult {
success: false,
actual: "none".to_string(),
expected: self.expected(variables)?,
type_mismatch,
type_mismatch: false,
})
}
Some(value) => self.eval_something(variables, value),
@ -454,12 +456,18 @@ fn assert_values_equal(actual: Value, expected: Value) -> Result<AssertResult, E
expected: expected.display(),
type_mismatch: false,
}),
_ => Ok(AssertResult {
(Value::Unit, _) => Ok(AssertResult {
success: false,
actual: actual.display(),
expected: expected.display(),
type_mismatch: true,
}),
_ => Ok(AssertResult {
success: false,
actual: actual.display(),
expected: expected.display(),
type_mismatch: false,
}),
}
}
@ -495,6 +503,13 @@ fn assert_include(value: Value, element: Value) -> Result<AssertResult, Error> {
mod tests {
use super::*;
fn whitespace() -> Whitespace {
Whitespace {
value: String::from(" "),
source_info: SourceInfo::init(0, 0, 0, 0),
}
}
#[test]
fn test_invalid_xpath() {}
@ -502,7 +517,7 @@ mod tests {
fn test_predicate() {
// not equals 10 with value 1 OK
// not equals 10 with value 10 ValueError
// not equals 10 with value true TypeError
// not equals 10 with value true => this is now valid
let variables = HashMap::new();
let whitespace = Whitespace {
value: String::from(" "),
@ -521,20 +536,10 @@ mod tests {
},
};
let error = predicate
assert!(predicate
.clone()
.eval(&variables, Some(Value::Bool(true)))
.err()
.unwrap();
assert_eq!(
error.inner,
RunnerError::AssertFailure {
actual: "bool <true>".to_string(),
expected: "int <10>".to_string(),
type_mismatch: true,
}
);
assert_eq!(error.source_info, SourceInfo::init(1, 0, 1, 0));
.is_ok());
let error = predicate
.clone()
@ -571,7 +576,7 @@ mod tests {
.eval(&variables, Some(Value::Bool(true)))
.unwrap();
assert_eq!(assert_result.success, false);
assert_eq!(assert_result.type_mismatch, true);
assert_eq!(assert_result.type_mismatch, false);
assert_eq!(assert_result.actual.as_str(), "bool <true>");
assert_eq!(assert_result.expected.as_str(), "int <10>");
}
@ -597,6 +602,7 @@ mod tests {
assert_eq!(assert_result.actual.as_str(), "unit");
assert_eq!(assert_result.expected.as_str(), "int <10>");
}
#[test]
fn test_predicate_value_error() {
let variables = HashMap::new();
@ -908,4 +914,94 @@ mod tests {
assert_eq!(assert_result.actual.as_str(), "nodeset of size <1>");
assert_eq!(assert_result.expected.as_str(), "count equals to <1>");
}
#[test]
fn test_predicate_not_with_different_types() {
// equals predicate does not generate a type error with an integer value
let predicate = Predicate {
not: true,
space0: whitespace(),
predicate_func: PredicateFunc {
source_info: SourceInfo::init(0, 0, 0, 0),
value: PredicateFuncValue::EqualNull {
space0: whitespace(),
},
},
};
let variables = HashMap::new();
assert!(predicate.eval(&variables, Some(Value::Integer(1))).is_ok());
//assert!(predicate.eval(&variables, None).is_ok());
// startswith predicate generates a type error with an integer value
let predicate = Predicate {
not: true,
space0: whitespace(),
predicate_func: PredicateFunc {
source_info: SourceInfo::init(0, 0, 0, 0),
value: PredicateFuncValue::StartWith {
space0: whitespace(),
value: Template {
quotes: false,
elements: vec![TemplateElement::String {
value: "toto".to_string(),
encoded: "toto".to_string(),
}],
source_info: SourceInfo::init(0, 0, 0, 0),
},
},
},
};
let error = predicate
.eval(&variables, Some(Value::Integer(1)))
.err()
.unwrap();
assert_eq!(
error.inner,
RunnerError::AssertFailure {
actual: "int <1>".to_string(),
expected: "not starts with string <toto>".to_string(),
type_mismatch: true
}
);
}
#[test]
fn test_no_type_mismatch_with_none_value() {
let predicate = Predicate {
not: false,
space0: whitespace(),
predicate_func: PredicateFunc {
source_info: SourceInfo::init(0, 0, 0, 0),
value: PredicateFuncValue::EqualNull {
space0: whitespace(),
},
},
};
let variables = HashMap::new();
let error = predicate.eval(&variables, None).err().unwrap();
assert_eq!(
error.inner,
RunnerError::AssertFailure {
actual: "none".to_string(),
expected: "null".to_string(),
type_mismatch: false
}
);
let predicate = Predicate {
not: true,
space0: whitespace(),
predicate_func: PredicateFunc {
source_info: SourceInfo::init(0, 0, 0, 0),
value: PredicateFuncValue::EqualNull {
space0: whitespace(),
},
},
};
let variables = HashMap::new();
assert!(predicate.eval(&variables, None).is_ok());
}
}