/** * Tests for Format Utilities * FE-TEST-004: Test all format utility functions */ import { describe, it, expect } from 'vitest'; import { formatFileSize, formatNumber, formatCurrency, formatPercentage, truncate, capitalize, capitalizeWords, slugify, initials, formatUsername, formatEmail, formatPhoneNumber, formatBytes, formatDuration, formatTimeAgo, formatList, formatPlural, } from './format'; describe('format utilities', () => { describe('formatFileSize', () => { it('should format bytes', () => { expect(formatFileSize(0)).toBe('0 Bytes'); expect(formatFileSize(500)).toBe('500 Bytes'); }); it('should format KB', () => { expect(formatFileSize(1024)).toBe('1 KB'); expect(formatFileSize(2048)).toBe('2 KB'); }); it('should format MB', () => { expect(formatFileSize(1048576)).toBe('1 MB'); }); it('should format GB', () => { expect(formatFileSize(1073741824)).toBe('1 GB'); }); }); describe('formatNumber', () => { it('should format numbers less than 1000', () => { expect(formatNumber(500)).toBe('500'); expect(formatNumber(999)).toBe('999'); }); it('should format thousands', () => { expect(formatNumber(1500)).toBe('1.5K'); expect(formatNumber(9999)).toBe('10.0K'); }); it('should format millions', () => { expect(formatNumber(1500000)).toBe('1.5M'); }); it('should format billions', () => { expect(formatNumber(1500000000)).toBe('1.5B'); }); }); describe('formatCurrency', () => { it('should format EUR by default', () => { const result = formatCurrency(1234.56); expect(result).toContain('1'); expect(result).toContain('234'); }); it('should format USD', () => { const result = formatCurrency(1234.56, 'USD'); expect(result).toBeTruthy(); expect(typeof result).toBe('string'); }); }); describe('formatPercentage', () => { it('should format percentage with default decimals', () => { expect(formatPercentage(0.5)).toBe('50.0%'); expect(formatPercentage(0.123)).toBe('12.3%'); }); it('should format percentage with custom decimals', () => { expect(formatPercentage(0.5, 2)).toBe('50.00%'); expect(formatPercentage(0.123, 0)).toBe('12%'); }); }); describe('truncate', () => { it('should truncate long text', () => { expect(truncate('Hello World', 5)).toBe('He...'); }); it('should not truncate short text', () => { expect(truncate('Hello', 10)).toBe('Hello'); }); it('should use custom suffix', () => { expect(truncate('Hello World', 5, '…')).toBe('Hell…'); }); }); describe('capitalize', () => { it('should capitalize first letter', () => { expect(capitalize('hello')).toBe('Hello'); expect(capitalize('WORLD')).toBe('World'); }); }); describe('capitalizeWords', () => { it('should capitalize each word', () => { expect(capitalizeWords('hello world')).toBe('Hello World'); expect(capitalizeWords('john doe')).toBe('John Doe'); }); }); describe('slugify', () => { it('should create slug from text', () => { expect(slugify('Hello World')).toBe('hello-world'); expect(slugify('Test 123')).toBe('test-123'); }); it('should remove special characters', () => { expect(slugify('Hello@World!')).toBe('helloworld'); }); it('should handle multiple spaces', () => { expect(slugify('Hello World')).toBe('hello-world'); }); }); describe('initials', () => { it('should extract initials', () => { expect(initials('John Doe')).toBe('JD'); expect(initials('John')).toBe('J'); }); it('should handle single word', () => { expect(initials('John')).toBe('J'); }); it('should handle multiple words', () => { expect(initials('John Michael Doe')).toBe('JM'); }); }); describe('formatUsername', () => { it('should add @ prefix', () => { expect(formatUsername('john')).toBe('@john'); }); }); describe('formatEmail', () => { it('should mask email', () => { expect(formatEmail('john.doe@example.com')).toBe('joh***@example.com'); }); it('should handle short local part', () => { expect(formatEmail('ab@example.com')).toBe('ab@example.com'); }); }); describe('formatPhoneNumber', () => { it('should format French phone number', () => { expect(formatPhoneNumber('0612345678')).toBe('06 12 34 56 78'); }); it('should handle already formatted numbers', () => { expect(formatPhoneNumber('06 12 34 56 78')).toBe('06 12 34 56 78'); }); }); describe('formatBytes', () => { it('should format bytes with default decimals', () => { expect(formatBytes(0)).toBe('0 Bytes'); expect(formatBytes(1024)).toBe('1 KB'); }); it('should format with custom decimals', () => { // parseFloat removes trailing zeros, so 1.000 becomes 1 expect(formatBytes(1024, 3)).toBe('1 KB'); // Test with a value that actually shows decimals expect(formatBytes(1536, 3)).toBe('1.5 KB'); }); }); describe('formatDuration', () => { it('should format seconds', () => { expect(formatDuration(45)).toBe('0:45'); }); it('should format minutes and seconds', () => { expect(formatDuration(125)).toBe('2:05'); }); it('should format hours', () => { expect(formatDuration(3665)).toBe('1:01:05'); }); }); describe('formatTimeAgo', () => { it('should format recent time', () => { const now = new Date(); const result = formatTimeAgo(now); expect(result).toBe("À l'instant"); }); it('should format minutes ago', () => { const past = new Date(Date.now() - 30 * 60 * 1000); const result = formatTimeAgo(past); expect(result).toContain('min'); }); }); describe('formatList', () => { it('should format empty list', () => { expect(formatList([])).toBe(''); }); it('should format single item', () => { expect(formatList(['apple'])).toBe('apple'); }); it('should format two items', () => { expect(formatList(['apple', 'banana'])).toBe('apple et banana'); }); it('should format multiple items', () => { expect(formatList(['apple', 'banana', 'cherry'])).toBe('apple, banana et cherry'); }); it('should use custom conjunction', () => { expect(formatList(['apple', 'banana'], 'ou')).toBe('apple ou banana'); }); }); describe('formatPlural', () => { it('should format singular', () => { expect(formatPlural(1, 'item')).toBe('1 item'); }); it('should format plural', () => { expect(formatPlural(2, 'item')).toBe('2 items'); }); it('should use custom plural', () => { expect(formatPlural(2, 'child', 'children')).toBe('2 children'); }); }); });