import { describe, expect, it } from 'vitest'; import { formatCooldown, formatDuration, formatMultiplier, formatScore, formatSequence, sanitizeName, validateName, } from '../../app/static/js/logic/format.js'; describe('Formatierung', () => { it('formatiert Punkte mit Tausenderpunkt', () => { expect(formatScore(0)).toBe('0'); expect(formatScore(1234567)).toBe('1.234.567'); expect(formatScore(-5)).toBe('0'); }); it('formatiert Dauer als m:ss', () => { expect(formatDuration(0)).toBe('0:00'); expect(formatDuration(65_400)).toBe('1:05'); expect(formatDuration(3_600_000)).toBe('60:00'); }); it('formatiert Richtungsfolgen als Pfeile', () => { expect(formatSequence(['up', 'right', 'down', 'left'])).toBe('↑ → ↓ ←'); expect(formatSequence(['left', 'left'], ' ')).toBe('← ←'); expect(formatSequence(['quer'])).toBe('?'); }); it('formatiert Multiplikator und Abklingzeit mit Dezimalkomma', () => { expect(formatMultiplier(1)).toBe('×1'); expect(formatMultiplier(2.5)).toBe('×2,5'); expect(formatCooldown(0)).toBe(''); expect(formatCooldown(12_100)).toBe('13'); expect(formatCooldown(800)).toBe('0,8'); }); }); // Dieselben Fälle wie tests/test_validation.py – Frontend und Backend müssen gleich bereinigen. describe('sanitizeName (gleich wie Backend)', () => { const ZWSP = String.fromCodePoint(0x200b); const RLO = String.fromCodePoint(0x202e); const cases = [ ['Ada', 'Ada'], [' Max Muster ', 'Max Muster'], ['Jürg Größli', 'Jürg Größli'], ['Fullwidth', 'Fullwidth'], ['Null\u0000Byte', 'NullByte'], [`Zero${ZWSP}Width`, 'ZeroWidth'], [`Bidi${RLO}Trick`, 'BidiTrick'], ['Tab\tNeu\nZeile', 'TabNeuZeile'], ['', 'scriptalert1script'], ["O'Neil-Test!?", "O'Neil-Test!?"], ['Emoji 🚀 Held', 'Emoji Held'], ['', ''], ]; it.each(cases)('%j → %j', (raw, expected) => { expect(sanitizeName(raw)).toBe(expected); }); }); describe('validateName', () => { it('akzeptiert gültige Namen bis 16 Zeichen', () => { expect(validateName(' Kadettin Ada ')).toEqual({ ok: true, name: 'Kadettin Ada' }); expect(validateName('N'.repeat(16)).ok).toBe(true); }); it('lehnt leere und zu lange Namen ab', () => { expect(validateName(' ').ok).toBe(false); expect(validateName('<>').ok).toBe(false); expect(validateName('N'.repeat(17)).ok).toBe(false); }); });