forked from GOODBOY008/labelize
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathunit_barcodes.rs
More file actions
311 lines (268 loc) · 9.23 KB
/
Copy pathunit_barcodes.rs
File metadata and controls
311 lines (268 loc) · 9.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
use labelize::barcodes::{
aztec, code128, code39, datamatrix, ean13, maxicode, pdf417, qrcode, twooffive,
};
use labelize::elements::barcode_qr::QrErrorCorrectionLevel;
// --- Code128 ---
#[test]
fn code128_encodes_ascii() {
let img = code128::encode_auto("Hello123", 100, 2).expect("encode_auto failed");
assert!(img.width() > 0);
assert!(img.height() > 0);
}
#[test]
fn code128_encodes_digits_only() {
let img = code128::encode_auto("1234567890", 80, 2).expect("encode_auto failed");
assert!(img.width() > 0);
}
#[test]
fn code128_empty_input_handled() {
// Empty input may succeed with a minimal barcode or error - either is acceptable
let _result = code128::encode_auto("", 100, 2);
}
#[test]
fn code128_no_mode_strips_prefix_from_display() {
// Per ZPL spec: >; = Start Code C, >6 = switch to Code B (from C), >7 = switch to Code A (from B).
// Code A in mode N uses digit pairs: "52"→'T', "37"→'E', "51"→'S', "52"→'T' → "TEST".
// Display text should NOT contain any > prefix codes.
let (img, text) = code128::encode_no_mode(">;382436>6CODE128>752375152", 100, 2)
.expect("encode_no_mode failed");
assert!(img.width() > 0);
assert!(
!text.contains('>'),
"display text should not contain '>' prefix codes: {}",
text
);
assert!(
text.contains("382436"),
"display text should contain '382436': {}",
text
);
assert!(
text.contains("CODE128"),
"display text should contain 'CODE128': {}",
text
);
assert!(
text.contains("TEST"),
"display text should contain 'TEST' (Code A pair-mode decoding of 52,37,51,52): {}",
text
);
}
#[test]
fn code128_no_mode_default_code_b() {
// Mode N without explicit prefix should default to Code B (not auto Code C)
let (img1, text1) = code128::encode_no_mode("12345678", 100, 2).expect("encode_no_mode failed");
// In Code B, each digit is 1 symbol; in Code C, pairs are 1 symbol.
// Code B (8 data + start + check + stop) vs Code C (4 pairs + start + check + stop)
// Code B should produce a wider barcode
let img2 = code128::encode_auto("12345678", 100, 2).expect("encode_auto failed");
assert!(
img1.width() > img2.width(),
"Mode N without prefix should use Code B (wider), not auto Code C"
);
assert_eq!(text1, "12345678");
}
#[test]
fn code128_auto_with_fnc1() {
// FNC1 at start followed by digits should still detect Code C start
let content = format!("{}1234567890", code128::ESCAPE_FNC_1);
let img = code128::encode_auto(&content, 100, 2).expect("encode_auto with FNC1 failed");
// With FNC1 + 10 digits: Start C, FNC1, 5 pairs, check, stop = 9 symbols
// Without FNC1: Start C, 5 pairs, check, stop = 8 symbols
let img_no_fnc1 = code128::encode_auto("1234567890", 100, 2).expect("encode_auto failed");
assert!(
img.width() > img_no_fnc1.width(),
"FNC1 should add one symbol width"
);
}
// --- Code39 ---
#[test]
fn code39_encodes_alphanumeric() {
let img = code39::encode("ABC123", 100, 3, 2).expect("code39 failed");
assert!(img.width() > 0);
assert!(img.height() > 0);
}
#[test]
fn code39_empty_input_handled() {
// Empty input may succeed with a minimal barcode or error - either is acceptable
let _result = code39::encode("", 100, 3, 2);
}
#[test]
fn code128_ean_mode_keeps_ai_formatting_but_hides_fnc1_invocations() {
let (encoded, display) = code128::prepare_ean_mode_data("(91)0005886>8(10)0000410549>8(99)05");
let fnc1 = code128::ESCAPE_FNC_1;
assert_eq!(
encoded,
format!("{fnc1}910005886{fnc1}100000410549{fnc1}9905")
);
assert_eq!(display, "(91)0005886(10)0000410549(99)05");
assert!(!display.contains(">8"));
}
// --- EAN-13 ---
#[test]
fn ean13_encodes_12_digits() {
let img = ean13::encode("123456789012", 100, 2).expect("ean13 failed");
assert!(img.width() > 0);
assert!(img.height() > 0);
}
#[test]
fn ean13_empty_input_returns_error() {
let result = ean13::encode("", 100, 2);
assert!(result.is_err(), "expected error for empty input");
}
// --- Interleaved 2-of-5 ---
#[test]
fn twooffive_encodes_digits() {
let img = twooffive::encode("12345678", 100, 3, 2, false).expect("2of5 failed");
assert!(img.width() > 0);
assert!(img.height() > 0);
}
#[test]
fn twooffive_empty_input_returns_error() {
let result = twooffive::encode("", 100, 3, 2, false);
assert!(result.is_err(), "expected error for empty input");
}
// --- PDF417 ---
#[test]
fn pdf417_encodes_text() {
let img = pdf417::encode("Hello World", 4, 0, 0, 0, false, 10).expect("pdf417 failed");
assert!(img.width() > 0);
assert!(img.height() > 0);
}
#[test]
fn pdf417_empty_input_returns_error() {
let result = pdf417::encode("", 4, 0, 0, 0, false, 10);
assert!(result.is_err(), "expected error for empty input");
}
#[test]
fn pdf417_module_width_scales_output() {
// Encode at 1px module width, then at 3px — verify width ratio
let img1 = pdf417::encode("Test data", 0, 0, 5, 0, false, 40).expect("encode 1");
let img3 = pdf417::encode("Test data", 0, 0, 5, 0, false, 40).expect("encode 3");
// Both produce same 1px-module-width images; scaling happens in renderer
assert_eq!(img1.width(), img3.width());
}
#[test]
fn pdf417_row_height_fallback_from_by() {
// b7_h=0 means use by_height/num_rows
let img = pdf417::encode("Hello World", 0, 2, 5, 0, false, 40).expect("encode");
assert!(img.height() > 0);
}
#[test]
fn pdf417_explicit_row_height_overrides_by() {
// b7_h=5 means each row = 5px, regardless of by_height
let img = pdf417::encode("Hello World", 5, 2, 5, 0, false, 9999).expect("encode");
// With explicit row_height=5, rows*5 = image height
// Verify height is reasonable (not 9999-based)
assert!(
img.height() < 500,
"height should use b7_h=5, not by_height"
);
}
#[test]
fn pdf417_default_aspect_ratio() {
// cols=0, rows=0 → should pick rows ≈ 2×cols
let img = pdf417::encode(
"Some data to encode for aspect ratio test",
0,
0,
0,
0,
false,
10,
)
.expect("encode");
assert!(img.width() > 0);
assert!(img.height() > 0);
}
#[test]
fn pdf417_validation_rejects_over_928() {
// rxing handles capacity validation internally; 30×90=2700 should fail
let result = pdf417::encode("x", 0, 0, 30, 90, false, 10);
assert!(result.is_err(), "30×90=2700 should exceed 928 limit");
}
#[test]
fn pdf417_truncated_mode() {
let full = pdf417::encode("Truncated test", 0, 0, 0, 0, false, 10).expect("full");
let trunc = pdf417::encode("Truncated test", 0, 0, 0, 0, true, 10).expect("truncated");
assert!(
trunc.width() <= full.width(),
"truncated PDF417 should not be wider than full"
);
}
#[test]
fn pdf417_crlf_in_data() {
let img = pdf417::encode("Line1\nLine2", 0, 0, 0, 0, false, 10).expect("encode");
assert!(img.width() > 0);
}
// --- Aztec ---
#[test]
fn aztec_encodes_text() {
let img = aztec::encode("Hello", 4, 0).expect("aztec failed");
assert!(img.width() > 0);
assert!(img.height() > 0);
// Aztec codes should be square
assert_eq!(img.width(), img.height(), "Aztec code should be square");
}
#[test]
fn aztec_empty_input_returns_error() {
let result = aztec::encode("", 4, 0);
assert!(result.is_err(), "expected error for empty input");
}
// --- DataMatrix ---
#[test]
fn datamatrix_encodes_text() {
let img = datamatrix::encode("Hello", 4, 0, 0).expect("datamatrix failed");
assert!(img.width() > 0);
assert!(img.height() > 0);
}
#[test]
fn datamatrix_empty_input_returns_error() {
let result = datamatrix::encode("", 4, 0, 0);
assert!(result.is_err(), "expected error for empty input");
}
// --- QR code ---
#[test]
fn qrcode_encodes_text() {
let img = qrcode::encode("Hello World", 5, QrErrorCorrectionLevel::M).expect("qrcode failed");
assert!(img.width() > 0);
assert!(img.height() > 0);
// QR codes should be square
assert_eq!(img.width(), img.height(), "QR code should be square");
}
#[test]
fn qrcode_empty_input_returns_error() {
let result = qrcode::encode("", 5, QrErrorCorrectionLevel::M);
assert!(result.is_err(), "expected error for empty input");
}
// --- MaxiCode ---
#[test]
fn maxicode_encodes_text() {
let img = maxicode::encode("Hello World", 4).expect("maxicode failed");
assert!(img.width() > 0);
assert!(img.height() > 0);
}
#[test]
fn maxicode_empty_input_returns_error() {
let result = maxicode::encode("", 4);
assert!(result.is_err(), "expected error for empty input");
}
// --- Multiple barcode widths ---
#[test]
fn code128_wider_bar_produces_wider_image() {
let narrow = code128::encode_auto("TEST", 100, 1).expect("narrow");
let wide = code128::encode_auto("TEST", 100, 3).expect("wide");
assert!(
wide.width() > narrow.width(),
"wider bar width should produce wider image"
);
}
#[test]
fn code128_taller_height_produces_taller_image() {
let short = code128::encode_auto("TEST", 50, 2).expect("short");
let tall = code128::encode_auto("TEST", 200, 2).expect("tall");
assert!(
tall.height() > short.height(),
"taller height should produce taller image"
);
}