import { describe, expect, it } from 'vitest' import { uuidv7 } from '@/lib/uuidv7' /** * Auf der Sortierbarkeit dieser Kennungen beruhen zwei Dinge: die * Nachlieferung verpasster Nachrichten (`id > seit`) und die Reihenfolge im * Chat. Bricht sie, kommen Nachrichten durcheinander an oder gehen bei einem * Wiederverbinden verloren - beides fällt spät und unangenehm auf. */ describe('UUIDv7', () => { it('hat die richtige Form, Version und Variante', () => { const id = uuidv7() expect(id).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/) }) it('trägt den Zeitstempel in den ersten 48 Bit', () => { // Muss über allem liegen, was vorherige Aufrufe schon vergeben haben: // der Zähler im Modul geht bewusst nie zurück. const zeitpunkt = Date.now() + 60_000 const id = uuidv7(zeitpunkt) const hex = id.replace(/-/g, '').slice(0, 12) expect(Number.parseInt(hex, 16)).toBe(zeitpunkt) }) it('bleibt innerhalb derselben Millisekunde sortierbar', () => { // Ohne Zähler kämen zwei schnell hintereinander gesendete Nachrichten in // zufälliger Reihenfolge an. const zeitpunkt = Date.now() const ids = Array.from({ length: 500 }, () => uuidv7(zeitpunkt)) expect([...ids].sort()).toEqual(ids) expect(new Set(ids).size).toBe(ids.length) }) it('sortiert über Millisekunden hinweg', () => { const frueh = uuidv7(1_700_000_000_000) const spaet = uuidv7(1_700_000_000_001) expect(frueh < spaet).toBe(true) }) it('fällt bei einer zurückspringenden Uhr nicht zurück', () => { // Sommerzeit, NTP-Korrektur: die Reihenfolge ist wichtiger als der genaue // Zeitpunkt, sonst überholt eine neue Nachricht eine alte. const vorher = uuidv7(1_800_000_000_000) const nachher = uuidv7(1_700_000_000_000) expect(nachher > vorher).toBe(true) }) })