Merge pull request #206 from sigmaSd/refactor
[ouch.git] / tests / integration.rs
blob49c2a27803b048dc6703ca8495d7aa7845dc6dff
1 #[macro_use]
2 mod utils;
4 use std::{iter::once, path::PathBuf};
6 use fs_err as fs;
7 use parse_display::Display;
8 use proptest::sample::size_range;
9 use rand::{rngs::SmallRng, RngCore, SeedableRng};
10 use tempfile::tempdir;
11 use test_strategy::{proptest, Arbitrary};
13 use crate::utils::{assert_same_directory, write_random_content};
15 // tar and zip extensions
16 #[derive(Arbitrary, Debug, Display)]
17 #[display(style = "lowercase")]
18 enum DirectoryExtension {
19     Tar,
20     Tbz,
21     Tgz,
22     Tlz4,
23     Tlz,
24     Tlzma,
25     Txz,
26     Zip,
29 // extensions of single file compression formats
30 #[derive(Arbitrary, Debug, Display)]
31 #[display(style = "lowercase")]
32 enum FileExtension {
33     Bz,
34     Bz2,
35     Gz,
36     Lz4,
37     Lzma,
38     Xz,
41 #[derive(Arbitrary, Debug, Display)]
42 #[display("{0}")]
43 enum Extension {
44     Directory(DirectoryExtension),
45     File(FileExtension),
48 // converts a list of extension structs to string
49 fn merge_extensions(ext: impl ToString, exts: Vec<FileExtension>) -> String {
50     once(ext.to_string()).chain(exts.into_iter().map(|x| x.to_string())).collect::<Vec<_>>().join(".")
53 // create random nested directories and files under the specified directory
54 fn create_random_files(dir: impl Into<PathBuf>, depth: u8, rng: &mut SmallRng) {
55     if depth == 0 {
56         return;
57     }
59     let dir = &dir.into();
61     // create 0 to 7 random files
62     for _ in 0..rng.next_u32() % 8 {
63         write_random_content(&mut tempfile::Builder::new().tempfile_in(dir).unwrap().keep().unwrap().0, rng);
64     }
66     // create more random files in 0 to 3 new directories
67     for _ in 0..rng.next_u32() % 4 {
68         create_random_files(&tempfile::tempdir_in(dir).unwrap().into_path(), depth - 1, rng);
69     }
72 // compress and decompress a single empty file
73 #[proptest(cases = 512)]
74 fn single_empty_file(ext: Extension, #[any(size_range(0..8).lift())] exts: Vec<FileExtension>) {
75     let dir = tempdir().unwrap();
76     let dir = dir.path();
77     let before = &dir.join("before");
78     fs::create_dir(before).unwrap();
79     let before_file = &before.join("file");
80     let archive = &dir.join(format!("file.{}", merge_extensions(ext, exts)));
81     let after = &dir.join("after");
82     write_random_content(&mut fs::File::create(before_file).unwrap(), &mut SmallRng::from_entropy());
83     ouch!("c", before_file, archive);
84     ouch!("d", archive, "-d", after);
85     assert_same_directory(before, after, false);
88 // compress and decompress a single file
89 #[proptest(cases = 512)]
90 fn single_file(ext: Extension, #[any(size_range(0..8).lift())] exts: Vec<FileExtension>) {
91     let dir = tempdir().unwrap();
92     let dir = dir.path();
93     let before = &dir.join("before");
94     fs::create_dir(before).unwrap();
95     let before_file = &before.join("file");
96     let archive = &dir.join(format!("file.{}", merge_extensions(ext, exts)));
97     let after = &dir.join("after");
98     fs::write(before_file, []).unwrap();
99     ouch!("c", before_file, archive);
100     ouch!("d", archive, "-d", after);
101     assert_same_directory(before, after, false);
104 // compress and decompress a directory with random content generated with create_random_files
105 #[proptest(cases = 512)]
106 fn multiple_files(
107     ext: DirectoryExtension,
108     #[any(size_range(0..8).lift())] exts: Vec<FileExtension>,
109     #[strategy(0u8..4)] depth: u8,
110 ) {
111     let dir = tempdir().unwrap();
112     let dir = dir.path();
113     let before = &dir.join("before");
114     let before_dir = &before.join("dir");
115     fs::create_dir_all(before_dir).unwrap();
116     let archive = &dir.join(format!("archive.{}", merge_extensions(&ext, exts)));
117     let after = &dir.join("after");
118     create_random_files(before_dir, depth, &mut SmallRng::from_entropy());
119     ouch!("c", before_dir, archive);
120     ouch!("d", archive, "-d", after);
121     assert_same_directory(before, after, !matches!(ext, DirectoryExtension::Zip));