98 lines
3.4 KiB
Rust
98 lines
3.4 KiB
Rust
|
|
#![allow(dead_code, unused_imports, unused_variables, unused_macros, unreachable_patterns, unused_assignments, clippy::cfg)]
|
||
|
|
use hcie_blend::BlendMode;
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_normal_zero_opacity_identity() {
|
||
|
|
let dst = [128, 64, 32, 200];
|
||
|
|
let src = [255, 0, 0, 255];
|
||
|
|
let result = hcie_blend::blend_pixels(dst, src, BlendMode::Normal, 0.0);
|
||
|
|
assert_eq!(result, dst, "opacity=0 should return dst unchanged");
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_normal_full_opacity() {
|
||
|
|
let dst = [100, 100, 100, 255];
|
||
|
|
let src = [200, 50, 80, 255];
|
||
|
|
let result = hcie_blend::blend_pixels(dst, src, BlendMode::Normal, 1.0);
|
||
|
|
assert_eq!(result, src, "Normal+opacity=1 should output src");
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_opacity_zero_no_mutation_for_all_modes() {
|
||
|
|
let dst = [128, 64, 32, 255];
|
||
|
|
let src = [255, 0, 0, 255];
|
||
|
|
for mode in BlendMode::ALL {
|
||
|
|
if *mode == BlendMode::PassThrough { continue; }
|
||
|
|
let result = hcie_blend::blend_pixels(dst, src, *mode, 0.0);
|
||
|
|
assert_eq!(result, dst, "opacity=0 should return dst unchanged for {:?}", mode);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[rstest::rstest]
|
||
|
|
#[case(BlendMode::Multiply, [200, 100, 50, 255], [100, 100, 100, 255])]
|
||
|
|
#[case(BlendMode::Screen, [200, 100, 50, 255], [100, 100, 100, 255])]
|
||
|
|
#[case(BlendMode::Difference, [100, 200, 50, 255], [100, 150, 150, 255])]
|
||
|
|
#[case(BlendMode::Darken, [100, 200, 50, 255], [100, 100, 150, 255])]
|
||
|
|
#[case(BlendMode::Lighten, [100, 200, 50, 255], [150, 200, 150, 255])]
|
||
|
|
fn test_specific_blend_modes(
|
||
|
|
#[case] mode: BlendMode,
|
||
|
|
#[case] src: [u8; 4],
|
||
|
|
#[case] dst: [u8; 4],
|
||
|
|
) {
|
||
|
|
let result = hcie_blend::blend_pixels(dst, src, mode, 1.0);
|
||
|
|
assert!(
|
||
|
|
result[3] > 0 || (src[3] == 0 && dst[3] == 0),
|
||
|
|
"Blend result should have valid alpha for {:?}, got {:?}",
|
||
|
|
mode, result
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_transparent_src_normal() {
|
||
|
|
let dst = [128, 64, 32, 200];
|
||
|
|
let src = [0, 0, 0, 0];
|
||
|
|
let result = hcie_blend::blend_pixels(dst, src, BlendMode::Normal, 1.0);
|
||
|
|
assert_eq!(result, dst, "fully transparent src should leave dst unchanged");
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_all_modes_produce_valid_alpha() {
|
||
|
|
let dst = [100, 150, 200, 255];
|
||
|
|
let src = [50, 100, 200, 128];
|
||
|
|
for mode in BlendMode::ALL {
|
||
|
|
if *mode == BlendMode::PassThrough { continue; }
|
||
|
|
let _result = hcie_blend::blend_pixels(dst, src, *mode, 0.5);
|
||
|
|
// u8 values are always valid (0-255)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_multiply_darkens() {
|
||
|
|
let dst = [200, 200, 200, 255];
|
||
|
|
let src = [100, 100, 100, 255];
|
||
|
|
let result = hcie_blend::blend_pixels(dst, src, BlendMode::Multiply, 1.0);
|
||
|
|
assert!(result[0] <= 100, "Multiply should darken red channel");
|
||
|
|
}
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn test_screen_lightens() {
|
||
|
|
let dst = [100, 100, 100, 255];
|
||
|
|
let src = [200, 200, 200, 255];
|
||
|
|
let result = hcie_blend::blend_pixels(dst, src, BlendMode::Screen, 1.0);
|
||
|
|
assert!(result[0] > 100, "Screen should lighten red channel");
|
||
|
|
}
|
||
|
|
|
||
|
|
proptest::proptest! {
|
||
|
|
#[test]
|
||
|
|
fn identity_at_zero_opacity(dr: u8, dg: u8, db: u8, da: u8,
|
||
|
|
sr: u8, sg: u8, sb: u8, sa: u8) {
|
||
|
|
let dst = [dr, dg, db, if da == 0 { 1 } else { da }];
|
||
|
|
let src = [sr, sg, sb, if sa == 0 { 1 } else { sa }];
|
||
|
|
for mode in BlendMode::ALL {
|
||
|
|
if *mode == BlendMode::PassThrough { continue; }
|
||
|
|
let result = hcie_blend::blend_pixels(dst, src, *mode, 0.0);
|
||
|
|
proptest::prop_assert_eq!(result, dst, "opacity=0 identity failed for {:?}", mode);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|