151 lines
4.2 KiB
Rust
151 lines
4.2 KiB
Rust
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).unwrap();
|
|
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);
|
|
}
|