tests: refactor conventional TestScenario usage

Updates to individual integration tests

  - use proposed conventional approach to beginning tests

  - use new convenience functions for using fixtures

  - use new names for TestScenario

Updates to integration test modules

  - add proposed conventional module-level functions

Updates to test/common/util.rs

  - rename TestSet, and its methods, for semantic clarity

  - create convenience functions for use of fixtures

  - delete convenience functions obsoleted by new conventions
This commit is contained in:
Nathan Ross
2016-08-01 13:42:00 -04:00
parent d7a053305c
commit 569cd162d3
57 changed files with 918 additions and 800 deletions
+50 -21
View File
@@ -25,10 +25,14 @@ static TESTS_DIR: &'static str = "tests";
static FIXTURES_DIR: &'static str = "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 \
another command in the same test, use TestScenario::new instead of \
testing();";
static MULTIPLE_STDIN_MEANINGLESS: &'static str = "Ucommand is designed around a typical use case of: provide args and input stream -> spawn process -> block until completion -> return output streams. For verifying that a particular section of the input stream is what causes a particular behavior, use the Command type directly.";
fn read_scenario_fixture<S: AsRef<OsStr>>(tmpd: &Option<Rc<TempDir>>, file_rel_path: S) -> String {
let tmpdir_path = tmpd.as_ref().unwrap().as_ref().path();
AtPath::new(tmpdir_path).read(file_rel_path.as_ref().to_str().unwrap())
}
pub fn repeat_str(s: &str, n: u32) -> String {
let mut repeated = String::new();
@@ -41,6 +45,8 @@ pub fn repeat_str(s: &str, n: u32) -> String {
/// A command result is the outputs of a command (streams and status code)
/// within a struct which has convenience assertion functions about those outputs
pub struct CmdResult {
//tmpd is used for convenience functions for asserts against fixtures
tmpd: Option<Rc<TempDir>>,
pub success: bool,
pub stdout: String,
pub stderr: String,
@@ -87,6 +93,12 @@ impl CmdResult {
assert_eq!(String::from(msg.as_ref()).trim_right(), self.stdout.trim_right());
Box::new(self)
}
/// like stdout_is(...), but expects the contents of the file at the provided relative path
pub fn stdout_is_fixture<T: AsRef<OsStr>>(&self, file_rel_path: T) -> Box<&CmdResult> {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.stdout_is(contents)
}
/// asserts that the command resulted in stderr stream output that equals the
/// passed in value, when both are trimmed of trailing whitespace
@@ -96,6 +108,12 @@ impl CmdResult {
Box::new(self)
}
/// like stderr_is(...), but expects the contents of the file at the provided relative path
pub fn stderr_is_fixture<T: AsRef<OsStr>>(&self, file_rel_path: T) -> Box<&CmdResult> {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.stderr_is(contents)
}
/// asserts that
/// 1. the command resulted in stdout stream output that equals the
/// passed in value, when both are trimmed of trailing whitespace
@@ -104,6 +122,12 @@ impl CmdResult {
self.stdout_is(msg).no_stderr()
}
/// like stdout_only(...), but expects the contents of the file at the provided relative path
pub fn stdout_only_fixture<T: AsRef<OsStr>>(&self, file_rel_path: T) -> Box<&CmdResult> {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.stdout_only(contents)
}
/// asserts that
/// 1. the command resulted in stderr stream output that equals the
/// passed in value, when both are trimmed of trailing whitespace
@@ -112,6 +136,12 @@ impl CmdResult {
self.stderr_is(msg).no_stdout()
}
/// like stderr_only(...), but expects the contents of the file at the provided relative path
pub fn stderr_only_fixture<T: AsRef<OsStr>>(&self, file_rel_path: T) -> Box<&CmdResult> {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.stderr_only(contents)
}
pub fn fails_silently(&self) -> Box<&CmdResult> {
assert!(!self.success);
assert_eq!(0, self.stderr.len());
@@ -321,17 +351,17 @@ impl AtPath {
/// 1. centralizes logic for locating the uutils binary and calling the utility
/// 2. provides a temporary directory for the test case
/// 3. copies over fixtures for the utility to the temporary directory
pub struct TestSet {
pub struct TestScenario {
bin_path: PathBuf,
util_name: String,
pub fixtures: AtPath,
tmpd: Rc<TempDir>,
}
impl TestSet {
pub fn new(util_name: &str) -> TestSet {
impl TestScenario {
pub fn new(util_name: &str) -> TestScenario {
let tmpd = Rc::new(TempDir::new("uutils").unwrap());
let ts = TestSet {
let ts = TestScenario {
bin_path: {
// Instead of hardcoding the path relative to the current
// directory, use Cargo's OUT_DIR to find path to executable.
@@ -356,7 +386,7 @@ impl TestSet {
ts
}
pub fn util_cmd(&self) -> UCommand {
pub fn ucmd(&self) -> UCommand {
let mut cmd = self.cmd(&self.bin_path);
cmd.arg(&self.util_name);
cmd
@@ -368,7 +398,7 @@ impl TestSet {
// 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 {
pub fn ucmd_keepenv(&self) -> UCommand {
let mut cmd = self.cmd_keepenv(&self.bin_path);
cmd.arg(&self.util_name);
cmd
@@ -440,6 +470,12 @@ impl UCommand {
Box::new(self)
}
/// like arg(...), but uses the contents of the file at the provided relative path as the argument
pub fn arg_fixture<S: AsRef<OsStr>>(&mut self, file_rel_path: S) -> Box<&mut UCommand> {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.arg(contents)
}
pub fn args<S: AsRef<OsStr>>(&mut self, args: &[S]) -> Box<&mut UCommand> {
if self.has_run {
panic!(MULTIPLE_STDIN_MEANINGLESS);
@@ -462,6 +498,12 @@ impl UCommand {
Box::new(self)
}
/// like pipe_in(...), but uses the contents of the file at the provided relative path as the piped in data
pub fn pipe_in_fixture<S: AsRef<OsStr>>(&mut self, file_rel_path: S) -> Box<&mut UCommand> {
let contents = read_scenario_fixture(&self.tmpd, file_rel_path);
self.pipe_in(contents)
}
pub fn env<K, V>(&mut self, key: K, val: V) -> Box<&mut UCommand> where K: AsRef<OsStr>, V: AsRef<OsStr> {
if self.has_run {
panic!(ALREADY_RUN);
@@ -505,6 +547,7 @@ impl UCommand {
let prog = self.run_no_wait().wait_with_output().unwrap();
CmdResult {
tmpd: self.tmpd.clone(),
success: prog.status.success(),
stdout: from_utf8(&prog.stdout).unwrap().to_string(),
stderr: from_utf8(&prog.stderr).unwrap().to_string(),
@@ -543,17 +586,3 @@ pub fn read_size(child: &mut Child, size: usize) -> String {
child.stdout.as_mut().unwrap().read(output.as_mut_slice()).unwrap();
String::from_utf8(output).unwrap()
}
/// 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)
}
+19 -14
View File
@@ -1,12 +1,15 @@
use common::util::*;
static UTIL_NAME: &'static str = "base64";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[test]
fn test_encode() {
let (_, mut ucmd) = testing(UTIL_NAME);
let input = "hello, world!";
ucmd.pipe_in(input)
new_ucmd()
.pipe_in(input)
.succeeds()
.stdout_only("aGVsbG8sIHdvcmxkIQ==\n");
}
@@ -14,9 +17,9 @@ fn test_encode() {
#[test]
fn test_decode() {
for decode_param in vec!["-d", "--decode"] {
let (_, mut ucmd) = testing(UTIL_NAME);
let input = "aGVsbG8sIHdvcmxkIQ==";
ucmd.arg(decode_param)
new_ucmd()
.arg(decode_param)
.pipe_in(input)
.succeeds()
.stdout_only("hello, world!");
@@ -25,9 +28,9 @@ fn test_decode() {
#[test]
fn test_garbage() {
let (_, mut ucmd) = testing(UTIL_NAME);
let input = "aGVsbG8sIHdvcmxkIQ==\0";
ucmd.arg("-d")
new_ucmd()
.arg("-d")
.pipe_in(input)
.fails()
.stderr_only("base64: error: invalid character (Invalid character '0' at position 20)\n");
@@ -36,9 +39,10 @@ fn test_garbage() {
#[test]
fn test_ignore_garbage() {
for ignore_garbage_param in vec!["-i", "--ignore-garbage"] {
let (_, mut ucmd) = testing(UTIL_NAME);
let input = "aGVsbG8sIHdvcmxkIQ==\0";
ucmd.arg("-d").arg(ignore_garbage_param)
new_ucmd()
.arg("-d")
.arg(ignore_garbage_param)
.pipe_in(input)
.succeeds()
.stdout_only("hello, world!");
@@ -48,9 +52,10 @@ fn test_ignore_garbage() {
#[test]
fn test_wrap() {
for wrap_param in vec!["-w", "--wrap"] {
let (_, mut ucmd) = testing(UTIL_NAME);
let input = "The quick brown fox jumps over the lazy dog.";
ucmd.arg(wrap_param).arg("20")
new_ucmd()
.arg(wrap_param)
.arg("20")
.pipe_in(input)
.succeeds()
.stdout_only("VGhlIHF1aWNrIGJyb3du\nIGZveCBqdW1wcyBvdmVy\nIHRoZSBsYXp5IGRvZy4=\n");
@@ -60,8 +65,8 @@ fn test_wrap() {
#[test]
fn test_wrap_no_arg() {
for wrap_param in vec!["-w", "--wrap"] {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.arg(wrap_param)
new_ucmd()
.arg(wrap_param)
.fails()
.stderr_only(
format!("base64: error: Argument to option '{}' missing.",
@@ -72,8 +77,8 @@ fn test_wrap_no_arg() {
#[test]
fn test_wrap_bad_arg() {
for wrap_param in vec!["-w", "--wrap"] {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.arg(wrap_param).arg("b")
new_ucmd()
.arg(wrap_param).arg("b")
.fails()
.stderr_only("base64: error: Argument to option 'wrap' improperly formatted: invalid digit found in string");
}
+7 -4
View File
@@ -1,10 +1,13 @@
use common::util::*;
static UTIL_NAME: &'static str = "basename";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
fn expect_successful_stdout(input: Vec<&str>, expected: &str) {
let (_, mut ucmd) = testing(UTIL_NAME);
let results = ucmd.args(&input).run();
let results = new_ucmd()
.args(&input).run();
assert_empty_stderr!(results);
assert!(results.success);
assert_eq!(expected, results.stdout.trim_right());
@@ -35,8 +38,8 @@ fn test_dont_remove_suffix() {
}
fn expect_error(input: Vec<&str>, expected_stdout: &str) {
let (_, mut ucmd) = testing(UTIL_NAME);
let results = ucmd.args(&input).run();
let results = new_ucmd()
.args(&input).run();
assert!(!results.success);
assert!(results.stderr.len() > 0);
assert_eq!(expected_stdout, results.stdout.trim_right());
+25 -22
View File
@@ -1,11 +1,14 @@
use common::util::*;
static UTIL_NAME: &'static str = "cat";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[test]
fn test_output_multi_files_print_all_chars() {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.args(&["alpha.txt", "256.txt", "-A", "-n"])
new_ucmd()
.args(&["alpha.txt", "256.txt", "-A", "-n"])
.succeeds()
.stdout_only(" 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 \
@@ -23,8 +26,8 @@ fn test_output_multi_files_print_all_chars() {
#[test]
fn test_stdin_show_nonprinting() {
for same_param in vec!["-v", "--show-nonprinting"] {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.args(&vec![same_param])
new_ucmd()
.args(&vec![same_param])
.pipe_in("\t\0\n")
.succeeds()
.stdout_only("\t^@");
@@ -34,8 +37,8 @@ fn test_stdin_show_nonprinting() {
#[test]
fn test_stdin_show_tabs() {
for same_param in vec!["-T", "--show-tabs"] {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.args(&[same_param])
new_ucmd()
.args(&[same_param])
.pipe_in("\t\0\n")
.succeeds()
.stdout_only("^I\0");
@@ -46,8 +49,8 @@ fn test_stdin_show_tabs() {
#[test]
fn test_stdin_show_ends() {
for same_param in vec!["-E", "--show-ends"] {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.args(&[same_param,"-"])
new_ucmd()
.args(&[same_param,"-"])
.pipe_in("\t\0\n")
.succeeds()
.stdout_only("\t\0$");
@@ -57,8 +60,8 @@ fn test_stdin_show_ends() {
#[test]
fn test_stdin_show_all() {
for same_param in vec!["-A", "--show-all"] {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.args(&[same_param])
new_ucmd()
.args(&[same_param])
.pipe_in("\t\0\n")
.succeeds()
.stdout_only("^I^@$");
@@ -67,8 +70,8 @@ fn test_stdin_show_all() {
#[test]
fn test_stdin_nonprinting_and_endofline() {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.args(&["-e"])
new_ucmd()
.args(&["-e"])
.pipe_in("\t\0\n")
.succeeds()
.stdout_only("\t^@$\n");
@@ -76,8 +79,8 @@ fn test_stdin_nonprinting_and_endofline() {
#[test]
fn test_stdin_nonprinting_and_tabs() {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.args(&["-t"])
new_ucmd()
.args(&["-t"])
.pipe_in("\t\0\n")
.succeeds()
.stdout_only("^I^@\n");
@@ -86,8 +89,8 @@ fn test_stdin_nonprinting_and_tabs() {
#[test]
fn test_stdin_squeeze_blank() {
for same_param in vec!["-s", "--squeeze-blank"] {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.arg(same_param)
new_ucmd()
.arg(same_param)
.pipe_in("\n\na\n\n\n\n\nb\n\n\n")
.succeeds()
.stdout_only("\na\n\nb\n\n");
@@ -97,8 +100,8 @@ fn test_stdin_squeeze_blank() {
#[test]
fn test_stdin_number_non_blank() {
for same_param in vec!["-b", "--number-nonblank"] {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.arg(same_param)
new_ucmd()
.arg(same_param)
.arg("-")
.pipe_in("\na\nb\n\n\nc")
.succeeds()
@@ -109,8 +112,8 @@ fn test_stdin_number_non_blank() {
#[test]
fn test_non_blank_overrides_number() {
for same_param in vec!["-b", "--number-nonblank"] {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.args(&[same_param, "-"])
new_ucmd()
.args(&[same_param, "-"])
.pipe_in("\na\nb\n\n\nc")
.succeeds()
.stdout_only("\n 1\ta\n 2\tb\n\n\n 3\tc");
@@ -120,8 +123,8 @@ fn test_non_blank_overrides_number() {
#[test]
fn test_squeeze_blank_before_numbering() {
for same_param in vec!["-s", "--squeeze-blank"] {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.args(&[same_param, "-n", "-"])
new_ucmd()
.args(&[same_param, "-n", "-"])
.pipe_in("a\n\n\nb")
.succeeds()
.stdout_only(" 1\ta\n 2\t\n 3\tb");
+8 -2
View File
@@ -6,6 +6,12 @@ extern crate libc;
use self::libc::umask;
static UTIL_NAME: &'static str = "chmod";
fn at_and_ucmd() -> (AtPath, UCommand) {
let ts = TestScenario::new(UTIL_NAME);
let ucmd = ts.ucmd();
(ts.fixtures, ucmd)
}
static TEST_FILE: &'static str = "file";
static REFERENCE_FILE: &'static str = "reference";
static REFERENCE_PERMS: u32 = 0o247;
@@ -47,7 +53,7 @@ fn run_single_test(test: &TestCase, at: AtPath, mut ucmd: UCommand) {
fn run_tests(tests: Vec<TestCase>) {
for test in tests {
let (at, ucmd) = testing(UTIL_NAME);
let (at, ucmd) = at_and_ucmd();
run_single_test(&test, at, ucmd);
}
}
@@ -129,7 +135,7 @@ fn test_chmod_reference_file() {
TestCase{args: vec!{"--reference", REFERENCE_FILE, TEST_FILE}, before: 0o070, after: 0o247},
TestCase{args: vec!{"a-w", "--reference", REFERENCE_FILE, TEST_FILE}, before: 0o070, after: 0o247},
};
let (at, ucmd) = testing(UTIL_NAME);
let (at, ucmd) = at_and_ucmd();
mkfile(&at.plus_as_string(REFERENCE_FILE), REFERENCE_PERMS);
run_single_test(&tests[0], at, ucmd);
}
+6 -3
View File
@@ -4,6 +4,9 @@ extern crate uu_chown;
pub use self::uu_chown::*;
static UTIL_NAME: &'static str = "chown";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[cfg(test)]
mod test_passwd {
@@ -46,7 +49,7 @@ mod test_passwd {
#[test]
fn test_invalid_option() {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.arg("-w").arg("-q").arg("/");
ucmd.fails();
new_ucmd()
.arg("-w").arg("-q").arg("/")
.fails();
}
+12 -21
View File
@@ -1,36 +1,27 @@
use common::util::*;
static UTIL_NAME: &'static str = "cksum";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[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"));
new_ucmd().arg("lorem_ipsum.txt")
.succeeds().stdout_is_fixture("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"));
new_ucmd()
.arg("lorem_ipsum.txt")
.arg("alice_in_wonderland.txt")
.succeeds().stdout_is_fixture("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"));
new_ucmd()
.pipe_in_fixture("lorem_ipsum.txt")
.succeeds().stdout_is_fixture("stdin.expected");
}
+14 -6
View File
@@ -1,12 +1,20 @@
use common::util::testing;
use common::util::*;
use std::ffi::OsStr;
static UTIL_NAME: &'static str = "comm";
fn at_and_ucmd() -> (AtPath, UCommand) {
let ts = TestScenario::new(UTIL_NAME);
let ucmd = ts.ucmd();
(ts.fixtures, ucmd)
}
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
fn comm<A: AsRef<OsStr>, B: AsRef<str>>(args: &[A],
file_stdout_relpath_opt: Option<B>,
error_message_opt: Option<B>) {
let (at, mut ucmd) = testing(UTIL_NAME);
let (at, mut ucmd) = at_and_ucmd();
let result = ucmd.args(args)
.run();
assert!(result.success == error_message_opt.is_none());
@@ -146,8 +154,8 @@ fn unintuitive_default_behavior_1() {
#[ignore] //bug? should help be stdout if not called via -h|--help?
#[test]
fn no_arguments() {
let (_, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.run();
let result = new_ucmd()
.run();
assert!(!result.success);
assert!(result.stdout.len() == 0);
assert!(result.stderr.len() > 0);
@@ -156,8 +164,8 @@ fn no_arguments() {
#[ignore] //bug? should help be stdout if not called via -h|--help?
#[test]
fn one_argument() {
let (_, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.arg("a").run();
let result = new_ucmd()
.arg("a").run();
assert!(!result.success);
assert!(result.stdout.len() == 0);
assert!(result.stderr.len() > 0);
+13 -9
View File
@@ -1,5 +1,10 @@
use common::util::*;
static UTIL_NAME: &'static str = "cp";
fn at_and_ucmd() -> (AtPath, UCommand) {
let ts = TestScenario::new(UTIL_NAME);
let ucmd = ts.ucmd();
(ts.fixtures, ucmd)
}
static TEST_HELLO_WORLD_SOURCE: &'static str = "hello_world.txt";
static TEST_HELLO_WORLD_DEST: &'static str = "copy_of_hello_world.txt";
@@ -9,7 +14,7 @@ static TEST_COPY_FROM_FOLDER_FILE: &'static str = "hello_dir_with_file/hello_wor
#[test]
fn test_cp_cp() {
let (at, mut ucmd) = testing(UTIL_NAME);
let (at, mut ucmd) = at_and_ucmd();
// Invoke our binary to make the copy.
let result = ucmd.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_HELLO_WORLD_DEST)
@@ -25,11 +30,10 @@ fn test_cp_cp() {
#[test]
fn test_cp_with_dirs_t() {
let ts = TestSet::new(UTIL_NAME);
let at = &ts.fixtures;
let (at, mut ucmd) = at_and_ucmd();
//using -t option
let result_to_dir_t = ts.util_cmd()
let result_to_dir_t = ucmd
.arg("-t")
.arg(TEST_COPY_TO_FOLDER)
.arg(TEST_HELLO_WORLD_SOURCE)
@@ -40,21 +44,21 @@ fn test_cp_with_dirs_t() {
#[test]
fn test_cp_with_dirs() {
let ts = TestSet::new(UTIL_NAME);
let at = &ts.fixtures;
let scene = TestScenario::new(UTIL_NAME);
let at = &scene.fixtures;
//using -t option
let result_to_dir = ts.util_cmd()
let result_to_dir = scene.ucmd()
.arg(TEST_HELLO_WORLD_SOURCE)
.arg(TEST_COPY_TO_FOLDER)
.run();
assert!(result_to_dir.success);
assert_eq!(at.read(TEST_COPY_TO_FOLDER_FILE), "Hello, World!\n");
let result_from_dir = ts.util_cmd()
let result_from_dir = scene.ucmd()
.arg(TEST_COPY_FROM_FOLDER_FILE)
.arg(TEST_HELLO_WORLD_DEST)
.run();
assert!(result_from_dir.success);
assert_eq!(at.read(TEST_HELLO_WORLD_DEST), "Hello, World!\n");
}
}
+12 -23
View File
@@ -1,57 +1,46 @@
use common::util::*;
static UTIL_NAME: &'static str = "cut";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
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"));
new_ucmd().args(&["-c", "-10", INPUT]).run().stdout_is_fixture("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"));
new_ucmd().args(&["-c", "4-10", INPUT]).run().stdout_is_fixture("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"));
new_ucmd().args(&["-d", ":", "-f", "5-", INPUT]).run().stdout_is_fixture("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"));
new_ucmd().args(&["-d", " ", "-f", "3", INPUT]).run().stdout_is_fixture("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"));
new_ucmd().args(&["-d", ":", "-f", "1,3", INPUT]).run().stdout_is_fixture("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"));
new_ucmd().args(&["-d", ":", "--complement", "-f", "1", INPUT]).run().stdout_is_fixture("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"));
new_ucmd()
.args(&["-d", ":", "--complement", "--output-delimiter=#", "-f", "1", INPUT])
.run().stdout_is_fixture("lists_change_delimiter.expected");
}
+24 -30
View File
@@ -4,6 +4,9 @@ use self::uu_dircolors::{StrUtils, guess_syntax, OutputFmt};
use common::util::*;
static UTIL_NAME: &'static str = "dircolors";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[test]
fn test_shell_syntax() {
@@ -57,55 +60,46 @@ fn test_keywords() {
#[test]
fn test_internal_db() {
let (at, mut ucmd) = testing(UTIL_NAME);
ucmd.arg("-p");
let out = ucmd.run().stdout;
let filename = "internal.expected";
assert_eq!(out, at.read(filename));
new_ucmd()
.arg("-p")
.run()
.stdout_is_fixture("internal.expected");
}
#[test]
fn test_bash_default() {
let (at, mut ucmd) = testing(UTIL_NAME);
ucmd.arg("-b");
let out = ucmd.env("TERM", "screen").run().stdout;
let filename = "bash_def.expected";
assert_eq!(out, at.read(filename));
new_ucmd().env("TERM", "screen").arg("-b").run().stdout_is_fixture("bash_def.expected");
}
#[test]
fn test_csh_default() {
let (at, mut ucmd) = testing(UTIL_NAME);
ucmd.arg("-c");
let out = ucmd.env("TERM", "screen").run().stdout;
let filename = "csh_def.expected";
assert_eq!(out, at.read(filename));
new_ucmd().env("TERM", "screen").arg("-c").run().stdout_is_fixture("csh_def.expected");
}
#[test]
fn test_no_env() {
// no SHELL and TERM
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.fails();
new_ucmd()
.fails();
}
#[test]
fn test_exclusive_option() {
let (_, mut ucmd) = testing(UTIL_NAME);
ucmd.arg("-cp");
ucmd.fails();
new_ucmd()
.arg("-cp")
.fails();
}
fn test_helper(file_name: &str, term: &str) {
let (at, mut ucmd) = testing(UTIL_NAME);
ucmd.arg("-c").env("TERM", term);
let out = ucmd.arg(format!("{}.txt", file_name)).run().stdout;
let filename = format!("{}.csh.expected", file_name);
assert_eq!(out, at.read(&filename));
new_ucmd()
.env("TERM", term)
.arg("-c")
.arg(format!("{}.txt", file_name))
.run().stdout_is_fixture(format!("{}.csh.expected", file_name));
let (at, mut ucmd) = testing(UTIL_NAME);
ucmd.arg("-b").env("TERM", term);
let out = ucmd.arg(format!("{}.txt", file_name)).run().stdout;
let filename = format!("{}.sh.expected", file_name);
assert_eq!(out, at.read(&filename));
new_ucmd()
.env("TERM", term)
.arg("-b")
.arg(format!("{}.txt", file_name))
.run().stdout_is_fixture(format!("{}.sh.expected", file_name));
}
+8 -10
View File
@@ -1,48 +1,46 @@
use common::util::*;
static UTIL_NAME: &'static str = "dirname";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[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;
let out = new_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;
let out = new_ucmd().arg(dir).run().stdout;
assert_eq!(out.trim_right(), "/root/alpha/beta/gamma/delta/epsilon");
}
#[test]
fn test_root() {
let (_, mut ucmd) = testing(UTIL_NAME);
let dir = "/";
let out = ucmd.arg(dir).run().stdout;
let out = new_ucmd().arg(dir).run().stdout;
assert_eq!(out.trim_right(), "/");
}
#[test]
fn test_pwd() {
let (_, mut ucmd) = testing(UTIL_NAME);
let dir = ".";
let out = ucmd.arg(dir).run().stdout;
let out = new_ucmd().arg(dir).run().stdout;
assert_eq!(out.trim_right(), ".");
}
#[test]
fn test_empty() {
let (_, mut ucmd) = testing(UTIL_NAME);
let dir = "";
let out = ucmd.arg(dir).run().stdout;
let out = new_ucmd().arg(dir).run().stdout;
assert_eq!(out.trim_right(), ".");
}
+20 -17
View File
@@ -1,36 +1,39 @@
use common::util::*;
static UTIL_NAME: &'static str = "echo";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[test]
fn test_default() {
let (_, mut ucmd) = testing(UTIL_NAME);
assert_eq!(ucmd.run().stdout, "\n");
assert_eq!(new_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");
new_ucmd()
.arg("-n")
.arg("hello_world")
.run()
.stdout_is("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");
new_ucmd()
.arg("-e")
.arg("\\\\\\t\\r")
.run()
.stdout_is("\\\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");
new_ucmd()
.arg("-E")
.arg("\\b\\c\\e")
.run()
.stdout_is("\\b\\c\\e\n");
}
+14 -11
View File
@@ -1,19 +1,22 @@
use common::util::*;
static UTIL_NAME: &'static str = "env";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[test]
fn test_single_name_value_pair() {
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.arg("FOO=bar").run().stdout;
let out = new_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")
let out = new_ucmd()
.arg("FOO=bar")
.arg("ABC=xyz")
.run()
.stdout;
@@ -24,16 +27,16 @@ fn test_multiple_name_value_pairs() {
#[test]
fn test_ignore_environment() {
let ts = TestSet::new(UTIL_NAME);
let scene = TestScenario::new(UTIL_NAME);
let out = ts.util_cmd()
let out = scene.ucmd()
.arg("-i")
.run()
.stdout;
assert_eq!(out, "");
let out = ts.util_cmd()
let out = scene.ucmd()
.arg("-")
.run()
.stdout;
@@ -43,8 +46,8 @@ fn test_ignore_environment() {
#[test]
fn test_null_delimiter() {
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.arg("-i")
let out = new_ucmd()
.arg("-i")
.arg("--null")
.arg("FOO=bar")
.arg("ABC=xyz")
@@ -63,8 +66,8 @@ fn test_null_delimiter() {
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()
let out = TestScenario::new(UTIL_NAME)
.ucmd_keepenv()
.arg("-u")
.arg("HOME")
.run()
+21 -18
View File
@@ -1,51 +1,54 @@
use common::util::*;
static UTIL_NAME: &'static str = "expr";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[test]
fn test_simple_arithmetic() {
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.args(&["1", "+", "1"]).run().stdout;
let out = new_ucmd()
.args(&["1", "+", "1"]).run().stdout;
assert_eq!(out, "2\n");
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.args(&["1", "-", "1"]).run().stdout;
let out = new_ucmd()
.args(&["1", "-", "1"]).run().stdout;
assert_eq!(out, "0\n");
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.args(&["3", "*", "2"]).run().stdout;
let out = new_ucmd()
.args(&["3", "*", "2"]).run().stdout;
assert_eq!(out, "6\n");
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.args(&["4", "/", "2"]).run().stdout;
let out = new_ucmd()
.args(&["4", "/", "2"]).run().stdout;
assert_eq!(out, "2\n");
}
#[test]
fn test_parenthesis() {
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.args(&["(", "1", "+", "1", ")", "*", "2"]).run().stdout;
let out = new_ucmd()
.args(&["(", "1", "+", "1", ")", "*", "2"]).run().stdout;
assert_eq!(out, "4\n");
}
#[test]
fn test_or() {
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.args(&["0", "|", "foo"]).run().stdout;
let out = new_ucmd()
.args(&["0", "|", "foo"]).run().stdout;
assert_eq!(out, "foo\n");
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.args(&["foo", "|", "bar"]).run().stdout;
let out = new_ucmd()
.args(&["foo", "|", "bar"]).run().stdout;
assert_eq!(out, "foo\n");
}
#[test]
fn test_and() {
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.args(&["foo", "&", "1"]).run().stdout;
let out = new_ucmd()
.args(&["foo", "&", "1"]).run().stdout;
assert_eq!(out, "foo\n");
let (_, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.args(&["", "&", "1"]).run().stdout;
let out = new_ucmd()
.args(&["", "&", "1"]).run().stdout;
assert_eq!(out, "0\n");
}
+4 -2
View File
@@ -18,6 +18,9 @@ const LOG_PRIMES: f64 = 14.0; // ceil(log2(NUM_PRIMES))
const NUM_TESTS: usize = 100;
static UTIL_NAME: &'static str = "factor";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[test]
fn test_random() {
@@ -157,9 +160,8 @@ fn test_big_primes() {
}
fn run(instring: &[u8], outstring: &[u8]) {
let (_, mut ucmd) = testing(UTIL_NAME);
// now run factor
let out = ucmd.run_piped_stdin(instring).stdout;
let out = new_ucmd().run_piped_stdin(instring).stdout;
assert_eq!(out, String::from_utf8(outstring.to_owned()).unwrap());
}
+5 -2
View File
@@ -1,10 +1,13 @@
use common::util::*;
static UTIL_NAME: &'static str = "false";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[test]
fn test_exit_code() {
let (_, mut ucmd) = testing(UTIL_NAME);
let exit_status = ucmd.run().success;
let exit_status = new_ucmd()
.run().success;
assert_eq!(exit_status, false);
}
+20 -23
View File
@@ -1,38 +1,35 @@
use common::util::*;
static UTIL_NAME: &'static str = "fold";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
#[test]
fn test_default_80_column_wrap() {
let (at, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.arg("lorem_ipsum.txt")
.run()
.stdout;
assert_eq!(out, at.read("lorem_ipsum_80_column.expected"));
new_ucmd()
.arg("lorem_ipsum.txt")
.run()
.stdout_is_fixture("lorem_ipsum_80_column.expected");
}
#[test]
fn test_40_column_hard_cutoff() {
let (at, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.arg("-w")
.arg("40")
.arg("lorem_ipsum.txt")
.run()
.stdout;
assert_eq!(out, at.read("lorem_ipsum_40_column_hard.expected"));
new_ucmd()
.arg("-w")
.arg("40")
.arg("lorem_ipsum.txt")
.run()
.stdout_is_fixture("lorem_ipsum_40_column_hard.expected");
}
#[test]
fn test_40_column_word_boundary() {
let (at, mut ucmd) = testing(UTIL_NAME);
let out = ucmd.arg("-s")
.arg("-w")
.arg("40")
.arg("lorem_ipsum.txt")
.run()
.stdout;
assert_eq!(out, at.read("lorem_ipsum_40_column_word.expected"));
new_ucmd()
.arg("-s")
.arg("-w")
.arg("40")
.arg("lorem_ipsum.txt")
.run()
.stdout_is_fixture("lorem_ipsum_40_column_word.expected");
}
+8 -3
View File
@@ -8,14 +8,19 @@ macro_rules! test_digest {
($($t:ident)*) => ($(
mod $t {
use common::util::*;
use::common::util::*;
static UTIL_NAME: &'static str = "hashsum";
fn at_and_ucmd() -> (AtPath, UCommand) {
let ts = TestScenario::new(UTIL_NAME);
let ucmd = ts.ucmd();
(ts.fixtures, ucmd)
}
static DIGEST_ARG: &'static str = concat!("--", stringify!($t));
static EXPECTED_FILE: &'static str = concat!(stringify!($t), ".expected");
#[test]
fn test_single_file() {
let (at, mut ucmd) = testing(UTIL_NAME);
let (at, mut ucmd) = at_and_ucmd();
let result = ucmd.arg(DIGEST_ARG).arg("input.txt").run();
assert_empty_stderr!(result);
@@ -25,7 +30,7 @@ macro_rules! test_digest {
#[test]
fn test_stdin() {
let (at, mut ucmd) = testing(UTIL_NAME);
let (at, mut ucmd) = at_and_ucmd();
let input = at.read("input.txt");
let result = ucmd.arg(DIGEST_ARG).run_piped_stdin(input);
+33 -30
View File
@@ -1,71 +1,74 @@
use common::util::*;
static UTIL_NAME: &'static str = "head";
fn new_ucmd() -> UCommand {
TestScenario::new(UTIL_NAME).ucmd()
}
static INPUT: &'static str = "lorem_ipsum.txt";
#[test]
fn test_stdin_default() {
let (at, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.run_piped_stdin(at.read(INPUT));
assert_eq!(result.stdout, at.read("lorem_ipsum_default.expected"));
new_ucmd()
.pipe_in_fixture(INPUT)
.run().stdout_is_fixture("lorem_ipsum_default.expected");
}
#[test]
fn test_stdin_1_line_obsolete() {
let (at, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.args(&["-1"])
.run_piped_stdin(at.read(INPUT));
assert_eq!(result.stdout, at.read("lorem_ipsum_1_line.expected"));
new_ucmd()
.args(&["-1"])
.pipe_in_fixture(INPUT)
.run().stdout_is_fixture("lorem_ipsum_1_line.expected");
}
#[test]
fn test_stdin_1_line() {
let (at, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.args(&["-n", "1"])
.run_piped_stdin(at.read(INPUT));
assert_eq!(result.stdout, at.read("lorem_ipsum_1_line.expected"));
new_ucmd()
.args(&["-n", "1"])
.pipe_in_fixture(INPUT)
.run().stdout_is_fixture("lorem_ipsum_1_line.expected");
}
#[test]
fn test_stdin_5_chars() {
let (at, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.args(&["-c", "5"])
.run_piped_stdin(at.read(INPUT));
assert_eq!(result.stdout, at.read("lorem_ipsum_5_chars.expected"));
new_ucmd()
.args(&["-c", "5"])
.pipe_in_fixture(INPUT)
.run().stdout_is_fixture("lorem_ipsum_5_chars.expected");
}
#[test]
fn test_single_default() {
let (at, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.arg(INPUT).run();
assert_eq!(result.stdout, at.read("lorem_ipsum_default.expected"));
new_ucmd()
.arg(INPUT)
.run().stdout_is_fixture("lorem_ipsum_default.expected");
}
#[test]
fn test_single_1_line_obsolete() {
let (at, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.args(&["-1", INPUT]).run();
assert_eq!(result.stdout, at.read("lorem_ipsum_1_line.expected"));
new_ucmd()
.args(&["-1", INPUT])
.run().stdout_is_fixture("lorem_ipsum_1_line.expected");
}
#[test]
fn test_single_1_line() {
let (at, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.args(&["-n", "1", INPUT]).run();
assert_eq!(result.stdout, at.read("lorem_ipsum_1_line.expected"));
new_ucmd()
.args(&["-n", "1", INPUT])
.run().stdout_is_fixture("lorem_ipsum_1_line.expected");
}
#[test]
fn test_single_5_chars() {
let (at, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.args(&["-c", "5", INPUT]).run();
assert_eq!(result.stdout, at.read("lorem_ipsum_5_chars.expected"));
new_ucmd()
.args(&["-c", "5", INPUT])
.run().stdout_is_fixture("lorem_ipsum_5_chars.expected");
}
#[test]
fn test_verbose() {
let (at, mut ucmd) = testing(UTIL_NAME);
let result = ucmd.args(&["-v", INPUT]).run();
assert_eq!(result.stdout, at.read("lorem_ipsum_verbose.expected"));
new_ucmd()
.args(&["-v", INPUT])
.run().stdout_is_fixture("lorem_ipsum_verbose.expected");
}

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