mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 20:17:45 +00:00
Merge branch 'master' of https://github.com/uutils/coreutils
This commit is contained in:
commit
4c395146dd
116 changed files with 3865 additions and 1614 deletions
|
@ -1,4 +1,7 @@
|
|||
use crate::common::util::*;
|
||||
#[cfg(unix)]
|
||||
use std::fs::OpenOptions;
|
||||
#[cfg(unix)]
|
||||
use std::io::Read;
|
||||
|
||||
#[test]
|
||||
|
@ -26,7 +29,7 @@ fn test_no_options() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
#[cfg(any(target_vendor = "apple", target_os = "linux", target_os = "android"))]
|
||||
fn test_no_options_big_input() {
|
||||
for &n in &[
|
||||
0,
|
||||
|
@ -54,7 +57,6 @@ fn test_no_options_big_input() {
|
|||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_fifo_symlink() {
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::thread;
|
||||
|
||||
|
@ -85,6 +87,74 @@ fn test_fifo_symlink() {
|
|||
thread.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_piped_to_regular_file() {
|
||||
use std::fs::read_to_string;
|
||||
|
||||
for &append in &[true, false] {
|
||||
let s = TestScenario::new(util_name!());
|
||||
let file_path = s.fixtures.plus("file.txt");
|
||||
|
||||
{
|
||||
let file = OpenOptions::new()
|
||||
.create_new(true)
|
||||
.write(true)
|
||||
.append(append)
|
||||
.open(&file_path)
|
||||
.unwrap();
|
||||
|
||||
s.ucmd()
|
||||
.set_stdout(file)
|
||||
.pipe_in_fixture("alpha.txt")
|
||||
.succeeds();
|
||||
}
|
||||
let contents = read_to_string(&file_path).unwrap();
|
||||
assert_eq!(contents, "abcde\nfghij\nklmno\npqrst\nuvwxyz\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_piped_to_dev_null() {
|
||||
for &append in &[true, false] {
|
||||
let s = TestScenario::new(util_name!());
|
||||
{
|
||||
let dev_null = OpenOptions::new()
|
||||
.write(true)
|
||||
.append(append)
|
||||
.open("/dev/null")
|
||||
.unwrap();
|
||||
|
||||
s.ucmd()
|
||||
.set_stdout(dev_null)
|
||||
.pipe_in_fixture("alpha.txt")
|
||||
.succeeds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
|
||||
fn test_piped_to_dev_full() {
|
||||
for &append in &[true, false] {
|
||||
let s = TestScenario::new(util_name!());
|
||||
{
|
||||
let dev_full = OpenOptions::new()
|
||||
.write(true)
|
||||
.append(append)
|
||||
.open("/dev/full")
|
||||
.unwrap();
|
||||
|
||||
s.ucmd()
|
||||
.set_stdout(dev_full)
|
||||
.pipe_in_fixture("alpha.txt")
|
||||
.fails()
|
||||
.stderr_contains(&"No space left on device".to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_directory() {
|
||||
let s = TestScenario::new(util_name!());
|
||||
|
@ -327,6 +397,7 @@ fn test_dev_full_show_all() {
|
|||
#[cfg(unix)]
|
||||
fn test_domain_socket() {
|
||||
use std::io::prelude::*;
|
||||
use std::sync::{Arc, Barrier};
|
||||
use std::thread;
|
||||
use tempdir::TempDir;
|
||||
use unix_socket::UnixListener;
|
||||
|
@ -335,17 +406,23 @@ fn test_domain_socket() {
|
|||
let socket_path = dir.path().join("sock");
|
||||
let listener = UnixListener::bind(&socket_path).expect("failed to create socket");
|
||||
|
||||
// use a barrier to ensure we don't run cat before the listener is setup
|
||||
let barrier = Arc::new(Barrier::new(2));
|
||||
let barrier2 = Arc::clone(&barrier);
|
||||
|
||||
let thread = thread::spawn(move || {
|
||||
let mut stream = listener.accept().expect("failed to accept connection").0;
|
||||
barrier2.wait();
|
||||
stream
|
||||
.write_all(b"a\tb")
|
||||
.expect("failed to write test data");
|
||||
});
|
||||
|
||||
new_ucmd!()
|
||||
.args(&[socket_path])
|
||||
.succeeds()
|
||||
.stdout_only("a\tb");
|
||||
let child = new_ucmd!().args(&[socket_path]).run_no_wait();
|
||||
barrier.wait();
|
||||
let stdout = &child.wait_with_output().unwrap().stdout.clone();
|
||||
let output = String::from_utf8_lossy(&stdout);
|
||||
assert_eq!("a\tb", output);
|
||||
|
||||
thread.join().unwrap();
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ fn test_reference() {
|
|||
// skip for root or MS-WSL
|
||||
// * MS-WSL is bugged (as of 2019-12-25), allowing non-root accounts su-level privileges for `chgrp`
|
||||
// * for MS-WSL, succeeds and stdout == 'group of /etc retained as root'
|
||||
if !(get_effective_gid() == 0 || is_wsl()) {
|
||||
if !(get_effective_gid() == 0 || uucore::os::is_wsl_1()) {
|
||||
new_ucmd!()
|
||||
.arg("-v")
|
||||
.arg("--reference=/etc/passwd")
|
||||
|
|
|
@ -47,7 +47,7 @@ fn run_single_test(test: &TestCase, at: AtPath, mut ucmd: UCommand) {
|
|||
ucmd.arg(arg);
|
||||
}
|
||||
let r = ucmd.run();
|
||||
if !r.success {
|
||||
if !r.succeeded() {
|
||||
println!("{}", r.stderr_str());
|
||||
panic!("{:?}: failed", ucmd.raw);
|
||||
}
|
||||
|
|
|
@ -4,14 +4,11 @@ use crate::common::util::*;
|
|||
fn test_missing_operand() {
|
||||
let result = new_ucmd!().run();
|
||||
|
||||
assert_eq!(
|
||||
true,
|
||||
result
|
||||
.stderr
|
||||
.starts_with("error: The following required arguments were not provided")
|
||||
);
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.starts_with("error: The following required arguments were not provided"));
|
||||
|
||||
assert_eq!(true, result.stderr.contains("<newroot>"));
|
||||
assert!(result.stderr_str().contains("<newroot>"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -20,14 +17,11 @@ fn test_enter_chroot_fails() {
|
|||
|
||||
at.mkdir("jail");
|
||||
|
||||
let result = ucmd.arg("jail").run();
|
||||
let result = ucmd.arg("jail").fails();
|
||||
|
||||
assert_eq!(
|
||||
true,
|
||||
result.stderr.starts_with(
|
||||
"chroot: error: cannot chroot to jail: Operation not permitted (os error 1)"
|
||||
)
|
||||
)
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.starts_with("chroot: error: cannot chroot to jail: Operation not permitted (os error 1)"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -47,19 +41,18 @@ fn test_invalid_user_spec() {
|
|||
|
||||
at.mkdir("a");
|
||||
|
||||
let result = ucmd.arg("a").arg("--userspec=ARABA:").run();
|
||||
let result = ucmd.arg("a").arg("--userspec=ARABA:").fails();
|
||||
|
||||
assert_eq!(
|
||||
true,
|
||||
result.stderr.starts_with("chroot: error: invalid userspec")
|
||||
);
|
||||
assert!(result
|
||||
.stderr_str()
|
||||
.starts_with("chroot: error: invalid userspec"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_preference_of_userspec() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let result = scene.cmd("whoami").run();
|
||||
if is_ci() && result.stderr.contains("No such user/group") {
|
||||
if is_ci() && result.stderr_str().contains("No such user/group") {
|
||||
// In the CI, some server are failing to return whoami.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
return;
|
||||
|
@ -73,7 +66,7 @@ fn test_preference_of_userspec() {
|
|||
println!("result.stdout = {}", result.stdout_str());
|
||||
println!("result.stderr = {}", result.stderr_str());
|
||||
|
||||
if is_ci() && result.stderr.contains("cannot find name for user ID") {
|
||||
if is_ci() && result.stderr_str().contains("cannot find name for user ID") {
|
||||
// In the CI, some server are failing to return id.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
return;
|
||||
|
|
|
@ -42,13 +42,9 @@ static TEST_MOUNT_OTHER_FILESYSTEM_FILE: &str = "mount/DO_NOT_copy_me.txt";
|
|||
fn test_cp_cp() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
// Invoke our binary to make the copy.
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
|
||||
// Check that the exit code represents a successful copy.
|
||||
assert!(result.success);
|
||||
.succeeds();
|
||||
|
||||
// Check the content of the destination file that was copied.
|
||||
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
|
||||
|
@ -57,12 +53,9 @@ fn test_cp_cp() {
|
|||
#[test]
|
||||
fn test_cp_existing_target() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_EXISTING_FILE)
|
||||
.run();
|
||||
|
||||
assert!(result.success);
|
||||
.succeeds();
|
||||
|
||||
// Check the content of the destination file
|
||||
assert_eq!(at.read(TEST_EXISTING_FILE), "Hello, World!\n");
|
||||
|
@ -74,52 +67,41 @@ fn test_cp_existing_target() {
|
|||
#[test]
|
||||
fn test_cp_duplicate_files() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
|
||||
assert!(result.success);
|
||||
assert!(result.stderr.contains("specified more than once"));
|
||||
.succeeds()
|
||||
.stderr_contains("specified more than once");
|
||||
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_multiple_files_target_is_file() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
new_ucmd!()
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_EXISTING_FILE)
|
||||
.run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result.stderr.contains("not a directory"));
|
||||
.fails()
|
||||
.stderr_contains("not a directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_directory_not_recursive() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
new_ucmd!()
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result.stderr.contains("omitting directory"));
|
||||
.fails()
|
||||
.stderr_contains("omitting directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_multiple_files() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
|
||||
assert_eq!(at.read(TEST_HOW_ARE_YOU_DEST), "How are you?\n");
|
||||
}
|
||||
|
@ -129,14 +111,11 @@ fn test_cp_multiple_files() {
|
|||
#[cfg(not(macos))]
|
||||
fn test_cp_recurse() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd
|
||||
.arg("-r")
|
||||
ucmd.arg("-r")
|
||||
.arg(TEST_COPY_FROM_FOLDER)
|
||||
.arg(TEST_COPY_TO_FOLDER_NEW)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
// Check the content of the destination file that was copied.
|
||||
assert_eq!(at.read(TEST_COPY_TO_FOLDER_NEW_FILE), "Hello, World!\n");
|
||||
}
|
||||
|
@ -144,14 +123,10 @@ fn test_cp_recurse() {
|
|||
#[test]
|
||||
fn test_cp_with_dirs_t() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
//using -t option
|
||||
let result_to_dir_t = ucmd
|
||||
.arg("-t")
|
||||
ucmd.arg("-t")
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.run();
|
||||
assert!(result_to_dir_t.success);
|
||||
.succeeds();
|
||||
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
|
||||
}
|
||||
|
||||
|
@ -162,63 +137,52 @@ fn test_cp_with_dirs() {
|
|||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
//using -t option
|
||||
let result_to_dir = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
assert!(result_to_dir.success);
|
||||
.succeeds();
|
||||
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
|
||||
|
||||
let result_from_dir = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg(TEST_COPY_FROM_FOLDER_FILE)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
assert!(result_from_dir.success);
|
||||
.succeeds();
|
||||
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_arg_target_directory() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("-t")
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_arg_no_target_directory() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
new_ucmd!()
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("-v")
|
||||
.arg("-T")
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result.stderr.contains("cannot overwrite directory"));
|
||||
.fails()
|
||||
.stderr_contains("cannot overwrite directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_arg_interactive() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
new_ucmd!()
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.arg("-i")
|
||||
.pipe_in("N\n")
|
||||
.run();
|
||||
|
||||
assert!(result.success);
|
||||
assert!(result.stderr.contains("Not overwriting"));
|
||||
.succeeds()
|
||||
.stderr_contains("Not overwriting");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -227,39 +191,33 @@ fn test_cp_arg_link() {
|
|||
use std::os::linux::fs::MetadataExt;
|
||||
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--link")
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.metadata(TEST_HELLO_WORLD_SOURCE).st_nlink(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_arg_symlink() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--symbolic-link")
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert!(at.is_symlink(TEST_HELLO_WORLD_DEST));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_arg_no_clobber() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--no-clobber")
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n");
|
||||
}
|
||||
|
||||
|
@ -267,34 +225,31 @@ fn test_cp_arg_no_clobber() {
|
|||
fn test_cp_arg_no_clobber_twice() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
at.touch("source.txt");
|
||||
let result = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--no-clobber")
|
||||
.arg("source.txt")
|
||||
.arg("dest.txt")
|
||||
.run();
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
println!("stderr = {:?}", result.stderr_str());
|
||||
println!("stdout = {:?}", result.stdout_str());
|
||||
assert!(result.success);
|
||||
assert!(result.stderr.is_empty());
|
||||
assert_eq!(at.read("source.txt"), "");
|
||||
|
||||
at.append("source.txt", "some-content");
|
||||
let result = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--no-clobber")
|
||||
.arg("source.txt")
|
||||
.arg("dest.txt")
|
||||
.run();
|
||||
.succeeds()
|
||||
.stdout_does_not_contain("Not overwriting");
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read("source.txt"), "some-content");
|
||||
// Should be empty as the "no-clobber" should keep
|
||||
// the previous version
|
||||
assert_eq!(at.read("dest.txt"), "");
|
||||
assert!(!result.stderr.contains("Not overwriting"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -311,16 +266,11 @@ fn test_cp_arg_force() {
|
|||
permissions.set_readonly(true);
|
||||
set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();
|
||||
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--force")
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
println!("{:?}", result.stderr_str());
|
||||
println!("{:?}", result.stdout_str());
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
|
||||
}
|
||||
|
||||
|
@ -342,13 +292,11 @@ fn test_cp_arg_remove_destination() {
|
|||
permissions.set_readonly(true);
|
||||
set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();
|
||||
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--remove-destination")
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
|
||||
}
|
||||
|
||||
|
@ -356,13 +304,11 @@ fn test_cp_arg_remove_destination() {
|
|||
fn test_cp_arg_backup() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--backup")
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
|
||||
assert_eq!(
|
||||
at.read(&*format!("{}~", TEST_HOW_ARE_YOU_SOURCE)),
|
||||
|
@ -374,14 +320,12 @@ fn test_cp_arg_backup() {
|
|||
fn test_cp_arg_suffix() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--suffix")
|
||||
.arg(".bak")
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
|
||||
assert_eq!(
|
||||
at.read(&*format!("{}.bak", TEST_HOW_ARE_YOU_SOURCE)),
|
||||
|
@ -391,9 +335,8 @@ fn test_cp_arg_suffix() {
|
|||
|
||||
#[test]
|
||||
fn test_cp_deref_conflicting_options() {
|
||||
let (_at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
ucmd.arg("-LP")
|
||||
new_ucmd!()
|
||||
.arg("-LP")
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.fails();
|
||||
|
@ -401,8 +344,7 @@ fn test_cp_deref_conflicting_options() {
|
|||
|
||||
#[test]
|
||||
fn test_cp_deref() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
#[cfg(not(windows))]
|
||||
let _r = fs::symlink(
|
||||
|
@ -415,16 +357,12 @@ fn test_cp_deref() {
|
|||
at.subdir.join(TEST_HELLO_WORLD_SOURCE_SYMLINK),
|
||||
);
|
||||
//using -L option
|
||||
let result = scene
|
||||
.ucmd()
|
||||
.arg("-L")
|
||||
ucmd.arg("-L")
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_HELLO_WORLD_SOURCE_SYMLINK)
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
// Check that the exit code represents a successful copy.
|
||||
assert!(result.success);
|
||||
let path_to_new_symlink = at
|
||||
.subdir
|
||||
.join(TEST_COPY_TO_FOLDER)
|
||||
|
@ -444,8 +382,7 @@ fn test_cp_deref() {
|
|||
}
|
||||
#[test]
|
||||
fn test_cp_no_deref() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
#[cfg(not(windows))]
|
||||
let _r = fs::symlink(
|
||||
|
@ -458,16 +395,12 @@ fn test_cp_no_deref() {
|
|||
at.subdir.join(TEST_HELLO_WORLD_SOURCE_SYMLINK),
|
||||
);
|
||||
//using -P option
|
||||
let result = scene
|
||||
.ucmd()
|
||||
.arg("-P")
|
||||
ucmd.arg("-P")
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_HELLO_WORLD_SOURCE_SYMLINK)
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
// Check that the exit code represents a successful copy.
|
||||
assert!(result.success);
|
||||
let path_to_new_symlink = at
|
||||
.subdir
|
||||
.join(TEST_COPY_TO_FOLDER)
|
||||
|
@ -490,14 +423,10 @@ fn test_cp_strip_trailing_slashes() {
|
|||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
//using --strip-trailing-slashes option
|
||||
let result = ucmd
|
||||
.arg("--strip-trailing-slashes")
|
||||
ucmd.arg("--strip-trailing-slashes")
|
||||
.arg(format!("{}/", TEST_HELLO_WORLD_SOURCE))
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
|
||||
// Check that the exit code represents a successful copy.
|
||||
assert!(result.success);
|
||||
.succeeds();
|
||||
|
||||
// Check the content of the destination file that was copied.
|
||||
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
|
||||
|
@ -507,14 +436,11 @@ fn test_cp_strip_trailing_slashes() {
|
|||
fn test_cp_parents() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd
|
||||
.arg("--parents")
|
||||
ucmd.arg("--parents")
|
||||
.arg(TEST_COPY_FROM_FOLDER_FILE)
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
// Check the content of the destination file that was copied.
|
||||
assert_eq!(
|
||||
at.read(&format!(
|
||||
"{}/{}",
|
||||
|
@ -528,14 +454,12 @@ fn test_cp_parents() {
|
|||
fn test_cp_parents_multiple_files() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd
|
||||
.arg("--parents")
|
||||
ucmd.arg("--parents")
|
||||
.arg(TEST_COPY_FROM_FOLDER_FILE)
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
at.read(&format!(
|
||||
"{}/{}",
|
||||
|
@ -554,20 +478,12 @@ fn test_cp_parents_multiple_files() {
|
|||
|
||||
#[test]
|
||||
fn test_cp_parents_dest_not_directory() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd
|
||||
new_ucmd!()
|
||||
.arg("--parents")
|
||||
.arg(TEST_COPY_FROM_FOLDER_FILE)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
println!("{:?}", result);
|
||||
|
||||
// Check that we did not succeed in copying.
|
||||
assert!(!result.success);
|
||||
assert!(result
|
||||
.stderr
|
||||
.contains("with --parents, the destination must be a directory"));
|
||||
.fails()
|
||||
.stderr_contains("with --parents, the destination must be a directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -594,18 +510,14 @@ fn test_cp_deref_folder_to_folder() {
|
|||
assert!(env::set_current_dir(&cwd).is_ok());
|
||||
|
||||
//using -P -R option
|
||||
let result = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-L")
|
||||
.arg("-R")
|
||||
.arg("-v")
|
||||
.arg(TEST_COPY_FROM_FOLDER)
|
||||
.arg(TEST_COPY_TO_FOLDER_NEW)
|
||||
.run();
|
||||
println!("cp output {}", result.stdout_str());
|
||||
|
||||
// Check that the exit code represents a successful copy.
|
||||
assert!(result.success);
|
||||
.succeeds();
|
||||
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
|
@ -698,18 +610,14 @@ fn test_cp_no_deref_folder_to_folder() {
|
|||
assert!(env::set_current_dir(&cwd).is_ok());
|
||||
|
||||
//using -P -R option
|
||||
let result = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-P")
|
||||
.arg("-R")
|
||||
.arg("-v")
|
||||
.arg(TEST_COPY_FROM_FOLDER)
|
||||
.arg(TEST_COPY_TO_FOLDER_NEW)
|
||||
.run();
|
||||
println!("cp output {}", result.stdout_str());
|
||||
|
||||
// Check that the exit code represents a successful copy.
|
||||
assert!(result.success);
|
||||
.succeeds();
|
||||
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
|
@ -791,13 +699,11 @@ fn test_cp_archive() {
|
|||
previous,
|
||||
)
|
||||
.unwrap();
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--archive")
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
|
||||
|
||||
let metadata = std_fs::metadata(at.subdir.join(TEST_HELLO_WORLD_SOURCE)).unwrap();
|
||||
|
@ -807,11 +713,10 @@ fn test_cp_archive() {
|
|||
let creation2 = metadata2.modified().unwrap();
|
||||
|
||||
let scene2 = TestScenario::new("ls");
|
||||
let result = scene2.cmd("ls").arg("-al").arg(at.subdir).run();
|
||||
let result = scene2.cmd("ls").arg("-al").arg(at.subdir).succeeds();
|
||||
|
||||
println!("ls dest {}", result.stdout_str());
|
||||
assert_eq!(creation, creation2);
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -850,11 +755,10 @@ fn test_cp_archive_recursive() {
|
|||
// Back to the initial cwd (breaks the other tests)
|
||||
assert!(env::set_current_dir(&cwd).is_ok());
|
||||
|
||||
let resultg = ucmd
|
||||
.arg("--archive")
|
||||
ucmd.arg("--archive")
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.arg(TEST_COPY_TO_FOLDER_NEW)
|
||||
.run();
|
||||
.fails(); // fails for now
|
||||
|
||||
let scene2 = TestScenario::new("ls");
|
||||
let result = scene2
|
||||
|
@ -865,7 +769,6 @@ fn test_cp_archive_recursive() {
|
|||
|
||||
println!("ls dest {}", result.stdout_str());
|
||||
|
||||
let scene2 = TestScenario::new("ls");
|
||||
let result = scene2
|
||||
.cmd("ls")
|
||||
.arg("-al")
|
||||
|
@ -910,9 +813,6 @@ fn test_cp_archive_recursive() {
|
|||
.join("2.link")
|
||||
.to_string_lossy()
|
||||
));
|
||||
|
||||
// fails for now
|
||||
assert!(resultg.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -928,13 +828,11 @@ fn test_cp_preserve_timestamps() {
|
|||
previous,
|
||||
)
|
||||
.unwrap();
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--preserve=timestamps")
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
|
||||
|
||||
let metadata = std_fs::metadata(at.subdir.join(TEST_HELLO_WORLD_SOURCE)).unwrap();
|
||||
|
@ -948,7 +846,6 @@ fn test_cp_preserve_timestamps() {
|
|||
|
||||
println!("ls dest {}", result.stdout_str());
|
||||
assert_eq!(creation, creation2);
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -966,13 +863,11 @@ fn test_cp_dont_preserve_timestamps() {
|
|||
.unwrap();
|
||||
sleep(Duration::from_secs(3));
|
||||
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
ucmd.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--no-preserve=timestamps")
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "Hello, World!\n");
|
||||
|
||||
let metadata = std_fs::metadata(at.subdir.join(TEST_HELLO_WORLD_SOURCE)).unwrap();
|
||||
|
@ -992,7 +887,6 @@ fn test_cp_dont_preserve_timestamps() {
|
|||
// Some margins with time check
|
||||
assert!(res.as_secs() > 3595);
|
||||
assert!(res.as_secs() < 3605);
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1017,7 +911,7 @@ fn test_cp_one_file_system() {
|
|||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
// Test must be run as root (or with `sudo -E`)
|
||||
if scene.cmd("whoami").run().stdout != "root\n" {
|
||||
if scene.cmd("whoami").run().stdout_str() != "root\n" {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1042,17 +936,16 @@ fn test_cp_one_file_system() {
|
|||
at_src.touch(TEST_MOUNT_OTHER_FILESYSTEM_FILE);
|
||||
|
||||
// Begin testing -x flag
|
||||
let result = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-rx")
|
||||
.arg(TEST_MOUNT_COPY_FROM_FOLDER)
|
||||
.arg(TEST_COPY_TO_FOLDER_NEW)
|
||||
.run();
|
||||
.succeeds();
|
||||
|
||||
// Ditch the mount before the asserts
|
||||
scene.cmd("umount").arg(mountpoint_path).succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert!(!at_dst.file_exists(TEST_MOUNT_OTHER_FILESYSTEM_FILE));
|
||||
// Check if the other files were copied from the source folder hirerarchy
|
||||
for entry in WalkDir::new(at_src.as_string()) {
|
||||
|
@ -1072,3 +965,59 @@ fn test_cp_one_file_system() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
fn test_cp_reflink_always() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
.arg("--reflink=always")
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_EXISTING_FILE)
|
||||
.run();
|
||||
|
||||
if result.succeeded() {
|
||||
// Check the content of the destination file
|
||||
assert_eq!(at.read(TEST_EXISTING_FILE), "Hello, World!\n");
|
||||
} else {
|
||||
// Older Linux versions do not support cloning.
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
fn test_cp_reflink_auto() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
ucmd.arg("--reflink=auto")
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_EXISTING_FILE)
|
||||
.succeeds();
|
||||
|
||||
// Check the content of the destination file
|
||||
assert_eq!(at.read(TEST_EXISTING_FILE), "Hello, World!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
fn test_cp_reflink_never() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
ucmd.arg("--reflink=never")
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_EXISTING_FILE)
|
||||
.succeeds();
|
||||
|
||||
// Check the content of the destination file
|
||||
assert_eq!(at.read(TEST_EXISTING_FILE), "Hello, World!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "linux", target_os = "macos"))]
|
||||
fn test_cp_reflink_bad() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let _result = ucmd
|
||||
.arg("--reflink=bad")
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_EXISTING_FILE)
|
||||
.fails()
|
||||
.stderr_contains("invalid argument");
|
||||
}
|
||||
|
|
|
@ -7,174 +7,147 @@ use rust_users::*;
|
|||
|
||||
#[test]
|
||||
fn test_date_email() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--rfc-email").run();
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg("--rfc-email").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_email2() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("-R").run();
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg("-R").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_rfc_3339() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let mut result = scene.ucmd().arg("--rfc-3339=ns").succeeds();
|
||||
let rfc_regexp = concat!(
|
||||
r#"(\d+)-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])\s([01]\d|2[0-3]):"#,
|
||||
r#"([0-5]\d):([0-5]\d|60)(\.\d+)?(([Zz])|([\+|\-]([01]\d|2[0-3])))"#
|
||||
);
|
||||
let re = Regex::new(rfc_regexp).unwrap();
|
||||
|
||||
// Check that the output matches the regexp
|
||||
let rfc_regexp = r"(\d+)-(0[1-9]|1[012])-(0[1-9]|[12]\d|3[01])\s([01]\d|2[0-3]):([0-5]\d):([0-5]\d|60)(\.\d+)?(([Zz])|([\+|\-]([01]\d|2[0-3])))";
|
||||
let re = Regex::new(rfc_regexp).unwrap();
|
||||
assert!(re.is_match(&result.stdout_str().trim()));
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--rfc-3339=ns")
|
||||
.succeeds()
|
||||
.stdout_matches(&re);
|
||||
|
||||
result = scene.ucmd().arg("--rfc-3339=seconds").succeeds();
|
||||
|
||||
// Check that the output matches the regexp
|
||||
let re = Regex::new(rfc_regexp).unwrap();
|
||||
assert!(re.is_match(&result.stdout_str().trim()));
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--rfc-3339=seconds")
|
||||
.succeeds()
|
||||
.stdout_matches(&re);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_rfc_8601() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--iso-8601=ns").run();
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg("--iso-8601=ns").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_rfc_8601_second() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--iso-8601=second").run();
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg("--iso-8601=second").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_utc() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--utc").run();
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg("--utc").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_universal() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--universal").run();
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg("--universal").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_format_y() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let mut result = scene.ucmd().arg("+%Y").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
let mut re = Regex::new(r"^\d{4}$").unwrap();
|
||||
assert!(re.is_match(&result.stdout_str().trim()));
|
||||
scene.ucmd().arg("+%Y").succeeds().stdout_matches(&re);
|
||||
|
||||
result = scene.ucmd().arg("+%y").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
re = Regex::new(r"^\d{2}$").unwrap();
|
||||
assert!(re.is_match(&result.stdout_str().trim()));
|
||||
scene.ucmd().arg("+%y").succeeds().stdout_matches(&re);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_format_m() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let mut result = scene.ucmd().arg("+%b").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
let mut re = Regex::new(r"\S+").unwrap();
|
||||
assert!(re.is_match(&result.stdout_str().trim()));
|
||||
scene.ucmd().arg("+%b").succeeds().stdout_matches(&re);
|
||||
|
||||
result = scene.ucmd().arg("+%m").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
re = Regex::new(r"^\d{2}$").unwrap();
|
||||
assert!(re.is_match(&result.stdout_str().trim()));
|
||||
scene.ucmd().arg("+%m").succeeds().stdout_matches(&re);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_format_day() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let mut result = scene.ucmd().arg("+%a").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
let mut re = Regex::new(r"\S+").unwrap();
|
||||
assert!(re.is_match(&result.stdout_str().trim()));
|
||||
|
||||
result = scene.ucmd().arg("+%A").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
scene.ucmd().arg("+%a").succeeds().stdout_matches(&re);
|
||||
|
||||
re = Regex::new(r"\S+").unwrap();
|
||||
assert!(re.is_match(&result.stdout_str().trim()));
|
||||
scene.ucmd().arg("+%A").succeeds().stdout_matches(&re);
|
||||
|
||||
result = scene.ucmd().arg("+%u").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
re = Regex::new(r"^\d{1}$").unwrap();
|
||||
assert!(re.is_match(&result.stdout_str().trim()));
|
||||
scene.ucmd().arg("+%u").succeeds().stdout_matches(&re);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_format_full_day() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let result = scene.ucmd().arg("+'%a %Y-%m-%d'").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
let re = Regex::new(r"\S+ \d{4}-\d{2}-\d{2}").unwrap();
|
||||
assert!(re.is_match(&result.stdout_str().trim()));
|
||||
new_ucmd!()
|
||||
.arg("+'%a %Y-%m-%d'")
|
||||
.succeeds()
|
||||
.stdout_matches(&re);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(unix, not(target_os = "macos")))]
|
||||
fn test_date_set_valid() {
|
||||
if get_effective_uid() == 0 {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
new_ucmd!()
|
||||
.arg("--set")
|
||||
.arg("2020-03-12 13:30:00+08:00")
|
||||
.succeeds();
|
||||
result.no_stdout().no_stderr();
|
||||
.succeeds()
|
||||
.no_stdout()
|
||||
.no_stderr();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(windows, all(unix, not(target_os = "macos"))))]
|
||||
fn test_date_set_invalid() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--set").arg("123abcd").fails();
|
||||
let result = result.no_stdout();
|
||||
assert!(result.stderr.starts_with("date: invalid date "));
|
||||
let result = new_ucmd!().arg("--set").arg("123abcd").fails();
|
||||
result.no_stdout();
|
||||
assert!(result.stderr_str().starts_with("date: invalid date "));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(all(unix, not(target_os = "macos")))]
|
||||
fn test_date_set_permissions_error() {
|
||||
if !(get_effective_uid() == 0 || is_wsl()) {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--set").arg("2020-03-11 21:45:00+08:00").fails();
|
||||
let result = result.no_stdout();
|
||||
assert!(result.stderr.starts_with("date: cannot set date: "));
|
||||
if !(get_effective_uid() == 0 || uucore::os::is_wsl_1()) {
|
||||
let result = new_ucmd!()
|
||||
.arg("--set")
|
||||
.arg("2020-03-11 21:45:00+08:00")
|
||||
.fails();
|
||||
result.no_stdout();
|
||||
assert!(result.stderr_str().starts_with("date: cannot set date: "));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "macos")]
|
||||
fn test_date_set_mac_unavailable() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--set").arg("2020-03-11 21:45:00+08:00").fails();
|
||||
let result = result.no_stdout();
|
||||
let result = new_ucmd!()
|
||||
.arg("--set")
|
||||
.arg("2020-03-11 21:45:00+08:00")
|
||||
.fails();
|
||||
result.no_stdout();
|
||||
assert!(result
|
||||
.stderr
|
||||
.stderr_str()
|
||||
.starts_with("date: setting the date is not supported by macOS"));
|
||||
}
|
||||
|
||||
|
@ -183,13 +156,12 @@ fn test_date_set_mac_unavailable() {
|
|||
/// TODO: expected to fail currently; change to succeeds() when required.
|
||||
fn test_date_set_valid_2() {
|
||||
if get_effective_uid() == 0 {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
let result = new_ucmd!()
|
||||
.arg("--set")
|
||||
.arg("Sat 20 Mar 2021 14:53:01 AWST")
|
||||
.fails();
|
||||
let result = result.no_stdout();
|
||||
assert!(result.stderr.starts_with("date: invalid date "));
|
||||
result.no_stdout();
|
||||
assert!(result.stderr_str().starts_with("date: invalid date "));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,13 +170,12 @@ fn test_date_set_valid_2() {
|
|||
/// TODO: expected to fail currently; change to succeeds() when required.
|
||||
fn test_date_set_valid_3() {
|
||||
if get_effective_uid() == 0 {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
let result = new_ucmd!()
|
||||
.arg("--set")
|
||||
.arg("Sat 20 Mar 2021 14:53:01") // Local timezone
|
||||
.fails();
|
||||
let result = result.no_stdout();
|
||||
assert!(result.stderr.starts_with("date: invalid date "));
|
||||
result.no_stdout();
|
||||
assert!(result.stderr_str().starts_with("date: invalid date "));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,12 +184,11 @@ fn test_date_set_valid_3() {
|
|||
/// TODO: expected to fail currently; change to succeeds() when required.
|
||||
fn test_date_set_valid_4() {
|
||||
if get_effective_uid() == 0 {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
let result = new_ucmd!()
|
||||
.arg("--set")
|
||||
.arg("2020-03-11 21:45:00") // Local timezone
|
||||
.fails();
|
||||
let result = result.no_stdout();
|
||||
assert!(result.stderr.starts_with("date: invalid date "));
|
||||
result.no_stdout();
|
||||
assert!(result.stderr_str().starts_with("date: invalid date "));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,30 +2,22 @@ use crate::common::util::*;
|
|||
|
||||
#[test]
|
||||
fn test_df_compatible_no_size_arg() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("-a").run();
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg("-a").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_df_compatible() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("-ah").run();
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg("-ah").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_df_compatible_type() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("-aT").run();
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg("-aT").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_df_compatible_si() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("-aH").run();
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg("-aH").succeeds();
|
||||
}
|
||||
|
||||
// ToDO: more tests...
|
||||
|
|
|
@ -10,7 +10,7 @@ fn test_du_basics() {
|
|||
new_ucmd!().succeeds().no_stderr();
|
||||
}
|
||||
#[cfg(target_vendor = "apple")]
|
||||
fn _du_basics(s: String) {
|
||||
fn _du_basics(s: &str) {
|
||||
let answer = "32\t./subdir
|
||||
8\t./subdir/deeper
|
||||
24\t./subdir/links
|
||||
|
@ -30,11 +30,18 @@ fn _du_basics(s: &str) {
|
|||
|
||||
#[test]
|
||||
fn test_du_basics_subdir() {
|
||||
let (_at, mut ucmd) = at_and_ucmd!();
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let result = ucmd.arg(SUB_DIR).run();
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stderr, "");
|
||||
let result = scene.ucmd().arg(SUB_DIR).succeeds();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let result_reference = scene.cmd("du").arg(SUB_DIR).run();
|
||||
if result_reference.succeeded() {
|
||||
assert_eq!(result.stdout_str(), result_reference.stdout_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
_du_basics_subdir(result.stdout_str());
|
||||
}
|
||||
|
||||
|
@ -49,7 +56,7 @@ fn _du_basics_subdir(s: &str) {
|
|||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
fn _du_basics_subdir(s: &str) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
if !uucore::os::is_wsl_1() {
|
||||
assert_eq!(s, "8\tsubdir/deeper\n");
|
||||
} else {
|
||||
assert_eq!(s, "0\tsubdir/deeper\n");
|
||||
|
@ -58,26 +65,29 @@ fn _du_basics_subdir(s: &str) {
|
|||
|
||||
#[test]
|
||||
fn test_du_basics_bad_name() {
|
||||
let (_at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg("bad_name").run();
|
||||
assert_eq!(result.stdout_str(), "");
|
||||
assert_eq!(
|
||||
result.stderr,
|
||||
"du: error: bad_name: No such file or directory\n"
|
||||
);
|
||||
new_ucmd!()
|
||||
.arg("bad_name")
|
||||
.succeeds() // TODO: replace with ".fails()" once `du` is fixed
|
||||
.stderr_only("du: error: bad_name: No such file or directory\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_du_soft_link() {
|
||||
let ts = TestScenario::new("du");
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
let link = ts.ccmd("ln").arg("-s").arg(SUB_FILE).arg(SUB_LINK).run();
|
||||
assert!(link.success);
|
||||
at.symlink_file(SUB_FILE, SUB_LINK);
|
||||
|
||||
let result = ts.ucmd().arg(SUB_DIR_LINKS).run();
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stderr, "");
|
||||
let result = scene.ucmd().arg(SUB_DIR_LINKS).succeeds();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let result_reference = scene.cmd("du").arg(SUB_DIR_LINKS).run();
|
||||
if result_reference.succeeded() {
|
||||
assert_eq!(result.stdout_str(), result_reference.stdout_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
_du_soft_link(result.stdout_str());
|
||||
}
|
||||
|
||||
|
@ -93,7 +103,7 @@ fn _du_soft_link(s: &str) {
|
|||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
fn _du_soft_link(s: &str) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
if !uucore::os::is_wsl_1() {
|
||||
assert_eq!(s, "16\tsubdir/links\n");
|
||||
} else {
|
||||
assert_eq!(s, "8\tsubdir/links\n");
|
||||
|
@ -102,14 +112,23 @@ fn _du_soft_link(s: &str) {
|
|||
|
||||
#[test]
|
||||
fn test_du_hard_link() {
|
||||
let ts = TestScenario::new("du");
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let link = ts.ccmd("ln").arg(SUB_FILE).arg(SUB_LINK).run();
|
||||
assert!(link.success);
|
||||
let result_ln = scene.cmd("ln").arg(SUB_FILE).arg(SUB_LINK).run();
|
||||
if !result_ln.succeeded() {
|
||||
scene.ccmd("ln").arg(SUB_FILE).arg(SUB_LINK).succeeds();
|
||||
}
|
||||
|
||||
let result = ts.ucmd().arg(SUB_DIR_LINKS).run();
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stderr, "");
|
||||
let result = scene.ucmd().arg(SUB_DIR_LINKS).succeeds();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let result_reference = scene.cmd("du").arg(SUB_DIR_LINKS).run();
|
||||
if result_reference.succeeded() {
|
||||
assert_eq!(result.stdout_str(), result_reference.stdout_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
// We do not double count hard links as the inodes are identical
|
||||
_du_hard_link(result.stdout_str());
|
||||
}
|
||||
|
@ -125,7 +144,7 @@ fn _du_hard_link(s: &str) {
|
|||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
fn _du_hard_link(s: &str) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
if !uucore::os::is_wsl_1() {
|
||||
assert_eq!(s, "16\tsubdir/links\n");
|
||||
} else {
|
||||
assert_eq!(s, "8\tsubdir/links\n");
|
||||
|
@ -134,11 +153,23 @@ fn _du_hard_link(s: &str) {
|
|||
|
||||
#[test]
|
||||
fn test_du_d_flag() {
|
||||
let ts = TestScenario::new("du");
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let result = ts.ucmd().arg("-d").arg("1").run();
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stderr, "");
|
||||
let result = scene.ucmd().arg("-d1").succeeds();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let result_reference = scene.cmd("du").arg("-d1").run();
|
||||
if result_reference.succeeded() {
|
||||
assert_eq!(
|
||||
// TODO: gnu `du` doesn't use trailing "/" here
|
||||
// result.stdout_str(), result_reference.stdout_str()
|
||||
result.stdout_str().trim_end_matches("/\n"),
|
||||
result_reference.stdout_str().trim_end_matches("\n")
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_du_d_flag(result.stdout_str());
|
||||
}
|
||||
|
||||
|
@ -153,7 +184,7 @@ fn _du_d_flag(s: &str) {
|
|||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
fn _du_d_flag(s: &str) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
if !uucore::os::is_wsl_1() {
|
||||
assert_eq!(s, "28\t./subdir\n36\t./\n");
|
||||
} else {
|
||||
assert_eq!(s, "8\t./subdir\n8\t./\n");
|
||||
|
@ -162,9 +193,7 @@ fn _du_d_flag(s: &str) {
|
|||
|
||||
#[test]
|
||||
fn test_du_h_flag_empty_file() {
|
||||
let ts = TestScenario::new("du");
|
||||
|
||||
ts.ucmd()
|
||||
new_ucmd!()
|
||||
.arg("-h")
|
||||
.arg("empty.txt")
|
||||
.succeeds()
|
||||
|
@ -174,54 +203,61 @@ fn test_du_h_flag_empty_file() {
|
|||
#[cfg(feature = "touch")]
|
||||
#[test]
|
||||
fn test_du_time() {
|
||||
let ts = TestScenario::new("du");
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let touch = ts
|
||||
scene
|
||||
.ccmd("touch")
|
||||
.arg("-a")
|
||||
.arg("-m")
|
||||
.arg("-t")
|
||||
.arg("201505150000")
|
||||
.arg("date_test")
|
||||
.run();
|
||||
assert!(touch.success);
|
||||
.succeeds();
|
||||
|
||||
let result = ts.ucmd().arg("--time").arg("date_test").run();
|
||||
|
||||
// cleanup by removing test file
|
||||
ts.cmd("rm").arg("date_test").run();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stderr, "");
|
||||
assert_eq!(result.stdout, "0\t2015-05-15 00:00\tdate_test\n");
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--time")
|
||||
.arg("date_test")
|
||||
.succeeds()
|
||||
.stdout_only("0\t2015-05-15 00:00\tdate_test\n");
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[cfg(feature = "chmod")]
|
||||
#[test]
|
||||
fn test_du_no_permission() {
|
||||
let ts = TestScenario::new("du");
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
let chmod = ts.ccmd("chmod").arg("-r").arg(SUB_DIR_LINKS).run();
|
||||
println!("chmod output: {:?}", chmod);
|
||||
assert!(chmod.success);
|
||||
let result = ts.ucmd().arg(SUB_DIR_LINKS).run();
|
||||
at.mkdir_all(SUB_DIR_LINKS);
|
||||
|
||||
ts.ccmd("chmod").arg("+r").arg(SUB_DIR_LINKS).run();
|
||||
scene.ccmd("chmod").arg("-r").arg(SUB_DIR_LINKS).succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stderr,
|
||||
"du: cannot read directory ‘subdir/links‘: Permission denied (os error 13)\n"
|
||||
let result = scene.ucmd().arg(SUB_DIR_LINKS).run(); // TODO: replace with ".fails()" once `du` is fixed
|
||||
result.stderr_contains(
|
||||
"du: cannot read directory ‘subdir/links‘: Permission denied (os error 13)",
|
||||
);
|
||||
_du_no_permission(result.stdout);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let result_reference = scene.cmd("du").arg(SUB_DIR_LINKS).fails();
|
||||
if result_reference
|
||||
.stderr_str()
|
||||
.contains("du: cannot read directory 'subdir/links': Permission denied")
|
||||
{
|
||||
assert_eq!(result.stdout_str(), result_reference.stdout_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_du_no_permission(result.stdout_str());
|
||||
}
|
||||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
fn _du_no_permission(s: String) {
|
||||
fn _du_no_permission(s: &str) {
|
||||
assert_eq!(s, "0\tsubdir/links\n");
|
||||
}
|
||||
#[cfg(all(not(target_vendor = "apple"), not(target_os = "windows")))]
|
||||
fn _du_no_permission(s: String) {
|
||||
fn _du_no_permission(s: &str) {
|
||||
assert_eq!(s, "4\tsubdir/links\n");
|
||||
}
|
||||
|
|
|
@ -140,8 +140,11 @@ fn test_unset_variable() {
|
|||
|
||||
#[test]
|
||||
fn test_fail_null_with_program() {
|
||||
let out = new_ucmd!().arg("--null").arg("cd").fails().stderr;
|
||||
assert!(out.contains("cannot specify --null (-0) with command"));
|
||||
new_ucmd!()
|
||||
.arg("--null")
|
||||
.arg("cd")
|
||||
.fails()
|
||||
.stderr_contains("cannot specify --null (-0) with command");
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
|
|
|
@ -29,7 +29,7 @@ fn test_fmt_w_too_big() {
|
|||
.run();
|
||||
//.stdout_is_fixture("call_graph.expected");
|
||||
assert_eq!(
|
||||
result.stderr.trim(),
|
||||
result.stderr_str().trim(),
|
||||
"fmt: error: invalid width: '2501': Numerical result out of range"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ fn test_groups() {
|
|||
// As seems to be a configuration issue, ignoring it
|
||||
return;
|
||||
}
|
||||
assert!(result.success);
|
||||
result.success();
|
||||
assert!(!result.stdout_str().trim().is_empty());
|
||||
}
|
||||
|
||||
|
@ -30,16 +30,12 @@ fn test_groups_arg() {
|
|||
|
||||
println!("result.stdout = {}", result.stdout_str());
|
||||
println!("result.stderr = {}", result.stderr_str());
|
||||
assert!(result.success);
|
||||
result.success();
|
||||
assert!(!result.stdout_str().is_empty());
|
||||
let username = result.stdout_str().trim();
|
||||
|
||||
// call groups with the user name to check that we
|
||||
// are getting something
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg(username).run();
|
||||
println!("result.stdout = {}", result.stdout_str());
|
||||
println!("result.stderr = {}", result.stderr_str());
|
||||
assert!(result.success);
|
||||
new_ucmd!().arg(username).succeeds();
|
||||
assert!(!result.stdout_str().is_empty());
|
||||
}
|
||||
|
|
|
@ -156,14 +156,10 @@ fn test_negative_zero_bytes() {
|
|||
}
|
||||
#[test]
|
||||
fn test_no_such_file_or_directory() {
|
||||
let result = new_ucmd!().arg("no_such_file.toml").run();
|
||||
|
||||
assert_eq!(
|
||||
true,
|
||||
result
|
||||
.stderr
|
||||
.contains("cannot open 'no_such_file.toml' for reading: No such file or directory")
|
||||
)
|
||||
new_ucmd!()
|
||||
.arg("no_such_file.toml")
|
||||
.fails()
|
||||
.stderr_contains("cannot open 'no_such_file.toml' for reading: No such file or directory");
|
||||
}
|
||||
|
||||
// there was a bug not caught by previous tests
|
||||
|
|
|
@ -11,12 +11,10 @@ use std::thread::sleep;
|
|||
fn test_install_help() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
assert!(ucmd
|
||||
.arg("--help")
|
||||
ucmd.arg("--help")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
.contains("FLAGS:"));
|
||||
.stdout_contains("FLAGS:");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -59,13 +57,11 @@ fn test_install_failing_not_dir() {
|
|||
at.touch(file1);
|
||||
at.touch(file2);
|
||||
at.touch(file3);
|
||||
assert!(ucmd
|
||||
.arg(file1)
|
||||
ucmd.arg(file1)
|
||||
.arg(file2)
|
||||
.arg(file3)
|
||||
.fails()
|
||||
.stderr
|
||||
.contains("not a directory"));
|
||||
.stderr_contains("not a directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -77,13 +73,11 @@ fn test_install_unimplemented_arg() {
|
|||
|
||||
at.touch(file);
|
||||
at.mkdir(dir);
|
||||
assert!(ucmd
|
||||
.arg(context_arg)
|
||||
ucmd.arg(context_arg)
|
||||
.arg(file)
|
||||
.arg(dir)
|
||||
.fails()
|
||||
.stderr
|
||||
.contains("Unimplemented"));
|
||||
.stderr_contains("Unimplemented");
|
||||
|
||||
assert!(!at.file_exists(&format!("{}/{}", dir, file)));
|
||||
}
|
||||
|
@ -231,13 +225,11 @@ fn test_install_mode_failing() {
|
|||
|
||||
at.touch(file);
|
||||
at.mkdir(dir);
|
||||
assert!(ucmd
|
||||
.arg(file)
|
||||
ucmd.arg(file)
|
||||
.arg(dir)
|
||||
.arg(mode_arg)
|
||||
.fails()
|
||||
.stderr
|
||||
.contains("Invalid mode string: invalid digit found in string"));
|
||||
.stderr_contains("Invalid mode string: invalid digit found in string");
|
||||
|
||||
let dest_file = &format!("{}/{}", dir, file);
|
||||
assert!(at.file_exists(file));
|
||||
|
@ -336,7 +328,7 @@ fn test_install_target_new_file_with_owner() {
|
|||
.arg(format!("{}/{}", dir, file))
|
||||
.run();
|
||||
|
||||
if is_ci() && result.stderr.contains("error: no such user:") {
|
||||
if is_ci() && result.stderr_str().contains("error: no such user:") {
|
||||
// In the CI, some server are failing to return the user id.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
return;
|
||||
|
@ -359,7 +351,7 @@ fn test_install_target_new_file_failing_nonexistent_parent() {
|
|||
ucmd.arg(file1)
|
||||
.arg(format!("{}/{}", dir, file2))
|
||||
.fails()
|
||||
.stderr_contains(&"not a directory");
|
||||
.stderr_contains(&"No such file or directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -619,33 +611,64 @@ fn test_install_and_strip_with_program() {
|
|||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_install_and_strip_with_invalid_program() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let stderr = scene
|
||||
.ucmd()
|
||||
new_ucmd!()
|
||||
.arg("-s")
|
||||
.arg("--strip-program")
|
||||
.arg("/bin/date")
|
||||
.arg(strip_source_file())
|
||||
.arg(STRIP_TARGET_FILE)
|
||||
.fails()
|
||||
.stderr;
|
||||
assert!(stderr.contains("strip program failed"));
|
||||
.stderr_contains("strip program failed");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_install_and_strip_with_non_existent_program() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let stderr = scene
|
||||
.ucmd()
|
||||
new_ucmd!()
|
||||
.arg("-s")
|
||||
.arg("--strip-program")
|
||||
.arg("/usr/bin/non_existent_program")
|
||||
.arg(strip_source_file())
|
||||
.arg(STRIP_TARGET_FILE)
|
||||
.fails()
|
||||
.stderr;
|
||||
assert!(stderr.contains("No such file or directory"));
|
||||
.stderr_contains("No such file or directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_creating_leading_dirs() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
let source = "create_leading_test_file";
|
||||
let target = "dir1/dir2/dir3/test_file";
|
||||
|
||||
at.touch(source);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-D")
|
||||
.arg(source)
|
||||
.arg(at.plus(target))
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_install_creating_leading_dir_fails_on_long_name() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
let source = "create_leading_test_file";
|
||||
let target = format!("{}/test_file", "d".repeat(libc::PATH_MAX as usize + 1));
|
||||
|
||||
at.touch(source);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-D")
|
||||
.arg(source)
|
||||
.arg(at.plus(target.as_str()))
|
||||
.fails()
|
||||
.stderr_contains("failed to create");
|
||||
}
|
||||
|
|
|
@ -299,13 +299,11 @@ fn test_symlink_overwrite_dir_fail() {
|
|||
at.touch(path_a);
|
||||
at.mkdir(path_b);
|
||||
|
||||
assert!(
|
||||
ucmd.args(&["-s", "-T", path_a, path_b])
|
||||
.fails()
|
||||
.stderr
|
||||
.len()
|
||||
> 0
|
||||
);
|
||||
assert!(!ucmd
|
||||
.args(&["-s", "-T", path_a, path_b])
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -358,7 +356,11 @@ fn test_symlink_target_only() {
|
|||
|
||||
at.mkdir(dir);
|
||||
|
||||
assert!(ucmd.args(&["-s", "-t", dir]).fails().stderr.len() > 0);
|
||||
assert!(!ucmd
|
||||
.args(&["-s", "-t", dir])
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -9,7 +9,7 @@ fn test_normal() {
|
|||
for (key, value) in env::vars() {
|
||||
println!("{}: {}", key, value);
|
||||
}
|
||||
if (is_ci() || is_wsl()) && result.stderr_str().contains("error: no login name") {
|
||||
if (is_ci() || uucore::os::is_wsl_1()) && result.stderr_str().contains("error: no login name") {
|
||||
// ToDO: investigate WSL failure
|
||||
// In the CI, some server are failing to return logname.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
|
|
|
@ -103,6 +103,20 @@ fn test_ls_width() {
|
|||
.succeeds()
|
||||
.stdout_only("test-width-1\ntest-width-2\ntest-width-3\ntest-width-4\n");
|
||||
}
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-w=bad")
|
||||
.fails()
|
||||
.stderr_contains("invalid line width");
|
||||
|
||||
for option in &["-w 1a", "-w=1a", "--width=1a", "--width 1a"] {
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&option.split(" ").collect::<Vec<_>>())
|
||||
.fails()
|
||||
.stderr_only("ls: error: invalid line width: ‘1a’");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -436,6 +450,39 @@ fn test_ls_deref() {
|
|||
assert!(!re.is_match(result.stdout_str().trim()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ls_sort_none() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
at.touch("test-3");
|
||||
at.touch("test-1");
|
||||
at.touch("test-2");
|
||||
|
||||
// Order is not specified so we just check that it doesn't
|
||||
// give any errors.
|
||||
scene.ucmd().arg("--sort=none").succeeds();
|
||||
scene.ucmd().arg("-U").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ls_sort_name() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
at.touch("test-3");
|
||||
at.touch("test-1");
|
||||
at.touch("test-2");
|
||||
|
||||
let sep = if cfg!(unix) { "\n" } else { " " };
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--sort=name")
|
||||
.succeeds()
|
||||
.stdout_is(["test-1", "test-2", "test-3\n"].join(sep));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ls_order_size() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
@ -464,6 +511,18 @@ fn test_ls_order_size() {
|
|||
result.stdout_only("test-1\ntest-2\ntest-3\ntest-4\n");
|
||||
#[cfg(windows)]
|
||||
result.stdout_only("test-1 test-2 test-3 test-4\n");
|
||||
|
||||
let result = scene.ucmd().arg("--sort=size").succeeds();
|
||||
#[cfg(not(windows))]
|
||||
result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n");
|
||||
#[cfg(windows)]
|
||||
result.stdout_only("test-4 test-3 test-2 test-1\n");
|
||||
|
||||
let result = scene.ucmd().arg("--sort=size").arg("-r").succeeds();
|
||||
#[cfg(not(windows))]
|
||||
result.stdout_only("test-1\ntest-2\ntest-3\ntest-4\n");
|
||||
#[cfg(windows)]
|
||||
result.stdout_only("test-1 test-2 test-3 test-4\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -472,13 +531,16 @@ fn test_ls_long_ctime() {
|
|||
let at = &scene.fixtures;
|
||||
|
||||
at.touch("test-long-ctime-1");
|
||||
let result = scene.ucmd().arg("-lc").succeeds();
|
||||
|
||||
// Should show the time on Unix, but question marks on windows.
|
||||
#[cfg(unix)]
|
||||
result.stdout_contains(":");
|
||||
#[cfg(not(unix))]
|
||||
result.stdout_contains("???");
|
||||
for arg in &["-c", "--time=ctime", "--time=status"] {
|
||||
let result = scene.ucmd().arg("-l").arg(arg).succeeds();
|
||||
|
||||
// Should show the time on Unix, but question marks on windows.
|
||||
#[cfg(unix)]
|
||||
result.stdout_contains(":");
|
||||
#[cfg(not(unix))]
|
||||
result.stdout_contains("???");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -519,32 +581,46 @@ fn test_ls_order_time() {
|
|||
#[cfg(windows)]
|
||||
result.stdout_only("test-4 test-3 test-2 test-1\n");
|
||||
|
||||
let result = scene.ucmd().arg("--sort=time").succeeds();
|
||||
#[cfg(not(windows))]
|
||||
result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n");
|
||||
#[cfg(windows)]
|
||||
result.stdout_only("test-4 test-3 test-2 test-1\n");
|
||||
|
||||
let result = scene.ucmd().arg("-tr").succeeds();
|
||||
#[cfg(not(windows))]
|
||||
result.stdout_only("test-1\ntest-2\ntest-3\ntest-4\n");
|
||||
#[cfg(windows)]
|
||||
result.stdout_only("test-1 test-2 test-3 test-4\n");
|
||||
|
||||
let result = scene.ucmd().arg("--sort=time").arg("-r").succeeds();
|
||||
#[cfg(not(windows))]
|
||||
result.stdout_only("test-1\ntest-2\ntest-3\ntest-4\n");
|
||||
#[cfg(windows)]
|
||||
result.stdout_only("test-1 test-2 test-3 test-4\n");
|
||||
|
||||
// 3 was accessed last in the read
|
||||
// So the order should be 2 3 4 1
|
||||
let result = scene.ucmd().arg("-tu").succeeds();
|
||||
let file3_access = at.open("test-3").metadata().unwrap().accessed().unwrap();
|
||||
let file4_access = at.open("test-4").metadata().unwrap().accessed().unwrap();
|
||||
for arg in &["-u", "--time=atime", "--time=access", "--time=use"] {
|
||||
let result = scene.ucmd().arg("-t").arg(arg).succeeds();
|
||||
let file3_access = at.open("test-3").metadata().unwrap().accessed().unwrap();
|
||||
let file4_access = at.open("test-4").metadata().unwrap().accessed().unwrap();
|
||||
|
||||
// It seems to be dependent on the platform whether the access time is actually set
|
||||
if file3_access > file4_access {
|
||||
if cfg!(not(windows)) {
|
||||
result.stdout_only("test-3\ntest-4\ntest-2\ntest-1\n");
|
||||
// It seems to be dependent on the platform whether the access time is actually set
|
||||
if file3_access > file4_access {
|
||||
if cfg!(not(windows)) {
|
||||
result.stdout_only("test-3\ntest-4\ntest-2\ntest-1\n");
|
||||
} else {
|
||||
result.stdout_only("test-3 test-4 test-2 test-1\n");
|
||||
}
|
||||
} else {
|
||||
result.stdout_only("test-3 test-4 test-2 test-1\n");
|
||||
}
|
||||
} else {
|
||||
// Access time does not seem to be set on Windows and some other
|
||||
// systems so the order is 4 3 2 1
|
||||
if cfg!(not(windows)) {
|
||||
result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n");
|
||||
} else {
|
||||
result.stdout_only("test-4 test-3 test-2 test-1\n");
|
||||
// Access time does not seem to be set on Windows and some other
|
||||
// systems so the order is 4 3 2 1
|
||||
if cfg!(not(windows)) {
|
||||
result.stdout_only("test-4\ntest-3\ntest-2\ntest-1\n");
|
||||
} else {
|
||||
result.stdout_only("test-4 test-3 test-2 test-1\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -621,20 +697,27 @@ fn test_ls_recursive() {
|
|||
result.stdout_contains(&"a\\b:\nb");
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn test_ls_ls_color() {
|
||||
fn test_ls_color() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
at.mkdir("a");
|
||||
at.mkdir("a/nested_dir");
|
||||
let nested_dir = Path::new("a")
|
||||
.join("nested_dir")
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
at.mkdir(&nested_dir);
|
||||
at.mkdir("z");
|
||||
at.touch(&at.plus_as_string("a/nested_file"));
|
||||
let nested_file = Path::new("a")
|
||||
.join("nested_file")
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
at.touch(&nested_file);
|
||||
at.touch("test-color");
|
||||
|
||||
let a_with_colors = "\x1b[01;34ma\x1b[0m";
|
||||
let z_with_colors = "\x1b[01;34mz\x1b[0m";
|
||||
let nested_dir_with_colors = "\x1b[01;34mnested_dir\x1b[0m";
|
||||
let a_with_colors = "\x1b[1;34ma\x1b[0m";
|
||||
let z_with_colors = "\x1b[1;34mz\x1b[0m";
|
||||
let nested_dir_with_colors = "\x1b[1;34mnested_dir\x1b[0m";
|
||||
|
||||
// Color is disabled by default
|
||||
let result = scene.ucmd().succeeds();
|
||||
|
@ -670,14 +753,6 @@ fn test_ls_ls_color() {
|
|||
.succeeds()
|
||||
.stdout_contains(nested_dir_with_colors);
|
||||
|
||||
// Color has no effect
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--color=always")
|
||||
.arg("a/nested_file")
|
||||
.succeeds()
|
||||
.stdout_contains("a/nested_file\n");
|
||||
|
||||
// No output
|
||||
scene
|
||||
.ucmd()
|
||||
|
@ -817,7 +892,7 @@ fn test_ls_indicator_style() {
|
|||
let options = vec!["classify", "file-type", "slash"];
|
||||
for opt in options {
|
||||
// Verify that classify and file-type both contain indicators for symlinks.
|
||||
let result = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg(format!("--indicator-style={}", opt))
|
||||
.succeeds()
|
||||
|
@ -827,7 +902,7 @@ fn test_ls_indicator_style() {
|
|||
// Same test as above, but with the alternate flags.
|
||||
let options = vec!["--classify", "--file-type", "-p"];
|
||||
for opt in options {
|
||||
let result = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg(format!("{}", opt))
|
||||
.succeeds()
|
||||
|
@ -838,7 +913,7 @@ fn test_ls_indicator_style() {
|
|||
let options = vec!["classify", "file-type"];
|
||||
for opt in options {
|
||||
// Verify that classify and file-type both contain indicators for symlinks.
|
||||
let result = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg(format!("--indicator-style={}", opt))
|
||||
.succeeds()
|
||||
|
@ -962,7 +1037,7 @@ fn test_ls_hidden_windows() {
|
|||
|
||||
let result = scene.ucmd().succeeds();
|
||||
assert!(!result.stdout_str().contains(file));
|
||||
let result = scene.ucmd().arg("-a").succeeds().stdout_contains(file);
|
||||
scene.ucmd().arg("-a").succeeds().stdout_contains(file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1052,9 +1127,11 @@ fn test_ls_quoting_style() {
|
|||
at.touch("one");
|
||||
|
||||
// It seems that windows doesn't allow \n in filenames.
|
||||
// And it also doesn't like \, of course.
|
||||
#[cfg(unix)]
|
||||
{
|
||||
at.touch("one\ntwo");
|
||||
at.touch("one\\two");
|
||||
// Default is shell-escape
|
||||
scene
|
||||
.ucmd()
|
||||
|
@ -1116,6 +1193,42 @@ fn test_ls_quoting_style() {
|
|||
.succeeds()
|
||||
.stdout_only(format!("{}\n", correct));
|
||||
}
|
||||
|
||||
for (arg, correct) in &[
|
||||
("--quoting-style=literal", "one\\two"),
|
||||
("-N", "one\\two"),
|
||||
("--quoting-style=c", "\"one\\\\two\""),
|
||||
("-Q", "\"one\\\\two\""),
|
||||
("--quote-name", "\"one\\\\two\""),
|
||||
("--quoting-style=escape", "one\\\\two"),
|
||||
("-b", "one\\\\two"),
|
||||
("--quoting-style=shell-escape", "'one\\two'"),
|
||||
("--quoting-style=shell-escape-always", "'one\\two'"),
|
||||
("--quoting-style=shell", "'one\\two'"),
|
||||
("--quoting-style=shell-always", "'one\\two'"),
|
||||
] {
|
||||
scene
|
||||
.ucmd()
|
||||
.arg(arg)
|
||||
.arg("one\\two")
|
||||
.succeeds()
|
||||
.stdout_only(format!("{}\n", correct));
|
||||
}
|
||||
|
||||
// Tests for a character that forces quotation in shell-style escaping
|
||||
// after a character in a dollar expression
|
||||
at.touch("one\n&two");
|
||||
for (arg, correct) in &[
|
||||
("--quoting-style=shell-escape", "'one'$'\\n''&two'"),
|
||||
("--quoting-style=shell-escape-always", "'one'$'\\n''&two'"),
|
||||
] {
|
||||
scene
|
||||
.ucmd()
|
||||
.arg(arg)
|
||||
.arg("one\n&two")
|
||||
.succeeds()
|
||||
.stdout_only(format!("{}\n", correct));
|
||||
}
|
||||
}
|
||||
|
||||
scene
|
||||
|
@ -1316,6 +1429,43 @@ fn test_ls_ignore_hide() {
|
|||
.stdout_is("CONTRIBUTING.md\nREADME.md\nREADMECAREFULLY.md\nsome_other_file\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ls_ignore_backups() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
at.touch("somefile");
|
||||
at.touch("somebackup~");
|
||||
at.touch(".somehiddenfile");
|
||||
at.touch(".somehiddenbackup~");
|
||||
|
||||
scene.ucmd().arg("-B").succeeds().stdout_is("somefile\n");
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--ignore-backups")
|
||||
.succeeds()
|
||||
.stdout_is("somefile\n");
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-aB")
|
||||
.succeeds()
|
||||
.stdout_contains(".somehiddenfile")
|
||||
.stdout_contains("somefile")
|
||||
.stdout_does_not_contain("somebackup")
|
||||
.stdout_does_not_contain(".somehiddenbackup~");
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-a")
|
||||
.arg("--ignore-backups")
|
||||
.succeeds()
|
||||
.stdout_contains(".somehiddenfile")
|
||||
.stdout_contains("somefile")
|
||||
.stdout_does_not_contain("somebackup")
|
||||
.stdout_does_not_contain(".somehiddenbackup~");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ls_directory() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
|
|
@ -19,8 +19,7 @@ fn test_create_one_fifo_with_invalid_mode() {
|
|||
.arg("-m")
|
||||
.arg("invalid")
|
||||
.fails()
|
||||
.stderr
|
||||
.contains("invalid mode");
|
||||
.stderr_contains("invalid mode");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -2,18 +2,15 @@ use crate::common::util::*;
|
|||
|
||||
#[test]
|
||||
fn test_more_no_arg() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.run();
|
||||
assert!(!result.success);
|
||||
// stderr = more: Reading from stdin isn't supported yet.
|
||||
new_ucmd!().fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_more_dir_arg() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
ucmd.arg(".");
|
||||
let result = ucmd.run();
|
||||
assert!(!result.success);
|
||||
let result = new_ucmd!().arg(".").run();
|
||||
result.failure();
|
||||
const EXPECTED_ERROR_MESSAGE: &str =
|
||||
"more: '.' is a directory.\nTry 'more --help' for more information.";
|
||||
assert_eq!(result.stderr.trim(), EXPECTED_ERROR_MESSAGE);
|
||||
assert_eq!(result.stderr_str().trim(), EXPECTED_ERROR_MESSAGE);
|
||||
}
|
||||
|
|
|
@ -476,16 +476,9 @@ fn test_mv_overwrite_nonempty_dir() {
|
|||
// GNU: "mv: cannot move ‘a’ to ‘b’: Directory not empty"
|
||||
|
||||
// Verbose output for the move should not be shown on failure
|
||||
assert!(
|
||||
ucmd.arg("-vT")
|
||||
.arg(dir_a)
|
||||
.arg(dir_b)
|
||||
.fails()
|
||||
.no_stdout()
|
||||
.stderr
|
||||
.len()
|
||||
> 0
|
||||
);
|
||||
let result = ucmd.arg("-vT").arg(dir_a).arg(dir_b).fails();
|
||||
result.no_stdout();
|
||||
assert!(!result.stderr_str().is_empty());
|
||||
|
||||
assert!(at.dir_exists(dir_a));
|
||||
assert!(at.dir_exists(dir_b));
|
||||
|
@ -526,15 +519,15 @@ fn test_mv_errors() {
|
|||
|
||||
// $ mv -T -t a b
|
||||
// mv: cannot combine --target-directory (-t) and --no-target-directory (-T)
|
||||
let result = scene
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-T")
|
||||
.arg("-t")
|
||||
.arg(dir)
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.fails();
|
||||
assert!(result.stderr.contains("cannot be used with"));
|
||||
.fails()
|
||||
.stderr_contains("cannot be used with");
|
||||
|
||||
// $ at.touch file && at.mkdir dir
|
||||
// $ mv -T file dir
|
||||
|
@ -553,7 +546,13 @@ fn test_mv_errors() {
|
|||
// $ at.mkdir dir && at.touch file
|
||||
// $ mv dir file
|
||||
// err == mv: cannot overwrite non-directory ‘file’ with directory ‘dir’
|
||||
assert!(scene.ucmd().arg(dir).arg(file_a).fails().stderr.len() > 0);
|
||||
assert!(!scene
|
||||
.ucmd()
|
||||
.arg(dir)
|
||||
.arg(file_a)
|
||||
.fails()
|
||||
.stderr_str()
|
||||
.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -16,7 +16,7 @@ fn test_negative_adjustment() {
|
|||
|
||||
let res = new_ucmd!().args(&["-n", "-1", "true"]).run();
|
||||
assert!(res
|
||||
.stderr
|
||||
.stderr_str()
|
||||
.starts_with("nice: warning: setpriority: Permission denied"));
|
||||
}
|
||||
|
||||
|
|
|
@ -9,35 +9,28 @@ fn test_output_is_random_permutation() {
|
|||
.collect::<Vec<String>>()
|
||||
.join("\n");
|
||||
|
||||
let result = new_ucmd!()
|
||||
.pipe_in(input.as_bytes())
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
.clone();
|
||||
let result = new_ucmd!().pipe_in(input.as_bytes()).succeeds();
|
||||
result.no_stderr();
|
||||
|
||||
let mut result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\n")
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
.collect();
|
||||
result_seq.sort();
|
||||
assert_ne!(result, input, "Output is not randomised");
|
||||
assert_ne!(result.stdout_str(), input, "Output is not randomised");
|
||||
assert_eq!(result_seq, input_seq, "Output is not a permutation");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_termination() {
|
||||
let input_seq = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
let result = new_ucmd!()
|
||||
.arg("-z")
|
||||
.arg("-i1-10")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
.clone();
|
||||
let result = new_ucmd!().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())
|
||||
|
@ -57,12 +50,11 @@ fn test_echo() {
|
|||
.map(|x| x.to_string())
|
||||
.collect::<Vec<String>>(),
|
||||
)
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
.clone();
|
||||
.succeeds();
|
||||
result.no_stderr();
|
||||
|
||||
let mut result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\n")
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
|
@ -84,12 +76,11 @@ fn test_head_count() {
|
|||
let result = new_ucmd!()
|
||||
.args(&["-n", &repeat_limit.to_string()])
|
||||
.pipe_in(input.as_bytes())
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
.clone();
|
||||
.succeeds();
|
||||
result.no_stderr();
|
||||
|
||||
let mut result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\n")
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
|
@ -99,7 +90,7 @@ fn test_head_count() {
|
|||
assert!(
|
||||
result_seq.iter().all(|x| input_seq.contains(x)),
|
||||
"Output includes element not from input: {}",
|
||||
result
|
||||
result.stdout_str()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -117,12 +108,11 @@ fn test_repeat() {
|
|||
.arg("-r")
|
||||
.args(&["-n", &repeat_limit.to_string()])
|
||||
.pipe_in(input.as_bytes())
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
.clone();
|
||||
.succeeds();
|
||||
result.no_stderr();
|
||||
|
||||
let result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\n")
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
|
@ -146,14 +136,11 @@ fn test_repeat() {
|
|||
fn test_file_input() {
|
||||
let expected_seq = vec![11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("file_input.txt")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
.clone();
|
||||
let result = new_ucmd!().arg("file_input.txt").succeeds();
|
||||
result.no_stderr();
|
||||
|
||||
let mut result_seq: Vec<i32> = result
|
||||
.stdout_str()
|
||||
.split("\n")
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| x.parse().unwrap())
|
||||
|
@ -164,52 +151,50 @@ fn test_file_input() {
|
|||
|
||||
#[test]
|
||||
fn test_shuf_echo_and_input_range_not_allowed() {
|
||||
let result = new_ucmd!().args(&["-e", "0", "-i", "0-2"]).run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result
|
||||
.stderr
|
||||
.contains("The argument '--input-range <LO-HI>' cannot be used with '--echo <ARG>...'"));
|
||||
new_ucmd!()
|
||||
.args(&["-e", "0", "-i", "0-2"])
|
||||
.fails()
|
||||
.stderr_contains(
|
||||
"The argument '--input-range <LO-HI>' cannot be used with '--echo <ARG>...'",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shuf_input_range_and_file_not_allowed() {
|
||||
let result = new_ucmd!().args(&["-i", "0-9", "file"]).run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result
|
||||
.stderr
|
||||
.contains("The argument '<file>' cannot be used with '--input-range <LO-HI>'"));
|
||||
new_ucmd!()
|
||||
.args(&["-i", "0-9", "file"])
|
||||
.fails()
|
||||
.stderr_contains("The argument '<file>' cannot be used with '--input-range <LO-HI>'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shuf_invalid_input_range_one() {
|
||||
let result = new_ucmd!().args(&["-i", "0"]).run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result.stderr.contains("invalid input range"));
|
||||
new_ucmd!()
|
||||
.args(&["-i", "0"])
|
||||
.fails()
|
||||
.stderr_contains("invalid input range");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shuf_invalid_input_range_two() {
|
||||
let result = new_ucmd!().args(&["-i", "a-9"]).run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result.stderr.contains("invalid input range: 'a'"));
|
||||
new_ucmd!()
|
||||
.args(&["-i", "a-9"])
|
||||
.fails()
|
||||
.stderr_contains("invalid input range: 'a'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shuf_invalid_input_range_three() {
|
||||
let result = new_ucmd!().args(&["-i", "0-b"]).run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result.stderr.contains("invalid input range: 'b'"));
|
||||
new_ucmd!()
|
||||
.args(&["-i", "0-b"])
|
||||
.fails()
|
||||
.stderr_contains("invalid input range: 'b'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shuf_invalid_input_line_count() {
|
||||
let result = new_ucmd!().args(&["-n", "a"]).run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result.stderr.contains("invalid line count: 'a'"));
|
||||
new_ucmd!()
|
||||
.args(&["-n", "a"])
|
||||
.fails()
|
||||
.stderr_contains("invalid line count: 'a'");
|
||||
}
|
||||
|
|
|
@ -2,10 +2,17 @@ use crate::common::util::*;
|
|||
|
||||
fn test_helper(file_name: &str, args: &str) {
|
||||
new_ucmd!()
|
||||
.arg(args)
|
||||
.arg(format!("{}.txt", file_name))
|
||||
.args(&args.split(' ').collect::<Vec<&str>>())
|
||||
.succeeds()
|
||||
.stdout_is_fixture(format!("{}.expected", file_name));
|
||||
|
||||
new_ucmd!()
|
||||
.arg(format!("{}.txt", file_name))
|
||||
.arg("--debug")
|
||||
.args(&args.split(' ').collect::<Vec<&str>>())
|
||||
.succeeds()
|
||||
.stdout_is_fixture(format!("{}.expected.debug", file_name));
|
||||
}
|
||||
|
||||
// FYI, the initialization size of our Line struct is 96 bytes.
|
||||
|
@ -65,11 +72,7 @@ fn test_extsort_as64_bailout() {
|
|||
|
||||
#[test]
|
||||
fn test_multiple_decimals_general() {
|
||||
new_ucmd!()
|
||||
.arg("-g")
|
||||
.arg("multiple_decimals_general.txt")
|
||||
.succeeds()
|
||||
.stdout_is("\n\n\n\n\n\n\n\nCARAvan\n-2028789030\n-896689\n-8.90880\n-1\n-.05\n000\n00000001\n1\n1.040000000\n1.444\n1.58590\n8.013\n45\n46.89\n576,446.88800000\n576,446.890\n 4567.\n4567.1\n4567.34\n\t\t\t\t\t\t\t\t\t\t4567..457\n\t\t\t\t37800\n\t\t\t\t\t\t45670.89079.098\n\t\t\t\t\t\t45670.89079.1\n4798908.340000000000\n4798908.45\n4798908.8909800\n");
|
||||
test_helper("multiple_decimals_general", "-g")
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -99,7 +102,7 @@ fn test_check_zero_terminated_success() {
|
|||
#[test]
|
||||
fn test_random_shuffle_len() {
|
||||
// check whether output is the same length as the input
|
||||
const FILE: &'static str = "default_unsorted_ints.expected";
|
||||
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);
|
||||
|
@ -111,7 +114,7 @@ fn test_random_shuffle_len() {
|
|||
#[test]
|
||||
fn test_random_shuffle_contains_all_lines() {
|
||||
// check whether lines of input are all in output
|
||||
const FILE: &'static str = "default_unsorted_ints.expected";
|
||||
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);
|
||||
|
@ -126,7 +129,22 @@ 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: &'static str = "default_unsorted_ints.expected";
|
||||
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);
|
||||
}
|
||||
|
||||
#[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);
|
||||
|
@ -228,6 +246,11 @@ fn test_non_printing_chars() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exponents_positive_general_fixed() {
|
||||
test_helper("exponents_general", "-g");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exponents_positive_numeric() {
|
||||
test_helper("exponents-positive-numeric", "-n");
|
||||
|
@ -344,62 +367,32 @@ fn test_numeric_unique_ints2() {
|
|||
|
||||
#[test]
|
||||
fn test_keys_open_ended() {
|
||||
let input = "aa bb cc\ndd aa ff\ngg aa cc\n";
|
||||
new_ucmd!()
|
||||
.args(&["-k", "2.2"])
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("gg aa cc\ndd aa ff\naa bb cc\n");
|
||||
test_helper("keys_open_ended", "-k 2.3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys_closed_range() {
|
||||
let input = "aa bb cc\ndd aa ff\ngg aa cc\n";
|
||||
new_ucmd!()
|
||||
.args(&["-k", "2.2,2.2"])
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("dd aa ff\ngg aa cc\naa bb cc\n");
|
||||
test_helper("keys_closed_range", "-k 2.2,2.2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys_multiple_ranges() {
|
||||
let input = "aa bb cc\ndd aa ff\ngg aa cc\n";
|
||||
new_ucmd!()
|
||||
.args(&["-k", "2,2", "-k", "3,3"])
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("gg aa cc\ndd aa ff\naa bb cc\n");
|
||||
test_helper("keys_multiple_ranges", "-k 2,2 -k 3,3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys_no_field_match() {
|
||||
let input = "aa aa aa aa\naa bb cc\ndd aa ff\n";
|
||||
new_ucmd!()
|
||||
.args(&["-k", "4,4"])
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("aa bb cc\ndd aa ff\naa aa aa aa\n");
|
||||
test_helper("keys_no_field_match", "-k 4,4");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys_no_char_match() {
|
||||
let input = "aaa\nba\nc\n";
|
||||
new_ucmd!()
|
||||
.args(&["-k", "1.2"])
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("c\nba\naaa\n");
|
||||
test_helper("keys_no_char_match", "-k 1.2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys_custom_separator() {
|
||||
let input = "aaxbbxcc\nddxaaxff\nggxaaxcc\n";
|
||||
new_ucmd!()
|
||||
.args(&["-k", "2.2,2.2", "-t", "x"])
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("ddxaaxff\nggxaaxcc\naaxbbxcc\n");
|
||||
test_helper("keys_custom_separator", "-k 2.2,2.2 -t x");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -426,6 +419,13 @@ fn test_keys_invalid_field_zero() {
|
|||
.stderr_only("sort: error: field index was 0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys_invalid_char_zero() {
|
||||
new_ucmd!().args(&["-k", "1.0"]).fails().stderr_only(
|
||||
"sort: error: invalid character index 0 in `1.0` for the start position of a field",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keys_with_options() {
|
||||
let input = "aa 3 cc\ndd 1 ff\ngg 2 cc\n";
|
||||
|
@ -591,3 +591,39 @@ fn test_check_silent() {
|
|||
.fails()
|
||||
.stdout_is("");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dictionary_and_nonprinting_conflicts() {
|
||||
let conflicting_args = ["n", "h", "g", "M"];
|
||||
for restricted_arg in &["d", "i"] {
|
||||
for conflicting_arg in &conflicting_args {
|
||||
new_ucmd!()
|
||||
.arg(&format!("-{}{}", restricted_arg, conflicting_arg))
|
||||
.fails();
|
||||
}
|
||||
for conflicting_arg in &conflicting_args {
|
||||
new_ucmd!()
|
||||
.args(&[
|
||||
format!("-{}", restricted_arg).as_str(),
|
||||
"-k",
|
||||
&format!("1,1{}", conflicting_arg),
|
||||
])
|
||||
.succeeds();
|
||||
}
|
||||
for conflicting_arg in &conflicting_args {
|
||||
// FIXME: this should ideally fail.
|
||||
new_ucmd!()
|
||||
.args(&["-k", &format!("1{},1{}", restricted_arg, conflicting_arg)])
|
||||
.succeeds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trailing_separator() {
|
||||
new_ucmd!()
|
||||
.args(&["-t", "x", "-k", "1,1"])
|
||||
.pipe_in("aax\naaa\n")
|
||||
.succeeds()
|
||||
.stdout_is("aax\naaa\n");
|
||||
}
|
||||
|
|
|
@ -337,5 +337,5 @@ fn expected_result(args: &[&str]) -> String {
|
|||
.env("LANGUAGE", "C")
|
||||
.args(args)
|
||||
.run()
|
||||
.stdout
|
||||
.stdout_move_str()
|
||||
}
|
||||
|
|
|
@ -52,18 +52,19 @@ fn test_single_non_newline_separator_before() {
|
|||
|
||||
#[test]
|
||||
fn test_invalid_input() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
ucmd.arg("b")
|
||||
.run()
|
||||
.stderr
|
||||
.contains("tac: error: failed to open 'b' for reading");
|
||||
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("b")
|
||||
.fails()
|
||||
.stderr_contains("failed to open 'b' for reading: No such file or directory");
|
||||
|
||||
at.mkdir("a");
|
||||
ucmd.arg("a")
|
||||
.run()
|
||||
.stderr
|
||||
.contains("tac: error: failed to read 'a'");
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("a")
|
||||
.fails()
|
||||
.stderr_contains("dir: read error: Invalid argument");
|
||||
}
|
||||
|
|
|
@ -343,3 +343,8 @@ fn test_negative_indexing() {
|
|||
assert_eq!(positive_lines_index.stdout(), negative_lines_index.stdout());
|
||||
assert_eq!(positive_bytes_index.stdout(), negative_bytes_index.stdout());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sleep_interval() {
|
||||
new_ucmd!().arg("-s").arg("10").arg(FOOBAR_TXT).succeeds();
|
||||
}
|
||||
|
|
|
@ -367,7 +367,58 @@ fn test_touch_mtime_dst_succeeds() {
|
|||
|
||||
let target_time = str_to_filetime("%Y%m%d%H%M", "202103140300");
|
||||
let (_, mtime) = get_file_times(&at, file);
|
||||
eprintln!("target_time: {:?}", target_time);
|
||||
eprintln!("mtime: {:?}", mtime);
|
||||
assert!(target_time == mtime);
|
||||
}
|
||||
|
||||
// is_dst_switch_hour returns true if timespec ts is just before the switch
|
||||
// to Daylight Saving Time.
|
||||
// For example, in EST (UTC-5), Timespec { sec: 1583647200, nsec: 0 }
|
||||
// for March 8 2020 01:00:00 AM
|
||||
// is just before the switch because on that day clock jumps by 1 hour,
|
||||
// so 1 minute after 01:59:00 is 03:00:00.
|
||||
fn is_dst_switch_hour(ts: time::Timespec) -> bool {
|
||||
let ts_after = ts + time::Duration::hours(1);
|
||||
let tm = time::at(ts);
|
||||
let tm_after = time::at(ts_after);
|
||||
tm_after.tm_hour == tm.tm_hour + 2
|
||||
}
|
||||
|
||||
// get_dstswitch_hour returns date string for which touch -m -t fails.
|
||||
// For example, in EST (UTC-5), that will be "202003080200" so
|
||||
// touch -m -t 202003080200 somefile
|
||||
// fails (that date/time does not exist).
|
||||
// In other locales it will be a different date/time, and in some locales
|
||||
// it doesn't exist at all, in which case this function will return None.
|
||||
fn get_dstswitch_hour() -> Option<String> {
|
||||
let now = time::now();
|
||||
// Start from January 1, 2020, 00:00.
|
||||
let mut tm = time::strptime("20200101-0000", "%Y%m%d-%H%M").unwrap();
|
||||
tm.tm_isdst = -1;
|
||||
tm.tm_utcoff = now.tm_utcoff;
|
||||
let mut ts = tm.to_timespec();
|
||||
// Loop through all hours in year 2020 until we find the hour just
|
||||
// before the switch to DST.
|
||||
for _i in 0..(366 * 24) {
|
||||
if is_dst_switch_hour(ts) {
|
||||
let mut tm = time::at(ts);
|
||||
tm.tm_hour = tm.tm_hour + 1;
|
||||
let s = time::strftime("%Y%m%d%H%M", &tm).unwrap().to_string();
|
||||
return Some(s);
|
||||
}
|
||||
ts = ts + time::Duration::hours(1);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_mtime_dst_fails() {
|
||||
let (_at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_mtime_dst_fails";
|
||||
|
||||
match get_dstswitch_hour() {
|
||||
Some(s) => {
|
||||
ucmd.args(&["-m", "-t", &s, file]).fails();
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,19 +120,15 @@ fn test_truncate_with_set1_shorter_than_set2() {
|
|||
#[test]
|
||||
fn missing_args_fails() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result.stderr.contains("missing operand"));
|
||||
ucmd.fails().stderr_contains("missing operand");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_required_second_arg_fails() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.args(&["foo"]).run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result.stderr.contains("missing operand after"));
|
||||
ucmd.args(&["foo"])
|
||||
.fails()
|
||||
.stderr_contains("missing operand after");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -53,6 +53,16 @@ fn test_decrease_file_size() {
|
|||
assert!(file.seek(SeekFrom::Current(0)).unwrap() == 6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_space_in_size() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let mut file = at.make_file(TFILE2);
|
||||
file.write_all(b"1234567890").unwrap();
|
||||
ucmd.args(&["--size", " 4", TFILE2]).succeeds();
|
||||
file.seek(SeekFrom::End(0)).unwrap();
|
||||
assert!(file.seek(SeekFrom::Current(0)).unwrap() == 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_failed() {
|
||||
new_ucmd!().fails();
|
||||
|
|
|
@ -18,33 +18,35 @@ fn test_sort_self_loop() {
|
|||
|
||||
#[test]
|
||||
fn test_no_such_file() {
|
||||
let result = new_ucmd!().arg("invalid_file_txt").run();
|
||||
|
||||
assert_eq!(true, result.stderr.contains("No such file or directory"));
|
||||
new_ucmd!()
|
||||
.arg("invalid_file_txt")
|
||||
.fails()
|
||||
.stderr_contains("No such file or directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version_flag() {
|
||||
let version_short = new_ucmd!().arg("-V").run();
|
||||
let version_long = new_ucmd!().arg("--version").run();
|
||||
let version_short = new_ucmd!().arg("-V").succeeds();
|
||||
let version_long = new_ucmd!().arg("--version").succeeds();
|
||||
|
||||
assert_eq!(version_short.stdout(), version_long.stdout());
|
||||
assert_eq!(version_short.stdout_str(), version_long.stdout_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_help_flag() {
|
||||
let help_short = new_ucmd!().arg("-h").run();
|
||||
let help_long = new_ucmd!().arg("--help").run();
|
||||
let help_short = new_ucmd!().arg("-h").succeeds();
|
||||
let help_long = new_ucmd!().arg("--help").succeeds();
|
||||
|
||||
assert_eq!(help_short.stdout(), help_long.stdout());
|
||||
assert_eq!(help_short.stdout_str(), help_long.stdout_str());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_arguments() {
|
||||
let result = new_ucmd!()
|
||||
new_ucmd!()
|
||||
.arg("call_graph.txt")
|
||||
.arg("invalid_file.txt")
|
||||
.run();
|
||||
|
||||
assert_eq!(true, result.stderr.contains("error: Found argument 'invalid_file.txt' which wasn't expected, or isn't valid in this context"))
|
||||
.arg("invalid_file")
|
||||
.fails()
|
||||
.stderr_contains(
|
||||
"Found argument 'invalid_file' which wasn't expected, or isn't valid in this context",
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ fn test_heading() {
|
|||
for opt in vec!["-H"] {
|
||||
// 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;
|
||||
let actual = new_ucmd!().arg(opt).run().stdout_move_str();
|
||||
let expect = expected_result(opt);
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
|
@ -80,5 +80,5 @@ fn expected_result(arg: &str) -> String {
|
|||
.env("LANGUAGE", "C")
|
||||
.args(&[arg])
|
||||
.run()
|
||||
.stdout
|
||||
.stdout_move_str()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue