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.
246 lines
5.9 KiB
Rust
246 lines
5.9 KiB
Rust
use pixstrip_core::operations::watermark::calculate_position;
|
|
use pixstrip_core::operations::WatermarkPosition;
|
|
use pixstrip_core::types::Dimensions;
|
|
|
|
#[test]
|
|
fn position_top_left() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::TopLeft,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
10,
|
|
);
|
|
assert_eq!(x, 10);
|
|
assert_eq!(y, 10);
|
|
}
|
|
|
|
#[test]
|
|
fn position_center() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::Center,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
10,
|
|
);
|
|
assert_eq!(x, 860); // (1920 - 200) / 2
|
|
assert_eq!(y, 515); // (1080 - 50) / 2
|
|
}
|
|
|
|
#[test]
|
|
fn position_bottom_right() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::BottomRight,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
10,
|
|
);
|
|
assert_eq!(x, 1710); // 1920 - 200 - 10
|
|
assert_eq!(y, 1020); // 1080 - 50 - 10
|
|
}
|
|
|
|
#[test]
|
|
fn position_top_center() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::TopCenter,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
10,
|
|
);
|
|
assert_eq!(x, 860); // (1920 - 200) / 2
|
|
assert_eq!(y, 10);
|
|
}
|
|
|
|
#[test]
|
|
fn position_bottom_center() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::BottomCenter,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
10,
|
|
);
|
|
assert_eq!(x, 860);
|
|
assert_eq!(y, 1020);
|
|
}
|
|
|
|
#[test]
|
|
fn position_middle_left() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::MiddleLeft,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
10,
|
|
);
|
|
assert_eq!(x, 10);
|
|
assert_eq!(y, 515);
|
|
}
|
|
|
|
#[test]
|
|
fn position_middle_right() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::MiddleRight,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
10,
|
|
);
|
|
assert_eq!(x, 1710);
|
|
assert_eq!(y, 515);
|
|
}
|
|
|
|
#[test]
|
|
fn position_top_right() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::TopRight,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
10,
|
|
);
|
|
assert_eq!(x, 1710);
|
|
assert_eq!(y, 10);
|
|
}
|
|
|
|
#[test]
|
|
fn position_bottom_left() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::BottomLeft,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
10,
|
|
);
|
|
assert_eq!(x, 10);
|
|
assert_eq!(y, 1020);
|
|
}
|
|
|
|
// --- Margin variation tests ---
|
|
|
|
#[test]
|
|
fn margin_zero_top_left() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::TopLeft,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
0,
|
|
);
|
|
assert_eq!(x, 0);
|
|
assert_eq!(y, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn margin_zero_bottom_right() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::BottomRight,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
0,
|
|
);
|
|
assert_eq!(x, 1720); // 1920 - 200
|
|
assert_eq!(y, 1030); // 1080 - 50
|
|
}
|
|
|
|
#[test]
|
|
fn large_margin_top_left() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::TopLeft,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
100,
|
|
);
|
|
assert_eq!(x, 100);
|
|
assert_eq!(y, 100);
|
|
}
|
|
|
|
#[test]
|
|
fn large_margin_bottom_right() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::BottomRight,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
100,
|
|
);
|
|
assert_eq!(x, 1620); // 1920 - 200 - 100
|
|
assert_eq!(y, 930); // 1080 - 50 - 100
|
|
}
|
|
|
|
#[test]
|
|
fn margin_does_not_affect_center() {
|
|
let (x1, y1) = calculate_position(
|
|
WatermarkPosition::Center,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
0,
|
|
);
|
|
let (x2, y2) = calculate_position(
|
|
WatermarkPosition::Center,
|
|
Dimensions { width: 1920, height: 1080 },
|
|
Dimensions { width: 200, height: 50 },
|
|
100,
|
|
);
|
|
assert_eq!(x1, x2);
|
|
assert_eq!(y1, y2);
|
|
}
|
|
|
|
// --- Edge case tests ---
|
|
|
|
#[test]
|
|
fn watermark_larger_than_image() {
|
|
// Watermark is bigger than the image - should not panic, saturating_sub clamps to 0
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::BottomRight,
|
|
Dimensions { width: 100, height: 100 },
|
|
Dimensions { width: 200, height: 200 },
|
|
10,
|
|
);
|
|
// (100 - 200 - 10) saturates to 0
|
|
assert_eq!(x, 0);
|
|
assert_eq!(y, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn watermark_exact_image_size() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::Center,
|
|
Dimensions { width: 200, height: 100 },
|
|
Dimensions { width: 200, height: 100 },
|
|
0,
|
|
);
|
|
assert_eq!(x, 0);
|
|
assert_eq!(y, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn zero_size_image() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::Center,
|
|
Dimensions { width: 0, height: 0 },
|
|
Dimensions { width: 200, height: 50 },
|
|
10,
|
|
);
|
|
assert_eq!(x, 0);
|
|
assert_eq!(y, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn margin_exceeds_available_space() {
|
|
// Margin is huge relative to image size
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::BottomRight,
|
|
Dimensions { width: 100, height: 100 },
|
|
Dimensions { width: 50, height: 50 },
|
|
200,
|
|
);
|
|
// saturating_sub: 100 - 50 - 200 = 0
|
|
assert_eq!(x, 0);
|
|
assert_eq!(y, 0);
|
|
}
|
|
|
|
#[test]
|
|
fn one_pixel_image() {
|
|
let (x, y) = calculate_position(
|
|
WatermarkPosition::TopLeft,
|
|
Dimensions { width: 1, height: 1 },
|
|
Dimensions { width: 1, height: 1 },
|
|
0,
|
|
);
|
|
assert_eq!(x, 0);
|
|
assert_eq!(y, 0);
|
|
}
|