mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
rewrite tests for cargo compat, decoupled directory, output handling
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
use common::util::*;
|
||||
|
||||
static UTIL_NAME: &'static str = "base64";
|
||||
|
||||
#[test]
|
||||
fn test_encode() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let input = "hello, world!";
|
||||
let result = ucmd.run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, "aGVsbG8sIHdvcmxkIQ==\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let input = "aGVsbG8sIHdvcmxkIQ==";
|
||||
let result = ucmd.arg("-d").run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, "hello, world!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_garbage() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let input = "aGVsbG8sIHdvcmxkIQ==\0";
|
||||
let result = ucmd.arg("-d").run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert!(!result.success);
|
||||
assert_eq!(result.stderr,
|
||||
"base64: error: invalid character (Invalid character '0' at position 20)\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ignore_garbage() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let input = "aGVsbG8sIHdvcmxkIQ==\0";
|
||||
let result = ucmd.arg("-d").arg("-i").run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, "hello, world!");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_wrap() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let input = "The quick brown fox jumps over the lazy dog.";
|
||||
let result = ucmd.arg("-w").arg("20").run_piped_stdin(input.as_bytes());
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout,
|
||||
"VGhlIHF1aWNrIGJyb3du\nIGZveCBqdW1wcyBvdmVy\nIHRoZSBsYXp5IGRvZy4=\n");
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
use common::util::*;
|
||||
|
||||
static UTIL_NAME: &'static str = "basename";
|
||||
|
||||
#[test]
|
||||
fn test_directory() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let dir = "/root/alpha/beta/gamma/delta/epsilon/omega/";
|
||||
ucmd.arg(dir);
|
||||
|
||||
assert_eq!(ucmd.run().stdout.trim_right(), "omega");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_file() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let file = "/etc/passwd";
|
||||
ucmd.arg(file);
|
||||
|
||||
assert_eq!(ucmd.run().stdout.trim_right(), "passwd");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_suffix() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let path = "/usr/local/bin/reallylongexecutable.exe";
|
||||
ucmd.arg(path)
|
||||
.arg(".exe");
|
||||
|
||||
assert_eq!(ucmd.run().stdout.trim_right(), "reallylongexecutable");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dont_remove_suffix() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let path = "/foo/bar/baz";
|
||||
ucmd.arg(path)
|
||||
.arg("baz");
|
||||
|
||||
assert_eq!(ucmd.run().stdout.trim_right(), "baz");
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
use common::util::*;
|
||||
|
||||
static UTIL_NAME: &'static str = "cat";
|
||||
|
||||
#[test]
|
||||
fn test_output_multi_files_print_all_chars() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
ucmd.arg("alpha.txt")
|
||||
.arg("256.txt")
|
||||
.arg("-A")
|
||||
.arg("-n");
|
||||
|
||||
assert_eq!(ucmd.run().stdout,
|
||||
" 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_stdin_squeeze() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let out = ucmd.arg("-A")
|
||||
.run_piped_stdin("\x00\x01\x02".as_bytes())
|
||||
.stdout;
|
||||
|
||||
assert_eq!(out, "^@^A^B");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin_number_non_blank() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let out = ucmd.arg("-b")
|
||||
.arg("-")
|
||||
.run_piped_stdin("\na\nb\n\n\nc".as_bytes())
|
||||
.stdout;
|
||||
|
||||
assert_eq!(out, "\n 1\ta\n 2\tb\n\n\n 3\tc");
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
use common::util::*;
|
||||
|
||||
static UTIL_NAME: &'static str = "cksum";
|
||||
|
||||
#[test]
|
||||
fn test_single_file() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
let result = ucmd.arg("lorem_ipsum.txt").run();
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, at.read("single_file.expected"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_files() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
let result = ucmd.arg("lorem_ipsum.txt")
|
||||
.arg("alice_in_wonderland.txt")
|
||||
.run();
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, at.read("multiple_files.expected"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdin() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
let input = at.read("lorem_ipsum.txt");
|
||||
let result = ucmd.run_piped_stdin(input);
|
||||
|
||||
assert_empty_stderr!(result);
|
||||
assert!(result.success);
|
||||
assert_eq!(result.stdout, at.read("stdin.expected"));
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#[macro_use]
|
||||
pub mod util;
|
||||
@@ -0,0 +1,354 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
extern crate tempdir;
|
||||
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{Read, Write, Result};
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::fs::symlink as symlink_file;
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::fs::symlink_file;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::str::from_utf8;
|
||||
use std::ffi::OsStr;
|
||||
use self::tempdir::TempDir;
|
||||
use std::rc::Rc;
|
||||
|
||||
static PROGNAME: &'static str = "target/debug/uutils";
|
||||
static FIXTURES_DIR: &'static str = "tests/fixtures";
|
||||
static ALREADY_RUN: &'static str = " you have already run this UCommand, if you want to run \
|
||||
another command in the same test, use TestSet::new instead of \
|
||||
testing();";
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_empty_stderr(
|
||||
($cond:expr) => (
|
||||
if $cond.stderr.len() > 0 {
|
||||
panic!(format!("stderr: {}", $cond.stderr))
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! assert_no_error(
|
||||
($cond:expr) => (
|
||||
assert!($cond.success);
|
||||
if $cond.stderr.len() > 0 {
|
||||
panic!(format!("stderr: {}", $cond.stderr))
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
pub struct CmdResult {
|
||||
pub success: bool,
|
||||
pub stdout: String,
|
||||
pub stderr: String,
|
||||
}
|
||||
|
||||
pub fn log_info<T: AsRef<str>, U: AsRef<str>>(msg: T, par: U) {
|
||||
println!("{}: {}", msg.as_ref(), par.as_ref());
|
||||
}
|
||||
|
||||
|
||||
pub fn repeat_str(s: &str, n: u32) -> String {
|
||||
let mut repeated = String::new();
|
||||
for _ in 0..n {
|
||||
repeated.push_str(s);
|
||||
}
|
||||
repeated
|
||||
}
|
||||
|
||||
pub fn recursive_copy(src: &Path, dest: &Path) -> Result<()> {
|
||||
if try!(fs::metadata(src)).is_dir() {
|
||||
for entry in try!(fs::read_dir(src)) {
|
||||
let entry = try!(entry);
|
||||
let mut new_dest = PathBuf::from(dest);
|
||||
new_dest.push(entry.file_name());
|
||||
if try!(fs::metadata(entry.path())).is_dir() {
|
||||
try!(fs::create_dir(&new_dest));
|
||||
try!(recursive_copy(&entry.path(), &new_dest));
|
||||
} else {
|
||||
try!(fs::copy(&entry.path(), new_dest));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct AtPath {
|
||||
pub subdir: PathBuf,
|
||||
}
|
||||
impl AtPath {
|
||||
pub fn new(subdir: &Path) -> AtPath {
|
||||
AtPath { subdir: PathBuf::from(subdir) }
|
||||
}
|
||||
pub fn as_string(&self) -> String {
|
||||
self.subdir.to_str().unwrap().to_owned()
|
||||
}
|
||||
pub fn plus(&self, name: &str) -> PathBuf {
|
||||
let mut pathbuf = self.subdir.clone();
|
||||
pathbuf.push(name);
|
||||
pathbuf
|
||||
}
|
||||
pub fn plus_as_string(&self, name: &str) -> String {
|
||||
String::from(self.plus(name).to_str().unwrap())
|
||||
}
|
||||
fn minus(&self, name: &str) -> PathBuf {
|
||||
// relative_from is currently unstable
|
||||
let prefixed = PathBuf::from(name);
|
||||
if prefixed.starts_with(&self.subdir) {
|
||||
let mut unprefixed = PathBuf::new();
|
||||
for component in prefixed.components()
|
||||
.skip(self.subdir.components().count()) {
|
||||
unprefixed.push(component.as_ref().to_str().unwrap());
|
||||
}
|
||||
unprefixed
|
||||
} else {
|
||||
prefixed
|
||||
}
|
||||
}
|
||||
pub fn minus_as_string(&self, name: &str) -> String {
|
||||
String::from(self.minus(name).to_str().unwrap())
|
||||
}
|
||||
pub fn open(&self, name: &str) -> File {
|
||||
log_info("open", self.plus_as_string(name));
|
||||
File::open(self.plus(name)).unwrap()
|
||||
}
|
||||
pub fn read(&self, name: &str) -> String {
|
||||
let mut f = self.open(name);
|
||||
let mut contents = String::new();
|
||||
let _ = f.read_to_string(&mut contents);
|
||||
contents
|
||||
}
|
||||
pub fn write(&self, name: &str, contents: &str) {
|
||||
let mut f = self.open(name);
|
||||
let _ = f.write(contents.as_bytes());
|
||||
}
|
||||
pub fn mkdir(&self, dir: &str) {
|
||||
log_info("mkdir", self.plus_as_string(dir));
|
||||
fs::create_dir(&self.plus(dir)).unwrap();
|
||||
}
|
||||
pub fn mkdir_all(&self, dir: &str) {
|
||||
log_info("mkdir_all", self.plus_as_string(dir));
|
||||
fs::create_dir_all(self.plus(dir)).unwrap();
|
||||
}
|
||||
pub fn make_file(&self, name: &str) -> File {
|
||||
match File::create(&self.plus(name)) {
|
||||
Ok(f) => f,
|
||||
Err(e) => panic!("{}", e),
|
||||
}
|
||||
}
|
||||
pub fn touch(&self, file: &str) {
|
||||
log_info("touch", self.plus_as_string(file));
|
||||
File::create(&self.plus(file)).unwrap();
|
||||
}
|
||||
pub fn symlink(&self, src: &str, dst: &str) {
|
||||
log_info("symlink",
|
||||
&format!("{},{}", self.plus_as_string(src), self.plus_as_string(dst)));
|
||||
symlink_file(&self.plus(src), &self.plus(dst)).unwrap();
|
||||
}
|
||||
pub fn is_symlink(&self, path: &str) -> bool {
|
||||
log_info("is_symlink", self.plus_as_string(path));
|
||||
match fs::symlink_metadata(&self.plus(path)) {
|
||||
Ok(m) => m.file_type().is_symlink(),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_link(&self, path: &str) -> String {
|
||||
log_info("resolve_link", self.plus_as_string(path));
|
||||
match fs::read_link(&self.plus(path)) {
|
||||
Ok(p) => {
|
||||
self.minus_as_string(p.to_str().unwrap())
|
||||
}
|
||||
Err(_) => "".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn metadata(&self, path: &str) -> fs::Metadata {
|
||||
match fs::metadata(&self.plus(path)) {
|
||||
Ok(m) => m,
|
||||
Err(e) => panic!("{}", e),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn file_exists(&self, path: &str) -> bool {
|
||||
match fs::metadata(&self.plus(path)) {
|
||||
Ok(m) => m.is_file(),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dir_exists(&self, path: &str) -> bool {
|
||||
match fs::metadata(&self.plus(path)) {
|
||||
Ok(m) => m.is_dir(),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cleanup(&self, path: &'static str) {
|
||||
let p = &self.plus(path);
|
||||
match fs::metadata(p) {
|
||||
Ok(m) => if m.is_file() {
|
||||
fs::remove_file(&p).unwrap();
|
||||
} else {
|
||||
fs::remove_dir(&p).unwrap();
|
||||
},
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
pub fn root_dir(&self) -> String {
|
||||
log_info("current_directory", "");
|
||||
self.subdir.to_str().unwrap().to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TestSet {
|
||||
bin_path: PathBuf,
|
||||
util_name: String,
|
||||
pub fixtures: AtPath,
|
||||
tmpd: Rc<TempDir>,
|
||||
}
|
||||
impl TestSet {
|
||||
pub fn new(util_name: &str) -> TestSet {
|
||||
let tmpd = Rc::new(TempDir::new("uutils").unwrap());
|
||||
let ts = TestSet {
|
||||
bin_path: {
|
||||
let mut bin_path_builder = env::current_dir().unwrap();
|
||||
bin_path_builder.push(PathBuf::from(PROGNAME));
|
||||
bin_path_builder
|
||||
},
|
||||
util_name: String::from(util_name),
|
||||
fixtures: AtPath::new(&tmpd.as_ref().path()),
|
||||
tmpd: tmpd,
|
||||
};
|
||||
let mut fixture_path_builder = env::current_dir().unwrap();
|
||||
fixture_path_builder.push(PathBuf::from(FIXTURES_DIR));
|
||||
fixture_path_builder.push(PathBuf::from(util_name));
|
||||
match fs::metadata(&fixture_path_builder) {
|
||||
Ok(m) => if m.is_dir() {
|
||||
recursive_copy(&fixture_path_builder, &ts.fixtures.subdir).unwrap();
|
||||
},
|
||||
Err(_) => {}
|
||||
}
|
||||
ts
|
||||
}
|
||||
pub fn util_cmd(&self) -> UCommand {
|
||||
let mut cmd = self.cmd(&self.bin_path);
|
||||
cmd.arg(&self.util_name);
|
||||
cmd
|
||||
}
|
||||
pub fn cmd<S: AsRef<OsStr>>(&self, bin: S) -> UCommand {
|
||||
UCommand::new_from_tmp(bin, self.tmpd.clone(), true)
|
||||
}
|
||||
// different names are used rather than an argument
|
||||
// because the need to keep the environment is exceedingly rare.
|
||||
pub fn util_cmd_keepenv(&self) -> UCommand {
|
||||
let mut cmd = self.cmd_keepenv(&self.bin_path);
|
||||
cmd.arg(&self.util_name);
|
||||
cmd
|
||||
}
|
||||
pub fn cmd_keepenv<S: AsRef<OsStr>>(&self, bin: S) -> UCommand {
|
||||
UCommand::new_from_tmp(bin, self.tmpd.clone(), false)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UCommand {
|
||||
pub raw: Command,
|
||||
comm_string: String,
|
||||
tmpd: Option<Rc<TempDir>>,
|
||||
has_run: bool,
|
||||
}
|
||||
impl UCommand {
|
||||
pub fn new<T: AsRef<OsStr>, U: AsRef<OsStr>>(arg: T, curdir: U, env_clear: bool) -> UCommand {
|
||||
UCommand {
|
||||
tmpd: None,
|
||||
has_run: false,
|
||||
raw: {
|
||||
let mut cmd = Command::new(arg.as_ref());
|
||||
cmd.current_dir(curdir.as_ref());
|
||||
if env_clear {
|
||||
cmd.env_clear();
|
||||
}
|
||||
cmd
|
||||
},
|
||||
comm_string: String::from(arg.as_ref().to_str().unwrap()),
|
||||
}
|
||||
}
|
||||
pub fn new_from_tmp<T: AsRef<OsStr>>(arg: T, tmpd: Rc<TempDir>, env_clear: bool) -> UCommand {
|
||||
let tmpd_path_buf = String::from(&(*tmpd.as_ref().path().to_str().unwrap()));
|
||||
let mut ucmd: UCommand = UCommand::new(arg.as_ref(), tmpd_path_buf, env_clear);
|
||||
ucmd.tmpd = Some(tmpd);
|
||||
ucmd
|
||||
}
|
||||
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> Box<&mut UCommand> {
|
||||
if self.has_run {
|
||||
panic!(ALREADY_RUN);
|
||||
}
|
||||
self.comm_string.push_str(" ");
|
||||
self.comm_string.push_str(arg.as_ref().to_str().unwrap());
|
||||
self.raw.arg(arg.as_ref());
|
||||
Box::new(self)
|
||||
}
|
||||
|
||||
pub fn args<S: AsRef<OsStr>>(&mut self, args: &[S]) -> Box<&mut UCommand> {
|
||||
if self.has_run {
|
||||
panic!(ALREADY_RUN);
|
||||
}
|
||||
for s in args {
|
||||
self.comm_string.push_str(" ");
|
||||
self.comm_string.push_str(s.as_ref().to_str().unwrap());
|
||||
}
|
||||
|
||||
self.raw.args(args.as_ref());
|
||||
Box::new(self)
|
||||
}
|
||||
pub fn run(&mut self) -> CmdResult {
|
||||
self.has_run = true;
|
||||
log_info("run", &self.comm_string);
|
||||
let prog = self.raw.output().unwrap();
|
||||
CmdResult {
|
||||
success: prog.status.success(),
|
||||
stdout: from_utf8(&prog.stdout).unwrap().to_string(),
|
||||
stderr: from_utf8(&prog.stderr).unwrap().to_string(),
|
||||
}
|
||||
}
|
||||
pub fn run_piped_stdin<T: AsRef<[u8]>>(&mut self, input: T) -> CmdResult {
|
||||
self.has_run = true;
|
||||
log_info("run_piped_stdin", &self.comm_string);
|
||||
let mut result = self.raw
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.unwrap();
|
||||
|
||||
result.stdin
|
||||
.take()
|
||||
.unwrap_or_else(|| panic!("Could not take child process stdin"))
|
||||
.write_all(input.as_ref())
|
||||
.unwrap_or_else(|e| panic!("{}", e));
|
||||
|
||||
let prog = result.wait_with_output().unwrap();
|
||||
CmdResult {
|
||||
success: prog.status.success(),
|
||||
stdout: from_utf8(&prog.stdout).unwrap().to_string(),
|
||||
stderr: from_utf8(&prog.stderr).unwrap().to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns a testSet and a ucommand initialized to the utility binary
|
||||
// operating in the fixtures directory with a cleared environment
|
||||
pub fn testset_and_ucommand(utilname: &str) -> (TestSet, UCommand) {
|
||||
let ts = TestSet::new(utilname);
|
||||
let ucmd = ts.util_cmd();
|
||||
(ts, ucmd)
|
||||
}
|
||||
pub fn testing(utilname: &str) -> (AtPath, UCommand) {
|
||||
let ts = TestSet::new(utilname);
|
||||
let ucmd = ts.util_cmd();
|
||||
(ts.fixtures, ucmd)
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
use common::util::*;
|
||||
|
||||
static UTIL_NAME: &'static str = "cp";
|
||||
|
||||
static TEST_HELLO_WORLD_SOURCE: &'static str = "hello_world.txt";
|
||||
static TEST_HELLO_WORLD_DEST: &'static str = "copy_of_hello_world.txt";
|
||||
|
||||
#[test]
|
||||
fn test_cp_cp() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
// 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_eq!(exit_success, true);
|
||||
|
||||
// Check the content of the destination file that was copied.
|
||||
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
use common::util::*;
|
||||
|
||||
static UTIL_NAME: &'static str = "cut";
|
||||
|
||||
static INPUT: &'static str = "lists.txt";
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_prefix() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
let result = ucmd.args(&["-c", "-10", INPUT]).run();
|
||||
assert_eq!(result.stdout, at.read("lists_prefix.expected"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_char_range() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
let result = ucmd.args(&["-c", "4-10", INPUT]).run();
|
||||
assert_eq!(result.stdout, at.read("lists_char_range.expected"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_column_to_end_of_line() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
let result = ucmd.args(&["-d", ":", "-f", "5-", INPUT]).run();
|
||||
assert_eq!(result.stdout,
|
||||
at.read("lists_column_to_end_of_line.expected"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_specific_field() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
let result = ucmd.args(&["-d", " ", "-f", "3", INPUT]).run();
|
||||
assert_eq!(result.stdout, at.read("lists_specific_field.expected"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_fields() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
let result = ucmd.args(&["-d", ":", "-f", "1,3", INPUT]).run();
|
||||
assert_eq!(result.stdout, at.read("lists_multiple_fields.expected"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tail() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
let result = ucmd.args(&["-d", ":", "--complement", "-f", "1", INPUT]).run();
|
||||
assert_eq!(result.stdout, at.read("lists_tail.expected"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_change_delimiter() {
|
||||
let (at, mut ucmd) = testing(UTIL_NAME);
|
||||
let result = ucmd.args(&["-d", ":", "--complement", "--output-delimiter=#", "-f", "1", INPUT])
|
||||
.run();
|
||||
assert_eq!(result.stdout, at.read("lists_change_delimiter.expected"));
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
use common::util::*;
|
||||
|
||||
static UTIL_NAME: &'static str = "dirname";
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_path_with_trailing_slashes() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let dir = "/root/alpha/beta/gamma/delta/epsilon/omega//";
|
||||
let out = ucmd.arg(dir).run().stdout;
|
||||
|
||||
assert_eq!(out.trim_right(), "/root/alpha/beta/gamma/delta/epsilon");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_path_without_trailing_slashes() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let dir = "/root/alpha/beta/gamma/delta/epsilon/omega";
|
||||
let out = ucmd.arg(dir).run().stdout;
|
||||
|
||||
assert_eq!(out.trim_right(), "/root/alpha/beta/gamma/delta/epsilon");
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
use common::util::*;
|
||||
|
||||
static UTIL_NAME: &'static str = "echo";
|
||||
|
||||
#[test]
|
||||
fn test_default() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
assert_eq!(ucmd.run().stdout, "\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_trailing_newline() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
ucmd.arg("-n")
|
||||
.arg("hello_world");
|
||||
|
||||
assert_eq!(ucmd.run().stdout, "hello_world");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_enable_escapes() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
ucmd.arg("-e")
|
||||
.arg("\\\\\\t\\r");
|
||||
|
||||
assert_eq!(ucmd.run().stdout, "\\\t\r\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_disable_escapes() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
ucmd.arg("-E")
|
||||
.arg("\\b\\c\\e");
|
||||
|
||||
assert_eq!(ucmd.run().stdout, "\\b\\c\\e\n");
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
use common::util::*;
|
||||
|
||||
static UTIL_NAME: &'static str = "env";
|
||||
|
||||
#[test]
|
||||
fn test_single_name_value_pair() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let out = ucmd.arg("FOO=bar").run().stdout;
|
||||
|
||||
assert!(out.lines().any(|line| line == "FOO=bar"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_name_value_pairs() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let out = 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 ts = TestSet::new(UTIL_NAME);
|
||||
|
||||
let out = ts.util_cmd()
|
||||
.arg("-i")
|
||||
.run()
|
||||
.stdout;
|
||||
|
||||
assert_eq!(out, "");
|
||||
|
||||
let out = ts.util_cmd()
|
||||
.arg("-")
|
||||
.run()
|
||||
.stdout;
|
||||
|
||||
assert_eq!(out, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_null_delimiter() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let out = ucmd.arg("-i")
|
||||
.arg("--null")
|
||||
.arg("FOO=bar")
|
||||
.arg("ABC=xyz")
|
||||
.run()
|
||||
.stdout;
|
||||
|
||||
assert_eq!(out, "FOO=bar\0ABC=xyz\0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unset_variable() {
|
||||
// This test depends on the HOME variable being pre-defined by the
|
||||
// default shell
|
||||
let out = TestSet::new(UTIL_NAME)
|
||||
.util_cmd_keepenv()
|
||||
.arg("-u")
|
||||
.arg("HOME")
|
||||
.run()
|
||||
.stdout;
|
||||
|
||||
assert_eq!(out.lines().any(|line| line.starts_with("HOME=")), false);
|
||||
}
|
||||
+1057
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
#[macro_use]
|
||||
mod common;
|
||||
|
||||
use common::util::*;
|
||||
|
||||
static UTIL_NAME: &'static str = "false";
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_exit_code() {
|
||||
let (_, mut ucmd) = testing(UTIL_NAME);
|
||||
let exit_status = ucmd.run().success;
|
||||
assert_eq!(exit_status, false);
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
abcde
|
||||
fghij
|
||||
klmno
|
||||
pqrst
|
||||
uvwxyz
|
||||
@@ -0,0 +1,5 @@
|
||||
Alice was beginning to get very tired of sitting by
|
||||
her sister on the bank, and of having nothing to do: once or twice
|
||||
she had peeped into the book her sister was reading, but it had no
|
||||
pictures or conversations in it, "and what is the use of a book,"
|
||||
thought Alice "without pictures or conversation?"
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing
|
||||
elit. Nunc interdum suscipit sem vel ornare. Proin euismod, justo
|
||||
sed mollis dictum, eros urna ultricies augue, eu pharetra mi ex id
|
||||
ante. Duis convallis porttitor aliquam. Nunc vitae tincidunt ex.
|
||||
Suspendisse iaculis ligula ac diam consectetur lacinia. Donec vel
|
||||
velit dui. Etiam fringilla, dolor quis tempor vehicula, lacus
|
||||
turpis bibendum velit, et pellentesque elit odio a magna. Cras
|
||||
vulputate tortor non libero vehicula euismod. Aliquam tincidunt
|
||||
nisl eget enim cursus, viverra sagittis magna commodo. Cras rhoncus
|
||||
egestas leo nec blandit. Suspendisse potenti. Etiam ullamcorper
|
||||
leo vel lacus vestibulum, cursus semper eros efficitur. In hac
|
||||
habitasse platea dictumst. Phasellus scelerisque vehicula
|
||||
fringilla.
|
||||
@@ -0,0 +1,2 @@
|
||||
378294376 772 lorem_ipsum.txt
|
||||
3805907707 302 alice_in_wonderland.txt
|
||||
+1
@@ -0,0 +1 @@
|
||||
378294376 772 lorem_ipsum.txt
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
378294376 772
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user