mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
test: improve handling of inverted Boolean expressions
- add `==` as undocumented alias of `=` - handle negated comparison of `=` as literal - negation generally applies to only the first expression of a Boolean chain, except when combining evaluation of two literal strings
This commit is contained in:
parent
ed42652803
commit
2ec4bee350
3 changed files with 158 additions and 25 deletions
|
@ -122,6 +122,13 @@ fn test_zero_len_not_equals_zero_len_is_false() {
|
|||
new_ucmd!().args(&["", "!=", ""]).run().status_code(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_equal_is_string_comparison_op() {
|
||||
// undocumented but part of the GNU test suite
|
||||
new_ucmd!().args(&["t", "==", "t"]).succeeds();
|
||||
new_ucmd!().args(&["t", "==", "f"]).run().status_code(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string_comparison() {
|
||||
let scenario = TestScenario::new(util_name!());
|
||||
|
@ -131,11 +138,22 @@ fn test_string_comparison() {
|
|||
["(", "=", "("],
|
||||
["(", "!=", ")"],
|
||||
["!", "=", "!"],
|
||||
["=", "=", "="],
|
||||
];
|
||||
|
||||
for test in &tests {
|
||||
scenario.ucmd().args(&test[..]).succeeds();
|
||||
}
|
||||
|
||||
// run the inverse of all these tests
|
||||
for test in &tests {
|
||||
scenario
|
||||
.ucmd()
|
||||
.arg("!")
|
||||
.args(&test[..])
|
||||
.run()
|
||||
.status_code(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -485,6 +503,81 @@ fn test_op_prec_and_or_2_overridden_by_parentheses() {
|
|||
.status_code(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_negated_boolean_precedence() {
|
||||
let scenario = TestScenario::new(util_name!());
|
||||
|
||||
let tests = [
|
||||
vec!["!", "(", "foo", ")", "-o", "bar"],
|
||||
vec!["!", "", "-o", "", "-a", ""],
|
||||
vec!["!", "(", "", "-a", "", ")", "-o", ""],
|
||||
];
|
||||
|
||||
for test in &tests {
|
||||
scenario.ucmd().args(&test[..]).succeeds();
|
||||
}
|
||||
|
||||
let negative_tests = [
|
||||
vec!["!", "-n", "", "-a", ""],
|
||||
vec!["", "-a", "", "-o", ""],
|
||||
vec!["!", "", "-a", "", "-o", ""],
|
||||
vec!["!", "(", "", "-a", "", ")", "-a", ""],
|
||||
];
|
||||
|
||||
for test in &negative_tests {
|
||||
scenario.ucmd().args(&test[..]).run().status_code(1);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bang_boolop_precedence() {
|
||||
// For a Boolean combination of two literals, bang inverts the entire expression
|
||||
new_ucmd!().args(&["!", "", "-a", ""]).succeeds();
|
||||
new_ucmd!().args(&["!", "", "-o", ""]).succeeds();
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["!", "a value", "-o", "another value"])
|
||||
.run()
|
||||
.status_code(1);
|
||||
|
||||
// Introducing a UOP — even one that is equivalent to a bare string — causes
|
||||
// bang to invert only the first term
|
||||
new_ucmd!()
|
||||
.args(&["!", "-n", "", "-a", ""])
|
||||
.run()
|
||||
.status_code(1);
|
||||
new_ucmd!()
|
||||
.args(&["!", "", "-a", "-n", ""])
|
||||
.run()
|
||||
.status_code(1);
|
||||
|
||||
// for compound Boolean expressions, bang inverts the _next_ expression
|
||||
// only, not the entire compound expression
|
||||
new_ucmd!()
|
||||
.args(&["!", "", "-a", "", "-a", ""])
|
||||
.run()
|
||||
.status_code(1);
|
||||
|
||||
// parentheses can override this
|
||||
new_ucmd!()
|
||||
.args(&["!", "(", "", "-a", "", "-a", "", ")"])
|
||||
.succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_inverted_parenthetical_boolop_precedence() {
|
||||
// For a Boolean combination of two literals, bang inverts the entire expression
|
||||
new_ucmd!()
|
||||
.args(&["!", "a value", "-o", "another value"])
|
||||
.run()
|
||||
.status_code(1);
|
||||
|
||||
// only the parenthetical is inverted, not the entire expression
|
||||
new_ucmd!()
|
||||
.args(&["!", "(", "a value", ")", "-o", "another value"])
|
||||
.succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore = "fixme: error reporting"]
|
||||
fn test_dangling_parenthesis() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue