|
| 1 | +import { describe, expect, it } from 'vitest' |
| 2 | +import { |
| 3 | + decodeHtmlEntities, |
| 4 | + formatBytes, |
| 5 | + formatCompactNumber, |
| 6 | + toIsoDateString, |
| 7 | +} from '../../../../app/utils/formatters' |
| 8 | + |
| 9 | +describe('toIsoDateString', () => { |
| 10 | + it('formats a date as YYYY-MM-DD', () => { |
| 11 | + expect(toIsoDateString(new Date('2024-03-15T00:00:00Z'))).toBe('2024-03-15') |
| 12 | + }) |
| 13 | + |
| 14 | + it('pads single-digit month and day', () => { |
| 15 | + expect(toIsoDateString(new Date('2024-01-05T00:00:00Z'))).toBe('2024-01-05') |
| 16 | + }) |
| 17 | +}) |
| 18 | + |
| 19 | +describe('decodeHtmlEntities', () => { |
| 20 | + it.each([ |
| 21 | + ['&', '&'], |
| 22 | + ['<', '<'], |
| 23 | + ['>', '>'], |
| 24 | + ['"', '"'], |
| 25 | + [''', "'"], |
| 26 | + [''', "'"], |
| 27 | + [' ', ' '], |
| 28 | + ] as const)('%s → %s', (input, expected) => { |
| 29 | + expect(decodeHtmlEntities(input)).toBe(expected) |
| 30 | + }) |
| 31 | + |
| 32 | + it('decodes multiple entities in one string', () => { |
| 33 | + expect(decodeHtmlEntities('a & b < c')).toBe('a & b < c') |
| 34 | + }) |
| 35 | + |
| 36 | + it('leaves plain text unchanged', () => { |
| 37 | + expect(decodeHtmlEntities('say no to bloat')).toBe('say no to bloat') |
| 38 | + }) |
| 39 | + |
| 40 | + it('leaves unknown entities unchanged', () => { |
| 41 | + expect(decodeHtmlEntities('&unknown;')).toBe('&unknown;') |
| 42 | + }) |
| 43 | +}) |
| 44 | + |
| 45 | +describe('formatCompactNumber', () => { |
| 46 | + describe('without options', () => { |
| 47 | + it.each([ |
| 48 | + [0, '0'], |
| 49 | + [1, '1'], |
| 50 | + [999, '999'], |
| 51 | + [1000, '1k'], |
| 52 | + [1500, '2k'], |
| 53 | + [10000, '10k'], |
| 54 | + [1000000, '1M'], |
| 55 | + [2500000, '3M'], |
| 56 | + [1000000000, '1B'], |
| 57 | + [1000000000000, '1T'], |
| 58 | + ] as const)('%d → %s', (input, expected) => { |
| 59 | + expect(formatCompactNumber(input)).toBe(expected) |
| 60 | + }) |
| 61 | + }) |
| 62 | + |
| 63 | + describe('with decimals', () => { |
| 64 | + it.each([ |
| 65 | + [1500, 1, '1.5k'], |
| 66 | + [1234567, 2, '1.23M'], |
| 67 | + [1200000, 1, '1.2M'], |
| 68 | + [1000, 2, '1k'], |
| 69 | + ] as const)('%d with %d decimals', (input, decimals, expected) => { |
| 70 | + expect(formatCompactNumber(input, { decimals })).toBe(expected) |
| 71 | + }) |
| 72 | + }) |
| 73 | + |
| 74 | + describe('with space', () => { |
| 75 | + it('adds space before suffix', () => { |
| 76 | + expect(formatCompactNumber(1500, { space: true })).toBe('2 k') |
| 77 | + }) |
| 78 | + }) |
| 79 | + |
| 80 | + describe('negative values', () => { |
| 81 | + it.each([ |
| 82 | + [-1000, '-1k'], |
| 83 | + [-2500000, '-3M'], |
| 84 | + [-42, '-42'], |
| 85 | + ] as const)('%d → %s', (input, expected) => { |
| 86 | + expect(formatCompactNumber(input)).toBe(expected) |
| 87 | + }) |
| 88 | + }) |
| 89 | + |
| 90 | + it('handles values below 1000', () => { |
| 91 | + expect(formatCompactNumber(500)).toBe('500') |
| 92 | + }) |
| 93 | +}) |
| 94 | + |
| 95 | +describe('formatBytes', () => { |
| 96 | + it.each([ |
| 97 | + [0, '0 B'], |
| 98 | + [512, '512 B'], |
| 99 | + [1023, '1023 B'], |
| 100 | + [1024, '1.0 kB'], |
| 101 | + [1536, '1.5 kB'], |
| 102 | + [1048576, '1.0 MB'], |
| 103 | + [1572864, '1.5 MB'], |
| 104 | + ] as const)('%d → %s', (input, expected) => { |
| 105 | + expect(formatBytes(input)).toBe(expected) |
| 106 | + }) |
| 107 | +}) |
0 commit comments