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("")); 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); }