mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-09-15 11:36:16 +00:00
Merge branch 'master' into issue2167
This commit is contained in:
commit
01a702c6fd
46 changed files with 1948 additions and 1176 deletions
|
@ -1,6 +1,29 @@
|
|||
use crate::common::util::*;
|
||||
use std::ffi::OsStr;
|
||||
|
||||
#[test]
|
||||
fn test_help() {
|
||||
for help_flg in vec!["-h", "--help"] {
|
||||
new_ucmd!()
|
||||
.arg(&help_flg)
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_contains("USAGE:");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version() {
|
||||
for version_flg in vec!["-V", "--version"] {
|
||||
assert!(new_ucmd!()
|
||||
.arg(&version_flg)
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_str()
|
||||
.starts_with("basename"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_directory() {
|
||||
new_ucmd!()
|
||||
|
@ -81,11 +104,25 @@ fn test_no_args() {
|
|||
expect_error(vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_args_output() {
|
||||
new_ucmd!()
|
||||
.fails()
|
||||
.stderr_is("basename: error: missing operand\nTry 'basename --help' for more information.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_many_args() {
|
||||
expect_error(vec!["a", "b", "c"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_many_args_output() {
|
||||
new_ucmd!().args(&["a", "b", "c"]).fails().stderr_is(
|
||||
"basename: error: extra operand 'c'\nTry 'basename --help' for more information.",
|
||||
);
|
||||
}
|
||||
|
||||
fn test_invalid_utf8_args(os_str: &OsStr) {
|
||||
let test_vec = vec![os_str.to_os_string()];
|
||||
new_ucmd!().args(&test_vec).succeeds().stdout_is("fo<EFBFBD>o\n");
|
||||
|
|
|
@ -20,4 +20,16 @@ fn test_df_compatible_si() {
|
|||
new_ucmd!().arg("-aH").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_df_output() {
|
||||
if cfg!(target_os = "macos") {
|
||||
new_ucmd!().arg("-H").arg("-total").succeeds().
|
||||
stdout_only("Filesystem Size Used Available Capacity Use% Mounted on \n");
|
||||
} else {
|
||||
new_ucmd!().arg("-H").arg("-total").succeeds().stdout_only(
|
||||
"Filesystem Size Used Available Use% Mounted on \n",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ToDO: more tests...
|
||||
|
|
|
@ -53,7 +53,15 @@ fn _du_basics_subdir(s: &str) {
|
|||
fn _du_basics_subdir(s: &str) {
|
||||
assert_eq!(s, "0\tsubdir/deeper\n");
|
||||
}
|
||||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
fn _du_basics_subdir(s: &str) {
|
||||
assert_eq!(s, "8\tsubdir/deeper\n");
|
||||
}
|
||||
#[cfg(all(
|
||||
not(target_vendor = "apple"),
|
||||
not(target_os = "windows"),
|
||||
not(target_os = "freebsd")
|
||||
))]
|
||||
fn _du_basics_subdir(s: &str) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !uucore::os::is_wsl_1() {
|
||||
|
@ -100,7 +108,15 @@ fn _du_soft_link(s: &str) {
|
|||
fn _du_soft_link(s: &str) {
|
||||
assert_eq!(s, "8\tsubdir/links\n");
|
||||
}
|
||||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
fn _du_soft_link(s: &str) {
|
||||
assert_eq!(s, "16\tsubdir/links\n");
|
||||
}
|
||||
#[cfg(all(
|
||||
not(target_vendor = "apple"),
|
||||
not(target_os = "windows"),
|
||||
not(target_os = "freebsd")
|
||||
))]
|
||||
fn _du_soft_link(s: &str) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !uucore::os::is_wsl_1() {
|
||||
|
@ -141,7 +157,15 @@ fn _du_hard_link(s: &str) {
|
|||
fn _du_hard_link(s: &str) {
|
||||
assert_eq!(s, "8\tsubdir/links\n")
|
||||
}
|
||||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
fn _du_hard_link(s: &str) {
|
||||
assert_eq!(s, "16\tsubdir/links\n")
|
||||
}
|
||||
#[cfg(all(
|
||||
not(target_vendor = "apple"),
|
||||
not(target_os = "windows"),
|
||||
not(target_os = "freebsd")
|
||||
))]
|
||||
fn _du_hard_link(s: &str) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !uucore::os::is_wsl_1() {
|
||||
|
@ -181,7 +205,15 @@ fn _du_d_flag(s: &str) {
|
|||
fn _du_d_flag(s: &str) {
|
||||
assert_eq!(s, "8\t./subdir\n8\t./\n");
|
||||
}
|
||||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
#[cfg(target_os = "freebsd")]
|
||||
fn _du_d_flag(s: &str) {
|
||||
assert_eq!(s, "28\t./subdir\n36\t./\n");
|
||||
}
|
||||
#[cfg(all(
|
||||
not(target_vendor = "apple"),
|
||||
not(target_os = "windows"),
|
||||
not(target_os = "freebsd")
|
||||
))]
|
||||
fn _du_d_flag(s: &str) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !uucore::os::is_wsl_1() {
|
||||
|
|
|
@ -33,18 +33,16 @@ fn test_fmt_w_too_big() {
|
|||
"fmt: error: invalid width: '2501': Numerical result out of range"
|
||||
);
|
||||
}
|
||||
/* #[test]
|
||||
Fails for now, see https://github.com/uutils/coreutils/issues/1501
|
||||
#[test]
|
||||
fn test_fmt_w() {
|
||||
let result = new_ucmd!()
|
||||
.arg("-w")
|
||||
.arg("10")
|
||||
.arg("one-word-per-line.txt")
|
||||
.run();
|
||||
//.stdout_is_fixture("call_graph.expected");
|
||||
assert_eq!(result.stdout_str().trim(), "this is a file with one word per line");
|
||||
//.stdout_is_fixture("call_graph.expected");
|
||||
assert_eq!(
|
||||
result.stdout_str().trim(),
|
||||
"this is\na file\nwith one\nword per\nline"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
fmt is pretty broken in general, needs more works to have more tests
|
||||
*/
|
||||
|
|
|
@ -5,6 +5,7 @@ use crate::common::util::*;
|
|||
extern crate regex;
|
||||
use self::regex::Regex;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
@ -308,6 +309,50 @@ fn test_ls_long() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ls_long_total_size() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
at.touch(&at.plus_as_string("test-long"));
|
||||
at.append("test-long", "1");
|
||||
at.touch(&at.plus_as_string("test-long2"));
|
||||
at.append("test-long2", "2");
|
||||
|
||||
let expected_prints: HashMap<_, _> = if cfg!(unix) {
|
||||
[
|
||||
("long_vanilla", "total 8"),
|
||||
("long_human_readable", "total 8.0K"),
|
||||
("long_si", "total 8.2k"),
|
||||
]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect()
|
||||
} else {
|
||||
[
|
||||
("long_vanilla", "total 2"),
|
||||
("long_human_readable", "total 2"),
|
||||
("long_si", "total 2"),
|
||||
]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect()
|
||||
};
|
||||
|
||||
for arg in &["-l", "--long", "--format=long", "--format=verbose"] {
|
||||
let result = scene.ucmd().arg(arg).succeeds();
|
||||
result.stdout_contains(expected_prints["long_vanilla"]);
|
||||
|
||||
for arg2 in &["-h", "--human-readable", "--si"] {
|
||||
let result = scene.ucmd().arg(arg).arg(arg2).succeeds();
|
||||
result.stdout_contains(if *arg2 == "--si" {
|
||||
expected_prints["long_si"]
|
||||
} else {
|
||||
expected_prints["long_human_readable"]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ls_long_formats() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
|
|
@ -1 +1,124 @@
|
|||
// ToDO: add tests
|
||||
use crate::common::util::*;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[test]
|
||||
fn test_mknod_help() {
|
||||
new_ucmd!()
|
||||
.arg("--help")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_contains("USAGE:");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_mknod_version() {
|
||||
assert!(new_ucmd!()
|
||||
.arg("--version")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout_str()
|
||||
.starts_with("mknod"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_mknod_fifo_default_writable() {
|
||||
let ts = TestScenario::new(util_name!());
|
||||
ts.ucmd().arg("test_file").arg("p").succeeds();
|
||||
assert!(ts.fixtures.is_fifo("test_file"));
|
||||
assert!(!ts.fixtures.metadata("test_file").permissions().readonly());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_mknod_fifo_mnemonic_usage() {
|
||||
let ts = TestScenario::new(util_name!());
|
||||
ts.ucmd().arg("test_file").arg("pipe").succeeds();
|
||||
assert!(ts.fixtures.is_fifo("test_file"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_mknod_fifo_read_only() {
|
||||
let ts = TestScenario::new(util_name!());
|
||||
ts.ucmd()
|
||||
.arg("-m")
|
||||
.arg("a=r")
|
||||
.arg("test_file")
|
||||
.arg("p")
|
||||
.succeeds();
|
||||
assert!(ts.fixtures.is_fifo("test_file"));
|
||||
assert!(ts.fixtures.metadata("test_file").permissions().readonly());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_mknod_fifo_invalid_extra_operand() {
|
||||
new_ucmd!()
|
||||
.arg("test_file")
|
||||
.arg("p")
|
||||
.arg("1")
|
||||
.arg("2")
|
||||
.fails()
|
||||
.stderr_contains(&"Fifos do not have major and minor device numbers");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_mknod_character_device_requires_major_and_minor() {
|
||||
new_ucmd!()
|
||||
.arg("test_file")
|
||||
.arg("c")
|
||||
.fails()
|
||||
.status_code(1)
|
||||
.stderr_contains(&"Special files require major and minor device numbers.");
|
||||
new_ucmd!()
|
||||
.arg("test_file")
|
||||
.arg("c")
|
||||
.arg("1")
|
||||
.fails()
|
||||
.status_code(1)
|
||||
.stderr_contains(&"Special files require major and minor device numbers.");
|
||||
new_ucmd!()
|
||||
.arg("test_file")
|
||||
.arg("c")
|
||||
.arg("1")
|
||||
.arg("c")
|
||||
.fails()
|
||||
.status_code(1)
|
||||
.stderr_contains(&"Invalid value for '<MINOR>'");
|
||||
new_ucmd!()
|
||||
.arg("test_file")
|
||||
.arg("c")
|
||||
.arg("c")
|
||||
.arg("1")
|
||||
.fails()
|
||||
.status_code(1)
|
||||
.stderr_contains(&"Invalid value for '<MAJOR>'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_mknod_invalid_arg() {
|
||||
new_ucmd!()
|
||||
.arg("--foo")
|
||||
.fails()
|
||||
.status_code(1)
|
||||
.no_stdout()
|
||||
.stderr_contains(&"Found argument '--foo' which wasn't expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_mknod_invalid_mode() {
|
||||
new_ucmd!()
|
||||
.arg("--mode")
|
||||
.arg("rw")
|
||||
.arg("test_file")
|
||||
.arg("p")
|
||||
.fails()
|
||||
.no_stdout()
|
||||
.status_code(1)
|
||||
.stderr_contains(&"invalid mode");
|
||||
}
|
||||
|
|
|
@ -37,7 +37,29 @@ fn test_larger_than_specified_segment() {
|
|||
.arg("50K")
|
||||
.arg("ext_sort.txt")
|
||||
.succeeds()
|
||||
.stdout_is_fixture(format!("{}", "ext_sort.expected"));
|
||||
.stdout_is_fixture("ext_sort.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_smaller_than_specified_segment() {
|
||||
new_ucmd!()
|
||||
.arg("-n")
|
||||
.arg("-S")
|
||||
.arg("100M")
|
||||
.arg("ext_sort.txt")
|
||||
.succeeds()
|
||||
.stdout_is_fixture("ext_sort.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extsort_zero_terminated() {
|
||||
new_ucmd!()
|
||||
.arg("-z")
|
||||
.arg("-S")
|
||||
.arg("10K")
|
||||
.arg("zero-terminated.txt")
|
||||
.succeeds()
|
||||
.stdout_is_fixture("zero-terminated.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -4,11 +4,15 @@ extern crate regex;
|
|||
use self::rand::{thread_rng, Rng};
|
||||
use self::regex::Regex;
|
||||
use crate::common::util::*;
|
||||
use rand::SeedableRng;
|
||||
#[cfg(not(windows))]
|
||||
use std::env;
|
||||
use std::fs::{read_dir, File};
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::{
|
||||
fs::{read_dir, File},
|
||||
io::BufWriter,
|
||||
};
|
||||
|
||||
fn random_chars(n: usize) -> String {
|
||||
thread_rng()
|
||||
|
@ -58,7 +62,7 @@ impl Glob {
|
|||
files.sort();
|
||||
let mut data: Vec<u8> = vec![];
|
||||
for name in &files {
|
||||
data.extend(self.directory.read(name).into_bytes());
|
||||
data.extend(self.directory.read_bytes(name));
|
||||
}
|
||||
data
|
||||
}
|
||||
|
@ -81,20 +85,30 @@ impl RandomFile {
|
|||
}
|
||||
|
||||
fn add_bytes(&mut self, bytes: usize) {
|
||||
let chunk_size: usize = if bytes >= 1024 { 1024 } else { bytes };
|
||||
let mut n = bytes;
|
||||
while n > chunk_size {
|
||||
let _ = write!(self.inner, "{}", random_chars(chunk_size));
|
||||
n -= chunk_size;
|
||||
// Note that just writing random characters isn't enough to cover all
|
||||
// cases. We need truly random bytes.
|
||||
let mut writer = BufWriter::new(&self.inner);
|
||||
|
||||
// Seed the rng so as to avoid spurious test failures.
|
||||
let mut rng = rand::rngs::StdRng::seed_from_u64(123);
|
||||
let mut buffer = [0; 1024];
|
||||
let mut remaining_size = bytes;
|
||||
|
||||
while remaining_size > 0 {
|
||||
let to_write = std::cmp::min(remaining_size, buffer.len());
|
||||
let buf = &mut buffer[..to_write];
|
||||
rng.fill(buf);
|
||||
writer.write(buf).unwrap();
|
||||
|
||||
remaining_size -= to_write;
|
||||
}
|
||||
let _ = write!(self.inner, "{}", random_chars(n));
|
||||
}
|
||||
|
||||
/// Add n lines each of size `RandomFile::LINESIZE`
|
||||
fn add_lines(&mut self, lines: usize) {
|
||||
let mut n = lines;
|
||||
while n > 0 {
|
||||
let _ = writeln!(self.inner, "{}", random_chars(RandomFile::LINESIZE));
|
||||
writeln!(self.inner, "{}", random_chars(RandomFile::LINESIZE)).unwrap();
|
||||
n -= 1;
|
||||
}
|
||||
}
|
||||
|
@ -104,18 +118,18 @@ impl RandomFile {
|
|||
fn test_split_default() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_default";
|
||||
let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]]$");
|
||||
RandomFile::new(&at, name).add_lines(2000);
|
||||
ucmd.args(&[name]).succeeds();
|
||||
|
||||
let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]]$");
|
||||
assert_eq!(glob.count(), 2);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
assert_eq!(glob.collate(), at.read_bytes(name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_numeric_prefixed_chunks_by_bytes() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_num_prefixed_chunks_by_bytes";
|
||||
let glob = Glob::new(&at, ".", r"a\d\d$");
|
||||
RandomFile::new(&at, name).add_bytes(10000);
|
||||
ucmd.args(&[
|
||||
"-d", // --numeric-suffixes
|
||||
|
@ -123,52 +137,89 @@ fn test_split_numeric_prefixed_chunks_by_bytes() {
|
|||
"1000", name, "a",
|
||||
])
|
||||
.succeeds();
|
||||
|
||||
let glob = Glob::new(&at, ".", r"a\d\d$");
|
||||
assert_eq!(glob.count(), 10);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
for filename in glob.collect() {
|
||||
assert_eq!(glob.directory.metadata(&filename).len(), 1000);
|
||||
}
|
||||
assert_eq!(glob.collate(), at.read_bytes(name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_str_prefixed_chunks_by_bytes() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_str_prefixed_chunks_by_bytes";
|
||||
let glob = Glob::new(&at, ".", r"b[[:alpha:]][[:alpha:]]$");
|
||||
RandomFile::new(&at, name).add_bytes(10000);
|
||||
// Important that this is less than 1024 since that's our internal buffer
|
||||
// size. Good to test that we don't overshoot.
|
||||
ucmd.args(&["-b", "1000", name, "b"]).succeeds();
|
||||
|
||||
let glob = Glob::new(&at, ".", r"b[[:alpha:]][[:alpha:]]$");
|
||||
assert_eq!(glob.count(), 10);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
for filename in glob.collect() {
|
||||
assert_eq!(glob.directory.metadata(&filename).len(), 1000);
|
||||
}
|
||||
assert_eq!(glob.collate(), at.read_bytes(name));
|
||||
}
|
||||
|
||||
// This is designed to test what happens when the desired part size is not a
|
||||
// multiple of the buffer size and we hopefully don't overshoot the desired part
|
||||
// size.
|
||||
#[test]
|
||||
fn test_split_bytes_prime_part_size() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "test_split_bytes_prime_part_size";
|
||||
RandomFile::new(&at, name).add_bytes(10000);
|
||||
// 1753 is prime and greater than the buffer size, 1024.
|
||||
ucmd.args(&["-b", "1753", name, "b"]).succeeds();
|
||||
|
||||
let glob = Glob::new(&at, ".", r"b[[:alpha:]][[:alpha:]]$");
|
||||
assert_eq!(glob.count(), 6);
|
||||
let mut fns = glob.collect();
|
||||
// glob.collect() is not guaranteed to return in sorted order, so we sort.
|
||||
fns.sort();
|
||||
for i in 0..5 {
|
||||
assert_eq!(glob.directory.metadata(&fns[i]).len(), 1753);
|
||||
}
|
||||
assert_eq!(glob.directory.metadata(&fns[5]).len(), 1235);
|
||||
assert_eq!(glob.collate(), at.read_bytes(name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_num_prefixed_chunks_by_lines() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_num_prefixed_chunks_by_lines";
|
||||
let glob = Glob::new(&at, ".", r"c\d\d$");
|
||||
RandomFile::new(&at, name).add_lines(10000);
|
||||
ucmd.args(&["-d", "-l", "1000", name, "c"]).succeeds();
|
||||
|
||||
let glob = Glob::new(&at, ".", r"c\d\d$");
|
||||
assert_eq!(glob.count(), 10);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
assert_eq!(glob.collate(), at.read_bytes(name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_str_prefixed_chunks_by_lines() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_str_prefixed_chunks_by_lines";
|
||||
let glob = Glob::new(&at, ".", r"d[[:alpha:]][[:alpha:]]$");
|
||||
RandomFile::new(&at, name).add_lines(10000);
|
||||
ucmd.args(&["-l", "1000", name, "d"]).succeeds();
|
||||
|
||||
let glob = Glob::new(&at, ".", r"d[[:alpha:]][[:alpha:]]$");
|
||||
assert_eq!(glob.count(), 10);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
assert_eq!(glob.collate(), at.read_bytes(name));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_additional_suffix() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_additional_suffix";
|
||||
let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]].txt$");
|
||||
RandomFile::new(&at, name).add_lines(2000);
|
||||
ucmd.args(&["--additional-suffix", ".txt", name]).succeeds();
|
||||
|
||||
let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]].txt$");
|
||||
assert_eq!(glob.count(), 2);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
assert_eq!(glob.collate(), at.read_bytes(name));
|
||||
}
|
||||
|
||||
// note: the test_filter* tests below are unix-only
|
||||
|
@ -182,15 +233,16 @@ fn test_filter() {
|
|||
// like `test_split_default()` but run a command before writing
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "filtered";
|
||||
let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]]$");
|
||||
let n_lines = 3;
|
||||
RandomFile::new(&at, name).add_lines(n_lines);
|
||||
|
||||
// change all characters to 'i'
|
||||
ucmd.args(&["--filter=sed s/./i/g > $FILE", name])
|
||||
.succeeds();
|
||||
|
||||
// assert all characters are 'i' / no character is not 'i'
|
||||
// (assert that command succeded)
|
||||
let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]]$");
|
||||
assert!(
|
||||
glob.collate().iter().find(|&&c| {
|
||||
// is not i
|
||||
|
@ -209,7 +261,6 @@ fn test_filter_with_env_var_set() {
|
|||
// implemented like `test_split_default()` but run a command before writing
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "filtered";
|
||||
let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]]$");
|
||||
let n_lines = 3;
|
||||
RandomFile::new(&at, name).add_lines(n_lines);
|
||||
|
||||
|
@ -217,7 +268,9 @@ fn test_filter_with_env_var_set() {
|
|||
env::set_var("FILE", &env_var_value);
|
||||
ucmd.args(&[format!("--filter={}", "cat > $FILE").as_str(), name])
|
||||
.succeeds();
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
|
||||
let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]]$");
|
||||
assert_eq!(glob.collate(), at.read_bytes(name));
|
||||
assert!(env::var("FILE").unwrap_or("var was unset".to_owned()) == env_var_value);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,42 +9,6 @@ pub use self::stat::*;
|
|||
mod test_fsext {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_access() {
|
||||
assert_eq!("drwxr-xr-x", pretty_access(S_IFDIR | 0o755));
|
||||
assert_eq!("-rw-r--r--", pretty_access(S_IFREG | 0o644));
|
||||
assert_eq!("srw-r-----", pretty_access(S_IFSOCK | 0o640));
|
||||
assert_eq!("lrw-r-xr-x", pretty_access(S_IFLNK | 0o655));
|
||||
assert_eq!("?rw-r-xr-x", pretty_access(0o655));
|
||||
|
||||
assert_eq!(
|
||||
"brwSr-xr-x",
|
||||
pretty_access(S_IFBLK | S_ISUID as mode_t | 0o655)
|
||||
);
|
||||
assert_eq!(
|
||||
"brwsr-xr-x",
|
||||
pretty_access(S_IFBLK | S_ISUID as mode_t | 0o755)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"prw---sr--",
|
||||
pretty_access(S_IFIFO | S_ISGID as mode_t | 0o614)
|
||||
);
|
||||
assert_eq!(
|
||||
"prw---Sr--",
|
||||
pretty_access(S_IFIFO | S_ISGID as mode_t | 0o604)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"c---r-xr-t",
|
||||
pretty_access(S_IFCHR | S_ISVTX as mode_t | 0o055)
|
||||
);
|
||||
assert_eq!(
|
||||
"c---r-xr-T",
|
||||
pretty_access(S_IFCHR | S_ISVTX as mode_t | 0o054)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file_type() {
|
||||
assert_eq!("block special file", pretty_filetype(S_IFBLK, 0));
|
||||
|
@ -198,9 +162,16 @@ fn test_terse_normal_format() {
|
|||
let expect = expected_result(&args);
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
let v_actual: Vec<&str> = actual.split(' ').collect();
|
||||
let v_expect: Vec<&str> = expect.split(' ').collect();
|
||||
let v_actual: Vec<&str> = actual.trim().split(' ').collect();
|
||||
let mut v_expect: Vec<&str> = expect.trim().split(' ').collect();
|
||||
assert!(!v_expect.is_empty());
|
||||
|
||||
// uu_stat does not support selinux
|
||||
if v_actual.len() == v_expect.len() - 1 && v_expect[v_expect.len() - 1].contains(":") {
|
||||
// assume last element contains: `SELinux security context string`
|
||||
v_expect.pop();
|
||||
}
|
||||
|
||||
// * allow for inequality if `stat` (aka, expect) returns "0" (unknown value)
|
||||
assert!(
|
||||
expect == "0"
|
||||
|
|
|
@ -33,7 +33,7 @@ fn test_stdin_default() {
|
|||
new_ucmd!()
|
||||
.pipe_in_fixture("lorem_ipsum.txt")
|
||||
.run()
|
||||
.stdout_is(" 13 109 772\n");
|
||||
.stdout_is(" 13 109 772\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -42,7 +42,7 @@ fn test_utf8() {
|
|||
.args(&["-lwmcL"])
|
||||
.pipe_in_fixture("UTF_8_test.txt")
|
||||
.run()
|
||||
.stdout_is(" 300 4969 22781 22213 79\n");
|
||||
.stdout_is(" 300 4969 22781 22213 79\n");
|
||||
// GNU returns " 300 2086 22219 22781 79"
|
||||
// TODO: we should fix that to match GNU's behavior
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ fn test_stdin_all_counts() {
|
|||
.args(&["-c", "-m", "-l", "-L", "-w"])
|
||||
.pipe_in_fixture("alice_in_wonderland.txt")
|
||||
.run()
|
||||
.stdout_is(" 5 57 302 302 66\n");
|
||||
.stdout_is(" 5 57 302 302 66\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -79,7 +79,7 @@ fn test_single_default() {
|
|||
new_ucmd!()
|
||||
.arg("moby_dick.txt")
|
||||
.run()
|
||||
.stdout_is(" 18 204 1115 moby_dick.txt\n");
|
||||
.stdout_is(" 18 204 1115 moby_dick.txt\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -95,7 +95,7 @@ fn test_single_all_counts() {
|
|||
new_ucmd!()
|
||||
.args(&["-c", "-l", "-L", "-m", "-w", "alice_in_wonderland.txt"])
|
||||
.run()
|
||||
.stdout_is(" 5 57 302 302 66 alice_in_wonderland.txt\n");
|
||||
.stdout_is(" 5 57 302 302 66 alice_in_wonderland.txt\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -108,7 +108,54 @@ fn test_multiple_default() {
|
|||
])
|
||||
.run()
|
||||
.stdout_is(
|
||||
" 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 5 57 302 \
|
||||
alice_in_wonderland.txt\n 36 370 2189 total\n",
|
||||
" 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 5 57 302 \
|
||||
alice_in_wonderland.txt\n 36 370 2189 total\n",
|
||||
);
|
||||
}
|
||||
|
||||
/// Test for an empty file.
|
||||
#[test]
|
||||
fn test_file_empty() {
|
||||
new_ucmd!()
|
||||
.args(&["-clmwL", "emptyfile.txt"])
|
||||
.run()
|
||||
.stdout_is("0 0 0 0 0 emptyfile.txt\n");
|
||||
}
|
||||
|
||||
/// Test for an file containing a single non-whitespace character
|
||||
/// *without* a trailing newline.
|
||||
#[test]
|
||||
fn test_file_single_line_no_trailing_newline() {
|
||||
new_ucmd!()
|
||||
.args(&["-clmwL", "notrailingnewline.txt"])
|
||||
.run()
|
||||
.stdout_is("1 1 2 2 1 notrailingnewline.txt\n");
|
||||
}
|
||||
|
||||
/// Test for a file that has 100 empty lines (that is, the contents of
|
||||
/// the file are the newline character repeated one hundred times).
|
||||
#[test]
|
||||
fn test_file_many_empty_lines() {
|
||||
new_ucmd!()
|
||||
.args(&["-clmwL", "manyemptylines.txt"])
|
||||
.run()
|
||||
.stdout_is("100 0 100 100 0 manyemptylines.txt\n");
|
||||
}
|
||||
|
||||
/// Test for a file that has one long line comprising only spaces.
|
||||
#[test]
|
||||
fn test_file_one_long_line_only_spaces() {
|
||||
new_ucmd!()
|
||||
.args(&["-clmwL", "onelongemptyline.txt"])
|
||||
.run()
|
||||
.stdout_is(" 1 0 10001 10001 10000 onelongemptyline.txt\n");
|
||||
}
|
||||
|
||||
/// Test for a file that has one long line comprising a single "word".
|
||||
#[test]
|
||||
fn test_file_one_long_word() {
|
||||
new_ucmd!()
|
||||
.args(&["-clmwL", "onelongword.txt"])
|
||||
.run()
|
||||
.stdout_is(" 1 1 10001 10001 10000 onelongword.txt\n");
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#[cfg(target_os = "linux")]
|
||||
use crate::common::util::*;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_count() {
|
||||
for opt in vec!["-q", "--count"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,17 +15,21 @@ fn test_count() {
|
|||
#[test]
|
||||
fn test_boot() {
|
||||
for opt in vec!["-b", "--boot"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_heading() {
|
||||
for opt in vec!["-H"] {
|
||||
for opt in vec!["-H", "--heading"] {
|
||||
// allow whitespace variation
|
||||
// * minor whitespace differences occur between platform built-in outputs; specifically number of TABs between "TIME" and "COMMENT" may be variant
|
||||
let actual = new_ucmd!().arg(opt).run().stdout_move_str();
|
||||
// * minor whitespace differences occur between platform built-in outputs;
|
||||
// specifically number of TABs between "TIME" and "COMMENT" may be variant
|
||||
let actual = new_ucmd!().arg(opt).succeeds().stdout_move_str();
|
||||
let expect = expected_result(opt);
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
|
@ -37,7 +43,10 @@ fn test_heading() {
|
|||
#[test]
|
||||
fn test_short() {
|
||||
for opt in vec!["-s", "--short"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +54,10 @@ fn test_short() {
|
|||
#[test]
|
||||
fn test_login() {
|
||||
for opt in vec!["-l", "--login"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +65,110 @@ fn test_login() {
|
|||
#[test]
|
||||
fn test_m() {
|
||||
for opt in vec!["-m"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_process() {
|
||||
for opt in vec!["-p", "--process"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_runlevel() {
|
||||
for opt in vec!["-r", "--runlevel"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_time() {
|
||||
for opt in vec!["-t", "--time"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_mesg() {
|
||||
for opt in vec!["-w", "-T", "--users", "--message", "--writable"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_arg1_arg2() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let expected = scene
|
||||
.cmd_keepenv(util_name!())
|
||||
.env("LANGUAGE", "C")
|
||||
.arg("am")
|
||||
.arg("i")
|
||||
.succeeds();
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("am")
|
||||
.arg("i")
|
||||
.succeeds()
|
||||
.stdout_is(expected.stdout_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_many_args() {
|
||||
let expected =
|
||||
"error: The value 'u' was provided to '<FILE>...', but it wasn't expecting any more values";
|
||||
|
||||
new_ucmd!()
|
||||
.arg("am")
|
||||
.arg("i")
|
||||
.arg("u")
|
||||
.fails()
|
||||
.stderr_contains(expected);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_users() {
|
||||
for opt in vec!["-u", "--users"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_lookup() {
|
||||
for opt in vec!["--lookup"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,15 +176,60 @@ fn test_m() {
|
|||
#[test]
|
||||
fn test_dead() {
|
||||
for opt in vec!["-d", "--dead"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_all_separately() {
|
||||
// -a, --all same as -b -d --login -p -r -t -T -u
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let expected = scene
|
||||
.cmd_keepenv(util_name!())
|
||||
.env("LANGUAGE", "C")
|
||||
.arg("-b")
|
||||
.arg("-d")
|
||||
.arg("--login")
|
||||
.arg("-p")
|
||||
.arg("-r")
|
||||
.arg("-t")
|
||||
.arg("-T")
|
||||
.arg("-u")
|
||||
.succeeds();
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-b")
|
||||
.arg("-d")
|
||||
.arg("--login")
|
||||
.arg("-p")
|
||||
.arg("-r")
|
||||
.arg("-t")
|
||||
.arg("-T")
|
||||
.arg("-u")
|
||||
.succeeds()
|
||||
.stdout_is(expected.stdout_str());
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--all")
|
||||
.succeeds()
|
||||
.stdout_is(expected.stdout_str());
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_all() {
|
||||
for opt in vec!["-a", "--all"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.succeeds()
|
||||
.stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,6 +239,6 @@ fn expected_result(arg: &str) -> String {
|
|||
.cmd_keepenv(util_name!())
|
||||
.env("LANGUAGE", "C")
|
||||
.args(&[arg])
|
||||
.run()
|
||||
.succeeds()
|
||||
.stdout_move_str()
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ impl CmdResult {
|
|||
|
||||
/// asserts that the command's exit code is the same as the given one
|
||||
pub fn status_code(&self, code: i32) -> &CmdResult {
|
||||
assert!(self.code == Some(code));
|
||||
assert_eq!(self.code, Some(code));
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -295,12 +295,22 @@ impl CmdResult {
|
|||
}
|
||||
|
||||
pub fn stdout_contains<T: AsRef<str>>(&self, cmp: T) -> &CmdResult {
|
||||
assert!(self.stdout_str().contains(cmp.as_ref()));
|
||||
assert!(
|
||||
self.stdout_str().contains(cmp.as_ref()),
|
||||
"'{}' does not contain '{}'",
|
||||
self.stdout_str(),
|
||||
cmp.as_ref()
|
||||
);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn stderr_contains<T: AsRef<str>>(&self, cmp: T) -> &CmdResult {
|
||||
assert!(self.stderr_str().contains(cmp.as_ref()));
|
||||
assert!(
|
||||
self.stderr_str().contains(cmp.as_ref()),
|
||||
"'{}' does not contain '{}'",
|
||||
self.stderr_str(),
|
||||
cmp.as_ref()
|
||||
);
|
||||
self
|
||||
}
|
||||
|
||||
|
|
0
tests/fixtures/wc/emptyfile.txt
vendored
Normal file
0
tests/fixtures/wc/emptyfile.txt
vendored
Normal file
100
tests/fixtures/wc/manyemptylines.txt
vendored
Normal file
100
tests/fixtures/wc/manyemptylines.txt
vendored
Normal file
|
@ -0,0 +1,100 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
1
tests/fixtures/wc/notrailingnewline.txt
vendored
Normal file
1
tests/fixtures/wc/notrailingnewline.txt
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
a
|
1
tests/fixtures/wc/onelongemptyline.txt
vendored
Normal file
1
tests/fixtures/wc/onelongemptyline.txt
vendored
Normal file
File diff suppressed because one or more lines are too long
1
tests/fixtures/wc/onelongword.txt
vendored
Normal file
1
tests/fixtures/wc/onelongword.txt
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue