mirror of
https://git.pumpin.online/funkpower/catena.git
synced 2026-10-23 19:27:14 +00:00
96 lines
3.1 KiB
Rust
96 lines
3.1 KiB
Rust
//! The tool as a caller meets it: files in, records and an exit code out.
|
|
|
|
use std::path::PathBuf;
|
|
use std::process::{Command, Output};
|
|
|
|
fn run(args: &[&str]) -> Output {
|
|
Command::new(env!("CARGO_BIN_EXE_booksniff"))
|
|
.args(args)
|
|
.output()
|
|
.expect("the binary should run")
|
|
}
|
|
|
|
fn written(name: &str, bytes: &[u8]) -> PathBuf {
|
|
let dir = std::env::temp_dir().join("booksniff-tests");
|
|
std::fs::create_dir_all(&dir).expect("a writable temp directory");
|
|
let path = dir.join(name);
|
|
std::fs::write(&path, bytes).expect("a writable path");
|
|
path
|
|
}
|
|
|
|
fn padded(head: &[u8]) -> Vec<u8> {
|
|
let mut out = head.to_vec();
|
|
out.resize(8192, b'x');
|
|
out
|
|
}
|
|
|
|
#[test]
|
|
fn a_file_it_recognises_comes_back_as_a_record() {
|
|
let path = written("book.pdf", &padded(b"%PDF-1.7\n"));
|
|
let out = run(&[path.to_str().expect("utf-8 path")]);
|
|
assert_eq!(out.status.code(), Some(0));
|
|
|
|
let doc: serde_json::Value = serde_json::from_slice(&out.stdout).expect("one JSON record");
|
|
assert_eq!(doc["kind"], "pdf");
|
|
assert_eq!(doc["declared_ext"], "pdf");
|
|
assert_eq!(doc["bytes"], 8192);
|
|
assert!(out.stderr.is_empty());
|
|
}
|
|
|
|
#[test]
|
|
fn a_file_it_cannot_place_answers_no() {
|
|
let path = written("mystery.bin", &padded(&[0x00, 0x01, 0x02]));
|
|
let out = run(&[path.to_str().expect("utf-8 path")]);
|
|
assert_eq!(out.status.code(), Some(1), "unknown must answer no");
|
|
let doc: serde_json::Value = serde_json::from_slice(&out.stdout).expect("one JSON record");
|
|
assert_eq!(doc["kind"], "unknown");
|
|
}
|
|
|
|
#[test]
|
|
fn several_files_come_back_as_several_records() {
|
|
let one = written("one.pdf", &padded(b"%PDF-1.7"));
|
|
let two = written("two.djvu", &padded(b"AT&TFORM"));
|
|
let out = run(&[
|
|
one.to_str().expect("utf-8 path"),
|
|
two.to_str().expect("utf-8 path"),
|
|
]);
|
|
let kinds: Vec<String> = String::from_utf8(out.stdout)
|
|
.expect("utf-8")
|
|
.lines()
|
|
.map(|line| {
|
|
serde_json::from_str::<serde_json::Value>(line).expect("valid JSON")["kind"].to_string()
|
|
})
|
|
.collect();
|
|
assert_eq!(kinds, ["\"pdf\"", "\"djvu\""]);
|
|
}
|
|
|
|
#[test]
|
|
fn a_file_that_is_not_there_is_an_io_error_and_the_rest_still_run() {
|
|
let path = written("kept.pdf", &padded(b"%PDF-1.7"));
|
|
let out = run(&[
|
|
"/definitely/not/here.pdf",
|
|
path.to_str().expect("utf-8 path"),
|
|
]);
|
|
assert_eq!(out.status.code(), Some(74));
|
|
assert!(!out.stderr.is_empty());
|
|
// The readable file was still identified, on stdout, uncontaminated.
|
|
let doc: serde_json::Value = serde_json::from_slice(&out.stdout).expect("one JSON record");
|
|
assert_eq!(doc["kind"], "pdf");
|
|
}
|
|
|
|
#[test]
|
|
fn the_plain_form_is_for_a_person() {
|
|
let path = written("lying.pdf", &padded(b"AT&TFORM"));
|
|
let out = run(&["--plain", path.to_str().expect("utf-8 path")]);
|
|
let said = String::from_utf8(out.stdout).expect("utf-8");
|
|
assert!(said.starts_with("djvu\t"), "{said}");
|
|
assert!(said.contains("named .pdf"), "{said}");
|
|
}
|
|
|
|
#[test]
|
|
fn no_files_named_is_a_usage_error() {
|
|
let out = run(&[]);
|
|
assert_eq!(out.status.code(), Some(64), "usage errors exit 64");
|
|
assert!(out.stdout.is_empty());
|
|
}
|