Skip to content

Commit 23ed61e

Browse files
eyupcanakmanhurl-bot
authored andcommitted
Fix misleading error message for not-equal predicate
1 parent 9e91a78 commit 23ed61e

3 files changed

Lines changed: 101 additions & 13 deletions

File tree

integration/hurl/tests_failed/assert_value_error/assert_value_error.err

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ error: Assert failure
1515
| ...
1616
5 | header "content-type" != "text/html; charset=utf-8"
1717
| actual: string <text/html; charset=utf-8>
18-
| expected: string <text/html; charset=utf-8>
18+
| expected: not string <text/html; charset=utf-8>
1919
|
2020

2121
error: Assert failure

integration/hurl/tests_failed/assert_value_error/assert_value_error.out.pattern

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
{
2020
"line": 5,
21-
"message": "Assert failure\n --> tests_failed/assert_value_error/assert_value_error.hurl:5:0\n |\n | GET http://localhost:8000/error-assert-value\n | ...\n 5 | header \"content-type\" != \"text/html; charset=utf-8\"\n | actual: string <text/html; charset=utf-8>\n | expected: string <text/html; charset=utf-8>\n |",
21+
"message": "Assert failure\n --> tests_failed/assert_value_error/assert_value_error.hurl:5:0\n |\n | GET http://localhost:8000/error-assert-value\n | ...\n 5 | header \"content-type\" != \"text/html; charset=utf-8\"\n | actual: string <text/html; charset=utf-8>\n | expected: not string <text/html; charset=utf-8>\n |",
2222
"success": false
2323
},
2424
{

packages/hurl/src/runner/predicate.rs

Lines changed: 99 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,26 +65,28 @@ pub fn eval_predicate(
6565
Pos::new(predicate.space0.source_info.start.line, 0),
6666
);
6767

68+
// `!=` already negates equality, so combine it with the `not` qualifier (XOR) for the prefix.
69+
let negated = predicate.not
70+
^ matches!(
71+
predicate.predicate_func.value,
72+
PredicateFuncValue::NotEqual { .. }
73+
);
74+
let not = if negated { "not " } else { "" };
75+
6876
if result.type_mismatch {
69-
let not = if predicate.not { "not " } else { "" };
70-
let expected = format!("{}{}", not, result.expected);
77+
let expected = format!("{not}{}", result.expected);
7178
let kind = RunnerErrorKind::AssertFailure {
7279
actual: result.actual,
7380
expected,
7481
type_mismatch: true,
7582
};
7683
Err(RunnerError::new(source_info, kind, true))
77-
} else if predicate.not && result.success {
78-
let kind = RunnerErrorKind::AssertFailure {
79-
actual: result.actual,
80-
expected: format!("not {}", result.expected),
81-
type_mismatch: false,
82-
};
83-
Err(RunnerError::new(source_info, kind, true))
84-
} else if !predicate.not && !result.success {
84+
} else if predicate.not == result.success {
85+
// Fail when the `not` qualifier and the predicate outcome agree.
86+
let expected = format!("{not}{}", result.expected);
8587
let kind = RunnerErrorKind::AssertFailure {
8688
actual: result.actual,
87-
expected: result.expected,
89+
expected,
8890
type_mismatch: false,
8991
};
9092
Err(RunnerError::new(source_info, kind, true))
@@ -900,6 +902,92 @@ mod tests {
900902
);
901903
}
902904

905+
#[test]
906+
fn test_predicate_not_equal_error_message() {
907+
// A failing `!=` assert reports the value that should not have matched (#2841).
908+
let variables = VariableSet::new();
909+
let current_dir = Path::new("/home");
910+
let file_root = Path::new("file_root");
911+
let context_dir = ContextDir::new(current_dir, file_root);
912+
913+
// predicate: `!= 1`
914+
let predicate = Predicate {
915+
not: false,
916+
space0: whitespace(),
917+
predicate_func: PredicateFunc {
918+
value: PredicateFuncValue::NotEqual {
919+
space0: whitespace(),
920+
value: PredicateValue::Number(hurl_core::ast::Number::Integer(I64::new(
921+
1,
922+
"1".to_source(),
923+
))),
924+
},
925+
source_info: SourceInfo::new(Pos::new(1, 11), Pos::new(1, 13)),
926+
},
927+
};
928+
929+
// value: 1 => fails, expected is the negated value
930+
let error = eval_predicate(
931+
&predicate,
932+
&variables,
933+
&Some(Value::Number(Number::Integer(1))),
934+
&context_dir,
935+
)
936+
.unwrap_err();
937+
assert_eq!(
938+
error.kind,
939+
RunnerErrorKind::AssertFailure {
940+
actual: "integer <1>".to_string(),
941+
expected: "not integer <1>".to_string(),
942+
type_mismatch: false,
943+
}
944+
);
945+
946+
// no value => fails, the negated value is still reported
947+
let error = eval_predicate(&predicate, &variables, &None, &context_dir).unwrap_err();
948+
assert_eq!(
949+
error.kind,
950+
RunnerErrorKind::AssertFailure {
951+
actual: "none".to_string(),
952+
expected: "not integer <1>".to_string(),
953+
type_mismatch: false,
954+
}
955+
);
956+
957+
// predicate: `not != 1`, the two negations cancel
958+
let predicate = Predicate {
959+
not: true,
960+
space0: whitespace(),
961+
predicate_func: PredicateFunc {
962+
value: PredicateFuncValue::NotEqual {
963+
space0: whitespace(),
964+
value: PredicateValue::Number(hurl_core::ast::Number::Integer(I64::new(
965+
1,
966+
"1".to_source(),
967+
))),
968+
},
969+
source_info: SourceInfo::new(Pos::new(1, 11), Pos::new(1, 13)),
970+
},
971+
};
972+
973+
// value: 2 => fails, no `not` prefix
974+
let error = eval_predicate(
975+
&predicate,
976+
&variables,
977+
&Some(Value::Number(Number::Integer(2))),
978+
&context_dir,
979+
)
980+
.unwrap_err();
981+
assert_eq!(
982+
error.kind,
983+
RunnerErrorKind::AssertFailure {
984+
actual: "integer <2>".to_string(),
985+
expected: "integer <1>".to_string(),
986+
type_mismatch: false,
987+
}
988+
);
989+
}
990+
903991
#[test]
904992
fn test_predicate_type_mismatch() {
905993
let variables = VariableSet::new();

0 commit comments

Comments
 (0)