extern crate csv;
extern crate proptest;
use metadata_backup::metadata::Metadata;
use std::path::PathBuf;
fn get_base_path() -> PathBuf {
let mut out = PathBuf::from(env!["CARGO_MANIFEST_DIR"]);
out.push("tests");
out.push("tree");
out
}
fn get_resource(path_components: &Vec<&str>) -> PathBuf {
let mut out = get_base_path();
for component in path_components.iter() {
out.push(component);
}
out
}
fn get_metadata(path_components: &Vec<&str>) -> Result<Metadata, std::io::Error> {
let pathbuf = get_resource(path_components);
let path = pathbuf.as_path();
Metadata::new(&path)
}
#[test]
fn test_size() {
let test_cases = [
(vec!["f1.txt"], 0),
(vec!["f2.txt"], 256),
(vec!["a", "a1.txt"], 117),
];
for (path_components, expected_size) in test_cases.iter() {
let meta = get_metadata(path_components).unwrap();
assert_eq!(meta.size, *expected_size);
}
}
#[test]
fn test_name() {
let test_cases = [
(vec!["f1.txt"], "f1.txt"),
(vec!["f2.txt"], "f2.txt"),
(vec!["a1.txt"], "a1.txt"),
(vec!["a", "a1.txt"], "a1.txt"),
(vec!["b", "b1.txt"], "b1.txt"),
];
for (path_components, expected_name) in test_cases.iter() {
let meta = get_metadata(path_components).unwrap();
assert_eq!(meta.name, expected_name.to_string());
}
}
#[test]
fn test_is_dir() {
let test_cases = [
(vec!["a"], true),
(vec!["b"], true),
(vec!["f1.txt"], false),
(vec!["f2.txt"], false),
(vec!["a1.txt"], false),
(vec!["a", "a1.txt"], false),
(vec!["b", "b1.txt"], false),
];
for (path_components, expected) in test_cases.iter() {
let meta = get_metadata(path_components).unwrap();
assert_eq!(meta.is_dir, *expected);
}
}
mod prop_tests {
extern crate strmode;
use metadata_backup::metadata::Metadata;
use proptest::prelude::*;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
prop_compose! {
fn system_time_truncated()
(seconds in 0..(2u64^64 - 1)) ->
SystemTime {
UNIX_EPOCH + Duration::from_secs(seconds)
}
}
prop_compose! {
fn arb_metadata()
(name in ".*",
size in any::<u64>(),
is_dir in any::<bool>(),
atime in prop::option::of(system_time_truncated()),
mtime in prop::option::of(system_time_truncated()),
ctime in prop::option::of(system_time_truncated()),
st_mode in prop::option::of(any::<u32>()),
uid in prop::option::of(any::<u32>()),
gid in prop::option::of(any::<u32>()),
link in prop::option::of("[^\0]+"),
) ->
Metadata {
Metadata {
name: name,
size: size,
is_dir: is_dir,
atime: atime,
mtime: mtime,
ctime: ctime,
st_mode: st_mode,
st_mode_string: st_mode.map(strmode::strmode),
uid: uid,
gid: gid,
link: link,
}
}
}
proptest! {
#[test]
fn serialize_deserialize_records(metadata_records in
prop::collection::vec(arb_metadata(), 1..100)) {
let mut wtr = csv::Writer::from_writer(vec![]);
for record in &metadata_records {
wtr.serialize(record).unwrap();
};
let data = String::from_utf8(wtr.into_inner().unwrap()).unwrap();
let mut reader = csv::Reader::from_reader(data.as_bytes());
let mut deserialized_vec : Vec<Metadata> =
Vec::with_capacity(metadata_records.len());
for result in reader.deserialize::<Metadata>() {
let record = result.unwrap();
deserialized_vec.push(record);
}
let deserialized_vec = deserialized_vec;
assert_eq!(metadata_records.len(), deserialized_vec.len());
for (record_in, record_out) in metadata_records.iter().zip(deserialized_vec) {
assert_eq!(*record_in, record_out);
}
}
}
}