use labelize::elements::field_orientation::FieldOrientation;
use labelize::elements::label_element::LabelElement;
use labelize::EplParser;
fn parse(epl: &str) -> Vec<labelize::LabelInfo> {
let parser = EplParser::new();
parser.parse(epl.as_bytes()).expect("EPL parse failed")
}
#[test]
fn parse_single_label() {
let labels = parse("N\nA10,20,0,1,1,1,N,\"Hello\"\nP1\n");
assert_eq!(labels.len(), 1);
assert_eq!(labels[0].elements.len(), 1);
}
#[test]
fn parse_text() {
let labels = parse("N\nA50,100,0,2,1,1,N,\"Hello World\"\nP1\n");
let tf = match &labels[0].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert_eq!(tf.text, "Hello World");
assert_eq!(tf.position.x, 50);
assert_eq!(tf.position.y, 100);
assert_eq!(tf.font.orientation, FieldOrientation::Normal);
assert_eq!(tf.font.width, 16.0);
assert_eq!(tf.font.height, 16.0);
}
#[test]
fn parse_text_rotated() {
let labels = parse("N\nA50,100,1,1,1,1,N,\"Rotated\"\nP1\n");
let tf = match &labels[0].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert_eq!(tf.font.orientation, FieldOrientation::Rotated90);
}
#[test]
fn parse_text_reverse() {
let labels = parse("N\nA50,100,0,1,1,1,R,\"Reverse\"\nP1\n");
let tf = match &labels[0].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert!(tf.reverse_print.value, "expected reverse print to be true");
}
#[test]
fn parse_text_multiplier() {
let labels = parse("N\nA10,20,0,3,2,3,N,\"Big\"\nP1\n");
let tf = match &labels[0].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert_eq!(tf.font.width, 24.0);
assert_eq!(tf.font.height, 60.0);
}
#[test]
fn parse_empty_text_skipped() {
let labels = parse("N\nA10,20,0,1,1,1,N,\"\"\nP1\n");
assert_eq!(labels.len(), 0);
}
#[test]
fn parse_barcode() {
let labels = parse("N\nB50,100,0,1,3,6,200,B,\"12345\"\nP1\n");
assert_eq!(labels[0].elements.len(), 1);
let bc = match &labels[0].elements[0] {
LabelElement::Barcode128(b) => b,
other => panic!("expected Barcode128, got {:?}", other),
};
assert_eq!(bc.data, "12345");
assert_eq!(bc.position.x, 50);
assert_eq!(bc.position.y, 100);
assert_eq!(bc.barcode.height, 200);
assert!(bc.barcode.line, "expected human-readable line to be true");
}
#[test]
fn parse_barcode_code39() {
let labels = parse("N\nB50,100,0,0,2,5,100,N,\"ABC123\"\nP1\n");
let bc = match &labels[0].elements[0] {
LabelElement::Barcode39(b) => b,
other => panic!("expected Barcode39, got {:?}", other),
};
assert_eq!(bc.data, "ABC123");
assert_eq!(bc.width, 2);
assert_eq!(bc.width_ratio, 2.5);
}
#[test]
fn parse_barcode_interleaved_2of5() {
let labels = parse("N\nB50,100,0,G,2,5,100,B,\"1234567890\"\nP1\n");
match &labels[0].elements[0] {
LabelElement::Barcode2of5(_) => {}
other => panic!("expected Barcode2of5, got {:?}", other),
}
}
#[test]
fn parse_line() {
let labels = parse("N\nLO10,20,300,5\nP1\n");
let gb = match &labels[0].elements[0] {
LabelElement::GraphicBox(b) => b,
other => panic!("expected GraphicBox, got {:?}", other),
};
assert_eq!(gb.position.x, 10);
assert_eq!(gb.position.y, 20);
assert_eq!(gb.width, 300);
assert_eq!(gb.height, 5);
assert_eq!(gb.border_thickness, 5);
}
#[test]
fn parse_reference_point() {
let labels = parse("N\nR40,10\nA50,100,0,1,1,1,N,\"Offset\"\nP1\n");
let tf = match &labels[0].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert_eq!(tf.position.x, 90);
assert_eq!(tf.position.y, 110);
}
#[test]
fn parse_multiple_labels() {
let labels = parse("N\nA10,20,0,1,1,1,N,\"Label1\"\nP1\nN\nA30,40,0,1,1,1,N,\"Label2\"\nP1\n");
assert_eq!(labels.len(), 2);
let tf1 = match &labels[0].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert_eq!(tf1.text, "Label1");
let tf2 = match &labels[1].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert_eq!(tf2.text, "Label2");
}
#[test]
fn parse_without_p_command() {
let labels = parse("N\nA10,20,0,1,1,1,N,\"NoPrint\"\n");
assert_eq!(labels.len(), 1, "expected 1 label (auto-emitted)");
}
#[test]
fn parse_ignored_commands() {
let labels = parse("N\nQ822,24\nS4\nD15\nZB\nA10,20,0,1,1,1,N,\"Test\"\nP1\n");
assert_eq!(labels.len(), 1);
assert_eq!(labels[0].elements.len(), 1);
}
#[test]
fn parse_mixed_elements() {
let epl = "N\nA10,20,0,1,1,1,N,\"Header\"\nB50,100,0,1,3,6,200,N,\"12345\"\nLO0,300,400,2\nA10,320,0,2,1,1,N,\"Footer\"\nP1\n";
let labels = parse(epl);
assert_eq!(labels[0].elements.len(), 4);
assert!(matches!(&labels[0].elements[0], LabelElement::Text(_)));
assert!(matches!(
&labels[0].elements[1],
LabelElement::Barcode128(_)
));
assert!(matches!(
&labels[0].elements[2],
LabelElement::GraphicBox(_)
));
assert!(matches!(&labels[0].elements[3], LabelElement::Text(_)));
}
#[test]
fn parse_dpd_uk() {
let file = std::fs::read("testdata/dpduk.epl").expect("failed to read dpduk.epl");
let parser = EplParser::new();
let labels = parser.parse(&file).expect("EPL parse failed");
assert!(!labels.is_empty(), "no labels parsed from dpduk.epl");
let label = &labels[0];
assert!(
!label.elements.is_empty(),
"no elements in the parsed label"
);
let mut texts = 0;
let mut barcodes = 0;
let mut lines = 0;
for el in &label.elements {
match el {
LabelElement::Text(_) => texts += 1,
LabelElement::Barcode128(_) => barcodes += 1,
LabelElement::GraphicBox(_) => lines += 1,
_ => {}
}
}
assert!(texts > 0, "expected at least one text element");
assert!(barcodes > 0, "expected at least one barcode element");
assert!(lines > 0, "expected at least one line element");
}
#[test]
fn draw_dpd_uk() {
use labelize::{DrawerOptions, Renderer};
use std::io::Cursor;
let file = std::fs::read("testdata/dpduk.epl").expect("failed to read dpduk.epl");
let parser = EplParser::new();
let labels = parser.parse(&file).expect("EPL parse failed");
assert!(!labels.is_empty(), "no labels parsed");
let renderer = Renderer::new();
let mut buf = Cursor::new(Vec::new());
renderer
.draw_label_as_png(&labels[0], &mut buf, DrawerOptions::default())
.expect("render failed");
assert!(buf.into_inner().len() > 0, "empty PNG output");
}
#[test]
fn parse_n_resets_reference_point() {
let labels =
parse("N\nR40,10\nA10,20,0,1,1,1,N,\"First\"\nP1\nN\nA10,20,0,1,1,1,N,\"Second\"\nP1\n");
assert_eq!(labels.len(), 2);
let tf1 = match &labels[0].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert_eq!(tf1.position.x, 50);
assert_eq!(tf1.position.y, 30);
let tf2 = match &labels[1].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert_eq!(tf2.position.x, 10);
assert_eq!(tf2.position.y, 20);
}
#[test]
fn parse_font_sizes() {
let tests = vec![
(1, 12.0, 12.0), (2, 16.0, 16.0), (3, 20.0, 20.0), (4, 24.0, 24.0), (5, 48.0, 48.0), (9, 12.0, 12.0), ];
for (font_num, expected_width, expected_height) in tests {
let epl = format!("N\nA10,20,0,{},1,1,N,\"test\"\nP1\n", font_num);
let labels = parse(&epl);
let tf = match &labels[0].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert_eq!(
tf.font.width, expected_width,
"font {}: width = {}, want {}",
font_num, tf.font.width, expected_width
);
assert_eq!(
tf.font.height, expected_height,
"font {}: height = {}, want {}",
font_num, tf.font.height, expected_height
);
}
}
#[test]
fn parse_rotations() {
let tests = vec![
(0, FieldOrientation::Normal),
(1, FieldOrientation::Rotated90),
(2, FieldOrientation::Rotated180),
(3, FieldOrientation::Rotated270),
(7, FieldOrientation::Normal), ];
for (rotation, expected) in tests {
let epl = format!("N\nA10,20,{},1,1,1,N,\"test\"\nP1\n", rotation);
let labels = parse(&epl);
let tf = match &labels[0].elements[0] {
LabelElement::Text(t) => t,
other => panic!("expected Text, got {:?}", other),
};
assert_eq!(
tf.font.orientation, expected,
"rotation {}: got {:?}, want {:?}",
rotation, tf.font.orientation, expected
);
}
}
#[test]
fn empty_input_does_not_panic() {
let parser = EplParser::new();
let result = parser.parse(b"");
assert!(result.is_ok());
}
#[test]
fn garbage_input_does_not_panic() {
let parser = EplParser::new();
let result = parser.parse(b"not EPL at all!");
assert!(result.is_ok());
}