mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-30 20:47:46 +00:00
Merge branch 'master' into ls/cross_platform_colors
This commit is contained in:
commit
cd1514bd57
8 changed files with 394 additions and 165 deletions
|
@ -1,4 +1,7 @@
|
|||
use crate::common::util::*;
|
||||
#[cfg(unix)]
|
||||
use std::fs::OpenOptions;
|
||||
#[cfg(unix)]
|
||||
use std::io::Read;
|
||||
|
||||
#[test]
|
||||
|
@ -54,7 +57,6 @@ fn test_no_options_big_input() {
|
|||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_fifo_symlink() {
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::thread;
|
||||
|
||||
|
@ -85,6 +87,74 @@ fn test_fifo_symlink() {
|
|||
thread.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_piped_to_regular_file() {
|
||||
use std::fs::read_to_string;
|
||||
|
||||
for &append in &[true, false] {
|
||||
let s = TestScenario::new(util_name!());
|
||||
let file_path = s.fixtures.plus("file.txt");
|
||||
|
||||
{
|
||||
let file = OpenOptions::new()
|
||||
.create_new(true)
|
||||
.write(true)
|
||||
.append(append)
|
||||
.open(&file_path)
|
||||
.unwrap();
|
||||
|
||||
s.ucmd()
|
||||
.set_stdout(file)
|
||||
.pipe_in_fixture("alpha.txt")
|
||||
.succeeds();
|
||||
}
|
||||
let contents = read_to_string(&file_path).unwrap();
|
||||
assert_eq!(contents, "abcde\nfghij\nklmno\npqrst\nuvwxyz\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
fn test_piped_to_dev_null() {
|
||||
for &append in &[true, false] {
|
||||
let s = TestScenario::new(util_name!());
|
||||
{
|
||||
let dev_null = OpenOptions::new()
|
||||
.write(true)
|
||||
.append(append)
|
||||
.open("/dev/null")
|
||||
.unwrap();
|
||||
|
||||
s.ucmd()
|
||||
.set_stdout(dev_null)
|
||||
.pipe_in_fixture("alpha.txt")
|
||||
.succeeds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
|
||||
fn test_piped_to_dev_full() {
|
||||
for &append in &[true, false] {
|
||||
let s = TestScenario::new(util_name!());
|
||||
{
|
||||
let dev_full = OpenOptions::new()
|
||||
.write(true)
|
||||
.append(append)
|
||||
.open("/dev/full")
|
||||
.unwrap();
|
||||
|
||||
s.ucmd()
|
||||
.set_stdout(dev_full)
|
||||
.pipe_in_fixture("alpha.txt")
|
||||
.fails()
|
||||
.stderr_contains(&"No space left on device".to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_directory() {
|
||||
let s = TestScenario::new(util_name!());
|
||||
|
@ -330,22 +400,29 @@ fn test_domain_socket() {
|
|||
use std::thread;
|
||||
use tempdir::TempDir;
|
||||
use unix_socket::UnixListener;
|
||||
use std::sync::{Barrier, Arc};
|
||||
|
||||
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");
|
||||
|
||||
// use a barrier to ensure we don't run cat before the listener is setup
|
||||
let barrier = Arc::new(Barrier::new(2));
|
||||
let barrier2 = Arc::clone(&barrier);
|
||||
|
||||
let thread = thread::spawn(move || {
|
||||
let mut stream = listener.accept().expect("failed to accept connection").0;
|
||||
barrier2.wait();
|
||||
stream
|
||||
.write_all(b"a\tb")
|
||||
.expect("failed to write test data");
|
||||
});
|
||||
|
||||
new_ucmd!()
|
||||
.args(&[socket_path])
|
||||
.succeeds()
|
||||
.stdout_only("a\tb");
|
||||
let child = new_ucmd!().args(&[socket_path]).run_no_wait();
|
||||
barrier.wait();
|
||||
let stdout = &child.wait_with_output().unwrap().stdout.clone();
|
||||
let output = String::from_utf8_lossy(&stdout);
|
||||
assert_eq!("a\tb", output);
|
||||
|
||||
thread.join().unwrap();
|
||||
}
|
||||
|
|
|
@ -103,6 +103,14 @@ fn test_ls_width() {
|
|||
.succeeds()
|
||||
.stdout_only("test-width-1\ntest-width-2\ntest-width-3\ntest-width-4\n");
|
||||
}
|
||||
|
||||
for option in &["-w 1a", "-w=1a", "--width=1a", "--width 1a"] {
|
||||
scene
|
||||
.ucmd()
|
||||
.args(&option.split(" ").collect::<Vec<_>>())
|
||||
.fails()
|
||||
.stderr_only("ls: error: invalid line width: ‘1a’");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -696,8 +696,11 @@ pub struct UCommand {
|
|||
comm_string: String,
|
||||
tmpd: Option<Rc<TempDir>>,
|
||||
has_run: bool,
|
||||
stdin: Option<Vec<u8>>,
|
||||
ignore_stdin_write_error: bool,
|
||||
stdin: Option<Stdio>,
|
||||
stdout: Option<Stdio>,
|
||||
stderr: Option<Stdio>,
|
||||
bytes_into_stdin: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl UCommand {
|
||||
|
@ -726,8 +729,11 @@ impl UCommand {
|
|||
cmd
|
||||
},
|
||||
comm_string: String::from(arg.as_ref().to_str().unwrap()),
|
||||
stdin: None,
|
||||
ignore_stdin_write_error: false,
|
||||
bytes_into_stdin: None,
|
||||
stdin: None,
|
||||
stdout: None,
|
||||
stderr: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -738,6 +744,21 @@ impl UCommand {
|
|||
ucmd
|
||||
}
|
||||
|
||||
pub fn set_stdin<T: Into<Stdio>>(&mut self, stdin: T) -> &mut UCommand {
|
||||
self.stdin = Some(stdin.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_stdout<T: Into<Stdio>>(&mut self, stdout: T) -> &mut UCommand {
|
||||
self.stdout = Some(stdout.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_stderr<T: Into<Stdio>>(&mut self, stderr: T) -> &mut UCommand {
|
||||
self.stderr = Some(stderr.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Add a parameter to the invocation. Path arguments are treated relative
|
||||
/// to the test environment directory.
|
||||
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut UCommand {
|
||||
|
@ -767,10 +788,10 @@ impl UCommand {
|
|||
|
||||
/// provides stdinput to feed in to the command when spawned
|
||||
pub fn pipe_in<T: Into<Vec<u8>>>(&mut self, input: T) -> &mut UCommand {
|
||||
if self.stdin.is_some() {
|
||||
if self.bytes_into_stdin.is_some() {
|
||||
panic!("{}", MULTIPLE_STDIN_MEANINGLESS);
|
||||
}
|
||||
self.stdin = Some(input.into());
|
||||
self.bytes_into_stdin = Some(input.into());
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -784,7 +805,7 @@ impl UCommand {
|
|||
/// This is typically useful to test non-standard workflows
|
||||
/// like feeding something to a command that does not read it
|
||||
pub fn ignore_stdin_write_error(&mut self) -> &mut UCommand {
|
||||
if self.stdin.is_none() {
|
||||
if self.bytes_into_stdin.is_none() {
|
||||
panic!("{}", NO_STDIN_MEANINGLESS);
|
||||
}
|
||||
self.ignore_stdin_write_error = true;
|
||||
|
@ -813,13 +834,13 @@ impl UCommand {
|
|||
log_info("run", &self.comm_string);
|
||||
let mut child = self
|
||||
.raw
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.stdin(self.stdin.take().unwrap_or_else(|| Stdio::piped()))
|
||||
.stdout(self.stdout.take().unwrap_or_else(|| Stdio::piped()))
|
||||
.stderr(self.stderr.take().unwrap_or_else(|| Stdio::piped()))
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
if let Some(ref input) = self.stdin {
|
||||
if let Some(ref input) = self.bytes_into_stdin {
|
||||
let write_result = child
|
||||
.stdin
|
||||
.take()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue