diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs index 57acb7fac..968682a26 100644 --- a/src/uu/tr/src/tr.rs +++ b/src/uu/tr/src/tr.rs @@ -164,20 +164,23 @@ pub fn uu_app() -> Command { .about(ABOUT) .override_usage(format_usage(USAGE)) .infer_long_args(true) + .trailing_var_arg(true) .arg( Arg::new(options::COMPLEMENT) .visible_short_alias('C') .short('c') .long(options::COMPLEMENT) .help("use the complement of SET1") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .overrides_with(options::COMPLEMENT), ) .arg( Arg::new(options::DELETE) .short('d') .long(options::DELETE) .help("delete characters in SET1, do not translate") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .overrides_with(options::DELETE), ) .arg( Arg::new(options::SQUEEZE) @@ -188,14 +191,16 @@ pub fn uu_app() -> Command { listed in the last specified SET, with a single occurrence \ of that character", ) - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .overrides_with(options::SQUEEZE), ) .arg( Arg::new(options::TRUNCATE_SET1) .long(options::TRUNCATE_SET1) .short('t') .help("first truncate SET1 to length of SET2") - .action(ArgAction::SetTrue), + .action(ArgAction::SetTrue) + .overrides_with(options::TRUNCATE_SET1), ) .arg(Arg::new(options::SETS).num_args(1..)) } diff --git a/tests/by-util/test_tr.rs b/tests/by-util/test_tr.rs index bf589a5c5..6adbc4022 100644 --- a/tests/by-util/test_tr.rs +++ b/tests/by-util/test_tr.rs @@ -46,6 +46,32 @@ fn test_delete() { .stdout_is("BD"); } +#[test] +fn test_delete_afterwards_is_not_flag() { + new_ucmd!() + .args(&["a-z", "-d"]) + .pipe_in("aBcD") + .succeeds() + .stdout_is("-BdD"); +} + +#[test] +fn test_delete_multi() { + new_ucmd!() + .args(&["-d", "-d", "a-z"]) + .pipe_in("aBcD") + .succeeds() + .stdout_is("BD"); +} + +#[test] +fn test_delete_late() { + new_ucmd!() + .args(&["-d", "a-z", "-d"]) + .fails() + .stderr_contains("extra operand '-d'"); +} + #[test] fn test_delete_complement() { new_ucmd!() @@ -78,6 +104,14 @@ fn test_complement1() { .stdout_is("aX"); } +#[test] +fn test_complement_afterwards_is_not_flag() { + new_ucmd!() + .args(&["a", "X", "-c"]) + .fails() + .stderr_contains("extra operand '-c'"); +} + #[test] fn test_complement2() { new_ucmd!() @@ -118,12 +152,46 @@ fn test_complement5() { .stdout_is("0a1b2c3"); } +#[test] +fn test_complement_multi_early() { + new_ucmd!() + .args(&["-c", "-c", "a", "X"]) + .pipe_in("ab") + .succeeds() + .stdout_is("aX"); +} + +#[test] +fn test_complement_multi_middle() { + new_ucmd!() + .args(&["-c", "a", "-c", "X"]) + .fails() + .stderr_contains("tr: extra operand 'X'"); +} + +#[test] +fn test_complement_multi_late() { + new_ucmd!() + .args(&["-c", "a", "X", "-c"]) + .fails() + .stderr_contains("tr: extra operand '-c'"); +} + #[test] fn test_squeeze() { new_ucmd!() .args(&["-s", "a-z"]) .pipe_in("aaBBcDcc") - .run() + .succeeds() + .stdout_is("aBBcDc"); +} + +#[test] +fn test_squeeze_multi() { + new_ucmd!() + .args(&["-ss", "-s", "a-z"]) + .pipe_in("aaBBcDcc") + .succeeds() .stdout_is("aBBcDc"); } @@ -132,7 +200,16 @@ fn test_squeeze_complement() { new_ucmd!() .args(&["-sc", "a-z"]) .pipe_in("aaBBcDcc") - .run() + .succeeds() + .stdout_is("aaBcDcc"); +} + +#[test] +fn test_squeeze_complement_multi() { + new_ucmd!() + .args(&["-scsc", "a-z"]) // spell-checker:disable-line + .pipe_in("aaBBcDcc") + .succeeds() .stdout_is("aaBcDcc"); } @@ -223,7 +300,16 @@ fn test_truncate() { new_ucmd!() .args(&["-t", "abc", "xy"]) .pipe_in("abcde") - .run() + .succeeds() + .stdout_is("xycde"); // spell-checker:disable-line +} + +#[test] +fn test_truncate_multi() { + new_ucmd!() + .args(&["-tt", "-t", "abc", "xy"]) + .pipe_in("abcde") + .succeeds() .stdout_is("xycde"); // spell-checker:disable-line }