coreutils/tests/by-util/test_cut.rs

322 lines
7.6 KiB
Rust

// 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.
use crate::common::util::TestScenario;
static INPUT: &str = "lists.txt";
struct TestedSequence<'b> {
name: &'b str,
sequence: &'b str,
}
static EXAMPLE_SEQUENCES: &[TestedSequence] = &[
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: &TestedSequence = &TestedSequence {
name: "",
sequence: "9-,6-7,-2,4",
};
#[test]
fn test_invalid_arg() {
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
}
#[test]
fn test_byte_sequence() {
for param in ["-b", "--bytes", "--byt"] {
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 ["-c", "--characters", "--char"] {
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 ["-f", "--fields", "--fie"] {
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_whitespace_delimited() {
new_ucmd!()
.args(&["-w", "-f", COMPLEX_SEQUENCE.sequence, INPUT])
.succeeds()
.stdout_only_fixture("whitespace_delimited.expected");
}
#[test]
fn test_whitespace_with_explicit_delimiter() {
new_ucmd!()
.args(&["-w", "-f", COMPLEX_SEQUENCE.sequence, "-d:"])
.fails()
.code_is(1);
}
#[test]
fn test_whitespace_with_byte() {
new_ucmd!()
.args(&["-w", "-b", COMPLEX_SEQUENCE.sequence])
.fails()
.code_is(1);
}
#[test]
fn test_whitespace_with_char() {
new_ucmd!()
.args(&["-c", COMPLEX_SEQUENCE.sequence, "-w"])
.fails()
.code_is(1);
}
#[test]
fn test_delimiter_with_byte_and_char() {
for conflicting_arg in ["-c", "-b"] {
new_ucmd!()
.args(&[conflicting_arg, COMPLEX_SEQUENCE.sequence, "-d="])
.fails()
.stderr_is("cut: invalid input: The '--delimiter' ('-d') option only usable if printing a sequence of fields\n")
.code_is(1);
}
}
#[test]
fn test_too_large() {
new_ucmd!()
.args(&["-b1-18446744073709551615", "/dev/null"])
.fails()
.code_is(1);
}
#[test]
fn test_delimiter() {
for param in ["-d", "--delimiter", "--del"] {
new_ucmd!()
.args(&[param, ":", "-f", COMPLEX_SEQUENCE.sequence, INPUT])
.succeeds()
.stdout_only_fixture("delimiter_specified.expected");
}
}
#[test]
fn test_delimiter_with_more_than_one_char() {
new_ucmd!()
.args(&["-d", "ab", "-f1"])
.fails()
.stderr_contains("cut: the delimiter must be a single character")
.no_stdout();
}
#[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");
new_ucmd!()
.args(&[
"-d:",
"--output-del=@",
"-f",
COMPLEX_SEQUENCE.sequence,
INPUT,
])
.succeeds()
.stdout_only_fixture("output_delimiter.expected");
}
#[test]
fn test_complement() {
for param in ["--complement", "--com"] {
new_ucmd!()
.args(&["-d_", param, "-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\x007_3")
.succeeds()
.stdout_only("9\x007\0");
}
#[test]
fn test_only_delimited() {
for param in ["-s", "--only-delimited", "--only-del"] {
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");
}
#[test]
fn test_is_a_directory() {
let (at, mut ucmd) = at_and_ucmd!();
at.mkdir("some");
ucmd.arg("-b1")
.arg("some")
.fails()
.code_is(1)
.stderr_is("cut: some: Is a directory\n");
}
#[test]
fn test_no_such_file() {
new_ucmd!()
.arg("-b1")
.arg("some")
.fails()
.code_is(1)
.stderr_is("cut: some: No such file or directory\n");
}
#[test]
fn test_equal_as_delimiter1() {
new_ucmd!()
.args(&["-f", "2", "-d="])
.pipe_in("--dir=./out/lib")
.succeeds()
.stdout_only("./out/lib\n");
}
#[test]
fn test_equal_as_delimiter2() {
new_ucmd!()
.args(&["-f2", "--delimiter="])
.pipe_in("a=b\n")
.succeeds()
.stdout_only("a=b\n");
}
#[test]
fn test_equal_as_delimiter3() {
new_ucmd!()
.args(&["-f", "1,2", "-d", "''", "--output-delimiter=Z"])
.pipe_in("ab\0cd\n")
.succeeds()
.stdout_only_bytes("abZcd\n");
}
#[test]
fn test_multiple() {
let result = new_ucmd!()
.args(&["-f2", "-d:", "-d="])
.pipe_in("a=b\n")
.succeeds();
assert_eq!(result.stdout_str(), "b\n");
assert_eq!(result.stderr_str(), "");
}
#[test]
fn test_multiple_mode_args() {
for args in [
vec!["-b1", "-b2"],
vec!["-c1", "-c2"],
vec!["-f1", "-f2"],
vec!["-b1", "-c2"],
vec!["-b1", "-f2"],
vec!["-c1", "-f2"],
vec!["-b1", "-c2", "-f3"],
] {
new_ucmd!()
.args(&args)
.fails()
.stderr_is("cut: invalid usage: expects no more than one of --fields (-f), --chars (-c) or --bytes (-b)\n");
}
}
#[test]
fn test_no_argument() {
new_ucmd!().fails().stderr_is(
"cut: invalid usage: expects one of --fields (-f), --chars (-c) or --bytes (-b)\n",
);
}
#[test]
#[cfg(unix)]
fn test_8bit_non_utf8_delimiter() {
use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt;
let delim = OsStr::from_bytes(b"\xAD".as_slice());
new_ucmd!()
.arg("-d")
.arg(delim)
.args(&["--out=_", "-f2,3", "8bit-delim.txt"])
.succeeds()
.stdout_check(|out| out == "b_c\n".as_bytes());
}