mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-31 13:07:46 +00:00
Merge branch 'master' of https://github.com/uutils/coreutils into timeout/cmd-args
This commit is contained in:
commit
a69c2d52f9
71 changed files with 1882 additions and 1513 deletions
|
@ -1,4 +1,4 @@
|
|||
// spell-checker:ignore (words) nosuchgroup
|
||||
// spell-checker:ignore (words) nosuchgroup groupname
|
||||
|
||||
use crate::common::util::*;
|
||||
use rust_users::*;
|
||||
|
@ -10,6 +10,33 @@ fn test_invalid_option() {
|
|||
|
||||
static DIR: &str = "/tmp";
|
||||
|
||||
// we should always get both arguments, regardless of whether --reference was used
|
||||
#[test]
|
||||
fn test_help() {
|
||||
new_ucmd!()
|
||||
.arg("--help")
|
||||
.succeeds()
|
||||
.stdout_contains("ARGS:\n <GROUP> \n <FILE>... ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_help_ref() {
|
||||
new_ucmd!()
|
||||
.arg("--help")
|
||||
.arg("--reference=ref_file")
|
||||
.succeeds()
|
||||
.stdout_contains("ARGS:\n <GROUP> \n <FILE>... ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ref_help() {
|
||||
new_ucmd!()
|
||||
.arg("--reference=ref_file")
|
||||
.arg("--help")
|
||||
.succeeds()
|
||||
.stdout_contains("ARGS:\n <GROUP> \n <FILE>... ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_group() {
|
||||
new_ucmd!()
|
||||
|
@ -121,9 +148,52 @@ fn test_reference() {
|
|||
fn test_reference() {
|
||||
new_ucmd!()
|
||||
.arg("-v")
|
||||
.arg("--reference=/etc/passwd")
|
||||
.arg("--reference=ref_file")
|
||||
.arg("/etc")
|
||||
.succeeds();
|
||||
.fails()
|
||||
// group name can differ, so just check the first part of the message
|
||||
.stderr_contains("chgrp: changing group of '/etc': Operation not permitted (os error 1)\nfailed to change group of '/etc' from ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "linux", target_vendor = "apple"))]
|
||||
fn test_reference_multi_no_equal() {
|
||||
new_ucmd!()
|
||||
.arg("-v")
|
||||
.arg("--reference")
|
||||
.arg("ref_file")
|
||||
.arg("file1")
|
||||
.arg("file2")
|
||||
.succeeds()
|
||||
.stderr_contains("chgrp: group of 'file1' retained as ")
|
||||
.stderr_contains("\nchgrp: group of 'file2' retained as ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "linux", target_vendor = "apple"))]
|
||||
fn test_reference_last() {
|
||||
new_ucmd!()
|
||||
.arg("-v")
|
||||
.arg("file1")
|
||||
.arg("file2")
|
||||
.arg("file3")
|
||||
.arg("--reference")
|
||||
.arg("ref_file")
|
||||
.succeeds()
|
||||
.stderr_contains("chgrp: group of 'file1' retained as ")
|
||||
.stderr_contains("\nchgrp: group of 'file2' retained as ")
|
||||
.stderr_contains("\nchgrp: group of 'file3' retained as ");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_missing_files() {
|
||||
new_ucmd!()
|
||||
.arg("-v")
|
||||
.arg("groupname")
|
||||
.fails()
|
||||
.stderr_contains(
|
||||
"error: The following required arguments were not provided:\n <FILE>...\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -135,7 +205,7 @@ fn test_big_p() {
|
|||
.arg("bin")
|
||||
.arg("/proc/self/cwd")
|
||||
.fails()
|
||||
.stderr_is(
|
||||
.stderr_contains(
|
||||
"chgrp: changing group of '/proc/self/cwd': Operation not permitted (os error 1)\n",
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// * This file is part of the uutils coreutils package.
|
||||
// *
|
||||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (paths) sublink subwords
|
||||
|
||||
use crate::common::util::*;
|
||||
|
@ -73,6 +78,23 @@ fn _du_basics_subdir(s: &str) {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_du_invalid_size() {
|
||||
new_ucmd!()
|
||||
.arg("--block-size=1fb4t")
|
||||
.arg("/tmp")
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only("du: invalid --block-size argument '1fb4t'");
|
||||
#[cfg(not(target_pointer_width = "128"))]
|
||||
new_ucmd!()
|
||||
.arg("--block-size=1Y")
|
||||
.arg("/tmp")
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only("du: --block-size argument '1Y' too large");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_du_basics_bad_name() {
|
||||
new_ucmd!()
|
||||
|
@ -312,3 +334,20 @@ fn _du_no_permission(s: &str) {
|
|||
fn _du_no_permission(s: &str) {
|
||||
assert_eq!(s, "4\tsubdir/links\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_du_one_file_system() {
|
||||
let scene = TestScenario::new(util_name!());
|
||||
|
||||
let result = scene.ucmd().arg("-x").arg(SUB_DIR).succeeds();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let result_reference = scene.cmd("du").arg("-x").arg(SUB_DIR).run();
|
||||
if result_reference.succeeded() {
|
||||
assert_eq!(result.stdout_str(), result_reference.stdout_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
_du_basics_subdir(result.stdout_str());
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
// spell-checker:ignore (words) bogusfile emptyfile
|
||||
// * This file is part of the uutils coreutils package.
|
||||
// *
|
||||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (words) bogusfile emptyfile abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstu
|
||||
|
||||
use crate::common::util::*;
|
||||
|
||||
|
@ -244,3 +249,61 @@ hello
|
|||
",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_head_invalid_num() {
|
||||
new_ucmd!()
|
||||
.args(&["-c", "1024R", "emptyfile.txt"])
|
||||
.fails()
|
||||
.stderr_is("head: invalid number of bytes: ‘1024R’");
|
||||
new_ucmd!()
|
||||
.args(&["-n", "1024R", "emptyfile.txt"])
|
||||
.fails()
|
||||
.stderr_is("head: invalid number of lines: ‘1024R’");
|
||||
#[cfg(not(target_pointer_width = "128"))]
|
||||
new_ucmd!()
|
||||
.args(&["-c", "1Y", "emptyfile.txt"])
|
||||
.fails()
|
||||
.stderr_is("head: invalid number of bytes: ‘1Y’: Value too large for defined data type");
|
||||
#[cfg(not(target_pointer_width = "128"))]
|
||||
new_ucmd!()
|
||||
.args(&["-n", "1Y", "emptyfile.txt"])
|
||||
.fails()
|
||||
.stderr_is("head: invalid number of lines: ‘1Y’: Value too large for defined data type");
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
{
|
||||
let sizes = ["1000G", "10T"];
|
||||
for size in &sizes {
|
||||
new_ucmd!()
|
||||
.args(&["-c", size])
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only(format!(
|
||||
"head: invalid number of bytes: ‘{}’: Value too large for defined data type",
|
||||
size
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_head_num_with_undocumented_sign_bytes() {
|
||||
// tail: '-' is not documented (8.32 man pages)
|
||||
// head: '+' is not documented (8.32 man pages)
|
||||
const ALPHABET: &str = "abcdefghijklmnopqrstuvwxyz";
|
||||
new_ucmd!()
|
||||
.args(&["-c", "5"])
|
||||
.pipe_in(ALPHABET)
|
||||
.succeeds()
|
||||
.stdout_is("abcde");
|
||||
new_ucmd!()
|
||||
.args(&["-c", "-5"])
|
||||
.pipe_in(ALPHABET)
|
||||
.succeeds()
|
||||
.stdout_is("abcdefghijklmnopqrstu");
|
||||
new_ucmd!()
|
||||
.args(&["-c", "+5"])
|
||||
.pipe_in(ALPHABET)
|
||||
.succeeds()
|
||||
.stdout_is("abcde");
|
||||
}
|
||||
|
|
|
@ -428,20 +428,6 @@ fn test_symlink_relative() {
|
|||
assert_eq!(at.resolve_link(link), file_a);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hardlink_relative() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
let file_a = "test_hardlink_relative_a";
|
||||
let link = "test_hardlink_relative_link";
|
||||
|
||||
at.touch(file_a);
|
||||
|
||||
// relative hardlink
|
||||
ucmd.args(&["-r", "-v", file_a, link])
|
||||
.succeeds()
|
||||
.stdout_only(format!("'{}' -> '{}'\n", link, file_a));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_symlink_relative_path() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
@ -571,3 +557,26 @@ fn test_symlink_no_deref_file() {
|
|||
assert!(at.is_symlink(link));
|
||||
assert_eq!(at.resolve_link(link), file1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_relative_requires_symbolic() {
|
||||
new_ucmd!().args(&["-r", "foo", "bar"]).fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_relative_dst_already_symlink() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.touch("file1");
|
||||
at.symlink_file("file1", "file2");
|
||||
ucmd.arg("-srf").arg("file1").arg("file2").succeeds();
|
||||
at.is_symlink("file2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_relative_src_already_symlink() {
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
at.touch("file1");
|
||||
at.symlink_file("file1", "file2");
|
||||
ucmd.arg("-sr").arg("file2").arg("file3").succeeds();
|
||||
assert!(at.resolve_link("file3").ends_with("file1"));
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// * This file is part of the uutils coreutils package.
|
||||
// *
|
||||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
extern crate unindent;
|
||||
|
||||
use self::unindent::*;
|
||||
|
@ -804,3 +809,40 @@ fn test_traditional_only_label() {
|
|||
",
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_od_invalid_bytes() {
|
||||
const INVALID_SIZE: &str = "1fb4t";
|
||||
const BIG_SIZE: &str = "1Y";
|
||||
|
||||
// NOTE:
|
||||
// GNU's od (8.32) with option '--width' does not accept 'Y' as valid suffix.
|
||||
// According to the man page it should be valid in the same way it is valid for
|
||||
// '--read-bytes' and '--skip-bytes'.
|
||||
|
||||
let options = [
|
||||
"--read-bytes",
|
||||
"--skip-bytes",
|
||||
"--width",
|
||||
// "--strings", // TODO: consider testing here once '--strings' is implemented
|
||||
];
|
||||
for option in &options {
|
||||
new_ucmd!()
|
||||
.arg(format!("{}={}", option, INVALID_SIZE))
|
||||
.arg("file")
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only(format!(
|
||||
"od: invalid {} argument '{}'",
|
||||
option, INVALID_SIZE
|
||||
));
|
||||
|
||||
#[cfg(not(target_pointer_width = "128"))]
|
||||
new_ucmd!()
|
||||
.arg(format!("{}={}", option, BIG_SIZE))
|
||||
.arg("file")
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only(format!("od: {} argument '{}' too large", option, BIG_SIZE));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// * This file is part of the uutils coreutils package.
|
||||
// *
|
||||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (words) ints
|
||||
|
||||
use crate::common::util::*;
|
||||
|
@ -21,9 +26,7 @@ fn test_helper(file_name: &str, possible_args: &[&str]) {
|
|||
|
||||
#[test]
|
||||
fn test_buffer_sizes() {
|
||||
let buffer_sizes = [
|
||||
"0", "50K", "50k", "1M", "100M", "1000G", "10T", "500E", "1Y",
|
||||
];
|
||||
let buffer_sizes = ["0", "50K", "50k", "1M", "100M"];
|
||||
for buffer_size in &buffer_sizes {
|
||||
new_ucmd!()
|
||||
.arg("-n")
|
||||
|
@ -32,6 +35,20 @@ fn test_buffer_sizes() {
|
|||
.arg("ext_sort.txt")
|
||||
.succeeds()
|
||||
.stdout_is_fixture("ext_sort.expected");
|
||||
|
||||
#[cfg(not(target_pointer_width = "32"))]
|
||||
{
|
||||
let buffer_sizes = ["1000G", "10T"];
|
||||
for buffer_size in &buffer_sizes {
|
||||
new_ucmd!()
|
||||
.arg("-n")
|
||||
.arg("-S")
|
||||
.arg(buffer_size)
|
||||
.arg("ext_sort.txt")
|
||||
.succeeds()
|
||||
.stdout_is_fixture("ext_sort.expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,11 +60,39 @@ fn test_invalid_buffer_size() {
|
|||
.arg("-S")
|
||||
.arg(invalid_buffer_size)
|
||||
.fails()
|
||||
.code_is(2)
|
||||
.stderr_only(format!(
|
||||
"sort: failed to parse buffer size `{}`: invalid digit found in string",
|
||||
"sort: invalid --buffer-size argument '{}'",
|
||||
invalid_buffer_size
|
||||
));
|
||||
}
|
||||
#[cfg(not(target_pointer_width = "128"))]
|
||||
new_ucmd!()
|
||||
.arg("-n")
|
||||
.arg("-S")
|
||||
.arg("1Y")
|
||||
.arg("ext_sort.txt")
|
||||
.fails()
|
||||
.code_is(2)
|
||||
.stderr_only("sort: --buffer-size argument '1Y' too large");
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
{
|
||||
let buffer_sizes = ["1000G", "10T"];
|
||||
for buffer_size in &buffer_sizes {
|
||||
new_ucmd!()
|
||||
.arg("-n")
|
||||
.arg("-S")
|
||||
.arg(buffer_size)
|
||||
.arg("ext_sort.txt")
|
||||
.fails()
|
||||
.code_is(2)
|
||||
.stderr_only(format!(
|
||||
"sort: --buffer-size argument '{}' too large",
|
||||
buffer_size
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -804,7 +849,7 @@ fn sort_multiple() {
|
|||
#[test]
|
||||
fn sort_empty_chunk() {
|
||||
new_ucmd!()
|
||||
.args(&["-S", "40B"])
|
||||
.args(&["-S", "40b"])
|
||||
.pipe_in("a\na\n")
|
||||
.succeeds()
|
||||
.stdout_is("a\na\n");
|
||||
|
@ -844,7 +889,7 @@ fn test_compress_fail() {
|
|||
#[test]
|
||||
fn test_merge_batches() {
|
||||
new_ucmd!()
|
||||
.args(&["ext_sort.txt", "-n", "-S", "150B"])
|
||||
.args(&["ext_sort.txt", "-n", "-S", "150b"])
|
||||
.succeeds()
|
||||
.stdout_only_fixture("ext_sort.expected");
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
// * This file is part of the uutils coreutils package.
|
||||
// *
|
||||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
extern crate rand;
|
||||
extern crate regex;
|
||||
|
||||
|
@ -285,3 +290,53 @@ fn test_filter_command_fails() {
|
|||
ucmd.args(&["--filter=/a/path/that/totally/does/not/exist", name])
|
||||
.fails();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_lines_number() {
|
||||
// Test if stdout/stderr for '--lines' option is correct
|
||||
let scene = TestScenario::new(util_name!());
|
||||
let at = &scene.fixtures;
|
||||
at.touch("file");
|
||||
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&["--lines", "2", "file"])
|
||||
.succeeds()
|
||||
.no_stderr()
|
||||
.no_stdout();
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&["--lines", "2fb", "file"])
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only("split: invalid number of lines: ‘2fb’");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_invalid_bytes_size() {
|
||||
new_ucmd!()
|
||||
.args(&["-b", "1024R"])
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only("split: invalid number of bytes: ‘1024R’");
|
||||
#[cfg(not(target_pointer_width = "128"))]
|
||||
new_ucmd!()
|
||||
.args(&["-b", "1Y"])
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only("split: invalid number of bytes: ‘1Y’: Value too large for defined data type");
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
{
|
||||
let sizes = ["1000G", "10T"];
|
||||
for size in &sizes {
|
||||
new_ucmd!()
|
||||
.args(&["-b", size])
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only(format!(
|
||||
"split: invalid number of bytes: ‘{}’: Value too large for defined data type",
|
||||
size
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,8 +57,18 @@ fn test_stdbuf_line_buffering_stdin_fails() {
|
|||
#[cfg(not(target_os = "windows"))]
|
||||
#[test]
|
||||
fn test_stdbuf_invalid_mode_fails() {
|
||||
new_ucmd!()
|
||||
.args(&["-i", "1024R", "head"])
|
||||
.fails()
|
||||
.stderr_is("stdbuf: invalid mode 1024R\nTry 'stdbuf --help' for more information.");
|
||||
let options = ["--input", "--output", "--error"];
|
||||
for option in &options {
|
||||
new_ucmd!()
|
||||
.args(&[*option, "1024R", "head"])
|
||||
.fails()
|
||||
.code_is(125)
|
||||
.stderr_only("stdbuf: invalid mode ‘1024R’");
|
||||
#[cfg(not(target_pointer_width = "128"))]
|
||||
new_ucmd!()
|
||||
.args(&[*option, "1Y", "head"])
|
||||
.fails()
|
||||
.code_is(125)
|
||||
.stderr_contains("stdbuf: invalid mode ‘1Y’: Value too large for defined data type");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
// * This file is part of the uutils coreutils package.
|
||||
// *
|
||||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (ToDO) abcdefghijklmnopqrstuvwxyz efghijklmnopqrstuvwxyz vwxyz emptyfile
|
||||
|
||||
extern crate tail;
|
||||
|
||||
use self::tail::parse_size;
|
||||
use crate::common::util::*;
|
||||
use std::char::from_digit;
|
||||
use std::io::Write;
|
||||
|
@ -236,41 +242,6 @@ fn test_bytes_big() {
|
|||
}
|
||||
}
|
||||
|
||||
#[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_u64).pow(exp)), parse_size(&s));
|
||||
|
||||
let s = format!("2{}", c);
|
||||
assert_eq!(Ok(2 * (1024_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()); // spell-checker:disable-line
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_lines_with_size_suffix() {
|
||||
const FILE: &str = "test_lines_with_size_suffix.txt";
|
||||
|
@ -320,12 +291,11 @@ fn test_multiple_input_files_with_suppressed_headers() {
|
|||
|
||||
#[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")
|
||||
.arg("-q")
|
||||
.run()
|
||||
.stdout_is_fixture("foobar_multiple_quiet.expected");
|
||||
}
|
||||
|
@ -388,3 +358,61 @@ fn test_positive_zero_lines() {
|
|||
.succeeds()
|
||||
.stdout_is("a\nb\nc\nd\ne\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tail_invalid_num() {
|
||||
new_ucmd!()
|
||||
.args(&["-c", "1024R", "emptyfile.txt"])
|
||||
.fails()
|
||||
.stderr_is("tail: invalid number of bytes: ‘1024R’");
|
||||
new_ucmd!()
|
||||
.args(&["-n", "1024R", "emptyfile.txt"])
|
||||
.fails()
|
||||
.stderr_is("tail: invalid number of lines: ‘1024R’");
|
||||
#[cfg(not(target_pointer_width = "128"))]
|
||||
new_ucmd!()
|
||||
.args(&["-c", "1Y", "emptyfile.txt"])
|
||||
.fails()
|
||||
.stderr_is("tail: invalid number of bytes: ‘1Y’: Value too large for defined data type");
|
||||
#[cfg(not(target_pointer_width = "128"))]
|
||||
new_ucmd!()
|
||||
.args(&["-n", "1Y", "emptyfile.txt"])
|
||||
.fails()
|
||||
.stderr_is("tail: invalid number of lines: ‘1Y’: Value too large for defined data type");
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
{
|
||||
let sizes = ["1000G", "10T"];
|
||||
for size in &sizes {
|
||||
new_ucmd!()
|
||||
.args(&["-c", size])
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only(format!(
|
||||
"tail: invalid number of bytes: ‘{}’: Value too large for defined data type",
|
||||
size
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tail_num_with_undocumented_sign_bytes() {
|
||||
// tail: '-' is not documented (8.32 man pages)
|
||||
// head: '+' is not documented (8.32 man pages)
|
||||
const ALPHABET: &str = "abcdefghijklmnopqrstuvwxyz";
|
||||
new_ucmd!()
|
||||
.args(&["-c", "5"])
|
||||
.pipe_in(ALPHABET)
|
||||
.succeeds()
|
||||
.stdout_is("vwxyz");
|
||||
new_ucmd!()
|
||||
.args(&["-c", "-5"])
|
||||
.pipe_in(ALPHABET)
|
||||
.succeeds()
|
||||
.stdout_is("vwxyz");
|
||||
new_ucmd!()
|
||||
.args(&["-c", "+5"])
|
||||
.pipe_in(ALPHABET)
|
||||
.succeeds()
|
||||
.stdout_is("efghijklmnopqrstuvwxyz");
|
||||
}
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
// * This file is part of the uutils coreutils package.
|
||||
// *
|
||||
// * For the full copyright and license information, please view the LICENSE
|
||||
// * file that was distributed with this source code.
|
||||
|
||||
// spell-checker:ignore (words) RFILE
|
||||
|
||||
use crate::common::util::*;
|
||||
use std::io::{Seek, SeekFrom, Write};
|
||||
|
||||
|
@ -45,9 +52,18 @@ fn test_reference() {
|
|||
let at = &scene.fixtures;
|
||||
let mut file = at.make_file(FILE2);
|
||||
|
||||
scene.ucmd().arg("-s").arg("+5KB").arg(FILE1).run();
|
||||
// manpage: "A FILE argument that does not exist is created."
|
||||
// TODO: 'truncate' does not create the file in this case,
|
||||
// but should because '--no-create' wasn't specified.
|
||||
at.touch(FILE1); // TODO: remove this when 'no-create' is fixed
|
||||
scene.ucmd().arg("-s").arg("+5KB").arg(FILE1).succeeds();
|
||||
|
||||
scene.ucmd().arg("--reference").arg(FILE1).arg(FILE2).run();
|
||||
scene
|
||||
.ucmd()
|
||||
.arg("--reference")
|
||||
.arg(FILE1)
|
||||
.arg(FILE2)
|
||||
.succeeds();
|
||||
|
||||
file.seek(SeekFrom::End(0)).unwrap();
|
||||
let actual = file.seek(SeekFrom::Current(0)).unwrap();
|
||||
|
@ -231,11 +247,18 @@ fn test_size_and_reference() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error_filename_only() {
|
||||
// truncate: you must specify either ‘--size’ or ‘--reference’
|
||||
new_ucmd!().args(&["file"]).fails().stderr_contains(
|
||||
"error: The following required arguments were not provided:
|
||||
--reference <RFILE>
|
||||
--size <SIZE>",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_numbers() {
|
||||
// TODO For compatibility with GNU, `truncate -s 0X` should cause
|
||||
// the same error as `truncate -s 0X file`, but currently it returns
|
||||
// a different error.
|
||||
new_ucmd!()
|
||||
.args(&["-s", "0X", "file"])
|
||||
.fails()
|
||||
|
@ -265,3 +288,36 @@ fn test_reference_with_size_file_not_found() {
|
|||
.fails()
|
||||
.stderr_contains("cannot stat 'a': No such file or directory");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_truncate_bytes_size() {
|
||||
// TODO: this should succeed without error, uncomment when '--no-create' is fixed
|
||||
// new_ucmd!()
|
||||
// .args(&["--no-create", "--size", "K", "file"])
|
||||
// .succeeds();
|
||||
new_ucmd!()
|
||||
.args(&["--size", "1024R", "file"])
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only("truncate: Invalid number: ‘1024R’");
|
||||
#[cfg(not(target_pointer_width = "128"))]
|
||||
new_ucmd!()
|
||||
.args(&["--size", "1Y", "file"])
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only("truncate: Invalid number: ‘1Y’: Value too large for defined data type");
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
{
|
||||
let sizes = ["1000G", "10T"];
|
||||
for size in &sizes {
|
||||
new_ucmd!()
|
||||
.args(&["--size", size, "file"])
|
||||
.fails()
|
||||
.code_is(1)
|
||||
.stderr_only(format!(
|
||||
"truncate: Invalid number: ‘{}’: Value too large for defined data type",
|
||||
size
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue