use std::path::Path;
use std::process::Command;
use image::{ImageBuffer, ImageReader, Rgb, RgbImage};
use tempfile::TempDir;
const FIXTURE_W: u32 = 16;
const FIXTURE_H: u32 = 16;
fn make_fixture(path: &Path) {
let img: RgbImage = ImageBuffer::from_fn(FIXTURE_W, FIXTURE_H, |x, y| {
Rgb([(x * 16) as u8, (y * 16) as u8, 128])
});
img.save(path).expect("write fixture");
}
fn run_crapify(args: &[&str]) -> std::process::ExitStatus {
Command::new(env!("CARGO_BIN_EXE_crapify"))
.args(args)
.status()
.expect("spawn crapify")
}
fn decode_dimensions(path: &Path) -> (u32, u32) {
let img = ImageReader::open(path)
.expect("open output")
.with_guessed_format()
.expect("guess output format")
.decode()
.expect("decode output");
(img.width(), img.height())
}
#[test]
fn deep_fry_raw_preset_round_trips() {
let dir = TempDir::new().expect("create tempdir");
let input = dir.path().join("in.png");
let output = dir.path().join("out.png");
make_fixture(&input);
let status = run_crapify(&[
"deep-fry",
"--preset",
"raw",
input.to_str().unwrap(),
output.to_str().unwrap(),
]);
assert!(status.success(), "crapify exited non-zero: {status:?}");
assert!(output.exists(), "output file was not created");
assert_eq!(decode_dimensions(&output), (FIXTURE_W, FIXTURE_H));
}
#[test]
fn palettecrush_geocities_preset_round_trips() {
let dir = TempDir::new().expect("create tempdir");
let input = dir.path().join("in.png");
let output = dir.path().join("out.png");
make_fixture(&input);
let status = run_crapify(&[
"palettecrush",
"--preset",
"geocities",
input.to_str().unwrap(),
output.to_str().unwrap(),
]);
assert!(status.success(), "crapify exited non-zero: {status:?}");
assert!(output.exists(), "output file was not created");
assert_eq!(decode_dimensions(&output), (FIXTURE_W, FIXTURE_H));
}
#[test]
fn palettecrush_adaptive_colors_round_trips() {
let dir = TempDir::new().expect("create tempdir");
let input = dir.path().join("in.png");
let output = dir.path().join("out.png");
make_fixture(&input);
let status = run_crapify(&[
"palettecrush",
"--colors",
"4",
"--dither",
"none",
input.to_str().unwrap(),
output.to_str().unwrap(),
]);
assert!(status.success(), "crapify exited non-zero: {status:?}");
assert!(output.exists(), "output file was not created");
assert_eq!(decode_dimensions(&output), (FIXTURE_W, FIXTURE_H));
}
fn run_xerox_smoke(extra_args: &[&str]) {
let dir = TempDir::new().expect("create tempdir");
let input = dir.path().join("in.png");
let output = dir.path().join("out.png");
make_fixture(&input);
let input_s = input.to_str().unwrap();
let output_s = output.to_str().unwrap();
let mut args = vec!["xerox"];
args.extend_from_slice(extra_args);
args.push(input_s);
args.push(output_s);
let status = run_crapify(&args);
assert!(status.success(), "crapify exited non-zero: {status:?}");
assert!(output.exists(), "output file was not created");
assert_eq!(decode_dimensions(&output), (FIXTURE_W, FIXTURE_H));
}
#[test]
fn xerox_decent_copy_preset_round_trips() {
run_xerox_smoke(&["--preset", "decent-copy"]);
}
#[test]
fn xerox_staff_meeting_handout_preset_round_trips() {
run_xerox_smoke(&["--preset", "staff-meeting-handout"]);
}
#[test]
fn xerox_fax_with_end_of_chain_threshold_round_trips() {
run_xerox_smoke(&[
"--preset",
"from-a-fax-from-1994",
"--threshold-timing",
"end-of-chain",
]);
}
#[test]
fn xerox_from_a_fax_from_1994_preset_round_trips() {
run_xerox_smoke(&["--preset", "from-a-fax-from-1994"]);
}
fn run_webcam_smoke(extra_args: &[&str]) {
let dir = TempDir::new().expect("create tempdir");
let input = dir.path().join("in.png");
let output = dir.path().join("out.png");
make_fixture(&input);
let input_s = input.to_str().unwrap();
let output_s = output.to_str().unwrap();
let mut args = vec!["webcam-1999"];
args.extend_from_slice(extra_args);
args.push(input_s);
args.push(output_s);
let status = run_crapify(&args);
assert!(status.success(), "crapify exited non-zero: {status:?}");
assert!(output.exists(), "output file was not created");
assert_eq!(decode_dimensions(&output), (FIXTURE_W, FIXTURE_H));
}
#[test]
fn webcam_1999_default_round_trips() {
run_webcam_smoke(&[]);
}
#[test]
fn webcam_1999_quickcam_vc_preset_round_trips() {
run_webcam_smoke(&["--preset", "quickcam-vc"]);
}
#[test]
fn webcam_1999_aim_buddy_preset_round_trips() {
run_webcam_smoke(&["--preset", "aim-buddy"]);
}
#[test]
fn webcam_1999_parents_bought_the_cheap_one_preset_round_trips() {
run_webcam_smoke(&["--preset", "parents-bought-the-cheap-one"]);
}
#[test]
fn webcam_1999_preserve_aspect_flag_round_trips() {
run_webcam_smoke(&["--preset", "aim-buddy", "--preserve-aspect"]);
}
#[test]
fn webcam_1999_tint_override_round_trips() {
run_webcam_smoke(&["--preset", "aim-buddy", "--tint", "#ff8866"]);
}
#[test]
fn format_override_writes_png_to_bin_extension() {
let dir = TempDir::new().expect("create tempdir");
let input = dir.path().join("in.png");
let output = dir.path().join("out.bin");
make_fixture(&input);
let status = run_crapify(&[
"--format",
"png",
"deep-fry",
"--preset",
"raw",
input.to_str().unwrap(),
output.to_str().unwrap(),
]);
assert!(status.success(), "crapify exited non-zero: {status:?}");
assert!(output.exists(), "output file was not created");
assert_eq!(decode_dimensions(&output), (FIXTURE_W, FIXTURE_H));
}