[wip] unit tests for file module

- testing for `Checked`
This commit is contained in:
Jörn-Michael Miehe 2025-07-04 17:06:01 +00:00
parent a34aa968b4
commit 95dcc25e0d
3 changed files with 95 additions and 14 deletions

View file

@ -112,3 +112,83 @@ impl FileTrait for Checked {
super::check_hash(&self.path, self.size, self.hash.as_deref(), on_progress)
}
}
#[cfg(test)]
mod tests {
use tempfile::TempDir;
use crate::{
create_file,
file::tests::{CASES, HASHES},
};
use super::*;
#[test]
fn new_on_existing_file_works() {
for (content, size) in CASES {
let file = create_file(content);
let path = file
.path()
.canonicalize()
.expect("the file should have a canonical path");
let chk = Checked::new(file.path()).expect("creating `Checked` should succeed");
assert_eq!(chk.path, path);
assert_eq!(chk.size, size);
assert!(chk.hash.is_none());
}
}
#[test]
fn new_on_dir_errors() {
let tempdir = TempDir::new().expect("creating temp dir");
let fs_root = PathBuf::from("/");
let dirs = [tempdir.path(), fs_root.as_path()];
for p in dirs {
let err = Checked::new(p).expect_err("creating `Checked` should fail");
assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
#[cfg(target_os = "linux")]
assert_eq!(err.to_string(), "Not a regular file");
}
}
#[test]
fn new_on_nex_errors() {
let tempdir = TempDir::new().expect("creating temp dir");
let nex_paths = [0, 1, 2, 3, 4].map(|i| tempdir.path().join(format!("nex_{i}.ext")));
for p in nex_paths {
let err = Checked::new(p).expect_err("creating `Checked` should fail");
assert_eq!(err.kind(), io::ErrorKind::NotFound);
#[cfg(target_os = "linux")]
assert_eq!(err.to_string(), "No such file or directory (os error 2)");
}
}
#[test]
fn hashing_works() {
for (&(content, _), hash) in CASES.iter().zip(HASHES) {
let file = create_file(content);
let mut chk = Checked::new(file.path()).expect("creating `Checked` should succeed");
chk.hash(drop).expect("hashing should succeed");
assert_eq!(chk.hash, Some(hash.to_string()));
}
}
#[test]
fn hashing_again_errors() {
for (content, _) in CASES {
let file = create_file(content);
let mut chk = Checked::new(file.path()).expect("creating `Checked` should succeed");
chk.hash(drop).expect("hashing should succeed");
let err = chk.hash(drop).expect_err("hashing twice should fail");
assert!(err.is_mismatch("unhashed file", chk.path.display().to_string()));
}
}
}

View file

@ -124,20 +124,11 @@ pub trait FileTrait {
#[cfg(test)]
mod tests {
use std::io::Write;
use tempfile::NamedTempFile;
use crate::create_file;
use super::*;
/// Helper to create a temp file from `data`
fn create_file(data: &[u8]) -> NamedTempFile {
let mut tmp = NamedTempFile::new().expect("creating temp file");
tmp.write_all(data).expect("writing to tempfile");
tmp
}
static CASES: [(&[u8], u64); 8] = [
pub static CASES: [(&[u8], u64); 8] = [
(b"The quick brown fox jumps over the lazy dog", 43), // common pangram
(b"hello world", 11), // simple greeting
(b"", 0), // empty slice
@ -148,7 +139,7 @@ mod tests {
(b"foo\0bar\0baz", 11), // embedded nulls
];
static HASHES: [&str; 8] = [
pub static HASHES: [&str; 8] = [
"qK3Uvd39k+SHfSdG5igXsRY2Sh+nvBSNlQkLxzM7NnP4JAHPeqLkyx7NkCluPxTLVBP47Xe+cwRbE5FM3NapGA", // common pangram
"Ahzth5kpbOylV4MquUGlC0oR+DR4zxQfUfkz9lOrn7zAWgN83b7QbjCb8zSULE5YzfGkbiN5EczX/Pl4fLx/0A", // simple greeting
"eGoC90IBWQPGxv2FJVLScpEvR0DhWEdhiobiF/cfVBnSXhAxr+5YUxOJZESTTrBLkDpoWxRIt1XVb3Aa/pvizg", // empty slice
@ -162,8 +153,9 @@ mod tests {
#[test]
fn compute_hash_as_expected() {
for (&(content, size), expected_hash) in CASES.iter().zip(HASHES) {
// to capture progress updates from `compute_hash`
let file = create_file(content);
// to capture progress updates from `compute_hash`
let mut read_total = 0;
let callback = |n| read_total += n;

View file

@ -15,7 +15,6 @@ pub use cli::Cli;
pub use error::{Error, Parameter, Result};
#[cfg(test)]
#[inline]
pub fn check_trait<E, A>(expected: &E, actual: &A, tr: &'static str, ty: &'static str)
where
E: std::fmt::Debug + PartialEq<A>,
@ -26,3 +25,13 @@ where
"`impl {tr} for {ty}` expected: {expected:?}, actual: {actual:?}",
);
}
/// Helper to create a temp file from `data`
#[cfg(test)]
fn create_file(data: &[u8]) -> tempfile::NamedTempFile {
use std::io::Write;
let mut tmp = tempfile::NamedTempFile::new().expect("creating temp file");
tmp.write_all(data).expect("writing to tempfile");
tmp
}