Merging dialogs.rs with question.rs
[ouch.git] / tests / integration.rs
blob8ee7f93dd71e451f29661e994cd5eb109d5e9f11
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     Lz,
38     Lzma,
39     Xz,
42 #[derive(Arbitrary, Debug, Display)]
43 #[display("{0}")]
44 enum Extension {
45     Directory(DirectoryExtension),
46     File(FileExtension),
49 // converts a list of extension structs to string
50 fn merge_extensions(ext: impl ToString, exts: Vec<FileExtension>) -> String {
51     once(ext.to_string()).chain(exts.into_iter().map(|x| x.to_string())).collect::<Vec<_>>().join(".")
54 // create random nested directories and files under the specified directory
55 fn create_random_files(dir: impl Into<PathBuf>, depth: u8, rng: &mut SmallRng) {
56     if depth == 0 {
57         return;
58     }
60     let dir = &dir.into();
62     // create 0 to 7 random files
63     for _ in 0..rng.next_u32() % 8 {
64         write_random_content(&mut tempfile::Builder::new().tempfile_in(dir).unwrap().keep().unwrap().0, rng);
65     }
67     // create more random files in 0 to 3 new directories
68     for _ in 0..rng.next_u32() % 4 {
69         create_random_files(&tempfile::tempdir_in(dir).unwrap().into_path(), depth - 1, rng);
70     }
73 // compress and decompress a single empty file
74 #[proptest(cases = 512)]
75 fn single_empty_file(ext: Extension, #[any(size_range(0..8).lift())] exts: Vec<FileExtension>) {
76     let dir = tempdir().unwrap();
77     let dir = dir.path();
78     let before = &dir.join("before");
79     fs::create_dir(before).unwrap();
80     let before_file = &before.join("file");
81     let archive = &dir.join(format!("file.{}", merge_extensions(ext, exts)));
82     let after = &dir.join("after");
83     write_random_content(&mut fs::File::create(before_file).unwrap(), &mut SmallRng::from_entropy());
84     ouch!("c", before_file, archive);
85     ouch!("d", archive, "-d", after);
86     assert_same_directory(before, after, false);
89 // compress and decompress a single file
90 #[proptest(cases = 512)]
91 fn single_file(ext: Extension, #[any(size_range(0..8).lift())] exts: Vec<FileExtension>) {
92     let dir = tempdir().unwrap();
93     let dir = dir.path();
94     let before = &dir.join("before");
95     fs::create_dir(before).unwrap();
96     let before_file = &before.join("file");
97     let archive = &dir.join(format!("file.{}", merge_extensions(ext, exts)));
98     let after = &dir.join("after");
99     fs::write(before_file, []).unwrap();
100     ouch!("c", before_file, archive);
101     ouch!("d", archive, "-d", after);
102     assert_same_directory(before, after, false);
105 // compress and decompress a directory with random content generated with create_random_files
106 #[proptest(cases = 512)]
107 fn multiple_files(
108     ext: DirectoryExtension,
109     #[any(size_range(0..8).lift())] exts: Vec<FileExtension>,
110     #[strategy(0u8..4)] depth: u8,
111 ) {
112     let dir = tempdir().unwrap();
113     let dir = dir.path();
114     let before = &dir.join("before");
115     let before_dir = &before.join("dir");
116     fs::create_dir_all(before_dir).unwrap();
117     let archive = &dir.join(format!("archive.{}", merge_extensions(&ext, exts)));
118     let after = &dir.join("after");
119     create_random_files(before_dir, depth, &mut SmallRng::from_entropy());
120     ouch!("c", before_dir, archive);
121     ouch!("d", archive, "-d", after);
122     assert_same_directory(before, after, !matches!(ext, DirectoryExtension::Zip));