Add an integration test

This commit is contained in:
Nbiba Bedis 2021-11-14 21:27:42 +01:00
parent ed68e17eb8
commit 7527014730
2 changed files with 63 additions and 1 deletions

View File

@ -1,7 +1,7 @@
#[macro_use]
mod utils;
use std::{iter::once, path::PathBuf};
use std::{io::Write, iter::once, path::PathBuf};
use fs_err as fs;
use parse_display::Display;
@ -120,3 +120,30 @@ fn multiple_files(
ouch!("d", archive, "-d", after);
assert_same_directory(before, after, !matches!(ext, DirectoryExtension::Zip));
}
#[test]
fn test_compress_decompress() {
let dir = tempdir().unwrap();
let dir = dir.path();
let i1 = dir.join("i1");
let o1 = dir.join("o1.tar");
std::fs::write(&i1, "ouch").unwrap();
assert!(ouch_interactive!("c", &i1, &dir.join("o1.tar")).0.wait().unwrap().success());
let (_ouch, mut sin, sout) = ouch_interactive!("d", &o1);
assert_eq!(sout.recv().unwrap(), "Do you want to overwrite 'i1'? [Y/n] ");
writeln!(&mut sin, "n").unwrap();
// This is the actual current behaviour for tar archives, if the user doesn't want to overwrite the file we just skip it
assert_eq!(sout.recv().unwrap(), "[INFO] Successfully decompressed archive in current directory.");
assert_eq!(sout.recv().unwrap(), "[INFO] Files unpacked: 0",);
let out = dir.join("out");
let (_ouch, _sin, sout) = ouch_interactive!("d", &o1, "-d", &out);
assert_eq!(sout.recv().unwrap(), format!("[INFO] directory {} created.", out.display()));
assert_eq!(sout.recv().unwrap(), format!("[INFO] \"{}\" extracted. (4.00 B)", out.join("i1").display()));
assert_eq!(sout.recv().unwrap(), format!("[INFO] Successfully decompressed archive in '{}'.", out.display()));
assert_eq!(sout.recv().unwrap(), "[INFO] Files unpacked: 1");
assert_eq!(std::fs::read(&dir.join("out/i1")).unwrap(), b"ouch");
}

View File

@ -3,6 +3,7 @@ use std::{io::Write, path::PathBuf};
use fs_err as fs;
use rand::RngCore;
/// Run ouch with cargo run
#[macro_export]
macro_rules! ouch {
($($e:expr),*) => {
@ -13,6 +14,40 @@ macro_rules! ouch {
}
}
/// Run ouch with cargo run and returns (child process, stdin handle and stdout channel receiver)
#[macro_export]
macro_rules! ouch_interactive {
($($e:expr),*) => {
{
let mut p = ::std::process::Command::new("cargo")
.stdin(::std::process::Stdio::piped())
.stdout(::std::process::Stdio::piped())
.arg("run")
.arg("--")
$(.arg($e))*
.spawn()
.unwrap();
let sin = p.stdin.take().unwrap();
let mut sout = p.stdout.take().unwrap();
let (tx, rx) = ::std::sync::mpsc::channel();
::std::thread::spawn(move ||{
// This thread/loop is used so we can make the output more deterministic
let mut s = [0; 1024];
loop {
let n = ::std::io::Read::read(&mut sout, &mut s).unwrap();
let s = ::std::string::String::from_utf8(s[..n].to_vec()).unwrap();
for l in s.lines() {
tx.send(l.to_string()).unwrap();
}
}
});
(p, sin, rx)
}
};
}
// write random content to a file
pub fn write_random_content(file: &mut impl Write, rng: &mut impl RngCore) {
let data = &mut Vec::with_capacity((rng.next_u32() % 8192) as usize);