isahaq-barcode 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +29 -0
- package/README.md +549 -0
- package/bin/generate.js +274 -0
- package/eslint.config.js +68 -0
- package/examples/basic-usage.js +58 -0
- package/examples/batch-example.json +56 -0
- package/examples/express-server.js +159 -0
- package/index.js +134 -0
- package/jest.config.js +13 -0
- package/package.json +66 -0
- package/src/builders/QrCodeBuilder.js +401 -0
- package/src/renderers/HTMLRenderer.js +212 -0
- package/src/renderers/PDFRenderer.js +184 -0
- package/src/renderers/PNGRenderer.js +123 -0
- package/src/renderers/RenderFormats.js +87 -0
- package/src/renderers/SVGRenderer.js +221 -0
- package/src/services/BarcodeService.js +175 -0
- package/src/types/BarcodeTypes.js +195 -0
- package/src/validators/Validator.js +352 -0
- package/tests/BarcodeGenerator.test.js +187 -0
- package/tests/BarcodeService.test.js +76 -0
- package/tests/QrCodeBuilder.test.js +130 -0
- package/tests/setup.js +59 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validator - Data validation for different barcode types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { BarcodeTypes } = require('../types/BarcodeTypes');
|
|
6
|
+
|
|
7
|
+
class Validator {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.patterns = {
|
|
10
|
+
// Numeric patterns
|
|
11
|
+
numeric: /^[0-9]+$/,
|
|
12
|
+
// Alphanumeric patterns
|
|
13
|
+
alphanumeric: /^[A-Za-z0-9]+$/,
|
|
14
|
+
// Code 39 pattern
|
|
15
|
+
code39: /^[A-Z0-9\s\-\.\$\/\+\%]+$/,
|
|
16
|
+
// Code 39 extended pattern
|
|
17
|
+
code39extended: /^[\x00-\x7F]+$/,
|
|
18
|
+
// EAN/UPC patterns
|
|
19
|
+
ean13: /^[0-9]{12,13}$/,
|
|
20
|
+
ean8: /^[0-9]{7,8}$/,
|
|
21
|
+
upca: /^[0-9]{11,12}$/,
|
|
22
|
+
upce: /^[0-9]{6,8}$/,
|
|
23
|
+
// QR Code pattern (supports Unicode)
|
|
24
|
+
qrcode: /^[\s\S]+$/,
|
|
25
|
+
// Data Matrix pattern
|
|
26
|
+
datamatrix: /^[\s\S]+$/,
|
|
27
|
+
// PDF417 pattern
|
|
28
|
+
pdf417: /^[\s\S]+$/,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Validate data for a specific barcode type
|
|
34
|
+
* @param {string} data - The data to validate
|
|
35
|
+
* @param {string} type - The barcode type
|
|
36
|
+
* @returns {Object} Validation result
|
|
37
|
+
*/
|
|
38
|
+
validate(data, type) {
|
|
39
|
+
if (!data || typeof data !== 'string') {
|
|
40
|
+
return {
|
|
41
|
+
valid: false,
|
|
42
|
+
error: 'Data must be a non-empty string',
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!BarcodeTypes.isValid(type)) {
|
|
47
|
+
return {
|
|
48
|
+
valid: false,
|
|
49
|
+
error: `Invalid barcode type: ${type}`,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Get configuration for the barcode type
|
|
54
|
+
const config = BarcodeTypes.getConfig(type);
|
|
55
|
+
|
|
56
|
+
// Check length constraints
|
|
57
|
+
if (data.length < config.minLength) {
|
|
58
|
+
return {
|
|
59
|
+
valid: false,
|
|
60
|
+
error: `Data too short. Minimum length: ${config.minLength}`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (data.length > config.maxLength) {
|
|
65
|
+
return {
|
|
66
|
+
valid: false,
|
|
67
|
+
error: `Data too long. Maximum length: ${config.maxLength}`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Type-specific validation
|
|
72
|
+
const validationResult = this.validateByType(data, type);
|
|
73
|
+
if (!validationResult.valid) {
|
|
74
|
+
return validationResult;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
valid: true,
|
|
79
|
+
data,
|
|
80
|
+
type,
|
|
81
|
+
length: data.length,
|
|
82
|
+
charset: config.charset,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Validate data by barcode type
|
|
88
|
+
* @param {string} data - The data to validate
|
|
89
|
+
* @param {string} type - The barcode type
|
|
90
|
+
* @returns {Object} Validation result
|
|
91
|
+
*/
|
|
92
|
+
validateByType(data, type) {
|
|
93
|
+
switch (type) {
|
|
94
|
+
case 'code128':
|
|
95
|
+
case 'code128a':
|
|
96
|
+
case 'code128b':
|
|
97
|
+
case 'code128c':
|
|
98
|
+
case 'code128auto':
|
|
99
|
+
return this.validateCode128(data, type);
|
|
100
|
+
|
|
101
|
+
case 'code39':
|
|
102
|
+
case 'code39extended':
|
|
103
|
+
case 'code39checksum':
|
|
104
|
+
case 'code39auto':
|
|
105
|
+
return this.validateCode39(data, type);
|
|
106
|
+
|
|
107
|
+
case 'code93':
|
|
108
|
+
return this.validateCode93(data);
|
|
109
|
+
|
|
110
|
+
case 'ean13':
|
|
111
|
+
return this.validateEAN13(data);
|
|
112
|
+
|
|
113
|
+
case 'ean8':
|
|
114
|
+
return this.validateEAN8(data);
|
|
115
|
+
|
|
116
|
+
case 'upca':
|
|
117
|
+
return this.validateUPCA(data);
|
|
118
|
+
|
|
119
|
+
case 'upce':
|
|
120
|
+
return this.validateUPCE(data);
|
|
121
|
+
|
|
122
|
+
case 'qrcode':
|
|
123
|
+
return this.validateQRCode(data);
|
|
124
|
+
|
|
125
|
+
case 'datamatrix':
|
|
126
|
+
return this.validateDataMatrix(data);
|
|
127
|
+
|
|
128
|
+
case 'pdf417':
|
|
129
|
+
return this.validatePDF417(data);
|
|
130
|
+
|
|
131
|
+
default:
|
|
132
|
+
// For other types, just check if data is not empty
|
|
133
|
+
return {
|
|
134
|
+
valid: data.length > 0,
|
|
135
|
+
error: data.length === 0 ? 'Data cannot be empty' : null,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Validate Code 128 data
|
|
142
|
+
* @param {string} data - The data to validate
|
|
143
|
+
* @param {string} type - The Code 128 variant
|
|
144
|
+
* @returns {Object} Validation result
|
|
145
|
+
*/
|
|
146
|
+
validateCode128(data) {
|
|
147
|
+
// Code 128 supports ASCII characters
|
|
148
|
+
if (!/^[\x00-\x7F]+$/.test(data)) {
|
|
149
|
+
return {
|
|
150
|
+
valid: false,
|
|
151
|
+
error: 'Code 128 supports ASCII characters only',
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return { valid: true };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Validate Code 39 data
|
|
160
|
+
* @param {string} data - The data to validate
|
|
161
|
+
* @param {string} type - The Code 39 variant
|
|
162
|
+
* @returns {Object} Validation result
|
|
163
|
+
*/
|
|
164
|
+
validateCode39(data, type) {
|
|
165
|
+
if (type === 'code39extended') {
|
|
166
|
+
// Extended Code 39 supports full ASCII
|
|
167
|
+
if (!/^[\x00-\x7F]+$/.test(data)) {
|
|
168
|
+
return {
|
|
169
|
+
valid: false,
|
|
170
|
+
error: 'Extended Code 39 supports ASCII characters only',
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
// Standard Code 39 supports limited character set
|
|
175
|
+
if (!this.patterns.code39.test(data)) {
|
|
176
|
+
return {
|
|
177
|
+
valid: false,
|
|
178
|
+
error: 'Code 39 supports characters: A-Z, 0-9, space, -.$/+%',
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return { valid: true };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Validate Code 93 data
|
|
188
|
+
* @param {string} data - The data to validate
|
|
189
|
+
* @returns {Object} Validation result
|
|
190
|
+
*/
|
|
191
|
+
validateCode93(data) {
|
|
192
|
+
if (!this.patterns.alphanumeric.test(data)) {
|
|
193
|
+
return {
|
|
194
|
+
valid: false,
|
|
195
|
+
error: 'Code 93 supports alphanumeric characters only',
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return { valid: true };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Validate EAN-13 data
|
|
204
|
+
* @param {string} data - The data to validate
|
|
205
|
+
* @returns {Object} Validation result
|
|
206
|
+
*/
|
|
207
|
+
validateEAN13(data) {
|
|
208
|
+
if (!this.patterns.ean13.test(data)) {
|
|
209
|
+
return {
|
|
210
|
+
valid: false,
|
|
211
|
+
error: 'EAN-13 must be 12 or 13 digits',
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Validate check digit if 13 digits provided
|
|
216
|
+
if (data.length === 13) {
|
|
217
|
+
const checkDigit = this.calculateEANCheckDigit(data.substring(0, 12));
|
|
218
|
+
if (parseInt(data[12]) !== checkDigit) {
|
|
219
|
+
return {
|
|
220
|
+
valid: false,
|
|
221
|
+
error: 'Invalid EAN-13 check digit',
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return { valid: true };
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Validate EAN-8 data
|
|
231
|
+
* @param {string} data - The data to validate
|
|
232
|
+
* @returns {Object} Validation result
|
|
233
|
+
*/
|
|
234
|
+
validateEAN8(data) {
|
|
235
|
+
if (!this.patterns.ean8.test(data)) {
|
|
236
|
+
return {
|
|
237
|
+
valid: false,
|
|
238
|
+
error: 'EAN-8 must be 7 or 8 digits',
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Validate check digit if 8 digits provided
|
|
243
|
+
if (data.length === 8) {
|
|
244
|
+
const checkDigit = this.calculateEANCheckDigit(data.substring(0, 7));
|
|
245
|
+
if (parseInt(data[7]) !== checkDigit) {
|
|
246
|
+
return {
|
|
247
|
+
valid: false,
|
|
248
|
+
error: 'Invalid EAN-8 check digit',
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return { valid: true };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Validate UPC-A data
|
|
258
|
+
* @param {string} data - The data to validate
|
|
259
|
+
* @returns {Object} Validation result
|
|
260
|
+
*/
|
|
261
|
+
validateUPCA(data) {
|
|
262
|
+
if (!this.patterns.upca.test(data)) {
|
|
263
|
+
return {
|
|
264
|
+
valid: false,
|
|
265
|
+
error: 'UPC-A must be 11 or 12 digits',
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return { valid: true };
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Validate UPC-E data
|
|
274
|
+
* @param {string} data - The data to validate
|
|
275
|
+
* @returns {Object} Validation result
|
|
276
|
+
*/
|
|
277
|
+
validateUPCE(data) {
|
|
278
|
+
if (!this.patterns.upce.test(data)) {
|
|
279
|
+
return {
|
|
280
|
+
valid: false,
|
|
281
|
+
error: 'UPC-E must be 6 to 8 digits',
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return { valid: true };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Validate QR Code data
|
|
290
|
+
* @param {string} data - The data to validate
|
|
291
|
+
* @returns {Object} Validation result
|
|
292
|
+
*/
|
|
293
|
+
validateQRCode(data) {
|
|
294
|
+
// QR Code supports Unicode, so we just check if it's not empty
|
|
295
|
+
if (data.length === 0) {
|
|
296
|
+
return {
|
|
297
|
+
valid: false,
|
|
298
|
+
error: 'QR Code data cannot be empty',
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return { valid: true };
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Validate Data Matrix data
|
|
307
|
+
* @param {string} data - The data to validate
|
|
308
|
+
* @returns {Object} Validation result
|
|
309
|
+
*/
|
|
310
|
+
validateDataMatrix(data) {
|
|
311
|
+
if (data.length === 0) {
|
|
312
|
+
return {
|
|
313
|
+
valid: false,
|
|
314
|
+
error: 'Data Matrix data cannot be empty',
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return { valid: true };
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Validate PDF417 data
|
|
323
|
+
* @param {string} data - The data to validate
|
|
324
|
+
* @returns {Object} Validation result
|
|
325
|
+
*/
|
|
326
|
+
validatePDF417(data) {
|
|
327
|
+
if (data.length === 0) {
|
|
328
|
+
return {
|
|
329
|
+
valid: false,
|
|
330
|
+
error: 'PDF417 data cannot be empty',
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return { valid: true };
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Calculate EAN check digit
|
|
339
|
+
* @param {string} data - The data without check digit
|
|
340
|
+
* @returns {number} Check digit
|
|
341
|
+
*/
|
|
342
|
+
calculateEANCheckDigit(data) {
|
|
343
|
+
let sum = 0;
|
|
344
|
+
for (let i = 0; i < data.length; i++) {
|
|
345
|
+
const digit = parseInt(data[i]);
|
|
346
|
+
sum += i % 2 === 0 ? digit : digit * 3;
|
|
347
|
+
}
|
|
348
|
+
return (10 - (sum % 10)) % 10;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
module.exports = { Validator };
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for BarcodeGenerator
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const BarcodeGenerator = require('../index');
|
|
6
|
+
|
|
7
|
+
describe('BarcodeGenerator', () => {
|
|
8
|
+
describe('PNG Generation', () => {
|
|
9
|
+
test('should generate PNG barcode', () => {
|
|
10
|
+
const result = BarcodeGenerator.png('1234567890', 'code128');
|
|
11
|
+
expect(Buffer.isBuffer(result)).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('should generate PNG barcode with options', () => {
|
|
15
|
+
const options = {
|
|
16
|
+
width: 3,
|
|
17
|
+
height: 150,
|
|
18
|
+
displayValue: false,
|
|
19
|
+
};
|
|
20
|
+
const result = BarcodeGenerator.png('1234567890', 'code128', options);
|
|
21
|
+
expect(Buffer.isBuffer(result)).toBe(true);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('should throw error for invalid data', () => {
|
|
25
|
+
expect(() => {
|
|
26
|
+
BarcodeGenerator.png('', 'code128');
|
|
27
|
+
}).toThrow('Data must be a non-empty string');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('should throw error for invalid barcode type', () => {
|
|
31
|
+
expect(() => {
|
|
32
|
+
BarcodeGenerator.png('1234567890', 'invalid-type');
|
|
33
|
+
}).toThrow('Invalid barcode type');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('SVG Generation', () => {
|
|
38
|
+
test('should generate SVG barcode', () => {
|
|
39
|
+
const result = BarcodeGenerator.svg('1234567890', 'code128');
|
|
40
|
+
expect(typeof result).toBe('string');
|
|
41
|
+
expect(result).toContain('<svg');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test('should generate SVG barcode with options', () => {
|
|
45
|
+
const options = {
|
|
46
|
+
width: 3,
|
|
47
|
+
height: 150,
|
|
48
|
+
displayValue: false,
|
|
49
|
+
};
|
|
50
|
+
const result = BarcodeGenerator.svg('1234567890', 'code128', options);
|
|
51
|
+
expect(typeof result).toBe('string');
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('HTML Generation', () => {
|
|
56
|
+
test('should generate HTML barcode', () => {
|
|
57
|
+
const result = BarcodeGenerator.html('1234567890', 'code128');
|
|
58
|
+
expect(typeof result).toBe('string');
|
|
59
|
+
expect(result).toContain('<div');
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('should generate HTML barcode with options', () => {
|
|
63
|
+
const options = {
|
|
64
|
+
width: 3,
|
|
65
|
+
height: 150,
|
|
66
|
+
displayValue: false,
|
|
67
|
+
};
|
|
68
|
+
const result = BarcodeGenerator.html('1234567890', 'code128', options);
|
|
69
|
+
expect(typeof result).toBe('string');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('PDF Generation', () => {
|
|
74
|
+
test('should generate PDF barcode', async () => {
|
|
75
|
+
const result = await BarcodeGenerator.pdf('1234567890', 'code128');
|
|
76
|
+
expect(Buffer.isBuffer(result)).toBe(true);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('should generate PDF barcode with options', async () => {
|
|
80
|
+
const options = {
|
|
81
|
+
width: 3,
|
|
82
|
+
height: 150,
|
|
83
|
+
displayValue: false,
|
|
84
|
+
};
|
|
85
|
+
const result = await BarcodeGenerator.pdf(
|
|
86
|
+
'1234567890',
|
|
87
|
+
'code128',
|
|
88
|
+
options
|
|
89
|
+
);
|
|
90
|
+
expect(Buffer.isBuffer(result)).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('QR Code Generation', () => {
|
|
95
|
+
test('should generate QR code', () => {
|
|
96
|
+
const result = BarcodeGenerator.modernQr({
|
|
97
|
+
data: 'https://example.com',
|
|
98
|
+
size: 300,
|
|
99
|
+
});
|
|
100
|
+
expect(result).toBeDefined();
|
|
101
|
+
expect(typeof result.generate).toBe('function');
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('should generate QR code with logo', () => {
|
|
105
|
+
const result = BarcodeGenerator.modernQr({
|
|
106
|
+
data: 'https://example.com',
|
|
107
|
+
size: 300,
|
|
108
|
+
logoPath: 'path/to/logo.png',
|
|
109
|
+
logoSize: 60,
|
|
110
|
+
});
|
|
111
|
+
expect(result).toBeDefined();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('should generate QR code with watermark', () => {
|
|
115
|
+
const result = BarcodeGenerator.modernQr({
|
|
116
|
+
data: 'https://example.com',
|
|
117
|
+
size: 300,
|
|
118
|
+
watermark: 'Watermark Text',
|
|
119
|
+
watermarkPosition: 'center',
|
|
120
|
+
});
|
|
121
|
+
expect(result).toBeDefined();
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
describe('Validation', () => {
|
|
126
|
+
test('should validate data for Code 128', () => {
|
|
127
|
+
const validation = BarcodeGenerator.validate('1234567890', 'code128');
|
|
128
|
+
expect(validation.valid).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test('should validate data for EAN-13', () => {
|
|
132
|
+
const validation = BarcodeGenerator.validate('1234567890123', 'ean13');
|
|
133
|
+
expect(validation.valid).toBe(true);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test('should reject invalid data for EAN-13', () => {
|
|
137
|
+
const validation = BarcodeGenerator.validate('123', 'ean13');
|
|
138
|
+
expect(validation.valid).toBe(false);
|
|
139
|
+
expect(validation.error).toContain('too short');
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('Batch Generation', () => {
|
|
144
|
+
test('should generate multiple barcodes', () => {
|
|
145
|
+
const items = [
|
|
146
|
+
{ data: '1234567890', type: 'code128', format: 'png' },
|
|
147
|
+
{ data: '9876543210', type: 'code39', format: 'svg' },
|
|
148
|
+
];
|
|
149
|
+
const results = BarcodeGenerator.batch(items);
|
|
150
|
+
expect(Array.isArray(results)).toBe(true);
|
|
151
|
+
expect(results.length).toBe(2);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test('should handle batch generation errors', () => {
|
|
155
|
+
const items = [
|
|
156
|
+
{ data: '1234567890', type: 'code128', format: 'png' },
|
|
157
|
+
{ data: '', type: 'code128', format: 'png' }, // Invalid data
|
|
158
|
+
];
|
|
159
|
+
const results = BarcodeGenerator.batch(items);
|
|
160
|
+
expect(results[0].success).toBe(true);
|
|
161
|
+
expect(results[1].success).toBe(false);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
describe('Utility Methods', () => {
|
|
166
|
+
test('should get barcode types', () => {
|
|
167
|
+
const types = BarcodeGenerator.getBarcodeTypes();
|
|
168
|
+
expect(Array.isArray(types)).toBe(true);
|
|
169
|
+
expect(types).toContain('code128');
|
|
170
|
+
expect(types).toContain('ean13');
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test('should get render formats', () => {
|
|
174
|
+
const formats = BarcodeGenerator.getRenderFormats();
|
|
175
|
+
expect(Array.isArray(formats)).toBe(true);
|
|
176
|
+
expect(formats).toContain('png');
|
|
177
|
+
expect(formats).toContain('svg');
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test('should get watermark positions', () => {
|
|
181
|
+
const positions = BarcodeGenerator.getWatermarkPositions();
|
|
182
|
+
expect(Array.isArray(positions)).toBe(true);
|
|
183
|
+
expect(positions).toContain('center');
|
|
184
|
+
expect(positions).toContain('top-left');
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for BarcodeService
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const BarcodeService = require('../src/services/BarcodeService');
|
|
6
|
+
|
|
7
|
+
describe('BarcodeService', () => {
|
|
8
|
+
let service;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
service = new BarcodeService();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
describe('PNG Generation', () => {
|
|
15
|
+
test('should generate PNG barcode', () => {
|
|
16
|
+
const result = service.png('1234567890', 'code128');
|
|
17
|
+
expect(Buffer.isBuffer(result)).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('should generate PNG barcode with options', () => {
|
|
21
|
+
const options = {
|
|
22
|
+
width: 3,
|
|
23
|
+
height: 150,
|
|
24
|
+
displayValue: false,
|
|
25
|
+
};
|
|
26
|
+
const result = service.png('1234567890', 'code128', options);
|
|
27
|
+
expect(Buffer.isBuffer(result)).toBe(true);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('SVG Generation', () => {
|
|
32
|
+
test('should generate SVG barcode', () => {
|
|
33
|
+
const result = service.svg('1234567890', 'code128');
|
|
34
|
+
expect(typeof result).toBe('string');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe('HTML Generation', () => {
|
|
39
|
+
test('should generate HTML barcode', () => {
|
|
40
|
+
const result = service.html('1234567890', 'code128');
|
|
41
|
+
expect(typeof result).toBe('string');
|
|
42
|
+
expect(result).toContain('<div');
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe('PDF Generation', () => {
|
|
47
|
+
test('should generate PDF barcode', async () => {
|
|
48
|
+
const result = await service.pdf('1234567890', 'code128');
|
|
49
|
+
expect(Buffer.isBuffer(result)).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('Validation', () => {
|
|
54
|
+
test('should validate data', () => {
|
|
55
|
+
const validation = service.validate('1234567890', 'code128');
|
|
56
|
+
expect(validation.valid).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('should reject invalid data', () => {
|
|
60
|
+
const validation = service.validate('', 'code128');
|
|
61
|
+
expect(validation.valid).toBe(false);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('Batch Generation', () => {
|
|
66
|
+
test('should generate multiple barcodes', () => {
|
|
67
|
+
const items = [
|
|
68
|
+
{ data: '1234567890', type: 'code128', format: 'png' },
|
|
69
|
+
{ data: '9876543210', type: 'code39', format: 'svg' },
|
|
70
|
+
];
|
|
71
|
+
const results = service.batch(items);
|
|
72
|
+
expect(Array.isArray(results)).toBe(true);
|
|
73
|
+
expect(results.length).toBe(2);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
});
|