Files
mediacms/frontend/tests/utils/helpers/formatViewsNumber.test.ts
2026-01-07 19:47:54 +02:00

107 lines
5.6 KiB
TypeScript

import formatViewsNumber from '../../../src/static/js/utils/helpers/formatViewsNumber';
describe('js/utils/helpers', () => {
describe('formatViewsNumber', () => {
describe('fullNumber = false (default compact formatting)', () => {
test('Formats values < 1,000 without suffix and with correct rounding', () => {
expect(formatViewsNumber(0)).toBe('0');
expect(formatViewsNumber(9)).toBe('9');
expect(formatViewsNumber(12)).toBe('12');
expect(formatViewsNumber(999)).toBe('999');
});
test('Formats thousands to K with decimals for < 10K and none for >= 10K', () => {
expect(formatViewsNumber(1000)).toBe('1K');
expect(formatViewsNumber(1500)).toBe('1.5K');
expect(formatViewsNumber(1499)).toBe('1.5K'); // rounds to 1 decimal
expect(formatViewsNumber(10_000)).toBe('10K');
expect(formatViewsNumber(10_400)).toBe('10K');
expect(formatViewsNumber(10_500)).toBe('11K'); // rounds to nearest whole
expect(formatViewsNumber(99_900)).toBe('100K'); // rounding up
});
test('Formats millions to M with decimals for < 10M and none for >= 10M', () => {
expect(formatViewsNumber(1_000_000)).toBe('1M');
expect(formatViewsNumber(1_200_000)).toBe('1.2M');
expect(formatViewsNumber(9_440_000)).toBe('9.4M');
expect(formatViewsNumber(9_960_000)).toBe('10M'); // rounds to whole when >= 10M threshold after rounding
expect(formatViewsNumber(10_000_000)).toBe('10M');
});
test('Formats billions and trillions correctly', () => {
expect(formatViewsNumber(1_000_000_000)).toBe('1B');
expect(formatViewsNumber(1_500_000_000)).toBe('1.5B');
expect(formatViewsNumber(10_000_000_000)).toBe('10B');
expect(formatViewsNumber(1_000_000_000_000)).toBe('1T');
expect(formatViewsNumber(1_230_000_000_000)).toBe('1.2T');
});
// @todo: Revisit this behavior
test('Beyond last unit keeps using the last unit with scaling', () => {
// Implementation scales beyond units by increasing the value so that the last unit remains applicable
// Here, expect a number in T with rounding behavior similar to others
expect(formatViewsNumber(9_999_999_999_999)).toBe('10T');
// With current rounding rules, this value rounds to whole trillions
expect(formatViewsNumber(12_345_678_901_234)).toBe('12T');
});
});
describe('fullNumber = true (locale formatting)', () => {
test('Returns locale string representation of the full number', () => {
// Use a fixed locale independent assertion by stripping non-digits except separators that could vary.
// However, to avoid locale variance, check that it equals toLocaleString directly.
const vals = [0, 12, 999, 1000, 1234567, 9876543210];
for (const v of vals) {
expect(formatViewsNumber(v, true)).toBe(v.toLocaleString());
}
});
});
describe('Additional edge cases and robustness', () => {
test('Handles negative values without unit suffix (no scaling applied)', () => {
expect(formatViewsNumber(-999)).toBe('-999');
expect(formatViewsNumber(-1000)).toBe('-1000');
expect(formatViewsNumber(-1500)).toBe('-1500');
expect(formatViewsNumber(-10_500)).toBe('-10500');
expect(formatViewsNumber(-1_230_000_000_000)).toBe('-1230000000000');
});
test('Handles non-integer inputs with correct rounding in compact mode', () => {
expect(formatViewsNumber(1499.5)).toBe('1.5K');
expect(formatViewsNumber(999.9)).toBe('1000');
expect(formatViewsNumber(10_499.5)).toBe('10K');
expect(formatViewsNumber(10_500.49)).toBe('11K');
expect(formatViewsNumber(9_440_000.49)).toBe('9.4M');
});
test('Respects locale formatting in fullNumber mode', () => {
const values = [1_234_567, -2_345_678, 0, 10_000, 99_999_999];
for (const v of values) {
expect(formatViewsNumber(v, true)).toBe(v.toLocaleString());
}
});
test('Caps unit at trillions for extremely large numbers', () => {
expect(formatViewsNumber(9_999_999_999_999)).toBe('10T');
expect(formatViewsNumber(12_345_678_901_234)).toBe('12T');
expect(formatViewsNumber(987_654_321_000_000)).toBe('988T');
});
// @todo: Revisit this behavior
test('Handles NaN and Infinity values gracefully', () => {
expect(formatViewsNumber(Number.NaN, true)).toBe(Number.NaN.toLocaleString());
expect(formatViewsNumber(Number.POSITIVE_INFINITY, true)).toBe(
Number.POSITIVE_INFINITY.toLocaleString()
);
expect(formatViewsNumber(Number.NEGATIVE_INFINITY, true)).toBe(
Number.NEGATIVE_INFINITY.toLocaleString()
);
expect(formatViewsNumber(Number.NaN)).toBe('NaN');
// @note: We don't test compact Infinity cases due to infinite loop behavior from while (views >= compare)
});
});
});
});