veza/apps/web/src/utils/format.test.ts

257 lines
6.8 KiB
TypeScript

/**
* 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');
});
});
});