Files
rippy/rippy-windows/test/messung.metadaten.test.ts
T
HitonabiandClaude Opus 5 38a3a87f70
Ampel / ampel (push) Successful in 1m38s
fix(v5): Disc-Erkennung — die Disc selbst befragen statt raten
Der Commander legte Disc 2 von „Spartacus: Gods of the Arena" ein, Rippy
meldete den FILM „Spartacus" von 1960. An der echten Disc gemessen
(Laufwerk G:, Label SPARTACUS_GOTA_D2, UDF, 33.759.100.928 Bytes): Der
stark gestutzte Kandidat „Spartacus" stand auf Platz 2 der Suchvarianten
und holte dort einen wörtlichen Filmtreffer mit 95 Prozent — die richtige
Serie stand auf Platz 6 und wurde nie gefragt.

Vier Ursachen, alle behoben:

1. Die Sicherheit maß die ART des Treffers, nie die QUALITÄT der Frage.
   Neu: abdeckung() + MINDEST_ABDECKUNG — wer mehr als die Hälfte des
   Titels wegwerfen musste, um zu treffen, bekommt höchstens einen
   Vorschlag (0,60), und das UI fragt nach, statt sich sicher zu irren.

2. Verpackungs-Zusätze galten als Wortmüll. Neu: discZusatzAbtrennen()
   trennt "- Disc 2" / "_D2" / "S1" ab UND merkt sie — die Nummer braucht
   die Ablage später sowieso. Vier Fallen sind abgesichert: "Rocky 2",
   "Kill Bill Teil 2", "Ocean s 11" (Apostroph-Wortgrenze) und nackte
   Zahlen am Ende.

3. Der Titelvergleich war zeichengenau. Ein Volume-Label KANN keinen
   Doppelpunkt tragen, TMDb schreibt ihn — der exakt richtige Treffer
   fiel an einem Satzzeichen durch. Neu: gleichBedeutend().

4. Rippy öffnete das Inhaltsverzeichnis der Disc und las nur die erste
   Zeile daraus. Neu: inhaltAusBdmt() liest auch <di:titleName>. "EP 1"
   und "EP 2" beweisen die Serie, "DUB GER 1" und "104 GER FSK" nicht.
   Ist die Serie bewiesen, sind die Film-Zweige der Kaskade AUS.

Gemessen an der eingelegten Disc (neue messung.disc-erkennung.test.ts):
  Titel "Spartacus: Gods Of The Arena - Disc 2" (Quelle: bdmt)
  Disc 2 | Staffel — | Folgen 2 | Serie bewiesen: true
  Varianten: "...Arena - Disc 2" -> "...Arena" -> ... -> "Spartacus"

225 Tests grün (vorher 209), Typprüfung sauber. Disc-Nummer, Staffel und
Folgenzahl stehen jetzt auch im Fenster (Kachel neben der Erkennung).

Version 5.1.1 — zugleich der erste echte Selbst-Update-Beweis (§ 6.8).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 17:31:56 +02:00

50 lines
1.9 KiB
TypeScript

// MESSUNG gegen die echten Metadaten-APIs (TMDb/OMDb) — läuft nur auf
// Verlangen und mit Schlüsseln aus der Umgebung (nie committet):
//
// RIPPY_MESSUNG_META=1 RIPPY_TMDB_KEY=… RIPPY_OMDB_KEY=… \
// npx vitest run test/messung.metadaten.test.ts --reporter=verbose
import { describe, expect, it } from 'vitest'
const messen = process.env.RIPPY_MESSUNG_META === '1'
const tmdbKey = process.env.RIPPY_TMDB_KEY ?? ''
const omdbKey = process.env.RIPPY_OMDB_KEY ?? ''
// Echte Disc-Titel-Fälle aus dem Projektalltag: der saubere Studio-Titel,
// der spezifische Fall (Evangelion-Fund), ein kryptisches Label und eine
// Serien-Disc.
const FAELLE = [
'Akira',
'Evangelion 2.22',
'Spartacus Gods Of The Arena',
// Der echte Studio-Titel der Disc vom 01.09.2026 — MIT Doppelpunkt und
// Verpackungs-Zusatz, genau so, wie er von der Disc kommt.
'Spartacus: Gods Of The Arena - Disc 2',
'Bd Evg D2',
]
describe.skipIf(!messen)('Zuordnung gegen echte APIs', () => {
it('ordnet die Projekt-Fälle zu', { timeout: 120_000 }, async () => {
expect(tmdbKey.length, 'RIPPY_TMDB_KEY fehlt').toBeGreaterThan(0)
const { TmdbClient } = await import('../src/kern/metadaten/tmdb')
const { OmdbClient } = await import('../src/kern/metadaten/omdb')
const { zuordnen } = await import('../src/kern/metadaten/zuordnung')
const tmdb = new TmdbClient(tmdbKey)
const omdb = new OmdbClient(omdbKey)
for (const fall of FAELLE) {
const z = await zuordnen(fall, tmdb, omdb)
console.log(
`MESSUNG „${fall}" → „${z.titel}"${z.jahr !== null ? ` (${z.jahr})` : ''} · ` +
`${Math.round(z.confidence * 100)} % · ${z.meta.quelle || 'keine Quelle'} · ${z.meta.typ}`,
)
expect(z.confidence).toBeGreaterThan(0)
}
})
})
describe.skipIf(messen)('Metadaten-Messung übersprungen', () => {
it('läuft nur mit RIPPY_MESSUNG_META=1', () => {
expect(true).toBe(true)
})
})