Fix 26 bugs, edge cases, and consistency issues from fifth audit pass
Critical: undo toast now trashes only batch output files (not entire dir), JPEG scanline write errors propagated, selective metadata write result returned. High: zero-dimension guards in ResizeConfig/fit_within, negative aspect ratio rejection, FM integration toggle infinite recursion guard, saturating counter arithmetic in executor. Medium: PNG compression level passed to oxipng, pct mode updates job_config, external file loading updates step indicator, CLI undo removes history entries, watch config write failures reported, fast-copy path reads image dimensions for rename templates, discovery excludes unprocessable formats (heic/svg/ico/jxl), CLI warns on invalid algorithm/overwrite values, resolve_collision trailing dot fix, generation guards on all preview threads to cancel stale results, default DPI aligned to 0, watermark text width uses char count not byte length. Low: binary path escaped in Nautilus extension, file dialog filter aligned with discovery, reset_wizard clears preset_mode and output_dir.
This commit is contained in:
145
pixstrip-core/tests/adjustments_tests.rs
Normal file
145
pixstrip-core/tests/adjustments_tests.rs
Normal file
@@ -0,0 +1,145 @@
|
||||
use pixstrip_core::operations::AdjustmentsConfig;
|
||||
use pixstrip_core::operations::adjustments::apply_adjustments;
|
||||
use image::DynamicImage;
|
||||
|
||||
fn noop_config() -> AdjustmentsConfig {
|
||||
AdjustmentsConfig {
|
||||
brightness: 0,
|
||||
contrast: 0,
|
||||
saturation: 0,
|
||||
sharpen: false,
|
||||
grayscale: false,
|
||||
sepia: false,
|
||||
crop_aspect_ratio: None,
|
||||
trim_whitespace: false,
|
||||
canvas_padding: 0,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_noop_default() {
|
||||
assert!(noop_config().is_noop());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_noop_with_brightness() {
|
||||
let mut config = noop_config();
|
||||
config.brightness = 10;
|
||||
assert!(!config.is_noop());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_noop_with_sharpen() {
|
||||
let mut config = noop_config();
|
||||
config.sharpen = true;
|
||||
assert!(!config.is_noop());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_noop_with_crop() {
|
||||
let mut config = noop_config();
|
||||
config.crop_aspect_ratio = Some((16.0, 9.0));
|
||||
assert!(!config.is_noop());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_noop_with_trim() {
|
||||
let mut config = noop_config();
|
||||
config.trim_whitespace = true;
|
||||
assert!(!config.is_noop());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_noop_with_padding() {
|
||||
let mut config = noop_config();
|
||||
config.canvas_padding = 20;
|
||||
assert!(!config.is_noop());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_noop_with_grayscale() {
|
||||
let mut config = noop_config();
|
||||
config.grayscale = true;
|
||||
assert!(!config.is_noop());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_noop_with_sepia() {
|
||||
let mut config = noop_config();
|
||||
config.sepia = true;
|
||||
assert!(!config.is_noop());
|
||||
}
|
||||
|
||||
// --- crop_to_aspect_ratio edge cases ---
|
||||
|
||||
fn make_test_image(w: u32, h: u32) -> DynamicImage {
|
||||
DynamicImage::ImageRgba8(image::RgbaImage::from_pixel(w, h, image::Rgba([128, 128, 128, 255])))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crop_zero_ratio_returns_original() {
|
||||
let img = make_test_image(100, 100);
|
||||
let config = AdjustmentsConfig {
|
||||
crop_aspect_ratio: Some((0.0, 9.0)),
|
||||
..noop_config()
|
||||
};
|
||||
let result = apply_adjustments(img, &config).unwrap();
|
||||
assert_eq!(result.width(), 100);
|
||||
assert_eq!(result.height(), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crop_zero_height_ratio_returns_original() {
|
||||
let img = make_test_image(100, 100);
|
||||
let config = AdjustmentsConfig {
|
||||
crop_aspect_ratio: Some((16.0, 0.0)),
|
||||
..noop_config()
|
||||
};
|
||||
let result = apply_adjustments(img, &config).unwrap();
|
||||
assert_eq!(result.width(), 100);
|
||||
assert_eq!(result.height(), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crop_square_on_landscape() {
|
||||
let img = make_test_image(200, 100);
|
||||
let config = AdjustmentsConfig {
|
||||
crop_aspect_ratio: Some((1.0, 1.0)),
|
||||
..noop_config()
|
||||
};
|
||||
let result = apply_adjustments(img, &config).unwrap();
|
||||
assert_eq!(result.width(), 100);
|
||||
assert_eq!(result.height(), 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crop_16_9_on_square() {
|
||||
let img = make_test_image(100, 100);
|
||||
let config = AdjustmentsConfig {
|
||||
crop_aspect_ratio: Some((16.0, 9.0)),
|
||||
..noop_config()
|
||||
};
|
||||
let result = apply_adjustments(img, &config).unwrap();
|
||||
assert_eq!(result.width(), 100);
|
||||
assert_eq!(result.height(), 56);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn canvas_padding_large_value() {
|
||||
let img = make_test_image(10, 10);
|
||||
let config = AdjustmentsConfig {
|
||||
canvas_padding: 500,
|
||||
..noop_config()
|
||||
};
|
||||
let result = apply_adjustments(img, &config).unwrap();
|
||||
assert_eq!(result.width(), 1010);
|
||||
assert_eq!(result.height(), 1010);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn noop_config_returns_same_dimensions() {
|
||||
let img = make_test_image(200, 100);
|
||||
let result = apply_adjustments(img, &noop_config()).unwrap();
|
||||
assert_eq!(result.width(), 200);
|
||||
assert_eq!(result.height(), 100);
|
||||
}
|
||||
Reference in New Issue
Block a user