Re-write integration tests in Rust (#67)

* Rewrite integration tests in Rust.
* Improve failure output for integration tests.
* Move TestEnv to separate module.
* Remove old integration tests script.
* Re-add integration test for subdirectory.
This commit is contained in:
Matthias Reitinger 2017-10-04 23:19:30 +02:00 committed by David Peter
parent 00b57b50ae
commit 6f22957cdc
6 changed files with 568 additions and 258 deletions

View File

@ -33,9 +33,6 @@ matrix:
rust: 1.16.0
env: TARGET=x86_64-unknown-linux-musl
after_success:
- bash tests/test.sh
notifications:
email:
on_success: never

67
Cargo.lock generated
View File

@ -5,9 +5,11 @@ dependencies = [
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
"diff 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -33,6 +35,11 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "0.9.1"
@ -54,11 +61,29 @@ dependencies = [
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "conv"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "custom_derive"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "diff"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fnv"
version = "1.0.5"
@ -115,6 +140,23 @@ name = "log"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "magenta"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "magenta-sys"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "1.0.1"
@ -131,6 +173,15 @@ dependencies = [
"libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)",
"magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex"
version = "0.2.2"
@ -162,6 +213,14 @@ name = "strsim"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "tempdir"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "term_size"
version = "0.3.0"
@ -247,9 +306,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5"
"checksum clap 2.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2267a8fdd4dce6956ba6649e130f62fb279026e5e84b92aa939ac8f85ce3f9f0"
"checksum conv 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "78ff10625fd0ac447827aa30ea8b861fead473bb60aeb73af6c1c58caf0d1299"
"checksum crossbeam 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0c5ea215664ca264da8a9d9c3be80d2eaf30923c259d03e870388eb927508f97"
"checksum custom_derive 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
"checksum diff 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0a515461b6c8c08419850ced27bc29e86166dcdcde8fbe76f8b1f0589bb49472"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum globset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "feeb1b6840809ef5efcf7a4a990bc4e1b7ee3df8cf9e2379a75aeb2ba42ac9c3"
"checksum ignore 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fcaf2365eb14b28ec7603c98c06cc531f19de9eb283d89a3dff8417c8c99f5"
@ -257,12 +320,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
"checksum libc 0.2.30 (registry+https://github.com/rust-lang/crates.io-index)" = "2370ca07ec338939e356443dac2296f581453c35fe1e3a3ed06023c49435f915"
"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
"checksum magenta 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf0336886480e671965f794bc9b6fce88503563013d1bfb7a502c81fe3ac527"
"checksum magenta-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40d014c7011ac470ae28e2f76a02bfea4a8480f73e701353b49ad7a8d75f4699"
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
"checksum num_cpus 1.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aec53c34f2d0247c5ca5d32cca1478762f301740468ee9ee6dcb7a0dd7a0c584"
"checksum rand 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "eb250fd207a4729c976794d03db689c9be1d634ab5a1c9da9492a13d8fecbcdf"
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6"
"checksum term_size 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2b6b55df3198cc93372e85dd2ed817f0e38ce8cc0f22eb32391bfad9c4bf209"
"checksum textwrap 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f728584ea33b0ad19318e20557cb0a39097751dbb07171419673502f848c7af6"
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"

View File

@ -29,4 +29,8 @@ ignore = "0.2"
num_cpus = "1.6.2"
[build-dependencies]
clap = "2.26.0"
clap = "2.26.0"
[dev-dependencies]
diff = "0.1"
tempdir = "0.3"

View File

@ -1,254 +0,0 @@
#!/bin/bash
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
fd="${SCRIPT_DIR}/../target/debug/fd"
MKTEMP_TEMPLATE="fd-tests.XXXXXXXXXX"
# Stabilize sort
export LC_ALL="C"
export LC_CTYPE="UTF-8"
export reset='\x1b[0m'
export bold='\x1b[01m'
export green='\x1b[32;01m'
export red='\x1b[31;01m'
set -eou pipefail
suite() {
echo
echo -e "${bold}$1${reset}"
echo
}
expect() {
expected_output="$1"
shift
tmp_expected="$(mktemp -t "$MKTEMP_TEMPLATE")"
tmp_output="$(mktemp -t "$MKTEMP_TEMPLATE")"
echo "$expected_output" > "$tmp_expected"
# Use python instead of sed here (for this to work on macOS)
"$fd" "$@" | python -c 'import sys; sys.stdout.write(sys.stdin.read().replace("\0", "NULL\n"))' | sort -f > "$tmp_output"
echo -ne " ${bold}${reset} Testing 'fd $*' ... "
if diff -q "$tmp_expected" "$tmp_output" > /dev/null; then
echo -e "${green}✓ okay${reset}"
rm -f "$tmp_expected" "$tmp_output"
else
echo -e "${red}❌FAILED${reset}"
echo -ne "\nShowing diff between ${red}expected${reset} and "
echo -e "${green}actual${reset} output:\n"
diff -C3 --label expected --label actual \
"$tmp_expected" "$tmp_output" || true
rm -f "$tmp_expected" "$tmp_output"
exit 1
fi
}
root=$(mktemp -d -t "$MKTEMP_TEMPLATE")
cd "$root"
# Setup test environment
mkdir -p one/two/three
touch a.foo
touch one/b.foo
touch one/two/c.foo
touch one/two/C.Foo2
touch one/two/three/d.foo
mkdir one/two/three/directory_foo
touch ignored.foo
touch .hidden.foo
ln -s one/two symlink
echo "ignored.foo" > .ignore
# Run the tests
suite "Simple tests"
expect "a.foo" a.foo
expect "one/b.foo" b.foo
expect "one/two/three/d.foo" d.foo
expect "a.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo" foo
expect "a.foo
one
one/b.foo
one/two
one/two/c.foo
one/two/C.Foo2
one/two/three
one/two/three/d.foo
one/two/three/directory_foo
symlink" # run 'fd' without arguments
suite "Explicit root path"
expect "one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo" foo one
expect "one/two/three/d.foo
one/two/three/directory_foo" foo one/two/three
(
cd one/two
expect "../../a.foo
../b.foo
c.foo
C.Foo2
three/d.foo
three/directory_foo" foo ../../
)
suite "Regex searches"
expect "a.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2" '[a-c].foo'
expect "a.foo
one/b.foo
one/two/c.foo" --case-sensitive '[a-c].foo'
suite "Smart case"
expect "one/two/c.foo
one/two/C.Foo2" c.foo
expect "one/two/C.Foo2" C.Foo
expect "one/two/C.Foo2" Foo
suite "Case-sensitivity (--case-sensitive)"
expect "one/two/c.foo" --case-sensitive c.foo
expect "one/two/C.Foo2" --case-sensitive C.Foo
suite "Full path search (--full-path)"
expect "one/two/three/d.foo
one/two/three/directory_foo" --full-path 'three.*foo'
expect "a.foo" --full-path '^a\.foo$'
suite "Hidden files (--hidden)"
expect ".hidden.foo
a.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo" --hidden foo
suite "Ignored files (--no-ignore)"
expect "a.foo
ignored.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo" --no-ignore foo
expect ".hidden.foo
a.foo
ignored.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo" --hidden --no-ignore foo
suite "Symlinks (--follow)"
expect "one/two/c.foo
one/two/C.Foo2
symlink/c.foo
symlink/C.Foo2" --follow c.foo
suite "Null separator (--print0)"
expect "a.fooNULL
one/b.fooNULL
one/two/C.Foo2NULL
one/two/c.fooNULL
one/two/three/d.fooNULL
one/two/three/directory_fooNULL" --print0 foo
suite "Maximum depth (--max-depth)"
expect "a.foo
one
one/b.foo
one/two
one/two/c.foo
one/two/C.Foo2
one/two/three
symlink" --max-depth 3
expect "a.foo
one
one/b.foo
one/two
symlink" --max-depth 2
expect "a.foo
one
symlink" --max-depth 1
abs_path=$(python -c "import os; print(os.path.realpath('$root'))")
suite "Absolute paths (--absolute-path)"
expect "$abs_path/a.foo
$abs_path/one/b.foo
$abs_path/one/two/c.foo
$abs_path/one/two/C.Foo2
$abs_path/one/two/three/d.foo
$abs_path/one/two/three/directory_foo" --absolute-path foo
expect "$abs_path/a.foo
$abs_path/one/b.foo
$abs_path/one/two/c.foo
$abs_path/one/two/C.Foo2
$abs_path/one/two/three/d.foo
$abs_path/one/two/three/directory_foo" foo "$abs_path"
suite "File type filter (--type)"
expect "a.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo" --type f
expect "one
one/two
one/two/three
one/two/three/directory_foo" --type d
expect "symlink" --type s
suite "File extension (--extension)"
expect "a.foo
one/b.foo
one/two/c.foo
one/two/three/d.foo" --extension foo
expect "a.foo
one/b.foo
one/two/c.foo
one/two/three/d.foo" --extension .foo
expect "one/two/C.Foo2" --extension foo2
# All done
echo

169
tests/testenv/mod.rs Normal file
View File

@ -0,0 +1,169 @@
use std;
use std::env;
use std::fs;
use std::io;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process;
#[cfg(unix)]
use std::os::unix;
#[cfg(windows)]
use std::os::windows;
extern crate diff;
extern crate tempdir;
use self::tempdir::TempDir;
/// Environment for the integration tests.
pub struct TestEnv {
/// Temporary working directory.
temp_dir: TempDir,
/// Path to the *fd* executable.
fd_exe: PathBuf,
}
/// Create the working directory and the test files.
fn create_working_directory() -> Result<TempDir, io::Error> {
let temp_dir = TempDir::new("fd-tests")?;
{
let root = temp_dir.path();
fs::create_dir_all(root.join("one/two/three"))?;
fs::File::create(root.join("a.foo"))?;
fs::File::create(root.join("one/b.foo"))?;
fs::File::create(root.join("one/two/c.foo"))?;
fs::File::create(root.join("one/two/C.Foo2"))?;
fs::File::create(root.join("one/two/three/d.foo"))?;
fs::create_dir(root.join("one/two/three/directory_foo"))?;
fs::File::create(root.join("ignored.foo"))?;
fs::File::create(root.join(".hidden.foo"))?;
#[cfg(unix)]
unix::fs::symlink(root.join("one/two"), root.join("symlink"))?;
#[cfg(windows)]
windows::fs::symlink_dir(root.join("one/two"), root.join("symlink"))?;
fs::File::create(root.join(".ignore"))?.write_all(b"ignored.foo")?;
}
Ok(temp_dir)
}
/// Find the *fd* executable.
fn find_fd_exe() -> PathBuf {
// Tests exe is in target/debug/deps, the *fd* exe is in target/debug
let root = env::current_exe().expect("tests executable")
.parent().expect("tests executable directory")
.parent().expect("fd executable directory")
.to_path_buf();
let exe_name = if cfg!(windows) { "fd.exe" } else { "fd" };
root.join(exe_name)
}
/// Format an error message for when *fd* did not exit successfully.
fn format_exit_error(args: &[&str], output: &process::Output) -> String {
format!(
"`fd {}` did not exit successfully.\nstdout:\n---\n{}---\nstderr:\n---\n{}---",
args.join(" "),
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr))
}
/// Format an error message for when the output of *fd* did not match the expected output.
fn format_output_error(args: &[&str], expected: &str, actual: &str) -> String {
// Generate diff text.
let diff_text =
diff::lines(expected, actual)
.into_iter()
.map(|diff| {
match diff {
diff::Result::Left(l) => format!("-{}", l),
diff::Result::Both(l, _) => format!(" {}", l),
diff::Result::Right(r) => format!("+{}", r),
}
})
.collect::<Vec<_>>()
.join("\n");
format!(
concat!(
"`fd {}` did not produce the expected output.\n",
"Showing diff between expected and actual:\n{}\n"),
args.join(" "),
diff_text)
}
/// Normalize the output for comparison.
fn normalize_output(s: &str, trim_left: bool) -> String {
// Split into lines and normalize separators.
let mut lines = s
.replace('\0', "NULL\n")
.lines()
.map(|line| {
let line = if trim_left { line.trim_left() } else { line };
line.replace('/', &std::path::MAIN_SEPARATOR.to_string())
})
.collect::<Vec<_>>();
// Sort ignoring case.
lines.sort_by_key(|s| s.to_lowercase());
lines.join("\n")
}
impl TestEnv {
pub fn new() -> TestEnv {
let temp_dir = create_working_directory().expect("working directory");
let fd_exe = find_fd_exe();
TestEnv {
temp_dir: temp_dir,
fd_exe: fd_exe,
}
}
/// Get the root directory for the tests.
pub fn root(&self) -> PathBuf {
self.temp_dir.path().to_path_buf()
}
/// Assert that calling *fd* with the specified arguments produces the expected output.
pub fn assert_output(&self, args: &[&str], expected: &str) {
self.assert_output_subdirectory(".", args, expected)
}
/// Assert that calling *fd* in the specified path under the root working directory,
/// and with the specified arguments produces the expected output.
pub fn assert_output_subdirectory<P: AsRef<Path>>(&self, path: P, args: &[&str], expected: &str) {
// Setup *fd* command.
let mut cmd = process::Command::new(&self.fd_exe);
cmd.current_dir(self.temp_dir.path().join(path));
cmd.args(args);
// Run *fd*.
let output = cmd.output().expect("fd output");
// Check for exit status.
if !output.status.success() {
panic!(format_exit_error(args, &output));
}
// Normalize both expected and actual output.
let expected = normalize_output(expected, true);
let actual = normalize_output(&String::from_utf8_lossy(&output.stdout), false);
// Compare actual output to expected output.
if expected != actual {
panic!(format_output_error(args, &expected, &actual));
}
}
}

327
tests/tests.rs Normal file
View File

@ -0,0 +1,327 @@
//! Integration tests for the CLI interface of fd.
#![allow(dead_code, unused_imports)]
mod testenv;
use testenv::TestEnv;
/// Simple tests
#[test]
fn test_simple() {
let te = TestEnv::new();
te.assert_output(&["a.foo"], "a.foo");
te.assert_output(&["b.foo"], "one/b.foo");
te.assert_output(&["d.foo"], "one/two/three/d.foo");
te.assert_output(
&["foo"],
"a.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo");
te.assert_output(
&[],
"a.foo
one
one/b.foo
one/two
one/two/c.foo
one/two/C.Foo2
one/two/three
one/two/three/d.foo
one/two/three/directory_foo
symlink");
}
/// Explicit root path
// TODO: Fails on windows
#[cfg_attr(windows, ignore)]
#[test]
fn test_explicit_root_path() {
let te = TestEnv::new();
te.assert_output(
&["foo", "one"],
"one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo");
te.assert_output(
&["foo", "one/two/three"],
"one/two/three/d.foo
one/two/three/directory_foo");
te.assert_output_subdirectory(
"one/two",
&["foo", "../../"],
"../../a.foo
../b.foo
c.foo
C.Foo2
three/d.foo
three/directory_foo");
}
/// Regex searches
#[test]
fn test_regex_searches() {
let te = TestEnv::new();
te.assert_output(
&["[a-c].foo"],
"a.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2");
te.assert_output(
&["--case-sensitive", "[a-c].foo"],
"a.foo
one/b.foo
one/two/c.foo");
}
/// Smart case
#[test]
fn test_smart_case() {
let te = TestEnv::new();
te.assert_output(
&["c.foo"],
"one/two/c.foo
one/two/C.Foo2");
te.assert_output(
&["C.Foo"],
"one/two/C.Foo2");
te.assert_output(
&["Foo"],
"one/two/C.Foo2");
}
/// Case sensitivity (--case-sensitive)
#[test]
fn test_case_sensitive() {
let te = TestEnv::new();
te.assert_output(
&["--case-sensitive", "c.foo"],
"one/two/c.foo");
te.assert_output(
&["--case-sensitive", "C.Foo"],
"one/two/C.Foo2");
}
/// Full path search (--full-path)
#[test]
fn test_full_path() {
let te = TestEnv::new();
te.assert_output(
&["--full-path", "three.*foo"],
"one/two/three/d.foo
one/two/three/directory_foo");
te.assert_output(
&["--full-path", "^a\\.foo"],
"a.foo");
}
/// Hidden files (--hidden)
#[test]
fn test_hidden() {
let te = TestEnv::new();
te.assert_output(
&["--hidden", "foo"],
".hidden.foo
a.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo");
}
/// Ignored files (--no-ignore)
#[test]
fn test_no_ignore() {
let te = TestEnv::new();
te.assert_output(
&["--no-ignore", "foo"],
"a.foo
ignored.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo");
te.assert_output(
&["--hidden", "--no-ignore", "foo"],
".hidden.foo
a.foo
ignored.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo
one/two/three/directory_foo");
}
/// Symlinks (--follow)
#[test]
fn test_follow() {
let te = TestEnv::new();
te.assert_output(
&["--follow", "c.foo"],
"one/two/c.foo
one/two/C.Foo2
symlink/c.foo
symlink/C.Foo2");
}
/// Null separator (--print0)
#[test]
fn test_print0() {
let te = TestEnv::new();
te.assert_output(
&["--print0", "foo"],
"a.fooNULL
one/b.fooNULL
one/two/C.Foo2NULL
one/two/c.fooNULL
one/two/three/d.fooNULL
one/two/three/directory_fooNULL");
}
/// Maximum depth (--max-depth)
#[test]
fn test_max_depth() {
let te = TestEnv::new();
te.assert_output(
&["--max-depth", "3"],
"a.foo
one
one/b.foo
one/two
one/two/c.foo
one/two/C.Foo2
one/two/three
symlink");
te.assert_output(
&["--max-depth", "2"],
"a.foo
one
one/b.foo
one/two
symlink");
te.assert_output(
&["--max-depth", "1"],
"a.foo
one
symlink");
}
/// Absolute paths (--absolute-path)
// TODO: fails on windows
#[cfg_attr(windows, ignore)]
#[test]
fn test_absolute_path() {
let te = TestEnv::new();
let abs_path = te.root()
.canonicalize().expect("absolute path")
.to_str().expect("string")
.to_string();
te.assert_output(
&["--absolute-path", "foo"],
&format!(
"{abs_path}/a.foo
{abs_path}/one/b.foo
{abs_path}/one/two/c.foo
{abs_path}/one/two/C.Foo2
{abs_path}/one/two/three/d.foo
{abs_path}/one/two/three/directory_foo",
abs_path=abs_path
)
);
te.assert_output(
&["foo", &abs_path],
&format!(
"{abs_path}/a.foo
{abs_path}/one/b.foo
{abs_path}/one/two/c.foo
{abs_path}/one/two/C.Foo2
{abs_path}/one/two/three/d.foo
{abs_path}/one/two/three/directory_foo",
abs_path=abs_path
)
);
}
/// File type filter (--type)
#[test]
fn test_type() {
let te = TestEnv::new();
te.assert_output(
&["--type", "f"],
"a.foo
one/b.foo
one/two/c.foo
one/two/C.Foo2
one/two/three/d.foo");
te.assert_output(
&["--type", "d"],
"one
one/two
one/two/three
one/two/three/directory_foo");
te.assert_output(
&["--type", "s"],
"symlink");
}
/// File extension (--extension)
#[test]
fn test_extension() {
let te = TestEnv::new();
te.assert_output(
&["--extension", "foo"],
"a.foo
one/b.foo
one/two/c.foo
one/two/three/d.foo");
te.assert_output(
&["--extension", ".foo"],
"a.foo
one/b.foo
one/two/c.foo
one/two/three/d.foo");
te.assert_output(
&["--extension", "foo2"],
"one/two/C.Foo2");
}