use engram_rs::{ArchiveReader, ArchiveWriter, CompressionMethod};
use tempfile::NamedTempFile;
fn get_compression_ratio(original_size: usize, compressed_archive_size: u64) -> f64 {
compressed_archive_size as f64 / original_size as f64
}
#[test]
fn test_compression_choice_small_files() {
println!("\n🔍 Testing compression for small files (<4KB)...");
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
let mut writer = ArchiveWriter::create(path).unwrap();
let small_data = vec![0xAB; 2048]; writer.add_file("small.bin", &small_data).unwrap();
writer.finalize().unwrap();
let mut reader = ArchiveReader::open_and_init(path).unwrap();
let data = reader.read_file("small.bin").unwrap();
assert_eq!(data, small_data);
println!(" ✓ Small files compress and decompress correctly");
}
#[test]
fn test_compression_choice_text_files() {
println!("\n🔍 Testing compression for text files (.txt, .json, .md)...");
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
let mut writer = ArchiveWriter::create(path).unwrap();
let text_data = "Lorem ipsum dolor sit amet ".repeat(1000);
writer.add_file("file.txt", text_data.as_bytes()).unwrap();
writer.add_file("data.json", text_data.as_bytes()).unwrap();
writer.add_file("readme.md", text_data.as_bytes()).unwrap();
writer.finalize().unwrap();
let original_size = text_data.len() * 3; let archive_size = std::fs::metadata(path).unwrap().len();
let ratio = get_compression_ratio(original_size, archive_size);
println!(" Original: {} bytes", original_size);
println!(" Archive: {} bytes", archive_size);
println!(" Ratio: {:.2}x", 1.0 / ratio);
assert!(
ratio < 0.5,
"Text should compress to <50% (got {:.2}%)",
ratio * 100.0
);
let mut reader = ArchiveReader::open_and_init(path).unwrap();
assert_eq!(reader.read_file("file.txt").unwrap(), text_data.as_bytes());
assert_eq!(reader.read_file("data.json").unwrap(), text_data.as_bytes());
assert_eq!(reader.read_file("readme.md").unwrap(), text_data.as_bytes());
println!(
" ✓ Text files compress well (>{:.0}% reduction)",
(1.0 - ratio) * 100.0
);
}
#[test]
fn test_compression_choice_binary_files() {
println!("\n🔍 Testing compression for binary files (.db, .wasm)...");
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
let mut writer = ArchiveWriter::create(path).unwrap();
let binary_data = vec![0x12; 100 * 1024];
writer.add_file("data.db", &binary_data).unwrap();
writer.add_file("app.wasm", &binary_data).unwrap();
writer.finalize().unwrap();
let mut reader = ArchiveReader::open_and_init(path).unwrap();
assert_eq!(reader.read_file("data.db").unwrap(), binary_data);
assert_eq!(reader.read_file("app.wasm").unwrap(), binary_data);
println!(" ✓ Binary files compress and decompress correctly");
}
#[test]
fn test_compression_choice_already_compressed() {
println!("\n🔍 Testing compression for already-compressed files (.png, .jpg, .zip)...");
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
let mut writer = ArchiveWriter::create(path).unwrap();
let fake_png = {
let mut data = vec![0x89, b'P', b'N', b'G', 0x0D, 0x0A, 0x1A, 0x0A];
data.extend(vec![0xAB; 1000]);
data
};
let fake_jpg = {
let mut data = vec![0xFF, 0xD8, 0xFF, 0xE0];
data.extend(vec![0xCD; 1000]);
data
};
let fake_zip = {
let mut data = vec![0x50, 0x4B, 0x03, 0x04];
data.extend(vec![0xEF; 1000]);
data
};
writer.add_file("image.png", &fake_png).unwrap();
writer.add_file("photo.jpg", &fake_jpg).unwrap();
writer.add_file("archive.zip", &fake_zip).unwrap();
writer.finalize().unwrap();
let mut reader = ArchiveReader::open_and_init(path).unwrap();
assert_eq!(reader.read_file("image.png").unwrap(), fake_png);
assert_eq!(reader.read_file("photo.jpg").unwrap(), fake_jpg);
assert_eq!(reader.read_file("archive.zip").unwrap(), fake_zip);
println!(" ✓ Pre-compressed files handled correctly");
}
#[test]
fn test_compression_effectiveness_highly_compressible() {
println!("\n🔍 Testing compression effectiveness on highly compressible data...");
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
let mut writer = ArchiveWriter::create(path).unwrap();
let zeros = vec![0u8; 1024 * 1024]; writer.add_file("zeros.bin", &zeros).unwrap();
writer.finalize().unwrap();
let original_size = zeros.len();
let archive_size = std::fs::metadata(path).unwrap().len();
let ratio = get_compression_ratio(original_size, archive_size);
println!(" Original: {} bytes (1 MB)", original_size);
println!(" Archive: {} bytes", archive_size);
println!(" Compression: {:.2}x", 1.0 / ratio);
assert!(
ratio < 0.01,
"Zeros should compress to <1% (got {:.4}%)",
ratio * 100.0
);
let mut reader = ArchiveReader::open_and_init(path).unwrap();
let data = reader.read_file("zeros.bin").unwrap();
assert_eq!(data.len(), 1024 * 1024);
assert_eq!(data, zeros);
println!(
" ✓ Highly compressible data: >{:.0}x compression",
1.0 / ratio
);
}
#[test]
fn test_compression_effectiveness_mixed_data() {
println!("\n🔍 Testing compression on mixed compressibility data...");
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
let mut writer = ArchiveWriter::create(path).unwrap();
let mut mixed_data = Vec::with_capacity(100_000);
mixed_data.extend(vec![0xAA; 30_000]);
for i in 0..30_000 {
mixed_data.push((i % 256) as u8);
}
mixed_data.extend(vec![0x55; 40_000]);
writer.add_file("mixed.bin", &mixed_data).unwrap();
writer.finalize().unwrap();
let original_size = mixed_data.len();
let archive_size = std::fs::metadata(path).unwrap().len();
let ratio = get_compression_ratio(original_size, archive_size);
println!(" Original: {} bytes", original_size);
println!(" Archive: {} bytes", archive_size);
println!(" Compression ratio: {:.2}x", 1.0 / ratio);
assert!(
ratio < 0.5,
"Mixed data should compress to <50% (got {:.2}%)",
ratio * 100.0
);
let mut reader = ArchiveReader::open_and_init(path).unwrap();
let data = reader.read_file("mixed.bin").unwrap();
assert_eq!(data, mixed_data);
println!(" ✓ Mixed data compressed correctly ({:.2}x)", 1.0 / ratio);
}
#[test]
fn test_explicit_compression_methods() {
println!("\n🔍 Testing explicit compression method specification...");
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
let mut writer = ArchiveWriter::create(path).unwrap();
let test_data = b"test data for compression";
writer
.add_file_with_compression("none.txt", test_data, CompressionMethod::None)
.unwrap();
writer
.add_file_with_compression("lz4.txt", test_data, CompressionMethod::Lz4)
.unwrap();
writer
.add_file_with_compression("zstd.txt", test_data, CompressionMethod::Zstd)
.unwrap();
writer.finalize().unwrap();
let mut reader = ArchiveReader::open_and_init(path).unwrap();
assert_eq!(reader.read_file("none.txt").unwrap(), test_data);
assert_eq!(reader.read_file("lz4.txt").unwrap(), test_data);
assert_eq!(reader.read_file("zstd.txt").unwrap(), test_data);
println!(" ✓ Explicit compression methods work correctly");
}
#[test]
fn test_mixed_compression_in_archive() {
println!("\n🔍 Testing mixed compression methods in single archive...");
let temp_file = NamedTempFile::new().unwrap();
let path = temp_file.path();
let mut writer = ArchiveWriter::create(path).unwrap();
let zeros = vec![0u8; 10_000]; let pattern: Vec<u8> = (0..10_000).map(|i| (i % 256) as u8).collect(); let text = "Hello World ".repeat(1000);
writer
.add_file_with_compression("zeros.bin", &zeros, CompressionMethod::Zstd)
.unwrap();
writer
.add_file_with_compression("pattern.bin", &pattern, CompressionMethod::Lz4)
.unwrap();
writer
.add_file_with_compression("text.txt", text.as_bytes(), CompressionMethod::Zstd)
.unwrap();
writer
.add_file_with_compression("raw.txt", b"small", CompressionMethod::None)
.unwrap();
writer.finalize().unwrap();
let mut reader = ArchiveReader::open_and_init(path).unwrap();
assert_eq!(reader.read_file("zeros.bin").unwrap(), zeros);
assert_eq!(reader.read_file("pattern.bin").unwrap(), pattern);
assert_eq!(reader.read_file("text.txt").unwrap(), text.as_bytes());
assert_eq!(reader.read_file("raw.txt").unwrap(), b"small");
println!(" ✓ Mixed compression methods in single archive work correctly");
}