#[cfg(test)]
mod test_hasher {
use crate::hasher::Hasher;
use anyhow::Result;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use std::sync::Arc;
use tempfile::TempDir;
// 2261 characters long
const LONG_STRING: &str = "a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long string";
const LONG_HASH: &str = "00019aad629dbdcab103d3dfa6c15797b1edc417e4a4b811ca386d9fc815b1b5";
// 3065 characters long
const LONG_WITH_NEWLINE: &str = "a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long string\n";
const LONG_WITH_NEWLINE_HASH: &str =
"0003ccdb94f7877c2b3143cfadfa72caaf70fcf96d41851a96402bd4671b07ab";
const SHORT_STRING: &str = "test338";
const SHORT_HASH: &str = "00099816175096d3c2e85e557843d8fdfdd996659df43d16c596a79bfbe82d17";
const SHORT_WITH_NEWLINE: &str = "test7248\n";
const SHORT_WITH_NEWLINE_HASH: &str =
"000ffee850a842b3d595a856231f8e679bfb34327a5333a6d04b6428f8113df7";
async fn create_temp_file(dir: &TempDir, content: &[u8]) -> Result<PathBuf> {
let file_path = dir.path().join("test_file.txt");
{
let mut file = File::create(&file_path)?;
file.write_all(content)?;
file.flush()?;
}
Ok(file_path)
}
#[tokio::test]
async fn test_stream_hasher_sha256_file() -> Result<()> {
let temp_dir = TempDir::new()?;
let hasher = Hasher::new().with_read_buffer_size(4096);
// Test with short string without newline
let file_path = create_temp_file(&temp_dir, SHORT_STRING.as_bytes()).await?;
let hash = hasher.sha256_file(&file_path).await?;
assert_eq!(hash, SHORT_HASH);
// Test with short string with newline
let file_path = create_temp_file(&temp_dir, SHORT_WITH_NEWLINE.as_bytes()).await?;
let hash = hasher.sha256_file(&file_path).await?;
assert_eq!(hash, SHORT_WITH_NEWLINE_HASH);
// Test with long string without newline
let file_path = create_temp_file(&temp_dir, LONG_STRING.as_bytes()).await?;
let hash = hasher.sha256_file(&file_path).await?;
assert_eq!(hash, LONG_HASH);
// Test with long string with newline
let file_path = create_temp_file(&temp_dir, LONG_WITH_NEWLINE.as_bytes()).await?;
let hash = hasher.sha256_file(&file_path).await?;
assert_eq!(hash, LONG_WITH_NEWLINE_HASH);
Ok(())
}
#[tokio::test]
async fn test_stream_hasher_with_different_buffer_sizes() -> Result<()> {
let temp_dir = TempDir::new()?;
// Test with buffer size smaller than the content
let small_buffer_hasher = Hasher::new().with_read_buffer_size(64);
// Test with buffer size exactly matching the short string
let exact_short_hasher = Hasher::new().with_read_buffer_size(SHORT_STRING.len());
// Test with buffer size between short and long string
let medium_buffer_hasher = Hasher::new().with_read_buffer_size(1024);
// Test with buffer size larger than the long string
let large_buffer_hasher = Hasher::new().with_read_buffer_size(LONG_WITH_NEWLINE.len() * 2);
// Test short string with different buffer sizes
let file_path = create_temp_file(&temp_dir, SHORT_STRING.as_bytes()).await?;
let hash = small_buffer_hasher.sha256_file(&file_path).await?;
assert_eq!(hash, SHORT_HASH, "Failed with small buffer on short string");
let hash = exact_short_hasher.sha256_file(&file_path).await?;
assert_eq!(hash, SHORT_HASH, "Failed with exact buffer on short string");
let hash = medium_buffer_hasher.sha256_file(&file_path).await?;
assert_eq!(
hash, SHORT_HASH,
"Failed with medium buffer on short string"
);
let hash = large_buffer_hasher.sha256_file(&file_path).await?;
assert_eq!(hash, SHORT_HASH, "Failed with large buffer on short string");
// Test long string with different buffer sizes
let file_path = create_temp_file(&temp_dir, LONG_STRING.as_bytes()).await?;
let hash = small_buffer_hasher.sha256_file(&file_path).await?;
assert_eq!(hash, LONG_HASH, "Failed with small buffer on long string");
let hash = medium_buffer_hasher.sha256_file(&file_path).await?;
assert_eq!(hash, LONG_HASH, "Failed with medium buffer on long string");
let hash = large_buffer_hasher.sha256_file(&file_path).await?;
assert_eq!(hash, LONG_HASH, "Failed with large buffer on long string");
Ok(())
}
#[test]
fn test_sync_sha256_bytes() -> Result<()> {
// Test with short strings
let hash = Hasher::sha256sum(SHORT_STRING);
assert_eq!(hash, SHORT_HASH);
let hash = Hasher::sha256sum(SHORT_WITH_NEWLINE);
assert_eq!(hash, SHORT_WITH_NEWLINE_HASH);
// Test with long strings
let hash = Hasher::sha256sum(LONG_STRING);
assert_eq!(hash, LONG_HASH);
let hash = Hasher::sha256sum(LONG_WITH_NEWLINE);
assert_eq!(hash, LONG_WITH_NEWLINE_HASH);
Ok(())
}
#[test]
fn test_sync_sha256_reader() -> Result<()> {
// Test with different buffer sizes
let tiny_buffer_hasher = Hasher::new().with_read_buffer_size(16);
let small_buffer_hasher = Hasher::new().with_read_buffer_size(128);
let medium_buffer_hasher = Hasher::new().with_read_buffer_size(1024);
let large_buffer_hasher = Hasher::new().with_read_buffer_size(4096);
// Test short string with different buffer sizes
let hash = tiny_buffer_hasher.sha256_reader(SHORT_STRING.as_bytes())?;
assert_eq!(hash, SHORT_HASH, "Failed with tiny buffer on short string");
let hash = small_buffer_hasher.sha256_reader(SHORT_STRING.as_bytes())?;
assert_eq!(hash, SHORT_HASH, "Failed with small buffer on short string");
let hash = medium_buffer_hasher.sha256_reader(SHORT_STRING.as_bytes())?;
assert_eq!(
hash, SHORT_HASH,
"Failed with medium buffer on short string"
);
let hash = large_buffer_hasher.sha256_reader(SHORT_STRING.as_bytes())?;
assert_eq!(hash, SHORT_HASH, "Failed with large buffer on short string");
// Test long string with different buffer sizes
let hash = tiny_buffer_hasher.sha256_reader(LONG_STRING.as_bytes())?;
assert_eq!(hash, LONG_HASH, "Failed with tiny buffer on long string");
let hash = small_buffer_hasher.sha256_reader(LONG_STRING.as_bytes())?;
assert_eq!(hash, LONG_HASH, "Failed with small buffer on long string");
let hash = medium_buffer_hasher.sha256_reader(LONG_STRING.as_bytes())?;
assert_eq!(hash, LONG_HASH, "Failed with medium buffer on long string");
let hash = large_buffer_hasher.sha256_reader(LONG_STRING.as_bytes())?;
assert_eq!(hash, LONG_HASH, "Failed with large buffer on long string");
Ok(())
}
#[tokio::test]
async fn test_stream_hasher_custom_stream() -> Result<()> {
use std::pin::Pin;
use std::task::{Context, Poll};
use tokio::io::{AsyncRead, ReadBuf};
struct TestStream {
data: Vec<u8>,
position: usize,
chunk_size: usize, // Added to test different read sizes
}
impl TestStream {
fn new(data: Vec<u8>, chunk_size: usize) -> Self {
Self {
data,
position: 0,
chunk_size,
}
}
}
impl AsyncRead for TestStream {
fn poll_read(
mut self: Pin<&mut Self>,
_cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<std::io::Result<()>> {
if self.position >= self.data.len() {
return Poll::Ready(Ok(()));
}
let remaining = self.data.len() - self.position;
let to_read =
std::cmp::min(std::cmp::min(remaining, buf.remaining()), self.chunk_size);
let chunk = &self.data[self.position..(self.position + to_read)];
buf.put_slice(chunk);
self.position += to_read;
Poll::Ready(Ok(()))
}
}
// Test with different buffer sizes and stream chunk sizes
let hasher_configs = [
("small hasher buffer, small chunks", 64, 32),
("small hasher buffer, large chunks", 64, 1024),
("large hasher buffer, small chunks", 4096, 32),
("large hasher buffer, large chunks", 4096, 1024),
];
for (config_name, buffer_size, chunk_size) in hasher_configs {
let hasher = Hasher::new().with_read_buffer_size(buffer_size);
// Test short string
let stream = TestStream::new(SHORT_STRING.as_bytes().to_vec(), chunk_size);
let hash = hasher.sha256_stream(stream).await?;
assert_eq!(
hash, SHORT_HASH,
"Failed with {config_name} on short string"
);
// Test short string with newline
let stream = TestStream::new(SHORT_WITH_NEWLINE.as_bytes().to_vec(), chunk_size);
let hash = hasher.sha256_stream(stream).await?;
assert_eq!(
hash, SHORT_WITH_NEWLINE_HASH,
"Failed with {config_name} on short string with newline"
);
// Test long string
let stream = TestStream::new(LONG_STRING.as_bytes().to_vec(), chunk_size);
let hash = hasher.sha256_stream(stream).await?;
assert_eq!(hash, LONG_HASH, "Failed with {config_name} on long string");
// Test long string with newline
let stream = TestStream::new(LONG_WITH_NEWLINE.as_bytes().to_vec(), chunk_size);
let hash = hasher.sha256_stream(stream).await?;
assert_eq!(
hash, LONG_WITH_NEWLINE_HASH,
"Failed with {config_name} on long string with newline"
);
}
Ok(())
}
#[tokio::test]
async fn test_non_existent_file() -> Result<()> {
let temp_dir = TempDir::new()?;
let non_existent_path = temp_dir.path().join("non_existent.txt");
let hasher = Hasher::new();
let result = hasher.sha256_file(&non_existent_path).await;
assert!(result.is_err());
Ok(())
}
#[tokio::test]
async fn test_stats_callback() -> Result<()> {
use std::sync::Mutex;
let temp_dir = TempDir::new()?;
let file_path = create_temp_file(&temp_dir, &vec![0; 10_000]).await?;
let stats_received = Arc::new(Mutex::new(false));
let stats_clone = Arc::clone(&stats_received);
let hasher = Hasher::new()
.with_read_buffer_size(100)
.with_throughput_update_interval(tokio::time::Duration::from_millis(1))
.with_stats_callback(move |_| {
*stats_clone.lock().unwrap() = true;
});
hasher.sha256_file(file_path).await?;
// Check if callback was called
assert!(*stats_received.lock().unwrap());
Ok(())
}
#[tokio::test]
async fn test_channel_buffer_size() -> Result<()> {
let temp_dir = TempDir::new()?;
let file_path = create_temp_file(&temp_dir, LONG_STRING.as_bytes()).await?;
// Test with different channel buffer sizes
let small_channel_hasher = Hasher::new()
.with_read_buffer_size(128)
.with_channel_buffer_size(1);
let large_channel_hasher = Hasher::new()
.with_read_buffer_size(128)
.with_channel_buffer_size(10);
let hash1 = small_channel_hasher.sha256_file(&file_path).await?;
assert_eq!(hash1, LONG_HASH);
let hash2 = large_channel_hasher.sha256_file(&file_path).await?;
assert_eq!(hash2, LONG_HASH);
Ok(())
}
#[tokio::test]
async fn test_edge_cases() -> Result<()> {
let temp_dir = TempDir::new()?;
// Test with empty file
let empty_file_path = create_temp_file(&temp_dir, b"").await?;
let hasher = Hasher::new();
let hash = hasher.sha256_file(&empty_file_path).await?;
assert_eq!(
hash,
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
);
// Test with buffer size larger than file
let tiny_file_path = create_temp_file(&temp_dir, b"a").await?;
let large_buffer_hasher = Hasher::new().with_read_buffer_size(4096);
let hash = large_buffer_hasher.sha256_file(&tiny_file_path).await?;
assert_eq!(
hash,
"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
);
// Test with buffer size equal to file size
let exact_buffer_hasher = Hasher::new().with_read_buffer_size(1);
let hash = exact_buffer_hasher.sha256_file(&tiny_file_path).await?;
assert_eq!(
hash,
"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
);
// Test with zero buffer size (should use default)
let zero_buffer_hasher = Hasher::new().with_read_buffer_size(0);
let hash = zero_buffer_hasher.sha256_file(&tiny_file_path).await?;
assert_eq!(
hash,
"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb"
);
Ok(())
}
}