// 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. #![allow(unused_imports)] mod common; use common::util::TestScenario; #[cfg(unix)] use std::os::unix::fs::symlink as symlink_file; #[cfg(windows)] use std::os::windows::fs::symlink_file; #[test] #[cfg(feature = "ls")] fn execution_phrase_double() { use std::process::Command; let scenario = TestScenario::new("ls"); let output = Command::new(&scenario.bin_path) .arg("ls") .arg("--some-invalid-arg") .output() .unwrap(); assert!(String::from_utf8(output.stderr) .unwrap() .contains(&format!("Usage: {} ls", scenario.bin_path.display(),))); } #[test] #[cfg(feature = "ls")] #[cfg(any(unix, windows))] fn execution_phrase_single() { use std::process::Command; let scenario = TestScenario::new("ls"); symlink_file(scenario.bin_path, scenario.fixtures.plus("uu-ls")).unwrap(); let output = Command::new(scenario.fixtures.plus("uu-ls")) .arg("--some-invalid-arg") .output() .unwrap(); dbg!(String::from_utf8(output.stderr.clone()).unwrap()); assert!(String::from_utf8(output.stderr).unwrap().contains(&format!( "Usage: {}", scenario.fixtures.plus("uu-ls").display() ))); } #[test] #[cfg(feature = "sort")] fn util_name_double() { use std::{ io::Write, process::{Command, Stdio}, }; let scenario = TestScenario::new("sort"); let mut child = Command::new(scenario.bin_path) .arg("sort") .stdin(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); // input invalid utf8 to cause an error child.stdin.take().unwrap().write_all(&[255]).unwrap(); let output = child.wait_with_output().unwrap(); assert!(String::from_utf8(output.stderr).unwrap().contains("sort: ")); } #[test] #[cfg(feature = "sort")] #[cfg(any(unix, windows))] fn util_name_single() { use std::{ io::Write, process::{Command, Stdio}, }; let scenario = TestScenario::new("sort"); symlink_file(scenario.bin_path, scenario.fixtures.plus("uu-sort")).unwrap(); let mut child = Command::new(scenario.fixtures.plus("uu-sort")) .stdin(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); // input invalid utf8 to cause an error child.stdin.take().unwrap().write_all(&[255]).unwrap(); let output = child.wait_with_output().unwrap(); assert!(String::from_utf8(output.stderr).unwrap().contains(&format!( "{}: ", scenario.fixtures.plus("uu-sort").display() ))); } #[test] #[cfg(any(unix, windows))] fn util_invalid_name_help() { use std::{ io::Write, process::{Command, Stdio}, }; let scenario = TestScenario::new("invalid_name"); symlink_file(scenario.bin_path, scenario.fixtures.plus("invalid_name")).unwrap(); let child = Command::new(scenario.fixtures.plus("invalid_name")) .arg("--help") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); let output = child.wait_with_output().unwrap(); assert_eq!(output.status.code(), Some(0)); assert_eq!(output.stderr, b""); let output_str = String::from_utf8(output.stdout).unwrap(); assert!(output_str.contains("(multi-call binary)"), "{output_str:?}"); assert!( output_str.contains("Usage: invalid_name [function "), "{output_str:?}" ); } #[test] // The exact set of permitted filenames depends on many factors. Non-UTF-8 strings // work on very few platforms, but linux works, especially because it also increases // the likelihood that a filesystem is being used that supports non-UTF-8 filenames. #[cfg(target_os = "linux")] fn util_non_utf8_name_help() { // Make sure we don't crash even if the util name is invalid UTF-8. use std::{ ffi::OsStr, io::Write, os::unix::ffi::OsStrExt, path::Path, process::{Command, Stdio}, }; let scenario = TestScenario::new("invalid_name"); let non_utf8_path = scenario.fixtures.plus(OsStr::from_bytes(b"\xff")); symlink_file(scenario.bin_path, &non_utf8_path).unwrap(); let child = Command::new(&non_utf8_path) .arg("--help") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); let output = child.wait_with_output().unwrap(); assert_eq!(output.status.code(), Some(0)); assert_eq!(output.stderr, b""); let output_str = String::from_utf8(output.stdout).unwrap(); assert!(output_str.contains("(multi-call binary)"), "{output_str:?}"); assert!( output_str.contains("Usage: [function "), "{output_str:?}" ); } #[test] #[cfg(any(unix, windows))] fn util_invalid_name_invalid_command() { use std::{ io::Write, process::{Command, Stdio}, }; let scenario = TestScenario::new("invalid_name"); symlink_file(scenario.bin_path, scenario.fixtures.plus("invalid_name")).unwrap(); let child = Command::new(scenario.fixtures.plus("invalid_name")) .arg("definitely_invalid") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); let output = child.wait_with_output().unwrap(); assert_eq!(output.status.code(), Some(1)); assert_eq!(output.stderr, b""); assert_eq!( output.stdout, b"definitely_invalid: function/utility not found\n" ); } #[test] #[cfg(feature = "true")] fn util_completion() { use std::{ io::Write, process::{Command, Stdio}, }; let scenario = TestScenario::new("completion"); let child = Command::new(scenario.bin_path) .arg("completion") .arg("true") .arg("powershell") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); let output = child.wait_with_output().unwrap(); assert_eq!(output.status.code(), Some(0)); assert_eq!(output.stderr, b""); let output_str = String::from_utf8(output.stdout).unwrap(); assert!( output_str.contains("using namespace System.Management.Automation"), "{output_str:?}" ); } #[test] #[cfg(feature = "true")] fn util_manpage() { use std::{ io::Write, process::{Command, Stdio}, }; let scenario = TestScenario::new("completion"); let child = Command::new(scenario.bin_path) .arg("manpage") .arg("true") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .unwrap(); let output = child.wait_with_output().unwrap(); assert_eq!(output.status.code(), Some(0)); assert_eq!(output.stderr, b""); let output_str = String::from_utf8(output.stdout).unwrap(); assert!(output_str.contains("\n.TH true 1 "), "{output_str:?}"); }