From a25336cee7076c8e6c2dc98a6c2737f8aed8b092 Mon Sep 17 00:00:00 2001 From: Haruaki Tamada Date: Fri, 3 May 2024 15:38:20 +0900 Subject: [PATCH 1/2] add some unit tests --- Cargo.toml | 2 +- src/archiver.rs | 32 +++++++++- src/archiver/{optscreator.rs => os.rs} | 0 src/archiver/{optscreator => os}/linux.rs | 0 src/archiver/{optscreator => os}/windows.rs | 0 src/archiver/rar.rs | 28 ++++++++ src/archiver/tar.rs | 71 ++++++++++++++++++++- src/archiver/zip.rs | 10 +-- src/extractor.rs | 28 +++++++- src/extractor/rar.rs | 27 ++++++++ src/extractor/tar.rs | 34 ++++++++++ src/extractor/zip.rs | 28 ++++++++ src/format.rs | 2 +- src/main.rs | 6 +- src/verboser.rs | 4 +- 15 files changed, 256 insertions(+), 16 deletions(-) rename src/archiver/{optscreator.rs => os.rs} (100%) rename src/archiver/{optscreator => os}/linux.rs (100%) rename src/archiver/{optscreator => os}/windows.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 81ac76b..ef15017 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ description = "A tool for archiving files and directories and extracting several repository = "https://github.com/tamada/totebag" readme = "README.md" authors = [ - "Haruaki Tamada " ] license = "MIT" categories = ["command-line-utilities", "compression"] diff --git a/src/archiver.rs b/src/archiver.rs index c4fd42d..d1eb2a4 100644 --- a/src/archiver.rs +++ b/src/archiver.rs @@ -9,7 +9,7 @@ use crate::archiver::tar::{TarArchiver, TarGzArchiver, TarBz2Archiver}; use crate::verboser::{create_verboser, Verboser}; use crate::CliOpts; -mod optscreator; +mod os; mod zip; mod rar; mod tar; @@ -19,7 +19,7 @@ pub trait Archiver { fn format(&self) -> Format; } -pub fn create_archiver(dest: PathBuf) -> Result> { +pub fn create_archiver(dest: &PathBuf) -> Result> { let format = find_format(dest.file_name()); match format { Ok(format) => { @@ -89,3 +89,31 @@ impl ArchiverOpts { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_archiver() { + let a1 = create_archiver(&PathBuf::from("results/test.tar")); + assert!(a1.is_ok()); + assert_eq!(a1.unwrap().format(), Format::Tar); + + let a2 = create_archiver(&PathBuf::from("results/test.tar.gz")); + assert!(a2.is_ok()); + assert_eq!(a2.unwrap().format(), Format::TarGz); + + let a3 = create_archiver(&PathBuf::from("results/test.tar.bz2")); + assert!(a3.is_ok()); + assert_eq!(a3.unwrap().format(), Format::TarBz2); + + let a4 = create_archiver(&PathBuf::from("results/test.zip")); + assert!(a4.is_ok()); + assert_eq!(a4.unwrap().format(), Format::Zip); + + let a5 = create_archiver(&PathBuf::from("results/test.rar")); + assert!(a5.is_ok()); + assert_eq!(a5.unwrap().format(), Format::Rar); + } +} \ No newline at end of file diff --git a/src/archiver/optscreator.rs b/src/archiver/os.rs similarity index 100% rename from src/archiver/optscreator.rs rename to src/archiver/os.rs diff --git a/src/archiver/optscreator/linux.rs b/src/archiver/os/linux.rs similarity index 100% rename from src/archiver/optscreator/linux.rs rename to src/archiver/os/linux.rs diff --git a/src/archiver/optscreator/windows.rs b/src/archiver/os/windows.rs similarity index 100% rename from src/archiver/optscreator/windows.rs rename to src/archiver/os/windows.rs diff --git a/src/archiver/rar.rs b/src/archiver/rar.rs index 6a4bf69..c461356 100644 --- a/src/archiver/rar.rs +++ b/src/archiver/rar.rs @@ -12,3 +12,31 @@ impl Archiver for RarArchiver { Format::Rar } } + +#[cfg(test)] +mod tests { + use super::*; + + use std::path::PathBuf; + use crate::verboser::create_verboser; + + #[test] + fn test_format() { + let archiver = RarArchiver{}; + assert_eq!(archiver.format(), Format::Rar); + } + + #[test] + fn test_archive() { + let archiver = RarArchiver{}; + let opts = ArchiverOpts { + dest: PathBuf::from("results/test.rar"), + targets: vec![], + overwrite: false, + recursive: false, + v: create_verboser(false), + }; + let r = archiver.perform(opts); + assert!(r.is_err()); + } +} diff --git a/src/archiver/tar.rs b/src/archiver/tar.rs index c32e16e..5e6c42d 100644 --- a/src/archiver/tar.rs +++ b/src/archiver/tar.rs @@ -95,4 +95,73 @@ fn write_to_tar(file: W, targets: Vec, recursive: bool) -> Re return Err(ToatError::ArchiverError(e.to_string())) } Ok(()) -} \ No newline at end of file +} + +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use crate::archiver::Archiver; + use crate::archiver::tar::{TarArchiver, TarGzArchiver, TarBz2Archiver}; + use crate::archiver::ArchiverOpts; + use crate::format::Format; + + fn run_test(f: F) + where + F: FnOnce() -> PathBuf, + { + // setup(); // 予めやりたい処理 + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)); + match result { + Ok(path) => teardown(path), + Err(err) => std::panic::resume_unwind(err), + } + } + + #[test] + fn test_tar() { + run_test(|| { + let archiver = TarArchiver{}; + let inout = ArchiverOpts::create(PathBuf::from("results/test.tar"), vec![PathBuf::from("src"), PathBuf::from("Cargo.toml")], true, true, false); + let result = archiver.perform(inout); + let path = PathBuf::from("results/test.tar"); + assert!(result.is_ok()); + assert!(path.exists()); + assert_eq!(archiver.format(), Format::Tar); + path + }); + } + + + #[test] + fn test_targz() { + run_test(|| { + let archiver = TarGzArchiver{}; + let inout = ArchiverOpts::create(PathBuf::from("results/test.tar.gz"), vec![PathBuf::from("src"), PathBuf::from("Cargo.toml")], true, true, false); + let result = archiver.perform(inout); + let path = PathBuf::from("results/test.tar.gz"); + assert!(result.is_ok()); + assert!(path.exists()); + assert_eq!(archiver.format(), Format::TarGz); + path + }); + } + + #[test] + fn test_tarbz2() { + run_test(|| { + let archiver = TarBz2Archiver{}; + let inout = ArchiverOpts::create(PathBuf::from("results/test.tar.bz2"), vec![PathBuf::from("src"), PathBuf::from("Cargo.toml")], true, true, false); + let result = archiver.perform(inout); + let path = PathBuf::from("results/test.tar.bz2"); + assert!(result.is_ok()); + assert!(path.exists()); + assert_eq!(archiver.format(), Format::TarBz2); + path + }); + } + + fn teardown(path: PathBuf) { + let _ = std::fs::remove_file(path); + } +} diff --git a/src/archiver/zip.rs b/src/archiver/zip.rs index 56cd27c..c73543f 100644 --- a/src/archiver/zip.rs +++ b/src/archiver/zip.rs @@ -1,8 +1,8 @@ #[cfg(target_os = "windows")] -use optscreator::windows::*; +use os::windows::*; #[cfg(any(target_os = "linux", target_os = "macos"))] -use optscreator::linux::*; +use os::linux::*; use std::fs::File; use std::path::PathBuf; @@ -10,7 +10,7 @@ use std::io::{BufReader, Write, Seek}; use zip::ZipWriter; use crate::archiver::{Archiver, Format, ArchiverOpts}; -use crate::archiver::optscreator; +use crate::archiver::os; use crate::cli::{ToatError, Result}; pub(super) struct ZipArchiver { @@ -95,7 +95,7 @@ mod tests { fn test_zip() { run_test(|| { let archiver = ZipArchiver{}; - let inout = ArchiverOpts::create(PathBuf::from("test.zip"), vec![PathBuf::from("src"), PathBuf::from("Cargo.toml")], true, true, false); + let inout = ArchiverOpts::create(PathBuf::from("results/test.zip"), vec![PathBuf::from("src"), PathBuf::from("Cargo.toml")], true, true, false); let result = archiver.perform(inout); assert!(result.is_ok()); assert_eq!(archiver.format(), Format::Zip); @@ -103,6 +103,6 @@ mod tests { } fn teardown() { - let _ = std::fs::remove_file("test.zip"); + let _ = std::fs::remove_file("results/test.zip"); } } \ No newline at end of file diff --git a/src/extractor.rs b/src/extractor.rs index 0324317..3a6786b 100644 --- a/src/extractor.rs +++ b/src/extractor.rs @@ -36,9 +36,10 @@ pub trait Extractor { fn format(&self) -> Format; } -pub fn create_extract_opts(opts: CliOpts) -> ExtractorOpts { +pub fn create_extract_opts(opts: &CliOpts) -> ExtractorOpts { + let d = opts.dest.clone(); ExtractorOpts { - dest: opts.dest.unwrap_or_else(|| { + dest: d.unwrap_or_else(|| { PathBuf::from(".") }), use_archive_name_dir: opts.to_archive_name_dir, @@ -97,4 +98,27 @@ mod tests { let target = PathBuf::from("/tmp/archive.zip"); assert_eq!(opts2.destination(&target), PathBuf::from(".")); } + + #[test] + fn test_create_extractor() { + let e1 = create_extractor(&PathBuf::from("results/test.zip")); + assert!(e1.is_ok()); + assert_eq!(e1.unwrap().format(), Format::Zip); + + let e2 = create_extractor(&PathBuf::from("results/test.tar")); + assert!(e2.is_ok()); + assert_eq!(e2.unwrap().format(), Format::Tar); + + let e3 = create_extractor(&PathBuf::from("results/test.tgz")); + assert!(e3.is_ok()); + assert_eq!(e3.unwrap().format(), Format::TarGz); + + let e4 = create_extractor(&PathBuf::from("results/test.tbz2")); + assert!(e4.is_ok()); + assert_eq!(e4.unwrap().format(), Format::TarBz2); + + let e5 = create_extractor(&PathBuf::from("results/test.rar")); + assert!(e5.is_ok()); + assert_eq!(e5.unwrap().format(), Format::Rar); + } } \ No newline at end of file diff --git a/src/extractor/rar.rs b/src/extractor/rar.rs index 817ebf9..1ce19da 100644 --- a/src/extractor/rar.rs +++ b/src/extractor/rar.rs @@ -44,6 +44,7 @@ impl Extractor for RarExtractor { #[cfg(test)] mod tests { use super::*; + use crate::verboser::create_verboser; #[test] fn test_list_archives() { @@ -60,4 +61,30 @@ mod tests { Err(_) => assert!(false), } } + + #[test] + fn test_extract_archive() { + let e = RarExtractor{}; + let file = PathBuf::from("testdata/test.rar"); + let opts = ExtractorOpts { + dest: PathBuf::from("results/rar"), + use_archive_name_dir: true, + overwrite: true, + v: create_verboser(false), + }; + match e.perform(file, &opts) { + Ok(_) => { + assert!(true); + assert!(PathBuf::from("results/rar/test/Cargo.toml").exists()); + std::fs::remove_dir_all(PathBuf::from("results/rar")).unwrap(); + }, + Err(_) => assert!(false), + }; + } + + #[test] + fn test_format() { + let extractor = RarExtractor{}; + assert_eq!(extractor.format(), Format::Rar); + } } \ No newline at end of file diff --git a/src/extractor/tar.rs b/src/extractor/tar.rs index 49e1086..2cb29be 100644 --- a/src/extractor/tar.rs +++ b/src/extractor/tar.rs @@ -103,6 +103,7 @@ fn list_tar(archive: &mut tar::Archive) -> Result> { #[cfg(test)] mod tests { use super::*; + use crate::verboser::create_verboser; #[test] fn test_list_tar_file() { @@ -120,6 +121,27 @@ mod tests { } } + #[test] + fn test_extract_archive() { + let e = TarExtractor{}; + let file = PathBuf::from("testdata/test.tar"); + let opts = ExtractorOpts { + dest: PathBuf::from("results/tar"), + use_archive_name_dir: false, + overwrite: true, + v: create_verboser(false), + }; + match e.perform(file, &opts) { + Ok(_) => { + assert!(true); + assert!(PathBuf::from("results/tar/Cargo.toml").exists()); + std::fs::remove_dir_all(PathBuf::from("results/tar")).unwrap(); + }, + Err(_) => assert!(false), + }; + } + + #[test] fn test_list_tarbz2_file() { let extractor = TarBz2Extractor{}; @@ -151,4 +173,16 @@ mod tests { Err(_) => assert!(false), } } + + #[test] + fn test_format() { + let e1 = TarExtractor{}; + assert_eq!(e1.format(), Format::Tar); + + let e2 = TarGzExtractor{}; + assert_eq!(e2.format(), Format::TarGz); + + let e3 = TarBz2Extractor{}; + assert_eq!(e3.format(), Format::TarBz2); + } } \ No newline at end of file diff --git a/src/extractor/zip.rs b/src/extractor/zip.rs index bc71b77..ed65ab0 100644 --- a/src/extractor/zip.rs +++ b/src/extractor/zip.rs @@ -48,6 +48,7 @@ impl Extractor for ZipExtractor { mod tests { use super::*; use std::path::PathBuf; + use crate::verboser::create_verboser; #[test] fn test_list_archives() { @@ -64,4 +65,31 @@ mod tests { Err(_) => assert!(false), } } + + #[test] + fn test_extract_archive() { + let e = ZipExtractor{}; + let file = PathBuf::from("testdata/test.zip"); + let opts = ExtractorOpts { + dest: PathBuf::from("results/zip"), + use_archive_name_dir: false, + overwrite: true, + v: create_verboser(false), + }; + match e.perform(file, &opts) { + Ok(_) => { + assert!(true); + assert!(PathBuf::from("results/zip/Cargo.toml").exists()); + std::fs::remove_dir_all(PathBuf::from("results/zip")).unwrap(); + }, + Err(_) => assert!(false), + }; + } + + #[test] + fn test_format() { + let e = ZipExtractor{}; + assert_eq!(e.format(), Format::Zip); + } + } \ No newline at end of file diff --git a/src/format.rs b/src/format.rs index 7891284..d9a00f7 100644 --- a/src/format.rs +++ b/src/format.rs @@ -13,7 +13,7 @@ pub fn find_format(file_name: Option<&OsStr>) -> Result { return Ok(Format::Tar); } else if name.ends_with(".rar") { return Ok(Format::Rar); - } else if name.ends_with(".zip") { + } else if name.ends_with(".zip") || name.ends_with(".jar") || name.ends_with(".war") || name.ends_with(".ear") { return Ok(Format::Zip); } else { return Ok(Format::Unknown); diff --git a/src/main.rs b/src/main.rs index 6ae055a..6c82dce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,7 +32,7 @@ fn perform(mut opts: CliOpts) -> Result<()> { fn perform_extract(opts: CliOpts) -> Result<()> { let args = opts.args.clone(); - let extract_opts = create_extract_opts(opts); + let extract_opts = create_extract_opts(&opts); for arg in args.iter() { let extractor = extractor::create_extractor(arg).unwrap(); let target = arg.to_path_buf(); @@ -48,7 +48,7 @@ fn perform_list(opts: CliOpts) -> Result<()> { if !arg.exists() { return Err(ToatError::FileNotFound(arg.to_path_buf())) } - let extractor = extractor::create_extractor(arg).unwrap(); + let extractor = extractor::create_extractor(&arg).unwrap(); if args.len() > 1 { println!("========== {:?} ========== \n", arg); } @@ -62,8 +62,8 @@ fn perform_list(opts: CliOpts) -> Result<()> { } fn perform_archive(opts: CliOpts) -> Result<()> { - let archiver = archiver::create_archiver(opts.output.clone().unwrap()).unwrap(); let inout = ArchiverOpts::new(&opts); + let archiver = archiver::create_archiver(&opts.output.unwrap()).unwrap(); inout.v.verbose(archiver_info(&archiver, &inout)); archiver.perform(inout) } diff --git a/src/verboser.rs b/src/verboser.rs index 57049c0..35798d3 100644 --- a/src/verboser.rs +++ b/src/verboser.rs @@ -1,3 +1,4 @@ + pub trait Verboser { fn verbose(&self, message: String); } @@ -25,4 +26,5 @@ impl Verboser for SimpleVerboser { fn verbose(&self, message: String) { println!("{}", message); } -} \ No newline at end of file +} + From 80d94043f997169cf9decb586c999a01c99faa53 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 3 May 2024 06:38:40 +0000 Subject: [PATCH 2/2] update version to 0.2.0, ready to publish v0.2.0 --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f21a41b..3900202 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # totebag -[![Version](https://shields.io/badge/Version-0.1.18-blue)](https://github.com/tamada/totebag/releases/tag/v0.1.18) +[![Version](https://shields.io/badge/Version-0.2.0-blue)](https://github.com/tamada/totebag/releases/tag/v0.2.0) [![MIT License](https://shields.io/badge/License-MIT-blue)](https://github.com/tamada/totebag/blob/main/LICENSE) [![build](https://github.com/tamada/totebag/actions/workflows/build.yaml/badge.svg)](https://github.com/tamada/totebag/actions/workflows/build.yaml) @@ -9,13 +9,13 @@ A tool for archiving files and directories and extracting several archive formats. -## :speaking_head: Description +## Description There are many archive formats and their tools. The one problem with using each tool is that its interfaces are slightly different. Then, The `totebag` treats the archive files as the same interface. The tool can extract archive files and archive files and directories. -## :runner: Usage +## Usage ```sh totebag [OPTIONS] @@ -37,7 +37,7 @@ ARGUMENTS Otherwise, it will archive the files. ``` -## :anchor: Install +## Install ```sh brew install tamada/tap/totebag