diff --git a/tests/end_to_end.rs b/tests/end_to_end.rs index d0185f60..25d0c54d 100644 --- a/tests/end_to_end.rs +++ b/tests/end_to_end.rs @@ -4,106 +4,135 @@ use std::io::prelude::*; use std::io::{Cursor, Seek}; use std::iter::FromIterator; use zip::write::FileOptions; -use zip::CompressionMethod; +use zip::{CompressionMethod, SUPPORTED_COMPRESSION_METHODS}; // This test asserts that after creating a zip file, then reading its contents back out, // the extracted data will *always* be exactly the same as the original data. #[test] fn end_to_end() { - let file = &mut Cursor::new(Vec::new()); + for &method in SUPPORTED_COMPRESSION_METHODS { + let file = &mut Cursor::new(Vec::new()); - write_to_zip(file).expect("file written"); + println!("Writing file with {} compression", method); + write_test_archive(file, method).expect("Couldn't write test zip archive"); - check_zip_contents(file, ENTRY_NAME); + println!("Checking file contents"); + check_archive_file(file, ENTRY_NAME, Some(method), LOREM_IPSUM); + } } // This test asserts that after copying a `ZipFile` to a new `ZipWriter`, then reading its // contents back out, the extracted data will *always* be exactly the same as the original data. #[test] fn copy() { - let src_file = &mut Cursor::new(Vec::new()); - write_to_zip(src_file).expect("file written"); + for &method in SUPPORTED_COMPRESSION_METHODS { + let src_file = &mut Cursor::new(Vec::new()); + write_test_archive(src_file, method).expect("Couldn't write to test file"); - let mut tgt_file = &mut Cursor::new(Vec::new()); - - { - let mut src_archive = zip::ZipArchive::new(src_file).unwrap(); - let mut zip = zip::ZipWriter::new(&mut tgt_file); + let mut tgt_file = &mut Cursor::new(Vec::new()); { - let file = src_archive.by_name(ENTRY_NAME).expect("file found"); - zip.raw_copy_file(file).unwrap(); + let mut src_archive = zip::ZipArchive::new(src_file).unwrap(); + let mut zip = zip::ZipWriter::new(&mut tgt_file); + + { + let file = src_archive + .by_name(ENTRY_NAME) + .expect("Missing expected file"); + + zip.raw_copy_file(file).expect("Couldn't copy file"); + } + + { + let file = src_archive + .by_name(ENTRY_NAME) + .expect("Missing expected file"); + + zip.raw_copy_file_rename(file, COPY_ENTRY_NAME) + .expect("Couldn't copy and rename file"); + } } - { - let file = src_archive.by_name(ENTRY_NAME).expect("file found"); - zip.raw_copy_file_rename(file, COPY_ENTRY_NAME).unwrap(); - } + let mut tgt_archive = zip::ZipArchive::new(tgt_file).unwrap(); + + check_archive_file_contents(&mut tgt_archive, ENTRY_NAME, LOREM_IPSUM); + check_archive_file_contents(&mut tgt_archive, COPY_ENTRY_NAME, LOREM_IPSUM); } - - let mut tgt_archive = zip::ZipArchive::new(tgt_file).unwrap(); - - check_zip_file_contents(&mut tgt_archive, ENTRY_NAME); - check_zip_file_contents(&mut tgt_archive, COPY_ENTRY_NAME); } // This test asserts that after appending to a `ZipWriter`, then reading its contents back out, // both the prior data and the appended data will be exactly the same as their originals. #[test] fn append() { - let mut file = &mut Cursor::new(Vec::new()); - write_to_zip(file).expect("file written"); + for &method in SUPPORTED_COMPRESSION_METHODS { + let mut file = &mut Cursor::new(Vec::new()); + write_test_archive(file, method).expect("Couldn't write to test file"); - { - let mut zip = zip::ZipWriter::new_append(&mut file).unwrap(); - zip.start_file(COPY_ENTRY_NAME, Default::default()).unwrap(); - zip.write_all(LOREM_IPSUM).unwrap(); - zip.finish().unwrap(); + { + let mut zip = zip::ZipWriter::new_append(&mut file).unwrap(); + zip.start_file( + COPY_ENTRY_NAME, + FileOptions::default().compression_method(method), + ) + .unwrap(); + zip.write_all(LOREM_IPSUM).unwrap(); + zip.finish().unwrap(); + } + + let mut zip = zip::ZipArchive::new(&mut file).unwrap(); + check_archive_file_contents(&mut zip, ENTRY_NAME, LOREM_IPSUM); + check_archive_file_contents(&mut zip, COPY_ENTRY_NAME, LOREM_IPSUM); } - - let mut zip = zip::ZipArchive::new(&mut file).unwrap(); - check_zip_file_contents(&mut zip, ENTRY_NAME); - check_zip_file_contents(&mut zip, COPY_ENTRY_NAME); } -fn write_to_zip(file: &mut Cursor>) -> zip::result::ZipResult<()> { +// Write a test zip archive to buffer. +fn write_test_archive( + file: &mut Cursor>, + method: CompressionMethod, +) -> zip::result::ZipResult<()> { let mut zip = zip::ZipWriter::new(file); zip.add_directory("test/", Default::default())?; let options = FileOptions::default() - .compression_method(CompressionMethod::Stored) + .compression_method(method) .unix_permissions(0o755); + zip.start_file("test/☃.txt", options)?; zip.write_all(b"Hello, World!\n")?; - zip.start_file_with_extra_data("test_with_extra_data/🐢.txt", Default::default())?; + zip.start_file_with_extra_data("test_with_extra_data/🐢.txt", options)?; zip.write_u16::(0xbeef)?; zip.write_u16::(EXTRA_DATA.len() as u16)?; zip.write_all(EXTRA_DATA)?; zip.end_extra_data()?; zip.write_all(b"Hello, World! Again.\n")?; - zip.start_file(ENTRY_NAME, Default::default())?; + zip.start_file(ENTRY_NAME, options)?; zip.write_all(LOREM_IPSUM)?; zip.finish()?; Ok(()) } -fn read_zip(zip_file: R) -> zip::result::ZipResult> { +// Load an archive from buffer and check for test data. +fn check_test_archive(zip_file: R) -> zip::result::ZipResult> { let mut archive = zip::ZipArchive::new(zip_file).unwrap(); - let expected_file_names = [ - "test/", - "test/☃.txt", - "test_with_extra_data/🐢.txt", - ENTRY_NAME, - ]; - let expected_file_names = HashSet::from_iter(expected_file_names.iter().copied()); - let file_names = archive.file_names().collect::>(); - assert_eq!(file_names, expected_file_names); + // Check archive contains expected file names. + { + let expected_file_names = [ + "test/", + "test/☃.txt", + "test_with_extra_data/🐢.txt", + ENTRY_NAME, + ]; + let expected_file_names = HashSet::from_iter(expected_file_names.iter().copied()); + let file_names = archive.file_names().collect::>(); + assert_eq!(file_names, expected_file_names); + } + // Check an archive file for extra data field contents. { let file_with_extra_data = archive.by_name("test_with_extra_data/🐢.txt")?; let mut extra_data = Vec::new(); @@ -116,7 +145,8 @@ fn read_zip(zip_file: R) -> zip::result::ZipResult( +// Read a file in the archive as a string. +fn read_archive_file( archive: &mut zip::ZipArchive, name: &str, ) -> zip::result::ZipResult { @@ -124,17 +154,41 @@ fn read_zip_file( let mut contents = String::new(); file.read_to_string(&mut contents).unwrap(); + Ok(contents) } -fn check_zip_contents(zip_file: &mut Cursor>, name: &str) { - let mut archive = read_zip(zip_file).unwrap(); - check_zip_file_contents(&mut archive, name); +// Check a file in the archive contains expected data and properties. +fn check_archive_file( + zip_file: &mut Cursor>, + name: &str, + expected_method: Option, + expected_data: &[u8], +) { + let mut archive = check_test_archive(zip_file).unwrap(); + + if let Some(expected_method) = expected_method { + // Check the file's compression method. + let file = archive.by_name(name).unwrap(); + let real_method = file.compression(); + + assert_eq!( + expected_method, real_method, + "File does not have expected compression method" + ); + } + + check_archive_file_contents(&mut archive, name, expected_data); } -fn check_zip_file_contents(archive: &mut zip::ZipArchive, name: &str) { - let file_contents: String = read_zip_file(archive, name).unwrap(); - assert_eq!(file_contents.as_bytes(), LOREM_IPSUM); +// Check a file in the archive contains the given data. +fn check_archive_file_contents( + archive: &mut zip::ZipArchive, + name: &str, + expected: &[u8], +) { + let file_contents: String = read_archive_file(archive, name).unwrap(); + assert_eq!(file_contents.as_bytes(), expected); } const LOREM_IPSUM : &[u8] = b"Lorem ipsum dolor sit amet, consectetur adipiscing elit. In tellus elit, tristique vitae mattis egestas, ultricies vitae risus. Quisque sit amet quam ut urna aliquet