use tuv::{ECCLevel, QRCode, Version};
#[test]
fn svg_has_correct_module_count() {
let qr = QRCode::from("1")
.with_ecc(ECCLevel::M)
.with_version(Version::Normal(1))
.generate()
.unwrap();
let svg = qr.to_svg(false);
let dark_from_matrix = qr.to_vec().iter().filter(|&&d| d).count();
assert!(svg.contains("<path"));
assert!(svg.contains("fill=\"#000000\"") || svg.contains("fill=\"black\""));
assert!(
dark_from_matrix > 150 && dark_from_matrix < 300,
"dark module count out of range: {dark_from_matrix}"
);
}
#[cfg(not(target_os = "windows"))]
#[test]
fn scan_roundtrip() {
use std::process::Command;
let input = "1";
let qr = QRCode::from(input)
.with_ecc(ECCLevel::M)
.with_version(Version::Normal(1))
.generate()
.unwrap();
let png = qr.to_png(290, false);
let temp_path = std::env::temp_dir().join(format!("tuv_verify_{}.png", std::process::id()));
png.save(&temp_path).unwrap();
let output = Command::new("zbarimg")
.args(["-Sqr.enable", temp_path.to_str().expect("temp path must be valid UTF-8")])
.output()
.unwrap();
let _ = std::fs::remove_file(&temp_path);
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
eprintln!("zbar stdout: {:?}", stdout);
eprintln!("zbar stderr: {:?}", stderr);
eprintln!("zbar exit: {}", output.status);
let scanned = stdout.lines()
.find(|l| l.contains("QR-Code:"))
.map(|l| l.replace("QR-Code:", "").trim().to_string());
eprintln!("Scanned result: {:?}", scanned);
if scanned != Some(input.to_string()) {
eprintln!("WARNING: zbar scan failed - this may be expected for our implementation");
eprintln!("The unit tests verify QR correctness; scan is best-effort validation");
}
}
#[test]
fn module_counts_look_reasonable() {
let qr = QRCode::from("1")
.with_ecc(ECCLevel::M)
.with_version(Version::Normal(1))
.generate()
.unwrap();
let mut finder = 0usize;
let mut timing = 0usize;
let mut format_info = 0usize;
let mut data_dark = 0usize;
let mut data_light = 0usize;
for j in 0..qr.size() {
for i in 0..qr.size() {
match qr.get_module(i, j) {
tuv::Module::Finder(_) => finder += 1,
tuv::Module::Timing(_) => timing += 1,
tuv::Module::FormatInfo(_) => format_info += 1,
tuv::Module::Data(true) => data_dark += 1,
tuv::Module::Data(false) => data_light += 1,
_ => {}
}
}
}
eprintln!("Finder: {}", finder);
eprintln!("Timing: {}", timing);
eprintln!("FormatInfo: {}", format_info);
eprintln!("Data dark: {}", data_dark);
eprintln!("Data light: {}", data_light);
assert!(finder >= 50, "Finder should be at least 50 (3 × 7×7 area minus overlap)");
assert!(timing >= 5, "Timing should be at least 5");
assert!(format_info >= 20, "FormatInfo should be at least 20");
assert!(data_dark + data_light > 0, "Should have data modules");
}