mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-02 05:57:46 +00:00
Merge branch 'master' into id_selinux_context
This commit is contained in:
commit
010565c8fb
54 changed files with 2013 additions and 691 deletions
|
@ -398,8 +398,7 @@ fn test_du_time() {
|
|||
let result = ts.ucmd().arg("--time=ctime").arg("date_test").succeeds();
|
||||
result.stdout_only("0\t2016-06-16 00:00\tdate_test\n");
|
||||
|
||||
#[cfg(not(target_env = "musl"))]
|
||||
{
|
||||
if birth_supported() {
|
||||
use regex::Regex;
|
||||
|
||||
let re_birth =
|
||||
|
@ -409,6 +408,16 @@ fn test_du_time() {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "touch")]
|
||||
fn birth_supported() -> bool {
|
||||
let ts = TestScenario::new(util_name!());
|
||||
let m = match std::fs::metadata(ts.fixtures.subdir) {
|
||||
Ok(m) => m,
|
||||
Err(e) => panic!("{}", e),
|
||||
};
|
||||
m.created().is_ok()
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[cfg(feature = "chmod")]
|
||||
#[test]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::common::util::*;
|
||||
// spell-checker:ignore (ToDO) taaaa tbbbb tcccc
|
||||
|
||||
#[test]
|
||||
fn test_with_tab() {
|
||||
|
@ -53,3 +54,140 @@ fn test_with_multiple_files() {
|
|||
.stdout_contains(" return")
|
||||
.stdout_contains(" ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_space_separated_list() {
|
||||
new_ucmd!()
|
||||
.args(&["--tabs", "3 6 9"])
|
||||
.pipe_in("a\tb\tc\td\te")
|
||||
.succeeds()
|
||||
.stdout_is("a b c d e");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_mixed_style_list() {
|
||||
new_ucmd!()
|
||||
.args(&["--tabs", ", 3,6 9"])
|
||||
.pipe_in("a\tb\tc\td\te")
|
||||
.succeeds()
|
||||
.stdout_is("a b c d e");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_empty_string() {
|
||||
new_ucmd!()
|
||||
.args(&["--tabs", ""])
|
||||
.pipe_in("a\tb\tc")
|
||||
.succeeds()
|
||||
.stdout_is("a b c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_comma_only() {
|
||||
new_ucmd!()
|
||||
.args(&["--tabs", ","])
|
||||
.pipe_in("a\tb\tc")
|
||||
.succeeds()
|
||||
.stdout_is("a b c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_space_only() {
|
||||
new_ucmd!()
|
||||
.args(&["--tabs", " "])
|
||||
.pipe_in("a\tb\tc")
|
||||
.succeeds()
|
||||
.stdout_is("a b c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_slash() {
|
||||
new_ucmd!()
|
||||
.args(&["--tabs", "/"])
|
||||
.pipe_in("a\tb\tc")
|
||||
.succeeds()
|
||||
.stdout_is("a b c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_plus() {
|
||||
new_ucmd!()
|
||||
.args(&["--tabs", "+"])
|
||||
.pipe_in("a\tb\tc")
|
||||
.succeeds()
|
||||
.stdout_is("a b c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_trailing_slash() {
|
||||
new_ucmd!()
|
||||
.arg("--tabs=1,/5")
|
||||
.pipe_in("\ta\tb\tc")
|
||||
.succeeds()
|
||||
// 0 1
|
||||
// 01234567890
|
||||
.stdout_is(" a b c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_trailing_slash_long_columns() {
|
||||
new_ucmd!()
|
||||
.arg("--tabs=1,/3")
|
||||
.pipe_in("\taaaa\tbbbb\tcccc")
|
||||
.succeeds()
|
||||
// 0 1
|
||||
// 01234567890123456
|
||||
.stdout_is(" aaaa bbbb cccc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_trailing_plus() {
|
||||
new_ucmd!()
|
||||
.arg("--tabs=1,+5")
|
||||
.pipe_in("\ta\tb\tc")
|
||||
.succeeds()
|
||||
// 0 1
|
||||
// 012345678901
|
||||
.stdout_is(" a b c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_trailing_plus_long_columns() {
|
||||
new_ucmd!()
|
||||
.arg("--tabs=1,+3")
|
||||
.pipe_in("\taaaa\tbbbb\tcccc")
|
||||
.succeeds()
|
||||
// 0 1
|
||||
// 012345678901234567
|
||||
.stdout_is(" aaaa bbbb cccc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_must_be_ascending() {
|
||||
new_ucmd!()
|
||||
.arg("--tabs=1,1")
|
||||
.fails()
|
||||
.stderr_contains("tab sizes must be ascending");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_keep_last_trailing_specifier() {
|
||||
// If there are multiple trailing specifiers, use only the last one
|
||||
// before the number.
|
||||
new_ucmd!()
|
||||
.arg("--tabs=1,+/+/5")
|
||||
.pipe_in("\ta\tb\tc")
|
||||
.succeeds()
|
||||
// 0 1
|
||||
// 01234567890
|
||||
.stdout_is(" a b c");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tabs_comma_separated_no_numbers() {
|
||||
new_ucmd!()
|
||||
.arg("--tabs=+,/,+,/")
|
||||
.pipe_in("\ta\tb\tc")
|
||||
.succeeds()
|
||||
.stdout_is(" a b c");
|
||||
}
|
||||
|
|
|
@ -110,3 +110,8 @@ fn test_sleep_sum_duration_many() {
|
|||
let duration = before_test.elapsed();
|
||||
assert!(duration >= millis_900);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sleep_wrong_time() {
|
||||
new_ucmd!().args(&["0.1s", "abc"]).fails();
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ fn test_check_zero_terminated_failure() {
|
|||
.arg("-c")
|
||||
.arg("zero-terminated.txt")
|
||||
.fails()
|
||||
.stdout_is("sort: zero-terminated.txt:2: disorder: ../../fixtures/du\n");
|
||||
.stderr_only("sort: zero-terminated.txt:2: disorder: ../../fixtures/du\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -220,32 +220,29 @@ fn test_random_shuffle_contains_all_lines() {
|
|||
|
||||
#[test]
|
||||
fn test_random_shuffle_two_runs_not_the_same() {
|
||||
// check to verify that two random shuffles are not equal; this has the
|
||||
// potential to fail in the very unlikely event that the random order is the same
|
||||
// as the starting order, or if both random sorts end up having the same order.
|
||||
const FILE: &str = "default_unsorted_ints.expected";
|
||||
let (at, _ucmd) = at_and_ucmd!();
|
||||
let result = new_ucmd!().arg("-R").arg(FILE).run().stdout_move_str();
|
||||
let expected = at.read(FILE);
|
||||
let unexpected = new_ucmd!().arg("-R").arg(FILE).run().stdout_move_str();
|
||||
for arg in &["-R", "-k1,1R"] {
|
||||
// check to verify that two random shuffles are not equal; this has the
|
||||
// potential to fail in the very unlikely event that the random order is the same
|
||||
// as the starting order, or if both random sorts end up having the same order.
|
||||
const FILE: &str = "default_unsorted_ints.expected";
|
||||
let (at, _ucmd) = at_and_ucmd!();
|
||||
let result = new_ucmd!().arg(arg).arg(FILE).run().stdout_move_str();
|
||||
let expected = at.read(FILE);
|
||||
let unexpected = new_ucmd!().arg(arg).arg(FILE).run().stdout_move_str();
|
||||
|
||||
assert_ne!(result, expected);
|
||||
assert_ne!(result, unexpected);
|
||||
assert_ne!(result, expected);
|
||||
assert_ne!(result, unexpected);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_random_shuffle_contains_two_runs_not_the_same() {
|
||||
// check to verify that two random shuffles are not equal; this has the
|
||||
// potential to fail in the unlikely event that random order is the same
|
||||
// as the starting order, or if both random sorts end up having the same order.
|
||||
const FILE: &str = "default_unsorted_ints.expected";
|
||||
let (at, _ucmd) = at_and_ucmd!();
|
||||
let result = new_ucmd!().arg("-R").arg(FILE).run().stdout_move_str();
|
||||
let expected = at.read(FILE);
|
||||
let unexpected = new_ucmd!().arg("-R").arg(FILE).run().stdout_move_str();
|
||||
|
||||
assert_ne!(result, expected);
|
||||
assert_ne!(result, unexpected);
|
||||
fn test_random_ignore_case() {
|
||||
let input = "ABC\nABc\nAbC\nAbc\naBC\naBc\nabC\nabc\n";
|
||||
new_ucmd!()
|
||||
.args(&["-fR"])
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_is(input);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -774,14 +771,15 @@ fn test_check() {
|
|||
new_ucmd!()
|
||||
.arg(diagnose_arg)
|
||||
.arg("check_fail.txt")
|
||||
.arg("--buffer-size=10b")
|
||||
.fails()
|
||||
.stdout_is("sort: check_fail.txt:6: disorder: 5\n");
|
||||
.stderr_only("sort: check_fail.txt:6: disorder: 5\n");
|
||||
|
||||
new_ucmd!()
|
||||
.arg(diagnose_arg)
|
||||
.arg("multiple_files.expected")
|
||||
.succeeds()
|
||||
.stdout_is("");
|
||||
.stderr_is("");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -796,6 +794,18 @@ fn test_check_silent() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_check_unique() {
|
||||
// Due to a clap bug the combination "-cu" does not work. "-c -u" works.
|
||||
// See https://github.com/clap-rs/clap/issues/2624
|
||||
new_ucmd!()
|
||||
.args(&["-c", "-u"])
|
||||
.pipe_in("A\nA\n")
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only("sort: -:2: disorder: A");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dictionary_and_nonprinting_conflicts() {
|
||||
let conflicting_args = ["n", "h", "g", "M"];
|
||||
|
@ -839,9 +849,9 @@ fn test_nonexistent_file() {
|
|||
.status_code(2)
|
||||
.stderr_only(
|
||||
#[cfg(not(windows))]
|
||||
"sort: cannot read: \"nonexistent.txt\": No such file or directory (os error 2)",
|
||||
"sort: cannot read: nonexistent.txt: No such file or directory",
|
||||
#[cfg(windows)]
|
||||
"sort: cannot read: \"nonexistent.txt\": The system cannot find the file specified. (os error 2)",
|
||||
"sort: cannot read: nonexistent.txt: The system cannot find the file specified.",
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -883,6 +893,29 @@ fn test_compress() {
|
|||
.stdout_only_fixture("ext_sort.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_compress_merge() {
|
||||
new_ucmd!()
|
||||
.args(&[
|
||||
"--compress-program",
|
||||
"gzip",
|
||||
"-S",
|
||||
"10",
|
||||
"--batch-size=2",
|
||||
"-m",
|
||||
"--unique",
|
||||
"merge_ints_interleaved_1.txt",
|
||||
"merge_ints_interleaved_2.txt",
|
||||
"merge_ints_interleaved_3.txt",
|
||||
"merge_ints_interleaved_3.txt",
|
||||
"merge_ints_interleaved_2.txt",
|
||||
"merge_ints_interleaved_1.txt",
|
||||
])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("merge_ints_interleaved.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compress_fail() {
|
||||
TestScenario::new(util_name!())
|
||||
|
@ -959,3 +992,102 @@ fn test_key_takes_one_arg() {
|
|||
.succeeds()
|
||||
.stdout_is_fixture("keys_open_ended.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verifies_out_file() {
|
||||
let inputs = ["" /* no input */, "some input"];
|
||||
for &input in &inputs {
|
||||
new_ucmd!()
|
||||
.args(&["-o", "nonexistent_dir/nonexistent_file"])
|
||||
.pipe_in(input)
|
||||
.ignore_stdin_write_error()
|
||||
.fails()
|
||||
.status_code(2)
|
||||
.stderr_only(
|
||||
#[cfg(not(windows))]
|
||||
"sort: open failed: nonexistent_dir/nonexistent_file: No such file or directory",
|
||||
#[cfg(windows)]
|
||||
"sort: open failed: nonexistent_dir/nonexistent_file: The system cannot find the path specified.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verifies_files_after_keys() {
|
||||
new_ucmd!()
|
||||
.args(&[
|
||||
"-o",
|
||||
"nonexistent_dir/nonexistent_file",
|
||||
"-k",
|
||||
"0",
|
||||
"nonexistent_dir/input_file",
|
||||
])
|
||||
.fails()
|
||||
.status_code(2)
|
||||
.stderr_contains("failed to parse key");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_verifies_input_files() {
|
||||
new_ucmd!()
|
||||
.args(&["/dev/random", "nonexistent_file"])
|
||||
.fails()
|
||||
.status_code(2)
|
||||
.stderr_is("sort: cannot read: nonexistent_file: No such file or directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_separator_null() {
|
||||
new_ucmd!()
|
||||
.args(&["-k1,1", "-k3,3", "-t", "\\0"])
|
||||
.pipe_in("z\0a\0b\nz\0b\0a\na\0z\0z\n")
|
||||
.succeeds()
|
||||
.stdout_only("a\0z\0z\nz\0b\0a\nz\0a\0b\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_output_is_input() {
|
||||
let input = "a\nb\nc\n";
|
||||
let (at, mut cmd) = at_and_ucmd!();
|
||||
at.touch("file");
|
||||
at.append("file", input);
|
||||
cmd.args(&["-m", "-u", "-o", "file", "file", "file", "file"])
|
||||
.succeeds();
|
||||
assert_eq!(at.read("file"), input);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_output_device() {
|
||||
new_ucmd!()
|
||||
.args(&["-o", "/dev/null"])
|
||||
.pipe_in("input")
|
||||
.succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_merge_empty_input() {
|
||||
new_ucmd!()
|
||||
.args(&["-m", "empty.txt"])
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.no_stdout();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_error_for_version() {
|
||||
new_ucmd!()
|
||||
.arg("--version")
|
||||
.succeeds()
|
||||
.stdout_contains("sort");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrong_args_exit_code() {
|
||||
new_ucmd!()
|
||||
.arg("--misspelled")
|
||||
.fails()
|
||||
.status_code(2)
|
||||
.stderr_contains("--misspelled");
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ mod test_generate_tokens {
|
|||
|
||||
#[test]
|
||||
fn printf_format() {
|
||||
let s = "%-# 15a\\r\\\"\\\\\\a\\b\\e\\f\\v%+020.-23w\\x12\\167\\132\\112\\n";
|
||||
let s = "%-# 15a\\t\\r\\\"\\\\\\a\\b\\e\\f\\v%+020.-23w\\x12\\167\\132\\112\\n";
|
||||
let expected = vec![
|
||||
Token::Directive {
|
||||
flag: F_LEFT | F_ALTER | F_SPACE,
|
||||
|
@ -72,6 +72,7 @@ mod test_generate_tokens {
|
|||
precision: -1,
|
||||
format: 'a',
|
||||
},
|
||||
Token::Char('\t'),
|
||||
Token::Char('\r'),
|
||||
Token::Char('"'),
|
||||
Token::Char('\\'),
|
||||
|
|
|
@ -66,5 +66,10 @@ fn test_invalid_input() {
|
|||
.ucmd()
|
||||
.arg("a")
|
||||
.fails()
|
||||
.stderr_contains("dir: read error: Invalid argument");
|
||||
.stderr_contains("a: read error: Invalid argument");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_line_separators() {
|
||||
new_ucmd!().pipe_in("a").succeeds().stdout_is("a");
|
||||
}
|
||||
|
|
|
@ -23,6 +23,15 @@ fn test_stdin_default() {
|
|||
.stdout_is_fixture("foobar_stdin_default.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_explicit() {
|
||||
new_ucmd!()
|
||||
.pipe_in_fixture(FOOBAR_TXT)
|
||||
.arg("-")
|
||||
.run()
|
||||
.stdout_is_fixture("foobar_stdin_default.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_default() {
|
||||
new_ucmd!()
|
||||
|
|
0
tests/fixtures/sort/empty.txt
vendored
Normal file
0
tests/fixtures/sort/empty.txt
vendored
Normal file
Loading…
Add table
Add a link
Reference in a new issue