From 8199d25a6e719a1b9195c7d25b0e90b937fe90d7 Mon Sep 17 00:00:00 2001 From: vchuser Date: Tue, 28 Jul 2026 14:21:47 +0200 Subject: [PATCH] Fix: canonical() und matchKnown() behandeln Zahlen wie Zeichenketten MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit canonical() und matchKnown() stützen sich auf normalizeToken(), das bei Nicht-Strings '' zurückgibt. Dies führt dazu, dass bereits geparste Zahlenwerte lautlos ignoriert werden: canonical(64) liefert '' statt '64', matchKnown(64, list) liefert null statt den gefundenen Wert. Die Behebung konvertiert Zahlen zu Zeichenketten, bevor sie normalizeToken() erreichen, ohne null/undefined zu ändern (diese ergeben weiterhin ''/'null). Alle 23 Tests grün. Co-Authored-By: Claude Opus 5 (1M context) --- src/spec.js | 10 ++++++++-- test/spec-match.test.js | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/spec.js b/src/spec.js index 6853260..3af00cd 100644 --- a/src/spec.js +++ b/src/spec.js @@ -70,7 +70,10 @@ const CONFUSIONS = { /** Vergleichsform eines Tokens: normalisiert, ohne Trennzeichen, verwechslungsfrei. */ export function canonical(raw) { - const normalized = normalizeToken(raw).replace(/[^A-Z0-9]/g, ''); + // Konvertiere Zahlen zu Zeichenketten, aber nicht null/undefined + const token = typeof raw === 'number' ? String(raw) : raw; + + const normalized = normalizeToken(token).replace(/[^A-Z0-9]/g, ''); let out = ''; for (const char of normalized) { out += CONFUSIONS[char] ?? char; @@ -83,7 +86,10 @@ export function canonical(raw) { * Erst exakt, dann ueber die Vergleichsform. Mehrdeutigkeit gilt als Treffer-los. */ export function matchKnown(raw, list) { - const normalized = normalizeToken(raw); + // Konvertiere Zahlen zu Zeichenketten, aber nicht null/undefined + const token = typeof raw === 'number' ? String(raw) : raw; + + const normalized = normalizeToken(token); if (normalized === '') return null; for (const candidate of list) { diff --git a/test/spec-match.test.js b/test/spec-match.test.js index 60094c9..fc86f22 100644 --- a/test/spec-match.test.js +++ b/test/spec-match.test.js @@ -56,3 +56,29 @@ test('specsCompatible toleriert eine Verwechslung in der Teilenummer', () => { const b = { ...emptySpec(), capacityGb: 64, partNumber: 'M386A8K4OBM1-CRC4Y' }; assert.equal(specsCompatible(a, b), true); }); + +test('matchKnown findet einen Zahlenwert in der Liste', () => { + assert.equal(matchKnown(64, KNOWN.capacityGb), 64); + assert.equal(matchKnown(128, KNOWN.capacityGb), 128); +}); + +test('canonical behandelt Zahlen wie Zeichenketten', () => { + assert.equal(canonical(64), canonical('64')); + assert.equal(canonical(128), canonical('128')); +}); + +test('canonical mit null ergibt Leerzeichenkette', () => { + assert.equal(canonical(null), ''); +}); + +test('canonical mit undefined ergibt Leerzeichenkette', () => { + assert.equal(canonical(undefined), ''); +}); + +test('matchKnown mit null ergibt null', () => { + assert.equal(matchKnown(null, KNOWN.capacityGb), null); +}); + +test('matchKnown mit undefined ergibt null', () => { + assert.equal(matchKnown(undefined, KNOWN.capacityGb), null); +});