Files
gridpilot.gg/adapters/bootstrap/racing/SeedIdHelper.test.ts
2025-12-29 19:44:11 +01:00

128 lines
4.3 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { stableUuidFromSeedKey, seedId, seedUuid } from './SeedIdHelper';
describe('SeedIdHelper', () => {
describe('stableUuidFromSeedKey', () => {
it('should return a valid UUID v4 format', () => {
const uuid = stableUuidFromSeedKey('team-3');
// UUID v4 format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
// where y is one of [8, 9, a, b]
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
expect(uuid).toMatch(uuidRegex);
});
it('should be deterministic - same input produces same output', () => {
const input = 'driver-1';
const uuid1 = stableUuidFromSeedKey(input);
const uuid2 = stableUuidFromSeedKey(input);
expect(uuid1).toBe(uuid2);
});
it('should produce different UUIDs for different inputs', () => {
const uuid1 = stableUuidFromSeedKey('team-1');
const uuid2 = stableUuidFromSeedKey('team-2');
expect(uuid1).not.toBe(uuid2);
});
it('should handle various seed patterns', () => {
const testCases = [
'team-3',
'driver-1',
'league-5',
'race-10',
'sponsor-1',
'season-1',
'demo-sponsor-1',
'league-3-season-a',
'team-join-team-1-driver-5',
'dup-team-join-req-1',
];
testCases.forEach((seed) => {
const uuid = stableUuidFromSeedKey(seed);
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
expect(uuid).toMatch(uuidRegex);
expect(uuid.length).toBe(36);
});
});
it('should handle empty string', () => {
const uuid = stableUuidFromSeedKey('');
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
expect(uuid).toMatch(uuidRegex);
});
it('should handle long seed strings', () => {
const longSeed = 'a'.repeat(1000);
const uuid = stableUuidFromSeedKey(longSeed);
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
expect(uuid).toMatch(uuidRegex);
});
});
describe('seedId', () => {
it('should return UUID for postgres mode', () => {
const result = seedId('team-3', 'postgres');
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
expect(result).toMatch(uuidRegex);
});
it('should return original string for inmemory mode', () => {
const result = seedId('team-3', 'inmemory');
expect(result).toBe('team-3');
});
it('should be deterministic for postgres mode', () => {
const result1 = seedId('driver-5', 'postgres');
const result2 = seedId('driver-5', 'postgres');
expect(result1).toBe(result2);
});
it('should preserve original string for inmemory mode', () => {
const testCases = ['team-3', 'driver-1', 'league-5', 'race-10'];
testCases.forEach((seed) => {
const result = seedId(seed, 'inmemory');
expect(result).toBe(seed);
});
});
});
describe('seedUuid', () => {
it('should return a valid UUID', () => {
const uuid = seedUuid('team-3');
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
expect(uuid).toMatch(uuidRegex);
});
it('should be deterministic', () => {
const uuid1 = seedUuid('driver-1');
const uuid2 = seedUuid('driver-1');
expect(uuid1).toBe(uuid2);
});
it('should produce different UUIDs for different inputs', () => {
const uuid1 = seedUuid('team-1');
const uuid2 = seedUuid('team-2');
expect(uuid1).not.toBe(uuid2);
});
});
describe('UUID v4 compliance', () => {
it('should have version 4 bits set correctly', () => {
const uuid = stableUuidFromSeedKey('test');
// Version is in the 13th character (0-indexed), should be '4'
expect(uuid.charAt(14)).toBe('4');
});
it('should have variant bits set correctly', () => {
const uuid = stableUuidFromSeedKey('test');
// Variant is in the 19th character (0-indexed), should be 8, 9, a, or b
const variantChar = uuid.charAt(19);
expect(['8', '9', 'a', 'b']).toContain(variantChar.toLowerCase());
});
});
});