diff --git a/Cargo.lock b/Cargo.lock index b254ed0..cc1dcff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,6 +67,16 @@ dependencies = [ "jobserver", ] +[[package]] +name = "cfb" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca453e8624711b2f0f4eb47076a318feda166252a827ee25d067b43de83dcba0" +dependencies = [ + "byteorder", + "uuid", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -127,6 +137,15 @@ dependencies = [ "libc", ] +[[package]] +name = "infer" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea70330449622910e0edebab230734569516269fb32342fb0a8956340fa48c6c" +dependencies = [ + "cfb", +] + [[package]] name = "jobserver" version = "0.1.24" @@ -187,6 +206,7 @@ dependencies = [ "atty", "bzip2", "flate2", + "infer", "lazy_static", "libc", "rand", @@ -364,6 +384,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/Cargo.toml b/Cargo.toml index 411e0a9..f1d3a9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ zstd = { version = "0.9.0", default-features = false, features = ["thin"] [dev-dependencies] tempfile = "3.2.0" +infer = "0.5.0" rand = { version = "0.8.3", default-features = false, features = ["small_rng", "std"] } [profile.release] diff --git a/src/archive/tar.rs b/src/archive/tar.rs index 8dc5d1e..38f6c2f 100644 --- a/src/archive/tar.rs +++ b/src/archive/tar.rs @@ -1,3 +1,5 @@ +//! Contains Tar-specific building and unpacking functions + use std::{ env, fs, io::prelude::*, diff --git a/src/archive/zip.rs b/src/archive/zip.rs index e25e7f5..ba43f73 100644 --- a/src/archive/zip.rs +++ b/src/archive/zip.rs @@ -1,3 +1,5 @@ +//! Contains Zip-specific building and unpacking functions + use std::{ env, fs, io::{self, prelude::*}, @@ -14,6 +16,7 @@ use crate::{ use self::utf8::get_invalid_utf8_paths; +/// Unpacks the archive given by `archive` into the folder given by `into`. pub fn unpack_archive(mut archive: ZipArchive, into: &Path, flags: &oof::Flags) -> crate::Result> where R: Read + Seek, diff --git a/src/lib.rs b/src/lib.rs index 59618bc..b6fd3b7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,7 @@ pub use error::{Error, Result}; use lazy_static::lazy_static; +/// The status code ouch has when an error is encountered pub const EXIT_FAILURE: i32 = libc::EXIT_FAILURE; const VERSION: &'static str = env!("CARGO_PKG_VERSION"); diff --git a/src/oof/util.rs b/src/oof/util.rs index 00d874b..5479818 100644 --- a/src/oof/util.rs +++ b/src/oof/util.rs @@ -13,3 +13,21 @@ pub fn trim_single_hyphen(flag_text: &str) -> &str { chars.next(); // Skipping 1 char chars.as_str() } + +#[cfg(test)] +mod tests { + use super::trim_double_hyphen; + use super::trim_single_hyphen; + + #[test] + fn _trim_double_hyphen() { + assert_eq!(trim_double_hyphen("--flag"), "flag"); + assert_eq!(trim_double_hyphen("--verbose"), "verbose"); + assert_eq!(trim_double_hyphen("--help"), "help"); + } + + fn _trim_single_hyphen() { + assert_eq!(trim_single_hyphen("-vv"), "vv"); + assert_eq!(trim_single_hyphen("-h"), "h"); + } +} diff --git a/tests/compress_and_decompress.rs b/tests/compress_and_decompress.rs index 724ef46..06eba2e 100644 --- a/tests/compress_and_decompress.rs +++ b/tests/compress_and_decompress.rs @@ -4,12 +4,57 @@ use std::{ env, fs, io::prelude::*, path::{Path, PathBuf}, + time::Duration, }; use ouch::{cli::Command, commands::run, oof}; use rand::{rngs::SmallRng, RngCore, SeedableRng}; +use tempfile::NamedTempFile; use utils::*; +#[test] +/// Makes sure that the files ouch produces are what they claim to be, checking their +/// types through MIME sniffing. +fn sanity_check_through_mime() { + // Somehow this test causes test failures when run in parallel with test_each_format + // This is a temporary hack that should allow the tests to pass while this bug isn't solved. + std::thread::sleep(Duration::from_millis(100)); + + let temp_dir = tempfile::tempdir().expect("to build a temporary directory"); + + let mut test_file = NamedTempFile::new_in(temp_dir.path()).expect("to be able to build a temporary file"); + + let bytes = generate_random_file_content(&mut SmallRng::from_entropy()); + test_file.write_all(&bytes).expect("to successfully write bytes to the file"); + + let formats = ["tar", "zip", "tar.gz", "tar.bz", "tar.bz2", "tar.lzma", "tar.xz", "tar.zst"]; + + let expected_mimes = [ + "application/x-tar", + "application/zip", + "application/gzip", + "application/x-bzip2", + "application/x-bzip2", + "application/x-xz", + "application/x-xz", + "application/zstd", + ]; + + assert_eq!(formats.len(), expected_mimes.len()); + + for (format, expected_mime) in formats.iter().zip(expected_mimes.iter()) { + let temp_dir_path = temp_dir.path(); + let paths_to_compress = &[test_file.path().into()]; + + let compressed_file_path = compress_files(temp_dir_path, paths_to_compress, format); + + let sniffed = + infer::get_from_path(compressed_file_path).expect("the file to be read").expect("the MIME to be found"); + + assert_eq!(&sniffed.mime_type(), expected_mime); + } +} + #[test] /// Tests each format that supports multiple files with random input. /// TODO: test the remaining formats.