Barcode-Adapter nimmt Codearten entgegen, Adapter-Weiche je Funktion

decodeBarcodes(imageData, formats) bekommt die zu suchenden Codearten
uebergeben; ohne Angabe unveraendertes Verhalten (Code128 + DataMatrix).

buildRecognitionAdapters() baut daraus und aus dem echten OCR-Adapter
die an recognize() (pipeline.js, unveraendert) uebergebenen Adapter:
in Strichcode/QR-Code liefert die Texterkennung sofort leeren Text ohne
Tesseract anzustossen, in Text-erkennen liefert die Barcode-Dekodierung
sofort eine leere Liste ohne zxing-wasm anzustossen.
This commit is contained in:
2026-07-29 13:37:05 +02:00
parent 9ef038ca98
commit 2eb9d1ecf8
3 changed files with 124 additions and 3 deletions
+79
View File
@@ -0,0 +1,79 @@
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { buildRecognitionAdapters } from '../src/scan-recognition.js';
import { recognize } from '../src/pipeline.js';
test('Funktion 1: Texterkennung wird nicht aufgerufen, auch wenn kein Code gefunden wird', async () => {
let ocrCalled = false;
const adapters = buildRecognitionAdapters('barcode', {
decodeBarcodes: async () => [],
runOcr: async () => { ocrCalled = true; return 'irgendein Text'; },
});
const result = await recognize({}, adapters);
assert.equal(ocrCalled, false, 'runOcr darf in Funktion 1 nie aufgerufen werden');
assert.equal(result.confidence, 'red');
});
test('Funktion 2: Texterkennung wird nicht aufgerufen, auch wenn kein Code gefunden wird', async () => {
let ocrCalled = false;
const adapters = buildRecognitionAdapters('qrcode', {
decodeBarcodes: async () => [],
runOcr: async () => { ocrCalled = true; return 'irgendein Text'; },
});
const result = await recognize({}, adapters);
assert.equal(ocrCalled, false, 'runOcr darf in Funktion 2 nie aufgerufen werden');
assert.equal(result.confidence, 'red');
});
test('Funktion 3: Barcode-Dekodierung wird nicht aufgerufen', async () => {
let barcodeCalled = false;
const adapters = buildRecognitionAdapters('ocr', {
decodeBarcodes: async () => { barcodeCalled = true; return []; },
runOcr: async () => '64GB 4DRx4 PC4-2400T-LD1-11-MC0 M386A8K40BM1-CRC4Y 1908',
});
const result = await recognize({}, adapters);
assert.equal(barcodeCalled, false, 'decodeBarcodes darf in Funktion 3 nie aufgerufen werden');
assert.equal(result.source, 'ocr');
assert.equal(result.confidence, 'yellow');
});
test('Funktion 1: ein gelesener Strichcode fuehrt zu Gruen', async () => {
const adapters = buildRecognitionAdapters('barcode', {
decodeBarcodes: async () => ['M386A8K40BM1-CRC4Y'],
runOcr: async () => '',
});
const result = await recognize({}, adapters);
assert.equal(result.source, 'barcode');
assert.equal(result.confidence, 'green');
});
test('Funktion 3: kein brauchbarer Text fuehrt zu Rot, nicht zu Gruen', async () => {
const adapters = buildRecognitionAdapters('ocr', {
decodeBarcodes: async () => { throw new Error('darf nicht aufgerufen werden'); },
runOcr: async () => 'Made in Philippines',
});
const result = await recognize({}, adapters);
assert.equal(result.source, 'none');
assert.equal(result.confidence, 'red');
});
test('decodeBarcodes bekommt die Codearten der jeweiligen Funktion uebergeben', async () => {
let receivedFormats = null;
const adapters = buildRecognitionAdapters('qrcode', {
decodeBarcodes: async (_imageData, formats) => { receivedFormats = formats; return []; },
runOcr: async () => '',
});
await adapters.decodeBarcodes({});
assert.deepEqual(receivedFormats, ['QRCode', 'MicroQRCode', 'RMQRCode']);
});
test('Funktion 3 uebergibt keine Codearten, weil decodeBarcodes gar nicht aufgerufen wird', async () => {
let called = false;
const adapters = buildRecognitionAdapters('ocr', {
decodeBarcodes: async () => { called = true; return []; },
runOcr: async () => '',
});
const codes = await adapters.decodeBarcodes({});
assert.deepEqual(codes, []);
assert.equal(called, false);
});