rewrite tests for cargo compat, decoupled directory, output handling

This commit is contained in:
Nathan Ross 2015-11-16 00:25:01 -05:00
parent b20b2cca19
commit a21c54e2cd
165 changed files with 4315 additions and 3538 deletions

View file

@ -157,6 +157,19 @@ wc = { optional=true, path="src/wc" }
whoami = { optional=true, path="src/whoami" }
yes = { optional=true, path="src/yes" }
[dev-dependencies]
time = "*"
kernel32-sys = "*"
winapi = "*"
filetime = "*"
libc = "*"
memchr = "*"
primal = "*"
aho-corasick= "*"
regex-syntax= "*"
regex="*"
rand="*"
tempdir="*"
[[bin]]
name="uutils"

View file

@ -18,7 +18,7 @@ LIBDIR ?= /lib
BASEDIR ?= $(shell pwd)
SRCDIR := $(BASEDIR)/src
BUILDDIR := $(BASEDIR)/build
TESTDIR := $(BASEDIR)/test
TESTDIR := $(BASEDIR)/tests
TEMPDIR := $(BASEDIR)/tmp
# Flags

View file

@ -1,62 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./base64";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_encode() {
let input = "hello, world!";
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd, input.as_bytes());
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, "aGVsbG8sIHdvcmxkIQ==\n");
}
#[test]
fn test_decode() {
let input = "aGVsbG8sIHdvcmxkIQ==";
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.arg("-d"), input.as_bytes());
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, "hello, world!");
}
#[test]
fn test_garbage() {
let input = "aGVsbG8sIHdvcmxkIQ==\0";
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.arg("-d"), 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 input = "aGVsbG8sIHdvcmxkIQ==\0";
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.arg("-d").arg("-i"), input.as_bytes());
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, "hello, world!");
}
#[test]
fn test_wrap() {
let input = "The quick brown fox jumps over the lazy dog.";
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.arg("-w").arg("20"), input.as_bytes());
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, "VGhlIHF1aWNrIGJyb3du\nIGZveCBqdW1wcyBvdmVy\nIHRoZSBsYXp5IGRvZy4=\n");
}

View file

@ -1,54 +0,0 @@
use std::process::Command;
use std::str;
static PROGNAME: &'static str = "./basename";
#[test]
fn test_directory() {
let dir = "/root/alpha/beta/gamma/delta/epsilon/omega/";
let po = Command::new(PROGNAME)
.arg(dir)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, "omega");
}
#[test]
fn test_file() {
let file = "/etc/passwd";
let po = Command::new(PROGNAME)
.arg(file)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, "passwd");
}
#[test]
fn test_remove_suffix() {
let path = "/usr/local/bin/reallylongexecutable.exe";
let po = Command::new(PROGNAME)
.arg(path)
.arg(".exe")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, "reallylongexecutable");
}
#[test]
fn test_dont_remove_suffix() {
let path = "/foo/bar/baz";
let po = Command::new(PROGNAME)
.arg(path)
.arg("baz")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, "baz");
}

View file

@ -1,60 +0,0 @@
use std::io::Write;
use std::process::Command;
use std::process::Stdio;
use std::str;
static PROGNAME: &'static str = "./cat";
#[test]
fn test_output_multi_files_print_all_chars() {
let po = match Command::new(PROGNAME)
.arg("alpha.txt")
.arg("256.txt")
.arg("-A")
.arg("-n").output() {
Ok(p) => p,
Err(err) => panic!("{}", err),
};
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out,
" 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-^VM-^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-UM-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 process = Command::new(PROGNAME)
.arg("-A")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("{}", e));
process.stdin.take().unwrap_or_else(|| panic!("Could not grab child process stdin"))
.write_all("\x00\x01\x02".as_bytes()).unwrap_or_else(|e| panic!("{}", e));
let po = process.wait_with_output().unwrap_or_else(|e| panic!("{}", e));
let out = str::from_utf8(&po.stdout[..]).unwrap_or_else(|e| panic!("{}", e));
assert_eq!(out, "^@^A^B");
}
#[test]
fn test_stdin_number_non_blank() {
let mut process = Command::new(PROGNAME)
.arg("-b")
.arg("-")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("{}", e));
process.stdin.take().unwrap_or_else(|| panic!("Could not grab child process stdin"))
.write_all("\na\nb\n\n\nc".as_bytes()).unwrap_or_else(|e| panic!("{}", e));
let po = process.wait_with_output().unwrap_or_else(|e| panic!("{}", e));
let out = str::from_utf8(&po.stdout[..]).unwrap_or_else(|e| panic!("{}", e));
assert_eq!(out, "\n 1\ta\n 2\tb\n\n\n 3\tc");
}

View file

@ -1,39 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./cksum";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_single_file() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.arg("lorem_ipsum.txt"));
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, get_file_contents("single_file.expected"));
}
#[test]
fn test_multiple_files() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.arg("lorem_ipsum.txt").arg("alice_in_wonderland.txt"));
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, get_file_contents("multiple_files.expected"));
}
#[test]
fn test_stdin() {
let input = get_file_contents("lorem_ipsum.txt");
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd, input);
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, get_file_contents("stdin.expected"));
}

View file

@ -1,152 +0,0 @@
#![allow(dead_code)]
use std::env;
use std::fs::{self, File};
use std::io::{Read, Write};
#[cfg(unix)]
use std::os::unix::fs::symlink as symlink_file;
#[cfg(windows)]
use std::os::windows::fs::symlink_file;
use std::path::Path;
use std::process::{Command, Stdio};
use std::str::from_utf8;
#[macro_export]
macro_rules! assert_empty_stderr(
($cond:expr) => (
if $cond.stderr.len() > 0 {
panic!(format!("stderr: {}", $cond.stderr))
}
);
);
pub struct CmdResult {
pub success: bool,
pub stdout: String,
pub stderr: String,
}
pub fn run(cmd: &mut Command) -> CmdResult {
let prog = cmd.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]>>(cmd: &mut Command, input: T)-> CmdResult {
let mut command = cmd
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
command.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 = command.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(),
}
}
pub fn get_file_contents(name: &str) -> String {
let mut f = File::open(Path::new(name)).unwrap();
let mut contents = String::new();
let _ = f.read_to_string(&mut contents);
contents
}
pub fn set_file_contents(name: &str, contents: &str) {
let mut f = File::open(Path::new(name)).unwrap();
let _ = f.write(contents.as_bytes());
}
pub fn mkdir(dir: &str) {
fs::create_dir(Path::new(dir)).unwrap();
}
pub fn mkdir_all(dir: &str) {
fs::create_dir_all(Path::new(dir)).unwrap();
}
pub fn make_file(name: &str) -> File {
match File::create(Path::new(name)) {
Ok(f) => f,
Err(e) => panic!("{}", e)
}
}
pub fn touch(file: &str) {
File::create(Path::new(file)).unwrap();
}
pub fn symlink(src: &str, dst: &str) {
symlink_file(src, dst).unwrap();
}
pub fn is_symlink(path: &str) -> bool {
match fs::symlink_metadata(path) {
Ok(m) => m.file_type().is_symlink(),
Err(_) => false
}
}
pub fn resolve_link(path: &str) -> String {
match fs::read_link(path) {
Ok(p) => p.to_str().unwrap().to_owned(),
Err(_) => "".to_string()
}
}
pub fn metadata(path: &str) -> fs::Metadata {
match fs::metadata(path) {
Ok(m) => m,
Err(e) => panic!("{}", e)
}
}
pub fn file_exists(path: &str) -> bool {
match fs::metadata(path) {
Ok(m) => m.is_file(),
Err(_) => false
}
}
pub fn dir_exists(path: &str) -> bool {
match fs::metadata(path) {
Ok(m) => m.is_dir(),
Err(_) => false
}
}
pub fn cleanup(path: &'static str) {
let p = Path::new(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 current_directory() -> String {
env::current_dir().unwrap().into_os_string().into_string().unwrap()
}
pub fn repeat_str(s: &str, n: u32) -> String {
let mut repeated = String::new();
for _ in 0 .. n {
repeated.push_str(s);
}
repeated
}

View file

@ -1,35 +0,0 @@
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::process::Command;
use util::*;
static PROGNAME: &'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";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_cp_cp() {
// Invoke our binary to make the copy.
let prog = Command::new(PROGNAME)
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_HELLO_WORLD_DEST)
.status();
// Check that the exit code represents a successful copy.
let exit_success = prog.unwrap().success();
assert_eq!(exit_success, true);
// Check the content of the destination file that was copied.
let mut contents = String::new();
let mut f = File::open(Path::new(TEST_HELLO_WORLD_DEST)).unwrap();
let _ = f.read_to_string(&mut contents);
assert_eq!(contents, "Hello, World!\n");
cleanup(TEST_HELLO_WORLD_SOURCE);
cleanup(TEST_HELLO_WORLD_DEST);
}

View file

@ -1,58 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./cut";
static INPUT: &'static str = "lists.txt";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_prefix() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-c", "-10", INPUT]));
assert_eq!(result.stdout, get_file_contents("lists_prefix.expected"));
}
#[test]
fn test_char_range() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-c", "4-10", INPUT]));
assert_eq!(result.stdout, get_file_contents("lists_char_range.expected"));
}
#[test]
fn test_column_to_end_of_line() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-d", ":", "-f", "5-", INPUT]));
assert_eq!(result.stdout, get_file_contents("lists_column_to_end_of_line.expected"));
}
#[test]
fn test_specific_field() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-d", " ", "-f", "3", INPUT]));
assert_eq!(result.stdout, get_file_contents("lists_specific_field.expected"));
}
#[test]
fn test_multiple_fields() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-d", ":", "-f", "1,3", INPUT]));
assert_eq!(result.stdout, get_file_contents("lists_multiple_fields.expected"));
}
#[test]
fn test_tail() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-d", ":", "--complement", "-f", "1", INPUT]));
assert_eq!(result.stdout, get_file_contents("lists_tail.expected"));
}
#[test]
fn test_change_delimiter() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-d", ":", "--complement", "--output-delimiter=#", "-f", "1", INPUT]));
assert_eq!(result.stdout, get_file_contents("lists_change_delimiter.expected"));
}

View file

@ -1,28 +0,0 @@
use std::process::Command;
use std::str;
static PROGNAME: &'static str = "./dirname";
#[test]
fn test_path_with_trailing_slashes() {
let dir = "/root/alpha/beta/gamma/delta/epsilon/omega//";
let po = Command::new(PROGNAME)
.arg(dir)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, "/root/alpha/beta/gamma/delta/epsilon");
}
#[test]
fn test_path_without_trailing_slashes() {
let dir = "/root/alpha/beta/gamma/delta/epsilon/omega";
let po = Command::new(PROGNAME)
.arg(dir)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, "/root/alpha/beta/gamma/delta/epsilon");
}

View file

@ -1,50 +0,0 @@
use std::process::Command;
use std::str;
static PROGNAME: &'static str = "./echo";
#[test]
fn test_default() {
let po = Command::new(PROGNAME)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out, "\n");
}
#[test]
fn test_no_trailing_newline() {
let po = Command::new(PROGNAME)
.arg("-n")
.arg("hello_world")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out, "hello_world");
}
#[test]
fn test_enable_escapes() {
let po = Command::new(PROGNAME)
.arg("-e")
.arg("\\\\\\t\\r")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out, "\\\t\r\n");
}
#[test]
fn test_disable_escapes() {
let po = Command::new(PROGNAME)
.arg("-E")
.arg("\\b\\c\\e")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out, "\\b\\c\\e\n");
}

View file

@ -1,74 +0,0 @@
use std::process::Command;
use std::str;
static PROGNAME: &'static str = "./env";
#[test]
fn test_single_name_value_pair() {
let po = Command::new(PROGNAME)
.arg("FOO=bar")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert!(out.lines().any(|line| line == "FOO=bar"));
}
#[test]
fn test_multiple_name_value_pairs() {
let po = Command::new(PROGNAME)
.arg("FOO=bar")
.arg("ABC=xyz")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out.lines().filter(|&line| line == "FOO=bar" || line == "ABC=xyz").count(), 2);
}
#[test]
fn test_ignore_environment() {
let po = Command::new(PROGNAME)
.arg("-i")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out, "");
let po = Command::new(PROGNAME)
.arg("-")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out, "");
}
#[test]
fn test_null_delimiter() {
let po = Command::new(PROGNAME)
.arg("-i")
.arg("--null")
.arg("FOO=bar")
.arg("ABC=xyz")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
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 po = Command::new(PROGNAME)
.arg("-u")
.arg("HOME")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out.lines().any(|line| line.starts_with("HOME=")), false);
}

View file

