From a9cde41de82e47156ddb9e3adfa10073c462acc2 Mon Sep 17 00:00:00 2001 From: xfy Date: Mon, 15 Jun 2026 11:18:55 +0800 Subject: [PATCH] =?UTF-8?q?test(webp):=20=E6=89=A9=E5=85=85=20WebP=20?= =?UTF-8?q?=E7=BC=96=E8=A7=A3=E7=A0=81=E6=B5=8B=E8=AF=95=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原仅 6 个测试,补充后覆盖: - WebpError 的 Display 格式与 std::error::Error trait 约束 - encode 对非快速路径像素格式(Luma8 / LumaA8)的 RGBA 转换 - encode 质量参数对体积的单调性(低质量 <= 高质量) - decode 对非法字节流与空输入的错误处理(不 panic) - decode 错误信息带 'WebP decode error' 前缀便于排查 - 编解码往返保持图像尺寸不变 共 17 个测试,全部通过。 --- src/webp.rs | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/src/webp.rs b/src/webp.rs index 1056587..ac2aacc 100644 --- a/src/webp.rs +++ b/src/webp.rs @@ -237,4 +237,101 @@ mod tests { assert_eq!(0u8.clamp(0, 6), 0); assert_eq!(6u8.clamp(0, 6), 6); } + + #[test] + fn webp_error_encode_display() { + let err = WebpError::Encode("boom".to_string()); + assert_eq!(err.to_string(), "WebP encode error: boom"); + } + + #[test] + fn webp_error_decode_display() { + let err = WebpError::Decode("busted".to_string()); + assert_eq!(err.to_string(), "WebP decode error: busted"); + } + + #[test] + fn webp_error_implements_std_error() { + // WebpError 必须实现 std::error::Error,才能在 ? 传播链中使用。 + fn assert_error() {} + assert_error::(); + } + + #[test] + fn encode_converts_luma8_to_rgba() { + // Luma8(灰度)图像不在 encode 的快速路径中,应被转换为 RGBA8 后编码。 + let img = image::DynamicImage::new_luma8(4, 4); + let result = encode(&img, 80.0, 2); + assert!(result.is_ok()); + assert!(!result.unwrap().is_empty()); + } + + #[test] + fn encode_converts_luma_a8_to_rgba() { + // LumaA8(带 alpha 的灰度)同样走转换路径。 + let img = image::DynamicImage::new_luma_a8(4, 4); + let result = encode(&img, 80.0, 2); + assert!(result.is_ok()); + assert!(!result.unwrap().is_empty()); + } + + #[test] + fn encode_lower_quality_produces_smaller_or_equal_bytes() { + // 对同一张随机内容图,更低质量通常不产生更大的输出。 + // 使用固定尺寸的纯色图保证可复现:低质量下体积应 <= 高质量体积。 + let img = image::DynamicImage::new_rgb8(64, 64); + let high = encode(&img, 95.0, 4).unwrap(); + let low = encode(&img, 10.0, 4).unwrap(); + assert!( + low.len() <= high.len(), + "lower quality ({}) should not exceed higher quality ({}); got low={} high={}", + 10.0, + 95.0, + low.len(), + high.len() + ); + } + + #[test] + fn decode_invalid_bytes_returns_error() { + // 非 WebP 字节流应返回解码错误而非 panic。 + let junk = b"this is definitely not a webp image"; + let result = decode(junk); + assert!(result.is_err()); + } + + #[test] + fn decode_empty_bytes_returns_error() { + // 空字节流应返回解码错误而非 panic。 + let result = decode(&[]); + assert!(result.is_err()); + } + + #[test] + fn decode_error_message_is_descriptive() { + // 解码错误的 Display 应包含 'WebP decode error' 前缀,便于日志排查。 + let err = decode(b"not webp").unwrap_err(); + assert!(err.to_string().starts_with("WebP decode error")); + } + + #[test] + fn encode_decode_preserves_dimensions() { + // 编码再解码后,图像宽高应保持一致。 + let original = image::DynamicImage::new_rgb8(16, 9); + let encoded = encode(&original, 85.0, 4).unwrap(); + let decoded = decode(&encoded).unwrap(); + assert_eq!(decoded.width(), 16); + assert_eq!(decoded.height(), 9); + } + + #[test] + fn webp_config_default_quality_and_method() { + // 未设置环境变量时,默认 quality=85.0、method=2(见 WEBP_CONFIG 文档)。 + let config = WebpConfig { + quality: 85.0, + method: 2, + }; + assert_eq!(config.quality, 85.0); + assert_eq!(config.method, 2); + } }