#![allow(clippy::unwrap_used, clippy::expect_fun_call)]
use mediagit_compression::{
BrotliCompressor, CompressionAlgorithm, CompressionLevel, Compressor, ZstdCompressor,
};
#[test]
fn test_zstd_roundtrip_various_sizes() {
let compressor = ZstdCompressor::new(CompressionLevel::Default);
let test_cases = vec![
("empty", b"".to_vec()),
("small", b"Hello, World!".to_vec()),
("medium", vec![0x42u8; 10_000]),
("large", vec![0x42u8; 1_000_000]),
];
for (name, data) in test_cases {
let compressed = compressor
.compress(&data)
.expect(&format!("compress {}", name));
let decompressed = compressor
.decompress(&compressed)
.expect(&format!("decompress {}", name));
assert_eq!(data, decompressed, "Failed roundtrip for {}", name);
}
}
#[test]
fn test_brotli_roundtrip_various_sizes() {
let compressor = BrotliCompressor::new(CompressionLevel::Default);
let test_cases = vec![
("empty", b"".to_vec()),
("small", b"Hello, World!".to_vec()),
("medium", vec![0x42u8; 10_000]),
("large", vec![0x42u8; 100_000]),
];
for (name, data) in test_cases {
let compressed = compressor
.compress(&data)
.expect(&format!("compress {}", name));
let decompressed = compressor
.decompress(&compressed)
.expect(&format!("decompress {}", name));
assert_eq!(data, decompressed, "Failed roundtrip for {}", name);
}
}
#[test]
fn test_algorithm_detection_zstd() {
let compressor = ZstdCompressor::new(CompressionLevel::Default);
let original = b"Test data for detection";
let compressed = compressor.compress(original).unwrap();
let algorithm = CompressionAlgorithm::detect(&compressed);
assert_eq!(algorithm, CompressionAlgorithm::Zstd);
}
#[test]
fn test_algorithm_detection_brotli() {
let compressor = BrotliCompressor::new(CompressionLevel::Default);
let original = b"Test data for detection";
let compressed = compressor.compress(original).unwrap();
let algorithm = CompressionAlgorithm::detect(&compressed);
assert_eq!(algorithm, CompressionAlgorithm::Brotli);
}
#[test]
fn test_algorithm_detection_raw() {
let raw_data = b"This is raw uncompressed data";
let algorithm = CompressionAlgorithm::detect(raw_data);
assert_eq!(algorithm, CompressionAlgorithm::None);
}
#[test]
fn test_compression_ratios_comparison() {
let test_data = b"Lorem ipsum dolor sit amet. ".repeat(100);
let zstd_compressor = ZstdCompressor::new(CompressionLevel::Default);
let brotli_compressor = BrotliCompressor::new(CompressionLevel::Default);
let zstd_compressed = zstd_compressor.compress(&test_data).unwrap();
let brotli_compressed = brotli_compressor.compress(&test_data).unwrap();
let zstd_ratio = zstd_compressed.len() as f64 / test_data.len() as f64;
let brotli_ratio = brotli_compressed.len() as f64 / test_data.len() as f64;
println!("Original: {} bytes", test_data.len());
println!(
"Zstd: {} bytes ({:.2}% of original)",
zstd_compressed.len(),
zstd_ratio * 100.0
);
println!(
"Brotli: {} bytes ({:.2}% of original)",
brotli_compressed.len(),
brotli_ratio * 100.0
);
assert!(
zstd_ratio < 0.5,
"Zstd should compress repetitive data well"
);
assert!(
brotli_ratio < 0.5,
"Brotli should compress repetitive data well"
);
}
#[test]
fn test_all_compression_levels() {
let data = b"Compression level test data. ".repeat(50);
for level in &[
CompressionLevel::Fast,
CompressionLevel::Default,
CompressionLevel::Best,
] {
let zstd = ZstdCompressor::new(*level);
let zstd_compressed = zstd.compress(&data).unwrap();
let brotli = BrotliCompressor::new(*level);
let brotli_compressed = brotli.compress(&data).unwrap();
let zstd_decompressed = zstd.decompress(&zstd_compressed).unwrap();
let brotli_decompressed = brotli.decompress(&brotli_compressed).unwrap();
assert_eq!(
&data[..],
&zstd_decompressed[..],
"Zstd decompress failed for {:?}",
level
);
assert_eq!(
&data[..],
&brotli_decompressed[..],
"Brotli decompress failed for {:?}",
level
);
}
}
#[test]
fn test_different_data_types() {
let test_cases = vec![
(
"ascii_text",
b"The quick brown fox jumps over the lazy dog. ".to_vec(),
),
(
"utf8_text",
"Hello, World! こんにちは 世界".as_bytes().to_vec(),
),
("json", b"{\"key\": \"value\", \"number\": 123}".to_vec()),
("binary", vec![0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA]),
];
let zstd = ZstdCompressor::new(CompressionLevel::Default);
let brotli = BrotliCompressor::new(CompressionLevel::Default);
for (name, data) in test_cases {
let zstd_compressed = zstd
.compress(&data)
.expect(&format!("zstd compress {}", name));
let zstd_decompressed = zstd
.decompress(&zstd_compressed)
.expect(&format!("zstd decompress {}", name));
assert_eq!(
data, zstd_decompressed,
"Zstd roundtrip failed for {}",
name
);
let brotli_compressed = brotli
.compress(&data)
.expect(&format!("brotli compress {}", name));
let brotli_decompressed = brotli
.decompress(&brotli_compressed)
.expect(&format!("brotli decompress {}", name));
assert_eq!(
data, brotli_decompressed,
"Brotli roundtrip failed for {}",
name
);
}
}
#[test]
fn test_cross_compressor_decompression() {
let zstd = ZstdCompressor::new(CompressionLevel::Default);
let brotli = BrotliCompressor::new(CompressionLevel::Default);
let data = b"Test cross-compression";
let brotli_compressed = brotli.compress(data).unwrap();
let result = zstd.decompress(&brotli_compressed).unwrap();
assert_ne!(result, data);
}
#[test]
fn test_large_file_simulation() {
let mut large_data = Vec::new();
for chunk_idx in 0..100 {
let chunk = format!("Chunk {}: {}\n", chunk_idx, "x".repeat(50_000)).into_bytes();
large_data.extend_from_slice(&chunk);
}
let zstd = ZstdCompressor::new(CompressionLevel::Default);
let brotli = BrotliCompressor::new(CompressionLevel::Default);
let zstd_compressed = zstd.compress(&large_data).unwrap();
let brotli_compressed = brotli.compress(&large_data).unwrap();
let zstd_decompressed = zstd.decompress(&zstd_compressed).unwrap();
let brotli_decompressed = brotli.decompress(&brotli_compressed).unwrap();
assert_eq!(large_data, zstd_decompressed);
assert_eq!(large_data, brotli_decompressed);
println!(
"Large file ({}MB) compression:",
large_data.len() / 1_000_000
);
println!(
" Zstd: {:.2}% of original",
(zstd_compressed.len() as f64 / large_data.len() as f64) * 100.0
);
println!(
" Brotli: {:.2}% of original",
(brotli_compressed.len() as f64 / large_data.len() as f64) * 100.0
);
}