@ -1,534 +0,0 @@
/*
* This file is part of the uutils coreutils package.
*
* (c) kwantam <kwantam@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/
extern crate libc;
extern crate rand;
use rand::{weak_rng, Rng};
use rand::distributions::{IndependentSample, Range};
use sieve::Sieve;
use std::io::Write;
use std::process::{Command, Stdio};
#[path="../src/factor/sieve.rs"]
mod sieve;
const NUM_PRIMES: usize = 10000;
const LOG_PRIMES: f64 = 14.0; // ceil(log2(NUM_PRIMES))
const NUM_TESTS: usize = 100;
const PROGNAME: &'static str = "./factor";
#[test]
fn test_random() {
let primes = Sieve::primes().take(NUM_PRIMES).collect::<Vec<u64>>();
let mut rng = weak_rng();
let mut rand_gt = move |min: u64| {
let mut product = 1u64;
let mut factors = Vec::new();
while product < min {
// log distribution---higher probability for lower numbers
let factor;
loop {
let next = rng.gen_range(0f64, LOG_PRIMES).exp2().floor() as usize;
if next < NUM_PRIMES {
factor = primes[next];
break;
}
}
let factor = factor;
match product.checked_mul(factor) {
Some(p) => {
product = p;
factors.push(factor);
},
None => break,
};
}
factors.sort();
(product, factors)
};
// build an input and expected output string from factor
let mut instring = String::new();
let mut outstring = String::new();
for _ in 0..NUM_TESTS {
let (product, factors) = rand_gt(1 << 63);
instring.push_str(&(format!("{} ", product))[..]);
outstring.push_str(&(format!("{}:", product))[..]);
for factor in factors {
outstring.push_str(&(format!(" {}", factor))[..]);
}
outstring.push_str("\n");
}
run(instring.as_bytes(), outstring.as_bytes());
}
#[test]
fn test_random_big() {
let mut rng = weak_rng();
let bitrange_1 = Range::new(14usize, 51);
let mut rand_64 = move || {
// first, choose a random number of bits for the first factor
let f_bit_1 = bitrange_1.ind_sample(&mut rng);
// how many more bits do we need?
let rem = 64 - f_bit_1;
// we will have a number of additional factors equal to nfacts + 1
// where nfacts is in [0, floor(rem/14) ) NOTE half-open interval
// Each prime factor is at least 14 bits, hence floor(rem/14)
let nfacts = Range::new(0usize, rem / 14).ind_sample(&mut rng);
// we have to distribute extrabits among the (nfacts + 1) values
let extrabits = rem - (nfacts + 1) * 14;
// (remember, a Range is a half-open interval)
let extrarange = Range::new(0usize, extrabits + 1);
// to generate an even split of this range, generate n-1 random elements
// in the range, add the desired total value to the end, sort this list,
// and then compute the sequential differences.
let mut f_bits = Vec::new();
for _ in 0..nfacts {
f_bits.push(extrarange.ind_sample(&mut rng));
}
f_bits.push(extrabits);
f_bits.sort();
// compute sequential differences here. We leave off the +14 bits
// so we can just index PRIMES_BY_BITS
let mut f_bits = f_bits.iter().scan(0, |st,&x| {
let ret = x - *st; // + 14 would give actual number of bits
*st = x;
Some(ret)
}).collect::<Vec<usize>>();
// finally, add f_bit_1 in there
f_bits.push(f_bit_1 - 14); // index of f_bit_1 in PRIMES_BY_BITS
let f_bits = f_bits;
let mut nbits = 0;
let mut product = 1u64;
let mut factors = Vec::new();
for bit in f_bits {
assert!(bit < 37);
nbits += 14 + bit;
let elm = Range::new(0, PRIMES_BY_BITS[bit].len()).ind_sample(&mut rng);
let factor = PRIMES_BY_BITS[bit][elm];
factors.push(factor);
product *= factor;
}
assert_eq!(nbits, 64);
factors.sort();
(product, factors)
};
let mut instring = String::new();
let mut outstring = String::new();
for _ in 0..NUM_TESTS {
let (product, factors) = rand_64();
instring.push_str(&(format!("{} ", product))[..]);
outstring.push_str(&(format!("{}:", product))[..]);
for factor in factors {
outstring.push_str(&(format!(" {}", factor))[..]);
}
outstring.push_str("\n");
}
run(instring.as_bytes(), outstring.as_bytes());
}
#[test]
fn test_big_primes() {
let mut instring = String::new();
let mut outstring = String::new();
for prime in PRIMES64 {
instring.push_str(&(format!("{} ", prime))[..]);
outstring.push_str(&(format!("{0}: {0}\n", prime))[..]);
}
run(instring.as_bytes(), outstring.as_bytes());
}
fn run(instring: &[u8], outstring: &[u8]) {
// now run factor
let mut process = Command::new(PROGNAME)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap_or_else(|e| panic!("{}", e));
process.stdin.take().unwrap_or_else(|| panic!("Could not take child process stdin"))
.write_all(instring).unwrap_or_else(|e| panic!("{}", e));
let output = process.wait_with_output().unwrap_or_else(|e| panic!("{}", e));
assert_eq!(&output.stdout[..], outstring);
}
const PRIMES_BY_BITS: &'static [&'static [u64]] = &[PRIMES14, PRIMES15, PRIMES16, PRIMES17,
PRIMES18, PRIMES19, PRIMES20, PRIMES21, PRIMES22, PRIMES23, PRIMES24, PRIMES25, PRIMES26,
PRIMES27, PRIMES28, PRIMES29, PRIMES30, PRIMES31, PRIMES32, PRIMES33, PRIMES34, PRIMES35,
PRIMES36, PRIMES37, PRIMES38, PRIMES39, PRIMES40, PRIMES41, PRIMES42, PRIMES43, PRIMES44,
PRIMES45, PRIMES46, PRIMES47, PRIMES48, PRIMES49, PRIMES50,
];
const PRIMES64: &'static [u64] = &[18446744073709551557, 18446744073709551533,
18446744073709551521, 18446744073709551437, 18446744073709551427, 18446744073709551359,
18446744073709551337, 18446744073709551293, 18446744073709551263, 18446744073709551253,
18446744073709551191, 18446744073709551163, 18446744073709551113, 18446744073709550873,
18446744073709550791, 18446744073709550773, 18446744073709550771, 18446744073709550719,
18446744073709550717, 18446744073709550681, 18446744073709550671, 18446744073709550593,
18446744073709550591, 18446744073709550539, 18446744073709550537, 18446744073709550381,
18446744073709550341, 18446744073709550293, 18446744073709550237, 18446744073709550147,
18446744073709550141, 18446744073709550129, 18446744073709550111, 18446744073709550099,
18446744073709550047, 18446744073709550033, 18446744073709550009, 18446744073709549951,
18446744073709549861, 18446744073709549817, 18446744073709549811, 18446744073709549777,
18446744073709549757, 18446744073709549733, 18446744073709549667, 18446744073709549621,
18446744073709549613, 18446744073709549583, 18446744073709549571,
];
const PRIMES14: &'static [u64] = &[16381, 16369, 16363, 16361, 16349, 16339, 16333, 16319,
16301, 16273, 16267, 16253, 16249, 16231, 16229, 16223, 16217, 16193, 16189, 16187, 16183,
16141, 16139, 16127, 16111, 16103, 16097, 16091, 16087, 16073, 16069, 16067, 16063, 16061,
16057, 16033, 16007, 16001, 15991, 15973, 15971, 15959, 15937, 15923, 15919, 15913, 15907,
15901, 15889, 15887, 15881, 15877, 15859, 15823, 15817, 15809, 15803, 15797, 15791, 15787,
15773, 15767, 15761, 15749, 15739, 15737, 15733, 15731, 15727, 15683, 15679, 15671, 15667,
15661, 15649, 15647, 15643, 15641, 15629, 15619, 15607, 15601, 15583, 15581, 15569, 15559,
15551, 15541, 15527, 15511, 15497, 15493, 15473, 15467, 15461, 15451, 15443, 15439, 15427,
15413, 15401, 15391, 15383, 15377, 15373,
];
const PRIMES15: &'static [u64] = &[32749, 32719, 32717, 32713, 32707, 32693, 32687, 32653,
32647, 32633, 32621, 32611, 32609, 32603, 32587, 32579, 32573, 32569, 32563, 32561, 32537,
32533, 32531, 32507, 32503, 32497, 32491, 32479, 32467, 32443, 32441, 32429, 32423, 32413,
32411, 32401, 32381, 32377, 32371, 32369, 32363, 32359, 32353, 32341, 32327, 32323, 32321,
32309, 32303, 32299, 32297, 32261, 32257, 32251, 32237, 32233, 32213, 32203, 32191, 32189,
32183, 32173, 32159, 32143, 32141, 32119, 32117, 32099, 32089, 32083, 32077, 32069, 32063,
32059, 32057, 32051, 32029, 32027, 32009, 32003, 31991, 31981, 31973, 31963, 31957, 31907,
31891, 31883, 31873, 31859, 31849, 31847, 31817, 31799, 31793, 31771, 31769, 31751,
];
const PRIMES16: &'static [u64] = &[65521, 65519, 65497, 65479, 65449, 65447, 65437, 65423,
65419, 65413, 65407, 65393, 65381, 65371, 65357, 65353, 65327, 65323, 65309, 65293, 65287,
65269, 65267, 65257, 65239, 65213, 65203, 65183, 65179, 65173, 65171, 65167, 65147, 65141,
65129, 65123, 65119, 65111, 65101, 65099, 65089, 65071, 65063, 65053, 65033, 65029, 65027,
65011, 65003, 64997, 64969, 64951, 64937, 64927, 64921, 64919, 64901, 64891, 64879, 64877,
64871, 64853, 64849, 64817, 64811, 64793, 64783, 64781, 64763, 64747, 64717, 64709, 64693,
64679, 64667, 64663, 64661, 64633, 64627, 64621, 64613, 64609, 64601, 64591, 64579, 64577,
64567, 64553,
];
const PRIMES17: &'static [u64] = &[131071, 131063, 131059, 131041, 131023, 131011, 131009,
130987, 130981, 130973, 130969, 130957, 130927, 130873, 130859, 130843, 130841, 130829,
130817, 130811, 130807, 130787, 130783, 130769, 130729, 130699, 130693, 130687, 130681,
130657, 130651, 130649, 130643, 130639, 130633, 130631, 130621, 130619, 130589, 130579,
130553, 130547, 130531, 130523, 130517, 130513, 130489, 130483, 130477, 130469, 130457,
130447, 130439, 130423, 130411, 130409, 130399, 130379, 130369, 130367, 130363, 130349,
130343, 130337, 130307, 130303, 130279, 130267, 130261, 130259, 130253, 130241, 130223,
130211, 130201, 130199, 130183, 130171, 130147, 130127, 130121, 130099, 130087, 130079,
130073, 130069, 130057, 130051,
];
const PRIMES18: &'static [u64] = &[262139, 262133, 262127, 262121, 262111, 262109, 262103,
262079, 262069, 262051, 262049, 262027, 262007, 261983, 261977, 261973, 261971, 261959,
261917, 261887, 261881, 261847, 261823, 261799, 261791, 261787, 261773, 261761, 261757,
261739, 261721, 261713, 261707, 261697, 261673, 261643, 261641, 261637, 261631, 261619,
261601, 261593, 261587, 261581, 261577, 261563, 261557, 261529, 261523, 261509, 261467,
261463, 261451, 261439, 261433, 261431, 261427, 261407, 261389, 261379, 261353, 261347,
261337, 261329, 261323, 261301, 261281, 261271, 261251, 261241, 261229, 261223, 261169,
261167, 261127,
];
const PRIMES19: &'static [u64] = &[524287, 524269, 524261, 524257, 524243, 524231, 524221,
524219, 524203, 524201, 524197, 524189, 524171, 524149, 524123, 524119, 524113, 524099,
524087, 524081, 524071, 524063, 524057, 524053, 524047, 523997, 523987, 523969, 523949,
523937, 523927, 523907, 523903, 523877, 523867, 523847, 523829, 523801, 523793, 523777,
523771, 523763, 523759, 523741, 523729, 523717, 523681, 523673, 523669, 523667, 523657,
523639, 523637, 523631, 523603, 523597, 523577, 523573, 523571, 523553, 523543, 523541,
523519, 523511, 523493, 523489, 523487, 523463, 523459, 523433, 523427, 523417, 523403,
523387, 523357, 523351, 523349, 523333, 523307, 523297,
];
const PRIMES20: &'static [u64] = &[1048573, 1048571, 1048559, 1048549, 1048517, 1048507,
1048447, 1048433, 1048423, 1048391, 1048387, 1048367, 1048361, 1048357, 1048343, 1048309,
1048291, 1048273, 1048261, 1048219, 1048217, 1048213, 1048193, 1048189, 1048139, 1048129,
1048127, 1048123, 1048063, 1048051, 1048049, 1048043, 1048027, 1048013, 1048009, 1048007,
1047997, 1047989, 1047979, 1047971, 1047961, 1047941, 1047929, 1047923, 1047887, 1047883,
1047881, 1047859, 1047841, 1047833, 1047821, 1047779, 1047773, 1047763, 1047751, 1047737,
1047721, 1047713, 1047703, 1047701, 1047691, 1047689, 1047671, 1047667, 1047653, 1047649,
1047647, 1047589, 1047587, 1047559,
];
const PRIMES21: &'static [u64] = &[2097143, 2097133, 2097131, 2097097, 2097091, 2097083,
2097047, 2097041, 2097031, 2097023, 2097013, 2096993, 2096987, 2096971, 2096959, 2096957,
2096947, 2096923, 2096911, 2096909, 2096893, 2096881, 2096873, 2096867, 2096851, 2096837,
2096807, 2096791, 2096789, 2096777, 2096761, 2096741, 2096737, 2096713, 2096693, 2096687,
2096681, 2096639, 2096629, 2096621, 2096599, 2096597, 2096569, 2096539, 2096533, 2096483,
2096449, 2096431, 2096429, 2096411, 2096407, 2096401, 2096399, 2096377, 2096357, 2096291,
2096273, 2096261, 2096233, 2096231, 2096221, 2096209, 2096191, 2096183, 2096147,
];
const PRIMES22: &'static [u64] = &[4194301, 4194287, 4194277, 4194271, 4194247, 4194217,
4194199, 4194191, 4194187, 4194181, 4194173, 4194167, 4194143, 4194137, 4194131, 4194107,
4194103, 4194023, 4194011, 4194007, 4193977, 4193971, 4193963, 4193957, 4193939, 4193929,
4193909, 4193869, 4193807, 4193803, 4193801, 4193789, 4193759, 4193753, 4193743, 4193701,
4193663, 4193633, 4193573, 4193569, 4193551, 4193549, 4193531, 4193513, 4193507, 4193459,
4193447, 4193443, 4193417, 4193411, 4193393, 4193389, 4193381, 4193377, 4193369, 4193359,
4193353, 4193327, 4193309, 4193303, 4193297,
];
const PRIMES23: &'static [u64] = &[8388593, 8388587, 8388581, 8388571, 8388547, 8388539,
8388473, 8388461, 8388451, 8388449, 8388439, 8388427, 8388421, 8388409, 8388377, 8388371,
8388319, 8388301, 8388287, 8388283, 8388277, 8388239, 8388209, 8388187, 8388113, 8388109,
8388091, 8388071, 8388059, 8388019, 8388013, 8387999, 8387993, 8387959, 8387957, 8387947,
8387933, 8387921, 8387917, 8387891, 8387879, 8387867, 8387861, 8387857, 8387839, 8387831,
8387809, 8387807, 8387741, 8387737, 8387723, 8387707, 8387671, 8387611, 8387609, 8387591,
];
const PRIMES24: &'static [u64] = &[16777213, 16777199, 16777183, 16777153, 16777141, 16777139,
16777127, 16777121, 16777099, 16777049, 16777027, 16776989, 16776973, 16776971, 16776967,
16776961, 16776941, 16776937, 16776931, 16776919, 16776901, 16776899, 16776869, 16776857,
16776839, 16776833, 16776817, 16776763, 16776731, 16776719, 16776713, 16776691, 16776689,
16776679, 16776659, 16776631, 16776623, 16776619, 16776607, 16776593, 16776581, 16776547,
16776521, 16776491, 16776481, 16776469, 16776451, 16776401, 16776391, 16776379, 16776371,
16776367, 16776343, 16776337, 16776317, 16776313, 16776289, 16776217, 16776211,
];
const PRIMES25: &'static [u64] = &[33554393, 33554383, 33554371, 33554347, 33554341, 33554317,
33554291, 33554273, 33554267, 33554249, 33554239, 33554221, 33554201, 33554167, 33554159,
33554137, 33554123, 33554093, 33554083, 33554077, 33554051, 33554021, 33554011, 33554009,
33553999, 33553991, 33553969, 33553967, 33553909, 33553901, 33553879, 33553837, 33553799,
33553787, 33553771, 33553769, 33553759, 33553747, 33553739, 33553727, 33553697, 33553693,
33553679, 33553661, 33553657, 33553651, 33553649, 33553633, 33553613, 33553607, 33553577,
33553549, 33553547, 33553537, 33553519, 33553517, 33553511, 33553489, 33553463, 33553451,
33553417,
];
const PRIMES26: &'static [u64] = &[67108859, 67108837, 67108819, 67108777, 67108763,
67108757, 67108753, 67108747, 67108739, 67108729, 67108721, 67108709, 67108693, 67108669,
67108667, 67108661, 67108649, 67108633, 67108597, 67108579, 67108529, 67108511, 67108507,
67108493, 67108471, 67108463, 67108453, 67108439, 67108387, 67108373, 67108369, 67108351,
67108331, 67108313, 67108303, 67108289, 67108271, 67108219, 67108207, 67108201, 67108199,
67108187, 67108183, 67108177, 67108127, 67108109, 67108081, 67108049, 67108039, 67108037,
67108033, 67108009, 67108007, 67108003, 67107983, 67107977, 67107967, 67107941, 67107919,
67107913, 67107883, 67107881, 67107871, 67107863,
];
const PRIMES27: &'static [u64] = &[134217689, 134217649, 134217617, 134217613, 134217593,
134217541, 134217529, 134217509, 134217497, 134217493, 134217487, 134217467, 134217439,
134217437, 134217409, 134217403, 134217401, 134217367, 134217361, 134217353, 134217323,
134217301, 134217277, 134217257, 134217247, 134217221, 134217199, 134217173, 134217163,
134217157, 134217131, 134217103, 134217089, 134217079, 134217049, 134217047, 134217043,
134217001, 134216987, 134216947, 134216939, 134216933, 134216911, 134216899, 134216881,
134216869, 134216867, 134216861, 134216837, 134216827, 134216807, 134216801, 134216791,
134216783, 134216777, 134216759, 134216737, 134216729,
];
const PRIMES28: &'static [u64] = &[268435399, 268435367, 268435361, 268435337, 268435331,
268435313, 268435291, 268435273, 268435243, 268435183, 268435171, 268435157, 268435147,
268435133, 268435129, 268435121, 268435109, 268435091, 268435067, 268435043, 268435039,
268435033, 268435019, 268435009, 268435007, 268434997, 268434979, 268434977, 268434961,
268434949, 268434941, 268434937, 268434857, 268434841, 268434827, 268434821, 268434787,
268434781, 268434779, 268434773, 268434731, 268434721, 268434713, 268434707, 268434703,
268434697, 268434659, 268434623, 268434619, 268434581, 268434577, 268434563, 268434557,
268434547, 268434511, 268434499, 268434479, 268434461,
];
const PRIMES29: &'static [u64] = &[536870909, 536870879, 536870869, 536870849, 536870839,
536870837, 536870819, 536870813, 536870791, 536870779, 536870767, 536870743, 536870729,
536870723, 536870717, 536870701, 536870683, 536870657, 536870641, 536870627, 536870611,
536870603, 536870599, 536870573, 536870569, 536870563, 536870561, 536870513, 536870501,
536870497, 536870473, 536870401, 536870363, 536870317, 536870303, 536870297, 536870273,
536870267, 536870239, 536870233, 536870219, 536870171, 536870167, 536870153, 536870123,
536870063, 536870057, 536870041, 536870027, 536869999, 536869951, 536869943, 536869937,
536869919, 536869901, 536869891,
];
const PRIMES30: &'static [u64] = &[1073741789, 1073741783, 1073741741, 1073741723, 1073741719,
1073741717, 1073741689, 1073741671, 1073741663, 1073741651, 1073741621, 1073741567, 1073741561,
1073741527, 1073741503, 1073741477, 1073741467, 1073741441, 1073741419, 1073741399, 1073741387,
1073741381, 1073741371, 1073741329, 1073741311, 1073741309, 1073741287, 1073741237, 1073741213,
1073741197, 1073741189, 1073741173, 1073741101, 1073741077, 1073741047, 1073740963, 1073740951,
1073740933, 1073740909, 1073740879, 1073740853, 1073740847, 1073740819, 1073740807,
];
const PRIMES31: &'static [u64] = &[2147483647, 2147483629, 2147483587, 2147483579, 2147483563,
2147483549, 2147483543, 2147483497, 2147483489, 2147483477, 2147483423, 2147483399, 2147483353,
2147483323, 2147483269, 2147483249, 2147483237, 2147483179, 2147483171, 2147483137, 2147483123,
2147483077, 2147483069, 2147483059, 2147483053, 2147483033, 2147483029, 2147482951, 2147482949,
2147482943, 2147482937, 2147482921, 2147482877, 2147482873, 2147482867, 2147482859, 2147482819,
2147482817, 2147482811, 2147482801, 2147482763, 2147482739, 2147482697, 2147482693, 2147482681,
2147482663, 2147482661,
];
const PRIMES32: &'static [u64] = &[4294967291, 4294967279, 4294967231, 4294967197, 4294967189,
4294967161, 4294967143, 4294967111, 4294967087, 4294967029, 4294966997, 4294966981, 4294966943,
4294966927, 4294966909, 4294966877, 4294966829, 4294966813, 4294966769, 4294966667, 4294966661,
4294966657, 4294966651, 4294966639, 4294966619, 4294966591, 4294966583, 4294966553, 4294966477,
4294966447, 4294966441, 4294966427, 4294966373, 4294966367, 4294966337, 4294966297,
];
const PRIMES33: &'static [u64] = &[8589934583, 8589934567, 8589934543, 8589934513, 8589934487,
8589934307, 8589934291, 8589934289, 8589934271, 8589934237, 8589934211, 8589934207, 8589934201,
8589934187, 8589934151, 8589934141, 8589934139, 8589934117, 8589934103, 8589934099, 8589934091,
8589934069, 8589934049, 8589934027, 8589934007, 8589933973, 8589933971, 8589933967, 8589933931,
8589933917, 8589933907, 8589933853, 8589933827, 8589933823, 8589933787, 8589933773, 8589933733,
8589933731, 8589933721, 8589933683, 8589933647, 8589933641, 8589933637, 8589933631, 8589933629,
8589933619, 8589933601, 8589933581,
];
const PRIMES34: &'static [u64] = &[17179869143, 17179869107, 17179869071, 17179869053,
17179869041, 17179869019, 17179868999, 17179868977, 17179868957, 17179868903, 17179868899,
17179868887, 17179868879, 17179868873, 17179868869, 17179868861, 17179868843, 17179868833,
17179868809, 17179868807, 17179868777, 17179868759, 17179868729, 17179868711, 17179868683,
17179868681, 17179868597, 17179868549, 17179868543, 17179868521, 17179868513, 17179868479,
17179868443, 17179868437, 17179868429, 17179868383, 17179868369, 17179868357, 17179868353,
17179868351, 17179868333, 17179868317, 17179868309, 17179868297, 17179868287, 17179868249,
17179868243, 17179868183,
];
const PRIMES35: &'static [u64] = &[34359738337, 34359738319, 34359738307, 34359738299,
34359738289, 34359738247, 34359738227, 34359738121, 34359738059, 34359738043, 34359738011,
34359737917, 34359737869, 34359737849, 34359737837, 34359737821, 34359737813, 34359737791,
34359737777, 34359737771, 34359737717, 34359737591, 34359737567, 34359737549, 34359737519,
34359737497, 34359737479, 34359737407, 34359737393, 34359737371,
];
const PRIMES36: &'static [u64] = &[68719476731, 68719476719, 68719476713, 68719476671,
68719476619, 68719476599, 68719476577, 68719476563, 68719476547, 68719476503, 68719476493,
68719476479, 68719476433, 68719476407, 68719476391, 68719476389, 68719476377, 68719476361,
68719476323, 68719476307, 68719476281, 68719476271, 68719476257, 68719476247, 68719476209,
68719476197, 68719476181, 68719476169, 68719476157, 68719476149, 68719476109, 68719476053,
68719476047, 68719476019, 68719475977, 68719475947, 68719475933, 68719475911, 68719475893,
68719475879, 68719475837, 68719475827, 68719475809, 68719475791, 68719475779, 68719475771,
68719475767, 68719475731, 68719475729,
];
const PRIMES37: &'static [u64] = &[137438953447, 137438953441, 137438953427, 137438953403,
137438953349, 137438953331, 137438953273, 137438953271, 137438953121, 137438953097,
137438953037, 137438953009, 137438952953, 137438952901, 137438952887, 137438952869,
137438952853, 137438952731, 137438952683, 137438952611, 137438952529, 137438952503,
137438952491,
];
const PRIMES38: &'static [u64] = &[274877906899, 274877906857, 274877906837, 274877906813,
274877906791, 274877906759, 274877906753, 274877906717, 274877906713, 274877906687,
274877906647, 274877906629, 274877906627, 274877906573, 274877906543, 274877906491,
274877906477, 274877906473, 274877906431, 274877906419, 274877906341, 274877906333,
274877906327, 274877906321, 274877906309, 274877906267, 274877906243, 274877906213,
274877906209, 274877906203, 274877906179, 274877906167, 274877906119, 274877906063,
274877906053, 274877906021, 274877905931,
];
const PRIMES39: &'static [u64] = &[549755813881, 549755813869, 549755813821, 549755813797,
549755813753, 549755813723, 549755813669, 549755813657, 549755813647, 549755813587,
549755813561, 549755813513, 549755813507, 549755813461, 549755813417, 549755813401,
549755813371, 549755813359, 549755813357, 549755813351, 549755813339, 549755813317,
549755813311, 549755813281, 549755813239, 549755813231, 549755813213, 549755813207,
549755813197, 549755813183, 549755813161, 549755813149, 549755813147, 549755813143,
549755813141, 549755813059, 549755813027, 549755813003, 549755812951, 549755812937,
549755812933, 549755812889, 549755812867,
];
const PRIMES40: &'static [u64] = &[1099511627689, 1099511627609, 1099511627581, 1099511627573,
1099511627563, 1099511627491, 1099511627483, 1099511627477, 1099511627387, 1099511627339,
1099511627321, 1099511627309, 1099511627297, 1099511627293, 1099511627261, 1099511627213,
1099511627191, 1099511627177, 1099511627173, 1099511627143, 1099511627089, 1099511626987,
1099511626949, 1099511626937, 1099511626793, 1099511626781, 1099511626771,
];
const PRIMES41: &'static [u64] = &[2199023255531, 2199023255521, 2199023255497, 2199023255489,
2199023255479, 2199023255477, 2199023255461, 2199023255441, 2199023255419, 2199023255413,
2199023255357, 2199023255327, 2199023255291, 2199023255279, 2199023255267, 2199023255243,
2199023255203, 2199023255171, 2199023255137, 2199023255101, 2199023255087, 2199023255081,
2199023255069, 2199023255027, 2199023255021, 2199023254979, 2199023254933, 2199023254913,
2199023254907, 2199023254903, 2199023254843, 2199023254787, 2199023254699, 2199023254693,
2199023254657, 2199023254567,
];
const PRIMES42: &'static [u64] = &[4398046511093, 4398046511087, 4398046511071, 4398046511051,
4398046511039, 4398046510961, 4398046510943, 4398046510939, 4398046510889, 4398046510877,
4398046510829, 4398046510787, 4398046510771, 4398046510751, 4398046510733, 4398046510721,
4398046510643, 4398046510639, 4398046510597, 4398046510577, 4398046510547, 4398046510531,
4398046510463, 4398046510397, 4398046510391, 4398046510379, 4398046510357, 4398046510331,
4398046510327, 4398046510313, 4398046510283, 4398046510279, 4398046510217, 4398046510141,
4398046510133, 4398046510103, 4398046510093,
];
const PRIMES43: &'static [u64] = &[8796093022151, 8796093022141, 8796093022091, 8796093022033,
8796093021953, 8796093021941, 8796093021917, 8796093021899, 8796093021889, 8796093021839,
8796093021803, 8796093021791, 8796093021769, 8796093021763, 8796093021743, 8796093021671,
8796093021607, 8796093021587, 8796093021533, 8796093021523, 8796093021517, 8796093021493,
8796093021467, 8796093021461, 8796093021449, 8796093021409, 8796093021407, 8796093021371,
8796093021347, 8796093021337, 8796093021281, 8796093021269,
];
const PRIMES44: &'static [u64] = &[17592186044399, 17592186044299, 17592186044297, 17592186044287,
17592186044273, 17592186044267, 17592186044129, 17592186044089, 17592186044057, 17592186044039,
17592186043987, 17592186043921, 17592186043889, 17592186043877, 17592186043841, 17592186043829,
17592186043819, 17592186043813, 17592186043807, 17592186043741, 17592186043693, 17592186043667,
17592186043631, 17592186043591, 17592186043577, 17592186043547, 17592186043483, 17592186043451,
17592186043433, 17592186043409,
];
const PRIMES45: &'static [u64] = &[35184372088777, 35184372088763, 35184372088751, 35184372088739,
35184372088711, 35184372088699, 35184372088693, 35184372088673, 35184372088639, 35184372088603,
35184372088571, 35184372088517, 35184372088493, 35184372088471, 35184372088403, 35184372088391,
35184372088379, 35184372088363, 35184372088321, 35184372088319, 35184372088279, 35184372088259,
35184372088249, 35184372088241, 35184372088223, 35184372088183, 35184372088097, 35184372088081,
35184372088079, 35184372088051, 35184372088043, 35184372088039, 35184372087937, 35184372087929,
35184372087923, 35184372087881, 35184372087877, 35184372087869,
];
const PRIMES46: &'static [u64] = &[70368744177643, 70368744177607, 70368744177601, 70368744177587,
70368744177497, 70368744177467, 70368744177427, 70368744177377, 70368744177359, 70368744177353,
70368744177331, 70368744177289, 70368744177283, 70368744177271, 70368744177257, 70368744177227,
70368744177167, 70368744177113, 70368744177029, 70368744176959, 70368744176921, 70368744176909,
70368744176879, 70368744176867, 70368744176833, 70368744176827, 70368744176807, 70368744176779,
70368744176777, 70368744176729, 70368744176719, 70368744176711,
];
const PRIMES47: &'static [u64] = &[140737488355213, 140737488355201, 140737488355181,
140737488355049, 140737488355031, 140737488354989, 140737488354893, 140737488354787,
140737488354709, 140737488354679, 140737488354613, 140737488354557, 140737488354511,
140737488354431, 140737488354413, 140737488354409, 140737488354373, 140737488354347,
140737488354329,
];
const PRIMES48: &'static [u64] = &[281474976710597, 281474976710591, 281474976710567,
281474976710563, 281474976710509, 281474976710491, 281474976710467, 281474976710423,
281474976710413, 281474976710399, 281474976710339, 281474976710327, 281474976710287,
281474976710197, 281474976710143, 281474976710131, 281474976710129, 281474976710107,
281474976710089, 281474976710087, 281474976710029, 281474976709987, 281474976709891,
281474976709859, 281474976709831, 281474976709757, 281474976709741, 281474976709711,
281474976709649, 281474976709637,
];
const PRIMES49: &'static [u64] = &[562949953421231, 562949953421201, 562949953421189,
562949953421173, 562949953421131, 562949953421111, 562949953421099, 562949953421047,
562949953421029, 562949953420973, 562949953420871, 562949953420867, 562949953420837,
562949953420793, 562949953420747, 562949953420741, 562949953420733, 562949953420727,
562949953420609, 562949953420571, 562949953420559, 562949953420553, 562949953420523,
562949953420507, 562949953420457, 562949953420403, 562949953420373, 562949953420369,
562949953420343, 562949953420303, 562949953420297,
];
const PRIMES50: &'static [u64] = &[1125899906842597, 1125899906842589, 1125899906842573,
1125899906842553, 1125899906842511, 1125899906842507, 1125899906842493, 1125899906842463,
1125899906842429, 1125899906842391, 1125899906842357, 1125899906842283, 1125899906842273,
1125899906842247, 1125899906842201, 1125899906842177, 1125899906842079, 1125899906842033,
1125899906842021, 1125899906842013, 1125899906841973, 1125899906841971, 1125899906841959,
1125899906841949, 1125899906841943, 1125899906841917, 1125899906841901, 1125899906841883,
1125899906841859, 1125899906841811, 1125899906841803, 1125899906841751, 1125899906841713,
1125899906841673, 1125899906841653, 1125899906841623, 1125899906841613,
];

View file

@ -1,9 +0,0 @@
use std::process::Command;
static PROGNAME: &'static str = "./false";
#[test]
fn test_exit_code() {
let exit_status = Command::new(PROGNAME).status().unwrap().success();
assert_eq!(exit_status, false);
}

View file

@ -1,53 +0,0 @@
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::process::Command;
static PROGNAME: &'static str = "./fold";
#[test]
fn test_default_80_column_wrap() {
let po = Command::new(PROGNAME)
.arg("lorem_ipsum.txt")
.output()
.unwrap_or_else(|err| panic!("{}", err));
fold_helper(po.stdout, "lorem_ipsum_80_column.expected");
}
#[test]
fn test_40_column_hard_cutoff() {
let po = Command::new(PROGNAME)
.arg("-w")
.arg("40")
.arg("lorem_ipsum.txt")
.output()
.unwrap_or_else(|err| panic!("{}", err));
fold_helper(po.stdout, "lorem_ipsum_40_column_hard.expected");
}
#[test]
fn test_40_column_word_boundary() {
let po = Command::new(PROGNAME)
.arg("-s")
.arg("-w")
.arg("40")
.arg("lorem_ipsum.txt")
.output()
.unwrap_or_else(|err| panic!("{}", err));
fold_helper(po.stdout, "lorem_ipsum_40_column_word.expected");
}
fn fold_helper(output: Vec<u8>, filename: &str) {
let mut f = File::open(Path::new(filename)).unwrap_or_else(|err| {
panic!("{}", err)
});
let mut expected = vec!();
match f.read_to_end(&mut expected) {
Ok(_) => {},
Err(err) => panic!("{}", err)
}
assert_eq!(String::from_utf8(output).unwrap(), String::from_utf8(expected).unwrap());
}

View file

@ -1,72 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./head";
static INPUT: &'static str = "lorem_ipsum.txt";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_stdin_default() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd, get_file_contents(INPUT));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_default.expected"));
}
#[test]
fn test_stdin_1_line_obsolete() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-1"]), get_file_contents(INPUT));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected"));
}
#[test]
fn test_stdin_1_line() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-n", "1"]), get_file_contents(INPUT));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected"));
}
#[test]
fn test_stdin_5_chars() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-c", "5"]), get_file_contents(INPUT));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_5_chars.expected"));
}
#[test]
fn test_single_default() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.arg(INPUT));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_default.expected"));
}
#[test]
fn test_single_1_line_obsolete() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-1", INPUT]));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected"));
}
#[test]
fn test_single_1_line() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-n", "1", INPUT]));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_1_line.expected"));
}
#[test]
fn test_single_5_chars() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-c", "5", INPUT]));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_5_chars.expected"));
}
#[test]
fn test_verbose() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-v", INPUT]));
assert_eq!(result.stdout, get_file_contents("lorem_ipsum_verbose.expected"));
}

View file

@ -1,49 +0,0 @@
extern crate libc;
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./link";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_link_existing_file() {
let file = "test_link_existing_file";
let link = "test_link_existing_file_link";
touch(file);
set_file_contents(file, "foobar");
assert!(file_exists(file));
let result = run(Command::new(PROGNAME).args(&[file, link]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(file));
assert!(file_exists(link));
assert_eq!(get_file_contents(file), get_file_contents(link));
}
#[test]
fn test_link_no_circular() {
let link = "test_link_no_circular";
let result = run(Command::new(PROGNAME).args(&[link, link]));
assert_eq!(result.stderr, "link: error: No such file or directory (os error 2)\n");
assert!(!result.success);
assert!(!file_exists(link));
}
#[test]
fn test_link_nonexistent_file() {
let file = "test_link_nonexistent_file";
let link = "test_link_nonexistent_file_link";
let result = run(Command::new(PROGNAME).args(&[file, link]));
assert_eq!(result.stderr, "link: error: No such file or directory (os error 2)\n");
assert!(!result.success);
assert!(!file_exists(file));
assert!(!file_exists(link));
}

View file

@ -1,354 +0,0 @@
extern crate libc;
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./ln";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_symlink_existing_file() {
let file = "test_symlink_existing_file";
let link = "test_symlink_existing_file_link";
touch(file);
let result = run(Command::new(PROGNAME).args(&["-s", file, link]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(file));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file);
}
#[test]
fn test_symlink_dangling_file() {
let file = "test_symlink_dangling_file";
let link = "test_symlink_dangling_file_link";
let result = run(Command::new(PROGNAME).args(&["-s", file, link]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file);
}
#[test]
fn test_symlink_existing_directory() {
let dir = "test_symlink_existing_dir";
let link = "test_symlink_existing_dir_link";
mkdir(dir);
let result = run(Command::new(PROGNAME).args(&["-s", dir, link]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(dir_exists(dir));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), dir);
}
#[test]
fn test_symlink_dangling_directory() {
let dir = "test_symlink_dangling_dir";
let link = "test_symlink_dangling_dir_link";
let result = run(Command::new(PROGNAME).args(&["-s", dir, link]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!dir_exists(dir));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), dir);
}
#[test]
fn test_symlink_circular() {
let link = "test_symlink_circular";
let result = run(Command::new(PROGNAME).args(&["-s", link]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(is_symlink(link));
assert_eq!(resolve_link(link), link);
}
#[test]
fn test_symlink_dont_overwrite() {
let file = "test_symlink_dont_overwrite";
let link = "test_symlink_dont_overwrite_link";
touch(file);
touch(link);
let result = run(Command::new(PROGNAME).args(&["-s", file, link]));
assert!(!result.success);
assert!(file_exists(file));
assert!(file_exists(link));
assert!(!is_symlink(link));
}
#[test]
fn test_symlink_overwrite_force() {
let file_a = "test_symlink_overwrite_force_a";
let file_b = "test_symlink_overwrite_force_b";
let link = "test_symlink_overwrite_force_link";
// Create symlink
symlink(file_a, link);
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file_a);
// Force overwrite of existing symlink
let result = run(Command::new(PROGNAME).args(&["--force", "-s", file_b, link]));
assert!(result.success);
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file_b);
}
#[test]
fn test_symlink_interactive() {
let file = "test_symlink_interactive_file";
let link = "test_symlink_interactive_file_link";
touch(file);
touch(link);
let result1 = run_piped_stdin(Command::new(PROGNAME).args(&["-i", "-s", file, link]), b"n");
assert_empty_stderr!(result1);
assert!(result1.success);
assert!(file_exists(file));
assert!(!is_symlink(link));
let result2 = run_piped_stdin(Command::new(PROGNAME).args(&["-i", "-s", file, link]), b"Yesh");
assert_empty_stderr!(result2);
assert!(result2.success);
assert!(file_exists(file));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file);
}
#[test]
fn test_symlink_simple_backup() {
let file = "test_symlink_simple_backup";
let link = "test_symlink_simple_backup_link";
touch(file);
symlink(file, link);
assert!(file_exists(file));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file);
let result = run(Command::new(PROGNAME).args(&["-b", "-s", file, link]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(file));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file);
let backup = &format!("{}~", link);
assert!(is_symlink(backup));
assert_eq!(resolve_link(backup), file);
}
#[test]
fn test_symlink_custom_backup_suffix() {
let file = "test_symlink_custom_backup_suffix";
let link = "test_symlink_custom_backup_suffix_link";
let suffix = "super-suffix-of-the-century";
touch(file);
symlink(file, link);
assert!(file_exists(file));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file);
let arg = &format!("--suffix={}", suffix);
let result = run(Command::new(PROGNAME).args(&["-b", arg, "-s", file, link]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(file));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file);
let backup = &format!("{}{}", link, suffix);
assert!(is_symlink(backup));
assert_eq!(resolve_link(backup), file);
}
#[test]
fn test_symlink_backup_numbering() {
let file = "test_symlink_backup_numbering";
let link = "test_symlink_backup_numbering_link";
touch(file);
symlink(file, link);
assert!(file_exists(file));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file);
let result = run(Command::new(PROGNAME).args(&["-s", "--backup=t", file, link]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(file));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file);
let backup = &format!("{}.~1~", link);
assert!(is_symlink(backup));
assert_eq!(resolve_link(backup), file);
}
#[test]
fn test_symlink_existing_backup() {
let file = "test_symlink_existing_backup";
let link = "test_symlink_existing_backup_link";
let link_backup = "test_symlink_existing_backup_link.~1~";
let resulting_backup = "test_symlink_existing_backup_link.~2~";
// Create symlink and verify
touch(file);
symlink(file, link);
assert!(file_exists(file));
assert!(is_symlink(link));
assert_eq!(resolve_link(link), file);
// Create backup symlink and verify
symlink(file, link_backup);
assert!(file_exists(file));
assert!(is_symlink(link_backup));
assert_eq!(resolve_link(link_backup), file);
let result = run(Command::new(PROGNAME).args(&["-s", "--backup=nil", file, link]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(file));
assert!(is_symlink(link_backup));
assert_eq!(resolve_link(link_backup), file);
assert!(is_symlink(resulting_backup));
assert_eq!(resolve_link(resulting_backup), file);
}
#[test]
fn test_symlink_target_dir() {
let dir = "test_ln_target_dir_dir";
let file_a = "test_ln_target_dir_file_a";
let file_b = "test_ln_target_dir_file_b";
touch(file_a);
touch(file_b);
mkdir(dir);
let result = run(Command::new(PROGNAME).args(&["-s", "-t", dir, file_a, file_b]));
assert_empty_stderr!(result);
assert!(result.success);
let file_a_link = &format!("{}/{}", dir, file_a);
assert!(is_symlink(file_a_link));
assert_eq!(resolve_link(file_a_link), file_a);
let file_b_link = &format!("{}/{}", dir, file_b);
assert!(is_symlink(file_b_link));
assert_eq!(resolve_link(file_b_link), file_b);
}
#[test]
fn test_symlink_overwrite_dir() {
let path_a = "test_symlink_overwrite_dir_a";
let path_b = "test_symlink_overwrite_dir_b";
touch(path_a);
mkdir(path_b);
let result = run(Command::new(PROGNAME).args(&["-s", "-T", path_a, path_b]));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(path_a));
assert!(is_symlink(path_b));
assert_eq!(resolve_link(path_b), path_a);
}
#[test]
fn test_symlink_overwrite_nonempty_dir() {
let path_a = "test_symlink_overwrite_nonempty_dir_a";
let path_b = "test_symlink_overwrite_nonempty_dir_b";
let dummy = "test_symlink_overwrite_nonempty_dir_b/file";
touch(path_a);
mkdir(path_b);
touch(dummy);
let result = run(Command::new(PROGNAME).args(&["-v", "-T", "-s", path_a, path_b]));
// Not same error as GNU; the error message is a Rust builtin
// TODO: test (and implement) correct error message (or at least decide whether to do so)
// Current: "ln: error: Directory not empty (os error 66)"
// GNU: "ln: cannot link 'a' to 'b': Directory not empty"
assert!(result.stderr.len() > 0);
// Verbose output for the link should not be shown on failure
assert!(result.stdout.len() == 0);
assert!(!result.success);
assert!(file_exists(path_a));
assert!(dir_exists(path_b));
}
#[test]
fn test_symlink_errors() {
let dir = "test_symlink_errors_dir";
let file_a = "test_symlink_errors_file_a";
let file_b = "test_symlink_errors_file_b";
mkdir(dir);
touch(file_a);
touch(file_b);
// $ ln -T -t a b
// ln: cannot combine --target-directory (-t) and --no-target-directory (-T)
let result = run(Command::new(PROGNAME).args(&["-T", "-t", dir, file_a, file_b]));
assert_eq!(result.stderr,
"ln: error: cannot combine --target-directory (-t) and --no-target-directory (-T)\n");
assert!(!result.success);
}
#[test]
fn test_symlink_verbose() {
let file_a = "test_symlink_verbose_file_a";
let file_b = "test_symlink_verbose_file_b";
touch(file_a);
let result = run(Command::new(PROGNAME).args(&["-v", file_a, file_b]));
assert_empty_stderr!(result);
assert_eq!(result.stdout,
format!("'{}' -> '{}'\n", file_b, file_a));
assert!(result.success);
touch(file_b);
let result = run(Command::new(PROGNAME).args(&["-v", "-b", file_a, file_b]));
assert_empty_stderr!(result);
assert_eq!(result.stdout,
format!("'{}' -> '{}' (backup: '{}~')\n", file_b, file_a, file_b));
assert!(result.success);
}

View file

@ -1,58 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./mkdir";
static TEST_DIR1: &'static str = "mkdir_test1";
static TEST_DIR2: &'static str = "mkdir_test2";
static TEST_DIR3: &'static str = "mkdir_test3";
static TEST_DIR4: &'static str = "mkdir_test4/mkdir_test4_1";
static TEST_DIR5: &'static str = "mkdir_test5/mkdir_test5_1";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_mkdir_mkdir() {
let mut cmd = Command::new(PROGNAME);
let exit_success = run(&mut cmd.arg(TEST_DIR1)).success;
cleanup(TEST_DIR1);
assert_eq!(exit_success, true);
}
#[test]
fn test_mkdir_dup_dir() {
let mut cmd = Command::new(PROGNAME);
let exit_success = run(&mut cmd.arg(TEST_DIR2)).success;
if !exit_success {
cleanup(TEST_DIR2);
panic!();
}
let exit_success2 = run(&mut cmd.arg(TEST_DIR2)).success;
cleanup(TEST_DIR2);
assert_eq!(exit_success2, false);
}
#[test]
fn test_mkdir_mode() {
let mut cmd = Command::new(PROGNAME);
let exit_success = run(&mut cmd.arg("-m").arg("755").arg(TEST_DIR3)).success;
cleanup(TEST_DIR3);
assert_eq!(exit_success, true);
}
#[test]
fn test_mkdir_parent() {
let mut cmd = Command::new(PROGNAME);
let exit_success = run(&mut cmd.arg("-p").arg(TEST_DIR4)).success;
cleanup(TEST_DIR4);
assert_eq!(exit_success, true);
}
#[test]
fn test_mkdir_no_parent() {
let mut cmd = Command::new(PROGNAME);
let exit_success = run(&mut cmd.arg(TEST_DIR5)).success;
cleanup(TEST_DIR5);
assert_eq!(exit_success, false);
}

View file

@ -1,446 +0,0 @@
extern crate libc;
extern crate time;
extern crate kernel32;
extern crate winapi;
extern crate filetime;
use filetime::*;
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./mv";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_mv_rename_dir() {
let dir1 = "test_mv_rename_dir";
let dir2 = "test_mv_rename_dir2";
mkdir(dir1);
let result = run(Command::new(PROGNAME).arg(dir1).arg(dir2));
assert_empty_stderr!(result);
assert!(result.success);
assert!(dir_exists(dir2));
}
#[test]
fn test_mv_rename_file() {
let file1 = "test_mv_rename_file";
let file2 = "test_mv_rename_file2";
touch(file1);
let result = run(Command::new(PROGNAME).arg(file1).arg(file2));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(file2));
}
#[test]
fn test_mv_move_file_into_dir() {
let dir = "test_mv_move_file_into_dir_dir";
let file = "test_mv_move_file_into_dir_file";
mkdir(dir);
touch(file);
let result = run(Command::new(PROGNAME).arg(file).arg(dir));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(&format!("{}/{}", dir, file)));
}
#[test]
fn test_mv_strip_slashes() {
let dir = "test_mv_strip_slashes_dir";
let file = "test_mv_strip_slashes_file";
let mut source = file.to_owned();
source.push_str("/");
mkdir(dir);
touch(file);
let result = run(Command::new(PROGNAME).arg(&source).arg(dir));
assert!(!result.success);
assert!(!file_exists(&format!("{}/{}", dir, file)));
let result = run(Command::new(PROGNAME).arg("--strip-trailing-slashes").arg(source).arg(dir));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(&format!("{}/{}", dir, file)));
}
#[test]
fn test_mv_multiple_files() {
let target_dir = "test_mv_multiple_files_dir";
let file_a = "test_mv_multiple_file_a";
let file_b = "test_mv_multiple_file_b";
mkdir(target_dir);
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg(file_a).arg(file_b).arg(target_dir));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(&format!("{}/{}", target_dir, file_a)));
assert!(file_exists(&format!("{}/{}", target_dir, file_b)));
}
#[test]
fn test_mv_multiple_folders() {
let target_dir = "test_mv_multiple_dirs_dir";
let dir_a = "test_mv_multiple_dir_a";
let dir_b = "test_mv_multiple_dir_b";
mkdir(target_dir);
mkdir(dir_a);
mkdir(dir_b);
let result = run(Command::new(PROGNAME).arg(dir_a).arg(dir_b).arg(target_dir));
assert_empty_stderr!(result);
assert!(result.success);
assert!(dir_exists(&format!("{}/{}", target_dir, dir_a)));
assert!(dir_exists(&format!("{}/{}", target_dir, dir_b)));
}
#[test]
fn test_mv_interactive() {
let file_a = "test_mv_interactive_file_a";
let file_b = "test_mv_interactive_file_b";
touch(file_a);
touch(file_b);
let result1 = run_piped_stdin(Command::new(PROGNAME).arg("-i").arg(file_a).arg(file_b), b"n");
assert_empty_stderr!(result1);
assert!(result1.success);
assert!(file_exists(file_a));
assert!(file_exists(file_b));
let result2 = run_piped_stdin(Command::new(PROGNAME).arg("-i").arg(file_a).arg(file_b), b"Yesh");
assert_empty_stderr!(result2);
assert!(result2.success);
assert!(!file_exists(file_a));
assert!(file_exists(file_b));
}
#[test]
fn test_mv_no_clobber() {
let file_a = "test_mv_no_clobber_file_a";
let file_b = "test_mv_no_clobber_file_b";
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg("-n").arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(file_exists(file_a));
assert!(file_exists(file_b));
}
#[test]
fn test_mv_replace_file() {
let file_a = "test_mv_replace_file_a";
let file_b = "test_mv_replace_file_b";
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file_a));
assert!(file_exists(file_b));
}
#[test]
fn test_mv_force_replace_file() {
let file_a = "test_mv_force_replace_file_a";
let file_b = "test_mv_force_replace_file_b";
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg("--force").arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file_a));
assert!(file_exists(file_b));
}
#[test]
fn test_mv_simple_backup() {
let file_a = "test_mv_simple_backup_file_a";
let file_b = "test_mv_simple_backup_file_b";
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg("-b").arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file_a));
assert!(file_exists(file_b));
assert!(file_exists(&format!("{}~", file_b)));
}
#[test]
fn test_mv_custom_backup_suffix() {
let file_a = "test_mv_custom_backup_suffix_file_a";
let file_b = "test_mv_custom_backup_suffix_file_b";
let suffix = "super-suffix-of-the-century";
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME)
.arg("-b").arg(format!("--suffix={}", suffix))
.arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file_a));
assert!(file_exists(file_b));
assert!(file_exists(&format!("{}{}", file_b, suffix)));
}
#[test]
fn test_mv_backup_numbering() {
let file_a = "test_mv_backup_numbering_file_a";
let file_b = "test_mv_backup_numbering_file_b";
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg("--backup=t").arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file_a));
assert!(file_exists(file_b));
assert!(file_exists(&format!("{}.~1~", file_b)));
}
#[test]
fn test_mv_existing_backup() {
let file_a = "test_mv_existing_backup_file_a";
let file_b = "test_mv_existing_backup_file_b";
let file_b_backup = "test_mv_existing_backup_file_b.~1~";
let resulting_backup = "test_mv_existing_backup_file_b.~2~";
touch(file_a);
touch(file_b);
touch(file_b_backup);
let result = run(Command::new(PROGNAME).arg("--backup=nil").arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file_a));
assert!(file_exists(file_b));
assert!(file_exists(file_b_backup));
assert!(file_exists(resulting_backup));
}
#[test]
fn test_mv_update_option() {
let file_a = "test_mv_update_option_file_a";
let file_b = "test_mv_update_option_file_b";
touch(file_a);
touch(file_b);
let ts = time::now().to_timespec();
let now = FileTime::from_seconds_since_1970(ts.sec as u64, ts.nsec as u32);
let later = FileTime::from_seconds_since_1970(ts.sec as u64 + 3600, ts.nsec as u32);
filetime::set_file_times(file_a, now, now).unwrap();
filetime::set_file_times(file_b, now, later).unwrap();
let result1 = run(Command::new(PROGNAME).arg("--update").arg(file_a).arg(file_b));
assert_empty_stderr!(result1);
assert!(result1.success);
assert!(file_exists(file_a));
assert!(file_exists(file_b));
let result2 = run(Command::new(PROGNAME).arg("--update").arg(file_b).arg(file_a));
assert_empty_stderr!(result2);
assert!(result2.success);
assert!(file_exists(file_a));
assert!(!file_exists(file_b));
}
#[test]
fn test_mv_target_dir() {
let dir = "test_mv_target_dir_dir";
let file_a = "test_mv_target_dir_file_a";
let file_b = "test_mv_target_dir_file_b";
touch(file_a);
touch(file_b);
mkdir(dir);
let result = run(Command::new(PROGNAME).arg("-t").arg(dir).arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file_a));
assert!(!file_exists(file_b));
assert!(file_exists(&format!("{}/{}", dir, file_a)));
assert!(file_exists(&format!("{}/{}", dir, file_b)));
}
#[test]
fn test_mv_overwrite_dir() {
let dir_a = "test_mv_overwrite_dir_a";
let dir_b = "test_mv_overwrite_dir_b";
mkdir(dir_a);
mkdir(dir_b);
let result = run(Command::new(PROGNAME).arg("-T").arg(dir_a).arg(dir_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!dir_exists(dir_a));
assert!(dir_exists(dir_b));
}
#[test]
fn test_mv_overwrite_nonempty_dir() {
let dir_a = "test_mv_overwrite_nonempty_dir_a";
let dir_b = "test_mv_overwrite_nonempty_dir_b";
let dummy = "test_mv_overwrite_nonempty_dir_b/file";
mkdir(dir_a);
mkdir(dir_b);
touch(dummy);
let result = run(Command::new(PROGNAME).arg("-vT").arg(dir_a).arg(dir_b));
// Not same error as GNU; the error message is a rust builtin
// TODO: test (and implement) correct error message (or at least decide whether to do so)
// Current: "mv: error: couldn't rename path (Directory not empty; from=a; to=b)"
// GNU: "mv: cannot move a to b: Directory not empty"
assert!(result.stderr.len() > 0);
// Verbose output for the move should not be shown on failure
assert!(result.stdout.len() == 0);
assert!(!result.success);
assert!(dir_exists(dir_a));
assert!(dir_exists(dir_b));
}
#[test]
fn test_mv_backup_dir() {
let dir_a = "test_mv_backup_dir_dir_a";
let dir_b = "test_mv_backup_dir_dir_b";
mkdir(dir_a);
mkdir(dir_b);
let result = run(Command::new(PROGNAME).arg("-vbT").arg(dir_a).arg(dir_b));
assert_empty_stderr!(result);
assert_eq!(result.stdout,
format!("{} -> {} (backup: {}~)\n", dir_a, dir_b, dir_b));
assert!(result.success);
assert!(!dir_exists(dir_a));
assert!(dir_exists(dir_b));
assert!(dir_exists(&format!("{}~", dir_b)));
}
#[test]
fn test_mv_errors() {
let dir = "test_mv_errors_dir";
let file_a = "test_mv_errors_file_a";
let file_b = "test_mv_errors_file_b";
mkdir(dir);
touch(file_a);
touch(file_b);
// $ mv -T -t a b
// mv: cannot combine --target-directory (-t) and --no-target-directory (-T)
let result = run(Command::new(PROGNAME).arg("-T").arg("-t").arg(dir).arg(file_a).arg(file_b));
assert_eq!(result.stderr,
"mv: error: cannot combine --target-directory (-t) and --no-target-directory (-T)\n");
assert!(!result.success);
// $ touch file && mkdir dir
// $ mv -T file dir
// err == mv: cannot overwrite directory dir with non-directory
let result = run(Command::new(PROGNAME).arg("-T").arg(file_a).arg(dir));
assert_eq!(result.stderr,
format!("mv: error: cannot overwrite directory {} with non-directory\n", dir));
assert!(!result.success);
// $ mkdir dir && touch file
// $ mv dir file
// err == mv: cannot overwrite non-directory file with directory dir
let result = run(Command::new(PROGNAME).arg(dir).arg(file_a));
assert!(result.stderr.len() > 0);
assert!(!result.success);
}
#[test]
fn test_mv_verbose() {
let dir = "test_mv_verbose_dir";
let file_a = "test_mv_verbose_file_a";
let file_b = "test_mv_verbose_file_b";
mkdir(dir);
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg("-v").arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert_eq!(result.stdout,
format!("{} -> {}\n", file_a, file_b));
assert!(result.success);
touch(file_a);
let result = run(Command::new(PROGNAME).arg("-vb").arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert_eq!(result.stdout,
format!("{} -> {} (backup: {}~)\n", file_a, file_b, file_b));
assert!(result.success);
}
// Todo:
// $ touch a b
// $ chmod -w b
// $ ll
// total 0
// -rw-rw-r-- 1 user user 0 okt 25 11:21 a
// -r--r--r-- 1 user user 0 okt 25 11:21 b
// $
// $ mv -v a b
// mv: try to overwrite b, overriding mode 0444 (r--r--r--)? y
// a -> b

View file

@ -1,53 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./nl";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_stdin_nonewline() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd, "No Newline".as_bytes());
assert_eq!(result.stdout, " 1\tNo Newline\n");
}
#[test]
fn test_stdin_newline() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-s", "-", "-w", "1"]), "Line One\nLine Two\n".as_bytes());
assert_eq!(result.stdout, "1-Line One\n2-Line Two\n");
}
#[test]
fn test_padding_without_overflow() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-i", "1000", "-s", "x", "-n", "rz", "simple.txt"]));
assert_eq!(result.stdout, "000001xL1\n001001xL2\n002001xL3\n003001xL4\n004001xL5\n005001xL6\n006001xL7\n007001xL8\n008001xL9\n009001xL10\n010001xL11\n011001xL12\n012001xL13\n013001xL14\n014001xL15\n");
}
#[test]
fn test_padding_with_overflow() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-i", "1000", "-s", "x", "-n", "rz", "-w", "4", "simple.txt"]));
assert_eq!(result.stdout, "0001xL1\n1001xL2\n2001xL3\n3001xL4\n4001xL5\n5001xL6\n6001xL7\n7001xL8\n8001xL9\n9001xL10\n10001xL11\n11001xL12\n12001xL13\n13001xL14\n14001xL15\n");
}
#[test]
fn test_sections_and_styles() {
for &(fixture, output) in [
(
"section.txt",
"\nHEADER1\nHEADER2\n\n1 |BODY1\n2 |BODY2\n\nFOOTER1\nFOOTER2\n\nNEXTHEADER1\nNEXTHEADER2\n\n1 |NEXTBODY1\n2 |NEXTBODY2\n\nNEXTFOOTER1\nNEXTFOOTER2\n"
),
(
"joinblanklines.txt",
"1 |Nonempty\n2 |Nonempty\n3 |Followed by 10x empty\n\n\n\n\n4 |\n\n\n\n\n5 |\n6 |Followed by 5x empty\n\n\n\n\n7 |\n8 |Followed by 4x empty\n\n\n\n\n9 |Nonempty\n10 |Nonempty\n11 |Nonempty.\n"
),
].iter() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-s", "|", "-n", "ln", "-w", "3", "-b", "a", "-l", "5", fixture]));
assert_eq!(result.stdout, output);
}
}

View file

@ -1,27 +0,0 @@
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::process::Command;
static PROGNAME: &'static str = "./paste";
#[test]
fn test_combine_pairs_of_lines() {
let po = Command::new(PROGNAME)
.arg("-s")
.arg("-d")
.arg("\t\n")
.arg("html_colors.txt")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let mut f = File::open(Path::new("html_colors.expected")).unwrap_or_else(|err| {
panic!("{}", err)
});
let mut expected = vec!();
match f.read_to_end(&mut expected) {
Ok(_) => {},
Err(err) => panic!("{}", err)
}
assert_eq!(String::from_utf8(po.stdout).unwrap(), String::from_utf8(expected).unwrap());
}

View file

@ -1,16 +0,0 @@
use std::env;
use std::process::Command;
use std::str;
static PROGNAME: &'static str = "./pwd";
#[test]
fn test_default() {
let po = Command::new(PROGNAME)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
let expected = env::current_dir().unwrap().into_os_string().into_string().unwrap();
assert_eq!(out, expected);
}

View file

@ -1,80 +0,0 @@
use std::process::Command;
use std::str;
use util::*;
static PROGNAME: &'static str = "./readlink";
static GIBBERISH: &'static str = "supercalifragilisticexpialidocious";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_canonicalize() {
let po = Command::new(PROGNAME)
.arg("-f")
.arg(".")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, current_directory());
}
#[test]
fn test_canonicalize_existing() {
let po = Command::new(PROGNAME)
.arg("-e")
.arg(".")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, current_directory());
}
#[test]
fn test_canonicalize_missing() {
let mut expected = current_directory();
expected.push_str("/");
expected.push_str(GIBBERISH);
let po = Command::new(PROGNAME)
.arg("-m")
.arg(GIBBERISH)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, expected);
}
#[test]
fn test_long_redirection_to_current_dir() {
// Create a 256-character path to current directory
let dir = repeat_str("./", 128);
let po = Command::new(PROGNAME)
.arg("-n")
.arg("-m")
.arg(dir)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out, current_directory());
}
#[test]
fn test_long_redirection_to_root() {
// Create a 255-character path to root
let dir = repeat_str("../", 85);
let po = Command::new(PROGNAME)
.arg("-n")
.arg("-m")
.arg(dir)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap();
assert_eq!(out, "/");
}

View file

@ -1,46 +0,0 @@
use std::process::Command;
use std::str;
use util::*;
static PROGNAME: &'static str = "./realpath";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_current_directory() {
let po = Command::new(PROGNAME)
.arg(".")
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, current_directory());
}
#[test]
fn test_long_redirection_to_current_dir() {
// Create a 256-character path to current directory
let dir = repeat_str("./", 128);
let po = Command::new(PROGNAME)
.arg(dir)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, current_directory());
}
#[test]
fn test_long_redirection_to_root() {
// Create a 255-character path to root
let dir = repeat_str("../", 85);
let po = Command::new(PROGNAME)
.arg(dir)
.output()
.unwrap_or_else(|err| panic!("{}", err));
let out = str::from_utf8(&po.stdout[..]).unwrap().trim_right();
assert_eq!(out, "/");
}

View file

@ -1,140 +0,0 @@
extern crate libc;
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./rm";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_rm_one_file() {
let file = "test_rm_one_file";
touch(file);
let result = run(Command::new(PROGNAME).arg(file));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file));
}
#[test]
fn test_rm_multiple_files() {
let file_a = "test_rm_multiple_file_a";
let file_b = "test_rm_multiple_file_b";
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file_a));
assert!(!file_exists(file_b));
}
#[test]
fn test_rm_interactive() {
let file_a = "test_rm_interactive_file_a";
let file_b = "test_rm_interactive_file_b";
touch(file_a);
touch(file_b);
let result1 = run_piped_stdin(Command::new(PROGNAME).arg("-i").arg(file_a).arg(file_b), b"n");
assert!(result1.success);
assert!(file_exists(file_a));
assert!(file_exists(file_b));
let result2 = run_piped_stdin(Command::new(PROGNAME).arg("-i").arg(file_a).arg(file_b), b"Yesh");
assert!(result2.success);
assert!(!file_exists(file_a));
assert!(file_exists(file_b));
}
#[test]
fn test_rm_force() {
let file_a = "test_rm_force_a";
let file_b = "test_rm_force_b";
let result = run(Command::new(PROGNAME).arg("-f").arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file_a));
assert!(!file_exists(file_b));
}
#[test]
fn test_rm_empty_directory() {
let dir = "test_rm_empty_directory";
mkdir(dir);
let result = run(Command::new(PROGNAME).arg("-d").arg(dir));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!dir_exists(dir));
}
#[test]
fn test_rm_recursive() {
let dir = "test_rm_recursive_directory";
let file_a = "test_rm_recursive_directory/test_rm_recursive_file_a";
let file_b = "test_rm_recursive_directory/test_rm_recursive_file_b";
mkdir(dir);
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg("-r").arg(dir));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!dir_exists(dir));
assert!(!file_exists(file_a));
assert!(!file_exists(file_b));
}
#[test]
fn test_rm_errors() {
let dir = "test_rm_errors_directory";
let file_a = "test_rm_errors_directory/test_rm_errors_file_a";
let file_b = "test_rm_errors_directory/test_rm_errors_file_b";
mkdir(dir);
touch(file_a);
touch(file_b);
// $ rm test_rm_errors_directory
// rm: error: could not remove directory 'test_rm_errors_directory' (did you mean to pass '-r'?)
let result = run(Command::new(PROGNAME).arg(dir));
assert_eq!(result.stderr,
"rm: error: could not remove directory 'test_rm_errors_directory' (did you mean to pass '-r'?)\n");
assert!(!result.success);
}
#[test]
fn test_rm_verbose() {
let file_a = "test_rm_verbose_file_a";
let file_b = "test_rm_verbose_file_b";
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg("-v").arg(file_a).arg(file_b));
assert_empty_stderr!(result);
assert_eq!(result.stdout,
format!("removed '{}'\nremoved '{}'\n", file_a, file_b));
assert!(result.success);
}

View file

@ -1,114 +0,0 @@
extern crate libc;
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./rmdir";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_rmdir_empty_directory_no_parents() {
let dir = "test_rmdir_empty_no_parents";
mkdir(dir);
assert!(dir_exists(dir));
let result = run(Command::new(PROGNAME).arg(dir));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!dir_exists(dir));
}
#[test]
fn test_rmdir_empty_directory_with_parents() {
let dir = "test_rmdir_empty/with/parents";
mkdir_all(dir);
assert!(dir_exists(dir));
let result = run(Command::new(PROGNAME).arg("-p").arg(dir));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!dir_exists(dir));
}
#[test]
fn test_rmdir_nonempty_directory_no_parents() {
let dir = "test_rmdir_nonempty_no_parents";
let file = "test_rmdir_nonempty_no_parents/foo";
mkdir(dir);
assert!(dir_exists(dir));
touch(file);
assert!(file_exists(file));
let result = run(Command::new(PROGNAME).arg(dir));
assert_eq!(result.stderr,
"rmdir: error: failed to remove 'test_rmdir_nonempty_no_parents': Directory not empty\n");
assert!(!result.success);
assert!(dir_exists(dir));
}
#[test]
fn test_rmdir_nonempty_directory_with_parents() {
let dir = "test_rmdir_nonempty/with/parents";
let file = "test_rmdir_nonempty/with/parents/foo";
mkdir_all(dir);
assert!(dir_exists(dir));
touch(file);
assert!(file_exists(file));
let result = run(Command::new(PROGNAME).arg("-p").arg(dir));
assert_eq!(result.stderr,
"rmdir: error: failed to remove 'test_rmdir_nonempty/with/parents': Directory not empty\n\
rmdir: error: failed to remove 'test_rmdir_nonempty/with': Directory not empty\n\
rmdir: error: failed to remove 'test_rmdir_nonempty': Directory not empty\n");
assert!(!result.success);
assert!(dir_exists(dir));
}
#[test]
fn test_rmdir_ignore_nonempty_directory_no_parents() {
let dir = "test_rmdir_ignore_nonempty_no_parents";
let file = "test_rmdir_ignore_nonempty_no_parents/foo";
mkdir(dir);
assert!(dir_exists(dir));
touch(file);
assert!(file_exists(file));
let result = run(Command::new(PROGNAME).arg("--ignore-fail-on-non-empty").arg(dir));
assert_empty_stderr!(result);
assert!(result.success);
assert!(dir_exists(dir));
}
#[test]
fn test_rmdir_ignore_nonempty_directory_with_parents() {
let dir = "test_rmdir_ignore_nonempty/with/parents";
let file = "test_rmdir_ignore_nonempty/with/parents/foo";
mkdir_all(dir);
assert!(dir_exists(dir));
touch(file);
assert!(file_exists(file));
let result = run(Command::new(PROGNAME).arg("--ignore-fail-on-non-empty").arg("-p").arg(dir));
assert_empty_stderr!(result);
assert!(result.success);
assert!(dir_exists(dir));
}

View file

@ -1,32 +0,0 @@
use std::process::Command;
use std::str;
static PROGNAME: &'static str = "./seq";
#[test]
fn test_count_up() {
let p = Command::new(PROGNAME).args(&["10"]).output().unwrap();
let out = str::from_utf8(&p.stdout).unwrap();
assert_eq!(out, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n");
}
#[test]
fn test_count_down() {
let p = Command::new(PROGNAME).args(&["--", "5", "-1", "1"]).output().unwrap();
let out = str::from_utf8(&p.stdout).unwrap();
assert_eq!(out, "5\n4\n3\n2\n1\n");
}
#[test]
fn test_separator_and_terminator() {
let p = Command::new(PROGNAME).args(&["-s", ",", "-t", "!", "2", "6"]).output().unwrap();
let out = str::from_utf8(&p.stdout).unwrap();
assert_eq!(out, "2,3,4,5,6!");
}
#[test]
fn test_equalize_widths() {
let p = Command::new(PROGNAME).args(&["-w", "5", "10"]).output().unwrap();
let out = str::from_utf8(&p.stdout).unwrap();
assert_eq!(out, "05\n06\n07\n08\n09\n10\n");
}

View file

@ -1,65 +0,0 @@
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::process::Command;
static PROGNAME: &'static str = "./sort";
#[test]
fn numeric1() {
numeric_helper(1);
}
#[test]
fn numeric2() {
numeric_helper(2);
}
#[test]
fn numeric3() {
numeric_helper(3);
}
#[test]
fn numeric4() {
numeric_helper(4);
}
#[test]
fn numeric5() {
numeric_helper(5);
}
#[test]
fn numeric6() {
numeric_helper(6);
}
#[test]
fn human1() {
test_helper(&String::from("human1"), &String::from("-H"));
}
fn numeric_helper(test_num: isize) {
test_helper(&format!("numeric{}", test_num), &String::from("-n"))
}
fn test_helper(file_name: &String, args: &String) {
let mut cmd = Command::new(PROGNAME);
cmd.arg(args);
let po = match cmd.arg(format!("{}{}", file_name, ".txt")).output() {
Ok(p) => p,
Err(err) => panic!("{}", err)
};
let filename = format!("{}{}", file_name, ".ans");
let mut f = File::open(Path::new(&filename)).unwrap_or_else(|err| {
panic!("{}", err)
});
let mut answer = vec!();
match f.read_to_end(&mut answer) {
Ok(_) => {},
Err(err) => panic!("{}", err)
}
assert_eq!(String::from_utf8(po.stdout).unwrap(), String::from_utf8(answer).unwrap());
}

View file

@ -1,160 +0,0 @@
extern crate libc;
extern crate memchr;
extern crate aho_corasick;
extern crate rand;
extern crate regex_syntax;
extern crate regex;
use std::fs::{File, read_dir, remove_file};
use std::io::{Read, Write};
use std::path::Path;
use std::process::Command;
use rand::{Rng, thread_rng};
use regex::Regex;
use util::*;
static PROGNAME: &'static str = "./split";
#[path = "common/util.rs"]
#[macro_use]
mod util;
fn random_chars(n: usize) -> String {
thread_rng().gen_ascii_chars().take(n).collect::<String>()
}
struct Glob {
directory: String,
regex: Regex
}
impl Glob {
fn new(directory: &str, regex: &str) -> Glob {
Glob {
directory: directory.to_string(),
regex: Regex::new(regex).unwrap()
}
}
fn count(&self) -> usize {
self.collect().len()
}
fn collect(&self) -> Vec<String> {
read_dir(Path::new(&self.directory)).unwrap().filter_map(|entry| {
let path = entry.unwrap().path();
let name = path.as_path().to_str().unwrap_or("");
if self.regex.is_match(name) { Some(name.to_string()) } else { None }
}).collect()
}
fn collate(&self) -> Vec<u8> {
let mut files = self.collect();
files.sort();
let mut data: Vec<u8> = vec!();
for name in files.iter() {
data.extend(get_file_contents(name).into_bytes());
}
data
}
fn remove_all(&self) {
for name in self.collect().iter() {
let _ = remove_file(name);
}
}
}
struct RandomFile {
inner: File
}
impl RandomFile {
fn new(name: &str) -> RandomFile {
RandomFile { inner: File::create(Path::new(name)).unwrap() }
}
fn add_bytes(&mut self, bytes: usize) {
let chunk_size: usize = if bytes >= 1024 { 1024 } else { bytes };
let mut n = bytes;
while n > chunk_size {
let _ = write!(self.inner, "{}", random_chars(chunk_size));
n -= chunk_size;
}
let _ = write!(self.inner, "{}", random_chars(n));
}
fn add_lines(&mut self, lines: usize) {
let line_size: usize = 32;
let mut n = lines;
while n > 0 {
let _ = writeln!(self.inner, "{}", random_chars(line_size));
n -= 1;
}
}
}
#[test]
fn test_split_default() {
let name = "split_default";
let glob = Glob::new(".", r"x[:alpha:][:alpha:]$");
RandomFile::new(name).add_lines(2000);
if !Command::new(PROGNAME).args(&[name]).status().unwrap().success() {
panic!();
}
assert_eq!(glob.count(), 2);
assert_eq!(glob.collate(), get_file_contents(name).into_bytes());
glob.remove_all();
}
#[test]
fn test_split_num_prefixed_chunks_by_bytes() {
let name = "split_num_prefixed_chunks_by_bytes";
let glob = Glob::new(".", r"a\d\d$");
RandomFile::new(name).add_bytes(10000);
if !Command::new(PROGNAME).args(&["-d", "-b", "1000", name, "a"]).status().unwrap().success() {
panic!();
}
assert_eq!(glob.count(), 10);
assert_eq!(glob.collate(), get_file_contents(name).into_bytes());
glob.remove_all();
}
#[test]
fn test_split_str_prefixed_chunks_by_bytes() {
let name = "split_str_prefixed_chunks_by_bytes";
let glob = Glob::new(".", r"b[:alpha:][:alpha:]$");
RandomFile::new(name).add_bytes(10000);
if !Command::new(PROGNAME).args(&["-b", "1000", name, "b"]).status().unwrap().success() {
panic!();
}
assert_eq!(glob.count(), 10);
assert_eq!(glob.collate(), get_file_contents(name).into_bytes());
glob.remove_all();
}
#[test]
fn test_split_num_prefixed_chunks_by_lines() {
let name = "split_num_prefixed_chunks_by_lines";
let glob = Glob::new(".", r"c\d\d$");
RandomFile::new(name).add_lines(10000);
if !Command::new(PROGNAME).args(&["-d", "-l", "1000", name, "c"]).status().unwrap().success() {
panic!();
}
assert_eq!(glob.count(), 10);
assert_eq!(glob.collate(), get_file_contents(name).into_bytes());
glob.remove_all();
}
#[test]
fn test_split_str_prefixed_chunks_by_lines() {
let name = "split_str_prefixed_chunks_by_lines";
let glob = Glob::new(".", r"d[:alpha:][:alpha:]$");
RandomFile::new(name).add_lines(10000);
if !Command::new(PROGNAME).args(&["-l", "1000", name, "d"]).status().unwrap().success() {
panic!();
}
assert_eq!(glob.count(), 10);
assert_eq!(glob.collate(), get_file_contents(name).into_bytes());
glob.remove_all();
}

View file

@ -1,16 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./stdbuf";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_stdbuf_unbuffered_stdout() {
// This is a basic smoke test
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-o0", "head"]), "The quick brown fox jumps over the lazy dog.");
assert_eq!(result.stdout, "The quick brown fox jumps over the lazy dog.");
}

View file

@ -1,70 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./sum";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_bsd_single_file() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.arg("lorem_ipsum.txt"));
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, get_file_contents("bsd_single_file.expected"));
}
#[test]
fn test_bsd_multiple_files() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.arg("lorem_ipsum.txt").arg("alice_in_wonderland.txt"));
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, get_file_contents("bsd_multiple_files.expected"));
}
#[test]
fn test_bsd_stdin() {
let input = get_file_contents("lorem_ipsum.txt");
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd, input);
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, get_file_contents("bsd_stdin.expected"));
}
#[test]
fn test_sysv_single_file() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.arg("-s").arg("lorem_ipsum.txt"));
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, get_file_contents("sysv_single_file.expected"));
}
#[test]
fn test_sysv_multiple_files() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.arg("-s").arg("lorem_ipsum.txt").arg("alice_in_wonderland.txt"));
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, get_file_contents("sysv_multiple_files.expected"));
}
#[test]
fn test_sysv_stdin() {
let input = get_file_contents("lorem_ipsum.txt");
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.arg("-s"), input);
assert_empty_stderr!(result);
assert!(result.success);
assert_eq!(result.stdout, get_file_contents("sysv_stdin.expected"));
}

View file

@ -1,50 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./tac";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_stdin_default() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd, "100\n200\n300\n400\n500");
assert_eq!(result.stdout, "500400\n300\n200\n100\n");
}
#[test]
fn test_stdin_non_newline_separator() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-s", ":"]), "100:200:300:400:500");
assert_eq!(result.stdout, "500400:300:200:100:");
}
#[test]
fn test_stdin_non_newline_separator_before() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-b", "-s", ":"]), "100:200:300:400:500");
assert_eq!(result.stdout, "500:400:300:200:100");
}
#[test]
fn test_single_default() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.arg("prime_per_line.txt"));
assert_eq!(result.stdout, get_file_contents("prime_per_line.expected"));
}
#[test]
fn test_single_non_newline_separator() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-s", ":", "delimited_primes.txt"]));
assert_eq!(result.stdout, get_file_contents("delimited_primes.expected"));
}
#[test]
fn test_single_non_newline_separator_before() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-b", "-s", ":", "delimited_primes.txt"]));
assert_eq!(result.stdout, get_file_contents("delimited_primes_before.expected"));
}

View file

@ -1,37 +0,0 @@
/*
* This file is part of the uutils coreutils package.
*
* (c) mahkoh (ju.orth [at] gmail [dot] com)
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use std::process::Command;
static PROGNAME: &'static str = "./test";
#[test]
fn test_op_prec_and_or_1() {
let status = Command::new(PROGNAME).arg(" ").arg("-o").arg("").arg("-a").arg("").status();
assert_eq!(true, status.unwrap().success());
}
#[test]
fn test_op_prec_and_or_2() {
let status = Command::new(PROGNAME).arg("")
.arg("-a")
.arg("")
.arg("-o")
.arg(" ")
.arg("-a")
.arg(" ")
.status();
assert_eq!(true, status.unwrap().success());
}
#[test]
fn test_or_as_filename() {
let status = Command::new(PROGNAME).arg("x").arg("-a").arg("-z").arg("-o").status();
assert_eq!(status.unwrap().code(), Some(1));
}

View file

@ -1,43 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./tr";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_toupper() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["a-z", "A-Z"]), b"!abcd!");
assert_eq!(result.stdout, "!ABCD!");
}
#[test]
fn test_small_set2() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["0-9", "X"]), b"@0123456789");
assert_eq!(result.stdout, "@XXXXXXXXXX");
}
#[test]
fn test_unicode() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&[", ┬─┬", "╯︵┻━┻"]), "(,°□°), ┬─┬".as_bytes());
assert_eq!(result.stdout, "(╯°□°)╯︵┻━┻");
}
#[test]
fn test_delete() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-d", "a-z"]), b"aBcD");
assert_eq!(result.stdout, "BD");
}
#[test]
fn test_delete_complement() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-d", "-c", "a-z"]), b"aBcD");
assert_eq!(result.stdout, "ac");
}

View file

@ -1,9 +0,0 @@
use std::process::Command;
static PROGNAME: &'static str = "./true";
#[test]
fn test_exit_code() {
let exit_status = Command::new(PROGNAME).status().unwrap().success();
assert_eq!(exit_status, true);
}

View file

@ -1,41 +0,0 @@
use std::fs;
use std::io::{Seek, SeekFrom, Write};
use std::path::Path;
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./truncate";
static TFILE1: &'static str = "truncate_test_1";
static TFILE2: &'static str = "truncate_test_2";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_increase_file_size() {
let mut file = make_file(TFILE1);
if !Command::new(PROGNAME).args(&["-s", "+5K", TFILE1]).status().unwrap().success() {
panic!();
}
file.seek(SeekFrom::End(0)).unwrap();
if file.seek(SeekFrom::Current(0)).unwrap() != 5 * 1024 {
panic!();
}
fs::remove_file(Path::new(TFILE1)).unwrap();
}
#[test]
fn test_decrease_file_size() {
let mut file = make_file(TFILE2);
file.write_all(b"1234567890").unwrap();
if !Command::new(PROGNAME).args(&["--size=-4", TFILE2]).status().unwrap().success() {
panic!();
}
file.seek(SeekFrom::End(0)).unwrap();
if file.seek(SeekFrom::Current(0)).unwrap() != 6 {
println!("{:?}", file.seek(SeekFrom::Current(0)));
panic!();
}
fs::remove_file(Path::new(TFILE2)).unwrap();
}

View file

@ -1,21 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./tsort";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_sort_call_graph() {
let input = "call_graph.txt";
let output = "call_graph.expected";
let po = Command::new(PROGNAME)
.arg(input)
.output()
.unwrap_or_else(|err| panic!("{}", err));
assert_eq!(String::from_utf8(po.stdout).unwrap(), String::from_utf8(get_file_contents(output).into_bytes()).unwrap());
}

View file

@ -1,115 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./unexpand";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn unexpand_init_0() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-t4"]), " 1\n 2\n 3\n 4\n");
assert_eq!(result.stdout, " 1\n 2\n 3\n\t4\n");
}
#[test]
fn unexpand_init_1() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-t4"]), " 5\n 6\n 7\n 8\n");
assert_eq!(result.stdout, "\t 5\n\t 6\n\t 7\n\t\t8\n");
}
#[test]
fn unexpand_init_list_0() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-t2,4"]), " 1\n 2\n 3\n 4\n");
assert_eq!(result.stdout, " 1\n\t2\n\t 3\n\t\t4\n");
}
#[test]
fn unexpand_init_list_1() {
// Once the list is exhausted, spaces are not converted anymore
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-t2,4"]), " 5\n 6\n 7\n 8\n");
assert_eq!(result.stdout, "\t\t 5\n\t\t 6\n\t\t 7\n\t\t 8\n");
}
#[test]
fn unexpand_aflag_0() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["--"]), "e E\nf F\ng G\nh H\n");
assert_eq!(result.stdout, "e E\nf F\ng G\nh H\n");
}
#[test]
fn unexpand_aflag_1() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-a"]), "e E\nf F\ng G\nh H\n");
assert_eq!(result.stdout, "e E\nf F\ng\tG\nh\t H\n");
}
#[test]
fn unexpand_aflag_2() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-t8"]), "e E\nf F\ng G\nh H\n");
assert_eq!(result.stdout, "e E\nf F\ng\tG\nh\t H\n");
}
#[test]
fn unexpand_first_only_0() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-t3"]), " A B");
assert_eq!(result.stdout, "\t\t A\t B");
}
#[test]
fn unexpand_first_only_1() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-t3", "--first-only"]), " A B");
assert_eq!(result.stdout, "\t\t A B");
}
#[test]
fn unexpand_trailing_space_0() { // evil
// Individual spaces before fields starting with non blanks should not be
// converted, unless they are at the beginning of the line.
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-t4"]), "123 \t1\n123 1\n123 \n123 ");
assert_eq!(result.stdout, "123\t\t1\n123 1\n123 \n123 ");
}
#[test]
fn unexpand_trailing_space_1() { // super evil
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-t1"]), " abc d e f g ");
assert_eq!(result.stdout, "\tabc d e\t\tf\t\tg ");
}
#[test]
fn unexpand_spaces_follow_tabs_0() {
// The two first spaces can be included into the first tab.
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd, " \t\t A");
assert_eq!(result.stdout, "\t\t A");
}
#[test]
fn unexpand_spaces_follow_tabs_1() { // evil
// Explanation of what is going on here:
// 'a' -> 'a' // first tabstop (1)
// ' \t' -> '\t' // second tabstop (4)
// ' ' -> '\t' // third tabstop (5)
// ' B \t' -> ' B \t' // after the list is exhausted, nothing must change
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-t1,4,5"]), "a \t B \t");
assert_eq!(result.stdout, "a\t\t B \t");
}
#[test]
fn unexpand_spaces_after_fields() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-a"]), " \t A B C D A\t\n");
assert_eq!(result.stdout, "\t\tA B C D\t\t A\t\n");
}

View file

@ -1,59 +0,0 @@
extern crate libc;
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./unlink";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_unlink_file() {
let file = "test_unlink_file";
touch(file);
let result = run(Command::new(PROGNAME).arg(file));
assert_empty_stderr!(result);
assert!(result.success);
assert!(!file_exists(file));
}
#[test]
fn test_unlink_multiple_files() {
let file_a = "test_unlink_multiple_file_a";
let file_b = "test_unlink_multiple_file_b";
touch(file_a);
touch(file_b);
let result = run(Command::new(PROGNAME).arg(file_a).arg(file_b));
assert_eq!(result.stderr,
"unlink: error: extra operand: 'test_unlink_multiple_file_b'\nTry 'unlink --help' for more information.\n");
assert!(!result.success);
}
#[test]
fn test_unlink_directory() {
let dir = "test_unlink_empty_directory";
mkdir(dir);
let result = run(Command::new(PROGNAME).arg(dir));
assert_eq!(result.stderr,
"unlink: error: cannot unlink 'test_unlink_empty_directory': Not a regular file or symlink\n");
assert!(!result.success);
}
#[test]
fn test_unlink_nonexistent() {
let file = "test_unlink_nonexistent";
let result = run(Command::new(PROGNAME).arg(file));
assert_eq!(result.stderr,
"unlink: error: Cannot stat 'test_unlink_nonexistent': No such file or directory (os error 2)\n");
assert!(!result.success);
}

View file

@ -1,57 +0,0 @@
use std::process::Command;
use util::*;
static PROGNAME: &'static str = "./wc";
#[path = "common/util.rs"]
#[macro_use]
mod util;
#[test]
fn test_stdin_default() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd, get_file_contents("lorem_ipsum.txt"));
assert_eq!(result.stdout, " 13 109 772\n");
}
#[test]
fn test_stdin_only_bytes() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-c"]), get_file_contents("lorem_ipsum.txt"));
assert_eq!(result.stdout, " 772\n");
}
#[test]
fn test_stdin_all_counts() {
let mut cmd = Command::new(PROGNAME);
let result = run_piped_stdin(&mut cmd.args(&["-c", "-m", "-l", "-L", "-w"]), get_file_contents("alice_in_wonderland.txt"));
assert_eq!(result.stdout, " 5 57 302 302 66\n");
}
#[test]
fn test_single_default() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.arg("moby_dick.txt"));
assert_eq!(result.stdout, " 18 204 1115 moby_dick.txt\n");
}
#[test]
fn test_single_only_lines() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-l", "moby_dick.txt"]));
assert_eq!(result.stdout, " 18 moby_dick.txt\n");
}
#[test]
fn test_single_all_counts() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["-c", "-l", "-L", "-m", "-w", "alice_in_wonderland.txt"]));
assert_eq!(result.stdout, " 5 57 302 302 66 alice_in_wonderland.txt\n");
}
#[test]
fn test_multiple_default() {
let mut cmd = Command::new(PROGNAME);
let result = run(&mut cmd.args(&["lorem_ipsum.txt", "moby_dick.txt", "alice_in_wonderland.txt"]));
assert_eq!(result.stdout, " 13 109 772 lorem_ipsum.txt\n 18 204 1115 moby_dick.txt\n 5 57 302 alice_in_wonderland.txt\n 36 370 2189 total\n");
}

62
tests/base64.rs Normal file
View file

@ -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");
}

44
tests/basename.rs Normal file
View file

@ -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");
}

49
tests/cat.rs Normal file
View file

@ -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");
}

39
tests/cksum.rs Normal file
View file

@ -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"));
}

2
tests/common/mod.rs Normal file
View file

@ -0,0 +1,2 @@
#[macro_use]
pub mod util;

354
tests/common/util.rs Normal file
View file

@ -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
tests/cp.rs Normal file
View file

@ -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");
}

60
tests/cut.rs Normal file
View file

@ -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"));
}

25
tests/dirname.rs Normal file
View file

@ -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");
}

39
tests/echo.rs Normal file
View file

@ -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");
}

72
tests/env.rs Normal file
View file

@ -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
tests/factor.rs Normal file

File diff suppressed because it is too large Load diff

14
tests/false.rs Normal file
View file

@ -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);
}

Some files were not shown because too many files have changed in this diff Show more