1 /*
2 libzint - the open source barcode library
3 Copyright (C) 2020 - 2021 Robin Stuart <rstuart114@gmail.com>
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. Neither the name of the project nor the names of its contributors
15 may be used to endorse or promote products derived from this software
16 without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 SUCH DAMAGE.
29 */
30 /* vim: set ts=4 sw=4 et : */
31
32 #include "testcommon.h"
33
test_large(int index,int debug)34 static void test_large(int index, int debug) {
35
36 struct item {
37 int symbology;
38 int option_2;
39 char *pattern;
40 int length;
41 int ret;
42 int expected_rows;
43 int expected_width;
44 };
45 // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
46 struct item data[] = {
47 /* 0*/ { BARCODE_C25STANDARD, -1, "1", 80, 0, 1, 817 },
48 /* 1*/ { BARCODE_C25STANDARD, -1, "1", 81, ZINT_ERROR_TOO_LONG, -1, -1 },
49 /* 2*/ { BARCODE_C25STANDARD, 1, "1", 80, 0, 1, 827 },
50 /* 3*/ { BARCODE_C25STANDARD, 1, "1", 81, ZINT_ERROR_TOO_LONG, -1, -1 },
51 /* 4*/ { BARCODE_C25INTER, -1, "1", 90, 0, 1, 819 },
52 /* 5*/ { BARCODE_C25INTER, -1, "1", 91, ZINT_ERROR_TOO_LONG, -1, -1 },
53 /* 6*/ { BARCODE_C25INTER, 1, "1", 90, 0, 1, 837 },
54 /* 7*/ { BARCODE_C25INTER, 1, "1", 91, ZINT_ERROR_TOO_LONG, -1, -1 },
55 /* 8*/ { BARCODE_C25IATA, -1, "1", 45, 0, 1, 639 },
56 /* 9*/ { BARCODE_C25IATA, -1, "1", 46, ZINT_ERROR_TOO_LONG, -1, -1 },
57 /* 10*/ { BARCODE_C25IATA, 1, "1", 45, 0, 1, 653 },
58 /* 11*/ { BARCODE_C25IATA, 1, "1", 46, ZINT_ERROR_TOO_LONG, -1, -1 },
59 /* 12*/ { BARCODE_C25LOGIC, -1, "1", 80, 0, 1, 809 },
60 /* 13*/ { BARCODE_C25LOGIC, -1, "1", 81, ZINT_ERROR_TOO_LONG, -1, -1 },
61 /* 14*/ { BARCODE_C25LOGIC, 1, "1", 80, 0, 1, 819 },
62 /* 15*/ { BARCODE_C25LOGIC, 1, "1", 81, ZINT_ERROR_TOO_LONG, -1, -1 },
63 /* 16*/ { BARCODE_C25IND, -1, "1", 45, 0, 1, 649 },
64 /* 17*/ { BARCODE_C25IND, -1, "1", 46, ZINT_ERROR_TOO_LONG, -1, -1 },
65 /* 18*/ { BARCODE_C25IND, 1, "1", 45, 0, 1, 663 },
66 /* 19*/ { BARCODE_C25IND, 1, "1", 46, ZINT_ERROR_TOO_LONG, -1, -1 },
67 /* 20*/ { BARCODE_DPLEIT, -1, "1", 13, 0, 1, 135 },
68 /* 21*/ { BARCODE_DPLEIT, -1, "1", 14, ZINT_ERROR_TOO_LONG, -1, -1 },
69 /* 22*/ { BARCODE_DPIDENT, -1, "1", 11, 0, 1, 117 },
70 /* 23*/ { BARCODE_DPIDENT, -1, "1", 12, ZINT_ERROR_TOO_LONG, -1, -1 },
71 /* 24*/ { BARCODE_ITF14, -1, "1", 13, 0, 1, 135 },
72 /* 25*/ { BARCODE_ITF14, -1, "1", 14, ZINT_ERROR_TOO_LONG, -1, -1 },
73 };
74 int data_size = ARRAY_SIZE(data);
75 int i, length, ret;
76 struct zint_symbol *symbol;
77
78 char data_buf[4096];
79
80 testStart("test_large");
81
82 for (i = 0; i < data_size; i++) {
83
84 if (index != -1 && i != index) continue;
85
86 symbol = ZBarcode_Create();
87 assert_nonnull(symbol, "Symbol not created\n");
88
89 testUtilStrCpyRepeat(data_buf, data[i].pattern, data[i].length);
90 assert_equal(data[i].length, (int) strlen(data_buf), "i:%d length %d != strlen(data_buf) %d\n", i, data[i].length, (int) strlen(data_buf));
91
92 length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data_buf, data[i].length, debug);
93
94 ret = ZBarcode_Encode(symbol, (unsigned char *) data_buf, length);
95 assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
96
97 if (ret < ZINT_ERROR) {
98 assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
99 assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
100 }
101
102 ZBarcode_Delete(symbol);
103 }
104
105 testFinish();
106 }
107
test_hrt(int index,int debug)108 static void test_hrt(int index, int debug) {
109
110 struct item {
111 int symbology;
112 int option_2;
113 char *data;
114 char *expected;
115 };
116 // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
117 struct item data[] = {
118 /* 0*/ { BARCODE_C25STANDARD, -1, "123456789", "123456789" },
119 /* 1*/ { BARCODE_C25STANDARD, 1, "123456789", "1234567895" },
120 /* 2*/ { BARCODE_C25STANDARD, 2, "123456789", "123456789" }, // Suppresses printing of check digit
121 /* 3*/ { BARCODE_C25INTER, -1, "123456789", "0123456789" }, // Adds leading zero if odd
122 /* 4*/ { BARCODE_C25INTER, 1, "123456789", "1234567895" }, // Unless check digit added when it becomes even
123 /* 5*/ { BARCODE_C25INTER, 2, "123456789", "123456789" },
124 /* 6*/ { BARCODE_C25INTER, -1, "1234567890", "1234567890" }, // No leading zero if even
125 /* 7*/ { BARCODE_C25INTER, 1, "1234567890", "012345678905" }, // Unless check digit added when it becomes odd
126 /* 8*/ { BARCODE_C25INTER, 2, "1234567890", "01234567890" },
127 /* 9*/ { BARCODE_C25IATA, -1, "123456789", "123456789" },
128 /* 10*/ { BARCODE_C25IATA, 1, "123456789", "1234567895" },
129 /* 11*/ { BARCODE_C25IATA, 2, "123456789", "123456789" },
130 /* 12*/ { BARCODE_C25LOGIC, -1, "123456789", "123456789" },
131 /* 13*/ { BARCODE_C25LOGIC, 1, "123456789", "1234567895" },
132 /* 14*/ { BARCODE_C25LOGIC, 2, "123456789", "123456789" },
133 /* 15*/ { BARCODE_C25IND, -1, "123456789", "123456789" },
134 /* 16*/ { BARCODE_C25IND, 1, "123456789", "1234567895" },
135 /* 17*/ { BARCODE_C25IND, 2, "123456789", "123456789" },
136 /* 18*/ { BARCODE_DPLEIT, -1, "123456789", "00001234567890" }, // Leading zeroes added to make 13 + appended checksum
137 /* 19*/ { BARCODE_DPLEIT, -1, "1234567890123", "12345678901236" },
138 /* 20*/ { BARCODE_DPIDENT, -1, "123456789", "001234567890" }, // Leading zeroes added to make 11 + appended checksum
139 /* 21*/ { BARCODE_DPIDENT, -1, "12345678901", "123456789016" },
140 /* 22*/ { BARCODE_ITF14, -1, "123456789", "00001234567895" }, // Leading zeroes added to make 13 + appended checksum
141 /* 23*/ { BARCODE_ITF14, -1, "1234567890123", "12345678901231" },
142 };
143 int data_size = ARRAY_SIZE(data);
144 int i, length, ret;
145 struct zint_symbol *symbol;
146
147 testStart("test_hrt");
148
149 for (i = 0; i < data_size; i++) {
150
151 if (index != -1 && i != index) continue;
152
153 symbol = ZBarcode_Create();
154 assert_nonnull(symbol, "Symbol not created\n");
155
156 length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
157
158 ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
159 assert_zero(ret, "i:%d ZBarcode_Encode ret %d != 0 %s\n", i, ret, symbol->errtxt);
160
161 assert_zero(strcmp((char *) symbol->text, data[i].expected), "i:%d strcmp(%s, %s) != 0\n", i, symbol->text, data[i].expected);
162
163 ZBarcode_Delete(symbol);
164 }
165
166 testFinish();
167 }
168
test_input(int index,int debug)169 static void test_input(int index, int debug) {
170
171 struct item {
172 int symbology;
173 char *data;
174 int ret;
175 int expected_rows;
176 int expected_width;
177 };
178 // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
179 struct item data[] = {
180 /* 0*/ { BARCODE_C25STANDARD, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
181 /* 1*/ { BARCODE_C25INTER, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
182 /* 2*/ { BARCODE_C25IATA, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
183 /* 3*/ { BARCODE_C25LOGIC, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
184 /* 4*/ { BARCODE_C25IND, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
185 /* 5*/ { BARCODE_DPLEIT, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
186 /* 6*/ { BARCODE_DPIDENT, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
187 /* 7*/ { BARCODE_ITF14, "A", ZINT_ERROR_INVALID_DATA, -1, -1 },
188 };
189 int data_size = ARRAY_SIZE(data);
190 int i, length, ret;
191 struct zint_symbol *symbol;
192
193 testStart("test_input");
194
195 for (i = 0; i < data_size; i++) {
196
197 if (index != -1 && i != index) continue;
198
199 symbol = ZBarcode_Create();
200 assert_nonnull(symbol, "Symbol not created\n");
201
202 length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, -1 /*option_2*/, -1, -1 /*output_options*/, data[i].data, -1, debug);
203
204 ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
205 assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
206
207 if (ret < ZINT_ERROR) {
208 assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d\n", i, symbol->rows, data[i].expected_rows);
209 assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d\n", i, symbol->width, data[i].expected_width);
210 }
211
212 ZBarcode_Delete(symbol);
213 }
214
215 testFinish();
216 }
217
test_encode(int index,int generate,int debug)218 static void test_encode(int index, int generate, int debug) {
219
220 struct item {
221 int symbology;
222 int option_2;
223 char *data;
224 int ret;
225
226 int expected_rows;
227 int expected_width;
228 char *comment;
229 char *expected;
230 };
231 // BARCODE_ITF14 examples verified manually against GS1 General Specifications 21.0.1
232 struct item data[] = {
233 /* 0*/ { BARCODE_C25STANDARD, -1, "87654321", 0, 1, 97, "Standard Code 2 of 5; note zint uses 4X start/end wides while BWIPP uses 3X",
234 "1111010101110100010101000111010001110101110111010101110111011100010101000101110111010111011110101"
235 },
236 /* 1*/ { BARCODE_C25STANDARD, 1, "87654321", 0, 1, 107, "With check digit",
237 "11110101011101000101010001110100011101011101110101011101110111000101010001011101110101110100010111011110101"
238 },
239 /* 2*/ { BARCODE_C25INTER, -1, "87654321", 0, 1, 81, "Interleaved Code 2 of 5, even; verified manually against tec-it",
240 "101011101010111000100010001110111000101010001000111010111010001110101011100011101"
241 },
242 /* 3*/ { BARCODE_C25INTER, 1, "87654321", 0, 1, 99, "With check digit",
243 "101010001011101110001010100010001110111011101011100010100011101110001010100011101000101011100011101"
244 },
245 /* 4*/ { BARCODE_C25INTER, -1, "7654321", 0, 1, 81, "Interleaved Code 2 of 5, odd",
246 "101010101110111000100010001110111000101010001000111010111010001110101011100011101"
247 },
248 /* 5*/ { BARCODE_C25INTER, 1, "7654321", 0, 1, 81, "With check digit",
249 "101010100010001110111011101011100010100011101110001010100011101010001000111011101"
250 },
251 /* 6*/ { BARCODE_C25INTER, -1, "602003", 0, 1, 63, "DX cartridge barcode https://en.wikipedia.org/wiki/Interleaved_2_of_5 example",
252 "101010111011100010001010111010001000111010001000111011101011101"
253 },
254 /* 7*/ { BARCODE_C25IATA, -1, "87654321", 0, 1, 121, "IATA Code 2 of 5; verified manually against tec-it",
255 "1010111010101110101010101110111010111011101010111010111010101010111010111011101110101010101110101011101110101010111011101"
256 },
257 /* 8*/ { BARCODE_C25IATA, 1, "87654321", 0, 1, 135, "With check digit",
258 "101011101010111010101010111011101011101110101011101011101010101011101011101110111010101010111010101110111010101011101011101010111011101"
259 },
260 /* 9*/ { BARCODE_C25LOGIC, -1, "87654321", 0, 1, 89, "Code 2 of 5 Data Logic; verified manually against tec-it",
261 "10101110100010101000111010001110101110111010101110111011100010101000101110111010111011101"
262 },
263 /* 10*/ { BARCODE_C25LOGIC, 1, "87654321", 0, 1, 99, "With check digit",
264 "101011101000101010001110100011101011101110101011101110111000101010001011101110101110100010111011101"
265 },
266 /* 11*/ { BARCODE_C25IND, -1, "87654321", 0, 1, 131, "Industrial Code 2 of 5; verified manually against tec-it",
267 "11101110101110101011101010101011101110101110111010101110101110101010101110101110111011101010101011101010111011101010101110111010111"
268 },
269 /* 12*/ { BARCODE_C25IND, 1, "87654321", 0, 1, 145, "With check digit",
270 "1110111010111010101110101010101110111010111011101010111010111010101010111010111011101110101010101110101011101110101010111010111010101110111010111"
271 },
272 /* 13*/ { BARCODE_DPLEIT, -1, "0000087654321", 0, 1, 135, "Deutsche Post Leitcode; verified manually against tec-it",
273 "101010101110001110001010101110001110001010001011101110001010100010001110111011101011100010100011101110001010100011101000100010111011101"
274 },
275 /* 14*/ { BARCODE_DPLEIT, -1, "5082300702800", 0, 1, 135, "Deutsche Post Leitcode https://de.wikipedia.org/wiki/Leitcode example",
276 "101011101011100010001011101000101110100011101110100010001010101110111000100010100011101110100011101010001110001010001011100011101011101"
277 },
278 /* 15*/ { BARCODE_DPIDENT, -1, "00087654321", 0, 1, 117, "Deutsche Post Identcode; verified manually against tec-it",
279 "101010101110001110001010001011101110001010100010001110111011101011100010100011101110001010100011101000100010111011101"
280 },
281 /* 16*/ { BARCODE_DPIDENT, -1, "39601313414", 0, 1, 117, "Deutsche Post Identcode https://de.wikipedia.org/wiki/Leitcode example",
282 "101011101110001010001010111011100010001011100010001010111011100010001010111010001011101011100010101110001000111011101"
283 },
284 /* 17*/ { BARCODE_ITF14, -1, "0000087654321", 0, 1, 135, "ITF-14; verified manually against tec-it",
285 "101010101110001110001010101110001110001010001011101110001010100010001110111011101011100010100011101110001010100011101000101011100011101"
286 },
287 /* 18*/ { BARCODE_ITF14, -1, "0950110153000", 0, 1, 135, "GS1 General Specifications Figure 5.1-2",
288 "101010100011101110001011101011100010001011100010101011100010001011101110100011100010001110101010101110001110001010001000111011101011101"
289 },
290 /* 19*/ { BARCODE_ITF14, -1, "1540014128876", 0, 1, 135, "GS1 General Specifications Figure 5.3.2.4-1",
291 "101011100010100010111010101110001000111010001011101110100010001011101011100010001110101000111011101010111000100010001110001110101011101"
292 },
293 /* 20*/ { BARCODE_ITF14, -1, "0950110153001", 0, 1, 135, "GS1 General Specifications Figure 5.3.6-1",
294 "101010100011101110001011101011100010001011100010101011100010001011101110100011100010001110101010101110001110001011101010001000111011101"
295 },
296 };
297 int data_size = ARRAY_SIZE(data);
298
299 char escaped[1024];
300 char bwipp_buf[4096];
301 char bwipp_msg[1024];
302 int i, length, ret;
303 struct zint_symbol *symbol;
304
305 int do_bwipp = (debug & ZINT_DEBUG_TEST_BWIPP) && testUtilHaveGhostscript(); // Only do BWIPP test if asked, too slow otherwise
306
307 testStart("test_encode");
308
309 for (i = 0; i < data_size; i++) {
310
311 if (index != -1 && i != index) continue;
312
313 symbol = ZBarcode_Create();
314 assert_nonnull(symbol, "Symbol not created\n");
315
316 length = testUtilSetSymbol(symbol, data[i].symbology, -1 /*input_mode*/, -1 /*eci*/, -1 /*option_1*/, data[i].option_2, -1, -1 /*output_options*/, data[i].data, -1, debug);
317
318 ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
319 assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
320
321 if (generate) {
322 printf(" /*%3d*/ { %s, %d, \"%s\", %s, %d, %d, \"%s\",\n",
323 i, testUtilBarcodeName(data[i].symbology), data[i].option_2, testUtilEscape(data[i].data, length, escaped, sizeof(escaped)),
324 testUtilErrorName(data[i].ret), symbol->rows, symbol->width, data[i].comment);
325 testUtilModulesPrint(symbol, " ", "\n");
326 printf(" },\n");
327 } else {
328 if (ret < ZINT_ERROR) {
329 int width, row;
330
331 assert_equal(symbol->rows, data[i].expected_rows, "i:%d symbol->rows %d != %d (%s)\n", i, symbol->rows, data[i].expected_rows, data[i].data);
332 assert_equal(symbol->width, data[i].expected_width, "i:%d symbol->width %d != %d (%s)\n", i, symbol->width, data[i].expected_width, data[i].data);
333
334 ret = testUtilModulesCmp(symbol, data[i].expected, &width, &row);
335 assert_zero(ret, "i:%d testUtilModulesCmp ret %d != 0 width %d row %d (%s)\n", i, ret, width, row, data[i].data);
336
337 if (do_bwipp && testUtilCanBwipp(i, symbol, -1, data[i].option_2, -1, debug)) {
338 ret = testUtilBwipp(i, symbol, -1, data[i].option_2, -1, data[i].data, length, NULL, bwipp_buf, sizeof(bwipp_buf));
339 assert_zero(ret, "i:%d %s testUtilBwipp ret %d != 0\n", i, testUtilBarcodeName(symbol->symbology), ret);
340
341 ret = testUtilBwippCmp(symbol, bwipp_msg, bwipp_buf, data[i].expected);
342 assert_zero(ret, "i:%d %s testUtilBwippCmp %d != 0 %s\n actual: %s\nexpected: %s\n",
343 i, testUtilBarcodeName(symbol->symbology), ret, bwipp_msg, bwipp_buf, data[i].expected);
344 }
345 }
346 }
347
348 ZBarcode_Delete(symbol);
349 }
350
351 testFinish();
352 }
353
main(int argc,char * argv[])354 int main(int argc, char *argv[]) {
355
356 testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
357 { "test_large", test_large, 1, 0, 1 },
358 { "test_hrt", test_hrt, 1, 0, 1 },
359 { "test_input", test_input, 1, 0, 1 },
360 { "test_encode", test_encode, 1, 1, 1 },
361 };
362
363 testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
364
365 testReport();
366
367 return 0;
368 }
369