Added scanning barcodes with a camera
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('2 of 5 Decoder Tests', () => {
|
||||
const twoOf5TestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': '9577149002', format: '2of5' },
|
||||
{ 'name': 'image-002.jpg', 'result': '9577149002', format: '2of5' },
|
||||
{ 'name': 'image-003.jpg', 'result': '5776158811', format: '2of5' },
|
||||
{ 'name': 'image-004.jpg', 'result': '0463381455', format: '2of5' },
|
||||
{ 'name': 'image-005.jpg', 'result': '3261594101', format: '2of5', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-006.jpg', 'result': '3261594101', format: '2of5', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-007.jpg', 'result': '3261594101', format: '2of5' },
|
||||
{ 'name': 'image-008.jpg', 'result': '6730705801', format: '2of5' },
|
||||
{ 'name': 'image-009.jpg', 'result': '5776158811', format: '2of5' },
|
||||
{ 'name': 'image-010.jpg', 'result': '5776158811', format: '2of5' },
|
||||
];
|
||||
runDecoderTestBothHalfSample('2of5', (halfSample) => generateConfig({
|
||||
inputStream: { size: 800, singleChannel: false },
|
||||
locator: {
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['2of5_reader'],
|
||||
},
|
||||
}), twoOf5TestSet);
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('Codabar Decoder Tests', () => {
|
||||
const codabarTestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': 'A10/53+17-70D', format: 'codabar' },
|
||||
{ 'name': 'image-002.jpg', 'result': 'B546745735B', format: 'codabar' },
|
||||
{ 'name': 'image-003.jpg', 'result': 'C$399.95A', format: 'codabar' },
|
||||
{ 'name': 'image-004.jpg', 'result': 'B546745735B', format: 'codabar' },
|
||||
{ 'name': 'image-005.jpg', 'result': 'C$399.95A', format: 'codabar' },
|
||||
{ 'name': 'image-006.jpg', 'result': 'B546745735B', format: 'codabar' },
|
||||
{ 'name': 'image-007.jpg', 'result': 'C$399.95A', format: 'codabar' },
|
||||
{ 'name': 'image-008.jpg', 'result': 'A16:9/4:3/3:2D', format: 'codabar', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-009.jpg', 'result': 'C$399.95A', format: 'codabar' },
|
||||
{ 'name': 'image-010.jpg', 'result': 'C$399.95A', format: 'codabar' },
|
||||
];
|
||||
runDecoderTestBothHalfSample('codabar', (halfSample) => generateConfig({
|
||||
locator: {
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['codabar_reader']
|
||||
}
|
||||
}), codabarTestSet);
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('Code 128 Decoder Tests', () => {
|
||||
// Note: FNC1 characters are represented as ASCII 29 (Group Separator, \x1D or \u001d)
|
||||
// These are used in GS1-128 barcodes as field separators
|
||||
const FNC1 = String.fromCharCode(29);
|
||||
const code128TestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': '0001285112001000040801', format: 'code_128' },
|
||||
{ 'name': 'image-002.jpg', 'result': 'FANAVF14617104', format: 'code_128' },
|
||||
{ 'name': 'image-003.jpg', 'result': '673023', format: 'code_128', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-004.jpg', 'result': '010210150301625334', format: 'code_128', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-005.jpg', 'result': '419055603900009001012999', format: 'code_128' },
|
||||
{ 'name': 'image-006.jpg', 'result': '419055603900009001012999', format: 'code_128' },
|
||||
// GS1-128 barcode with FNC1 characters as field separators
|
||||
{ 'name': 'image-007.jpg', 'result': `${FNC1}42095747${FNC1}9499907123456123456781`, format: 'code_128' },
|
||||
{ 'name': 'image-008.jpg', 'result': '1020185021797280784055', format: 'code_128' },
|
||||
{ 'name': 'image-009.jpg', 'result': '0001285112001000040801', format: 'code_128' },
|
||||
{ 'name': 'image-010.jpg', 'result': '673023', format: 'code_128' },
|
||||
// TODO: need to implement having different inputStream parameters to be able to
|
||||
// read this one -- it works only with inputStream size set to 1600 presently, but
|
||||
// other samples break at that high a size.
|
||||
// { name: 'image-011.png', result: '33c64780-a9c0-e92a-820c-fae7011c11e2' },
|
||||
// GS1-128 barcodes from issue #390 - real-world food packaging barcodes
|
||||
// image-012 works with halfSample: false, but not with halfSample: true
|
||||
{ 'name': 'image-012.jpg', 'result': '01906641589574681121102531020003402152731515', format: 'code_128', allowFailInNode: true, allowFailInBrowser: true },
|
||||
// image-013 and image-014 require higher resolution settings to decode properly
|
||||
// According to issue #390, image-013 needs size: 1280, patchSize: 'small'
|
||||
// and image-014 needs size: 1600, patchSize: 'large'
|
||||
{ 'name': 'image-013.jpg', 'result': '', format: 'code_128', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-014.jpg', 'result': '', format: 'code_128', allowFailInNode: true, allowFailInBrowser: true },
|
||||
];
|
||||
runDecoderTestBothHalfSample('code_128', (halfSample) => generateConfig({
|
||||
inputStream: {
|
||||
size: 800,
|
||||
singleChannel: false,
|
||||
},
|
||||
locator: {
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['code_128_reader'],
|
||||
},
|
||||
}), code128TestSet);
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('Code 32 Decoder Tests', () => {
|
||||
const code32TestSet = [
|
||||
{ name: 'image-1.jpg', result: 'A123456788', format: 'code_32_reader' },
|
||||
{ name: 'image-2.jpg', result: 'A931028462', format: 'code_32_reader', allowFailInNode: true },
|
||||
{ name: 'image-3.jpg', result: 'A931028462', format: 'code_32_reader', allowFailInNode: true },
|
||||
{ name: 'image-4.jpg', result: 'A935776043', format: 'code_32_reader' },
|
||||
{ name: 'image-5.jpg', result: 'A935776043', format: 'code_32_reader' },
|
||||
{ name: 'image-6.jpg', result: 'A012745182', format: 'code_32_reader', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ name: 'image-7.jpg', result: 'A029651039', format: 'code_32_reader', allowFailInNode: true },
|
||||
{ name: 'image-8.jpg', result: 'A029651039', format: 'code_32_reader', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ name: 'image-9.jpg', result: 'A015896018', format: 'code_32_reader' },
|
||||
{ name: 'image-10.jpg', result: 'A015896018', format: 'code_32_reader' },
|
||||
];
|
||||
runDecoderTestBothHalfSample('code_32', (halfSample) => generateConfig({
|
||||
inputStream: {
|
||||
size: 1280,
|
||||
},
|
||||
locator: {
|
||||
patchSize: 'large',
|
||||
halfSample,
|
||||
},
|
||||
numOfWorkers: 4,
|
||||
decoder: {
|
||||
readers: ['code_32_reader']
|
||||
}
|
||||
}), code32TestSet);
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('Code 39 Decoder Tests', () => {
|
||||
const code39TestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': 'B3% $DAD$', format: 'code_39' },
|
||||
{ 'name': 'image-003.jpg', 'result': 'CODE39', format: 'code_39' },
|
||||
{ 'name': 'image-004.jpg', 'result': 'QUAGGAJS', format: 'code_39' },
|
||||
{ 'name': 'image-005.jpg', 'result': 'CODE39', format: 'code_39', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-006.jpg', 'result': '2/4-8/16-32', format: 'code_39' },
|
||||
{ 'name': 'image-007.jpg', 'result': '2/4-8/16-32', format: 'code_39' },
|
||||
{ 'name': 'image-008.jpg', 'result': 'CODE39', format: 'code_39' },
|
||||
{ 'name': 'image-009.jpg', 'result': '2/4-8/16-32', format: 'code_39' },
|
||||
// TODO: image 10 in this set appears to be dependent upon #191
|
||||
{ 'name': 'image-010.jpg', 'result': 'CODE39', format: 'code_39' },
|
||||
{ 'name': 'image-011.jpg', 'result': '4', format: 'code_39', allowFailInNode: true, allowFailInBrowser: true },
|
||||
];
|
||||
runDecoderTestBothHalfSample('code_39', (halfSample) => generateConfig({
|
||||
locator: {
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['code_39_reader'],
|
||||
}
|
||||
}), code39TestSet);
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('Code 39 VIN Decoder Tests', () => {
|
||||
const code39VinTestSet = [
|
||||
{ name: 'image-001.jpg', result: '2HGFG1B86BH501831', format: 'code_39_vin' },
|
||||
{ name: 'image-002.jpg', result: 'JTDKB20U887718156', format: 'code_39_vin', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ name: 'image-003.jpg', result: 'JM1BK32G071773697', format: 'code_39_vin' },
|
||||
{ name: 'image-004.jpg', result: 'WDBTK75G94T028954', format: 'code_39_vin', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ name: 'image-005.jpg', result: '3VW2K7AJ9EM381173', format: 'code_39_vin' },
|
||||
{ name: 'image-006.jpg', result: 'JM1BL1H4XA1335663', format: 'code_39_vin' },
|
||||
{ name: 'image-007.jpg', result: 'JHMGE8H42AS021233', format: 'code_39_vin', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ name: 'image-008.jpg', result: 'WMEEJ3BA4DK652562', format: 'code_39_vin', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ name: 'image-009.jpg', result: 'WMEEJ3BA4DK652562', format: 'code_39_vin', allowFailInNode: true, allowFailInBrowser: true }, //yes, 8 and 9 are same barcodes, different images slightly
|
||||
{ name: 'image-010.jpg', result: 'WMEEJ3BA4DK652562', format: 'code_39_vin', allowFailInNode: true, allowFailInBrowser: true }, // 10 also
|
||||
{ name: 'image-011.jpg', result: '5FNRL38488B411196', format: 'code_39_vin' },
|
||||
];
|
||||
runDecoderTestBothHalfSample('code_39_vin', (halfSample) => generateConfig({
|
||||
inputStream: {
|
||||
size: 2200, // 2x scaling (from 1100x658) provides optimal detection accuracy
|
||||
sequence: false,
|
||||
},
|
||||
locator: {
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['code_39_vin_reader'],
|
||||
},
|
||||
}), code39VinTestSet);
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('Code 93 Decoder Tests', () => {
|
||||
const code93TestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': 'WIWV8ETQZ1', format: 'code_93' },
|
||||
{ 'name': 'image-002.jpg', 'result': 'EH3C-%GU23RK3', format: 'code_93' },
|
||||
{ 'name': 'image-003.jpg', 'result': 'O308SIHQOXN5SA/PJ', format: 'code_93', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-004.jpg', 'result': 'DG7Q$TV8JQ/EN', format: 'code_93', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-005.jpg', 'result': 'DG7Q$TV8JQ/EN', format: 'code_93', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-006.jpg', 'result': 'O308SIHQOXN5SA/PJ', format: 'code_93' },
|
||||
{ 'name': 'image-007.jpg', 'result': 'VOFD1DB5A.1F6QU', format: 'code_93', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-008.jpg', 'result': 'WIWV8ETQZ1', format: 'code_93', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-009.jpg', 'result': '4SO64P4X8 U4YUU1T-', format: 'code_93' },
|
||||
{ 'name': 'image-010.jpg', 'result': '4SO64P4X8 U4YUU1T-', format: 'code_93', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-011.jpg', result: '11169', format: 'code_93' },
|
||||
];
|
||||
runDecoderTestBothHalfSample('code_93', (halfSample) => generateConfig({
|
||||
inputStream: { size: 800, singleChannel: false },
|
||||
locator: {
|
||||
patchSize: 'large',
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['code_93_reader'],
|
||||
},
|
||||
}), code93TestSet);
|
||||
});
|
||||
17
quagga2/quagga2-1.12.1/test/integration/decoders/ean.spec.ts
Normal file
17
quagga2/quagga2-1.12.1/test/integration/decoders/ean.spec.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('EAN Decoder Tests', () => {
|
||||
const eanTestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': '3574660239843', format: 'ean_13' },
|
||||
{ 'name': 'image-002.jpg', 'result': '8032754490297', format: 'ean_13' },
|
||||
{ 'name': 'image-004.jpg', 'result': '9002233139084', format: 'ean_13' },
|
||||
{ 'name': 'image-003.jpg', 'result': '4006209700068', format: 'ean_13' },
|
||||
{ 'name': 'image-005.jpg', 'result': '8004030044005', format: 'ean_13' },
|
||||
{ 'name': 'image-006.jpg', 'result': '4003626011159', format: 'ean_13' },
|
||||
{ 'name': 'image-007.jpg', 'result': '2111220009686', format: 'ean_13' },
|
||||
{ 'name': 'image-008.jpg', 'result': '9000275609022', format: 'ean_13' },
|
||||
{ 'name': 'image-009.jpg', 'result': '9004593978587', format: 'ean_13' },
|
||||
{ 'name': 'image-010.jpg', 'result': '9002244845578', format: 'ean_13' },
|
||||
];
|
||||
runDecoderTestBothHalfSample('ean', (halfSample) => generateConfig({ locator: { halfSample } }), eanTestSet);
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('EAN-8 Decoder Tests', () => {
|
||||
const ean8TestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': '42191605', format: 'ean_8' },
|
||||
{ 'name': 'image-002.jpg', 'result': '42191605', format: 'ean_8' },
|
||||
{ 'name': 'image-003.jpg', 'result': '90311208', format: 'ean_8', allowFailInBrowser: true },
|
||||
{ 'name': 'image-004.jpg', 'result': '24057257', format: 'ean_8' },
|
||||
// {"name": "image-005.jpg", "result": "90162602"},
|
||||
{ 'name': 'image-006.jpg', 'result': '24036153', format: 'ean_8' },
|
||||
// {"name": "image-007.jpg", "result": "42176817"},
|
||||
{ 'name': 'image-008.jpg', 'result': '42191605', format: 'ean_8' },
|
||||
{ 'name': 'image-009.jpg', 'result': '42242215', format: 'ean_8', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-010.jpg', 'result': '42184799', format: 'ean_8' },
|
||||
];
|
||||
runDecoderTestBothHalfSample('ean_8', (halfSample) => generateConfig({
|
||||
locator: {
|
||||
patchSize: 'large',
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['ean_8_reader']
|
||||
}
|
||||
}), ean8TestSet);
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('EAN Extended Decoder Tests', () => {
|
||||
// Note: The main result's format is 'ean_13' (the parent barcode format).
|
||||
// The supplement's format is available in result.codeResult.supplement.format
|
||||
// and will correctly be 'ean_2' or 'ean_5' depending on the supplement type.
|
||||
const eanExtendedTestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': '900437801102701', format: 'ean_13', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-002.jpg', 'result': '419871600890101', format: 'ean_13' },
|
||||
{ 'name': 'image-003.jpg', 'result': '419871600890101', format: 'ean_13', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-004.jpg', 'result': '978054466825652495', format: 'ean_13' },
|
||||
{ 'name': 'image-005.jpg', 'result': '419664190890712', format: 'ean_13', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-006.jpg', 'result': '412056690699101', format: 'ean_13', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-007.jpg', 'result': '419204531290601', format: 'ean_13' },
|
||||
{ 'name': 'image-008.jpg', 'result': '419871600890101', format: 'ean_13' },
|
||||
{ 'name': 'image-009.jpg', 'result': '978054466825652495', format: 'ean_13' },
|
||||
{ 'name': 'image-010.jpg', 'result': '900437801102701', format: 'ean_13' },
|
||||
];
|
||||
runDecoderTestBothHalfSample('ean_extended', (halfSample) => generateConfig({
|
||||
inputStream: {
|
||||
size: 800,
|
||||
singleChannel: false,
|
||||
},
|
||||
locator: {
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: [{
|
||||
format: 'ean_reader',
|
||||
config: {
|
||||
supplements: [
|
||||
'ean_5_reader',
|
||||
'ean_2_reader',
|
||||
],
|
||||
},
|
||||
}],
|
||||
},
|
||||
}), eanExtendedTestSet);
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
import Quagga from '../../../src/quagga';
|
||||
import { expect } from 'chai';
|
||||
import { it } from '../helpers';
|
||||
|
||||
describe('EAN Supplement Format Tests', () => {
|
||||
// Test that verifies the supplement format is correctly returned as 'ean_2' or 'ean_5'
|
||||
// rather than inheriting the parent 'ean_13' format
|
||||
|
||||
const isBrowser = typeof window !== 'undefined';
|
||||
const fixturePrefix = isBrowser ? '/' : '';
|
||||
|
||||
const baseConfig = {
|
||||
inputStream: {
|
||||
size: 800,
|
||||
singleChannel: false,
|
||||
},
|
||||
locator: {
|
||||
patchSize: 'medium' as const,
|
||||
halfSample: false,
|
||||
},
|
||||
numOfWorkers: 0,
|
||||
decoder: {
|
||||
readers: [{
|
||||
format: 'ean_reader',
|
||||
config: {
|
||||
supplements: [
|
||||
'ean_5_reader',
|
||||
'ean_2_reader',
|
||||
],
|
||||
},
|
||||
}],
|
||||
},
|
||||
};
|
||||
|
||||
it('should return ean_2 format for 2-digit supplement', async function() {
|
||||
this.timeout(30000);
|
||||
|
||||
const config = {
|
||||
...baseConfig,
|
||||
src: `${fixturePrefix}test/fixtures/ean_extended/image-002.jpg`, // EAN-13 with 2-digit supplement
|
||||
};
|
||||
|
||||
const result = await Quagga.decodeSingle(config);
|
||||
|
||||
expect(result).to.be.an('Object');
|
||||
expect(result.codeResult).to.be.an('Object');
|
||||
expect(result.codeResult.format).to.equal('ean_13');
|
||||
expect(result.codeResult.supplement).to.be.an('Object');
|
||||
expect(result.codeResult.supplement.format).to.equal('ean_2');
|
||||
expect(result.codeResult.supplement.code).to.equal('01');
|
||||
});
|
||||
|
||||
it('should return ean_5 format for 5-digit supplement', async function() {
|
||||
this.timeout(30000);
|
||||
|
||||
const config = {
|
||||
...baseConfig,
|
||||
src: `${fixturePrefix}test/fixtures/ean_extended/image-004.jpg`, // EAN-13 with 5-digit supplement
|
||||
};
|
||||
|
||||
const result = await Quagga.decodeSingle(config);
|
||||
|
||||
expect(result).to.be.an('Object');
|
||||
expect(result.codeResult).to.be.an('Object');
|
||||
expect(result.codeResult.format).to.equal('ean_13');
|
||||
expect(result.codeResult.supplement).to.be.an('Object');
|
||||
expect(result.codeResult.supplement.format).to.equal('ean_5');
|
||||
expect(result.codeResult.supplement.code).to.equal('52495');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('Interleaved 2 of 5 Decoder Tests', () => {
|
||||
const i2of5TestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': '2167361334', format: 'i2of5' },
|
||||
{ 'name': 'image-002.jpg', 'result': '2167361334', format: 'i2of5' },
|
||||
{ 'name': 'image-003.jpg', 'result': '2167361334', format: 'i2of5' },
|
||||
{ 'name': 'image-004.jpg', 'result': '2167361334', format: 'i2of5' },
|
||||
{ 'name': 'image-005.jpg', 'result': '2167361334', format: 'i2of5' },
|
||||
];
|
||||
runDecoderTestBothHalfSample('i2of5', (halfSample) => generateConfig({
|
||||
inputStream: { size: 1375, singleChannel: false }, // 1.25x scaling (from 1100x658) provides optimal detection
|
||||
locator: {
|
||||
patchSize: 'small',
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['i2of5_reader'],
|
||||
},
|
||||
}), i2of5TestSet);
|
||||
});
|
||||
@@ -0,0 +1,129 @@
|
||||
import { runDecoderTestBothHalfSample, runNoCodeTest, generateConfig } from '../helpers';
|
||||
|
||||
describe('Pharmacode Decoder Tests', () => {
|
||||
// Synthetic test images with known values
|
||||
// Note: Tests only run with halfSample: false currently work reliably
|
||||
// halfSample: true causes bar width detection issues for some images
|
||||
const pharmacodeTestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': '3', format: 'pharmacode' },
|
||||
{ 'name': 'image-002.jpg', 'result': '7', format: 'pharmacode' },
|
||||
{ 'name': 'image-003.jpg', 'result': '12', format: 'pharmacode' },
|
||||
{ 'name': 'image-004.jpg', 'result': '15', format: 'pharmacode' },
|
||||
{ 'name': 'image-005.jpg', 'result': '64', format: 'pharmacode' },
|
||||
{ 'name': 'image-006.jpg', 'result': '100', format: 'pharmacode' },
|
||||
{ 'name': 'image-007.jpg', 'result': '255', format: 'pharmacode' },
|
||||
{ 'name': 'image-008.jpg', 'result': '755', format: 'pharmacode' },
|
||||
{ 'name': 'image-009.jpg', 'result': '1000', format: 'pharmacode' },
|
||||
{ 'name': 'image-010.jpg', 'result': '4096', format: 'pharmacode' },
|
||||
{ 'name': 'image-011.jpg', 'result': '12345', format: 'pharmacode' },
|
||||
{ 'name': 'image-012.jpg', 'result': '65535', format: 'pharmacode' },
|
||||
];
|
||||
|
||||
// Real-world test images added by @ericblade
|
||||
// Images 013, 014, 018 contain Pharmacode value 123456
|
||||
// Image 017 contains multiple barcodes: 4174 and 3715
|
||||
// Images 015, 016 have unknown values
|
||||
|
||||
const pharmacodeRealWorldPositiveTestSet = [
|
||||
{ 'name': 'image-013.png', 'result': '123456', format: 'pharmacode' },
|
||||
// image-014 is two-track pharmacode, not supported at the moment -- maybe not ever depending on difficulty level
|
||||
// { 'name': 'image-014.png', 'result': '123456', format: 'pharmacode' },
|
||||
];
|
||||
|
||||
// image-018 requires a constrained scan window to avoid false positives elsewhere in the frame
|
||||
// still working out how to fix the false positive from the "orange and white" barcode.
|
||||
const pharmacodeRealWorldAreaConstrainedTestSet = [
|
||||
{ 'name': 'image-018.png', 'result': '123456', format: 'pharmacode' },
|
||||
];
|
||||
|
||||
// Images intentionally expected to decode nothing (should succeed with empty result)
|
||||
const pharmacodeRealWorldNoCodeTestSet = [
|
||||
{ 'name': 'image-015.png', 'result': '', format: 'pharmacode' },
|
||||
{ 'name': 'image-016.png', 'result': '', format: 'pharmacode' },
|
||||
{ 'name': 'image-016-sheared.png', 'result': '', format: 'pharmacode' },
|
||||
{ 'name': 'image-017.png', 'result': '', format: 'pharmacode' },
|
||||
];
|
||||
|
||||
// Cross-barcode rejection: i2of5 images should be rejected by pharmacode reader
|
||||
// This ensures the pharmacode reader doesn't accidentally decode other barcode types
|
||||
const pharmacodeCrossBarcodeRejectionTestSet = [
|
||||
{ 'name': 'image-011.jpg', 'result': '', format: 'pharmacode' },
|
||||
];
|
||||
|
||||
// Use locate: false since test images are synthetically generated and pre-cropped to contain only the barcode (location detection not required)
|
||||
runDecoderTestBothHalfSample('pharmacode set 1', (halfSample) => generateConfig({
|
||||
locate: false,
|
||||
locator: {
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['pharmacode_reader']
|
||||
}
|
||||
}), pharmacodeTestSet, 'pharmacode');
|
||||
|
||||
runDecoderTestBothHalfSample('pharmacode set 2', (halfSample) => generateConfig({
|
||||
locate: false,
|
||||
inputStream: {
|
||||
size: 800,
|
||||
},
|
||||
locator: {
|
||||
halfSample,
|
||||
patchSize: 'large',
|
||||
},
|
||||
decoder: {
|
||||
readers: ['pharmacode_reader']
|
||||
}
|
||||
}), pharmacodeRealWorldPositiveTestSet, 'pharmacode');
|
||||
|
||||
// Dedicated run for image-018 with a narrowed search area (bottom 50%) - top 50% has an unreadable code
|
||||
runDecoderTestBothHalfSample('pharmacode area constrained', (halfSample) => generateConfig({
|
||||
locate: false,
|
||||
inputStream: {
|
||||
size: 800,
|
||||
area: {
|
||||
top: '50%',
|
||||
},
|
||||
},
|
||||
locator: {
|
||||
halfSample,
|
||||
patchSize: 'large',
|
||||
},
|
||||
decoder: {
|
||||
readers: ['pharmacode_reader']
|
||||
}
|
||||
}), pharmacodeRealWorldAreaConstrainedTestSet, 'pharmacode');
|
||||
|
||||
// Explicitly validate that certain images decode to nothing (empty barcodes array)
|
||||
[true, false].forEach((halfSample) => {
|
||||
runNoCodeTest(`pharmacode SHOULD NOT DECODE halfSample:${halfSample}`, generateConfig({
|
||||
locate: false,
|
||||
inputStream: {
|
||||
size: 800,
|
||||
},
|
||||
locator: {
|
||||
halfSample,
|
||||
patchSize: 'large',
|
||||
},
|
||||
decoder: {
|
||||
readers: ['pharmacode_reader']
|
||||
}
|
||||
}), pharmacodeRealWorldNoCodeTestSet, 'pharmacode');
|
||||
});
|
||||
|
||||
// Cross-barcode rejection: Pharmacode reader should reject other barcode types (e.g., i2of5)
|
||||
[true, false].forEach((halfSample) => {
|
||||
runNoCodeTest(`pharmacode rejects i2of5 barcodes halfSample:${halfSample}`, generateConfig({
|
||||
locate: false,
|
||||
inputStream: {
|
||||
size: 800,
|
||||
},
|
||||
locator: {
|
||||
halfSample,
|
||||
patchSize: 'large',
|
||||
},
|
||||
decoder: {
|
||||
readers: ['pharmacode_reader']
|
||||
}
|
||||
}), pharmacodeCrossBarcodeRejectionTestSet, 'i2of5');
|
||||
});
|
||||
});
|
||||
24
quagga2/quagga2-1.12.1/test/integration/decoders/upc.spec.ts
Normal file
24
quagga2/quagga2-1.12.1/test/integration/decoders/upc.spec.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('UPC-A Decoder Tests', () => {
|
||||
const upcTestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': '882428015268', format: 'upc_a' },
|
||||
{ 'name': 'image-002.jpg', 'result': '882428015268', format: 'upc_a' },
|
||||
{ 'name': 'image-003.jpg', 'result': '882428015084', format: 'upc_a' },
|
||||
{ 'name': 'image-004.jpg', 'result': '882428015343', format: 'upc_a' },
|
||||
{ 'name': 'image-005.jpg', 'result': '882428015343', format: 'upc_a' },
|
||||
{ 'name': 'image-006.jpg', 'result': '882428015046', format: 'upc_a', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-007.jpg', 'result': '882428015084', format: 'upc_a' },
|
||||
{ 'name': 'image-008.jpg', 'result': '882428015046', format: 'upc_a' },
|
||||
{ 'name': 'image-009.jpg', 'result': '039047013551', format: 'upc_a' },
|
||||
{ 'name': 'image-010.jpg', 'result': '039047013551', format: 'upc_a', allowFailInNode: true, allowFailInBrowser: true },
|
||||
];
|
||||
runDecoderTestBothHalfSample('upc', (halfSample) => generateConfig({
|
||||
locator: {
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['upc_reader']
|
||||
}
|
||||
}), upcTestSet);
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
import { runDecoderTestBothHalfSample, generateConfig } from '../helpers';
|
||||
|
||||
describe('UPC-E Decoder Tests', () => {
|
||||
const upcETestSet = [
|
||||
{ 'name': 'image-001.jpg', 'result': '04965802', format: 'upc_e', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-002.jpg', 'result': '04965802', format: 'upc_e' },
|
||||
{ 'name': 'image-003.jpg', 'result': '03897425', format: 'upc_e' },
|
||||
{ 'name': 'image-004.jpg', 'result': '05096893', format: 'upc_e' },
|
||||
{ 'name': 'image-005.jpg', 'result': '05096893', format: 'upc_e', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-006.jpg', 'result': '05096893', format: 'upc_e' },
|
||||
{ 'name': 'image-007.jpg', 'result': '03897425', format: 'upc_e', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-008.jpg', 'result': '01264904', format: 'upc_e', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-009.jpg', 'result': '01264904', format: 'upc_e', allowFailInNode: true, allowFailInBrowser: true },
|
||||
{ 'name': 'image-010.jpg', 'result': '01264904', format: 'upc_e', allowFailInNode: true, allowFailInBrowser: true },
|
||||
];
|
||||
runDecoderTestBothHalfSample('upc_e', (halfSample) => generateConfig({
|
||||
locator: {
|
||||
halfSample,
|
||||
},
|
||||
decoder: {
|
||||
readers: ['upc_e_reader']
|
||||
}
|
||||
}), upcETestSet);
|
||||
});
|
||||
Reference in New Issue
Block a user