test: Implement [ expr ] syntax

When invoked via '[' name, last argument must be ']' or we bail out with
syntax error. Then the trailing ']' is simply disregarded and processing
happens like usual.
This commit is contained in:
Tuomas Tynkkynen 2021-06-18 16:56:00 +03:00
parent 7739080e6e
commit 7b9814c778
3 changed files with 68 additions and 3 deletions

View file

@ -54,6 +54,29 @@ pub fn main() {
for krate in crates {
match krate.as_ref() {
// 'test' is named uu_test to avoid collision with rust core crate 'test'.
// It can also be invoked by name '[' for the '[ expr ] syntax'.
"uu_test" => {
mf.write_all(
format!(
"\
\tmap.insert(\"test\", {krate}::uumain);\n\
\t\tmap.insert(\"[\", {krate}::uumain);\n\
",
krate = krate
)
.as_bytes(),
)
.unwrap();
tf.write_all(
format!(
"#[path=\"{dir}/test_test.rs\"]\nmod test_test;\n",
dir = util_tests_dir,
)
.as_bytes(),
)
.unwrap()
}
k if k.starts_with(override_prefix) => {
mf.write_all(
format!(

View file

@ -12,10 +12,24 @@ mod parser;
use parser::{parse, Symbol};
use std::ffi::{OsStr, OsString};
use std::path::Path;
pub fn uumain(args: impl uucore::Args) -> i32 {
// TODO: handle being called as `[`
let args: Vec<_> = args.skip(1).collect();
pub fn uumain(mut args: impl uucore::Args) -> i32 {
let program = args.next().unwrap_or_else(|| OsString::from("test"));
let binary_name = Path::new(&program)
.file_name()
.unwrap_or_else(|| OsStr::new("test"))
.to_string_lossy();
let mut args: Vec<_> = args.collect();
// If invoked via name '[', matching ']' must be in the last arg
if binary_name == "[" {
let last = args.pop();
if last != Some(OsString::from("]")) {
eprintln!("[: missing ']'");
return 2;
}
}
let result = parse(args).and_then(|mut stack| eval(&mut stack));

View file

@ -690,3 +690,31 @@ fn test_or_as_filename() {
fn test_string_length_and_nothing() {
new_ucmd!().args(&["-n", "a", "-a"]).run().status_code(2);
}
#[test]
fn test_bracket_syntax_success() {
let scenario = TestScenario::new("[");
let mut ucmd = scenario.ucmd();
ucmd.args(&["1", "-eq", "1", "]"]).succeeds();
}
#[test]
fn test_bracket_syntax_failure() {
let scenario = TestScenario::new("[");
let mut ucmd = scenario.ucmd();
ucmd.args(&["1", "-eq", "2", "]"]).run().status_code(1);
}
#[test]
fn test_bracket_syntax_missing_right_bracket() {
let scenario = TestScenario::new("[");
let mut ucmd = scenario.ucmd();
// Missing closing bracket takes precedence over other possible errors.
ucmd.args(&["1", "-eq"])
.run()
.status_code(2)
.stderr_is("[: missing ']'");
}