test: 集成测试 + 端到端验证
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
use qr_core::qr::{QrCode, QrConfig, VersionMode};
|
||||
use qr_core::version::EcLevel;
|
||||
|
||||
#[test]
|
||||
fn test_encode_simple_text() {
|
||||
let config = QrConfig::default();
|
||||
let qr = QrCode::encode("HELLO WORLD", config).unwrap();
|
||||
assert_eq!(qr.version.0, 1);
|
||||
assert_eq!(qr.size(), 21);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all_levels() {
|
||||
for level in [EcLevel::L, EcLevel::M, EcLevel::Q, EcLevel::H] {
|
||||
let config = QrConfig { level, ..Default::default() };
|
||||
let qr = QrCode::encode("TEST", config).unwrap();
|
||||
assert!(qr.size() >= 21);
|
||||
assert!(qr.size() <= 177);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_chinese_text() {
|
||||
let config = QrConfig::default();
|
||||
let qr = QrCode::encode("你好世界", config).unwrap();
|
||||
assert!(qr.size() >= 21);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_url_encoding() {
|
||||
let config = QrConfig::default();
|
||||
let qr = QrCode::encode("https://example.com/path?q=1", config).unwrap();
|
||||
assert!(qr.size() >= 21);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_numeric_only_small_version() {
|
||||
let mut config = QrConfig::default();
|
||||
config.version = VersionMode::Fixed(1);
|
||||
let qr = QrCode::encode("12345678901234567890", config).unwrap();
|
||||
assert_eq!(qr.version.0, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fixed_version() {
|
||||
let config = QrConfig {
|
||||
version: VersionMode::Fixed(5),
|
||||
..Default::default()
|
||||
};
|
||||
let qr = QrCode::encode("FIXED VERSION TEST", config).unwrap();
|
||||
assert_eq!(qr.version.0, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_empty_input_fails() {
|
||||
let config = QrConfig::default();
|
||||
let result = QrCode::encode("", config);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_svg_output() {
|
||||
let qr = QrCode::encode("TEST", QrConfig::default()).unwrap();
|
||||
let svg = qr.to_svg();
|
||||
assert!(svg.contains("<svg"));
|
||||
assert!(svg.contains("</svg>"));
|
||||
assert!(svg.contains("fill=\"black\""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ascii_output() {
|
||||
let qr = QrCode::encode("TEST", QrConfig::default()).unwrap();
|
||||
let ascii = qr.to_ascii(false);
|
||||
assert!(!ascii.is_empty());
|
||||
assert!(ascii.contains('\n'));
|
||||
// 应该有暗模块
|
||||
assert!(ascii.contains("██"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_png_output() {
|
||||
let qr = QrCode::encode("TEST", QrConfig::default()).unwrap();
|
||||
let png = qr.to_png_bytes(4);
|
||||
assert!(!png.is_empty());
|
||||
// PNG 文件应以 8 字节魔术签名开头
|
||||
assert_eq!(&png[..8], &[137, 80, 78, 71, 13, 10, 26, 10]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_modules_matrix() {
|
||||
let qr = QrCode::encode("QR", QrConfig::default()).unwrap();
|
||||
let modules = qr.modules();
|
||||
assert_eq!(modules.len(), qr.size() as usize);
|
||||
assert_eq!(modules[0].len(), qr.size() as usize);
|
||||
// 至少有一些暗模块
|
||||
let has_dark = modules.iter().any(|row| row.iter().any(|&m| m));
|
||||
assert!(has_dark, "QR 码应该包含暗模块");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_margin_is_included_in_dimensions() {
|
||||
let mut config = QrConfig::default();
|
||||
config.margin = 2;
|
||||
let qr = QrCode::encode("MARGIN TEST", config).unwrap();
|
||||
|
||||
// SVG 的总宽度应该包含 margin
|
||||
let svg = qr.to_svg();
|
||||
let matrix_size = qr.size() as u32;
|
||||
let expected_total = matrix_size + 2 * 2u32;
|
||||
assert!(svg.contains(&format!("width=\"{}\"", expected_total)));
|
||||
|
||||
// ASCII 输出行应该包含 margin 列
|
||||
let ascii = qr.to_ascii(false);
|
||||
let first_line = ascii.lines().next().unwrap();
|
||||
let chars_per_module = 2; // ██ 是两个字符
|
||||
assert_eq!(first_line.chars().count(), expected_total as usize * chars_per_module);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_text_auto_version() {
|
||||
// 长文本应该自动选择更高的版本
|
||||
let long_text = "A".repeat(200);
|
||||
let qr = QrCode::encode(&long_text, QrConfig::default()).unwrap();
|
||||
// 至少要 Version 2 以上
|
||||
assert!(qr.version.0 >= 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_special_chars() {
|
||||
let config = QrConfig::default();
|
||||
let qr = QrCode::encode("$%*+-./: SPACE", config).unwrap();
|
||||
assert!(qr.size() >= 21);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_numeric_mode_efficiency() {
|
||||
// 纯数字在 Version 1 L 级最多 41 位(约 7089 位数字)
|
||||
let digits = "1".repeat(20);
|
||||
let mut config = QrConfig::default();
|
||||
config.version = VersionMode::Fixed(1);
|
||||
config.level = EcLevel::L;
|
||||
let qr = QrCode::encode(&digits, config).unwrap();
|
||||
assert_eq!(qr.version.0, 1);
|
||||
}
|
||||
Reference in New Issue
Block a user