add ui snapshot tests

these tests are used to assert on Ouch's output for error reports and
progress logging
This commit is contained in:
João M. Bezerra 2023-09-15 22:42:23 -03:00 committed by João Marcos
parent c7f69194e8
commit 192eaca5dc
14 changed files with 394 additions and 16 deletions

141
Cargo.lock generated
View File

@ -52,7 +52,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
dependencies = [
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -62,7 +62,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd"
dependencies = [
"anstyle",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -266,6 +266,18 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "console"
version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"windows-sys 0.45.0",
]
[[package]]
name = "core_affinity"
version = "0.8.1"
@ -353,6 +365,12 @@ version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "errno"
version = "0.3.2"
@ -361,7 +379,7 @@ checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
dependencies = [
"errno-dragonfly",
"libc",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -389,7 +407,7 @@ dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -530,6 +548,19 @@ dependencies = [
"cfb",
]
[[package]]
name = "insta"
version = "1.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0770b0a3d4c70567f0d58331f3088b0e4c4f56c9b8d764efe654b4a5d46de3a"
dependencies = [
"console",
"lazy_static",
"linked-hash-map",
"similar",
"yaml-rust",
]
[[package]]
name = "is_executable"
version = "1.0.1"
@ -720,6 +751,7 @@ dependencies = [
"gzp",
"ignore",
"infer",
"insta",
"is_executable",
"libc",
"linked-hash-map",
@ -991,7 +1023,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -1027,6 +1059,12 @@ version = "1.0.185"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be9b6f69f1dfd54c3b568ffa45c310d6973a5e5148fd40cf515acaf38cf5bc31"
[[package]]
name = "similar"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
[[package]]
name = "snap"
version = "1.1.0"
@ -1109,7 +1147,7 @@ dependencies = [
"fastrand",
"redox_syscall",
"rustix",
"windows-sys",
"windows-sys 0.48.0",
]
[[package]]
@ -1327,13 +1365,37 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets 0.42.2",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
"windows-targets 0.48.1",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm 0.42.2",
"windows_aarch64_msvc 0.42.2",
"windows_i686_gnu 0.42.2",
"windows_i686_msvc 0.42.2",
"windows_x86_64_gnu 0.42.2",
"windows_x86_64_gnullvm 0.42.2",
"windows_x86_64_msvc 0.42.2",
]
[[package]]
@ -1342,51 +1404,93 @@ version = "0.48.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
"windows_aarch64_gnullvm 0.48.0",
"windows_aarch64_msvc 0.48.0",
"windows_i686_gnu 0.48.0",
"windows_i686_msvc 0.48.0",
"windows_x86_64_gnu 0.48.0",
"windows_x86_64_gnullvm 0.48.0",
"windows_x86_64_msvc 0.48.0",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.0"
@ -1411,6 +1515,15 @@ dependencies = [
"lzma-sys",
]
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "zip"
version = "0.6.6"

View File

@ -45,6 +45,7 @@ clap_mangen = "0.2.13"
[dev-dependencies]
assert_cmd = "2.0.12"
infer = "0.15.0"
insta = "1.31.0"
parse-display = "0.8.2"
proptest = "1.2.0"
rand = { version = "0.8.5", default-features = false, features = ["small_rng", "std"] }

View File

@ -0,0 +1,14 @@
---
source: tests/ui.rs
expression: "run_ouch(\"ouch compress input output\", dir)"
---
[ERROR] Cannot compress to 'output'.
- You shall supply the compression format
hint: Try adding supported extensions (see --help):
hint: ouch compress <FILES>... output.tar.gz
hint: ouch compress <FILES>... output.zip
hint:
hint: Alternatively, you can overwrite this option by using the '--format' flag:
hint: ouch compress <FILES>... output --format tar.gz

View File

@ -0,0 +1,14 @@
---
source: tests/ui.rs
expression: "run_ouch(\"ouch decompress a\", dir)"
---
[ERROR] Cannot decompress files without extensions
- Files without supported extensions: <FOLDER>/a
- Decompression formats are detected automatically by the file extension
hint: Provide a file with a supported extension:
hint: ouch decompress example.tar.gz
hint:
hint: Or overwrite this option with the '--format' flag:
hint: ouch decompress <FOLDER>/a --format tar.gz

View File

@ -0,0 +1,7 @@
---
source: tests/ui.rs
expression: "run_ouch(\"ouch decompress a b\", dir)"
---
[ERROR] failed to canonicalize path `a`
- File not found

View File

@ -0,0 +1,7 @@
---
source: tests/ui.rs
expression: "run_ouch(\"ouch list a b\", dir)"
---
[ERROR] failed to canonicalize path `a`
- File not found

View File

@ -0,0 +1,7 @@
---
source: tests/ui.rs
expression: "run_ouch(\"ouch compress a b\", dir)"
---
[ERROR] failed to canonicalize path `a`
- File not found

View File

@ -0,0 +1,6 @@
---
source: tests/ui.rs
expression: "run_ouch(\"ouch compress input output.gz\", dir)"
---
[INFO] Successfully compressed 'output.gz'.

View File

@ -0,0 +1,7 @@
---
source: tests/ui.rs
expression: "run_ouch(\"ouch compress input output.zip\", dir)"
---
[INFO] Compressing 'input'.
[INFO] Successfully compressed 'output.zip'.

View File

@ -0,0 +1,8 @@
---
source: tests/ui.rs
expression: "run_ouch(\"ouch decompress output.zst\", dir)"
---
[INFO] Failed to confirm the format of `output` by sniffing the contents, file might be misnamed
[INFO] Successfully decompressed archive in current directory.
[INFO] Files unpacked: 1

View File

@ -0,0 +1,25 @@
---
source: tests/ui.rs
expression: "output_to_string(ouch!(\"-h\"))"
---
A command-line utility for easily compressing and decompressing files and directories.
Usage: ouch [OPTIONS] <COMMAND>
Commands:
compress Compress one or more files into one output file [aliases: c]
decompress Decompresses one or more files, optionally into another folder [aliases: d]
list List contents of an archive [aliases: l, ls]
help Print this message or the help of the given subcommand(s)
Options:
-y, --yes Skip [Y/n] questions positively
-n, --no Skip [Y/n] questions negatively
-A, --accessible Activate accessibility mode, reducing visual noise [env: ACCESSIBLE=]
-H, --hidden Ignores hidden files
-q, --quiet Silences output
-g, --gitignore Ignores files matched by git's ignore files
-f, --format <FORMAT> Specify the format of the archive
-h, --help Print help (see more with '--help')
-V, --version Print version

View File

@ -0,0 +1,48 @@
---
source: tests/ui.rs
expression: "output_to_string(ouch!(\"--help\"))"
---
A command-line utility for easily compressing and decompressing files and directories.
Supported formats: tar, zip, gz, xz/lzma, bz/bz2, lz4, sz, zst.
Repository: https://github.com/ouch-org/ouch
Usage: ouch [OPTIONS] <COMMAND>
Commands:
compress Compress one or more files into one output file [aliases: c]
decompress Decompresses one or more files, optionally into another folder [aliases: d]
list List contents of an archive [aliases: l, ls]
help Print this message or the help of the given subcommand(s)
Options:
-y, --yes
Skip [Y/n] questions positively
-n, --no
Skip [Y/n] questions negatively
-A, --accessible
Activate accessibility mode, reducing visual noise
[env: ACCESSIBLE=]
-H, --hidden
Ignores hidden files
-q, --quiet
Silences output
-g, --gitignore
Ignores files matched by git's ignore files
-f, --format <FORMAT>
Specify the format of the archive
-h, --help
Print help (see a summary with '-h')
-V, --version
Print version

100
tests/ui.rs Normal file
View File

@ -0,0 +1,100 @@
// Snapshot tests for Ouch's output.
#[macro_use]
mod utils;
use std::{io, path::Path, process::Output};
use insta::assert_display_snapshot as ui;
use crate::utils::run_in;
fn testdir() -> io::Result<(tempfile::TempDir, &'static Path)> {
let dir = tempfile::tempdir()?;
let path = dir.path().to_path_buf().into_boxed_path();
Ok((dir, Box::leak(path)))
}
fn run_ouch(argv: &str, dir: &Path) -> String {
let output = utils::cargo_bin()
.args(argv.split_whitespace().skip(1))
.current_dir(dir)
.output()
.unwrap_or_else(|err| {
panic!(
"Failed to run command\n\
argv: {argv}\n\
path: {dir:?}\n\
err: {err}"
)
});
redact_paths(&output_to_string(output), dir)
}
// remove random tempdir paths from snapshots to make them deterministic
fn redact_paths(text: &str, path: &Path) -> String {
let path = format!("{}/", path.display());
text.replace(&path, "<FOLDER>/")
}
fn output_to_string(output: Output) -> String {
String::from_utf8(output.stdout).unwrap() + std::str::from_utf8(&output.stderr).unwrap()
}
#[test]
fn ui_test_err_compress_missing_extension() {
let (_dropper, dir) = testdir().unwrap();
// prepare
run_in(dir, "touch", "input").unwrap();
ui!(run_ouch("ouch compress input output", dir));
}
#[test]
fn ui_test_err_decompress_missing_extension() {
let (_dropper, dir) = testdir().unwrap();
run_in(dir, "touch", "a").unwrap();
ui!(run_ouch("ouch decompress a", dir));
}
#[test]
fn ui_test_err_missing_files() {
let (_dropper, dir) = testdir().unwrap();
ui!(run_ouch("ouch compress a b", dir));
ui!(run_ouch("ouch decompress a b", dir));
ui!(run_ouch("ouch list a b", dir));
}
#[test]
fn ui_test_ok_compress() {
let (_dropper, dir) = testdir().unwrap();
// prepare
run_in(dir, "touch", "input").unwrap();
ui!(run_ouch("ouch compress input output.zip", dir));
ui!(run_ouch("ouch compress input output.gz", dir));
}
#[test]
fn ui_test_ok_decompress() {
let (_dropper, dir) = testdir().unwrap();
// prepare
run_in(dir, "touch", "input").unwrap();
run_ouch("ouch compress input output.zst", dir);
ui!(run_ouch("ouch decompress output.zst", dir));
}
#[test]
fn ui_test_usage_help_flag() {
ui!(output_to_string(ouch!("--help")));
ui!(output_to_string(ouch!("-h")));
}

View File

@ -1,16 +1,27 @@
use std::{env, io::Write, path::PathBuf};
// This warning is unavoidable when reusing testing utils.
#![allow(dead_code)]
use std::{
env,
ffi::OsStr,
io,
io::Write,
path::{Path, PathBuf},
process::Output,
};
use assert_cmd::Command;
use fs_err as fs;
use rand::{Rng, RngCore};
// Run ouch with the provided arguments, returns `assert_cmd::Output`
#[macro_export]
macro_rules! ouch {
($($e:expr),*) => {
$crate::utils::cargo_bin()
$(.arg($e))*
.arg("--yes")
.unwrap();
.unwrap()
}
}
@ -27,6 +38,16 @@ pub fn cargo_bin() -> Command {
.unwrap_or_else(|| Command::cargo_bin("ouch").expect("Failed to find ouch executable"))
}
/// Run a command inside of another folder.
///
/// example: `run_in("/tmp", "touch", "a b c")`
pub fn run_in(folder: impl AsRef<Path>, bin: impl AsRef<OsStr>, args: &str) -> io::Result<Output> {
Command::new(bin)
.args(args.split_whitespace())
.current_dir(folder)
.output()
}
// write random content to a file
pub fn write_random_content(file: &mut impl Write, rng: &mut impl RngCore) {
let mut data = Vec::new();