Skip to main content
Glama
generateStableId.test.ts4.49 kB
/** * Tests for generateStableId utility */ import { describe, it, expect } from 'vitest'; import Chance from 'chance'; import { generateStableId } from '../../src/utils/generateStableId'; /** Seeded random generator for reproducible tests */ const chance = new Chance(12345); /** Valid character set used by generateStableId */ const VALID_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789'; /** Default ID length */ const DEFAULT_LENGTH = 8; /** * Fixed iteration count for statistical distribution tests. * Using a constant ensures reproducible statistical analysis. */ const DISTRIBUTION_TEST_ITERATIONS = 1000; /** Character frequency count map for distribution testing */ interface CharacterCountMap { [char: string]: number; } describe('generateStableId', () => { describe('default behavior', () => { it('should generate ID with default length of 8', () => { const id = generateStableId(); expect(id).toHaveLength(DEFAULT_LENGTH); }); it('should generate lowercase alphanumeric characters only', () => { const id = generateStableId(); expect(id).toMatch(/^[a-z0-9]+$/); }); it('should generate different IDs on multiple calls', () => { const ids = new Set<string>(); const iterations = chance.integer({ min: 50, max: 100 }); for (let i = 0; i < iterations; i++) { ids.add(generateStableId()); } // Should have at least 95% unique IDs (allowing for very rare collisions) expect(ids.size).toBeGreaterThanOrEqual(Math.floor(iterations * 0.95)); }); }); describe('custom length', () => { it('should generate ID with specified short length', () => { const length = chance.integer({ min: 1, max: 5 }); const id = generateStableId(length); expect(id).toHaveLength(length); }); it('should generate ID with specified medium length', () => { const length = chance.integer({ min: 10, max: 20 }); const id = generateStableId(length); expect(id).toHaveLength(length); }); it('should generate ID with length of 1', () => { const id = generateStableId(1); expect(id).toHaveLength(1); expect(id).toMatch(/^[a-z0-9]$/); }); it('should generate empty string with length of 0', () => { const id = generateStableId(0); expect(id).toBe(''); }); }); describe('character distribution', () => { it('should use only characters from the valid character set', () => { const iterations = chance.integer({ min: 50, max: 100 }); const length = chance.integer({ min: 16, max: 32 }); for (let i = 0; i < iterations; i++) { const id = generateStableId(length); for (const char of id) { expect(VALID_CHARS).toContain(char); } } }); it('should produce reasonable character distribution over many IDs', () => { const charCounts: CharacterCountMap = {}; const iterations = DISTRIBUTION_TEST_ITERATIONS; const idLength = VALID_CHARS.length; // Use length equal to charset size for (let i = 0; i < iterations; i++) { const id = generateStableId(idLength); for (const char of id) { charCounts[char] = (charCounts[char] || 0) + 1; } } const totalChars = iterations * idLength; const expectedPerChar = totalChars / VALID_CHARS.length; for (const char of VALID_CHARS) { // Allow for some variance - each char should appear at least 50% of expected expect(charCounts[char] || 0).toBeGreaterThan(expectedPerChar * 0.5); } }); }); describe('edge cases', () => { it('should handle large length values', () => { const largeLength = chance.integer({ min: 500, max: 1000 }); const id = generateStableId(largeLength); expect(id).toHaveLength(largeLength); expect(id).toMatch(/^[a-z0-9]+$/); }); it('should not throw error for negative length', () => { expect(() => generateStableId(-1)).not.toThrow(); const id = generateStableId(-1); // Function returns empty string for negative length (graceful handling) expect(id).toBe(''); }); it('should not throw error for non-integer length input', () => { expect(() => generateStableId(5.7)).not.toThrow(); const id = generateStableId(5.7); // Should truncate to integer behavior expect(id.length).toBeLessThanOrEqual(6); expect(id).toMatch(/^[a-z0-9]*$/); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AgiFlow/aicode-toolkit'

If you have feedback or need assistance with the MCP directory API, please join our Discord server