forked from ouch-org/ouch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.rs
101 lines (87 loc) · 3.15 KB
/
utils.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use std::{env, io::Write, path::PathBuf};
use assert_cmd::Command;
use fs_err as fs;
use rand::{Rng, RngCore};
#[macro_export]
macro_rules! ouch {
($($e:expr),*) => {
$crate::utils::cargo_bin()
$(.arg($e))*
.arg("--yes")
.unwrap();
}
}
pub fn cargo_bin() -> Command {
env::vars()
.find_map(|(k, v)| {
(k.starts_with("CARGO_TARGET_") && k.ends_with("_RUNNER")).then(|| {
let mut runner = v.split_whitespace();
let mut cmd = Command::new(runner.next().unwrap());
cmd.args(runner).arg(assert_cmd::cargo::cargo_bin("ouch"));
cmd
})
})
.unwrap_or_else(|| Command::cargo_bin("ouch").expect("Failed to find ouch executable"))
}
// write random content to a file
pub fn write_random_content(file: &mut impl Write, rng: &mut impl RngCore) {
let mut data = Vec::new();
data.resize(rng.gen_range(0..8192), 0);
rng.fill_bytes(&mut data);
file.write_all(&data).unwrap();
}
// check that two directories have the exact same content recursively
// checks equility of file types if preserve_permissions is true, ignored on non-unix
pub fn assert_same_directory(x: impl Into<PathBuf>, y: impl Into<PathBuf>, preserve_permissions: bool) {
fn read_dir(dir: impl Into<PathBuf>) -> impl Iterator<Item = fs::DirEntry> {
let mut dir: Vec<_> = fs::read_dir(dir).unwrap().map(|entry| entry.unwrap()).collect();
dir.sort_by_key(|x| x.file_name());
dir.into_iter()
}
let mut x = read_dir(x);
let mut y = read_dir(y);
loop {
match (x.next(), y.next()) {
(Some(x), Some(y)) => {
assert_eq!(x.file_name(), y.file_name());
let meta_x = x.metadata().unwrap();
let meta_y = y.metadata().unwrap();
let ft_x = meta_x.file_type();
let ft_y = meta_y.file_type();
#[cfg(unix)]
if preserve_permissions {
assert_eq!(ft_x, ft_y);
}
if ft_x.is_dir() && ft_y.is_dir() {
assert_same_directory(x.path(), y.path(), preserve_permissions);
} else if ft_x.is_file() && ft_y.is_file() {
assert_eq!(meta_x.len(), meta_y.len());
assert_eq!(fs::read(x.path()).unwrap(), fs::read(y.path()).unwrap());
} else {
panic!(
"entries should be both directories or both files\n left: `{:?}`,\n right: `{:?}`",
x.path(),
y.path()
);
}
}
(None, None) => break,
(x, y) => {
panic!(
"directories don't have the same number of entries\n left: `{:?}`,\n right: `{:?}`",
x.map(|x| x.path()),
y.map(|y| y.path()),
)
}
}
}
}
#[test]
fn src_is_src() {
assert_same_directory("src", "src", true);
}
#[test]
#[should_panic]
fn src_is_not_tests() {
assert_same_directory("src", "tests", false);
}