Files
keep/src/tests/common/test_helpers.rs
Andrew Phillips 2f78e45444 feat: add helper functions for creating temporary files with random binary content and asserting file sizes
Co-authored-by: aider (openai/andrew/openrouter/qwen/qwen3-coder) <aider@aider.chat>
2025-08-15 11:26:25 -03:00

207 lines
7.6 KiB
Rust

//! Common test utilities and helper functions to reduce duplication in tests
use tempfile::{TempDir, TempPath};
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use rusqlite::Connection;
use crate::db;
/// Create a temporary directory for testing
pub fn create_temp_dir() -> TempDir {
TempDir::new().expect("Failed to create temporary directory")
}
/// Create a temporary file with the given content
pub fn create_temp_file_with_content(dir: &TempDir, filename: &str, content: &str) -> PathBuf {
let file_path = dir.path().join(filename);
let mut file = File::create(&file_path).expect("Failed to create test file");
write!(file, "{}", content).expect("Failed to write to test file");
file_path
}
/// Create an empty temporary file
pub fn create_empty_temp_file(dir: &TempDir, filename: &str) -> PathBuf {
let file_path = dir.path().join(filename);
File::create(&file_path).expect("Failed to create empty test file");
file_path
}
/// Helper to test basic temporary directory setup
pub fn test_temp_dir_setup() {
let temp_dir = create_temp_dir();
assert!(temp_dir.path().exists());
}
/// Helper to test file creation and verification
pub fn test_file_creation(dir: &TempDir, filename: &str, content: &str) -> PathBuf {
let file_path = create_temp_file_with_content(dir, filename, content);
assert!(file_path.exists());
let metadata = std::fs::metadata(&file_path).expect("Failed to get file metadata");
assert!(metadata.len() > 0);
file_path
}
/// Create a temporary database for testing
pub fn create_temp_db() -> (TempDir, Connection, PathBuf) {
let temp_dir = create_temp_dir();
let db_path = temp_dir.path().join("test.db");
let conn = db::open(db_path.clone()).expect("Failed to open database");
(temp_dir, conn, db_path)
}
/// Create a test item in the database
pub fn create_test_item(conn: &Connection) -> i64 {
let item = crate::db::Item {
id: None,
ts: chrono::Utc::now(),
size: Some(100),
compression: crate::compression_engine::CompressionType::None.to_string(),
};
db::insert_item(conn, item).expect("Failed to insert item")
}
/// Create a test file with compression engine testing data
pub fn create_test_file_with_data(dir: &TempDir, filename: &str, data: &[u8]) -> PathBuf {
let file_path = dir.path().join(filename);
let mut file = File::create(&file_path).expect("Failed to create test file");
file.write_all(data).expect("Failed to write to test file");
file_path
}
/// Test compression and decompression with an engine
pub fn test_compression_engine(engine: &dyn crate::compression_engine::CompressionEngine, test_data: &[u8]) {
let dir = create_temp_dir();
let file_path = dir.path().join("test_compression.dat");
// Test compression
{
let mut writer = engine.create(file_path.clone()).expect("Failed to create writer");
writer.write_all(test_data).expect("Failed to write data");
}
// Test decompression
let mut reader = engine.open(file_path).expect("Failed to open reader");
let mut decompressed = Vec::new();
std::io::copy(&mut reader, &mut decompressed).expect("Failed to read data");
assert_eq!(test_data, decompressed.as_slice());
}
/// Create a test database with some initial data
pub fn create_test_db_with_data() -> (TempDir, Connection, PathBuf) {
let (temp_dir, conn, db_path) = create_temp_db();
// Add some test items
let item1 = crate::db::Item {
id: None,
ts: chrono::Utc::now(),
size: Some(100),
compression: crate::compression_engine::CompressionType::None.to_string(),
};
db::insert_item(&conn, item1).expect("Failed to insert item1");
let item2 = crate::db::Item {
id: None,
ts: chrono::Utc::now(),
size: Some(200),
compression: crate::compression_engine::CompressionType::LZ4.to_string(),
};
db::insert_item(&conn, item2).expect("Failed to insert item2");
(temp_dir, conn, db_path)
}
/// Assert that two paths point to files with identical content
pub fn assert_files_equal(path1: &PathBuf, path2: &PathBuf) {
let content1 = std::fs::read(path1).expect("Failed to read first file");
let content2 = std::fs::read(path2).expect("Failed to read second file");
assert_eq!(content1, content2, "Files {:?} and {:?} have different content", path1, path2);
}
/// Create a temporary file with binary content
pub fn create_temp_file_with_binary_content(dir: &TempDir, filename: &str, content: &[u8]) -> PathBuf {
let file_path = dir.path().join(filename);
let mut file = File::create(&file_path).expect("Failed to create test file");
file.write_all(content).expect("Failed to write binary content to test file");
file_path
}
/// Get the size of a file
pub fn get_file_size(file_path: &PathBuf) -> u64 {
let metadata = std::fs::metadata(file_path).expect("Failed to get file metadata");
metadata.len()
}
/// Assert that a file exists
pub fn assert_file_exists(file_path: &PathBuf) {
assert!(file_path.exists(), "File {:?} does not exist", file_path);
}
/// Assert that a file does not exist
pub fn assert_file_not_exists(file_path: &PathBuf) {
assert!(!file_path.exists(), "File {:?} should not exist but it does", file_path);
}
/// Create a temporary database and populate it with sample data for testing
pub fn create_populated_test_db() -> (TempDir, Connection, PathBuf) {
let (temp_dir, conn, db_path) = create_temp_db();
// Insert some sample items
for i in 1..=5 {
let item = crate::db::Item {
id: None,
ts: chrono::Utc::now(),
size: Some(i * 100),
compression: if i % 2 == 0 {
crate::compression_engine::CompressionType::LZ4.to_string()
} else {
crate::compression_engine::CompressionType::GZip.to_string()
},
};
db::insert_item(&conn, item).expect("Failed to insert item");
}
(temp_dir, conn, db_path)
}
/// Assert that a directory exists and is actually a directory
pub fn assert_directory_exists(dir_path: &PathBuf) {
assert!(dir_path.exists(), "Directory {:?} does not exist", dir_path);
assert!(dir_path.is_dir(), "Path {:?} exists but is not a directory", dir_path);
}
/// Create a nested directory structure for testing
pub fn create_nested_temp_dir_structure(dir: &TempDir) -> (PathBuf, PathBuf, PathBuf) {
let level1 = dir.path().join("level1");
let level2 = level1.join("level2");
let level3 = level2.join("level3");
std::fs::create_dir_all(&level3).expect("Failed to create nested directory structure");
(level1, level2, level3)
}
/// Create a temporary file with random binary content of specified size
pub fn create_temp_file_with_random_binary_content(dir: &TempDir, filename: &str, size: usize) -> PathBuf {
use rand::Rng;
let mut rng = rand::thread_rng();
let random_data: Vec<u8> = (0..size).map(|_| rng.gen()).collect();
create_temp_file_with_binary_content(dir, filename, &random_data)
}
/// Assert that a file has the expected size
pub fn assert_file_size(file_path: &PathBuf, expected_size: u64) {
let actual_size = get_file_size(file_path);
assert_eq!(actual_size, expected_size, "File {:?} has size {} but expected {}", file_path, actual_size, expected_size);
}
/// Create multiple temporary files with content in a directory
pub fn create_multiple_temp_files_with_content(dir: &TempDir, files: &[(&str, &str)]) -> Vec<PathBuf> {
files.iter().map(|(filename, content)| {
create_temp_file_with_content(dir, filename, content)
}).collect()
}