mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 19:47:45 +00:00
tests ~ reorganize tests
This commit is contained in:
parent
1c88bc8c45
commit
de0375f909
75 changed files with 0 additions and 0 deletions
18
tests/by-util/test_arch.rs
Normal file
18
tests/by-util/test_arch.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_arch() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_arch_help() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg("--help").run();
|
||||
assert!(result.success);
|
||||
assert!(result.stdout.contains("architecture name"));
|
||||
}
|
89
tests/by-util/test_base32.rs
Normal file
89
tests/by-util/test_base32.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
// This file is part of the uutils coreutils package.
|
||||
//
|
||||
// (c) Jian Zeng <anonymousknight96@gmail.com>
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE file
|
||||
// that was distributed with this source code.
|
||||
//
|
||||
|
||||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_encode() {
|
||||
let input = "Hello, World!";
|
||||
new_ucmd!()
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("JBSWY3DPFQQFO33SNRSCC===\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode() {
|
||||
for decode_param in vec!["-d", "--decode"] {
|
||||
let input = "JBSWY3DPFQQFO33SNRSCC===\n";
|
||||
new_ucmd!()
|
||||
.arg(decode_param)
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("Hello, World!");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_garbage() {
|
||||
let input = "aGVsbG8sIHdvcmxkIQ==\0";
|
||||
new_ucmd!()
|
||||
.arg("-d")
|
||||
.pipe_in(input)
|
||||
.fails()
|
||||
.stderr_only("base32: error: invalid input\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ignore_garbage() {
|
||||
for ignore_garbage_param in vec!["-i", "--ignore-garbage"] {
|
||||
let input = "JBSWY\x013DPFQ\x02QFO33SNRSCC===\n";
|
||||
new_ucmd!()
|
||||
.arg("-d")
|
||||
.arg(ignore_garbage_param)
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("Hello, World!");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
let input = "The quick brown fox jumps over the lazy dog.";
|
||||
new_ucmd!()
|
||||
.arg(wrap_param)
|
||||
.arg("20")
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only(
|
||||
"KRUGKIDROVUWG2ZAMJZG\n653OEBTG66BANJ2W24DT\nEBXXMZLSEB2GQZJANRQX\nU6JAMRXWOLQ=\n",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_no_arg() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
new_ucmd!().arg(wrap_param).fails().stderr_only(format!(
|
||||
"base32: error: Argument to option '{}' missing\n",
|
||||
if wrap_param == "-w" { "w" } else { "wrap" }
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_bad_arg() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
new_ucmd!()
|
||||
.arg(wrap_param)
|
||||
.arg("b")
|
||||
.fails()
|
||||
.stderr_only("base32: error: invalid wrap size: ‘b’: invalid digit found in string\n");
|
||||
}
|
||||
}
|
79
tests/by-util/test_base64.rs
Normal file
79
tests/by-util/test_base64.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_encode() {
|
||||
let input = "hello, world!";
|
||||
new_ucmd!()
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("aGVsbG8sIHdvcmxkIQ==\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode() {
|
||||
for decode_param in vec!["-d", "--decode"] {
|
||||
let input = "aGVsbG8sIHdvcmxkIQ==";
|
||||
new_ucmd!()
|
||||
.arg(decode_param)
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("hello, world!");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_garbage() {
|
||||
let input = "aGVsbG8sIHdvcmxkIQ==\0";
|
||||
new_ucmd!()
|
||||
.arg("-d")
|
||||
.pipe_in(input)
|
||||
.fails()
|
||||
.stderr_only("base64: error: invalid input\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ignore_garbage() {
|
||||
for ignore_garbage_param in vec!["-i", "--ignore-garbage"] {
|
||||
let input = "aGVsbG8sIHdvcmxkIQ==\0";
|
||||
new_ucmd!()
|
||||
.arg("-d")
|
||||
.arg(ignore_garbage_param)
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("hello, world!");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
let input = "The quick brown fox jumps over the lazy dog.";
|
||||
new_ucmd!()
|
||||
.arg(wrap_param)
|
||||
.arg("20")
|
||||
.pipe_in(input)
|
||||
.succeeds()
|
||||
.stdout_only("VGhlIHF1aWNrIGJyb3du\nIGZveCBqdW1wcyBvdmVy\nIHRoZSBsYXp5IGRvZy4=\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_no_arg() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
new_ucmd!().arg(wrap_param).fails().stderr_only(format!(
|
||||
"base64: error: Argument to option '{}' missing\n",
|
||||
if wrap_param == "-w" { "w" } else { "wrap" }
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap_bad_arg() {
|
||||
for wrap_param in vec!["-w", "--wrap"] {
|
||||
new_ucmd!()
|
||||
.arg(wrap_param)
|
||||
.arg("b")
|
||||
.fails()
|
||||
.stderr_only("base64: error: invalid wrap size: ‘b’: invalid digit found in string\n");
|
||||
}
|
||||
}
|
86
tests/by-util/test_basename.rs
Normal file
86
tests/by-util/test_basename.rs
Normal file
|
@ -0,0 +1,86 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_directory() {
|
||||
new_ucmd!()
|
||||
.args(&["/root/alpha/beta/gamma/delta/epsilon/omega/"])
|
||||
.succeeds()
|
||||
.stdout_only("omega\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file() {
|
||||
new_ucmd!()
|
||||
.args(&["/etc/passwd"])
|
||||
.succeeds()
|
||||
.stdout_only("passwd\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_suffix() {
|
||||
new_ucmd!()
|
||||
.args(&["/usr/local/bin/reallylongexecutable.exe", ".exe"])
|
||||
.succeeds()
|
||||
.stdout_only("reallylongexecutable\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dont_remove_suffix() {
|
||||
new_ucmd!()
|
||||
.args(&["/foo/bar/baz", "baz"])
|
||||
.succeeds()
|
||||
.stdout_only("baz\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_param() {
|
||||
for multiple_param in vec!["-a", "--multiple"] {
|
||||
let path = "/foo/bar/baz";
|
||||
new_ucmd!()
|
||||
.args(&[multiple_param, path, path])
|
||||
.succeeds()
|
||||
.stdout_only("baz\nbaz\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_suffix_param() {
|
||||
for suffix_param in vec!["-s", "--suffix"] {
|
||||
let path = "/foo/bar/baz.exe";
|
||||
new_ucmd!()
|
||||
.args(&[suffix_param, ".exe", path, path])
|
||||
.succeeds()
|
||||
.stdout_only("baz\nbaz\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_param() {
|
||||
for zero_param in vec!["-z", "--zero"] {
|
||||
let path = "/foo/bar/baz";
|
||||
new_ucmd!()
|
||||
.args(&[zero_param, "-a", path, path])
|
||||
.succeeds()
|
||||
.stdout_only("baz\0baz\0");
|
||||
}
|
||||
}
|
||||
|
||||
fn expect_error(input: Vec<&str>) {
|
||||
assert!(new_ucmd!().args(&input).fails().no_stdout().stderr.len() > 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_option() {
|
||||
let path = "/foo/bar/baz";
|
||||
expect_error(vec!["-q", path]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_args() {
|
||||
expect_error(vec![]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_many_args() {
|
||||
expect_error(vec!["a", "b", "c"]);
|
||||
}
|
170
tests/by-util/test_cat.rs
Normal file
170
tests/by-util/test_cat.rs
Normal file
|
@ -0,0 +1,170 @@
|
|||
extern crate tempdir;
|
||||
#[cfg(unix)]
|
||||
extern crate unix_socket;
|
||||
|
||||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_output_multi_files_print_all_chars() {
|
||||
new_ucmd!()
|
||||
.args(&["alpha.txt", "256.txt", "-A", "-n"])
|
||||
.succeeds()
|
||||
.stdout_only(
|
||||
" 1\tabcde$\n 2\tfghij$\n 3\tklmno$\n 4\tpqrst$\n \
|
||||
5\tuvwxyz$\n 6\t^@^A^B^C^D^E^F^G^H^I$\n \
|
||||
7\t^K^L^M^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\\^]^^^_ \
|
||||
!\"#$%&\'()*+,-./0123456789:;\
|
||||
<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?M-^@M-^AM-^\
|
||||
BM-^CM-^DM-^EM-^FM-^GM-^HM-^IM-^JM-^KM-^LM-^MM-^NM-^OM-^PM-^QM-^RM-^SM-^TM-^UM-^V\
|
||||
M-^WM-^XM-^YM-^ZM-^[M-^\\M-^]M-^^M-^_M- \
|
||||
M-!M-\"M-#M-$M-%M-&M-\'M-(M-)M-*M-+M-,M--M-.M-/M-0M-1M-2M-3M-4M-5M-6M-7M-8M-9M-:\
|
||||
M-;M-<M-=M->M-?M-@M-AM-BM-CM-DM-EM-FM-GM-HM-IM-JM-KM-LM-MM-NM-OM-PM-QM-RM-SM-TM-U\
|
||||
M-VM-WM-XM-YM-ZM-[M-\\M-]M-^M-_M-`M-aM-bM-cM-dM-eM-fM-gM-hM-iM-jM-kM-lM-mM-nM-oM-\
|
||||
pM-qM-rM-sM-tM-uM-vM-wM-xM-yM-zM-{M-|M-}M-~M-^?",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_numbered_lines_no_trailing_newline() {
|
||||
new_ucmd!()
|
||||
.args(&["nonewline.txt", "alpha.txt", "-n"])
|
||||
.succeeds()
|
||||
.stdout_only(
|
||||
" 1\ttext without a trailing newlineabcde\n 2\tfghij\n \
|
||||
3\tklmno\n 4\tpqrst\n 5\tuvwxyz\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_show_nonprinting() {
|
||||
for same_param in vec!["-v", "--show-nonprinting"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param])
|
||||
.pipe_in("\t\0\n")
|
||||
.succeeds()
|
||||
.stdout_only("\t^@\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_show_tabs() {
|
||||
for same_param in vec!["-T", "--show-tabs"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param])
|
||||
.pipe_in("\t\0\n")
|
||||
.succeeds()
|
||||
.stdout_only("^I\0\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_show_ends() {
|
||||
for same_param in vec!["-E", "--show-ends"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param, "-"])
|
||||
.pipe_in("\t\0\n\t")
|
||||
.succeeds()
|
||||
.stdout_only("\t\0$\n\t");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_show_all() {
|
||||
for same_param in vec!["-A", "--show-all"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param])
|
||||
.pipe_in("\t\0\n")
|
||||
.succeeds()
|
||||
.stdout_only("^I^@$\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_nonprinting_and_endofline() {
|
||||
new_ucmd!()
|
||||
.args(&["-e"])
|
||||
.pipe_in("\t\0\n")
|
||||
.succeeds()
|
||||
.stdout_only("\t^@$\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_nonprinting_and_tabs() {
|
||||
new_ucmd!()
|
||||
.args(&["-t"])
|
||||
.pipe_in("\t\0\n")
|
||||
.succeeds()
|
||||
.stdout_only("^I^@\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_squeeze_blank() {
|
||||
for same_param in vec!["-s", "--squeeze-blank"] {
|
||||
new_ucmd!()
|
||||
.arg(same_param)
|
||||
.pipe_in("\n\na\n\n\n\n\nb\n\n\n")
|
||||
.succeeds()
|
||||
.stdout_only("\na\n\nb\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_number_non_blank() {
|
||||
for same_param in vec!["-b", "--number-nonblank"] {
|
||||
new_ucmd!()
|
||||
.arg(same_param)
|
||||
.arg("-")
|
||||
.pipe_in("\na\nb\n\n\nc")
|
||||
.succeeds()
|
||||
.stdout_only("\n 1\ta\n 2\tb\n\n\n 3\tc");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_non_blank_overrides_number() {
|
||||
for same_param in vec!["-b", "--number-nonblank"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param, "-"])
|
||||
.pipe_in("\na\nb\n\n\nc")
|
||||
.succeeds()
|
||||
.stdout_only("\n 1\ta\n 2\tb\n\n\n 3\tc");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_squeeze_blank_before_numbering() {
|
||||
for same_param in vec!["-s", "--squeeze-blank"] {
|
||||
new_ucmd!()
|
||||
.args(&[same_param, "-n", "-"])
|
||||
.pipe_in("a\n\n\nb")
|
||||
.succeeds()
|
||||
.stdout_only(" 1\ta\n 2\t\n 3\tb");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(foo)]
|
||||
fn test_domain_socket() {
|
||||
use self::tempdir::TempDir;
|
||||
use self::unix_socket::UnixListener;
|
||||
use std::io::prelude::*;
|
||||
use std::thread;
|
||||
|
||||
let dir = TempDir::new("unix_socket").expect("failed to create dir");
|
||||
let socket_path = dir.path().join("sock");
|
||||
let listener = UnixListener::bind(&socket_path).expect("failed to create socket");
|
||||
|
||||
let thread = thread::spawn(move || {
|
||||
let mut stream = listener.accept().expect("failed to accept connection").0;
|
||||
stream
|
||||
.write_all(b"a\tb")
|
||||
.expect("failed to write test data");
|
||||
});
|
||||
|
||||
new_ucmd!()
|
||||
.args(&[socket_path])
|
||||
.succeeds()
|
||||
.stdout_only("a\tb");
|
||||
|
||||
thread.join().unwrap();
|
||||
}
|
159
tests/by-util/test_chgrp.rs
Normal file
159
tests/by-util/test_chgrp.rs
Normal file
|
@ -0,0 +1,159 @@
|
|||
use crate::common::util::*;
|
||||
use rust_users::*;
|
||||
|
||||
#[test]
|
||||
fn test_invalid_option() {
|
||||
new_ucmd!().arg("-w").arg("/").fails();
|
||||
}
|
||||
|
||||
static DIR: &'static str = "/tmp";
|
||||
|
||||
#[test]
|
||||
fn test_invalid_group() {
|
||||
new_ucmd!()
|
||||
.arg("__nosuchgroup__")
|
||||
.arg("/")
|
||||
.fails()
|
||||
.stderr_is("chgrp: invalid group: __nosuchgroup__");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_1() {
|
||||
if get_effective_gid() != 0 {
|
||||
new_ucmd!()
|
||||
.arg("bin")
|
||||
.arg(DIR)
|
||||
.fails()
|
||||
.stderr_is("chgrp: changing group of '/tmp': Operation not permitted (os error 1)");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fail_silently() {
|
||||
if get_effective_gid() != 0 {
|
||||
for opt in &["-f", "--silent", "--quiet"] {
|
||||
new_ucmd!()
|
||||
.arg(opt)
|
||||
.arg("bin")
|
||||
.arg(DIR)
|
||||
.run()
|
||||
.fails_silently();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_preserve_root() {
|
||||
// It's weird that on OS X, `realpath /etc/..` returns '/private'
|
||||
for d in &[
|
||||
"/",
|
||||
"/////tmp///../../../../",
|
||||
"../../../../../../../../../../../../../../",
|
||||
"./../../../../../../../../../../../../../../",
|
||||
] {
|
||||
new_ucmd!()
|
||||
.arg("--preserve-root")
|
||||
.arg("-R")
|
||||
.arg("bin").arg(d)
|
||||
.fails()
|
||||
.stderr_is("chgrp: it is dangerous to operate recursively on '/'\nchgrp: use --no-preserve-root to override this failsafe");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_preserve_root_symlink() {
|
||||
let file = "test_chgrp_symlink2root";
|
||||
for d in &[
|
||||
"/",
|
||||
"////tmp//../../../../",
|
||||
"..//../../..//../..//../../../../../../../../",
|
||||
".//../../../../../../..//../../../../../../../",
|
||||
] {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.symlink_file(d, file);
|
||||
ucmd.arg("--preserve-root")
|
||||
.arg("-HR")
|
||||
.arg("bin").arg(file)
|
||||
.fails()
|
||||
.stderr_is("chgrp: it is dangerous to operate recursively on '/'\nchgrp: use --no-preserve-root to override this failsafe");
|
||||
}
|
||||
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.symlink_file("///usr", file);
|
||||
ucmd.arg("--preserve-root")
|
||||
.arg("-HR")
|
||||
.arg("bin").arg(format!(".//{}/..//..//../../", file))
|
||||
.fails()
|
||||
.stderr_is("chgrp: it is dangerous to operate recursively on '/'\nchgrp: use --no-preserve-root to override this failsafe");
|
||||
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.symlink_file("/", "/tmp/__root__");
|
||||
ucmd.arg("--preserve-root")
|
||||
.arg("-R")
|
||||
.arg("bin").arg("/tmp/__root__/.")
|
||||
.fails()
|
||||
.stderr_is("chgrp: it is dangerous to operate recursively on '/'\nchgrp: use --no-preserve-root to override this failsafe");
|
||||
|
||||
use std::fs;
|
||||
fs::remove_file("/tmp/__root__").unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
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()) {
|
||||
new_ucmd!()
|
||||
.arg("-v")
|
||||
.arg("--reference=/etc/passwd")
|
||||
.arg("/etc")
|
||||
.fails()
|
||||
.stderr_is("chgrp: changing group of '/etc': Operation not permitted (os error 1)\n")
|
||||
.stdout_is("failed to change group of /etc from root to root\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "macos")]
|
||||
fn test_reference() {
|
||||
new_ucmd!()
|
||||
.arg("-v")
|
||||
.arg("--reference=/etc/passwd")
|
||||
.arg("/etc")
|
||||
.succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_big_p() {
|
||||
if get_effective_gid() != 0 {
|
||||
new_ucmd!()
|
||||
.arg("-RP")
|
||||
.arg("bin")
|
||||
.arg("/proc/self/cwd")
|
||||
.fails()
|
||||
.stderr_is(
|
||||
"chgrp: changing group of '/proc/self/cwd': Operation not permitted (os error 1)\n",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_big_h() {
|
||||
if get_effective_gid() != 0 {
|
||||
assert!(
|
||||
new_ucmd!()
|
||||
.arg("-RH")
|
||||
.arg("bin")
|
||||
.arg("/proc/self/fd")
|
||||
.fails()
|
||||
.stderr
|
||||
.lines()
|
||||
.fold(0, |acc, _| acc + 1)
|
||||
> 1
|
||||
);
|
||||
}
|
||||
}
|
281
tests/by-util/test_chmod.rs
Normal file
281
tests/by-util/test_chmod.rs
Normal file
|
@ -0,0 +1,281 @@
|
|||
use crate::common::util::*;
|
||||
use std::fs::{metadata, set_permissions, OpenOptions};
|
||||
use std::os::unix::fs::{OpenOptionsExt, PermissionsExt};
|
||||
use std::sync::Mutex;
|
||||
|
||||
extern crate libc;
|
||||
use self::libc::umask;
|
||||
|
||||
static TEST_FILE: &'static str = "file";
|
||||
static REFERENCE_FILE: &'static str = "reference";
|
||||
static REFERENCE_PERMS: u32 = 0o247;
|
||||
lazy_static! {
|
||||
static ref UMASK_MUTEX: Mutex<()> = Mutex::new(());
|
||||
}
|
||||
|
||||
struct TestCase {
|
||||
args: Vec<&'static str>,
|
||||
before: u32,
|
||||
after: u32,
|
||||
}
|
||||
|
||||
fn mkfile(file: &str, mode: u32) {
|
||||
OpenOptions::new()
|
||||
.mode(mode)
|
||||
.create(true)
|
||||
.write(true)
|
||||
.open(file)
|
||||
.unwrap();
|
||||
let mut perms = metadata(file).unwrap().permissions();
|
||||
perms.set_mode(mode);
|
||||
set_permissions(file, perms).unwrap();
|
||||
}
|
||||
|
||||
fn run_single_test(test: &TestCase, at: AtPath, mut ucmd: UCommand) {
|
||||
mkfile(&at.plus_as_string(TEST_FILE), test.before);
|
||||
let perms = at.metadata(TEST_FILE).permissions().mode();
|
||||
if perms != test.before {
|
||||
panic!(format!(
|
||||
"{}: expected: {:o} got: {:o}",
|
||||
"setting permissions on test files before actual test run failed", test.after, perms
|
||||
));
|
||||
}
|
||||
|
||||
for arg in &test.args {
|
||||
ucmd.arg(arg);
|
||||
}
|
||||
let r = ucmd.run();
|
||||
if !r.success {
|
||||
println!("{}", r.stderr);
|
||||
panic!(format!("{:?}: failed", ucmd.raw));
|
||||
}
|
||||
|
||||
let perms = at.metadata(TEST_FILE).permissions().mode();
|
||||
if perms != test.after {
|
||||
panic!(format!(
|
||||
"{:?}: expected: {:o} got: {:o}",
|
||||
ucmd.raw, test.after, perms
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn run_tests(tests: Vec<TestCase>) {
|
||||
for test in tests {
|
||||
let (at, ucmd) = at_and_ucmd!();
|
||||
run_single_test(&test, at, ucmd);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chmod_octal() {
|
||||
let tests = vec![
|
||||
TestCase {
|
||||
args: vec!["0700", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100700,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["0070", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100070,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["0007", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100007,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["-0700", TEST_FILE],
|
||||
before: 0o100700,
|
||||
after: 0o100000,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["-0070", TEST_FILE],
|
||||
before: 0o100060,
|
||||
after: 0o100000,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["-0007", TEST_FILE],
|
||||
before: 0o100001,
|
||||
after: 0o100000,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["+0100", TEST_FILE],
|
||||
before: 0o100600,
|
||||
after: 0o100700,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["+0020", TEST_FILE],
|
||||
before: 0o100050,
|
||||
after: 0o100070,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["+0004", TEST_FILE],
|
||||
before: 0o100003,
|
||||
after: 0o100007,
|
||||
},
|
||||
];
|
||||
run_tests(tests);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chmod_ugoa() {
|
||||
let _guard = UMASK_MUTEX.lock();
|
||||
|
||||
let last = unsafe { umask(0) };
|
||||
let tests = vec![
|
||||
TestCase {
|
||||
args: vec!["u=rwx", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100700,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["g=rwx", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100070,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["o=rwx", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100007,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["a=rwx", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100777,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["-r", TEST_FILE],
|
||||
before: 0o100777,
|
||||
after: 0o100333,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["-w", TEST_FILE],
|
||||
before: 0o100777,
|
||||
after: 0o100555,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["-x", TEST_FILE],
|
||||
before: 0o100777,
|
||||
after: 0o100666,
|
||||
},
|
||||
];
|
||||
run_tests(tests);
|
||||
|
||||
unsafe {
|
||||
umask(0o022);
|
||||
}
|
||||
let tests = vec![
|
||||
TestCase {
|
||||
args: vec!["u=rwx", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100700,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["g=rwx", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100070,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["o=rwx", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100007,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["a=rwx", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100777,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["+rw", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100644,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["=rwx", TEST_FILE],
|
||||
before: 0o100000,
|
||||
after: 0o100755,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["-w", TEST_FILE],
|
||||
before: 0o100777,
|
||||
after: 0o100577,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["-x", TEST_FILE],
|
||||
before: 0o100777,
|
||||
after: 0o100666,
|
||||
},
|
||||
];
|
||||
run_tests(tests);
|
||||
unsafe {
|
||||
umask(last);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chmod_ugo_copy() {
|
||||
let tests = vec![
|
||||
TestCase {
|
||||
args: vec!["u=g", TEST_FILE],
|
||||
before: 0o100070,
|
||||
after: 0o100770,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["g=o", TEST_FILE],
|
||||
before: 0o100005,
|
||||
after: 0o100055,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["o=u", TEST_FILE],
|
||||
before: 0o100200,
|
||||
after: 0o100202,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["u-g", TEST_FILE],
|
||||
before: 0o100710,
|
||||
after: 0o100610,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["u+g", TEST_FILE],
|
||||
before: 0o100250,
|
||||
after: 0o100750,
|
||||
},
|
||||
];
|
||||
run_tests(tests);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chmod_many_options() {
|
||||
let _guard = UMASK_MUTEX.lock();
|
||||
|
||||
let original_umask = unsafe { umask(0) };
|
||||
let tests = vec![TestCase {
|
||||
args: vec!["-r,a+w", TEST_FILE],
|
||||
before: 0o100444,
|
||||
after: 0o100222,
|
||||
}];
|
||||
run_tests(tests);
|
||||
unsafe {
|
||||
umask(original_umask);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chmod_reference_file() {
|
||||
let tests = vec![
|
||||
TestCase {
|
||||
args: vec!["--reference", REFERENCE_FILE, TEST_FILE],
|
||||
before: 0o100070,
|
||||
after: 0o100247,
|
||||
},
|
||||
TestCase {
|
||||
args: vec!["a-w", "--reference", REFERENCE_FILE, TEST_FILE],
|
||||
before: 0o100070,
|
||||
after: 0o100247,
|
||||
},
|
||||
];
|
||||
let (at, ucmd) = at_and_ucmd!();
|
||||
mkfile(&at.plus_as_string(REFERENCE_FILE), REFERENCE_PERMS);
|
||||
run_single_test(&tests[0], at, ucmd);
|
||||
}
|
48
tests/by-util/test_chown.rs
Normal file
48
tests/by-util/test_chown.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
extern crate chown;
|
||||
// pub use self::uu_chown::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_passgrp {
|
||||
use super::chown::entries::{gid2grp, grp2gid, uid2usr, usr2uid};
|
||||
|
||||
#[test]
|
||||
fn test_usr2uid() {
|
||||
assert_eq!(0, usr2uid("root").unwrap());
|
||||
assert!(usr2uid("88888888").is_err());
|
||||
assert!(usr2uid("auserthatdoesntexist").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_grp2gid() {
|
||||
if cfg!(target_os = "linux") || cfg!(target_os = "android") || cfg!(target_os = "windows") {
|
||||
assert_eq!(0, grp2gid("root").unwrap())
|
||||
} else {
|
||||
assert_eq!(0, grp2gid("wheel").unwrap());
|
||||
}
|
||||
assert!(grp2gid("88888888").is_err());
|
||||
assert!(grp2gid("agroupthatdoesntexist").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uid2usr() {
|
||||
assert_eq!("root", uid2usr(0).unwrap());
|
||||
assert!(uid2usr(88888888).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_gid2grp() {
|
||||
if cfg!(target_os = "linux") || cfg!(target_os = "android") || cfg!(target_os = "windows") {
|
||||
assert_eq!("root", gid2grp(0).unwrap());
|
||||
} else {
|
||||
assert_eq!("wheel", gid2grp(0).unwrap());
|
||||
}
|
||||
assert!(gid2grp(88888888).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_option() {
|
||||
new_ucmd!().arg("-w").arg("-q").arg("/").fails();
|
||||
}
|
26
tests/by-util/test_cksum.rs
Normal file
26
tests/by-util/test_cksum.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_single_file() {
|
||||
new_ucmd!()
|
||||
.arg("lorem_ipsum.txt")
|
||||
.succeeds()
|
||||
.stdout_is_fixture("single_file.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_files() {
|
||||
new_ucmd!()
|
||||
.arg("lorem_ipsum.txt")
|
||||
.arg("alice_in_wonderland.txt")
|
||||
.succeeds()
|
||||
.stdout_is_fixture("multiple_files.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin() {
|
||||
new_ucmd!()
|
||||
.pipe_in_fixture("lorem_ipsum.txt")
|
||||
.succeeds()
|
||||
.stdout_is_fixture("stdin.expected");
|
||||
}
|
170
tests/by-util/test_comm.rs
Normal file
170
tests/by-util/test_comm.rs
Normal file
|
@ -0,0 +1,170 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn ab_no_args() {
|
||||
new_ucmd!()
|
||||
.args(&["a", "b"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("ab.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ab_dash_one() {
|
||||
new_ucmd!()
|
||||
.args(&["a", "b", "-1"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("ab1.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ab_dash_two() {
|
||||
new_ucmd!()
|
||||
.args(&["a", "b", "-2"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("ab2.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ab_dash_three() {
|
||||
new_ucmd!()
|
||||
.args(&["a", "b", "-3"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("ab3.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn aempty() {
|
||||
new_ucmd!()
|
||||
.args(&["a", "empty"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("aempty.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn emptyempty() {
|
||||
new_ucmd!()
|
||||
.args(&["empty", "empty"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("emptyempty.expected");
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn output_delimiter() {
|
||||
new_ucmd!()
|
||||
.args(&["--output-delimiter=word", "a", "b"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("ab_delimiter_word.expected");
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn output_delimiter_require_arg() {
|
||||
new_ucmd!()
|
||||
.args(&["--output-delimiter=", "a", "b"])
|
||||
.fails()
|
||||
.stderr_only("error to be defined");
|
||||
}
|
||||
|
||||
// even though (info) documentation suggests this is an option
|
||||
// in latest GNU Coreutils comm, it actually is not.
|
||||
// this test is essentially an alarm in case someone well-intendingly
|
||||
// implements it.
|
||||
//marked as unimplemented as error message not set yet.
|
||||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn zero_terminated() {
|
||||
for param in vec!["-z", "--zero-terminated"] {
|
||||
new_ucmd!()
|
||||
.args(&[param, "a", "b"])
|
||||
.fails()
|
||||
.stderr_only("error to be defined");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn check_order() {
|
||||
new_ucmd!()
|
||||
.args(&["--check-order", "bad_order_1", "bad_order_2"])
|
||||
.fails()
|
||||
.stdout_is_fixture("bad_order12.check_order.expected")
|
||||
.stderr_is("error to be defined");
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn nocheck_order() {
|
||||
new_ucmd!()
|
||||
.args(&["--nocheck-order", "bad_order_1", "bad_order_2"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("bad_order12.nocheck_order.expected");
|
||||
}
|
||||
|
||||
// when neither --check-order nor --no-check-order is provided,
|
||||
// stderr and the error code behaves like check order, but stdout
|
||||
// behaves like nocheck_order. However with some quirks detailed below.
|
||||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn defaultcheck_order() {
|
||||
new_ucmd!()
|
||||
.args(&["a", "bad_order_1"])
|
||||
.fails()
|
||||
.stderr_only("error to be defined");
|
||||
}
|
||||
|
||||
// * the first: if both files are not in order, the default behavior is the only
|
||||
// behavior that will provide an error message
|
||||
|
||||
// * the second: if two rows are paired but are out of order,
|
||||
// it won't matter if all rows in the two files are exactly the same.
|
||||
// This is specified in the documentation
|
||||
|
||||
#[test]
|
||||
fn defaultcheck_order_identical_bad_order_files() {
|
||||
new_ucmd!()
|
||||
.args(&["bad_order_1", "bad_order_1"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("bad_order11.defaultcheck_order.expected");
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn defaultcheck_order_two_different_bad_order_files() {
|
||||
new_ucmd!()
|
||||
.args(&["bad_order_1", "bad_order_2"])
|
||||
.fails()
|
||||
.stdout_is_fixture("bad_order12.nocheck_order.expected")
|
||||
.stderr_is("error to be defined");
|
||||
}
|
||||
|
||||
// * the third: (it is not know whether this is a bug or not)
|
||||
// for the first incident, and only the first incident,
|
||||
// where both lines are different and one or both file lines being
|
||||
// compared are out of order from the preceding line,
|
||||
// it is ignored and no errors occur.
|
||||
|
||||
// * the fourth: (it is not known whether this is a bug or not)
|
||||
// there are additional, not-yet-understood circumstances where an out-of-order
|
||||
// pair is ignored and is not counted against the 1 maximum out-of-order line.
|
||||
|
||||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn unintuitive_default_behavior_1() {
|
||||
new_ucmd!()
|
||||
.args(&["defaultcheck_unintuitive_1", "defaultcheck_unintuitive_2"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("defaultcheck_unintuitive.expected");
|
||||
}
|
||||
|
||||
#[ignore] //bug? should help be stdout if not called via -h|--help?
|
||||
#[test]
|
||||
fn no_arguments() {
|
||||
new_ucmd!().fails().no_stdout().no_stderr();
|
||||
}
|
||||
|
||||
#[ignore] //bug? should help be stdout if not called via -h|--help?
|
||||
#[test]
|
||||
fn one_argument() {
|
||||
new_ucmd!().arg("a").fails().no_stdout().no_stderr();
|
||||
}
|
330
tests/by-util/test_cp.rs
Normal file
330
tests/by-util/test_cp.rs
Normal file
|
@ -0,0 +1,330 @@
|
|||
use crate::common::util::*;
|
||||
#[cfg(not(windows))]
|
||||
use std::fs::set_permissions;
|
||||
|
||||
static TEST_EXISTING_FILE: &str = "existing_file.txt";
|
||||
static TEST_HELLO_WORLD_SOURCE: &str = "hello_world.txt";
|
||||
static TEST_HELLO_WORLD_DEST: &str = "copy_of_hello_world.txt";
|
||||
static TEST_HOW_ARE_YOU_SOURCE: &str = "how_are_you.txt";
|
||||
static TEST_HOW_ARE_YOU_DEST: &str = "hello_dir/how_are_you.txt";
|
||||
static TEST_COPY_TO_FOLDER: &str = "hello_dir/";
|
||||
static TEST_COPY_TO_FOLDER_FILE: &str = "hello_dir/hello_world.txt";
|
||||
static TEST_COPY_FROM_FOLDER: &str = "hello_dir_with_file/";
|
||||
static TEST_COPY_FROM_FOLDER_FILE: &str = "hello_dir_with_file/hello_world.txt";
|
||||
static TEST_COPY_TO_FOLDER_NEW: &str = "hello_dir_new/";
|
||||
static TEST_COPY_TO_FOLDER_NEW_FILE: &str = "hello_dir_new/hello_world.txt";
|
||||
|
||||
#[test]
|
||||
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)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
|
||||
// Check that the exit code represents a successful copy.
|
||||
let exit_success = result.success;
|
||||
assert!(exit_success);
|
||||
|
||||
// Check the content of the destination file that was copied.
|
||||
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_existing_target() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_EXISTING_FILE)
|
||||
.run();
|
||||
|
||||
assert!(result.success);
|
||||
|
||||
// Check the content of the destination file
|
||||
assert_eq!(at.read(TEST_EXISTING_FILE), "Hello, World!\n");
|
||||
|
||||
// No backup should have been created
|
||||
assert!(!at.file_exists(&*format!("{}~", TEST_EXISTING_FILE)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_duplicate_files() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let result = 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"));
|
||||
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
|
||||
.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"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_directory_not_recursive() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
|
||||
assert!(!result.success);
|
||||
assert!(result.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)
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_recurse() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd
|
||||
.arg("-r")
|
||||
.arg(TEST_COPY_FROM_FOLDER)
|
||||
.arg(TEST_COPY_TO_FOLDER_NEW)
|
||||
.run();
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
#[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")
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.run();
|
||||
assert!(result_to_dir_t.success);
|
||||
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_with_dirs() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
//using -t option
|
||||
let result_to_dir = scene
|
||||
.ucmd()
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
assert!(result_to_dir.success);
|
||||
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
|
||||
|
||||
let result_from_dir = scene
|
||||
.ucmd()
|
||||
.arg(TEST_COPY_FROM_FOLDER_FILE)
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
assert!(result_from_dir.success);
|
||||
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)
|
||||
.arg("-t")
|
||||
.arg(TEST_COPY_TO_FOLDER)
|
||||
.run();
|
||||
|
||||
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
|
||||
.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"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_arg_interactive() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = 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"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "unix")]
|
||||
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)
|
||||
.arg("--link")
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
|
||||
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)
|
||||
.arg("--symbolic-link")
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
|
||||
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)
|
||||
.arg("--no-clobber")
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.run();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HOW_ARE_YOU_SOURCE), "How are you?\n");
|
||||
assert!(result.stderr.contains("Not overwriting"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_cp_arg_force() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
// create dest without write permissions
|
||||
let mut permissions = at
|
||||
.make_file(TEST_HELLO_WORLD_DEST)
|
||||
.metadata()
|
||||
.unwrap()
|
||||
.permissions();
|
||||
permissions.set_readonly(true);
|
||||
set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();
|
||||
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--force")
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
|
||||
println!("{:?}", result.stderr);
|
||||
println!("{:?}", result.stdout);
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
|
||||
}
|
||||
|
||||
/// TODO: write a better test that differentiates --remove-destination
|
||||
/// from --force. Also this test currently doesn't work on
|
||||
/// Windows. This test originally checked file timestamps, which
|
||||
/// proved to be unreliable per target / CI platform
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_cp_arg_remove_destination() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
// create dest without write permissions
|
||||
let mut permissions = at
|
||||
.make_file(TEST_HELLO_WORLD_DEST)
|
||||
.metadata()
|
||||
.unwrap()
|
||||
.permissions();
|
||||
permissions.set_readonly(true);
|
||||
set_permissions(at.plus(TEST_HELLO_WORLD_DEST), permissions).unwrap();
|
||||
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--remove-destination")
|
||||
.arg(TEST_HELLO_WORLD_DEST)
|
||||
.run();
|
||||
|
||||
assert!(result.success);
|
||||
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_arg_backup() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--backup")
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.run();
|
||||
|
||||
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)),
|
||||
"How are you?\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cp_arg_suffix() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd
|
||||
.arg(TEST_HELLO_WORLD_SOURCE)
|
||||
.arg("--suffix")
|
||||
.arg(".bak")
|
||||
.arg(TEST_HOW_ARE_YOU_SOURCE)
|
||||
.run();
|
||||
|
||||
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)),
|
||||
"How are you?\n"
|
||||
);
|
||||
}
|
141
tests/by-util/test_cut.rs
Normal file
141
tests/by-util/test_cut.rs
Normal file
|
@ -0,0 +1,141 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
static INPUT: &'static str = "lists.txt";
|
||||
|
||||
struct TestedSequence<'b> {
|
||||
name: &'b str,
|
||||
sequence: &'b str,
|
||||
}
|
||||
|
||||
static EXAMPLE_SEQUENCES: &'static [TestedSequence<'static>] = &[
|
||||
TestedSequence {
|
||||
name: "singular",
|
||||
sequence: "2",
|
||||
},
|
||||
TestedSequence {
|
||||
name: "prefix",
|
||||
sequence: "-2",
|
||||
},
|
||||
TestedSequence {
|
||||
name: "suffix",
|
||||
sequence: "2-",
|
||||
},
|
||||
TestedSequence {
|
||||
name: "range",
|
||||
sequence: "2-4",
|
||||
},
|
||||
TestedSequence {
|
||||
name: "aggregate",
|
||||
sequence: "9-,6-7,-2,4",
|
||||
},
|
||||
TestedSequence {
|
||||
name: "subsumed",
|
||||
sequence: "2-,3",
|
||||
},
|
||||
];
|
||||
|
||||
static COMPLEX_SEQUENCE: &'static TestedSequence<'static> = &TestedSequence {
|
||||
name: "",
|
||||
sequence: "9-,6-7,-2,4",
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_byte_sequence() {
|
||||
for param in vec!["-b", "--bytes"] {
|
||||
for example_seq in EXAMPLE_SEQUENCES {
|
||||
new_ucmd!()
|
||||
.args(&[param, example_seq.sequence, INPUT])
|
||||
.succeeds()
|
||||
.stdout_only_fixture(format!("sequences/byte_{}.expected", example_seq.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_char_sequence() {
|
||||
for param in vec!["-c", "--characters"] {
|
||||
for example_seq in EXAMPLE_SEQUENCES {
|
||||
//as of coreutils 8.25 a char range is effectively the same as a byte range; there is no distinct treatment of utf8 chars.
|
||||
new_ucmd!()
|
||||
.args(&[param, example_seq.sequence, INPUT])
|
||||
.succeeds()
|
||||
.stdout_only_fixture(format!("sequences/byte_{}.expected", example_seq.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_field_sequence() {
|
||||
for param in vec!["-f", "--fields"] {
|
||||
for example_seq in EXAMPLE_SEQUENCES {
|
||||
new_ucmd!()
|
||||
.args(&[param, example_seq.sequence, INPUT])
|
||||
.succeeds()
|
||||
.stdout_only_fixture(format!("sequences/field_{}.expected", example_seq.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_specify_delimiter() {
|
||||
for param in vec!["-d", "--delimiter"] {
|
||||
new_ucmd!()
|
||||
.args(&[param, ":", "-f", COMPLEX_SEQUENCE.sequence, INPUT])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("delimiter_specified.expected");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_output_delimiter() {
|
||||
// we use -d here to ensure output delimiter
|
||||
// is applied to the current, and not just the default, input delimiter
|
||||
new_ucmd!()
|
||||
.args(&[
|
||||
"-d:",
|
||||
"--output-delimiter=@",
|
||||
"-f",
|
||||
COMPLEX_SEQUENCE.sequence,
|
||||
INPUT,
|
||||
])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("output_delimiter.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_complement() {
|
||||
new_ucmd!()
|
||||
.args(&["-d_", "--complement", "-f", "2"])
|
||||
.pipe_in("9_1\n8_2\n7_3")
|
||||
.succeeds()
|
||||
.stdout_only("9\n8\n7\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_terminated() {
|
||||
new_ucmd!()
|
||||
.args(&["-d_", "-z", "-f", "1"])
|
||||
.pipe_in("9_1\n8_2\n\07_3")
|
||||
.succeeds()
|
||||
.stdout_only("9\07\0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_only_delimited() {
|
||||
for param in vec!["-s", "--only-delimited"] {
|
||||
new_ucmd!()
|
||||
.args(&["-d_", param, "-f", "1"])
|
||||
.pipe_in("91\n82\n7_3")
|
||||
.succeeds()
|
||||
.stdout_only("7\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_terminated_only_delimited() {
|
||||
new_ucmd!()
|
||||
.args(&["-d_", "-z", "-s", "-f", "1"])
|
||||
.pipe_in("91\n\082\n7_3")
|
||||
.succeeds()
|
||||
.stdout_only("82\n7\0");
|
||||
}
|
133
tests/by-util/test_date.rs
Normal file
133
tests/by-util/test_date.rs
Normal file
|
@ -0,0 +1,133 @@
|
|||
extern crate regex;
|
||||
|
||||
use self::regex::Regex;
|
||||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_date_email() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--rfc-email").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_email2() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("-R").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_rfc_3339() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let mut result = scene.ucmd().arg("--rfc-3339=ns").succeeds();
|
||||
|
||||
// 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.trim()));
|
||||
|
||||
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.trim()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_rfc_8601() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--iso-8601=ns").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_rfc_8601_second() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--iso-8601=second").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_utc() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--utc").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_date_universal() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("--universal").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[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.trim()));
|
||||
|
||||
result = scene.ucmd().arg("+%y").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
re = Regex::new(r"^\d{2}$").unwrap();
|
||||
assert!(re.is_match(&result.stdout.trim()));
|
||||
}
|
||||
|
||||
#[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.trim()));
|
||||
|
||||
result = scene.ucmd().arg("+%m").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
re = Regex::new(r"^\d{2}$").unwrap();
|
||||
assert!(re.is_match(&result.stdout.trim()));
|
||||
}
|
||||
|
||||
#[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.trim()));
|
||||
|
||||
result = scene.ucmd().arg("+%A").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
|
||||
re = Regex::new(r"\S+").unwrap();
|
||||
assert!(re.is_match(&result.stdout.trim()));
|
||||
|
||||
result = scene.ucmd().arg("+%u").succeeds();
|
||||
|
||||
assert!(result.success);
|
||||
re = Regex::new(r"^\d{1}$").unwrap();
|
||||
assert!(re.is_match(&result.stdout.trim()));
|
||||
}
|
||||
|
||||
#[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.trim()));
|
||||
}
|
31
tests/by-util/test_df.rs
Normal file
31
tests/by-util/test_df.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_df_compatible() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("-ah").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_df_compatible_type() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("-aT").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_df_compatible_si() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.arg("-aH").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
// ToDO: more tests...
|
107
tests/by-util/test_dircolors.rs
Normal file
107
tests/by-util/test_dircolors.rs
Normal file
|
@ -0,0 +1,107 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
extern crate dircolors;
|
||||
use self::dircolors::{guess_syntax, OutputFmt, StrUtils};
|
||||
|
||||
#[test]
|
||||
fn test_shell_syntax() {
|
||||
use std::env;
|
||||
let last = env::var("SHELL");
|
||||
env::set_var("SHELL", "/path/csh");
|
||||
assert_eq!(OutputFmt::CShell, guess_syntax());
|
||||
env::set_var("SHELL", "csh");
|
||||
assert_eq!(OutputFmt::CShell, guess_syntax());
|
||||
env::set_var("SHELL", "/path/bash");
|
||||
assert_eq!(OutputFmt::Shell, guess_syntax());
|
||||
env::set_var("SHELL", "bash");
|
||||
assert_eq!(OutputFmt::Shell, guess_syntax());
|
||||
env::set_var("SHELL", "/asd/bar");
|
||||
assert_eq!(OutputFmt::Shell, guess_syntax());
|
||||
env::set_var("SHELL", "foo");
|
||||
assert_eq!(OutputFmt::Shell, guess_syntax());
|
||||
env::set_var("SHELL", "");
|
||||
assert_eq!(OutputFmt::Unknown, guess_syntax());
|
||||
env::remove_var("SHELL");
|
||||
assert_eq!(OutputFmt::Unknown, guess_syntax());
|
||||
|
||||
if let Ok(s) = last {
|
||||
env::set_var("SHELL", s);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_strutils() {
|
||||
let s = " asd#zcv #hk\t\n ";
|
||||
assert_eq!("asd#zcv", s.purify());
|
||||
|
||||
let s = "con256asd";
|
||||
assert!(s.fnmatch("*[2][3-6][5-9]?sd"));
|
||||
|
||||
let s = "zxc \t\nqwe jlk hjl";
|
||||
let (k, v) = s.split_two();
|
||||
assert_eq!("zxc", k);
|
||||
assert_eq!("qwe jlk hjl", v);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test1() {
|
||||
test_helper("test1", "gnome");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_keywords() {
|
||||
test_helper("keywords", "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_internal_db() {
|
||||
new_ucmd!()
|
||||
.arg("-p")
|
||||
.run()
|
||||
.stdout_is_fixture("internal.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bash_default() {
|
||||
new_ucmd!()
|
||||
.env("TERM", "screen")
|
||||
.arg("-b")
|
||||
.run()
|
||||
.stdout_is_fixture("bash_def.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_csh_default() {
|
||||
new_ucmd!()
|
||||
.env("TERM", "screen")
|
||||
.arg("-c")
|
||||
.run()
|
||||
.stdout_is_fixture("csh_def.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_env() {
|
||||
// no SHELL and TERM
|
||||
new_ucmd!().fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_exclusive_option() {
|
||||
new_ucmd!().arg("-cp").fails();
|
||||
}
|
||||
|
||||
fn test_helper(file_name: &str, term: &str) {
|
||||
new_ucmd!()
|
||||
.env("TERM", term)
|
||||
.arg("-c")
|
||||
.arg(format!("{}.txt", file_name))
|
||||
.run()
|
||||
.stdout_is_fixture(format!("{}.csh.expected", file_name));
|
||||
|
||||
new_ucmd!()
|
||||
.env("TERM", term)
|
||||
.arg("-b")
|
||||
.arg(format!("{}.txt", file_name))
|
||||
.run()
|
||||
.stdout_is_fixture(format!("{}.sh.expected", file_name));
|
||||
}
|
32
tests/by-util/test_dirname.rs
Normal file
32
tests/by-util/test_dirname.rs
Normal file
|
@ -0,0 +1,32 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_path_with_trailing_slashes() {
|
||||
new_ucmd!()
|
||||
.arg("/root/alpha/beta/gamma/delta/epsilon/omega//")
|
||||
.run()
|
||||
.stdout_is("/root/alpha/beta/gamma/delta/epsilon\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_path_without_trailing_slashes() {
|
||||
new_ucmd!()
|
||||
.arg("/root/alpha/beta/gamma/delta/epsilon/omega")
|
||||
.run()
|
||||
.stdout_is("/root/alpha/beta/gamma/delta/epsilon\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_root() {
|
||||
new_ucmd!().arg("/").run().stdout_is("/\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pwd() {
|
||||
new_ucmd!().arg(".").run().stdout_is(".\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty() {
|
||||
new_ucmd!().arg("").run().stdout_is(".\n");
|
||||
}
|
148
tests/by-util/test_du.rs
Normal file
148
tests/by-util/test_du.rs
Normal file
|
@ -0,0 +1,148 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
const SUB_DIR: &str = "subdir/deeper";
|
||||
const SUB_DIR_LINKS: &str = "subdir/links";
|
||||
const SUB_FILE: &str = "subdir/links/subwords.txt";
|
||||
const SUB_LINK: &str = "subdir/links/sublink.txt";
|
||||
|
||||
#[test]
|
||||
fn test_du_basics() {
|
||||
let (_at, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.run();
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stderr, "");
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
fn _du_basics(s: String) {
|
||||
let answer = "32\t./subdir
|
||||
8\t./subdir/deeper
|
||||
24\t./subdir/links
|
||||
40\t./
|
||||
";
|
||||
assert_eq!(s, answer);
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn _du_basics(s: String) {
|
||||
let answer = "28\t./subdir
|
||||
8\t./subdir/deeper
|
||||
16\t./subdir/links
|
||||
36\t./
|
||||
";
|
||||
assert_eq!(s, answer);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_du_basics_subdir() {
|
||||
let (_at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg(SUB_DIR).run();
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stderr, "");
|
||||
_du_basics_subdir(result.stdout);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn _du_basics_subdir(s: String) {
|
||||
assert_eq!(s, "4\tsubdir/deeper\n");
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn _du_basics_subdir(s: String) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
assert_eq!(s, "8\tsubdir/deeper\n");
|
||||
} else {
|
||||
assert_eq!(s, "0\tsubdir/deeper\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[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, "");
|
||||
assert_eq!(
|
||||
result.stderr,
|
||||
"du: error: bad_name: No such file or directory\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_du_soft_link() {
|
||||
let ts = TestScenario::new("du");
|
||||
|
||||
let link = ts.cmd("ln").arg("-s").arg(SUB_FILE).arg(SUB_LINK).run();
|
||||
assert!(link.success);
|
||||
|
||||
let result = ts.ucmd().arg(SUB_DIR_LINKS).run();
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stderr, "");
|
||||
_du_soft_link(result.stdout);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn _du_soft_link(s: String) {
|
||||
// 'macos' host variants may have `du` output variation for soft links
|
||||
assert!((s == "12\tsubdir/links\n") || (s == "16\tsubdir/links\n"));
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn _du_soft_link(s: String) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
assert_eq!(s, "16\tsubdir/links\n");
|
||||
} else {
|
||||
assert_eq!(s, "8\tsubdir/links\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_du_hard_link() {
|
||||
let ts = TestScenario::new("du");
|
||||
|
||||
let link = ts.cmd("ln").arg(SUB_FILE).arg(SUB_LINK).run();
|
||||
assert!(link.success);
|
||||
|
||||
let result = ts.ucmd().arg(SUB_DIR_LINKS).run();
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stderr, "");
|
||||
// We do not double count hard links as the inodes are identical
|
||||
_du_hard_link(result.stdout);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn _du_hard_link(s: String) {
|
||||
assert_eq!(s, "12\tsubdir/links\n")
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn _du_hard_link(s: String) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
assert_eq!(s, "16\tsubdir/links\n");
|
||||
} else {
|
||||
assert_eq!(s, "8\tsubdir/links\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_du_d_flag() {
|
||||
let ts = TestScenario::new("du");
|
||||
|
||||
let result = ts.ucmd().arg("-d").arg("1").run();
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stderr, "");
|
||||
_du_d_flag(result.stdout);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn _du_d_flag(s: String) {
|
||||
assert_eq!(s, "16\t./subdir\n20\t./\n");
|
||||
}
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn _du_d_flag(s: String) {
|
||||
// MS-WSL linux has altered expected output
|
||||
if !is_wsl() {
|
||||
assert_eq!(s, "28\t./subdir\n36\t./\n");
|
||||
} else {
|
||||
assert_eq!(s, "8\t./subdir\n8\t./\n");
|
||||
}
|
||||
}
|
175
tests/by-util/test_echo.rs
Normal file
175
tests/by-util/test_echo.rs
Normal file
|
@ -0,0 +1,175 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_default() {
|
||||
//CmdResult.stdout_only(...) trims trailing newlines
|
||||
assert_eq!("hi\n", new_ucmd!().arg("hi").succeeds().no_stderr().stdout);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_trailing_newline() {
|
||||
//CmdResult.stdout_only(...) trims trailing newlines
|
||||
assert_eq!(
|
||||
"hi",
|
||||
new_ucmd!()
|
||||
.arg("-n")
|
||||
.arg("hi")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_alert() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\a"])
|
||||
.succeeds()
|
||||
.stdout_only("\x07\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_backslash() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\\\"])
|
||||
.succeeds()
|
||||
.stdout_only("\\\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_backspace() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\b"])
|
||||
.succeeds()
|
||||
.stdout_only("\x08\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_carriage_return() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\r"])
|
||||
.succeeds()
|
||||
.stdout_only("\r\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_escape() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\e"])
|
||||
.succeeds()
|
||||
.stdout_only("\x1B\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_form_feed() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\f"])
|
||||
.succeeds()
|
||||
.stdout_only("\x0C\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_hex() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\x41"])
|
||||
.succeeds()
|
||||
.stdout_only("A\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_short_hex() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "foo\\xa bar"])
|
||||
.succeeds()
|
||||
.stdout_only("foo\n bar\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_no_hex() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "foo\\x bar"])
|
||||
.succeeds()
|
||||
.stdout_only("foo\\x bar\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_one_slash() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "foo\\ bar"])
|
||||
.succeeds()
|
||||
.stdout_only("foo\\ bar\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_one_slash_multi() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "foo\\", "bar"])
|
||||
.succeeds()
|
||||
.stdout_only("foo\\ bar\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_newline() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\na"])
|
||||
.succeeds()
|
||||
.stdout_only("\na\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_no_further_output() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "a\\cb", "c"])
|
||||
.succeeds()
|
||||
.stdout_only("a\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_octal() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\0100"])
|
||||
.succeeds()
|
||||
.stdout_only("@\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_short_octal() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "foo\\040bar"])
|
||||
.succeeds()
|
||||
.stdout_only("foo bar\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_no_octal() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "foo\\0 bar"])
|
||||
.succeeds()
|
||||
.stdout_only("foo\\0 bar\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_tab() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\t"])
|
||||
.succeeds()
|
||||
.stdout_only("\t\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_escape_vertical_tab() {
|
||||
new_ucmd!()
|
||||
.args(&["-e", "\\v"])
|
||||
.succeeds()
|
||||
.stdout_only("\x0B\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_disable_escapes() {
|
||||
let input_str = "\\a \\\\ \\b \\r \\e \\f \\x41 \\n a\\cb \\u0100 \\t \\v";
|
||||
new_ucmd!()
|
||||
.arg("-E")
|
||||
.arg(input_str)
|
||||
.succeeds()
|
||||
.stdout_only(format!("{}\n", input_str));
|
||||
}
|
152
tests/by-util/test_env.rs
Normal file
152
tests/by-util/test_env.rs
Normal file
|
@ -0,0 +1,152 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_env_help() {
|
||||
assert!(new_ucmd!()
|
||||
.arg("--help")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
.contains("OPTIONS:"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_env_version() {
|
||||
assert!(new_ucmd!()
|
||||
.arg("--version")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
.contains(util_name!()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_echo() {
|
||||
// assert!(new_ucmd!().arg("printf").arg("FOO-bar").succeeds().no_stderr().stdout.contains("FOO-bar"));
|
||||
let mut cmd = new_ucmd!();
|
||||
cmd.arg("echo").arg("FOO-bar");
|
||||
println!("cmd={:?}", cmd);
|
||||
|
||||
let result = cmd.run();
|
||||
println!("success={:?}", result.success);
|
||||
println!("stdout={:?}", result.stdout);
|
||||
println!("stderr={:?}", result.stderr);
|
||||
assert!(result.success);
|
||||
|
||||
let out = result.stdout.trim_end();
|
||||
|
||||
assert_eq!(out, "FOO-bar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file_option() {
|
||||
let out = new_ucmd!().arg("-f").arg("vars.conf.txt").run().stdout;
|
||||
|
||||
assert_eq!(
|
||||
out.lines()
|
||||
.filter(|&line| line == "FOO=bar" || line == "BAR=bamf this")
|
||||
.count(),
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_combined_file_set() {
|
||||
let out = new_ucmd!()
|
||||
.arg("-f")
|
||||
.arg("vars.conf.txt")
|
||||
.arg("FOO=bar.alt")
|
||||
.run()
|
||||
.stdout;
|
||||
|
||||
assert_eq!(out.lines().filter(|&line| line == "FOO=bar.alt").count(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_combined_file_set_unset() {
|
||||
let out = new_ucmd!()
|
||||
.arg("-u")
|
||||
.arg("BAR")
|
||||
.arg("-f")
|
||||
.arg("vars.conf.txt")
|
||||
.arg("FOO=bar.alt")
|
||||
.run()
|
||||
.stdout;
|
||||
|
||||
assert_eq!(
|
||||
out.lines()
|
||||
.filter(|&line| line == "FOO=bar.alt" || line.starts_with("BAR="))
|
||||
.count(),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_name_value_pair() {
|
||||
let out = new_ucmd!().arg("FOO=bar").run().stdout;
|
||||
|
||||
assert!(out.lines().any(|line| line == "FOO=bar"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_name_value_pairs() {
|
||||
let out = new_ucmd!().arg("FOO=bar").arg("ABC=xyz").run().stdout;
|
||||
|
||||
assert_eq!(
|
||||
out.lines()
|
||||
.filter(|&line| line == "FOO=bar" || line == "ABC=xyz")
|
||||
.count(),
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ignore_environment() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let out = scene.ucmd().arg("-i").run().stdout;
|
||||
|
||||
assert_eq!(out, "");
|
||||
|
||||
let out = scene.ucmd().arg("-").run().stdout;
|
||||
|
||||
assert_eq!(out, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_null_delimiter() {
|
||||
let out = new_ucmd!()
|
||||
.arg("-i")
|
||||
.arg("--null")
|
||||
.arg("FOO=bar")
|
||||
.arg("ABC=xyz")
|
||||
.run()
|
||||
.stdout;
|
||||
|
||||
let mut vars: Vec<_> = out.split('\0').collect();
|
||||
assert_eq!(vars.len(), 3);
|
||||
vars.sort();
|
||||
assert_eq!(vars[0], "");
|
||||
assert_eq!(vars[1], "ABC=xyz");
|
||||
assert_eq!(vars[2], "FOO=bar");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unset_variable() {
|
||||
// This test depends on the HOME variable being pre-defined by the
|
||||
// default shell
|
||||
let out = TestScenario::new(util_name!())
|
||||
.ucmd_keepenv()
|
||||
.arg("-u")
|
||||
.arg("HOME")
|
||||
.run()
|
||||
.stdout;
|
||||
|
||||
assert_eq!(out.lines().any(|line| line.starts_with("HOME=")), false);
|
||||
}
|
||||
|
||||
#[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"));
|
||||
}
|
48
tests/by-util/test_expand.rs
Normal file
48
tests/by-util/test_expand.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_with_tab() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg("with-tab.txt").run();
|
||||
assert!(result.success);
|
||||
assert!(result.stdout.contains(" "));
|
||||
assert!(!result.stdout.contains("\t"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_trailing_tab() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg("with-trailing-tab.txt").run();
|
||||
assert!(result.success);
|
||||
assert!(result.stdout.contains("with tabs=> "));
|
||||
assert!(!result.stdout.contains("\t"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_trailing_tab_i() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg("with-trailing-tab.txt").arg("-i").run();
|
||||
assert!(result.success);
|
||||
assert!(result.stdout.contains(" // with tabs=>\t"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_tab_size() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg("with-tab.txt").arg("--tabs=10").run();
|
||||
assert!(result.success);
|
||||
assert!(result.stdout.contains(" "));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_space() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg("with-spaces.txt").run();
|
||||
assert!(result.success);
|
||||
assert!(result.stdout.contains(" return"));
|
||||
}
|
56
tests/by-util/test_expr.rs
Normal file
56
tests/by-util/test_expr.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_simple_arithmetic() {
|
||||
new_ucmd!().args(&["1", "+", "1"]).run().stdout_is("2\n");
|
||||
|
||||
new_ucmd!().args(&["1", "-", "1"]).run().stdout_is("0\n");
|
||||
|
||||
new_ucmd!().args(&["3", "*", "2"]).run().stdout_is("6\n");
|
||||
|
||||
new_ucmd!().args(&["4", "/", "2"]).run().stdout_is("2\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_complex_arithmetic() {
|
||||
let run = new_ucmd!()
|
||||
.args(&["9223372036854775807", "+", "9223372036854775807"])
|
||||
.run();
|
||||
run.stdout_is("");
|
||||
run.stderr_is("expr: error: +: Numerical result out of range");
|
||||
|
||||
let run = new_ucmd!().args(&["9", "/", "0"]).run();
|
||||
run.stdout_is("");
|
||||
run.stderr_is("expr: error: division by zero");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parenthesis() {
|
||||
new_ucmd!()
|
||||
.args(&["(", "1", "+", "1", ")", "*", "2"])
|
||||
.run()
|
||||
.stdout_is("4\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or() {
|
||||
new_ucmd!()
|
||||
.args(&["0", "|", "foo"])
|
||||
.run()
|
||||
.stdout_is("foo\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["foo", "|", "bar"])
|
||||
.run()
|
||||
.stdout_is("foo\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and() {
|
||||
new_ucmd!()
|
||||
.args(&["foo", "&", "1"])
|
||||
.run()
|
||||
.stdout_is("foo\n");
|
||||
|
||||
new_ucmd!().args(&["", "&", "1"]).run().stdout_is("0\n");
|
||||
}
|
1060
tests/by-util/test_factor.rs
Normal file
1060
tests/by-util/test_factor.rs
Normal file
File diff suppressed because it is too large
Load diff
6
tests/by-util/test_false.rs
Normal file
6
tests/by-util/test_false.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_exit_code() {
|
||||
new_ucmd!().fails();
|
||||
}
|
37
tests/by-util/test_fmt.rs
Normal file
37
tests/by-util/test_fmt.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_fmt() {
|
||||
let result = new_ucmd!().arg("one-word-per-line.txt").run();
|
||||
//.stdout_is_fixture("call_graph.expected");
|
||||
assert_eq!(
|
||||
result.stdout.trim(),
|
||||
"this is a file with one word per line"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt_q() {
|
||||
let result = new_ucmd!().arg("-q").arg("one-word-per-line.txt").run();
|
||||
//.stdout_is_fixture("call_graph.expected");
|
||||
assert_eq!(
|
||||
result.stdout.trim(),
|
||||
"this is a file with one word per line"
|
||||
);
|
||||
}
|
||||
|
||||
/* #[test]
|
||||
Fails for now, see https://github.com/uutils/coreutils/issues/1501
|
||||
fn test_fmt_w() {
|
||||
let result = new_ucmd!()
|
||||
.arg("-w")
|
||||
.arg("10")
|
||||
.arg("one-word-per-line.txt")
|
||||
.run();
|
||||
//.stdout_is_fixture("call_graph.expected");
|
||||
assert_eq!(result.stdout.trim(), "this is a file with one word per line");
|
||||
}
|
||||
|
||||
|
||||
fmt is pretty broken in general, needs more works to have more tests
|
||||
*/
|
25
tests/by-util/test_fold.rs
Normal file
25
tests/by-util/test_fold.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_default_80_column_wrap() {
|
||||
new_ucmd!()
|
||||
.arg("lorem_ipsum.txt")
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_80_column.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_40_column_hard_cutoff() {
|
||||
new_ucmd!()
|
||||
.args(&["-w", "40", "lorem_ipsum.txt"])
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_40_column_hard.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_40_column_word_boundary() {
|
||||
new_ucmd!()
|
||||
.args(&["-s", "-w", "40", "lorem_ipsum.txt"])
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_40_column_word.expected");
|
||||
}
|
46
tests/by-util/test_hashsum.rs
Normal file
46
tests/by-util/test_hashsum.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
macro_rules! get_hash(
|
||||
($str:expr) => (
|
||||
$str.split(' ').collect::<Vec<&str>>()[0]
|
||||
);
|
||||
);
|
||||
|
||||
macro_rules! test_digest {
|
||||
($($id:ident $t:ident $size:expr)*) => ($(
|
||||
|
||||
mod $id {
|
||||
use crate::common::util::*;
|
||||
static DIGEST_ARG: &'static str = concat!("--", stringify!($t));
|
||||
static BITS_ARG: &'static str = concat!("--bits=", stringify!($size));
|
||||
static EXPECTED_FILE: &'static str = concat!(stringify!($id), ".expected");
|
||||
|
||||
#[test]
|
||||
fn test_single_file() {
|
||||
let ts = TestScenario::new("hashsum");
|
||||
assert_eq!(ts.fixtures.read(EXPECTED_FILE),
|
||||
get_hash!(ts.ucmd().arg(DIGEST_ARG).arg(BITS_ARG).arg("input.txt").succeeds().no_stderr().stdout));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin() {
|
||||
let ts = TestScenario::new("hashsum");
|
||||
assert_eq!(ts.fixtures.read(EXPECTED_FILE),
|
||||
get_hash!(ts.ucmd().arg(DIGEST_ARG).arg(BITS_ARG).pipe_in_fixture("input.txt").succeeds().no_stderr().stdout));
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
test_digest! {
|
||||
md5 md5 128
|
||||
sha1 sha1 160
|
||||
sha224 sha224 224
|
||||
sha256 sha256 256
|
||||
sha384 sha384 384
|
||||
sha512 sha512 512
|
||||
sha3_224 sha3 224
|
||||
sha3_256 sha3 256
|
||||
sha3_384 sha3 384
|
||||
sha3_512 sha3 512
|
||||
shake128_256 shake128 256
|
||||
shake256_512 shake256 512
|
||||
}
|
87
tests/by-util/test_head.rs
Normal file
87
tests/by-util/test_head.rs
Normal file
|
@ -0,0 +1,87 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
static INPUT: &'static str = "lorem_ipsum.txt";
|
||||
|
||||
#[test]
|
||||
fn test_stdin_default() {
|
||||
new_ucmd!()
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_default.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_1_line_obsolete() {
|
||||
new_ucmd!()
|
||||
.args(&["-1"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_1_line.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_1_line() {
|
||||
new_ucmd!()
|
||||
.args(&["-n", "1"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_1_line.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_negative_23_line() {
|
||||
new_ucmd!()
|
||||
.args(&["-n", "-23"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_1_line.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_5_chars() {
|
||||
new_ucmd!()
|
||||
.args(&["-c", "5"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_5_chars.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_default() {
|
||||
new_ucmd!()
|
||||
.arg(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_default.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_1_line_obsolete() {
|
||||
new_ucmd!()
|
||||
.args(&["-1", INPUT])
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_1_line.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_1_line() {
|
||||
new_ucmd!()
|
||||
.args(&["-n", "1", INPUT])
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_1_line.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_5_chars() {
|
||||
new_ucmd!()
|
||||
.args(&["-c", "5", INPUT])
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_5_chars.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_verbose() {
|
||||
new_ucmd!()
|
||||
.args(&["-v", INPUT])
|
||||
.run()
|
||||
.stdout_is_fixture("lorem_ipsum_verbose.expected");
|
||||
}
|
26
tests/by-util/test_hostname.rs
Normal file
26
tests/by-util/test_hostname.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_hostname() {
|
||||
let ls_default_res = new_ucmd!().succeeds();
|
||||
let ls_short_res = new_ucmd!().arg("-s").succeeds();
|
||||
let ls_domain_res = new_ucmd!().arg("-d").succeeds();
|
||||
|
||||
assert!(ls_default_res.stdout.len() >= ls_short_res.stdout.len());
|
||||
assert!(ls_default_res.stdout.len() >= ls_domain_res.stdout.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hostname_ip() {
|
||||
let result = new_ucmd!().arg("-i").succeeds();
|
||||
assert!(!result.stdout.trim().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hostname_full() {
|
||||
let result = new_ucmd!().arg("-f").succeeds();
|
||||
assert!(!result.stdout.trim().is_empty());
|
||||
|
||||
let ls_short_res = new_ucmd!().arg("-s").succeeds();
|
||||
assert!(result.stdout.trim().contains(ls_short_res.stdout.trim()));
|
||||
}
|
141
tests/by-util/test_id.rs
Normal file
141
tests/by-util/test_id.rs
Normal file
|
@ -0,0 +1,141 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_id() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let mut result = scene.ucmd().arg("-u").run();
|
||||
if result.stderr.contains("cannot find name for user ID") {
|
||||
// In the CI, some server are failing to return whoami.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
return;
|
||||
}
|
||||
assert!(result.success);
|
||||
|
||||
let uid = String::from(result.stdout.trim());
|
||||
result = scene.ucmd().run();
|
||||
if result.stderr.contains("cannot find name for user ID") {
|
||||
// In the CI, some server are failing to return whoami.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
return;
|
||||
}
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
if !result.stderr.contains("Could not find uid") {
|
||||
// Verify that the id found by --user/-u exists in the list
|
||||
assert!(result.stdout.contains(&uid));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_id_from_name() {
|
||||
let mut scene = TestScenario::new("whoami");
|
||||
let result = scene.cmd("whoami").run();
|
||||
if result.stderr.contains("cannot find name for user ID") {
|
||||
// In the CI, some server are failing to return whoami.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
return;
|
||||
}
|
||||
|
||||
let username = result.stdout.trim();
|
||||
|
||||
scene = TestScenario::new(util_name!());
|
||||
let result = scene.ucmd().arg(username).succeeds();
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
assert!(result.success);
|
||||
let uid = String::from(result.stdout.trim());
|
||||
let result = scene.ucmd().succeeds();
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
// Verify that the id found by --user/-u exists in the list
|
||||
assert!(result.stdout.contains(&uid));
|
||||
// Verify that the username found by whoami exists in the list
|
||||
assert!(result.stdout.contains(&username));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_id_name_from_id() {
|
||||
let mut scene = TestScenario::new(util_name!());
|
||||
let result = scene.ucmd().arg("-u").run();
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
assert!(result.success);
|
||||
let uid = String::from(result.stdout.trim());
|
||||
|
||||
scene = TestScenario::new(util_name!());
|
||||
let result = scene.ucmd().arg("-nu").arg(uid).run();
|
||||
if result.stderr.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;
|
||||
}
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
assert!(result.success);
|
||||
|
||||
let username_id = String::from(result.stdout.trim());
|
||||
|
||||
scene = TestScenario::new("whoami");
|
||||
let result = scene.cmd("whoami").run();
|
||||
|
||||
let username_whoami = result.stdout.trim();
|
||||
|
||||
assert_eq!(username_id, username_whoami);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_id_group() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let mut result = scene.ucmd().arg("-g").succeeds();
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
assert!(result.success);
|
||||
let s1 = String::from(result.stdout.trim());
|
||||
assert!(s1.parse::<f64>().is_ok());
|
||||
|
||||
result = scene.ucmd().arg("--group").succeeds();
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
assert!(result.success);
|
||||
let s1 = String::from(result.stdout.trim());
|
||||
assert!(s1.parse::<f64>().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_id_groups() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let result = scene.ucmd().arg("-G").succeeds();
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
assert!(result.success);
|
||||
let groups = result.stdout.trim().split_whitespace();
|
||||
for s in groups {
|
||||
assert!(s.parse::<f64>().is_ok());
|
||||
}
|
||||
|
||||
let result = scene.ucmd().arg("--groups").succeeds();
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
assert!(result.success);
|
||||
let groups = result.stdout.trim().split_whitespace();
|
||||
for s in groups {
|
||||
assert!(s.parse::<f64>().is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_id_user() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let mut result = scene.ucmd().arg("-u").succeeds();
|
||||
assert!(result.success);
|
||||
let s1 = String::from(result.stdout.trim());
|
||||
assert!(s1.parse::<f64>().is_ok());
|
||||
result = scene.ucmd().arg("--user").succeeds();
|
||||
assert!(result.success);
|
||||
let s1 = String::from(result.stdout.trim());
|
||||
assert!(s1.parse::<f64>().is_ok());
|
||||
}
|
228
tests/by-util/test_install.rs
Normal file
228
tests/by-util/test_install.rs
Normal file
|
@ -0,0 +1,228 @@
|
|||
use crate::common::util::*;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
#[test]
|
||||
fn test_install_help() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
assert!(ucmd
|
||||
.arg("--help")
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.stdout
|
||||
.contains("Options:"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_basic() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_install_target_dir_dir_a";
|
||||
let file1 = "test_install_target_dir_file_a1";
|
||||
let file2 = "test_install_target_dir_file_a2";
|
||||
|
||||
at.touch(file1);
|
||||
at.touch(file2);
|
||||
at.mkdir(dir);
|
||||
ucmd.arg(file1).arg(file2).arg(dir).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(file1));
|
||||
assert!(at.file_exists(file2));
|
||||
assert!(at.file_exists(&format!("{}/{}", dir, file1)));
|
||||
assert!(at.file_exists(&format!("{}/{}", dir, file2)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_failing_not_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file1 = "test_install_target_dir_file_a1";
|
||||
let file2 = "test_install_target_dir_file_a2";
|
||||
let file3 = "test_install_target_dir_file_a3";
|
||||
|
||||
at.touch(file1);
|
||||
at.touch(file2);
|
||||
at.touch(file3);
|
||||
assert!(ucmd
|
||||
.arg(file1)
|
||||
.arg(file2)
|
||||
.arg(file3)
|
||||
.fails()
|
||||
.stderr
|
||||
.contains("not a directory"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_unimplemented_arg() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_install_target_dir_dir_b";
|
||||
let file = "test_install_target_dir_file_b";
|
||||
let context_arg = "--context";
|
||||
|
||||
at.touch(file);
|
||||
at.mkdir(dir);
|
||||
assert!(ucmd
|
||||
.arg(context_arg)
|
||||
.arg(file)
|
||||
.arg(dir)
|
||||
.fails()
|
||||
.stderr
|
||||
.contains("Unimplemented"));
|
||||
|
||||
assert!(!at.file_exists(&format!("{}/{}", dir, file)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_component_directories() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let component1 = "test_install_target_dir_component_c1";
|
||||
let component2 = "test_install_target_dir_component_c2";
|
||||
let component3 = "test_install_target_dir_component_c3";
|
||||
let directories_arg = "-d";
|
||||
|
||||
ucmd.args(&[directories_arg, component1, component2, component3])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.dir_exists(component1));
|
||||
assert!(at.dir_exists(component2));
|
||||
assert!(at.dir_exists(component3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_component_directories_failing() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let component = "test_install_target_dir_component_d1";
|
||||
let directories_arg = "-d";
|
||||
|
||||
at.mkdir(component);
|
||||
assert!(ucmd
|
||||
.arg(directories_arg)
|
||||
.arg(component)
|
||||
.fails()
|
||||
.stderr
|
||||
.contains("File exists"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_mode_numeric() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_install_target_dir_dir_e";
|
||||
let file = "test_install_target_dir_file_e";
|
||||
let mode_arg = "--mode=333";
|
||||
|
||||
at.touch(file);
|
||||
at.mkdir(dir);
|
||||
ucmd.arg(file).arg(dir).arg(mode_arg).succeeds().no_stderr();
|
||||
|
||||
let dest_file = &format!("{}/{}", dir, file);
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.file_exists(dest_file));
|
||||
let permissions = at.metadata(dest_file).permissions();
|
||||
assert_eq!(0o100333 as u32, PermissionsExt::mode(&permissions));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_mode_symbolic() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_install_target_dir_dir_f";
|
||||
let file = "test_install_target_dir_file_f";
|
||||
let mode_arg = "--mode=o+wx";
|
||||
|
||||
at.touch(file);
|
||||
at.mkdir(dir);
|
||||
ucmd.arg(file).arg(dir).arg(mode_arg).succeeds().no_stderr();
|
||||
|
||||
let dest_file = &format!("{}/{}", dir, file);
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.file_exists(dest_file));
|
||||
let permissions = at.metadata(dest_file).permissions();
|
||||
assert_eq!(0o100003 as u32, PermissionsExt::mode(&permissions));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_mode_failing() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_install_target_dir_dir_g";
|
||||
let file = "test_install_target_dir_file_g";
|
||||
let mode_arg = "--mode=999";
|
||||
|
||||
at.touch(file);
|
||||
at.mkdir(dir);
|
||||
assert!(ucmd
|
||||
.arg(file)
|
||||
.arg(dir)
|
||||
.arg(mode_arg)
|
||||
.fails()
|
||||
.stderr
|
||||
.contains("Invalid mode string: invalid digit found in string"));
|
||||
|
||||
let dest_file = &format!("{}/{}", dir, file);
|
||||
assert!(at.file_exists(file));
|
||||
assert!(!at.file_exists(dest_file));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_mode_directories() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let component = "test_install_target_dir_component_h";
|
||||
let directories_arg = "-d";
|
||||
let mode_arg = "--mode=333";
|
||||
|
||||
ucmd.arg(directories_arg)
|
||||
.arg(component)
|
||||
.arg(mode_arg)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.dir_exists(component));
|
||||
let permissions = at.metadata(component).permissions();
|
||||
assert_eq!(0o040333 as u32, PermissionsExt::mode(&permissions));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_target_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file1 = "test_install_target_file_file_i1";
|
||||
let file2 = "test_install_target_file_file_i2";
|
||||
|
||||
at.touch(file1);
|
||||
at.touch(file2);
|
||||
ucmd.arg(file1).arg(file2).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(file1));
|
||||
assert!(at.file_exists(file2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_target_new_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_install_target_new_filer_file_j";
|
||||
let dir = "test_install_target_new_file_dir_j";
|
||||
|
||||
at.touch(file);
|
||||
at.mkdir(dir);
|
||||
ucmd.arg(file)
|
||||
.arg(format!("{}/{}", dir, file))
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.file_exists(&format!("{}/{}", dir, file)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_install_target_new_file_failing_nonexistent_parent() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file1 = "test_install_target_new_file_failing_file_k1";
|
||||
let file2 = "test_install_target_new_file_failing_file_k2";
|
||||
let dir = "test_install_target_new_file_failing_dir_k";
|
||||
|
||||
at.touch(file1);
|
||||
|
||||
let err = ucmd
|
||||
.arg(file1)
|
||||
.arg(format!("{}/{}", dir, file2))
|
||||
.fails()
|
||||
.stderr;
|
||||
|
||||
assert!(err.contains("not a directory"))
|
||||
}
|
291
tests/by-util/test_join.rs
Normal file
291
tests/by-util/test_join.rs
Normal file
|
@ -0,0 +1,291 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn empty_files() {
|
||||
new_ucmd!()
|
||||
.arg("empty.txt")
|
||||
.arg("empty.txt")
|
||||
.succeeds()
|
||||
.stdout_only("");
|
||||
|
||||
new_ucmd!()
|
||||
.arg("empty.txt")
|
||||
.arg("fields_1.txt")
|
||||
.succeeds()
|
||||
.stdout_only("");
|
||||
|
||||
new_ucmd!()
|
||||
.arg("fields_1.txt")
|
||||
.arg("empty.txt")
|
||||
.succeeds()
|
||||
.stdout_only("");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_intersection() {
|
||||
new_ucmd!()
|
||||
.arg("fields_1.txt")
|
||||
.arg("fields_2.txt")
|
||||
.arg("-2")
|
||||
.arg("2")
|
||||
.succeeds()
|
||||
.stdout_only("");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_arguments() {
|
||||
new_ucmd!()
|
||||
.arg("fields_1.txt")
|
||||
.arg("fields_2.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("default.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn different_fields() {
|
||||
new_ucmd!()
|
||||
.arg("fields_2.txt")
|
||||
.arg("fields_4.txt")
|
||||
.arg("-j")
|
||||
.arg("2")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("different_fields.expected");
|
||||
|
||||
new_ucmd!()
|
||||
.arg("fields_2.txt")
|
||||
.arg("fields_4.txt")
|
||||
.arg("-1")
|
||||
.arg("2")
|
||||
.arg("-2")
|
||||
.arg("2")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("different_fields.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn different_field() {
|
||||
new_ucmd!()
|
||||
.arg("fields_2.txt")
|
||||
.arg("fields_3.txt")
|
||||
.arg("-2")
|
||||
.arg("2")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("different_field.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unpaired_lines() {
|
||||
new_ucmd!()
|
||||
.arg("fields_2.txt")
|
||||
.arg("fields_3.txt")
|
||||
.arg("-a")
|
||||
.arg("1")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("fields_2.txt");
|
||||
|
||||
new_ucmd!()
|
||||
.arg("fields_3.txt")
|
||||
.arg("fields_2.txt")
|
||||
.arg("-1")
|
||||
.arg("2")
|
||||
.arg("-a")
|
||||
.arg("2")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("unpaired_lines.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suppress_joined() {
|
||||
new_ucmd!()
|
||||
.arg("fields_3.txt")
|
||||
.arg("fields_2.txt")
|
||||
.arg("-1")
|
||||
.arg("2")
|
||||
.arg("-v")
|
||||
.arg("2")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("suppress_joined.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case_insensitive() {
|
||||
new_ucmd!()
|
||||
.arg("capitalized.txt")
|
||||
.arg("fields_3.txt")
|
||||
.arg("-i")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("case_insensitive.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn semicolon_separated() {
|
||||
new_ucmd!()
|
||||
.arg("semicolon_fields_1.txt")
|
||||
.arg("semicolon_fields_2.txt")
|
||||
.arg("-t")
|
||||
.arg(";")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("semicolon_separated.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_line_separated() {
|
||||
new_ucmd!()
|
||||
.arg("-")
|
||||
.arg("fields_2.txt")
|
||||
.arg("-t")
|
||||
.arg("")
|
||||
.pipe_in("1 a\n1 b\n8 h\n")
|
||||
.succeeds()
|
||||
.stdout_only("1 a\n8 h\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multitab_character() {
|
||||
new_ucmd!()
|
||||
.arg("semicolon_fields_1.txt")
|
||||
.arg("semicolon_fields_2.txt")
|
||||
.arg("-t")
|
||||
.arg("э")
|
||||
.fails()
|
||||
.stderr_is("join: error: multi-character tab э");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default_format() {
|
||||
new_ucmd!()
|
||||
.arg("fields_1.txt")
|
||||
.arg("fields_2.txt")
|
||||
.arg("-o")
|
||||
.arg("1.1 2.2")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("default.expected");
|
||||
|
||||
new_ucmd!()
|
||||
.arg("fields_1.txt")
|
||||
.arg("fields_2.txt")
|
||||
.arg("-o")
|
||||
.arg("0 2.2")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("default.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unpaired_lines_format() {
|
||||
new_ucmd!()
|
||||
.arg("fields_2.txt")
|
||||
.arg("fields_3.txt")
|
||||
.arg("-a")
|
||||
.arg("2")
|
||||
.arg("-o")
|
||||
.arg("1.2 1.1 2.4 2.3 2.2 0")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("unpaired_lines_format.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn autoformat() {
|
||||
new_ucmd!()
|
||||
.arg("fields_2.txt")
|
||||
.arg("different_lengths.txt")
|
||||
.arg("-o")
|
||||
.arg("auto")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("autoformat.expected");
|
||||
|
||||
new_ucmd!()
|
||||
.arg("-")
|
||||
.arg("fields_2.txt")
|
||||
.arg("-o")
|
||||
.arg("auto")
|
||||
.pipe_in("1 x y z\n2 p")
|
||||
.succeeds()
|
||||
.stdout_only("1 x y z a\n2 p b\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_format() {
|
||||
new_ucmd!()
|
||||
.arg("fields_1.txt")
|
||||
.arg("fields_2.txt")
|
||||
.arg("-o")
|
||||
.arg("")
|
||||
.fails()
|
||||
.stderr_is("join: error: invalid file number in field spec: ''");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_key() {
|
||||
new_ucmd!()
|
||||
.arg("fields_1.txt")
|
||||
.arg("empty.txt")
|
||||
.arg("-j")
|
||||
.arg("2")
|
||||
.arg("-a")
|
||||
.arg("1")
|
||||
.arg("-e")
|
||||
.arg("x")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("empty_key.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_format_fields() {
|
||||
new_ucmd!()
|
||||
.arg("fields_2.txt")
|
||||
.arg("different_lengths.txt")
|
||||
.arg("-o")
|
||||
.arg("0 1.2 2.4")
|
||||
.arg("-e")
|
||||
.arg("x")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("missing_format_fields.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wrong_line_order() {
|
||||
new_ucmd!()
|
||||
.arg("fields_2.txt")
|
||||
.arg("fields_4.txt")
|
||||
.fails()
|
||||
.stderr_is("fields_4.txt:5: is not sorted");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn headers() {
|
||||
new_ucmd!()
|
||||
.arg("header_1.txt")
|
||||
.arg("header_2.txt")
|
||||
.arg("--header")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("header.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn headers_autoformat() {
|
||||
new_ucmd!()
|
||||
.arg("header_1.txt")
|
||||
.arg("header_2.txt")
|
||||
.arg("--header")
|
||||
.arg("-o")
|
||||
.arg("auto")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("header_autoformat.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_file_with_header() {
|
||||
new_ucmd!()
|
||||
.arg("capitalized.txt")
|
||||
.arg("empty.txt")
|
||||
.arg("--header")
|
||||
.succeeds()
|
||||
.stdout_is("A 1\n");
|
||||
|
||||
new_ucmd!()
|
||||
.arg("empty.txt")
|
||||
.arg("capitalized.txt")
|
||||
.arg("--header")
|
||||
.succeeds()
|
||||
.stdout_is("A 1\n");
|
||||
}
|
41
tests/by-util/test_link.rs
Normal file
41
tests/by-util/test_link.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_link_existing_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_link_existing_file";
|
||||
let link = "test_link_existing_file_link";
|
||||
|
||||
at.touch(file);
|
||||
at.write(file, "foobar");
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
ucmd.args(&[file, link]).succeeds().no_stderr();
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.file_exists(link));
|
||||
assert_eq!(at.read(file), at.read(link));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_link_no_circular() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let link = "test_link_no_circular";
|
||||
|
||||
ucmd.args(&[link, link])
|
||||
.fails()
|
||||
.stderr_is("link: error: No such file or directory (os error 2)\n");
|
||||
assert!(!at.file_exists(link));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_link_nonexistent_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_link_nonexistent_file";
|
||||
let link = "test_link_nonexistent_file_link";
|
||||
|
||||
ucmd.args(&[file, link])
|
||||
.fails()
|
||||
.stderr_is("link: error: No such file or directory (os error 2)\n");
|
||||
assert!(!at.file_exists(file));
|
||||
assert!(!at.file_exists(link));
|
||||
}
|
418
tests/by-util/test_ln.rs
Normal file
418
tests/by-util/test_ln.rs
Normal file
|
@ -0,0 +1,418 @@
|
|||
use crate::common::util::*;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[test]
|
||||
fn test_symlink_existing_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_symlink_existing_file";
|
||||
let link = "test_symlink_existing_file_link";
|
||||
|
||||
at.touch(file);
|
||||
|
||||
ucmd.args(&["-s", file, link]).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_dangling_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_symlink_dangling_file";
|
||||
let link = "test_symlink_dangling_file_link";
|
||||
|
||||
ucmd.args(&["-s", file, link]).succeeds().no_stderr();
|
||||
assert!(!at.file_exists(file));
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_existing_directory() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_symlink_existing_dir";
|
||||
let link = "test_symlink_existing_dir_link";
|
||||
|
||||
at.mkdir(dir);
|
||||
|
||||
ucmd.args(&["-s", dir, link]).succeeds().no_stderr();
|
||||
assert!(at.dir_exists(dir));
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_dangling_directory() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_symlink_dangling_dir";
|
||||
let link = "test_symlink_dangling_dir_link";
|
||||
|
||||
ucmd.args(&["-s", dir, link]).succeeds().no_stderr();
|
||||
assert!(!at.dir_exists(dir));
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_circular() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let link = "test_symlink_circular";
|
||||
|
||||
ucmd.args(&["-s", link]).succeeds().no_stderr();
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), link);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_dont_overwrite() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_symlink_dont_overwrite";
|
||||
let link = "test_symlink_dont_overwrite_link";
|
||||
|
||||
at.touch(file);
|
||||
at.touch(link);
|
||||
|
||||
ucmd.args(&["-s", file, link]).fails();
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.file_exists(link));
|
||||
assert!(!at.is_symlink(link));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_overwrite_force() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_symlink_overwrite_force_a";
|
||||
let file_b = "test_symlink_overwrite_force_b";
|
||||
let link = "test_symlink_overwrite_force_link";
|
||||
|
||||
// Create symlink
|
||||
at.symlink_file(file_a, link);
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file_a);
|
||||
|
||||
// Force overwrite of existing symlink
|
||||
ucmd.args(&["--force", "-s", file_b, link]).succeeds();
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file_b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_interactive() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let file = "test_symlink_interactive_file";
|
||||
let link = "test_symlink_interactive_file_link";
|
||||
|
||||
at.touch(file);
|
||||
at.touch(link);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&["-i", "-s", file, link])
|
||||
.pipe_in("n")
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
assert!(!at.is_symlink(link));
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&["-i", "-s", file, link])
|
||||
.pipe_in("Yesh")
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_simple_backup() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_symlink_simple_backup";
|
||||
let link = "test_symlink_simple_backup_link";
|
||||
|
||||
at.touch(file);
|
||||
at.symlink_file(file, link);
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file);
|
||||
|
||||
ucmd.args(&["-b", "-s", file, link]).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file);
|
||||
|
||||
let backup = &format!("{}~", link);
|
||||
assert!(at.is_symlink(backup));
|
||||
assert_eq!(at.resolve_link(backup), file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_custom_backup_suffix() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_symlink_custom_backup_suffix";
|
||||
let link = "test_symlink_custom_backup_suffix_link";
|
||||
let suffix = "super-suffix-of-the-century";
|
||||
|
||||
at.touch(file);
|
||||
at.symlink_file(file, link);
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file);
|
||||
|
||||
let arg = &format!("--suffix={}", suffix);
|
||||
ucmd.args(&["-b", arg, "-s", file, link])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file);
|
||||
|
||||
let backup = &format!("{}{}", link, suffix);
|
||||
assert!(at.is_symlink(backup));
|
||||
assert_eq!(at.resolve_link(backup), file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_backup_numbering() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_symlink_backup_numbering";
|
||||
let link = "test_symlink_backup_numbering_link";
|
||||
|
||||
at.touch(file);
|
||||
at.symlink_file(file, link);
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file);
|
||||
|
||||
ucmd.args(&["-s", "--backup=t", file, link])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file);
|
||||
|
||||
let backup = &format!("{}.~1~", link);
|
||||
assert!(at.is_symlink(backup));
|
||||
assert_eq!(at.resolve_link(backup), file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_existing_backup() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_symlink_existing_backup";
|
||||
let link = "test_symlink_existing_backup_link";
|
||||
let link_backup = "test_symlink_existing_backup_link.~1~";
|
||||
let resulting_backup = "test_symlink_existing_backup_link.~2~";
|
||||
|
||||
// Create symlink and verify
|
||||
at.touch(file);
|
||||
at.symlink_file(file, link);
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file);
|
||||
|
||||
// Create backup symlink and verify
|
||||
at.symlink_file(file, link_backup);
|
||||
assert!(at.file_exists(file));
|
||||
assert!(at.is_symlink(link_backup));
|
||||
assert_eq!(at.resolve_link(link_backup), file);
|
||||
|
||||
ucmd.args(&["-s", "--backup=nil", file, link])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
assert!(at.is_symlink(link_backup));
|
||||
assert_eq!(at.resolve_link(link_backup), file);
|
||||
|
||||
assert!(at.is_symlink(resulting_backup));
|
||||
assert_eq!(at.resolve_link(resulting_backup), file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_target_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_ln_target_dir_dir";
|
||||
let file_a = "test_ln_target_dir_file_a";
|
||||
let file_b = "test_ln_target_dir_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
at.mkdir(dir);
|
||||
|
||||
ucmd.args(&["-s", "-t", dir, file_a, file_b])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
let file_a_link = &format!("{}/{}", dir, file_a);
|
||||
assert!(at.is_symlink(file_a_link));
|
||||
assert_eq!(at.resolve_link(file_a_link), file_a);
|
||||
|
||||
let file_b_link = &format!("{}/{}", dir, file_b);
|
||||
assert!(at.is_symlink(file_b_link));
|
||||
assert_eq!(at.resolve_link(file_b_link), file_b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_target_dir_from_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_ln_target_dir_dir";
|
||||
let from_dir = "test_ln_target_dir_from_dir";
|
||||
let filename_a = "test_ln_target_dir_file_a";
|
||||
let filename_b = "test_ln_target_dir_file_b";
|
||||
let file_a = &format!("{}/{}", from_dir, filename_a);
|
||||
let file_b = &format!("{}/{}", from_dir, filename_b);
|
||||
|
||||
at.mkdir(from_dir);
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
at.mkdir(dir);
|
||||
|
||||
ucmd.args(&["-s", "-t", dir, file_a, file_b])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
let file_a_link = &format!("{}/{}", dir, filename_a);
|
||||
assert!(at.is_symlink(file_a_link));
|
||||
assert_eq!(&at.resolve_link(file_a_link), file_a);
|
||||
|
||||
let file_b_link = &format!("{}/{}", dir, filename_b);
|
||||
assert!(at.is_symlink(file_b_link));
|
||||
assert_eq!(&at.resolve_link(file_b_link), file_b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_overwrite_dir_fail() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let path_a = "test_symlink_overwrite_dir_a";
|
||||
let path_b = "test_symlink_overwrite_dir_b";
|
||||
|
||||
at.touch(path_a);
|
||||
at.mkdir(path_b);
|
||||
|
||||
assert!(
|
||||
ucmd.args(&["-s", "-T", path_a, path_b])
|
||||
.fails()
|
||||
.stderr
|
||||
.len()
|
||||
> 0
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_errors() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_symlink_errors_dir";
|
||||
let file_a = "test_symlink_errors_file_a";
|
||||
let file_b = "test_symlink_errors_file_b";
|
||||
|
||||
at.mkdir(dir);
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
// $ ln -T -t a b
|
||||
// ln: cannot combine --target-directory (-t) and --no-target-directory (-T)
|
||||
ucmd.args(&["-T", "-t", dir, file_a, file_b])
|
||||
.fails()
|
||||
.stderr_is(
|
||||
"ln: error: cannot combine --target-directory (-t) and --no-target-directory \
|
||||
(-T)\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_verbose() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let file_a = "test_symlink_verbose_file_a";
|
||||
let file_b = "test_symlink_verbose_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&["-v", file_a, file_b])
|
||||
.succeeds()
|
||||
.stdout_only(format!("'{}' -> '{}'\n", file_b, file_a));
|
||||
|
||||
at.touch(file_b);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&["-v", "-b", file_a, file_b])
|
||||
.succeeds()
|
||||
.stdout_only(format!(
|
||||
"'{}' -> '{}' (backup: '{}~')\n",
|
||||
file_b, file_a, file_b
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_target_only() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_symlink_target_only";
|
||||
|
||||
at.mkdir(dir);
|
||||
|
||||
assert!(ucmd.args(&["-s", "-t", dir]).fails().stderr.len() > 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_implicit_target_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_symlink_implicit_target_dir";
|
||||
// On windows, slashes aren't allowed in symlink targets, so use
|
||||
// PathBuf to construct `file` instead of simple "dir/file".
|
||||
let filename = "test_symlink_implicit_target_file";
|
||||
let path = PathBuf::from(dir).join(filename);
|
||||
let file = &path.to_string_lossy();
|
||||
|
||||
at.mkdir(dir);
|
||||
at.touch(file);
|
||||
|
||||
ucmd.args(&["-s", file]).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(filename));
|
||||
assert!(at.is_symlink(filename));
|
||||
assert_eq!(at.resolve_link(filename), *file);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_to_dir_2args() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let filename = "test_symlink_to_dir_2args_file";
|
||||
let from_file = &format!("{}/{}", at.as_string(), filename);
|
||||
let to_dir = "test_symlink_to_dir_2args_to_dir";
|
||||
let to_file = &format!("{}/{}", to_dir, filename);
|
||||
|
||||
at.mkdir(to_dir);
|
||||
at.touch(from_file);
|
||||
|
||||
ucmd.args(&["-s", from_file, to_dir]).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(to_file));
|
||||
assert!(at.is_symlink(to_file));
|
||||
assert_eq!(at.resolve_link(to_file), filename);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_missing_destination() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_symlink_missing_destination";
|
||||
|
||||
at.touch(file);
|
||||
|
||||
ucmd.args(&["-s", "-T", file]).fails().stderr_is(format!(
|
||||
"ln: error: missing destination file operand after '{}'",
|
||||
file
|
||||
));
|
||||
}
|
19
tests/by-util/test_ls.rs
Normal file
19
tests/by-util/test_ls.rs
Normal file
|
@ -0,0 +1,19 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_ls_ls() {
|
||||
new_ucmd!().succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ls_ls_i() {
|
||||
new_ucmd!().arg("-i").succeeds();
|
||||
new_ucmd!().arg("-il").succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ls_ls_color() {
|
||||
new_ucmd!().arg("--color").succeeds();
|
||||
new_ucmd!().arg("--color=always").succeeds();
|
||||
new_ucmd!().arg("--color=never").succeeds();
|
||||
}
|
55
tests/by-util/test_mkdir.rs
Normal file
55
tests/by-util/test_mkdir.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
static TEST_DIR1: &'static str = "mkdir_test1";
|
||||
static TEST_DIR2: &'static str = "mkdir_test2";
|
||||
static TEST_DIR3: &'static str = "mkdir_test3";
|
||||
static TEST_DIR4: &'static str = "mkdir_test4/mkdir_test4_1";
|
||||
static TEST_DIR5: &'static str = "mkdir_test5/mkdir_test5_1";
|
||||
static TEST_DIR6: &'static str = "mkdir_test6";
|
||||
static TEST_FILE7: &'static str = "mkdir_test7";
|
||||
|
||||
#[test]
|
||||
fn test_mkdir_mkdir() {
|
||||
new_ucmd!().arg(TEST_DIR1).succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mkdir_dup_dir() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
scene.ucmd().arg(TEST_DIR2).succeeds();
|
||||
scene.ucmd().arg(TEST_DIR2).fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mkdir_mode() {
|
||||
new_ucmd!().arg("-m").arg("755").arg(TEST_DIR3).succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mkdir_parent() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
scene.ucmd().arg("-p").arg(TEST_DIR4).succeeds();
|
||||
scene.ucmd().arg("-p").arg(TEST_DIR4).succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mkdir_no_parent() {
|
||||
new_ucmd!().arg(TEST_DIR5).fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mkdir_dup_dir_parent() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
scene.ucmd().arg(TEST_DIR6).succeeds();
|
||||
scene.ucmd().arg("-p").arg(TEST_DIR6).succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mkdir_dup_file() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
scene.fixtures.touch(TEST_FILE7);
|
||||
scene.ucmd().arg(TEST_FILE7).fails();
|
||||
|
||||
// mkdir should fail for a file even if -p is specified.
|
||||
scene.ucmd().arg("-p").arg(TEST_FILE7).fails();
|
||||
}
|
321
tests/by-util/test_mktemp.rs
Normal file
321
tests/by-util/test_mktemp.rs
Normal file
|
@ -0,0 +1,321 @@
|
|||
use crate::common::util::*;
|
||||
extern crate tempdir;
|
||||
use self::tempdir::TempDir;
|
||||
|
||||
static TEST_TEMPLATE1: &'static str = "tempXXXXXX";
|
||||
static TEST_TEMPLATE2: &'static str = "temp";
|
||||
static TEST_TEMPLATE3: &'static str = "tempX";
|
||||
static TEST_TEMPLATE4: &'static str = "tempXX";
|
||||
static TEST_TEMPLATE5: &'static str = "tempXXX";
|
||||
static TEST_TEMPLATE6: &'static str = "tempXXXlate";
|
||||
static TEST_TEMPLATE7: &'static str = "XXXtemplate";
|
||||
#[cfg(unix)]
|
||||
static TEST_TEMPLATE8: &'static str = "tempXXXl/ate";
|
||||
#[cfg(windows)]
|
||||
static TEST_TEMPLATE8: &'static str = "tempXXXl\\ate";
|
||||
|
||||
const TMPDIR: &'static str = "TMPDIR";
|
||||
|
||||
#[test]
|
||||
fn test_mktemp_mktemp() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let pathname = scene.fixtures.as_string();
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg(TEST_TEMPLATE1)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg(TEST_TEMPLATE2)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg(TEST_TEMPLATE3)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg(TEST_TEMPLATE4)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg(TEST_TEMPLATE5)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg(TEST_TEMPLATE6)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg(TEST_TEMPLATE7)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg(TEST_TEMPLATE8)
|
||||
.fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mktemp_make_temp_dir() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let pathname = scene.fixtures.as_string();
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-d")
|
||||
.arg(TEST_TEMPLATE1)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-d")
|
||||
.arg(TEST_TEMPLATE2)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-d")
|
||||
.arg(TEST_TEMPLATE3)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-d")
|
||||
.arg(TEST_TEMPLATE4)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-d")
|
||||
.arg(TEST_TEMPLATE5)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-d")
|
||||
.arg(TEST_TEMPLATE6)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-d")
|
||||
.arg(TEST_TEMPLATE7)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-d")
|
||||
.arg(TEST_TEMPLATE8)
|
||||
.fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mktemp_dry_run() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let pathname = scene.fixtures.as_string();
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-u")
|
||||
.arg(TEST_TEMPLATE1)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-u")
|
||||
.arg(TEST_TEMPLATE2)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-u")
|
||||
.arg(TEST_TEMPLATE3)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-u")
|
||||
.arg(TEST_TEMPLATE4)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-u")
|
||||
.arg(TEST_TEMPLATE5)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-u")
|
||||
.arg(TEST_TEMPLATE6)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-u")
|
||||
.arg(TEST_TEMPLATE7)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("-u")
|
||||
.arg(TEST_TEMPLATE8)
|
||||
.fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mktemp_quiet() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-p")
|
||||
.arg("/definitely/not/exist/I/promise")
|
||||
.arg("-q")
|
||||
.fails()
|
||||
.no_stdout()
|
||||
.no_stderr();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-d")
|
||||
.arg("-p")
|
||||
.arg("/definitely/not/exist/I/promise")
|
||||
.arg("-q")
|
||||
.fails()
|
||||
.no_stdout()
|
||||
.no_stderr();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mktemp_suffix() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let pathname = scene.fixtures.as_string();
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("--suffix")
|
||||
.arg("suf")
|
||||
.arg(TEST_TEMPLATE1)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("--suffix")
|
||||
.arg("suf")
|
||||
.arg(TEST_TEMPLATE2)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("--suffix")
|
||||
.arg("suf")
|
||||
.arg(TEST_TEMPLATE3)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("--suffix")
|
||||
.arg("suf")
|
||||
.arg(TEST_TEMPLATE4)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("--suffix")
|
||||
.arg("suf")
|
||||
.arg(TEST_TEMPLATE5)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("--suffix")
|
||||
.arg("suf")
|
||||
.arg(TEST_TEMPLATE6)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("--suffix")
|
||||
.arg("suf")
|
||||
.arg(TEST_TEMPLATE7)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.env(TMPDIR, &pathname)
|
||||
.arg("--suffix")
|
||||
.arg("suf")
|
||||
.arg(TEST_TEMPLATE8)
|
||||
.fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mktemp_tmpdir() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let path = TempDir::new_in(scene.fixtures.as_string(), util_name!()).unwrap();
|
||||
let pathname = path.path().as_os_str();
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-p")
|
||||
.arg(pathname)
|
||||
.arg(TEST_TEMPLATE1)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-p")
|
||||
.arg(pathname)
|
||||
.arg(TEST_TEMPLATE2)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-p")
|
||||
.arg(pathname)
|
||||
.arg(TEST_TEMPLATE3)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-p")
|
||||
.arg(pathname)
|
||||
.arg(TEST_TEMPLATE4)
|
||||
.fails();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-p")
|
||||
.arg(pathname)
|
||||
.arg(TEST_TEMPLATE5)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-p")
|
||||
.arg(pathname)
|
||||
.arg(TEST_TEMPLATE6)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-p")
|
||||
.arg(pathname)
|
||||
.arg(TEST_TEMPLATE7)
|
||||
.succeeds();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-p")
|
||||
.arg(pathname)
|
||||
.arg(TEST_TEMPLATE8)
|
||||
.fails();
|
||||
}
|
8
tests/by-util/test_more.rs
Normal file
8
tests/by-util/test_more.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_more_no_arg() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.run();
|
||||
assert!(!result.success);
|
||||
}
|
537
tests/by-util/test_mv.rs
Normal file
537
tests/by-util/test_mv.rs
Normal file
|
@ -0,0 +1,537 @@
|
|||
extern crate filetime;
|
||||
extern crate time;
|
||||
|
||||
use self::filetime::*;
|
||||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_mv_rename_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir1 = "test_mv_rename_dir";
|
||||
let dir2 = "test_mv_rename_dir2";
|
||||
|
||||
at.mkdir(dir1);
|
||||
|
||||
ucmd.arg(dir1).arg(dir2).succeeds().no_stderr();
|
||||
|
||||
assert!(at.dir_exists(dir2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_rename_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file1 = "test_mv_rename_file";
|
||||
let file2 = "test_mv_rename_file2";
|
||||
|
||||
at.touch(file1);
|
||||
|
||||
ucmd.arg(file1).arg(file2).succeeds().no_stderr();
|
||||
assert!(at.file_exists(file2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_move_file_into_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_mv_move_file_into_dir_dir";
|
||||
let file = "test_mv_move_file_into_dir_file";
|
||||
|
||||
at.mkdir(dir);
|
||||
at.touch(file);
|
||||
|
||||
ucmd.arg(file).arg(dir).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(&format!("{}/{}", dir, file)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_move_file_between_dirs() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir1 = "test_mv_move_file_between_dirs_dir1";
|
||||
let dir2 = "test_mv_move_file_between_dirs_dir2";
|
||||
let file = "test_mv_move_file_between_dirs_file";
|
||||
|
||||
at.mkdir(dir1);
|
||||
at.mkdir(dir2);
|
||||
at.touch(&format!("{}/{}", dir1, file));
|
||||
|
||||
assert!(at.file_exists(&format!("{}/{}", dir1, file)));
|
||||
|
||||
ucmd.arg(&format!("{}/{}", dir1, file))
|
||||
.arg(dir2)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(!at.file_exists(&format!("{}/{}", dir1, file)));
|
||||
assert!(at.file_exists(&format!("{}/{}", dir2, file)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_strip_slashes() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let dir = "test_mv_strip_slashes_dir";
|
||||
let file = "test_mv_strip_slashes_file";
|
||||
let mut source = file.to_owned();
|
||||
source.push_str("/");
|
||||
|
||||
at.mkdir(dir);
|
||||
at.touch(file);
|
||||
|
||||
scene.ucmd().arg(&source).arg(dir).fails();
|
||||
|
||||
assert!(!at.file_exists(&format!("{}/{}", dir, file)));
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--strip-trailing-slashes")
|
||||
.arg(source)
|
||||
.arg(dir)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(&format!("{}/{}", dir, file)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_multiple_files() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let target_dir = "test_mv_multiple_files_dir";
|
||||
let file_a = "test_mv_multiple_file_a";
|
||||
let file_b = "test_mv_multiple_file_b";
|
||||
|
||||
at.mkdir(target_dir);
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
ucmd.arg(file_a)
|
||||
.arg(file_b)
|
||||
.arg(target_dir)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(&format!("{}/{}", target_dir, file_a)));
|
||||
assert!(at.file_exists(&format!("{}/{}", target_dir, file_b)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_multiple_folders() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let target_dir = "test_mv_multiple_dirs_dir";
|
||||
let dir_a = "test_mv_multiple_dir_a";
|
||||
let dir_b = "test_mv_multiple_dir_b";
|
||||
|
||||
at.mkdir(target_dir);
|
||||
at.mkdir(dir_a);
|
||||
at.mkdir(dir_b);
|
||||
|
||||
ucmd.arg(dir_a)
|
||||
.arg(dir_b)
|
||||
.arg(target_dir)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.dir_exists(&format!("{}/{}", target_dir, dir_a)));
|
||||
assert!(at.dir_exists(&format!("{}/{}", target_dir, dir_b)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_interactive() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let file_a = "test_mv_interactive_file_a";
|
||||
let file_b = "test_mv_interactive_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-i")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.pipe_in("n")
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-i")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.pipe_in("Yesh")
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_no_clobber() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_mv_no_clobber_file_a";
|
||||
let file_b = "test_mv_no_clobber_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
ucmd.arg("-n")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_replace_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_mv_replace_file_a";
|
||||
let file_b = "test_mv_replace_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
ucmd.arg(file_a).arg(file_b).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_force_replace_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_mv_force_replace_file_a";
|
||||
let file_b = "test_mv_force_replace_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
ucmd.arg("--force")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_simple_backup() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_mv_simple_backup_file_a";
|
||||
let file_b = "test_mv_simple_backup_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
ucmd.arg("-b")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
assert!(at.file_exists(&format!("{}~", file_b)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_custom_backup_suffix() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_mv_custom_backup_suffix_file_a";
|
||||
let file_b = "test_mv_custom_backup_suffix_file_b";
|
||||
let suffix = "super-suffix-of-the-century";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
ucmd.arg("-b")
|
||||
.arg(format!("--suffix={}", suffix))
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
assert!(at.file_exists(&format!("{}{}", file_b, suffix)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_custom_backup_suffix_via_env() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_mv_custom_backup_suffix_file_a";
|
||||
let file_b = "test_mv_custom_backup_suffix_file_b";
|
||||
let suffix = "super-suffix-of-the-century";
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
ucmd.arg("-b")
|
||||
.env("SIMPLE_BACKUP_SUFFIX", suffix)
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
assert!(at.file_exists(&format!("{}{}", file_b, suffix)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_backup_numbering() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_mv_backup_numbering_file_a";
|
||||
let file_b = "test_mv_backup_numbering_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
ucmd.arg("--backup=t")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
assert!(at.file_exists(&format!("{}.~1~", file_b)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_existing_backup() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_mv_existing_backup_file_a";
|
||||
let file_b = "test_mv_existing_backup_file_b";
|
||||
let file_b_backup = "test_mv_existing_backup_file_b.~1~";
|
||||
let resulting_backup = "test_mv_existing_backup_file_b.~2~";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
at.touch(file_b_backup);
|
||||
ucmd.arg("--backup=nil")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
assert!(at.file_exists(file_b_backup));
|
||||
assert!(at.file_exists(resulting_backup));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_update_option() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let file_a = "test_mv_update_option_file_a";
|
||||
let file_b = "test_mv_update_option_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
let ts = time::now().to_timespec();
|
||||
let now = FileTime::from_unix_time(ts.sec as i64, ts.nsec as u32);
|
||||
let later = FileTime::from_unix_time(ts.sec as i64 + 3600, ts.nsec as u32);
|
||||
filetime::set_file_times(at.plus_as_string(file_a), now, now).unwrap();
|
||||
filetime::set_file_times(at.plus_as_string(file_b), now, later).unwrap();
|
||||
|
||||
scene.ucmd().arg("--update").arg(file_a).arg(file_b).run();
|
||||
|
||||
assert!(at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--update")
|
||||
.arg(file_b)
|
||||
.arg(file_a)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file_a));
|
||||
assert!(!at.file_exists(file_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_target_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_mv_target_dir_dir";
|
||||
let file_a = "test_mv_target_dir_file_a";
|
||||
let file_b = "test_mv_target_dir_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
at.mkdir(dir);
|
||||
ucmd.arg("-t")
|
||||
.arg(dir)
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(!at.file_exists(file_b));
|
||||
assert!(at.file_exists(&format!("{}/{}", dir, file_a)));
|
||||
assert!(at.file_exists(&format!("{}/{}", dir, file_b)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_overwrite_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir_a = "test_mv_overwrite_dir_a";
|
||||
let dir_b = "test_mv_overwrite_dir_b";
|
||||
|
||||
at.mkdir(dir_a);
|
||||
at.mkdir(dir_b);
|
||||
ucmd.arg("-T").arg(dir_a).arg(dir_b).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.dir_exists(dir_a));
|
||||
assert!(at.dir_exists(dir_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_overwrite_nonempty_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir_a = "test_mv_overwrite_nonempty_dir_a";
|
||||
let dir_b = "test_mv_overwrite_nonempty_dir_b";
|
||||
let dummy = "test_mv_overwrite_nonempty_dir_b/file";
|
||||
|
||||
at.mkdir(dir_a);
|
||||
at.mkdir(dir_b);
|
||||
at.touch(dummy);
|
||||
// Not same error as GNU; the error message is a rust builtin
|
||||
// TODO: test (and implement) correct error message (or at least decide whether to do so)
|
||||
// Current: "mv: error: couldn't rename path (Directory not empty; from=a; to=b)"
|
||||
// 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
|
||||
);
|
||||
|
||||
assert!(at.dir_exists(dir_a));
|
||||
assert!(at.dir_exists(dir_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_backup_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir_a = "test_mv_backup_dir_dir_a";
|
||||
let dir_b = "test_mv_backup_dir_dir_b";
|
||||
|
||||
at.mkdir(dir_a);
|
||||
at.mkdir(dir_b);
|
||||
ucmd.arg("-vbT")
|
||||
.arg(dir_a)
|
||||
.arg(dir_b)
|
||||
.succeeds()
|
||||
.stdout_only(format!(
|
||||
"‘{}’ -> ‘{}’ (backup: ‘{}~’)\n",
|
||||
dir_a, dir_b, dir_b
|
||||
));
|
||||
|
||||
assert!(!at.dir_exists(dir_a));
|
||||
assert!(at.dir_exists(dir_b));
|
||||
assert!(at.dir_exists(&format!("{}~", dir_b)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_errors() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let dir = "test_mv_errors_dir";
|
||||
let file_a = "test_mv_errors_file_a";
|
||||
let file_b = "test_mv_errors_file_b";
|
||||
at.mkdir(dir);
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
// $ mv -T -t a b
|
||||
// mv: cannot combine --target-directory (-t) and --no-target-directory (-T)
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-T")
|
||||
.arg("-t")
|
||||
.arg(dir)
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.fails()
|
||||
.stderr_is(
|
||||
"mv: error: cannot combine --target-directory (-t) and --no-target-directory (-T)\n",
|
||||
);
|
||||
|
||||
// $ at.touch file && at.mkdir dir
|
||||
// $ mv -T file dir
|
||||
// err == mv: cannot overwrite directory ‘dir’ with non-directory
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-T")
|
||||
.arg(file_a)
|
||||
.arg(dir)
|
||||
.fails()
|
||||
.stderr_is(format!(
|
||||
"mv: error: cannot overwrite directory ‘{}’ with non-directory\n",
|
||||
dir
|
||||
));
|
||||
|
||||
// $ 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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mv_verbose() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
let dir = "test_mv_verbose_dir";
|
||||
let file_a = "test_mv_verbose_file_a";
|
||||
let file_b = "test_mv_verbose_file_b";
|
||||
at.mkdir(dir);
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-v")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.stdout_only(format!("‘{}’ -> ‘{}’\n", file_a, file_b));
|
||||
|
||||
at.touch(file_a);
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-vb")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.stdout_only(format!(
|
||||
"‘{}’ -> ‘{}’ (backup: ‘{}~’)\n",
|
||||
file_a, file_b, file_b
|
||||
));
|
||||
}
|
||||
|
||||
// Todo:
|
||||
|
||||
// $ at.touch a b
|
||||
// $ chmod -w b
|
||||
// $ ll
|
||||
// total 0
|
||||
// -rw-rw-r-- 1 user user 0 okt 25 11:21 a
|
||||
// -r--r--r-- 1 user user 0 okt 25 11:21 b
|
||||
// $
|
||||
// $ mv -v a b
|
||||
// mv: try to overwrite ‘b’, overriding mode 0444 (r--r--r--)? y
|
||||
// ‘a’ -> ‘b’
|
66
tests/by-util/test_nl.rs
Normal file
66
tests/by-util/test_nl.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_stdin_nonewline() {
|
||||
new_ucmd!()
|
||||
.pipe_in("No Newline")
|
||||
.run()
|
||||
.stdout_is(" 1\tNo Newline\n");
|
||||
}
|
||||
#[test]
|
||||
fn test_stdin_newline() {
|
||||
new_ucmd!()
|
||||
.args(&["-s", "-", "-w", "1"])
|
||||
.pipe_in("Line One\nLine Two\n")
|
||||
.run()
|
||||
.stdout_is("1-Line One\n2-Line Two\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_padding_without_overflow() {
|
||||
new_ucmd!()
|
||||
.args(&["-i", "1000", "-s", "x", "-n", "rz", "simple.txt"])
|
||||
.run()
|
||||
.stdout_is(
|
||||
"000001xL1\n001001xL2\n002001xL3\n003001xL4\n004001xL5\n005001xL6\n006001xL7\n0070\
|
||||
01xL8\n008001xL9\n009001xL10\n010001xL11\n011001xL12\n012001xL13\n013001xL14\n014\
|
||||
001xL15\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_padding_with_overflow() {
|
||||
new_ucmd!()
|
||||
.args(&["-i", "1000", "-s", "x", "-n", "rz", "-w", "4", "simple.txt"])
|
||||
.run()
|
||||
.stdout_is(
|
||||
"0001xL1\n1001xL2\n2001xL3\n3001xL4\n4001xL5\n5001xL6\n6001xL7\n7001xL8\n8001xL9\n\
|
||||
9001xL10\n10001xL11\n11001xL12\n12001xL13\n13001xL14\n14001xL15\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sections_and_styles() {
|
||||
for &(fixture, output) in &[
|
||||
(
|
||||
"section.txt",
|
||||
"\nHEADER1\nHEADER2\n\n1 |BODY1\n2 \
|
||||
|BODY2\n\nFOOTER1\nFOOTER2\n\nNEXTHEADER1\nNEXTHEADER2\n\n1 \
|
||||
|NEXTBODY1\n2 |NEXTBODY2\n\nNEXTFOOTER1\nNEXTFOOTER2\n",
|
||||
),
|
||||
(
|
||||
"joinblanklines.txt",
|
||||
"1 |Nonempty\n2 |Nonempty\n3 |Followed by 10x empty\n\n\n\n\n4 \
|
||||
|\n\n\n\n\n5 |\n6 |Followed by 5x empty\n\n\n\n\n7 |\n8 \
|
||||
|Followed by 4x empty\n\n\n\n\n9 |Nonempty\n10 |Nonempty\n11 \
|
||||
|Nonempty.\n",
|
||||
),
|
||||
] {
|
||||
new_ucmd!()
|
||||
.args(&[
|
||||
"-s", "|", "-n", "ln", "-w", "3", "-b", "a", "-l", "5", fixture,
|
||||
])
|
||||
.run()
|
||||
.stdout_is(output);
|
||||
}
|
||||
}
|
147
tests/by-util/test_numfmt.rs
Normal file
147
tests/by-util/test_numfmt.rs
Normal file
|
@ -0,0 +1,147 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_from_si() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=si"])
|
||||
.pipe_in("1000\n1.1M\n0.1G")
|
||||
.run()
|
||||
.stdout_is("1000\n1100000\n100000000\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_iec() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=iec"])
|
||||
.pipe_in("1024\n1.1M\n0.1G")
|
||||
.run()
|
||||
.stdout_is("1024\n1153434\n107374182\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_iec_i() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=iec-i"])
|
||||
.pipe_in("1024\n1.1Mi\n0.1Gi")
|
||||
.run()
|
||||
.stdout_is("1024\n1153434\n107374182\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_auto() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=auto"])
|
||||
.pipe_in("1K\n1Ki")
|
||||
.run()
|
||||
.stdout_is("1000\n1024\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_si() {
|
||||
new_ucmd!()
|
||||
.args(&["--to=si"])
|
||||
.pipe_in("1000\n1100000\n100000000")
|
||||
.run()
|
||||
.stdout_is("1.0K\n1.1M\n100.0M\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_iec() {
|
||||
new_ucmd!()
|
||||
.args(&["--to=iec"])
|
||||
.pipe_in("1024\n1153434\n107374182")
|
||||
.run()
|
||||
.stdout_is("1.0K\n1.1M\n102.4M\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_iec_i() {
|
||||
new_ucmd!()
|
||||
.args(&["--to=iec-i"])
|
||||
.pipe_in("1024\n1153434\n107374182")
|
||||
.run()
|
||||
.stdout_is("1.0Ki\n1.1Mi\n102.4Mi\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_input_from_free_arguments() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=si", "1K", "1.1M", "0.1G"])
|
||||
.run()
|
||||
.stdout_is("1000\n1100000\n100000000\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_padding() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=si", "--padding=8"])
|
||||
.pipe_in("1K\n1.1M\n0.1G")
|
||||
.run()
|
||||
.stdout_is(" 1000\n 1100000\n100000000\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_negative_padding() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=si", "--padding=-8"])
|
||||
.pipe_in("1K\n1.1M\n0.1G")
|
||||
.run()
|
||||
.stdout_is("1000 \n1100000 \n100000000\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_header() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=si", "--header=2"])
|
||||
.pipe_in("header\nheader2\n1K\n1.1M\n0.1G")
|
||||
.run()
|
||||
.stdout_is("header\nheader2\n1000\n1100000\n100000000\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_header_default() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=si", "--header"])
|
||||
.pipe_in("header\n1K\n1.1M\n0.1G")
|
||||
.run()
|
||||
.stdout_is("header\n1000\n1100000\n100000000\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_negative() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=si"])
|
||||
.pipe_in("-1000\n-1.1M\n-0.1G")
|
||||
.run()
|
||||
.stdout_is("-1000\n-1100000\n-100000000\n");
|
||||
new_ucmd!()
|
||||
.args(&["--to=iec-i"])
|
||||
.pipe_in("-1024\n-1153434\n-107374182")
|
||||
.run()
|
||||
.stdout_is("-1.0Ki\n-1.1Mi\n-102.4Mi\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_op() {
|
||||
new_ucmd!()
|
||||
.pipe_in("1024\n1234567")
|
||||
.run()
|
||||
.stdout_is("1024\n1234567\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_normalize() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=si", "--to=si"])
|
||||
.pipe_in("10000000K\n0.001K")
|
||||
.run()
|
||||
.stdout_is("10.0G\n1\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_si_to_iec() {
|
||||
new_ucmd!()
|
||||
.args(&["--from=si", "--to=iec", "15334263563K"])
|
||||
.run()
|
||||
.stdout_is("13.9T\n");
|
||||
}
|
866
tests/by-util/test_od.rs
Normal file
866
tests/by-util/test_od.rs
Normal file
|
@ -0,0 +1,866 @@
|
|||
extern crate unindent;
|
||||
|
||||
use self::unindent::*;
|
||||
use crate::common::util::*;
|
||||
use std::env;
|
||||
use std::fs::remove_file;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
// octal dump of 'abcdefghijklmnopqrstuvwxyz\n'
|
||||
static ALPHA_OUT: &'static str = "
|
||||
0000000 061141 062143 063145 064147 065151 066153 067155 070157
|
||||
0000020 071161 072163 073165 074167 075171 000012
|
||||
0000033
|
||||
";
|
||||
|
||||
// XXX We could do a better job of ensuring that we have a fresh temp dir to ourselves,
|
||||
// not a general one full of other proc's leftovers.
|
||||
|
||||
// Test that od can read one file and dump with default format
|
||||
#[test]
|
||||
fn test_file() {
|
||||
use std::env;
|
||||
let temp = env::temp_dir();
|
||||
let tmpdir = Path::new(&temp);
|
||||
let file = tmpdir.join("test");
|
||||
|
||||
{
|
||||
let mut f = File::create(&file).unwrap();
|
||||
if f.write_all(b"abcdefghijklmnopqrstuvwxyz\n").is_err() {
|
||||
panic!("Test setup failed - could not write file");
|
||||
}
|
||||
}
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg(file.as_os_str())
|
||||
.run();
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, unindent(ALPHA_OUT));
|
||||
|
||||
let _ = remove_file(file);
|
||||
}
|
||||
|
||||
// Test that od can read 2 files and concatenate the contents
|
||||
#[test]
|
||||
fn test_2files() {
|
||||
let temp = env::temp_dir();
|
||||
let tmpdir = Path::new(&temp);
|
||||
let file1 = tmpdir.join("test1");
|
||||
let file2 = tmpdir.join("test2");
|
||||
|
||||
for &(n, a) in &[(1, "a"), (2, "b")] {
|
||||
println!("number: {} letter:{}", n, a);
|
||||
}
|
||||
|
||||
for &(path, data) in &[(&file1, "abcdefghijklmnop"), (&file2, "qrstuvwxyz\n")] {
|
||||
let mut f = File::create(&path).unwrap();
|
||||
if f.write_all(data.as_bytes()).is_err() {
|
||||
panic!("Test setup failed - could not write file");
|
||||
}
|
||||
}
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg(file1.as_os_str())
|
||||
.arg(file2.as_os_str())
|
||||
.run();
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, unindent(ALPHA_OUT));
|
||||
|
||||
let _ = remove_file(file1);
|
||||
let _ = remove_file(file2);
|
||||
}
|
||||
|
||||
// Test that od gives non-0 exit val for filename that doesn't exist.
|
||||
#[test]
|
||||
fn test_no_file() {
|
||||
let temp = env::temp_dir();
|
||||
let tmpdir = Path::new(&temp);
|
||||
let file = tmpdir.join("}surely'none'would'thus'a'file'name");
|
||||
|
||||
let result = new_ucmd!().arg(file.as_os_str()).run();
|
||||
|
||||
assert!(!result.success);
|
||||
}
|
||||
|
||||
// Test that od reads from stdin instead of a file
|
||||
#[test]
|
||||
fn test_from_stdin() {
|
||||
let input = "abcdefghijklmnopqrstuvwxyz\n";
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, unindent(ALPHA_OUT));
|
||||
}
|
||||
|
||||
// Test that od reads from stdin and also from files
|
||||
#[test]
|
||||
fn test_from_mixed() {
|
||||
let temp = env::temp_dir();
|
||||
let tmpdir = Path::new(&temp);
|
||||
let file1 = tmpdir.join("test-1");
|
||||
let file3 = tmpdir.join("test-3");
|
||||
|
||||
let (data1, data2, data3) = ("abcdefg", "hijklmnop", "qrstuvwxyz\n");
|
||||
for &(path, data) in &[(&file1, data1), (&file3, data3)] {
|
||||
let mut f = File::create(&path).unwrap();
|
||||
if f.write_all(data.as_bytes()).is_err() {
|
||||
panic!("Test setup failed - could not write file");
|
||||
}
|
||||
}
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg(file1.as_os_str())
|
||||
.arg("-")
|
||||
.arg(file3.as_os_str())
|
||||
.run_piped_stdin(data2.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, unindent(ALPHA_OUT));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_formats() {
|
||||
let input = "abcdefghijklmnopqrstuvwxyz\n";
|
||||
let result = new_ucmd!()
|
||||
.arg("-c")
|
||||
.arg("-b")
|
||||
.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
"
|
||||
0000000 a b c d e f g h i j k l m n o p
|
||||
141 142 143 144 145 146 147 150 151 152 153 154 155 156 157 160
|
||||
0000020 q r s t u v w x y z \\n
|
||||
161 162 163 164 165 166 167 170 171 172 012
|
||||
0000033
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dec() {
|
||||
let input = [
|
||||
0u8, 0u8, 1u8, 0u8, 2u8, 0u8, 3u8, 0u8, 0xffu8, 0x7fu8, 0x00u8, 0x80u8, 0x01u8, 0x80u8,
|
||||
];
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 0 1 2 3 32767 -32768 -32767
|
||||
0000016
|
||||
",
|
||||
);
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg("-s")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hex16() {
|
||||
let input: [u8; 9] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xff];
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 2301 6745 ab89 efcd 00ff
|
||||
0000011
|
||||
",
|
||||
);
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg("-x")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hex32() {
|
||||
let input: [u8; 9] = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xff];
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 67452301 efcdab89 000000ff
|
||||
0000011
|
||||
",
|
||||
);
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg("-X")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_f16() {
|
||||
let input: [u8; 14] = [
|
||||
0x00, 0x3c, // 0x3C00 1.0
|
||||
0x00, 0x00, // 0x0000 0.0
|
||||
0x00, 0x80, // 0x8000 -0.0
|
||||
0x00, 0x7c, // 0x7C00 Inf
|
||||
0x00, 0xfc, // 0xFC00 -Inf
|
||||
0x00, 0xfe, // 0xFE00 NaN
|
||||
0x00, 0x84,
|
||||
]; // 0x8400 -6.104e-5
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 1.000 0 -0 inf
|
||||
0000010 -inf NaN -6.104e-5
|
||||
0000016
|
||||
",
|
||||
);
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg("-tf2")
|
||||
.arg("-w8")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_f32() {
|
||||
let input: [u8; 28] = [
|
||||
0x52, 0x06, 0x9e, 0xbf, // 0xbf9e0652 -1.2345679
|
||||
0x4e, 0x61, 0x3c, 0x4b, // 0x4b3c614e 12345678
|
||||
0x0f, 0x9b, 0x94, 0xfe, // 0xfe949b0f -9.876543E37
|
||||
0x00, 0x00, 0x00, 0x80, // 0x80000000 -0.0
|
||||
0xff, 0xff, 0xff, 0x7f, // 0x7fffffff NaN
|
||||
0xc2, 0x16, 0x01, 0x00, // 0x000116c2 1e-40
|
||||
0x00, 0x00, 0x7f, 0x80,
|
||||
]; // 0x807f0000 -1.1663108E-38
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 -1.2345679 12345678 -9.8765427e37 -0
|
||||
0000020 NaN 1e-40 -1.1663108e-38
|
||||
0000034
|
||||
",
|
||||
);
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg("-f")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_f64() {
|
||||
let input: [u8; 40] = [
|
||||
0x27, 0x6b, 0x0a, 0x2f, 0x2a, 0xee, 0x45,
|
||||
0x43, // 0x4345EE2A2F0A6B27 12345678912345678
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x0000000000000000 0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
|
||||
0x80, // 0x8010000000000000 -2.2250738585072014e-308
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, // 0x0000000000000001 5e-324 (subnormal)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
|
||||
]; // 0xc000000000000000 -2
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 12345678912345678 0
|
||||
0000020 -2.2250738585072014e-308 5e-324
|
||||
0000040 -2.0000000000000000
|
||||
0000050
|
||||
",
|
||||
);
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg("-F")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multibyte() {
|
||||
let result = new_ucmd!()
|
||||
.arg("-c")
|
||||
.arg("-w12")
|
||||
.run_piped_stdin("Universität Tübingen \u{1B000}".as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
"
|
||||
0000000 U n i v e r s i t ä ** t
|
||||
0000014 T ü ** b i n g e n \u{1B000}
|
||||
0000030 ** ** **
|
||||
0000033
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_width() {
|
||||
let input: [u8; 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 000000 000000
|
||||
0000004 000000 000000
|
||||
0000010
|
||||
",
|
||||
);
|
||||
|
||||
let result = new_ucmd!().arg("-w4").arg("-v").run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_width() {
|
||||
let input: [u8; 4] = [0x00, 0x00, 0x00, 0x00];
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 000000
|
||||
0000002 000000
|
||||
0000004
|
||||
",
|
||||
);
|
||||
|
||||
let result = new_ucmd!().arg("-w5").arg("-v").run_piped_stdin(&input[..]);
|
||||
|
||||
assert_eq!(
|
||||
result.stderr,
|
||||
"od: warning: invalid width 5; using 2 instead\n"
|
||||
);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_zero_width() {
|
||||
let input: [u8; 4] = [0x00, 0x00, 0x00, 0x00];
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 000000
|
||||
0000002 000000
|
||||
0000004
|
||||
",
|
||||
);
|
||||
|
||||
let result = new_ucmd!().arg("-w0").arg("-v").run_piped_stdin(&input[..]);
|
||||
|
||||
assert_eq!(
|
||||
result.stderr,
|
||||
"od: warning: invalid width 0; using 2 instead\n"
|
||||
);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_width_without_value() {
|
||||
let input: [u8; 40] = [0; 40];
|
||||
let expected_output = unindent("
|
||||
0000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000 000000
|
||||
0000040 000000 000000 000000 000000
|
||||
0000050
|
||||
");
|
||||
|
||||
let result = new_ucmd!().arg("-w").run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_suppress_duplicates() {
|
||||
let input: [u8; 41] = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 00000000000
|
||||
0000 0000
|
||||
*
|
||||
0000020 00000000001
|
||||
0001 0000
|
||||
0000024 00000000000
|
||||
0000 0000
|
||||
*
|
||||
0000050 00000000000
|
||||
0000
|
||||
0000051
|
||||
",
|
||||
);
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("-w4")
|
||||
.arg("-O")
|
||||
.arg("-x")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_big_endian() {
|
||||
let input: [u8; 8] = [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; // 0xc000000000000000 -2
|
||||
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 -2.0000000000000000
|
||||
-2.0000000 0
|
||||
c0000000 00000000
|
||||
c000 0000 0000 0000
|
||||
0000010
|
||||
",
|
||||
);
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=big")
|
||||
.arg("-F")
|
||||
.arg("-f")
|
||||
.arg("-X")
|
||||
.arg("-x")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(non_snake_case)]
|
||||
fn test_alignment_Xxa() {
|
||||
let input: [u8; 8] = [0x0A, 0x0D, 0x65, 0x66, 0x67, 0x00, 0x9e, 0x9f];
|
||||
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 66650d0a 9f9e0067
|
||||
0d0a 6665 0067 9f9e
|
||||
nl cr e f g nul rs us
|
||||
0000010
|
||||
",
|
||||
);
|
||||
|
||||
// in this case the width of the -a (8-bit) determines the alignment for the other fields
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg("-X")
|
||||
.arg("-x")
|
||||
.arg("-a")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(non_snake_case)]
|
||||
fn test_alignment_Fx() {
|
||||
let input: [u8; 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0]; // 0xc000000000000000 -2
|
||||
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 -2.0000000000000000
|
||||
0000 0000 0000 c000
|
||||
0000010
|
||||
",
|
||||
);
|
||||
|
||||
// in this case the width of the -F (64-bit) determines the alignment for the other field
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg("-F")
|
||||
.arg("-x")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maxuint() {
|
||||
let input = [0xFFu8; 8];
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 1777777777777777777777
|
||||
37777777777 37777777777
|
||||
177777 177777 177777 177777
|
||||
377 377 377 377 377 377 377 377
|
||||
18446744073709551615
|
||||
4294967295 4294967295
|
||||
65535 65535 65535 65535
|
||||
255 255 255 255 255 255 255 255
|
||||
0000010
|
||||
",
|
||||
);
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("--format=o8")
|
||||
.arg("-Oobtu8")
|
||||
.arg("-Dd")
|
||||
.arg("--format=u1")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hex_offset() {
|
||||
let input = [0u8; 0x1F];
|
||||
let expected_output = unindent(
|
||||
"
|
||||
000000 00000000 00000000 00000000 00000000
|
||||
00000000 00000000 00000000 00000000
|
||||
000010 00000000 00000000 00000000 00000000
|
||||
00000000 00000000 00000000 00000000
|
||||
00001F
|
||||
",
|
||||
);
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("-Ax")
|
||||
.arg("-X")
|
||||
.arg("-X")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dec_offset() {
|
||||
let input = [0u8; 19];
|
||||
let expected_output = unindent(
|
||||
"
|
||||
0000000 00000000 00000000 00000000 00000000
|
||||
00000000 00000000 00000000 00000000
|
||||
0000016 00000000
|
||||
00000000
|
||||
0000019
|
||||
",
|
||||
);
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("-Ad")
|
||||
.arg("-X")
|
||||
.arg("-X")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_offset() {
|
||||
let input = [0u8; 31];
|
||||
const LINE: &'static str = " 00000000 00000000 00000000 00000000\n";
|
||||
let expected_output = [LINE, LINE, LINE, LINE].join("");
|
||||
|
||||
let result = new_ucmd!()
|
||||
.arg("-An")
|
||||
.arg("-X")
|
||||
.arg("-X")
|
||||
.run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, expected_output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_offset() {
|
||||
let result = new_ucmd!().arg("-Ab").run();
|
||||
|
||||
assert!(!result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_skip_bytes() {
|
||||
let input = "abcdefghijklmnopq";
|
||||
let result = new_ucmd!()
|
||||
.arg("-c")
|
||||
.arg("--skip-bytes=5")
|
||||
.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
"
|
||||
0000005 f g h i j k l m n o p q
|
||||
0000021
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_skip_bytes_error() {
|
||||
let input = "12345";
|
||||
let result = new_ucmd!()
|
||||
.arg("--skip-bytes=10")
|
||||
.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert!(!result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_bytes() {
|
||||
let input = "abcdefghijklmnopqrstuvwxyz\n12345678";
|
||||
let result = new_ucmd!()
|
||||
.arg("--endian=little")
|
||||
.arg("--read-bytes=27")
|
||||
.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, unindent(ALPHA_OUT));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ascii_dump() {
|
||||
let input: [u8; 22] = [
|
||||
0x00, 0x01, 0x0a, 0x0d, 0x10, 0x1f, 0x20, 0x61, 0x62, 0x63, 0x7d, 0x7e, 0x7f, 0x80, 0x90,
|
||||
0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff,
|
||||
];
|
||||
let result = new_ucmd!().arg("-tx1zacz").run_piped_stdin(&input[..]);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
r"
|
||||
0000000 00 01 0a 0d 10 1f 20 61 62 63 7d 7e 7f 80 90 a0 >...... abc}~....<
|
||||
nul soh nl cr dle us sp a b c } ~ del nul dle sp
|
||||
\0 001 \n \r 020 037 a b c } ~ 177 ** ** ** >...... abc}~....<
|
||||
0000020 b0 c0 d0 e0 f0 ff >......<
|
||||
0 @ P ` p del
|
||||
** 300 320 340 360 377 >......<
|
||||
0000026
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_filename_parsing() {
|
||||
// files "a" and "x" both exists, but are no filenames in the commandline below
|
||||
// "-f" must be treated as a filename, it contains the text: minus lowercase f
|
||||
// so "-f" should not be interpreted as a formatting option.
|
||||
let result = new_ucmd!()
|
||||
.arg("--format")
|
||||
.arg("a")
|
||||
.arg("-A")
|
||||
.arg("x")
|
||||
.arg("--")
|
||||
.arg("-f")
|
||||
.run();
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
"
|
||||
000000 m i n u s sp l o w e r c a s e sp
|
||||
000010 f nl
|
||||
000012
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_offset() {
|
||||
let input = "abcdefghijklmnopq";
|
||||
let result = new_ucmd!()
|
||||
.arg("-c")
|
||||
.arg("+5")
|
||||
.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
"
|
||||
0000005 f g h i j k l m n o p q
|
||||
0000021
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file_offset() {
|
||||
let result = new_ucmd!().arg("-c").arg("--").arg("-f").arg("10").run();
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
r"
|
||||
0000010 w e r c a s e f \n
|
||||
0000022
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_traditional() {
|
||||
// note gnu od does not align both lines
|
||||
let input = "abcdefghijklmnopq";
|
||||
let result = new_ucmd!()
|
||||
.arg("--traditional")
|
||||
.arg("-a")
|
||||
.arg("-c")
|
||||
.arg("-")
|
||||
.arg("10")
|
||||
.arg("0")
|
||||
.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
r"
|
||||
0000010 (0000000) i j k l m n o p q
|
||||
i j k l m n o p q
|
||||
0000021 (0000011)
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_traditional_with_skip_bytes_override() {
|
||||
// --skip-bytes is ignored in this case
|
||||
let input = "abcdefghijklmnop";
|
||||
let result = new_ucmd!()
|
||||
.arg("--traditional")
|
||||
.arg("--skip-bytes=10")
|
||||
.arg("-c")
|
||||
.arg("0")
|
||||
.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
r"
|
||||
0000000 a b c d e f g h i j k l m n o p
|
||||
0000020
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_traditional_with_skip_bytes_non_override() {
|
||||
// no offset specified in the traditional way, so --skip-bytes is used
|
||||
let input = "abcdefghijklmnop";
|
||||
let result = new_ucmd!()
|
||||
.arg("--traditional")
|
||||
.arg("--skip-bytes=10")
|
||||
.arg("-c")
|
||||
.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
r"
|
||||
0000012 k l m n o p
|
||||
0000020
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_traditional_error() {
|
||||
// file "0" exists - don't fail on that, but --traditional only accepts a single input
|
||||
let result = new_ucmd!()
|
||||
.arg("--traditional")
|
||||
.arg("0")
|
||||
.arg("0")
|
||||
.arg("0")
|
||||
.arg("0")
|
||||
.run();
|
||||
|
||||
assert!(!result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_traditional_only_label() {
|
||||
let input = "abcdefghijklmnopqrstuvwxyz";
|
||||
let result = new_ucmd!()
|
||||
.arg("-An")
|
||||
.arg("--traditional")
|
||||
.arg("-a")
|
||||
.arg("-c")
|
||||
.arg("-")
|
||||
.arg("10")
|
||||
.arg("0x10")
|
||||
.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(
|
||||
result.stdout,
|
||||
unindent(
|
||||
r"
|
||||
(0000020) i j k l m n o p q r s t u v w x
|
||||
i j k l m n o p q r s t u v w x
|
||||
(0000040) y z
|
||||
y z
|
||||
(0000042)
|
||||
"
|
||||
)
|
||||
);
|
||||
}
|
9
tests/by-util/test_paste.rs
Normal file
9
tests/by-util/test_paste.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_combine_pairs_of_lines() {
|
||||
new_ucmd!()
|
||||
.args(&["-s", "-d", "\t\n", "html_colors.txt"])
|
||||
.run()
|
||||
.stdout_is_fixture("html_colors.expected");
|
||||
}
|
15
tests/by-util/test_pathchk.rs
Normal file
15
tests/by-util/test_pathchk.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_default_mode() {
|
||||
// test the default mode
|
||||
|
||||
// accept some reasonable default
|
||||
new_ucmd!().args(&["abc/def"]).succeeds().no_stdout();
|
||||
|
||||
// fail on long inputs
|
||||
new_ucmd!()
|
||||
.args(&[repeat_str("test", 20000)])
|
||||
.fails()
|
||||
.no_stdout();
|
||||
}
|
83
tests/by-util/test_pinky.rs
Normal file
83
tests/by-util/test_pinky.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
extern crate uucore;
|
||||
|
||||
use crate::common::util::*;
|
||||
|
||||
use self::uucore::entries::{Locate, Passwd};
|
||||
|
||||
extern crate pinky;
|
||||
pub use self::pinky::*;
|
||||
|
||||
#[test]
|
||||
fn test_capitalize() {
|
||||
assert_eq!("Zbnmasd", "zbnmasd".capitalize());
|
||||
assert_eq!("Abnmasd", "Abnmasd".capitalize());
|
||||
assert_eq!("1masd", "1masd".capitalize());
|
||||
assert_eq!("", "".capitalize());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_format() {
|
||||
let ulogin = "root";
|
||||
let pw: Passwd = Passwd::locate(ulogin).unwrap();
|
||||
let real_name = pw.user_info().replace("&", &pw.name().capitalize());
|
||||
new_ucmd!().arg("-l").arg(ulogin).run().stdout_is(format!(
|
||||
"Login name: {:<28}In real life: {}\nDirectory: {:<29}Shell: {}\n\n",
|
||||
ulogin,
|
||||
real_name,
|
||||
pw.user_dir(),
|
||||
pw.user_shell()
|
||||
));
|
||||
|
||||
new_ucmd!().arg("-lb").arg(ulogin).run().stdout_is(format!(
|
||||
"Login name: {:<28}In real life: {1}\n\n",
|
||||
ulogin, real_name
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_short_format_i() {
|
||||
// allow whitespace variation
|
||||
// * minor whitespace differences occur between platform built-in outputs; specifically, the number of trailing TABs may be variant
|
||||
let args = ["-i"];
|
||||
let actual = TestScenario::new(util_name!())
|
||||
.ucmd()
|
||||
.args(&args)
|
||||
.run()
|
||||
.stdout;
|
||||
let expect = expected_result(&args);
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
let v_actual: Vec<&str> = actual.split_whitespace().collect();
|
||||
let v_expect: Vec<&str> = expect.split_whitespace().collect();
|
||||
assert_eq!(v_actual, v_expect);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_short_format_q() {
|
||||
// allow whitespace variation
|
||||
// * minor whitespace differences occur between platform built-in outputs; specifically, the number of trailing TABs may be variant
|
||||
let args = ["-q"];
|
||||
let actual = TestScenario::new(util_name!())
|
||||
.ucmd()
|
||||
.args(&args)
|
||||
.run()
|
||||
.stdout;
|
||||
let expect = expected_result(&args);
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
let v_actual: Vec<&str> = actual.split_whitespace().collect();
|
||||
let v_expect: Vec<&str> = expect.split_whitespace().collect();
|
||||
assert_eq!(v_actual, v_expect);
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn expected_result(args: &[&str]) -> String {
|
||||
TestScenario::new(util_name!())
|
||||
.cmd_keepenv(util_name!())
|
||||
.env("LANGUAGE", "C")
|
||||
.args(args)
|
||||
.run()
|
||||
.stdout
|
||||
}
|
30
tests/by-util/test_printenv.rs
Normal file
30
tests/by-util/test_printenv.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use crate::common::util::*;
|
||||
use std::env;
|
||||
|
||||
#[test]
|
||||
fn test_get_all() {
|
||||
let key = "KEY";
|
||||
env::set_var(key, "VALUE");
|
||||
assert_eq!(env::var(key), Ok("VALUE".to_string()));
|
||||
|
||||
let result = TestScenario::new(util_name!()).ucmd_keepenv().run();
|
||||
assert!(result.success);
|
||||
assert!(result.stdout.contains("HOME="));
|
||||
assert!(result.stdout.contains("KEY=VALUE"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_var() {
|
||||
let key = "KEY";
|
||||
env::set_var(key, "VALUE");
|
||||
assert_eq!(env::var(key), Ok("VALUE".to_string()));
|
||||
|
||||
let result = TestScenario::new(util_name!())
|
||||
.ucmd_keepenv()
|
||||
.arg("KEY")
|
||||
.run();
|
||||
|
||||
assert!(result.success);
|
||||
assert!(!result.stdout.is_empty());
|
||||
assert!(result.stdout.trim() == "VALUE");
|
||||
}
|
431
tests/by-util/test_printf.rs
Normal file
431
tests/by-util/test_printf.rs
Normal file
|
@ -0,0 +1,431 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn basic_literal() {
|
||||
new_ucmd!()
|
||||
.args(&["hello world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_tab() {
|
||||
new_ucmd!()
|
||||
.args(&["hello\\t world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello\t world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_newline() {
|
||||
new_ucmd!()
|
||||
.args(&["hello\\n world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello\n world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_slash() {
|
||||
new_ucmd!()
|
||||
.args(&["hello\\\\ world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello\\ world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_hex() {
|
||||
new_ucmd!().args(&["\\x41"]).succeeds().stdout_only("A");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_octal() {
|
||||
new_ucmd!().args(&["\\101"]).succeeds().stdout_only("A");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_unicode_fourdigit() {
|
||||
new_ucmd!().args(&["\\u0125"]).succeeds().stdout_only("ĥ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_unicode_eightdigit() {
|
||||
new_ucmd!()
|
||||
.args(&["\\U00000125"])
|
||||
.succeeds()
|
||||
.stdout_only("ĥ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_percent_sign() {
|
||||
new_ucmd!()
|
||||
.args(&["hello%% world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello% world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn escaped_unrecognized() {
|
||||
new_ucmd!().args(&["c\\d"]).succeeds().stdout_only("c\\d");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_string() {
|
||||
new_ucmd!()
|
||||
.args(&["hello %s", "world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_multifield() {
|
||||
new_ucmd!()
|
||||
.args(&["%s %s", "hello", "world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_repeat_formatstr() {
|
||||
new_ucmd!()
|
||||
.args(&["%s.", "hello", "world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello.world.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_string_ignore_escapes() {
|
||||
new_ucmd!()
|
||||
.args(&["hello %s", "\\tworld"])
|
||||
.succeeds()
|
||||
.stdout_only("hello \\tworld");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_bstring_handle_escapes() {
|
||||
new_ucmd!()
|
||||
.args(&["hello %b", "\\tworld"])
|
||||
.succeeds()
|
||||
.stdout_only("hello \tworld");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_bstring_ignore_subs() {
|
||||
new_ucmd!()
|
||||
.args(&["hello %b", "world %% %i"])
|
||||
.succeeds()
|
||||
.stdout_only("hello world %% %i");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_char() {
|
||||
new_ucmd!()
|
||||
.args(&["the letter %c", "A"])
|
||||
.succeeds()
|
||||
.stdout_only("the letter A");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_int() {
|
||||
new_ucmd!()
|
||||
.args(&["twenty is %i", "20"])
|
||||
.succeeds()
|
||||
.stdout_only("twenty is 20");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_int_minwidth() {
|
||||
new_ucmd!()
|
||||
.args(&["twenty is %1i", "20"])
|
||||
.succeeds()
|
||||
.stdout_only("twenty is 20");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_int_neg() {
|
||||
new_ucmd!()
|
||||
.args(&["neg. twenty is %i", "-20"])
|
||||
.succeeds()
|
||||
.stdout_only("neg. twenty is -20");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_int_oct_in() {
|
||||
new_ucmd!()
|
||||
.args(&["twenty is %i", "024"])
|
||||
.succeeds()
|
||||
.stdout_only("twenty is 20");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_int_oct_in_neg() {
|
||||
new_ucmd!()
|
||||
.args(&["neg. twenty is %i", "-024"])
|
||||
.succeeds()
|
||||
.stdout_only("neg. twenty is -20");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_int_hex_in() {
|
||||
new_ucmd!()
|
||||
.args(&["twenty is %i", "0x14"])
|
||||
.succeeds()
|
||||
.stdout_only("twenty is 20");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_int_hex_in_neg() {
|
||||
new_ucmd!()
|
||||
.args(&["neg. twenty is %i", "-0x14"])
|
||||
.succeeds()
|
||||
.stdout_only("neg. twenty is -20");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_int_charconst_in() {
|
||||
new_ucmd!()
|
||||
.args(&["ninetyseven is %i", "'a"])
|
||||
.succeeds()
|
||||
.stdout_only("ninetyseven is 97");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_uint() {
|
||||
new_ucmd!()
|
||||
.args(&["twenty is %u", "20"])
|
||||
.succeeds()
|
||||
.stdout_only("twenty is 20");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_octal() {
|
||||
new_ucmd!()
|
||||
.args(&["twenty in octal is %o", "20"])
|
||||
.succeeds()
|
||||
.stdout_only("twenty in octal is 24");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_hex_lower() {
|
||||
new_ucmd!()
|
||||
.args(&["thirty in hex is %x", "30"])
|
||||
.succeeds()
|
||||
.stdout_only("thirty in hex is 1e");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_hex_upper() {
|
||||
new_ucmd!()
|
||||
.args(&["thirty in hex is %X", "30"])
|
||||
.succeeds()
|
||||
.stdout_only("thirty in hex is 1E");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_float() {
|
||||
new_ucmd!()
|
||||
.args(&["twenty is %f", "20"])
|
||||
.succeeds()
|
||||
.stdout_only("twenty is 20.000000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_float_round() {
|
||||
new_ucmd!()
|
||||
.args(&["two is %f", "1.9999995"])
|
||||
.succeeds()
|
||||
.stdout_only("two is 2.000000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_sci_lower() {
|
||||
new_ucmd!()
|
||||
.args(&["twenty is %e", "20"])
|
||||
.succeeds()
|
||||
.stdout_only("twenty is 2.000000e+01");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_sci_upper() {
|
||||
new_ucmd!()
|
||||
.args(&["twenty is %E", "20"])
|
||||
.succeeds()
|
||||
.stdout_only("twenty is 2.000000E+01");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_sci_trunc() {
|
||||
new_ucmd!()
|
||||
.args(&["pi is ~ %e", "3.1415926535"])
|
||||
.succeeds()
|
||||
.stdout_only("pi is ~ 3.141593e+00");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_num_dec_trunc() {
|
||||
new_ucmd!()
|
||||
.args(&["pi is ~ %g", "3.1415926535"])
|
||||
.succeeds()
|
||||
.stdout_only("pi is ~ 3.141593");
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn sub_num_hex_float_lower() {
|
||||
new_ucmd!()
|
||||
.args(&["%a", ".875"])
|
||||
.succeeds()
|
||||
.stdout_only("0xep-4");
|
||||
}
|
||||
|
||||
#[cfg_attr(not(feature = "test_unimplemented"), ignore)]
|
||||
#[test]
|
||||
fn sub_num_hex_float_upper() {
|
||||
new_ucmd!()
|
||||
.args(&["%A", ".875"])
|
||||
.succeeds()
|
||||
.stdout_only("0XEP-4");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_minwidth() {
|
||||
new_ucmd!()
|
||||
.args(&["hello %7s", "world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_minwidth_negative() {
|
||||
new_ucmd!()
|
||||
.args(&["hello %-7s", "world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello world ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_str_max_chars_input() {
|
||||
new_ucmd!()
|
||||
.args(&["hello %7.2s", "world"])
|
||||
.succeeds()
|
||||
.stdout_only("hello wo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_int_decimal() {
|
||||
new_ucmd!()
|
||||
.args(&["%0.i", "11"])
|
||||
.succeeds()
|
||||
.stdout_only("11");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_int_leading_zeroes() {
|
||||
new_ucmd!()
|
||||
.args(&["%.4i", "11"])
|
||||
.succeeds()
|
||||
.stdout_only("0011");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_int_leading_zeroes_prio() {
|
||||
new_ucmd!()
|
||||
.args(&["%5.4i", "11"])
|
||||
.succeeds()
|
||||
.stdout_only(" 0011");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_float_dec_places() {
|
||||
new_ucmd!()
|
||||
.args(&["pi is ~ %.11f", "3.1415926535"])
|
||||
.succeeds()
|
||||
.stdout_only("pi is ~ 3.14159265350");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_float_hex_in() {
|
||||
new_ucmd!()
|
||||
.args(&["%f", "0xF1.1F"])
|
||||
.succeeds()
|
||||
.stdout_only("241.121094");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_float_no_octal_in() {
|
||||
new_ucmd!()
|
||||
.args(&["%f", "077"])
|
||||
.succeeds()
|
||||
.stdout_only("77.000000");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_asterisk_firstparam() {
|
||||
new_ucmd!()
|
||||
.args(&["%*i", "3", "11", "4", "12"])
|
||||
.succeeds()
|
||||
.stdout_only(" 11 12");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_asterisk_second_param() {
|
||||
new_ucmd!()
|
||||
.args(&["%.*i", "3", "11", "4", "12"])
|
||||
.succeeds()
|
||||
.stdout_only("0110012");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_asterisk_both_params() {
|
||||
new_ucmd!()
|
||||
.args(&["%*.*i", "4", "3", "11", "5", "4", "12"])
|
||||
.succeeds()
|
||||
.stdout_only(" 011 0012");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_asterisk_octal_arg() {
|
||||
new_ucmd!()
|
||||
.args(&["%.*i", "011", "12345678"])
|
||||
.succeeds()
|
||||
.stdout_only("012345678");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_asterisk_hex_arg() {
|
||||
new_ucmd!()
|
||||
.args(&["%.*i", "0xA", "123456789"])
|
||||
.succeeds()
|
||||
.stdout_only("0123456789");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_specifiers_no_params() {
|
||||
new_ucmd!()
|
||||
.args(&["%ztlhLji", "3"])
|
||||
.succeeds()
|
||||
.stdout_only("3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_specifiers_after_first_param() {
|
||||
new_ucmd!()
|
||||
.args(&["%0ztlhLji", "3"])
|
||||
.succeeds()
|
||||
.stdout_only("3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_specifiers_after_period() {
|
||||
new_ucmd!()
|
||||
.args(&["%0.ztlhLji", "3"])
|
||||
.succeeds()
|
||||
.stdout_only("3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_specifiers_after_second_param() {
|
||||
new_ucmd!()
|
||||
.args(&["%0.0ztlhLji", "3"])
|
||||
.succeeds()
|
||||
.stdout_only("3");
|
||||
}
|
57
tests/by-util/test_ptx.rs
Normal file
57
tests/by-util/test_ptx.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn gnu_ext_disabled_roff_no_ref() {
|
||||
new_ucmd!()
|
||||
.args(&["-G", "-R", "input"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("gnu_ext_disabled_roff_no_ref.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gnu_ext_disabled_roff_input_ref() {
|
||||
new_ucmd!()
|
||||
.args(&["-G", "-r", "-R", "input"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("gnu_ext_disabled_roff_input_ref.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gnu_ext_disabled_roff_auto_ref() {
|
||||
new_ucmd!()
|
||||
.args(&["-G", "-A", "-R", "input"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("gnu_ext_disabled_roff_auto_ref.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gnu_ext_disabled_tex_no_ref() {
|
||||
new_ucmd!()
|
||||
.args(&["-G", "-T", "-R", "input"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("gnu_ext_disabled_tex_no_ref.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gnu_ext_disabled_tex_input_ref() {
|
||||
new_ucmd!()
|
||||
.args(&["-G", "-T", "-r", "-R", "input"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("gnu_ext_disabled_tex_input_ref.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gnu_ext_disabled_tex_auto_ref() {
|
||||
new_ucmd!()
|
||||
.args(&["-G", "-T", "-A", "-R", "input"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("gnu_ext_disabled_tex_auto_ref.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gnu_ext_disabled_ignore_and_only_file() {
|
||||
new_ucmd!()
|
||||
.args(&["-G", "-o", "only", "-i", "ignore", "input"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("gnu_ext_disabled_ignore_and_only_file.expected");
|
||||
}
|
7
tests/by-util/test_pwd.rs
Normal file
7
tests/by-util/test_pwd.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_default() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
ucmd.run().stdout_is(at.root_dir_resolved() + "\n");
|
||||
}
|
56
tests/by-util/test_readlink.rs
Normal file
56
tests/by-util/test_readlink.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
static GIBBERISH: &'static str = "supercalifragilisticexpialidocious";
|
||||
|
||||
#[test]
|
||||
fn test_canonicalize() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let actual = ucmd.arg("-f").arg(".").run().stdout;
|
||||
let expect = at.root_dir_resolved() + "\n";
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
assert_eq!(actual, expect);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_canonicalize_existing() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let actual = ucmd.arg("-e").arg(".").run().stdout;
|
||||
let expect = at.root_dir_resolved() + "\n";
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
assert_eq!(actual, expect);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_canonicalize_missing() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let actual = ucmd.arg("-m").arg(GIBBERISH).run().stdout;
|
||||
let expect = path_concat!(at.root_dir_resolved(), GIBBERISH) + "\n";
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
assert_eq!(actual, expect);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_redirection_to_current_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
// Create a 256-character path to current directory
|
||||
let dir = path_concat!(".", ..128);
|
||||
let actual = ucmd.arg("-n").arg("-m").arg(dir).run().stdout;
|
||||
let expect = at.root_dir_resolved();
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
assert_eq!(actual, expect);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_redirection_to_root() {
|
||||
// Create a 255-character path to root
|
||||
let dir = path_concat!("..", ..85);
|
||||
let actual = new_ucmd!().arg("-n").arg("-m").arg(dir).run().stdout;
|
||||
let expect = get_root_path();
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
assert_eq!(actual, expect);
|
||||
}
|
34
tests/by-util/test_realpath.rs
Normal file
34
tests/by-util/test_realpath.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_current_directory() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let actual = ucmd.arg(".").run().stdout;
|
||||
let expect = at.root_dir_resolved() + "\n";
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
assert_eq!(actual, expect);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_redirection_to_current_dir() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
// Create a 256-character path to current directory
|
||||
let dir = path_concat!(".", ..128);
|
||||
let actual = ucmd.arg(dir).run().stdout;
|
||||
let expect = at.root_dir_resolved() + "\n";
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
assert_eq!(actual, expect);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_redirection_to_root() {
|
||||
// Create a 255-character path to root
|
||||
let dir = path_concat!("..", ..85);
|
||||
let actual = new_ucmd!().arg(dir).run().stdout;
|
||||
let expect = get_root_path().to_owned() + "\n";
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
assert_eq!(actual, expect);
|
||||
}
|
180
tests/by-util/test_rm.rs
Normal file
180
tests/by-util/test_rm.rs
Normal file
|
@ -0,0 +1,180 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_rm_one_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_rm_one_file";
|
||||
|
||||
at.touch(file);
|
||||
|
||||
ucmd.arg(file).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_multiple_files() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_rm_multiple_file_a";
|
||||
let file_b = "test_rm_multiple_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
ucmd.arg(file_a).arg(file_b).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(!at.file_exists(file_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_interactive() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
|
||||
let file_a = "test_rm_interactive_file_a";
|
||||
let file_b = "test_rm_interactive_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-i")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.pipe_in("n")
|
||||
.succeeds();
|
||||
|
||||
assert!(at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("-i")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.pipe_in("Yesh")
|
||||
.succeeds();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(at.file_exists(file_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_force() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_rm_force_a";
|
||||
let file_b = "test_rm_force_b";
|
||||
|
||||
ucmd.arg("-f")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(!at.file_exists(file_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_empty_directory() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rm_empty_directory";
|
||||
|
||||
at.mkdir(dir);
|
||||
|
||||
ucmd.arg("-d").arg(dir).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.dir_exists(dir));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_recursive() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rm_recursive_directory";
|
||||
let file_a = "test_rm_recursive_directory/test_rm_recursive_file_a";
|
||||
let file_b = "test_rm_recursive_directory/test_rm_recursive_file_b";
|
||||
|
||||
at.mkdir(dir);
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
ucmd.arg("-r").arg(dir).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.dir_exists(dir));
|
||||
assert!(!at.file_exists(file_a));
|
||||
assert!(!at.file_exists(file_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_errors() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rm_errors_directory";
|
||||
let file_a = "test_rm_errors_directory/test_rm_errors_file_a";
|
||||
let file_b = "test_rm_errors_directory/test_rm_errors_file_b";
|
||||
|
||||
at.mkdir(dir);
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
// $ rm test_rm_errors_directory
|
||||
// rm: error: could not remove directory 'test_rm_errors_directory' (did you mean to pass '-r'?)
|
||||
ucmd.arg(dir).fails().stderr_is(
|
||||
"rm: error: could not remove directory 'test_rm_errors_directory' (did you mean \
|
||||
to pass '-r'?)\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_verbose() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_rm_verbose_file_a";
|
||||
let file_b = "test_rm_verbose_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
ucmd.arg("-v")
|
||||
.arg(file_a)
|
||||
.arg(file_b)
|
||||
.succeeds()
|
||||
.stdout_only(format!("removed '{}'\nremoved '{}'\n", file_a, file_b));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_dir_symlink() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rm_dir_symlink_dir";
|
||||
let link = "test_rm_dir_symlink_link";
|
||||
|
||||
at.mkdir(dir);
|
||||
at.symlink_dir(dir, link);
|
||||
|
||||
ucmd.arg(link).succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_invalid_symlink() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let link = "test_rm_invalid_symlink";
|
||||
|
||||
at.symlink_file(link, link);
|
||||
|
||||
ucmd.arg(link).succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_force_no_operand() {
|
||||
let mut ucmd = new_ucmd!();
|
||||
|
||||
ucmd.arg("-f").succeeds().no_stderr();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rm_no_operand() {
|
||||
let mut ucmd = new_ucmd!();
|
||||
|
||||
ucmd.fails()
|
||||
.stderr_is("rm: error: missing an argument\nrm: error: for help, try 'rm --help'\n");
|
||||
}
|
110
tests/by-util/test_rmdir.rs
Normal file
110
tests/by-util/test_rmdir.rs
Normal file
|
@ -0,0 +1,110 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_rmdir_empty_directory_no_parents() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rmdir_empty_no_parents";
|
||||
|
||||
at.mkdir(dir);
|
||||
assert!(at.dir_exists(dir));
|
||||
|
||||
ucmd.arg(dir).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.dir_exists(dir));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rmdir_empty_directory_with_parents() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rmdir_empty/with/parents";
|
||||
|
||||
at.mkdir_all(dir);
|
||||
assert!(at.dir_exists(dir));
|
||||
|
||||
ucmd.arg("-p").arg(dir).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.dir_exists(dir));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rmdir_nonempty_directory_no_parents() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rmdir_nonempty_no_parents";
|
||||
let file = "test_rmdir_nonempty_no_parents/foo";
|
||||
|
||||
at.mkdir(dir);
|
||||
assert!(at.dir_exists(dir));
|
||||
|
||||
at.touch(file);
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
ucmd.arg(dir).fails().stderr_is(
|
||||
"rmdir: error: failed to remove 'test_rmdir_nonempty_no_parents': Directory not \
|
||||
empty\n",
|
||||
);
|
||||
|
||||
assert!(at.dir_exists(dir));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rmdir_nonempty_directory_with_parents() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rmdir_nonempty/with/parents";
|
||||
let file = "test_rmdir_nonempty/with/parents/foo";
|
||||
|
||||
at.mkdir_all(dir);
|
||||
assert!(at.dir_exists(dir));
|
||||
|
||||
at.touch(file);
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
ucmd.arg("-p").arg(dir).fails().stderr_is(
|
||||
"rmdir: error: failed to remove 'test_rmdir_nonempty/with/parents': Directory not \
|
||||
empty\nrmdir: error: failed to remove 'test_rmdir_nonempty/with': Directory not \
|
||||
empty\nrmdir: error: failed to remove 'test_rmdir_nonempty': Directory not \
|
||||
empty\n",
|
||||
);
|
||||
|
||||
assert!(at.dir_exists(dir));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rmdir_ignore_nonempty_directory_no_parents() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rmdir_ignore_nonempty_no_parents";
|
||||
let file = "test_rmdir_ignore_nonempty_no_parents/foo";
|
||||
|
||||
at.mkdir(dir);
|
||||
assert!(at.dir_exists(dir));
|
||||
|
||||
at.touch(file);
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
ucmd.arg("--ignore-fail-on-non-empty")
|
||||
.arg(dir)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.dir_exists(dir));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rmdir_ignore_nonempty_directory_with_parents() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_rmdir_ignore_nonempty/with/parents";
|
||||
let file = "test_rmdir_ignore_nonempty/with/parents/foo";
|
||||
|
||||
at.mkdir_all(dir);
|
||||
assert!(at.dir_exists(dir));
|
||||
|
||||
at.touch(file);
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
ucmd.arg("--ignore-fail-on-non-empty")
|
||||
.arg("-p")
|
||||
.arg(dir)
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.dir_exists(dir));
|
||||
}
|
33
tests/by-util/test_seq.rs
Normal file
33
tests/by-util/test_seq.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_count_up() {
|
||||
new_ucmd!()
|
||||
.args(&["10"])
|
||||
.run()
|
||||
.stdout_is("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_down() {
|
||||
new_ucmd!()
|
||||
.args(&["--", "5", "-1", "1"])
|
||||
.run()
|
||||
.stdout_is("5\n4\n3\n2\n1\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_separator_and_terminator() {
|
||||
new_ucmd!()
|
||||
.args(&["-s", ",", "-t", "!", "2", "6"])
|
||||
.run()
|
||||
.stdout_is("2,3,4,5,6!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_equalize_widths() {
|
||||
new_ucmd!()
|
||||
.args(&["-w", "5", "10"])
|
||||
.run()
|
||||
.stdout_is("05\n06\n07\n08\n09\n10\n");
|
||||
}
|
142
tests/by-util/test_sort.rs
Normal file
142
tests/by-util/test_sort.rs
Normal file
|
@ -0,0 +1,142 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_numeric_floats_and_ints() {
|
||||
test_helper("numeric_floats_and_ints", "-n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_numeric_floats() {
|
||||
test_helper("numeric_floats", "-n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_numeric_floats_with_nan() {
|
||||
test_helper("numeric_floats_with_nan", "-n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_numeric_unfixed_floats() {
|
||||
test_helper("numeric_unfixed_floats", "-n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_numeric_fixed_floats() {
|
||||
test_helper("numeric_fixed_floats", "-n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_numeric_unsorted_ints() {
|
||||
test_helper("numeric_unsorted_ints", "-n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_human_block_sizes() {
|
||||
test_helper("human_block_sizes", "-h");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_month_default() {
|
||||
test_helper("month_default", "-M");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_month_stable() {
|
||||
test_helper("month_stable", "-Ms");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_unsorted_ints() {
|
||||
test_helper("default_unsorted_ints", "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_numeric_unique_ints() {
|
||||
test_helper("numeric_unsorted_ints_unique", "-nu");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_version() {
|
||||
test_helper("version", "-V");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ignore_case() {
|
||||
test_helper("ignore_case", "-f");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dictionary_order() {
|
||||
test_helper("dictionary_order", "-d");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_files() {
|
||||
new_ucmd!()
|
||||
.arg("-n")
|
||||
.arg("multiple_files1.txt")
|
||||
.arg("multiple_files2.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("multiple_files.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_merge_interleaved() {
|
||||
new_ucmd!()
|
||||
.arg("-m")
|
||||
.arg("merge_ints_interleaved_1.txt")
|
||||
.arg("merge_ints_interleaved_2.txt")
|
||||
.arg("merge_ints_interleaved_3.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("merge_ints_interleaved.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_merge_unique() {
|
||||
new_ucmd!()
|
||||
.arg("-m")
|
||||
.arg("--unique")
|
||||
.arg("merge_ints_interleaved_1.txt")
|
||||
.arg("merge_ints_interleaved_2.txt")
|
||||
.arg("merge_ints_interleaved_3.txt")
|
||||
.arg("merge_ints_interleaved_3.txt")
|
||||
.arg("merge_ints_interleaved_2.txt")
|
||||
.arg("merge_ints_interleaved_1.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("merge_ints_interleaved.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_merge_reversed() {
|
||||
new_ucmd!()
|
||||
.arg("-m")
|
||||
.arg("--reverse")
|
||||
.arg("merge_ints_reversed_1.txt")
|
||||
.arg("merge_ints_reversed_2.txt")
|
||||
.arg("merge_ints_reversed_3.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("merge_ints_reversed.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_check() {
|
||||
new_ucmd!()
|
||||
.arg("-c")
|
||||
.arg("check_fail.txt")
|
||||
.fails()
|
||||
.stdout_is("sort: disorder in line 4\n");
|
||||
|
||||
new_ucmd!()
|
||||
.arg("-c")
|
||||
.arg("multiple_files.expected")
|
||||
.succeeds()
|
||||
.stdout_is("");
|
||||
}
|
||||
|
||||
fn test_helper(file_name: &str, args: &str) {
|
||||
new_ucmd!()
|
||||
.arg(args)
|
||||
.arg(format!("{}{}", file_name, ".txt"))
|
||||
.succeeds()
|
||||
.stdout_is_fixture(format!("{}{}", file_name, ".expected"));
|
||||
}
|
147
tests/by-util/test_split.rs
Normal file
147
tests/by-util/test_split.rs
Normal file
|
@ -0,0 +1,147 @@
|
|||
extern crate rand;
|
||||
extern crate regex;
|
||||
|
||||
use self::rand::{thread_rng, Rng};
|
||||
use self::regex::Regex;
|
||||
use crate::common::util::*;
|
||||
use std::fs::{read_dir, File};
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
fn random_chars(n: usize) -> String {
|
||||
thread_rng()
|
||||
.sample_iter(&rand::distributions::Alphanumeric)
|
||||
.take(n)
|
||||
.collect::<String>()
|
||||
}
|
||||
|
||||
struct Glob {
|
||||
directory: AtPath,
|
||||
regex: Regex,
|
||||
}
|
||||
|
||||
impl Glob {
|
||||
fn new(at: &AtPath, directory: &str, regex: &str) -> Glob {
|
||||
Glob {
|
||||
directory: AtPath::new(Path::new(&at.plus_as_string(directory))),
|
||||
regex: Regex::new(regex).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn count(&self) -> usize {
|
||||
self.collect().len()
|
||||
}
|
||||
|
||||
fn collect(&self) -> Vec<String> {
|
||||
read_dir(Path::new(&self.directory.subdir))
|
||||
.unwrap()
|
||||
.filter_map(|entry| {
|
||||
let path = entry.unwrap().path();
|
||||
let name = self
|
||||
.directory
|
||||
.minus_as_string(path.as_path().to_str().unwrap_or(""));
|
||||
if self.regex.is_match(&name) {
|
||||
Some(name)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn collate(&self) -> Vec<u8> {
|
||||
let mut files = self.collect();
|
||||
files.sort();
|
||||
let mut data: Vec<u8> = vec![];
|
||||
for name in &files {
|
||||
data.extend(self.directory.read(name).into_bytes());
|
||||
}
|
||||
data
|
||||
}
|
||||
}
|
||||
|
||||
struct RandomFile {
|
||||
inner: File,
|
||||
}
|
||||
|
||||
impl RandomFile {
|
||||
fn new(at: &AtPath, name: &str) -> RandomFile {
|
||||
RandomFile {
|
||||
inner: File::create(&at.plus(name)).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_bytes(&mut self, bytes: usize) {
|
||||
let chunk_size: usize = if bytes >= 1024 { 1024 } else { bytes };
|
||||
let mut n = bytes;
|
||||
while n > chunk_size {
|
||||
let _ = write!(self.inner, "{}", random_chars(chunk_size));
|
||||
n -= chunk_size;
|
||||
}
|
||||
let _ = write!(self.inner, "{}", random_chars(n));
|
||||
}
|
||||
|
||||
fn add_lines(&mut self, lines: usize) {
|
||||
let line_size: usize = 32;
|
||||
let mut n = lines;
|
||||
while n > 0 {
|
||||
let _ = writeln!(self.inner, "{}", random_chars(line_size));
|
||||
n -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_default() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_default";
|
||||
let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]]$");
|
||||
RandomFile::new(&at, name).add_lines(2000);
|
||||
ucmd.args(&[name]).succeeds();
|
||||
assert_eq!(glob.count(), 2);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_num_prefixed_chunks_by_bytes() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_num_prefixed_chunks_by_bytes";
|
||||
let glob = Glob::new(&at, ".", r"a\d\d$");
|
||||
RandomFile::new(&at, name).add_bytes(10000);
|
||||
ucmd.args(&["-d", "-b", "1000", name, "a"]).succeeds();
|
||||
assert_eq!(glob.count(), 10);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_str_prefixed_chunks_by_bytes() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_str_prefixed_chunks_by_bytes";
|
||||
let glob = Glob::new(&at, ".", r"b[[:alpha:]][[:alpha:]]$");
|
||||
RandomFile::new(&at, name).add_bytes(10000);
|
||||
ucmd.args(&["-b", "1000", name, "b"]).succeeds();
|
||||
assert_eq!(glob.count(), 10);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_num_prefixed_chunks_by_lines() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_num_prefixed_chunks_by_lines";
|
||||
let glob = Glob::new(&at, ".", r"c\d\d$");
|
||||
RandomFile::new(&at, name).add_lines(10000);
|
||||
ucmd.args(&["-d", "-l", "1000", name, "c"]).succeeds();
|
||||
assert_eq!(glob.count(), 10);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_str_prefixed_chunks_by_lines() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let name = "split_str_prefixed_chunks_by_lines";
|
||||
let glob = Glob::new(&at, ".", r"d[[:alpha:]][[:alpha:]]$");
|
||||
RandomFile::new(&at, name).add_lines(10000);
|
||||
ucmd.args(&["-l", "1000", name, "d"]).succeeds();
|
||||
assert_eq!(glob.count(), 10);
|
||||
assert_eq!(glob.collate(), at.read(name).into_bytes());
|
||||
}
|
341
tests/by-util/test_stat.rs
Normal file
341
tests/by-util/test_stat.rs
Normal file
|
@ -0,0 +1,341 @@
|
|||
extern crate regex;
|
||||
|
||||
use crate::common::util::*;
|
||||
|
||||
extern crate stat;
|
||||
pub use self::stat::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_fsext {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_access() {
|
||||
assert_eq!("drwxr-xr-x", pretty_access(S_IFDIR | 0o755));
|
||||
assert_eq!("-rw-r--r--", pretty_access(S_IFREG | 0o644));
|
||||
assert_eq!("srw-r-----", pretty_access(S_IFSOCK | 0o640));
|
||||
assert_eq!("lrw-r-xr-x", pretty_access(S_IFLNK | 0o655));
|
||||
assert_eq!("?rw-r-xr-x", pretty_access(0o655));
|
||||
|
||||
assert_eq!(
|
||||
"brwSr-xr-x",
|
||||
pretty_access(S_IFBLK | S_ISUID as mode_t | 0o655)
|
||||
);
|
||||
assert_eq!(
|
||||
"brwsr-xr-x",
|
||||
pretty_access(S_IFBLK | S_ISUID as mode_t | 0o755)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"prw---sr--",
|
||||
pretty_access(S_IFIFO | S_ISGID as mode_t | 0o614)
|
||||
);
|
||||
assert_eq!(
|
||||
"prw---Sr--",
|
||||
pretty_access(S_IFIFO | S_ISGID as mode_t | 0o604)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
"c---r-xr-t",
|
||||
pretty_access(S_IFCHR | S_ISVTX as mode_t | 0o055)
|
||||
);
|
||||
assert_eq!(
|
||||
"c---r-xr-T",
|
||||
pretty_access(S_IFCHR | S_ISVTX as mode_t | 0o054)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file_type() {
|
||||
assert_eq!("block special file", pretty_filetype(S_IFBLK, 0));
|
||||
assert_eq!("character special file", pretty_filetype(S_IFCHR, 0));
|
||||
assert_eq!("regular file", pretty_filetype(S_IFREG, 1));
|
||||
assert_eq!("regular empty file", pretty_filetype(S_IFREG, 0));
|
||||
assert_eq!("weird file", pretty_filetype(0, 0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fs_type() {
|
||||
assert_eq!("ext2/ext3", pretty_fstype(0xEF53));
|
||||
assert_eq!("tmpfs", pretty_fstype(0x01021994));
|
||||
assert_eq!("nfs", pretty_fstype(0x6969));
|
||||
assert_eq!("btrfs", pretty_fstype(0x9123683e));
|
||||
assert_eq!("xfs", pretty_fstype(0x58465342));
|
||||
assert_eq!("zfs", pretty_fstype(0x2FC12FC1));
|
||||
assert_eq!("ntfs", pretty_fstype(0x5346544e));
|
||||
assert_eq!("fat", pretty_fstype(0x4006));
|
||||
assert_eq!("UNKNOWN (0x1234)", pretty_fstype(0x1234));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scanutil() {
|
||||
assert_eq!(Some((-5, 2)), "-5zxc".scan_num::<i32>());
|
||||
assert_eq!(Some((51, 2)), "51zxc".scan_num::<u32>());
|
||||
assert_eq!(Some((192, 4)), "+192zxc".scan_num::<i32>());
|
||||
assert_eq!(None, "z192zxc".scan_num::<i32>());
|
||||
|
||||
assert_eq!(Some(('a', 3)), "141zxc".scan_char(8));
|
||||
assert_eq!(Some(('\n', 2)), "12qzxc".scan_char(8));
|
||||
assert_eq!(Some(('\r', 1)), "dqzxc".scan_char(16));
|
||||
assert_eq!(None, "z2qzxc".scan_char(8));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groupnum() {
|
||||
assert_eq!("12,379,821,234", group_num("12379821234"));
|
||||
assert_eq!("21,234", group_num("21234"));
|
||||
assert_eq!("821,234", group_num("821234"));
|
||||
assert_eq!("1,821,234", group_num("1821234"));
|
||||
assert_eq!("1,234", group_num("1234"));
|
||||
assert_eq!("234", group_num("234"));
|
||||
assert_eq!("24", group_num("24"));
|
||||
assert_eq!("4", group_num("4"));
|
||||
assert_eq!("", group_num(""));
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_generate_tokens {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn normal_format() {
|
||||
let s = "%'010.2ac%-#5.w\n";
|
||||
let expected = vec![
|
||||
Token::Directive {
|
||||
flag: F_GROUP | F_ZERO,
|
||||
width: 10,
|
||||
precision: 2,
|
||||
format: 'a',
|
||||
},
|
||||
Token::Char('c'),
|
||||
Token::Directive {
|
||||
flag: F_LEFT | F_ALTER,
|
||||
width: 5,
|
||||
precision: 0,
|
||||
format: 'w',
|
||||
},
|
||||
Token::Char('\n'),
|
||||
];
|
||||
assert_eq!(&expected, &Stater::generate_tokens(s, false).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn printf_format() {
|
||||
let s = "%-# 15a\\r\\\"\\\\\\a\\b\\e\\f\\v%+020.-23w\\x12\\167\\132\\112\\n";
|
||||
let expected = vec![
|
||||
Token::Directive {
|
||||
flag: F_LEFT | F_ALTER | F_SPACE,
|
||||
width: 15,
|
||||
precision: -1,
|
||||
format: 'a',
|
||||
},
|
||||
Token::Char('\r'),
|
||||
Token::Char('"'),
|
||||
Token::Char('\\'),
|
||||
Token::Char('\x07'),
|
||||
Token::Char('\x08'),
|
||||
Token::Char('\x1B'),
|
||||
Token::Char('\x0C'),
|
||||
Token::Char('\x0B'),
|
||||
Token::Directive {
|
||||
flag: F_SIGN | F_ZERO,
|
||||
width: 20,
|
||||
precision: -1,
|
||||
format: 'w',
|
||||
},
|
||||
Token::Char('\x12'),
|
||||
Token::Char('w'),
|
||||
Token::Char('Z'),
|
||||
Token::Char('J'),
|
||||
Token::Char('\n'),
|
||||
];
|
||||
assert_eq!(&expected, &Stater::generate_tokens(s, true).unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_option() {
|
||||
new_ucmd!().arg("-w").arg("-q").arg("/").fails();
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
const NORMAL_FMTSTR: &'static str =
|
||||
"%a %A %b %B %d %D %f %F %g %G %h %i %m %n %o %s %u %U %x %X %y %Y %z %Z"; // avoid "%w %W" (birth/creation) due to `stat` limitations and linux kernel & rust version capability variations
|
||||
#[cfg(target_os = "linux")]
|
||||
const DEV_FMTSTR: &'static str =
|
||||
"%a %A %b %B %d %D %f %F %g %G %h %i %m %n %o %s (%t/%T) %u %U %w %W %x %X %y %Y %z %Z";
|
||||
#[cfg(target_os = "linux")]
|
||||
const FS_FMTSTR: &'static str = "%b %c %i %l %n %s %S %t %T"; // avoid "%a %d %f" which can cause test failure due to race conditions
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_terse_fs_format() {
|
||||
let args = ["-f", "-t", "/proc"];
|
||||
new_ucmd!()
|
||||
.args(&args)
|
||||
.run()
|
||||
.stdout_is(expected_result(&args));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_fs_format() {
|
||||
let args = ["-f", "-c", FS_FMTSTR, "/dev/shm"];
|
||||
new_ucmd!()
|
||||
.args(&args)
|
||||
.run()
|
||||
.stdout_is(expected_result(&args));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_terse_normal_format() {
|
||||
// note: contains birth/creation date which increases test fragility
|
||||
// * results may vary due to built-in `stat` limitations as well as linux kernel and rust version capability variations
|
||||
let args = ["-t", "/"];
|
||||
let actual = new_ucmd!().args(&args).run().stdout;
|
||||
let expect = expected_result(&args);
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
let v_actual: Vec<&str> = actual.split(' ').collect();
|
||||
let v_expect: Vec<&str> = expect.split(' ').collect();
|
||||
assert!(!v_expect.is_empty());
|
||||
// * allow for inequality if `stat` (aka, expect) returns "0" (unknown value)
|
||||
assert!(
|
||||
expect == "0"
|
||||
|| expect == "0\n"
|
||||
|| v_actual
|
||||
.iter()
|
||||
.zip(v_expect.iter())
|
||||
.all(|(a, e)| a == e || *e == "0" || *e == "0\n")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_format_created_time() {
|
||||
let args = ["-c", "%w", "/boot"];
|
||||
let actual = new_ucmd!().args(&args).run().stdout;
|
||||
let expect = expected_result(&args);
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
// note: using a regex instead of `split_whitespace()` in order to detect whitespace differences
|
||||
let re = regex::Regex::new(r"\s").unwrap();
|
||||
let v_actual: Vec<&str> = re.split(&actual).collect();
|
||||
let v_expect: Vec<&str> = re.split(&expect).collect();
|
||||
assert!(!v_expect.is_empty());
|
||||
// * allow for inequality if `stat` (aka, expect) returns "-" (unknown value)
|
||||
assert!(
|
||||
expect == "-"
|
||||
|| expect == "-\n"
|
||||
|| v_actual
|
||||
.iter()
|
||||
.zip(v_expect.iter())
|
||||
.all(|(a, e)| a == e || *e == "-" || *e == "-\n")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_format_created_seconds() {
|
||||
let args = ["-c", "%W", "/boot"];
|
||||
let actual = new_ucmd!().args(&args).run().stdout;
|
||||
let expect = expected_result(&args);
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
// note: using a regex instead of `split_whitespace()` in order to detect whitespace differences
|
||||
let re = regex::Regex::new(r"\s").unwrap();
|
||||
let v_actual: Vec<&str> = re.split(&actual).collect();
|
||||
let v_expect: Vec<&str> = re.split(&expect).collect();
|
||||
assert!(!v_expect.is_empty());
|
||||
// * allow for inequality if `stat` (aka, expect) returns "0" (unknown value)
|
||||
assert!(
|
||||
expect == "0"
|
||||
|| expect == "0\n"
|
||||
|| v_actual
|
||||
.iter()
|
||||
.zip(v_expect.iter())
|
||||
.all(|(a, e)| a == e || *e == "0" || *e == "0\n")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_normal_format() {
|
||||
let args = ["-c", NORMAL_FMTSTR, "/boot"];
|
||||
new_ucmd!()
|
||||
.args(&args)
|
||||
.run()
|
||||
.stdout_is(expected_result(&args));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_follow_symlink() {
|
||||
let args = ["-L", "-c", DEV_FMTSTR, "/dev/cdrom"];
|
||||
new_ucmd!()
|
||||
.args(&args)
|
||||
.run()
|
||||
.stdout_is(expected_result(&args));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_symlink() {
|
||||
let args = ["-c", DEV_FMTSTR, "/dev/cdrom"];
|
||||
new_ucmd!()
|
||||
.args(&args)
|
||||
.run()
|
||||
.stdout_is(expected_result(&args));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_char() {
|
||||
let args = ["-c", DEV_FMTSTR, "/dev/pts/ptmx"];
|
||||
new_ucmd!()
|
||||
.args(&args)
|
||||
.run()
|
||||
.stdout_is(expected_result(&args));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_multi_files() {
|
||||
let args = [
|
||||
"-c",
|
||||
NORMAL_FMTSTR,
|
||||
"/dev",
|
||||
"/usr/lib",
|
||||
"/etc/fstab",
|
||||
"/var",
|
||||
];
|
||||
new_ucmd!()
|
||||
.args(&args)
|
||||
.run()
|
||||
.stdout_is(expected_result(&args));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_os = "linux")]
|
||||
fn test_printf() {
|
||||
let args = [
|
||||
"--printf=123%-# 15q\\r\\\"\\\\\\a\\b\\e\\f\\v%+020.23m\\x12\\167\\132\\112\\n",
|
||||
"/",
|
||||
];
|
||||
new_ucmd!()
|
||||
.args(&args)
|
||||
.run()
|
||||
.stdout_is(expected_result(&args));
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn expected_result(args: &[&str]) -> String {
|
||||
TestScenario::new(util_name!())
|
||||
.cmd_keepenv(util_name!())
|
||||
.env("LANGUAGE", "C")
|
||||
.args(args)
|
||||
.run()
|
||||
.stdout
|
||||
}
|
13
tests/by-util/test_stdbuf.rs
Normal file
13
tests/by-util/test_stdbuf.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_stdbuf_unbuffered_stdout() {
|
||||
if cfg!(target_os = "linux") {
|
||||
// This is a basic smoke test
|
||||
new_ucmd!()
|
||||
.args(&["-o0", "head"])
|
||||
.pipe_in("The quick brown fox jumps over the lazy dog.")
|
||||
.run()
|
||||
.stdout_is("The quick brown fox jumps over the lazy dog.");
|
||||
}
|
||||
}
|
54
tests/by-util/test_sum.rs
Normal file
54
tests/by-util/test_sum.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_bsd_single_file() {
|
||||
new_ucmd!()
|
||||
.arg("lorem_ipsum.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("bsd_single_file.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bsd_multiple_files() {
|
||||
new_ucmd!()
|
||||
.arg("lorem_ipsum.txt")
|
||||
.arg("alice_in_wonderland.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("bsd_multiple_files.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bsd_stdin() {
|
||||
new_ucmd!()
|
||||
.pipe_in_fixture("lorem_ipsum.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("bsd_stdin.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sysv_single_file() {
|
||||
new_ucmd!()
|
||||
.arg("-s")
|
||||
.arg("lorem_ipsum.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("sysv_single_file.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sysv_multiple_files() {
|
||||
new_ucmd!()
|
||||
.arg("-s")
|
||||
.arg("lorem_ipsum.txt")
|
||||
.arg("alice_in_wonderland.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("sysv_multiple_files.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sysv_stdin() {
|
||||
new_ucmd!()
|
||||
.arg("-s")
|
||||
.pipe_in_fixture("lorem_ipsum.txt")
|
||||
.succeeds()
|
||||
.stdout_only_fixture("sysv_stdin.expected");
|
||||
}
|
51
tests/by-util/test_tac.rs
Normal file
51
tests/by-util/test_tac.rs
Normal file
|
@ -0,0 +1,51 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_stdin_default() {
|
||||
new_ucmd!()
|
||||
.pipe_in("100\n200\n300\n400\n500")
|
||||
.run()
|
||||
.stdout_is("500400\n300\n200\n100\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_non_newline_separator() {
|
||||
new_ucmd!()
|
||||
.args(&["-s", ":"])
|
||||
.pipe_in("100:200:300:400:500")
|
||||
.run()
|
||||
.stdout_is("500400:300:200:100:");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_non_newline_separator_before() {
|
||||
new_ucmd!()
|
||||
.args(&["-b", "-s", ":"])
|
||||
.pipe_in("100:200:300:400:500")
|
||||
.run()
|
||||
.stdout_is("500:400:300:200:100");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_default() {
|
||||
new_ucmd!()
|
||||
.arg("prime_per_line.txt")
|
||||
.run()
|
||||
.stdout_is_fixture("prime_per_line.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_non_newline_separator() {
|
||||
new_ucmd!()
|
||||
.args(&["-s", ":", "delimited_primes.txt"])
|
||||
.run()
|
||||
.stdout_is_fixture("delimited_primes.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_non_newline_separator_before() {
|
||||
new_ucmd!()
|
||||
.args(&["-b", "-s", ":", "delimited_primes.txt"])
|
||||
.run()
|
||||
.stdout_is_fixture("delimited_primes_before.expected");
|
||||
}
|
328
tests/by-util/test_tail.rs
Normal file
328
tests/by-util/test_tail.rs
Normal file
|
@ -0,0 +1,328 @@
|
|||
extern crate tail;
|
||||
|
||||
use self::tail::parse_size;
|
||||
use crate::common::util::*;
|
||||
use std::char::from_digit;
|
||||
use std::io::Write;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
static FOOBAR_TXT: &'static str = "foobar.txt";
|
||||
static FOOBAR_2_TXT: &'static str = "foobar2.txt";
|
||||
static FOOBAR_WITH_NULL_TXT: &'static str = "foobar_with_null.txt";
|
||||
|
||||
#[test]
|
||||
fn test_stdin_default() {
|
||||
new_ucmd!()
|
||||
.pipe_in_fixture(FOOBAR_TXT)
|
||||
.run()
|
||||
.stdout_is_fixture("foobar_stdin_default.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_default() {
|
||||
new_ucmd!()
|
||||
.arg(FOOBAR_TXT)
|
||||
.run()
|
||||
.stdout_is_fixture("foobar_single_default.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_n_greater_than_number_of_lines() {
|
||||
new_ucmd!()
|
||||
.arg("-n")
|
||||
.arg("99999999")
|
||||
.arg(FOOBAR_TXT)
|
||||
.run()
|
||||
.stdout_is_fixture(FOOBAR_TXT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_null_default() {
|
||||
new_ucmd!()
|
||||
.arg("-z")
|
||||
.arg(FOOBAR_WITH_NULL_TXT)
|
||||
.run()
|
||||
.stdout_is_fixture("foobar_with_null_default.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_follow() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let mut child = ucmd.arg("-f").arg(FOOBAR_TXT).run_no_wait();
|
||||
|
||||
let expected = at.read("foobar_single_default.expected");
|
||||
assert_eq!(read_size(&mut child, expected.len()), expected);
|
||||
|
||||
// We write in a temporary copy of foobar.txt
|
||||
let expected = "line1\nline2\n";
|
||||
at.append(FOOBAR_TXT, expected);
|
||||
|
||||
assert_eq!(read_size(&mut child, expected.len()), expected);
|
||||
|
||||
child.kill().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_follow_multiple() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let mut child = ucmd
|
||||
.arg("-f")
|
||||
.arg(FOOBAR_TXT)
|
||||
.arg(FOOBAR_2_TXT)
|
||||
.run_no_wait();
|
||||
|
||||
let expected = at.read("foobar_follow_multiple.expected");
|
||||
assert_eq!(read_size(&mut child, expected.len()), expected);
|
||||
|
||||
let first_append = "trois\n";
|
||||
at.append(FOOBAR_2_TXT, first_append);
|
||||
assert_eq!(read_size(&mut child, first_append.len()), first_append);
|
||||
|
||||
let second_append = "doce\ntrece\n";
|
||||
let expected = at.read("foobar_follow_multiple_appended.expected");
|
||||
at.append(FOOBAR_TXT, second_append);
|
||||
assert_eq!(read_size(&mut child, expected.len()), expected);
|
||||
|
||||
child.kill().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_follow_stdin() {
|
||||
new_ucmd!()
|
||||
.arg("-f")
|
||||
.pipe_in_fixture(FOOBAR_TXT)
|
||||
.run()
|
||||
.stdout_is_fixture("follow_stdin.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_follow_with_pid() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
#[cfg(unix)]
|
||||
let dummy_cmd = "sh";
|
||||
#[cfg(windows)]
|
||||
let dummy_cmd = "cmd";
|
||||
|
||||
let mut dummy = Command::new(dummy_cmd)
|
||||
.stdout(Stdio::null())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
let pid = dummy.id();
|
||||
|
||||
let mut child = ucmd
|
||||
.arg("-f")
|
||||
.arg(format!("--pid={}", pid))
|
||||
.arg(FOOBAR_TXT)
|
||||
.arg(FOOBAR_2_TXT)
|
||||
.run_no_wait();
|
||||
|
||||
let expected = at.read("foobar_follow_multiple.expected");
|
||||
assert_eq!(read_size(&mut child, expected.len()), expected);
|
||||
|
||||
let first_append = "trois\n";
|
||||
at.append(FOOBAR_2_TXT, first_append);
|
||||
assert_eq!(read_size(&mut child, first_append.len()), first_append);
|
||||
|
||||
let second_append = "doce\ntrece\n";
|
||||
let expected = at.read("foobar_follow_multiple_appended.expected");
|
||||
at.append(FOOBAR_TXT, second_append);
|
||||
assert_eq!(read_size(&mut child, expected.len()), expected);
|
||||
|
||||
// kill the dummy process and give tail time to notice this
|
||||
dummy.kill().unwrap();
|
||||
let _ = dummy.wait();
|
||||
sleep(Duration::from_secs(1));
|
||||
|
||||
let third_append = "should\nbe\nignored\n";
|
||||
at.append(FOOBAR_TXT, third_append);
|
||||
assert_eq!(read_size(&mut child, 1), "\u{0}");
|
||||
|
||||
// On Unix, trying to kill a process that's already dead is fine; on Windows it's an error.
|
||||
#[cfg(unix)]
|
||||
child.kill().unwrap();
|
||||
#[cfg(windows)]
|
||||
assert_eq!(child.kill().is_err(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_big_args() {
|
||||
const FILE: &'static str = "single_big_args.txt";
|
||||
const EXPECTED_FILE: &'static str = "single_big_args_expected.txt";
|
||||
const LINES: usize = 1_000_000;
|
||||
const N_ARG: usize = 100_000;
|
||||
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let mut big_input = at.make_file(FILE);
|
||||
for i in 0..LINES {
|
||||
write!(&mut big_input, "Line {}\n", i).expect("Could not write to FILE");
|
||||
}
|
||||
big_input.flush().expect("Could not flush FILE");
|
||||
|
||||
let mut big_expected = at.make_file(EXPECTED_FILE);
|
||||
for i in (LINES - N_ARG)..LINES {
|
||||
write!(&mut big_expected, "Line {}\n", i).expect("Could not write to EXPECTED_FILE");
|
||||
}
|
||||
big_expected.flush().expect("Could not flush EXPECTED_FILE");
|
||||
|
||||
ucmd.arg(FILE)
|
||||
.arg("-n")
|
||||
.arg(format!("{}", N_ARG))
|
||||
.run()
|
||||
.stdout_is(at.read(EXPECTED_FILE));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytes_single() {
|
||||
new_ucmd!()
|
||||
.arg("-c")
|
||||
.arg("10")
|
||||
.arg(FOOBAR_TXT)
|
||||
.run()
|
||||
.stdout_is_fixture("foobar_bytes_single.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytes_stdin() {
|
||||
new_ucmd!()
|
||||
.arg("-c")
|
||||
.arg("13")
|
||||
.pipe_in_fixture(FOOBAR_TXT)
|
||||
.run()
|
||||
.stdout_is_fixture("foobar_bytes_stdin.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bytes_big() {
|
||||
const FILE: &'static str = "test_bytes_big.txt";
|
||||
const EXPECTED_FILE: &'static str = "test_bytes_big_expected.txt";
|
||||
const BYTES: usize = 1_000_000;
|
||||
const N_ARG: usize = 100_000;
|
||||
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let mut big_input = at.make_file(FILE);
|
||||
for i in 0..BYTES {
|
||||
let digit = from_digit((i % 10) as u32, 10).unwrap();
|
||||
write!(&mut big_input, "{}", digit).expect("Could not write to FILE");
|
||||
}
|
||||
big_input.flush().expect("Could not flush FILE");
|
||||
|
||||
let mut big_expected = at.make_file(EXPECTED_FILE);
|
||||
for i in (BYTES - N_ARG)..BYTES {
|
||||
let digit = from_digit((i % 10) as u32, 10).unwrap();
|
||||
write!(&mut big_expected, "{}", digit).expect("Could not write to EXPECTED_FILE");
|
||||
}
|
||||
big_expected.flush().expect("Could not flush EXPECTED_FILE");
|
||||
|
||||
let result = ucmd
|
||||
.arg(FILE)
|
||||
.arg("-c")
|
||||
.arg(format!("{}", N_ARG))
|
||||
.run()
|
||||
.stdout;
|
||||
let expected = at.read(EXPECTED_FILE);
|
||||
|
||||
assert_eq!(result.len(), expected.len());
|
||||
for (actual_char, expected_char) in result.chars().zip(expected.chars()) {
|
||||
assert_eq!(actual_char, expected_char);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_size() {
|
||||
// No suffix.
|
||||
assert_eq!(Ok(1234), parse_size("1234"));
|
||||
|
||||
// kB is 1000
|
||||
assert_eq!(Ok(9 * 1000), parse_size("9kB"));
|
||||
|
||||
// K is 1024
|
||||
assert_eq!(Ok(2 * 1024), parse_size("2K"));
|
||||
|
||||
let suffixes = [
|
||||
('M', 2u32),
|
||||
('G', 3u32),
|
||||
('T', 4u32),
|
||||
('P', 5u32),
|
||||
('E', 6u32),
|
||||
];
|
||||
|
||||
for &(c, exp) in &suffixes {
|
||||
let s = format!("2{}B", c);
|
||||
assert_eq!(Ok(2 * (1000 as u64).pow(exp)), parse_size(&s));
|
||||
|
||||
let s = format!("2{}", c);
|
||||
assert_eq!(Ok(2 * (1024 as u64).pow(exp)), parse_size(&s));
|
||||
}
|
||||
|
||||
// Sizes that are too big.
|
||||
assert!(parse_size("1Z").is_err());
|
||||
assert!(parse_size("1Y").is_err());
|
||||
|
||||
// Bad number
|
||||
assert!(parse_size("328hdsf3290").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lines_with_size_suffix() {
|
||||
const FILE: &'static str = "test_lines_with_size_suffix.txt";
|
||||
const EXPECTED_FILE: &'static str = "test_lines_with_size_suffix_expected.txt";
|
||||
const LINES: usize = 3_000;
|
||||
const N_ARG: usize = 2 * 1024;
|
||||
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let mut big_input = at.make_file(FILE);
|
||||
for i in 0..LINES {
|
||||
writeln!(&mut big_input, "Line {}", i).expect("Could not write to FILE");
|
||||
}
|
||||
big_input.flush().expect("Could not flush FILE");
|
||||
|
||||
let mut big_expected = at.make_file(EXPECTED_FILE);
|
||||
for i in (LINES - N_ARG)..LINES {
|
||||
writeln!(&mut big_expected, "Line {}", i).expect("Could not write to EXPECTED_FILE");
|
||||
}
|
||||
big_expected.flush().expect("Could not flush EXPECTED_FILE");
|
||||
|
||||
ucmd.arg(FILE)
|
||||
.arg("-n")
|
||||
.arg("2K")
|
||||
.run()
|
||||
.stdout_is_fixture(EXPECTED_FILE);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_input_files() {
|
||||
new_ucmd!()
|
||||
.arg(FOOBAR_TXT)
|
||||
.arg(FOOBAR_2_TXT)
|
||||
.run()
|
||||
.stdout_is_fixture("foobar_follow_multiple.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_input_files_with_suppressed_headers() {
|
||||
new_ucmd!()
|
||||
.arg(FOOBAR_TXT)
|
||||
.arg(FOOBAR_2_TXT)
|
||||
.arg("-q")
|
||||
.run()
|
||||
.stdout_is_fixture("foobar_multiple_quiet.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_input_quiet_flag_overrides_verbose_flag_for_suppressing_headers() {
|
||||
// TODO: actually the later one should win, i.e. -qv should lead to headers being printed, -vq to them being suppressed
|
||||
new_ucmd!()
|
||||
.arg(FOOBAR_TXT)
|
||||
.arg(FOOBAR_2_TXT)
|
||||
.arg("-q")
|
||||
.arg("-v")
|
||||
.run()
|
||||
.stdout_is_fixture("foobar_multiple_quiet.expected");
|
||||
}
|
27
tests/by-util/test_test.rs
Normal file
27
tests/by-util/test_test.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// This file is part of the uutils coreutils package.
|
||||
//
|
||||
// (c) mahkoh (ju.orth [at] gmail [dot] com)
|
||||
//
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
//
|
||||
|
||||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_op_prec_and_or_1() {
|
||||
new_ucmd!().args(&[" ", "-o", "", "-a", ""]).succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_op_prec_and_or_2() {
|
||||
new_ucmd!()
|
||||
.args(&["", "-a", "", "-o", " ", "-a", " "])
|
||||
.succeeds();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or_as_filename() {
|
||||
new_ucmd!().args(&["x", "-a", "-z", "-o"]).fails();
|
||||
}
|
299
tests/by-util/test_touch.rs
Normal file
299
tests/by-util/test_touch.rs
Normal file
|
@ -0,0 +1,299 @@
|
|||
extern crate touch;
|
||||
use self::touch::filetime::{self, FileTime};
|
||||
|
||||
extern crate time;
|
||||
|
||||
use crate::common::util::*;
|
||||
|
||||
fn get_file_times(at: &AtPath, path: &str) -> (FileTime, FileTime) {
|
||||
let m = at.metadata(path);
|
||||
(
|
||||
FileTime::from_last_access_time(&m),
|
||||
FileTime::from_last_modification_time(&m),
|
||||
)
|
||||
}
|
||||
|
||||
fn get_symlink_times(at: &AtPath, path: &str) -> (FileTime, FileTime) {
|
||||
let m = at.symlink_metadata(path);
|
||||
(
|
||||
FileTime::from_last_access_time(&m),
|
||||
FileTime::from_last_modification_time(&m),
|
||||
)
|
||||
}
|
||||
|
||||
fn set_file_times(at: &AtPath, path: &str, atime: FileTime, mtime: FileTime) {
|
||||
filetime::set_file_times(&at.plus_as_string(path), atime, mtime).unwrap()
|
||||
}
|
||||
|
||||
// Adjusts for local timezone
|
||||
fn str_to_filetime(format: &str, s: &str) -> FileTime {
|
||||
let mut tm = time::strptime(s, format).unwrap();
|
||||
tm.tm_utcoff = time::now().tm_utcoff;
|
||||
let ts = tm.to_timespec();
|
||||
FileTime::from_unix_time(ts.sec as i64, ts.nsec as u32)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_default() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_default_file";
|
||||
|
||||
ucmd.arg(file).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_no_create_file_absent() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_no_create_file_absent";
|
||||
|
||||
ucmd.arg("-c").arg(file).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_no_create_file_exists() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_no_create_file_exists";
|
||||
|
||||
at.touch(file);
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
ucmd.arg("-c").arg(file).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_set_mdhm_time() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_mdhm_time";
|
||||
|
||||
ucmd.args(&["-t", "01011234", file]).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
let start_of_year = str_to_filetime(
|
||||
"%Y%m%d%H%M",
|
||||
&format!("{}01010000", 1900 + time::now().tm_year),
|
||||
);
|
||||
let (atime, mtime) = get_file_times(&at, file);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime.unix_seconds() - start_of_year.unix_seconds(), 45240);
|
||||
assert_eq!(mtime.unix_seconds() - start_of_year.unix_seconds(), 45240);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_set_mdhms_time() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_mdhms_time";
|
||||
|
||||
ucmd.args(&["-t", "01011234.56", file])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
let start_of_year = str_to_filetime(
|
||||
"%Y%m%d%H%M.%S",
|
||||
&format!("{}01010000.00", 1900 + time::now().tm_year),
|
||||
);
|
||||
let (atime, mtime) = get_file_times(&at, file);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime.unix_seconds() - start_of_year.unix_seconds(), 45296);
|
||||
assert_eq!(mtime.unix_seconds() - start_of_year.unix_seconds(), 45296);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_set_ymdhm_time() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_ymdhm_time";
|
||||
|
||||
ucmd.args(&["-t", "1501011234", file])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
let start_of_year = str_to_filetime("%y%m%d%H%M", "1501010000");
|
||||
let (atime, mtime) = get_file_times(&at, file);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime.unix_seconds() - start_of_year.unix_seconds(), 45240);
|
||||
assert_eq!(mtime.unix_seconds() - start_of_year.unix_seconds(), 45240);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_set_ymdhms_time() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_ymdhms_time";
|
||||
|
||||
ucmd.args(&["-t", "1501011234.56", file])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
let start_of_year = str_to_filetime("%y%m%d%H%M.%S", "1501010000.00");
|
||||
let (atime, mtime) = get_file_times(&at, file);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime.unix_seconds() - start_of_year.unix_seconds(), 45296);
|
||||
assert_eq!(mtime.unix_seconds() - start_of_year.unix_seconds(), 45296);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_set_cymdhm_time() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_cymdhm_time";
|
||||
|
||||
ucmd.args(&["-t", "201501011234", file])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000");
|
||||
let (atime, mtime) = get_file_times(&at, file);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime.unix_seconds() - start_of_year.unix_seconds(), 45240);
|
||||
assert_eq!(mtime.unix_seconds() - start_of_year.unix_seconds(), 45240);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_set_cymdhms_time() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_cymdhms_time";
|
||||
|
||||
ucmd.args(&["-t", "201501011234.56", file])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
let start_of_year = str_to_filetime("%Y%m%d%H%M.%S", "201501010000.00");
|
||||
let (atime, mtime) = get_file_times(&at, file);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime.unix_seconds() - start_of_year.unix_seconds(), 45296);
|
||||
assert_eq!(mtime.unix_seconds() - start_of_year.unix_seconds(), 45296);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_set_only_atime() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_only_atime";
|
||||
|
||||
ucmd.args(&["-t", "201501011234", "-a", file])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000");
|
||||
let (atime, mtime) = get_file_times(&at, file);
|
||||
assert!(atime != mtime);
|
||||
assert_eq!(atime.unix_seconds() - start_of_year.unix_seconds(), 45240);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_set_only_mtime() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_only_mtime";
|
||||
|
||||
ucmd.args(&["-t", "201501011234", "-m", file])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000");
|
||||
let (atime, mtime) = get_file_times(&at, file);
|
||||
assert!(atime != mtime);
|
||||
assert_eq!(mtime.unix_seconds() - start_of_year.unix_seconds(), 45240);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_set_both() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_both";
|
||||
|
||||
ucmd.args(&["-t", "201501011234", "-a", "-m", file])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000");
|
||||
let (atime, mtime) = get_file_times(&at, file);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime.unix_seconds() - start_of_year.unix_seconds(), 45240);
|
||||
assert_eq!(mtime.unix_seconds() - start_of_year.unix_seconds(), 45240);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_no_dereference() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_touch_no_dereference_a";
|
||||
let file_b = "test_touch_no_dereference_b";
|
||||
let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000");
|
||||
let end_of_year = str_to_filetime("%Y%m%d%H%M", "201512312359");
|
||||
|
||||
at.touch(file_a);
|
||||
set_file_times(&at, file_a, start_of_year, start_of_year);
|
||||
at.symlink_file(file_a, file_b);
|
||||
assert!(at.file_exists(file_a));
|
||||
assert!(at.is_symlink(file_b));
|
||||
|
||||
ucmd.args(&["-t", "201512312359", "-h", file_b])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
let (atime, mtime) = get_symlink_times(&at, file_b);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime, end_of_year);
|
||||
assert_eq!(mtime, end_of_year);
|
||||
|
||||
let (atime, mtime) = get_file_times(&at, file_a);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime, start_of_year);
|
||||
assert_eq!(mtime, start_of_year);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_reference() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_touch_reference_a";
|
||||
let file_b = "test_touch_reference_b";
|
||||
let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501010000");
|
||||
|
||||
at.touch(file_a);
|
||||
set_file_times(&at, file_a, start_of_year, start_of_year);
|
||||
assert!(at.file_exists(file_a));
|
||||
|
||||
ucmd.args(&["-r", file_a, file_b]).succeeds().no_stderr();
|
||||
|
||||
assert!(at.file_exists(file_b));
|
||||
|
||||
let (atime, mtime) = get_file_times(&at, file_b);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime, start_of_year);
|
||||
assert_eq!(mtime, start_of_year);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_touch_set_date() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_touch_set_date";
|
||||
|
||||
ucmd.args(&["-d", "Thu Jan 01 12:34:00 2015", file])
|
||||
.succeeds()
|
||||
.no_stderr();
|
||||
|
||||
assert!(at.file_exists(file));
|
||||
|
||||
let start_of_year = str_to_filetime("%Y%m%d%H%M", "201501011234");
|
||||
let (atime, mtime) = get_file_times(&at, file);
|
||||
assert_eq!(atime, mtime);
|
||||
assert_eq!(atime, start_of_year);
|
||||
assert_eq!(mtime, start_of_year);
|
||||
}
|
118
tests/by-util/test_tr.rs
Normal file
118
tests/by-util/test_tr.rs
Normal file
|
@ -0,0 +1,118 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_toupper() {
|
||||
new_ucmd!()
|
||||
.args(&["a-z", "A-Z"])
|
||||
.pipe_in("!abcd!")
|
||||
.run()
|
||||
.stdout_is("!ABCD!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_small_set2() {
|
||||
new_ucmd!()
|
||||
.args(&["0-9", "X"])
|
||||
.pipe_in("@0123456789")
|
||||
.run()
|
||||
.stdout_is("@XXXXXXXXXX");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unicode() {
|
||||
new_ucmd!()
|
||||
.args(&[", ┬─┬", "╯︵┻━┻"])
|
||||
.pipe_in("(,°□°), ┬─┬")
|
||||
.run()
|
||||
.stdout_is("(╯°□°)╯︵┻━┻");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete() {
|
||||
new_ucmd!()
|
||||
.args(&["-d", "a-z"])
|
||||
.pipe_in("aBcD")
|
||||
.run()
|
||||
.stdout_is("BD");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_complement() {
|
||||
new_ucmd!()
|
||||
.args(&["-d", "-c", "a-z"])
|
||||
.pipe_in("aBcD")
|
||||
.run()
|
||||
.stdout_is("ac");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_squeeze() {
|
||||
new_ucmd!()
|
||||
.args(&["-s", "a-z"])
|
||||
.pipe_in("aaBBcDcc")
|
||||
.run()
|
||||
.stdout_is("aBBcDc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_squeeze_complement() {
|
||||
new_ucmd!()
|
||||
.args(&["-sc", "a-z"])
|
||||
.pipe_in("aaBBcDcc")
|
||||
.run()
|
||||
.stdout_is("aaBcDcc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_and_squeeze() {
|
||||
new_ucmd!()
|
||||
.args(&["-ds", "a-z", "A-Z"])
|
||||
.pipe_in("abBcB")
|
||||
.run()
|
||||
.stdout_is("B");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_and_squeeze_complement() {
|
||||
new_ucmd!()
|
||||
.args(&["-dsc", "a-z", "A-Z"])
|
||||
.pipe_in("abBcB")
|
||||
.run()
|
||||
.stdout_is("abc");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set1_longer_than_set2() {
|
||||
new_ucmd!()
|
||||
.args(&["abc", "xy"])
|
||||
.pipe_in("abcde")
|
||||
.run()
|
||||
.stdout_is("xyyde");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set1_shorter_than_set2() {
|
||||
new_ucmd!()
|
||||
.args(&["ab", "xyz"])
|
||||
.pipe_in("abcde")
|
||||
.run()
|
||||
.stdout_is("xycde");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate() {
|
||||
new_ucmd!()
|
||||
.args(&["-t", "abc", "xy"])
|
||||
.pipe_in("abcde")
|
||||
.run()
|
||||
.stdout_is("xycde");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_with_set1_shorter_than_set2() {
|
||||
new_ucmd!()
|
||||
.args(&["-t", "ab", "xyz"])
|
||||
.pipe_in("abcde")
|
||||
.run()
|
||||
.stdout_is("xycde");
|
||||
}
|
6
tests/by-util/test_true.rs
Normal file
6
tests/by-util/test_true.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_exit_code() {
|
||||
new_ucmd!().succeeds();
|
||||
}
|
25
tests/by-util/test_truncate.rs
Normal file
25
tests/by-util/test_truncate.rs
Normal file
|
@ -0,0 +1,25 @@
|
|||
use crate::common::util::*;
|
||||
use std::io::{Seek, SeekFrom, Write};
|
||||
|
||||
static TFILE1: &'static str = "truncate_test_1";
|
||||
static TFILE2: &'static str = "truncate_test_2";
|
||||
|
||||
#[test]
|
||||
fn test_increase_file_size() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let mut file = at.make_file(TFILE1);
|
||||
ucmd.args(&["-s", "+5K", TFILE1]).succeeds();
|
||||
|
||||
file.seek(SeekFrom::End(0)).unwrap();
|
||||
assert!(file.seek(SeekFrom::Current(0)).unwrap() == 5 * 1024);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decrease_file_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() == 6);
|
||||
}
|
17
tests/by-util/test_tsort.rs
Normal file
17
tests/by-util/test_tsort.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_sort_call_graph() {
|
||||
new_ucmd!()
|
||||
.arg("call_graph.txt")
|
||||
.run()
|
||||
.stdout_is_fixture("call_graph.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sort_self_loop() {
|
||||
new_ucmd!()
|
||||
.pipe_in("first first\nfirst second second second")
|
||||
.succeeds()
|
||||
.stdout_only("first\nsecond\n");
|
||||
}
|
27
tests/by-util/test_uname.rs
Normal file
27
tests/by-util/test_uname.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_uname_compatible() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg("-a").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uname_name() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg("-n").run();
|
||||
assert!(result.success);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uname_kernel() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.arg("-o").run();
|
||||
assert!(result.success);
|
||||
#[cfg(target_os = "linux")]
|
||||
assert!(result.stdout.to_lowercase().contains("linux"));
|
||||
}
|
138
tests/by-util/test_unexpand.rs
Normal file
138
tests/by-util/test_unexpand.rs
Normal file
|
@ -0,0 +1,138 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn unexpand_init_0() {
|
||||
new_ucmd!()
|
||||
.args(&["-t4"])
|
||||
.pipe_in(" 1\n 2\n 3\n 4\n")
|
||||
.run()
|
||||
.stdout_is(" 1\n 2\n 3\n\t4\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_init_1() {
|
||||
new_ucmd!()
|
||||
.args(&["-t4"])
|
||||
.pipe_in(" 5\n 6\n 7\n 8\n")
|
||||
.run()
|
||||
.stdout_is("\t 5\n\t 6\n\t 7\n\t\t8\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_init_list_0() {
|
||||
new_ucmd!()
|
||||
.args(&["-t2,4"])
|
||||
.pipe_in(" 1\n 2\n 3\n 4\n")
|
||||
.run()
|
||||
.stdout_is(" 1\n\t2\n\t 3\n\t\t4\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_init_list_1() {
|
||||
// Once the list is exhausted, spaces are not converted anymore
|
||||
new_ucmd!()
|
||||
.args(&["-t2,4"])
|
||||
.pipe_in(" 5\n 6\n 7\n 8\n")
|
||||
.run()
|
||||
.stdout_is("\t\t 5\n\t\t 6\n\t\t 7\n\t\t 8\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_aflag_0() {
|
||||
new_ucmd!()
|
||||
.args(&["--"])
|
||||
.pipe_in("e E\nf F\ng G\nh H\n")
|
||||
.run()
|
||||
.stdout_is("e E\nf F\ng G\nh H\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_aflag_1() {
|
||||
new_ucmd!()
|
||||
.args(&["-a"])
|
||||
.pipe_in("e E\nf F\ng G\nh H\n")
|
||||
.run()
|
||||
.stdout_is("e E\nf F\ng\tG\nh\t H\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_aflag_2() {
|
||||
new_ucmd!()
|
||||
.args(&["-t8"])
|
||||
.pipe_in("e E\nf F\ng G\nh H\n")
|
||||
.run()
|
||||
.stdout_is("e E\nf F\ng\tG\nh\t H\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_first_only_0() {
|
||||
new_ucmd!()
|
||||
.args(&["-t3"])
|
||||
.pipe_in(" A B")
|
||||
.run()
|
||||
.stdout_is("\t\t A\t B");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_first_only_1() {
|
||||
new_ucmd!()
|
||||
.args(&["-t3", "--first-only"])
|
||||
.pipe_in(" A B")
|
||||
.run()
|
||||
.stdout_is("\t\t A B");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_trailing_space_0() {
|
||||
// evil
|
||||
// Individual spaces before fields starting with non blanks should not be
|
||||
// converted, unless they are at the beginning of the line.
|
||||
new_ucmd!()
|
||||
.args(&["-t4"])
|
||||
.pipe_in("123 \t1\n123 1\n123 \n123 ")
|
||||
.run()
|
||||
.stdout_is("123\t\t1\n123 1\n123 \n123 ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_trailing_space_1() {
|
||||
// super evil
|
||||
new_ucmd!()
|
||||
.args(&["-t1"])
|
||||
.pipe_in(" abc d e f g ")
|
||||
.run()
|
||||
.stdout_is("\tabc d e\t\tf\t\tg ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_spaces_follow_tabs_0() {
|
||||
// The two first spaces can be included into the first tab.
|
||||
new_ucmd!()
|
||||
.pipe_in(" \t\t A")
|
||||
.run()
|
||||
.stdout_is("\t\t A");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_spaces_follow_tabs_1() {
|
||||
// evil
|
||||
// Explanation of what is going on here:
|
||||
// 'a' -> 'a' // first tabstop (1)
|
||||
// ' \t' -> '\t' // second tabstop (4)
|
||||
// ' ' -> '\t' // third tabstop (5)
|
||||
// ' B \t' -> ' B \t' // after the list is exhausted, nothing must change
|
||||
new_ucmd!()
|
||||
.args(&["-t1,4,5"])
|
||||
.pipe_in("a \t B \t")
|
||||
.run()
|
||||
.stdout_is("a\t\t B \t");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unexpand_spaces_after_fields() {
|
||||
new_ucmd!()
|
||||
.args(&["-a"])
|
||||
.pipe_in(" \t A B C D A\t\n")
|
||||
.run()
|
||||
.stdout_is("\t\tA B C D\t\t A\t\n");
|
||||
}
|
130
tests/by-util/test_uniq.rs
Normal file
130
tests/by-util/test_uniq.rs
Normal file
|
@ -0,0 +1,130 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
static INPUT: &'static str = "sorted.txt";
|
||||
static SKIP_CHARS: &'static str = "skip-chars.txt";
|
||||
static SKIP_FIELDS: &'static str = "skip-fields.txt";
|
||||
static SORTED_ZERO_TERMINATED: &'static str = "sorted-zero-terminated.txt";
|
||||
|
||||
#[test]
|
||||
fn test_stdin_default() {
|
||||
new_ucmd!()
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-simple.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_default() {
|
||||
new_ucmd!()
|
||||
.arg(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-simple.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_counts() {
|
||||
new_ucmd!()
|
||||
.args(&["-c"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-counts.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_skip_1_char() {
|
||||
new_ucmd!()
|
||||
.args(&["-s1"])
|
||||
.pipe_in_fixture(SKIP_CHARS)
|
||||
.run()
|
||||
.stdout_is_fixture("skip-1-char.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_skip_5_chars() {
|
||||
new_ucmd!()
|
||||
.args(&["-s5"])
|
||||
.pipe_in_fixture(SKIP_CHARS)
|
||||
.run()
|
||||
.stdout_is_fixture("skip-5-chars.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_skip_and_check_2_chars() {
|
||||
new_ucmd!()
|
||||
.args(&["-s3", "-w2"])
|
||||
.pipe_in_fixture(SKIP_CHARS)
|
||||
.run()
|
||||
.stdout_is_fixture("skip-3-check-2-chars.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_skip_1_field() {
|
||||
new_ucmd!()
|
||||
.args(&["-f2"])
|
||||
.pipe_in_fixture(SKIP_FIELDS)
|
||||
.run()
|
||||
.stdout_is_fixture("skip-2-fields.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_all_repeated() {
|
||||
new_ucmd!()
|
||||
.args(&["--all-repeated"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_all_repeated_separate() {
|
||||
new_ucmd!()
|
||||
.args(&["--all-repeated=separate"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated-separate.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_all_repeated_prepend() {
|
||||
new_ucmd!()
|
||||
.args(&["--all-repeated=prepend"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-all-repeated-prepend.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_unique_only() {
|
||||
new_ucmd!()
|
||||
.args(&["-u"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-unique-only.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_repeated_only() {
|
||||
new_ucmd!()
|
||||
.args(&["-d"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-repeated-only.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_ignore_case() {
|
||||
new_ucmd!()
|
||||
.args(&["-i"])
|
||||
.pipe_in_fixture(INPUT)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-ignore-case.expected");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_zero_terminated() {
|
||||
new_ucmd!()
|
||||
.args(&["-z"])
|
||||
.pipe_in_fixture(SORTED_ZERO_TERMINATED)
|
||||
.run()
|
||||
.stdout_is_fixture("sorted-zero-terminated.expected");
|
||||
}
|
51
tests/by-util/test_unlink.rs
Normal file
51
tests/by-util/test_unlink.rs
Normal file
|
@ -0,0 +1,51 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_unlink_file() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file = "test_unlink_file";
|
||||
|
||||
at.touch(file);
|
||||
|
||||
ucmd.arg(file).succeeds().no_stderr();
|
||||
|
||||
assert!(!at.file_exists(file));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unlink_multiple_files() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_unlink_multiple_file_a";
|
||||
let file_b = "test_unlink_multiple_file_b";
|
||||
|
||||
at.touch(file_a);
|
||||
at.touch(file_b);
|
||||
|
||||
ucmd.arg(file_a).arg(file_b).fails().stderr_is(
|
||||
"unlink: error: extra operand: 'test_unlink_multiple_file_b'\nTry 'unlink --help' \
|
||||
for more information.\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unlink_directory() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let dir = "test_unlink_empty_directory";
|
||||
|
||||
at.mkdir(dir);
|
||||
|
||||
ucmd.arg(dir).fails().stderr_is(
|
||||
"unlink: error: cannot unlink 'test_unlink_empty_directory': Not a regular file \
|
||||
or symlink\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unlink_nonexistent() {
|
||||
let file = "test_unlink_nonexistent";
|
||||
|
||||
new_ucmd!().arg(file).fails().stderr_is(
|
||||
"unlink: error: Cannot stat 'test_unlink_nonexistent': No such file or directory \
|
||||
(os error 2)\n",
|
||||
);
|
||||
}
|
30
tests/by-util/test_uptime.rs
Normal file
30
tests/by-util/test_uptime.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
extern crate regex;
|
||||
use self::regex::Regex;
|
||||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_uptime() {
|
||||
let result = TestScenario::new(util_name!()).ucmd_keepenv().run();
|
||||
|
||||
println!("stdout = {}", result.stdout);
|
||||
println!("stderr = {}", result.stderr);
|
||||
|
||||
assert!(result.success);
|
||||
assert!(result.stdout.contains("load average:"));
|
||||
assert!(result.stdout.contains(" up "));
|
||||
// Don't check for users as it doesn't show in some CI
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uptime_since() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let result = scene.ucmd().arg("--since").succeeds();
|
||||
|
||||
println!("stdout = {}", result.stdout);
|
||||
println!("stderr = {}", result.stderr);
|
||||
|
||||
assert!(result.success);
|
||||
let re = Regex::new(r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}").unwrap();
|
||||
assert!(re.is_match(&result.stdout.trim()));
|
||||
}
|
30
tests/by-util/test_users.rs
Normal file
30
tests/by-util/test_users.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use crate::common::util::*;
|
||||
use std::env;
|
||||
|
||||
#[test]
|
||||
fn test_users_noarg() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
let result = ucmd.run();
|
||||
assert!(result.success);
|
||||
}
|
||||
#[test]
|
||||
fn test_users_check_name() {
|
||||
let result = TestScenario::new(util_name!()).ucmd_keepenv().run();
|
||||
assert!(result.success);
|
||||
|
||||
// Expectation: USER is often set
|
||||
let key = "USER";
|
||||
|
||||
match env::var(key) {
|
||||
Err(e) => println!("Key {} isn't set. Found {}", &key, e),
|
||||
Ok(username) =>
|
||||
// Check if "users" contains the name of the user
|
||||
{
|
||||
println!("username found {}", &username);
|
||||
println!("result.stdout {}", &result.stdout);
|
||||
if !&result.stdout.is_empty() {
|
||||
assert!(result.stdout.contains(&username))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
66
tests/by-util/test_wc.rs
Normal file
66
tests/by-util/test_wc.rs
Normal file
|
@ -0,0 +1,66 @@
|
|||
use crate::common::util::*;
|
||||
|
||||
#[test]
|
||||
fn test_stdin_default() {
|
||||
new_ucmd!()
|
||||
.pipe_in_fixture("lorem_ipsum.txt")
|
||||
.run()
|
||||
.stdout_is(" 13 109 772\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_only_bytes() {
|
||||
new_ucmd!()
|
||||
.args(&["-c"])
|
||||
.pipe_in_fixture("lorem_ipsum.txt")
|
||||
.run()
|
||||
.stdout_is(" 772\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_all_counts() {
|
||||
new_ucmd!()
|
||||
.args(&["-c", "-m", "-l", "-L", "-w"])
|
||||
.pipe_in_fixture("alice_in_wonderland.txt")
|
||||
.run()
|
||||
.stdout_is(" 5 57 302 302 66\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_default() {
|
||||
new_ucmd!()
|
||||
.arg("moby_dick.txt")
|
||||
.run()
|
||||
.stdout_is(" 18 204 1115 moby_dick.txt\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_only_lines() {
|
||||
new_ucmd!()
|
||||
.args(&["-l", "moby_dick.txt"])
|
||||
.run()
|
||||
.stdout_is(" 18 moby_dick.txt\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_all_counts() {
|
||||
new_ucmd!()
|
||||
.args(&["-c", "-l", "-L", "-m", "-w", "alice_in_wonderland.txt"])
|
||||
.run()
|
||||
.stdout_is(" 5 57 302 302 66 alice_in_wonderland.txt\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_default() {
|
||||
new_ucmd!()
|
||||
.args(&[
|
||||
"lorem_ipsum.txt",
|
||||
"moby_dick.txt",
|
||||
"alice_in_wonderland.txt",
|
||||
])
|
||||
.run()
|
||||
.stdout_is(
|
||||
" 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 5 57 302 \
|
||||
alice_in_wonderland.txt\n 36 370 2189 total\n",
|
||||
);
|
||||
}
|
84
tests/by-util/test_who.rs
Normal file
84
tests/by-util/test_who.rs
Normal file
|
@ -0,0 +1,84 @@
|
|||
#[cfg(target_os = "linux")]
|
||||
use crate::common::util::*;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_count() {
|
||||
for opt in vec!["-q", "--count"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_boot() {
|
||||
for opt in vec!["-b", "--boot"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
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 expect = expected_result(opt);
|
||||
println!("actual: {:?}", actual);
|
||||
println!("expect: {:?}", expect);
|
||||
let v_actual: Vec<&str> = actual.split_whitespace().collect();
|
||||
let v_expect: Vec<&str> = expect.split_whitespace().collect();
|
||||
assert_eq!(v_actual, v_expect);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_short() {
|
||||
for opt in vec!["-s", "--short"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_login() {
|
||||
for opt in vec!["-l", "--login"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_m() {
|
||||
for opt in vec!["-m"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_dead() {
|
||||
for opt in vec!["-d", "--dead"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[test]
|
||||
fn test_all() {
|
||||
for opt in vec!["-a", "--all"] {
|
||||
new_ucmd!().arg(opt).run().stdout_is(expected_result(opt));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn expected_result(arg: &str) -> String {
|
||||
TestScenario::new(util_name!())
|
||||
.cmd_keepenv(util_name!())
|
||||
.env("LANGUAGE", "C")
|
||||
.args(&[arg])
|
||||
.run()
|
||||
.stdout
|
||||
}
|
59
tests/by-util/test_whoami.rs
Normal file
59
tests/by-util/test_whoami.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use crate::common::util::*;
|
||||
use std::env;
|
||||
|
||||
#[test]
|
||||
fn test_normal() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.run();
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
println!("env::var(CI).is_ok() = {}", env::var("CI").is_ok());
|
||||
|
||||
for (key, value) in env::vars() {
|
||||
println!("{}: {}", key, value);
|
||||
}
|
||||
if env::var("USER").is_ok()
|
||||
&& env::var("USER").unwrap() == "runner"
|
||||
&& result.stderr.contains("failed to get username")
|
||||
{
|
||||
// In the CI, some server are failing to return whoami.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
return;
|
||||
}
|
||||
|
||||
assert!(result.success);
|
||||
assert!(!result.stdout.trim().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
fn test_normal_compare_id() {
|
||||
let (_, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
let result = ucmd.run();
|
||||
|
||||
println!("result.stdout = {}", result.stdout);
|
||||
println!("result.stderr = {}", result.stderr);
|
||||
if env::var("USER").is_ok()
|
||||
&& env::var("USER").unwrap() == "runner"
|
||||
&& result.stderr.contains("failed to get username")
|
||||
{
|
||||
// In the CI, some server are failing to return whoami.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
return;
|
||||
}
|
||||
assert!(result.success);
|
||||
let ts = TestScenario::new("id");
|
||||
let id = ts.cmd("id").arg("-un").run();
|
||||
|
||||
if env::var("USER").is_ok()
|
||||
&& env::var("USER").unwrap() == "runner"
|
||||
&& id.stderr.contains("cannot find name for user ID")
|
||||
{
|
||||
// In the CI, some server are failing to return whoami.
|
||||
// As seems to be a configuration issue, ignoring it
|
||||
return;
|
||||
}
|
||||
assert_eq!(result.stdout.trim(), id.stdout.trim());
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue