#![cfg(feature = "code128")]
use smart_package_tracker::{Barcode, IdGenerator, Length, RenderOptions, TrackingId};
#[test]
#[cfg(all(feature = "os-rng", feature = "png", feature = "svg"))]
fn documented_workflow_end_to_end() {
let id = TrackingId::generate().expect("system entropy available");
assert!(id.as_str().starts_with("PKG-"));
assert_eq!(id.body().len(), 8);
let barcode = Barcode::code128(&id).expect("ids are always encodable");
let options = RenderOptions::default();
let png = barcode.to_png(&options).expect("png renders");
let svg = barcode.to_svg(&options).expect("svg renders");
assert_eq!(&png[..8], b"\x89PNG\r\n\x1a\n");
assert!(svg.contains("<svg"));
assert_eq!(barcode.decode().unwrap(), id.as_str());
}
#[test]
#[cfg(feature = "os-rng")]
fn ids_survive_a_storage_round_trip() {
use smart_package_tracker::Checksum;
let generator = IdGenerator::builder()
.entropy_bits(64)
.checksum(Checksum::Iso7064Mod37_36)
.build()
.unwrap();
let original = generator.generate().unwrap();
let stored = original.to_string();
let restored: TrackingId = stored.parse().unwrap();
assert_eq!(original, restored);
generator.validate(&restored).unwrap();
}
#[test]
fn a_scanner_reads_back_what_was_encoded() {
for payload in [
"PKG-9ED9285C",
"PKG-FFFFFFFFFFFFFFFFZ",
"1Z999AA10123456784", "770123456789", "9400111899223197428490", ] {
let barcode = Barcode::code128(payload).unwrap();
assert_eq!(barcode.decode().unwrap(), payload, "failed for {payload}");
}
}
#[test]
#[cfg(all(feature = "png", feature = "svg"))]
fn png_and_svg_agree_on_geometry() {
let barcode = Barcode::code128("PKG-9ED9285C").unwrap();
let options = RenderOptions::default();
let layout = options.layout(barcode.symbol()).unwrap();
let svg = barcode.to_svg(&options).unwrap();
assert!(svg.contains(&format!(
"viewBox=\"0 0 {} {}\"",
layout.width_px, layout.height_px
)));
let png = barcode.to_png(&options).unwrap();
let mut reader = png::Decoder::new(std::io::Cursor::new(&png[..]))
.read_info()
.unwrap();
let info = reader
.next_frame(&mut vec![0; reader.output_buffer_size().unwrap()])
.unwrap();
assert_eq!(
(info.width, info.height),
(layout.width_px, layout.height_px)
);
}
#[test]
#[cfg(all(feature = "png", feature = "svg"))]
fn renderers_are_usable_through_the_trait() {
use smart_package_tracker::render::{Png, Svg};
let barcode = Barcode::code128("PKG-9ED9285C").unwrap();
let options = RenderOptions::default();
let via_trait: Vec<u8> = barcode.render(&Png, &options).unwrap();
let via_helper = barcode.to_png(&options).unwrap();
assert_eq!(via_trait, via_helper);
let via_trait: String = barcode.render(&Svg, &options).unwrap();
assert_eq!(via_trait, barcode.to_svg(&options).unwrap());
}
#[test]
#[cfg(feature = "os-rng")]
fn a_thousand_ids_at_64_bits_are_all_distinct() {
let generator = IdGenerator::builder().entropy_bits(64).build().unwrap();
let ids: std::collections::HashSet<String> = (0..1000)
.map(|_| generator.generate().unwrap().into_string())
.collect();
assert_eq!(ids.len(), 1000);
}
#[test]
fn label_geometry_matches_a_300_dpi_thermal_printer() {
let barcode = Barcode::code128("PKG-9ED9285C").unwrap();
let options = RenderOptions::builder()
.module_width(Length::Mils(13.0))
.height(Length::Mm(25.0))
.dpi(300)
.build()
.unwrap();
let layout = options.layout(barcode.symbol()).unwrap();
assert_eq!(layout.module_px, 4);
assert_eq!(layout.symbol_h_px, 295);
assert!(
layout.width_px < 1200,
"label is {} px wide, wider than a 4 inch label",
layout.width_px
);
}
#[test]
fn errors_are_reported_rather_than_panicking() {
assert!(TrackingId::parse("not a tracking id").is_err());
assert!(Barcode::code128("").is_err());
assert!(IdGenerator::builder().entropy_bits(3).build().is_err());
assert!(RenderOptions::builder().dpi(0).build().is_err());
let barcode = Barcode::code128("PKG-9ED9285C").unwrap();
let absurd = RenderOptions::builder()
.module_width(Length::Inch(100.0))
.build()
.unwrap();
assert!(absurd.layout(barcode.symbol()).is_err());
#[cfg(feature = "png")]
assert!(barcode.to_png(&absurd).is_err());
#[cfg(feature = "svg")]
assert!(barcode.to_svg(&absurd).is_err());
}
#[test]
fn quiet_zone_default_meets_the_specification() {
let barcode = Barcode::code128("PKG-9ED9285C").unwrap();
let layout = RenderOptions::default().layout(barcode.symbol()).unwrap();
assert_eq!(
layout.quiet_x_px,
10 * layout.module_px,
"Code 128 requires a 10-module quiet zone"
);
}
#[test]
#[cfg(feature = "png")]
fn output_is_deterministic_across_runs() {
use smart_package_tracker::{Color, QuietZone};
let barcode = Barcode::code128("PKG-9ED9285C").unwrap();
let options = RenderOptions::builder()
.colors(Color::BLACK, Color::WHITE)
.quiet_zone(QuietZone::Standard)
.build()
.unwrap();
let a = barcode.to_png(&options).unwrap();
let b = Barcode::code128("PKG-9ED9285C")
.unwrap()
.to_png(&options)
.unwrap();
assert_eq!(a, b, "identical inputs must produce identical bytes");
}