#![cfg(test)]
#![allow(missing_docs)]
use assert_cmd::Command;
use assert_fs::prelude::*;
use assert_fs::TempDir;
use predicates::prelude::*;
use rstest::rstest;
use rstest_reuse::{self, apply, template};
use std::ffi::OsString;
use test_binary::build_test_binary_once;
build_test_binary_once!(linelen, "tests/bins");
build_test_binary_once!(revbytes, "tests/bins");
build_test_binary_once!(revchars, "tests/bins");
build_test_binary_once!(tokio_linelen, "tests/bins");
build_test_binary_once!(tokio_revbytes, "tests/bins");
build_test_binary_once!(tokio_revchars, "tests/bins");
enum PathPolicy {
Default,
Hyphen,
Path,
}
struct IOPolicy {
input: PathPolicy,
output: PathPolicy,
}
impl IOPolicy {
fn run<S: ?Sized + AsRef<[u8]>>(
&self,
cmdpath: OsString,
input: &'static S,
output: &'static S,
) {
let input: &'static [u8] = input.as_ref();
let output: &'static [u8] = output.as_ref();
let mut cmd = Command::new(cmdpath);
let tmpdir = TempDir::new().unwrap();
let outfile = match self.output {
PathPolicy::Default => None,
PathPolicy::Hyphen => {
cmd.arg("-o-");
None
}
PathPolicy::Path => {
let tmpfile = tmpdir.child("output.dat");
cmd.arg("--outfile").arg(tmpfile.path());
Some(tmpfile)
}
};
let infile = match self.input {
PathPolicy::Default => {
cmd.write_stdin(input);
None
}
PathPolicy::Hyphen => {
cmd.arg("-").write_stdin(input);
None
}
PathPolicy::Path => {
let tmpfile = tmpdir.child("input.dat");
tmpfile.write_binary(input).unwrap();
cmd.arg(tmpfile.path());
Some(tmpfile)
}
};
let r = cmd.assert().success();
if let Some(p) = infile {
p.assert(input);
}
match outfile {
Some(p) => {
p.assert(output);
}
None => {
r.stdout(predicate::eq(output));
}
}
}
}
#[template]
#[rstest]
#[test]
#[case(IOPolicy {input: PathPolicy::Default, output: PathPolicy::Default})]
#[case(IOPolicy {input: PathPolicy::Default, output: PathPolicy::Hyphen})]
#[case(IOPolicy {input: PathPolicy::Default, output: PathPolicy::Path})]
#[case(IOPolicy {input: PathPolicy::Hyphen, output: PathPolicy::Default})]
#[case(IOPolicy {input: PathPolicy::Hyphen, output: PathPolicy::Hyphen})]
#[case(IOPolicy {input: PathPolicy::Hyphen, output: PathPolicy::Path})]
#[case(IOPolicy {input: PathPolicy::Path, output: PathPolicy::Default})]
#[case(IOPolicy {input: PathPolicy::Path, output: PathPolicy::Hyphen})]
#[case(IOPolicy {input: PathPolicy::Path, output: PathPolicy::Path})]
fn policies(#[case] policy: IOPolicy) {}
#[apply(policies)]
fn test_lines_and_create(#[case] policy: IOPolicy) {
policy.run(
path_to_linelen(),
concat!(
"1\n",
"To\n",
"Tre\n",
"Four\n",
"The longest line in the file\n",
"\n",
"Goodbye\n",
),
"1\n2\n3\n4\n28\n0\n7\n",
);
}
#[apply(policies)]
fn test_read_and_write(#[case] policy: IOPolicy) {
policy.run(
path_to_revbytes(),
&b"\x1F\x8B\x08\x08\x0B\xC1\xA0\x62\x00\x03\x68\x69\x2E\x74\x78\x74\x00\xF3\xC8\xE4\x02\x00\x9A\x3C\x22\xD5\x03\x00\x00\x00"[..],
&b"\x00\x00\x00\x03\xd5\x22\x3C\x9a\x00\x02\xe4\xc8\xf3\x00\x74\x78\x74\x2e\x69\x68\x03\x00\x62\xa0\xc1\x0b\x08\x08\x8b\x1f"[..],
);
}
#[apply(policies)]
fn test_read_to_string_and_write(#[case] policy: IOPolicy) {
policy.run(
path_to_revchars(),
concat!(
"In Xanadu did Kubla Khan\n",
"A stately pleasure-dome decree:\n",
"Where Alph, the sacred river, ran\n",
"Through caverns measureless to man\n",
"\tDown to a sunless sea.\n",
),
concat!(
"\n.aes sselnus a ot nwoD\t",
"\nnam ot sselerusaem snrevac hguorhT",
"\nnar ,revir dercas eht ,hplA erehW",
"\n:eerced emod-erusaelp yletats A",
"\nnahK albuK did udanaX nI",
),
);
}
#[apply(policies)]
fn test_tokio_lines_and_create(#[case] policy: IOPolicy) {
policy.run(
path_to_tokio_linelen(),
concat!(
"1\n",
"To\n",
"Tre\n",
"Four\n",
"The longest line in the file\n",
"\n",
"Goodbye\n",
),
"1\n2\n3\n4\n28\n0\n7\n",
);
}
#[apply(policies)]
fn test_tokio_read_and_write(#[case] policy: IOPolicy) {
policy.run(
path_to_tokio_revbytes(),
&b"\x1F\x8B\x08\x08\x0B\xC1\xA0\x62\x00\x03\x68\x69\x2E\x74\x78\x74\x00\xF3\xC8\xE4\x02\x00\x9A\x3C\x22\xD5\x03\x00\x00\x00"[..],
&b"\x00\x00\x00\x03\xd5\x22\x3C\x9a\x00\x02\xe4\xc8\xf3\x00\x74\x78\x74\x2e\x69\x68\x03\x00\x62\xa0\xc1\x0b\x08\x08\x8b\x1f"[..],
);
}
#[apply(policies)]
fn test_tokio_read_to_string_and_write(#[case] policy: IOPolicy) {
policy.run(
path_to_tokio_revchars(),
concat!(
"In Xanadu did Kubla Khan\n",
"A stately pleasure-dome decree:\n",
"Where Alph, the sacred river, ran\n",
"Through caverns measureless to man\n",
"\tDown to a sunless sea.\n",
),
concat!(
"\n.aes sselnus a ot nwoD\t",
"\nnam ot sselerusaem snrevac hguorhT",
"\nnar ,revir dercas eht ,hplA erehW",
"\n:eerced emod-erusaelp yletats A",
"\nnahK albuK did udanaX nI",
),
);
}