this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 52ec9ed3a28388caee2e1d877b9b3eaf727655b6 194 lines 6.7 kB view raw
1use crate::utils::ExtractedTarget; 2use std::fs; 3use std::io; 4use std::path::Path; 5use tempfile::tempdir; 6 7use crate::utils::{CmprssInput, CmprssOutput, CompressionLevelValidator, Compressor}; 8 9/// Test basic trait functionality that should be common across all compressors 10pub fn test_compressor_interface<T: Compressor>( 11 compressor: &T, 12 expected_name: &str, 13 expected_extension: Option<&str>, 14) { 15 let ext = expected_extension.unwrap_or(expected_name); 16 17 // Test name() returns expected value 18 assert_eq!(compressor.name(), expected_name); 19 20 // Test extension() returns expected value 21 assert_eq!(compressor.extension(), ext); 22 23 // Test is_archive() detection logic 24 let temp_dir = tempdir().expect("Failed to create temp dir"); 25 26 // Test with matching extension 27 let archive_path = temp_dir.path().join(format!("test.{}", ext)); 28 fs::File::create(&archive_path).expect("Failed to create test file"); 29 assert!(compressor.is_archive(&archive_path)); 30 31 // Test with non-matching extension 32 let non_archive_path = temp_dir.path().join("test.txt"); 33 fs::File::create(&non_archive_path).expect("Failed to create test file"); 34 assert!(!compressor.is_archive(&non_archive_path)); 35 36 // Test default_compressed_filename 37 let test_path = Path::new("test.txt"); 38 let expected = format!("test.txt.{}", ext); 39 assert_eq!(compressor.default_compressed_filename(test_path), expected); 40 41 // Test default_extracted_filename 42 let formatted_name = format!("test.{}", ext); 43 let archive_path = Path::new(&formatted_name); 44 match compressor.default_extracted_target() { 45 ExtractedTarget::FILE => { 46 assert_eq!(compressor.default_extracted_filename(archive_path), "test"); 47 } 48 ExtractedTarget::DIRECTORY => { 49 assert_eq!(compressor.default_extracted_filename(archive_path), "."); 50 } 51 } 52 53 // Test default_extracted_filename with non-matching extension 54 let non_archive_path = Path::new("test.txt"); 55 match compressor.default_extracted_target() { 56 ExtractedTarget::FILE => { 57 assert_eq!( 58 compressor.default_extracted_filename(non_archive_path), 59 "archive" 60 ); 61 } 62 ExtractedTarget::DIRECTORY => { 63 assert_eq!(compressor.default_extracted_filename(non_archive_path), "."); 64 } 65 } 66} 67 68/// Test compression and extraction functionality with a simple string 69pub fn test_compressor_roundtrip<T: Compressor>( 70 compressor: &T, 71 test_data: &str, 72) -> Result<(), io::Error> { 73 let temp_dir = tempdir().expect("Failed to create temp dir"); 74 75 // Create test file 76 let input_path = temp_dir.path().join("input.txt"); 77 fs::write(&input_path, test_data)?; 78 79 // Compress 80 let archive_path = temp_dir 81 .path() 82 .join(format!("archive.{}", compressor.extension())); 83 compressor.compress( 84 CmprssInput::Path(vec![input_path.clone()]), 85 CmprssOutput::Path(archive_path.clone()), 86 )?; 87 88 // Extract 89 let output_path = match compressor.default_extracted_target() { 90 ExtractedTarget::FILE => temp_dir.path().join("output.txt"), 91 ExtractedTarget::DIRECTORY => temp_dir.path().join("output"), 92 }; 93 compressor.extract( 94 CmprssInput::Path(vec![archive_path]), 95 CmprssOutput::Path(output_path.clone()), 96 )?; 97 98 // Verify 99 let input_filename = "input.txt"; 100 let output_data = match compressor.default_extracted_target() { 101 ExtractedTarget::FILE => fs::read_to_string(output_path)?, 102 ExtractedTarget::DIRECTORY => fs::read_to_string(output_path.join(input_filename))?, 103 }; 104 assert_eq!(output_data, test_data); 105 106 Ok(()) 107} 108 109/// Test compression and extraction with different content sizes 110pub fn test_compression<T: Compressor>(compressor: &T) -> Result<(), io::Error> { 111 // Test with empty content 112 test_compressor_roundtrip(compressor, "")?; 113 114 // Test with small content 115 test_compressor_roundtrip(compressor, "Small test content")?; 116 117 // Test with medium content (generate a 10KB string) 118 let medium_content = "0123456789".repeat(1024); 119 test_compressor_roundtrip(compressor, &medium_content)?; 120 121 Ok(()) 122} 123 124/// Run a full suite of tests on a compressor implementation 125pub fn run_compressor_tests<T: Compressor>( 126 compressor: &T, 127 expected_name: &str, 128 expected_extension: Option<&str>, 129) -> Result<(), io::Error> { 130 // Test interface methods 131 test_compressor_interface(compressor, expected_name, expected_extension); 132 133 // Test compression/extraction functionality 134 test_compression(compressor)?; 135 136 Ok(()) 137} 138 139/// Helper function to test CompressionValidator implementations 140/// This avoids duplicating the same test pattern across multiple backends 141pub fn test_compression_validator_helper<V: CompressionLevelValidator>( 142 validator: &V, 143 min_level: i32, 144 max_level: i32, 145 default_level: i32, 146 fast_name_level: Option<i32>, 147 best_name_level: Option<i32>, 148 none_name_level: Option<i32>, 149) { 150 // Test range 151 assert_eq!(validator.min_level(), min_level); 152 assert_eq!(validator.max_level(), max_level); 153 assert_eq!(validator.default_level(), default_level); 154 155 // Test validation 156 assert!(validator.is_valid_level(min_level)); 157 assert!(validator.is_valid_level(max_level)); 158 assert!(!validator.is_valid_level(min_level - 1)); 159 assert!(!validator.is_valid_level(max_level + 1)); 160 161 // Test middle level if range is big enough 162 if max_level - min_level >= 2 { 163 let mid_level = (min_level + max_level) / 2; 164 assert!(validator.is_valid_level(mid_level)); 165 } 166 167 // Test clamping 168 assert_eq!(validator.validate_and_clamp_level(min_level - 1), min_level); 169 assert_eq!(validator.validate_and_clamp_level(min_level), min_level); 170 assert_eq!(validator.validate_and_clamp_level(max_level), max_level); 171 assert_eq!(validator.validate_and_clamp_level(max_level + 1), max_level); 172 173 // Test special names 174 if let Some(level) = fast_name_level { 175 assert_eq!(validator.name_to_level("fast"), Some(level)); 176 } else { 177 assert_eq!(validator.name_to_level("fast"), None); 178 } 179 180 if let Some(level) = best_name_level { 181 assert_eq!(validator.name_to_level("best"), Some(level)); 182 } else { 183 assert_eq!(validator.name_to_level("best"), None); 184 } 185 186 if let Some(level) = none_name_level { 187 assert_eq!(validator.name_to_level("none"), Some(level)); 188 } else { 189 assert_eq!(validator.name_to_level("none"), None); 190 } 191 192 // Test invalid name 193 assert_eq!(validator.name_to_level("invalid"), None); 194}