mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-09-16 19:56:17 +00:00
Merge branch 'main' into clap-3
This commit is contained in:
commit
8872485922
135 changed files with 1758 additions and 840 deletions
|
@ -328,3 +328,31 @@ fn single_file_with_header() {
|
|||
.succeeds()
|
||||
.stdout_is("A 1\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_line_feeds() {
|
||||
new_ucmd!()
|
||||
.arg("non-line_feeds_1.txt")
|
||||
.arg("non-line_feeds_2.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("non-line_feeds.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_unicode() {
|
||||
new_ucmd!()
|
||||
.arg("non-unicode_1.bin")
|
||||
.arg("non-unicode_2.bin")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("non-unicode.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn null_line_endings() {
|
||||
new_ucmd!()
|
||||
.arg("-z")
|
||||
.arg("non-unicode_1.bin")
|
||||
.arg("non-unicode_2.bin")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("z.expected");
|
||||
}
|
||||
|
|
|
@ -56,8 +56,70 @@ fn test_ls_ordering() {
|
|||
.stdout_matches(&Regex::new("some-dir1:\\ntotal 0").unwrap());
|
||||
}
|
||||
|
||||
//#[cfg(all(feature = "mknod"))]
|
||||
#[test]
|
||||
fn test_ls_devices() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
at.mkdir("some-dir1");
|
||||
|
||||
// Regex tests correct device ID and correct (no pad) spacing for a single file
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
{
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-al")
|
||||
.arg("/dev/null")
|
||||
.succeeds()
|
||||
.stdout_matches(&Regex::new("[^ ] 3, 2 [^ ]").unwrap());
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-al")
|
||||
.arg("/dev/null")
|
||||
.succeeds()
|
||||
.stdout_matches(&Regex::new("[^ ] 1, 3 [^ ]").unwrap());
|
||||
}
|
||||
|
||||
// Regex tests alignment against a file (stdout is a link to a tty)
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let res = scene
|
||||
.ucmd()
|
||||
.arg("-alL")
|
||||
.arg("/dev/null")
|
||||
.arg("/dev/stdout")
|
||||
.succeeds();
|
||||
|
||||
let null_len = String::from_utf8(res.stdout().to_owned())
|
||||
.ok()
|
||||
.unwrap()
|
||||
.lines()
|
||||
.next()
|
||||
.unwrap()
|
||||
.strip_suffix("/dev/null")
|
||||
.unwrap()
|
||||
.len();
|
||||
|
||||
let stdout_len = String::from_utf8(res.stdout().to_owned())
|
||||
.ok()
|
||||
.unwrap()
|
||||
.lines()
|
||||
.nth(1)
|
||||
.unwrap()
|
||||
.strip_suffix("/dev/stdout")
|
||||
.unwrap()
|
||||
.len();
|
||||
|
||||
assert_eq!(stdout_len, null_len);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "chmod"))]
|
||||
#[test]
|
||||
#[cfg(feature = "chmod")]
|
||||
fn test_ls_io_errors() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
@ -2457,6 +2519,36 @@ fn test_ls_dangling_symlinks() {
|
|||
.arg("temp_dir")
|
||||
.fails()
|
||||
.stdout_contains("l?????????");
|
||||
|
||||
#[cfg(unix)]
|
||||
{
|
||||
// Check padding is the same for real files and dangling links, in non-long formats
|
||||
at.touch("temp_dir/real_file");
|
||||
|
||||
let real_file_res = scene.ucmd().arg("-Li1").arg("temp_dir").fails();
|
||||
let real_file_stdout_len = String::from_utf8(real_file_res.stdout().to_owned())
|
||||
.ok()
|
||||
.unwrap()
|
||||
.lines()
|
||||
.nth(1)
|
||||
.unwrap()
|
||||
.strip_suffix("real_file")
|
||||
.unwrap()
|
||||
.len();
|
||||
|
||||
let dangle_file_res = scene.ucmd().arg("-Li1").arg("temp_dir").fails();
|
||||
let dangle_stdout_len = String::from_utf8(dangle_file_res.stdout().to_owned())
|
||||
.ok()
|
||||
.unwrap()
|
||||
.lines()
|
||||
.next()
|
||||
.unwrap()
|
||||
.strip_suffix("dangle")
|
||||
.unwrap()
|
||||
.len();
|
||||
|
||||
assert_eq!(real_file_stdout_len, dangle_stdout_len);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -340,10 +340,10 @@ fn test_dictionary_order() {
|
|||
fn test_dictionary_order2() {
|
||||
for non_dictionary_order2_param in &["-d"] {
|
||||
new_ucmd!()
|
||||
.pipe_in("a👦🏻aa b\naaaa b") // spell-checker:disable-line
|
||||
.pipe_in("a👦🏻aa\tb\naaaa\tb") // spell-checker:disable-line
|
||||
.arg(non_dictionary_order2_param) // spell-checker:disable-line
|
||||
.succeeds()
|
||||
.stdout_only("a👦🏻aa b\naaaa b\n"); // spell-checker:disable-line
|
||||
.stdout_only("a👦🏻aa\tb\naaaa\tb\n"); // spell-checker:disable-line
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// *
|
||||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore xzaaa sixhundredfiftyonebytes ninetyonebytes asciilowercase
|
||||
extern crate rand;
|
||||
extern crate regex;
|
||||
|
||||
|
@ -16,7 +16,7 @@ use std::io::Write;
|
|||
use std::path::Path;
|
||||
use std::{
|
||||
fs::{read_dir, File},
|
||||
io::BufWriter,
|
||||
io::{BufWriter, Read},
|
||||
};
|
||||
|
||||
fn random_chars(n: usize) -> String {
|
||||
|
@ -340,3 +340,87 @@ fn test_split_invalid_bytes_size() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn file_read(at: &AtPath, filename: &str) -> String {
|
||||
let mut s = String::new();
|
||||
at.open(filename).read_to_string(&mut s).unwrap();
|
||||
s
|
||||
}
|
||||
|
||||
// TODO Use char::from_digit() in Rust v1.51.0 or later.
|
||||
fn char_from_digit(n: usize) -> char {
|
||||
(b'a' + n as u8) as char
|
||||
}
|
||||
|
||||
/// Test for the default suffix length behavior: dynamically increasing size.
|
||||
#[test]
|
||||
fn test_alphabetic_dynamic_suffix_length() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
// Split into chunks of one byte each.
|
||||
//
|
||||
// The input file has (26^2) - 26 + 1 = 651 bytes. This is just
|
||||
// enough to force `split` to dynamically increase the length of
|
||||
// the filename for the very last chunk.
|
||||
//
|
||||
// We expect the output files to be named
|
||||
//
|
||||
// xaa, xab, xac, ..., xyx, xyy, xyz, xzaaa
|
||||
//
|
||||
ucmd.args(&["-b", "1", "sixhundredfiftyonebytes.txt"])
|
||||
.succeeds();
|
||||
for i in 0..25 {
|
||||
for j in 0..26 {
|
||||
let filename = format!("x{}{}", char_from_digit(i), char_from_digit(j),);
|
||||
let contents = file_read(&at, &filename);
|
||||
assert_eq!(contents, "a");
|
||||
}
|
||||
}
|
||||
assert_eq!(file_read(&at, "xzaaa"), "a");
|
||||
}
|
||||
|
||||
/// Test for the default suffix length behavior: dynamically increasing size.
|
||||
#[test]
|
||||
fn test_numeric_dynamic_suffix_length() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
// Split into chunks of one byte each, use numbers instead of
|
||||
// letters as file suffixes.
|
||||
//
|
||||
// The input file has (10^2) - 10 + 1 = 91 bytes. This is just
|
||||
// enough to force `split` to dynamically increase the length of
|
||||
// the filename for the very last chunk.
|
||||
//
|
||||
// x00, x01, x02, ..., x87, x88, x89, x9000
|
||||
//
|
||||
ucmd.args(&["-d", "-b", "1", "ninetyonebytes.txt"])
|
||||
.succeeds();
|
||||
for i in 0..90 {
|
||||
let filename = format!("x{:02}", i);
|
||||
let contents = file_read(&at, &filename);
|
||||
assert_eq!(contents, "a");
|
||||
}
|
||||
assert_eq!(file_read(&at, "x9000"), "a");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_suffixes_exhausted() {
|
||||
new_ucmd!()
|
||||
.args(&["-b", "1", "-a", "1", "asciilowercase.txt"])
|
||||
.fails()
|
||||
.stderr_only("split: output file suffixes exhausted");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verbose() {
|
||||
new_ucmd!()
|
||||
.args(&["-b", "5", "--verbose", "asciilowercase.txt"])
|
||||
.succeeds()
|
||||
.stdout_only(
|
||||
"creating file 'xaa'
|
||||
creating file 'xab'
|
||||
creating file 'xac'
|
||||
creating file 'xad'
|
||||
creating file 'xae'
|
||||
creating file 'xaf'
|
||||
",
|
||||
);
|
||||
}
|
||||
|
|
|
@ -63,9 +63,7 @@ fn test_tee_append() {
|
|||
fn test_tee_no_more_writeable_1() {
|
||||
// equals to 'tee /dev/full out2 <multi_read' call
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let content = (1..=10)
|
||||
.map(|x| format!("{}\n", x.to_string()))
|
||||
.collect::<String>();
|
||||
let content = (1..=10).map(|x| format!("{}\n", x)).collect::<String>();
|
||||
let file_out = "tee_file_out";
|
||||
|
||||
ucmd.arg("/dev/full")
|
||||
|
@ -85,9 +83,7 @@ fn test_tee_no_more_writeable_2() {
|
|||
// but currently there is no way to redirect stdout to /dev/full
|
||||
// so this test is disabled
|
||||
let (_at, mut ucmd) = at_and_ucmd!();
|
||||
let _content = (1..=10)
|
||||
.map(|x| format!("{}\n", x.to_string()))
|
||||
.collect::<String>();
|
||||
let _content = (1..=10).map(|x| format!("{}\n", x)).collect::<String>();
|
||||
let file_out_a = "tee_file_out_a";
|
||||
let file_out_b = "tee_file_out_b";
|
||||
|
||||
|
|
|
@ -1230,14 +1230,7 @@ pub fn check_coreutil_version(
|
|||
.output()
|
||||
{
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
return Err(format!(
|
||||
"{}: '{}' {}",
|
||||
UUTILS_WARNING,
|
||||
util_name,
|
||||
e.to_string()
|
||||
))
|
||||
}
|
||||
Err(e) => return Err(format!("{}: '{}' {}", UUTILS_WARNING, util_name, e)),
|
||||
};
|
||||
std::str::from_utf8(&version_check.stdout).unwrap()
|
||||
.split('\n')
|
||||
|
@ -1247,7 +1240,7 @@ pub fn check_coreutil_version(
|
|||
|| Err(format!("{}: unexpected output format for reference coreutil: '{} --version'", UUTILS_WARNING, util_name)),
|
||||
|s| {
|
||||
if s.contains(&format!("(GNU coreutils) {}", version_expected)) {
|
||||
Ok(format!("{}: {}", UUTILS_INFO, s.to_string()))
|
||||
Ok(format!("{}: {}", UUTILS_INFO, s))
|
||||
} else if s.contains("(GNU coreutils)") {
|
||||
let version_found = parse_coreutil_version(s);
|
||||
let version_expected = version_expected.parse::<f32>().unwrap_or_default();
|
||||
|
|
2
tests/fixtures/join/non-line_feeds.expected
vendored
Normal file
2
tests/fixtures/join/non-line_feeds.expected
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
b
d
|
||||
a c f
|
2
tests/fixtures/join/non-line_feeds_1.txt
vendored
Normal file
2
tests/fixtures/join/non-line_feeds_1.txt
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
b
|
||||
a c
|
2
tests/fixtures/join/non-line_feeds_2.txt
vendored
Normal file
2
tests/fixtures/join/non-line_feeds_2.txt
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
d
|
||||
a f
|
BIN
tests/fixtures/join/non-unicode.expected
vendored
Normal file
BIN
tests/fixtures/join/non-unicode.expected
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/join/non-unicode_1.bin
vendored
Normal file
BIN
tests/fixtures/join/non-unicode_1.bin
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/join/non-unicode_2.bin
vendored
Normal file
BIN
tests/fixtures/join/non-unicode_2.bin
vendored
Normal file
Binary file not shown.
BIN
tests/fixtures/join/z.expected
vendored
Normal file
BIN
tests/fixtures/join/z.expected
vendored
Normal file
Binary file not shown.
1
tests/fixtures/split/asciilowercase.txt
vendored
Normal file
1
tests/fixtures/split/asciilowercase.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
abcdefghijklmnopqrstuvwxyz
|
1
tests/fixtures/split/ninetyonebytes.txt
vendored
Normal file
1
tests/fixtures/split/ninetyonebytes.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
1
tests/fixtures/split/sixhundredfiftyonebytes.txt
vendored
Normal file
1
tests/fixtures/split/sixhundredfiftyonebytes.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
Loading…
Add table
Add a link
Reference in a new issue