mirror of
https://github.com/uutils/coreutils
synced 2024-12-12 22:32:53 +00:00
Merge pull request #5978 from BenWiederhake/dev-shuf-multi
shuf: include all echo args, not just the last
This commit is contained in:
commit
a12d7c2b67
2 changed files with 166 additions and 3 deletions
|
@ -120,7 +120,6 @@ pub fn uu_app() -> Command {
|
|||
.version(crate_version!())
|
||||
.override_usage(format_usage(USAGE))
|
||||
.infer_long_args(true)
|
||||
.args_override_self(true)
|
||||
.arg(
|
||||
Arg::new(options::ECHO)
|
||||
.short('e')
|
||||
|
@ -129,6 +128,7 @@ pub fn uu_app() -> Command {
|
|||
.help("treat each ARG as an input line")
|
||||
.use_value_delimiter(false)
|
||||
.num_args(0..)
|
||||
.action(clap::ArgAction::Append)
|
||||
.conflicts_with(options::INPUT_RANGE),
|
||||
)
|
||||
.arg(
|
||||
|
@ -144,6 +144,7 @@ pub fn uu_app() -> Command {
|
|||
.short('n')
|
||||
.long(options::HEAD_COUNT)
|
||||
.value_name("COUNT")
|
||||
.action(clap::ArgAction::Append)
|
||||
.help("output at most COUNT lines"),
|
||||
)
|
||||
.arg(
|
||||
|
@ -166,14 +167,16 @@ pub fn uu_app() -> Command {
|
|||
.short('r')
|
||||
.long(options::REPEAT)
|
||||
.help("output lines can be repeated")
|
||||
.action(ArgAction::SetTrue),
|
||||
.action(ArgAction::SetTrue)
|
||||
.overrides_with(options::REPEAT),
|
||||
)
|
||||
.arg(
|
||||
Arg::new(options::ZERO_TERMINATED)
|
||||
.short('z')
|
||||
.long(options::ZERO_TERMINATED)
|
||||
.help("line delimiter is NUL, not newline")
|
||||
.action(ArgAction::SetTrue),
|
||||
.action(ArgAction::SetTrue)
|
||||
.overrides_with(options::ZERO_TERMINATED),
|
||||
)
|
||||
.arg(Arg::new(options::FILE).value_hint(clap::ValueHint::FilePath))
|
||||
}
|
||||
|
|
|
@ -48,6 +48,22 @@ fn test_zero_termination() {
|
|||
assert_eq!(result_seq, input_seq, "Output is not a permutation");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_termination_multi() {
|
||||
let input_seq = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
let result = new_ucmd!().arg("-z").arg("-z").arg("-i1-10").succeeds();
|
||||
result.no_stderr();
|
||||
|
||||
let mut result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split('\0')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
result_seq.sort_unstable();
|
||||
assert_eq!(result_seq, input_seq, "Output is not a permutation");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_input() {
|
||||
let result = new_ucmd!().pipe_in(vec![]).succeeds();
|
||||
|
@ -79,6 +95,27 @@ fn test_echo() {
|
|||
assert_eq!(result_seq, input_seq, "Output is not a permutation");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_echo_multi() {
|
||||
let result = new_ucmd!()
|
||||
.arg("-e")
|
||||
.arg("a")
|
||||
.arg("b")
|
||||
.arg("-e")
|
||||
.arg("c")
|
||||
.succeeds();
|
||||
result.no_stderr();
|
||||
|
||||
let mut result_seq: Vec<String> = result
|
||||
.stdout_str()
|
||||
.split('\n')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.into())
|
||||
.collect();
|
||||
result_seq.sort_unstable();
|
||||
assert_eq!(result_seq, ["a", "b", "c"], "Output is not a permutation");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_head_count() {
|
||||
let repeat_limit = 5;
|
||||
|
@ -110,6 +147,72 @@ fn test_head_count() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_head_count_multi_big_then_small() {
|
||||
let repeat_limit = 5;
|
||||
let input_seq = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
let input = input_seq
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("-n")
|
||||
.arg(&(repeat_limit + 1).to_string())
|
||||
.arg("-n")
|
||||
.arg(&repeat_limit.to_string())
|
||||
.pipe_in(input.as_bytes())
|
||||
.succeeds();
|
||||
result.no_stderr();
|
||||
|
||||
let result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split('\n')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
assert_eq!(result_seq.len(), repeat_limit, "Output is not limited");
|
||||
assert!(
|
||||
result_seq.iter().all(|x| input_seq.contains(x)),
|
||||
"Output includes element not from input: {}",
|
||||
result.stdout_str()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_head_count_multi_small_then_big() {
|
||||
let repeat_limit = 5;
|
||||
let input_seq = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
let input = input_seq
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("-n")
|
||||
.arg(&repeat_limit.to_string())
|
||||
.arg("-n")
|
||||
.arg(&(repeat_limit + 1).to_string())
|
||||
.pipe_in(input.as_bytes())
|
||||
.succeeds();
|
||||
result.no_stderr();
|
||||
|
||||
let result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split('\n')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
assert_eq!(result_seq.len(), repeat_limit, "Output is not limited");
|
||||
assert!(
|
||||
result_seq.iter().all(|x| input_seq.contains(x)),
|
||||
"Output includes element not from input: {}",
|
||||
result.stdout_str()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeat() {
|
||||
let repeat_limit = 15000;
|
||||
|
@ -148,6 +251,45 @@ fn test_repeat() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeat_multi() {
|
||||
let repeat_limit = 15000;
|
||||
let input_seq = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
let input = input_seq
|
||||
.iter()
|
||||
.map(ToString::to_string)
|
||||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("-r")
|
||||
.arg("-r") // The only difference to test_repeat()
|
||||
.args(&["-n", &repeat_limit.to_string()])
|
||||
.pipe_in(input.as_bytes())
|
||||
.succeeds();
|
||||
result.no_stderr();
|
||||
|
||||
let result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split('\n')
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
assert_eq!(
|
||||
result_seq.len(),
|
||||
repeat_limit,
|
||||
"Output is not repeating forever"
|
||||
);
|
||||
assert!(
|
||||
result_seq.iter().all(|x| input_seq.contains(x)),
|
||||
"Output includes element not from input: {:?}",
|
||||
result_seq
|
||||
.iter()
|
||||
.filter(|x| !input_seq.contains(x))
|
||||
.collect::<Vec<&i32>>()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file_input() {
|
||||
let expected_seq = vec![11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
|
||||
|
@ -205,6 +347,24 @@ fn test_shuf_invalid_input_range_three() {
|
|||
.stderr_contains("invalid input range: 'b'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shuf_multiple_input_ranges() {
|
||||
new_ucmd!()
|
||||
.args(&["-i", "2-9", "-i", "2-9"])
|
||||
.fails()
|
||||
.stderr_contains("--input-range")
|
||||
.stderr_contains("cannot be used multiple times");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shuf_multiple_outputs() {
|
||||
new_ucmd!()
|
||||
.args(&["-o", "file_a", "-o", "file_b"])
|
||||
.fails()
|
||||
.stderr_contains("--output")
|
||||
.stderr_contains("cannot be used multiple times");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shuf_invalid_input_line_count() {
|
||||
new_ucmd!()
|
||||
|
|
Loading…
Reference in a new issue