feat: add jest testing for utility functions

This commit is contained in:
pa
2025-07-21 14:24:50 +09:00
committed by Natsumi
parent b9b0cebd7f
commit e2b1948159
17 changed files with 9188 additions and 25 deletions

View File

@@ -0,0 +1,36 @@
import { removeFromArray } from '../array';
describe('Array Utils', () => {
describe('removeFromArray', () => {
test('removes items', () => {
const arr = [1, 2, 3];
expect(removeFromArray(arr, 2)).toBe(true);
expect(arr).toEqual([1, 3]);
});
test('removes objects', () => {
const obj = { id: 1 };
const arr = [obj, { id: 2 }];
expect(removeFromArray(arr, obj)).toBe(true);
expect(arr).toHaveLength(1);
});
test('handles missing items', () => {
const arr = [1, 2, 3];
expect(removeFromArray(arr, 4)).toBe(false);
});
test('removes first occurrence only', () => {
const arr = [1, 2, 2, 3];
removeFromArray(arr, 2);
expect(arr).toEqual([1, 2, 3]);
});
test('handles null items', () => {
const arr = [1, null, 2];
// @ts-ignore
expect(removeFromArray(arr, null)).toBe(true);
expect(arr).toEqual([1, 2]);
});
});
});

View File

@@ -0,0 +1,27 @@
import { timeToText } from '../format';
describe('Format Utils', () => {
describe('timeToText', () => {
test('formats basic durations', () => {
expect(timeToText(1000)).toBe('1s');
expect(timeToText(60000)).toBe('1m');
expect(timeToText(3600000)).toBe('1h');
});
test('formats with seconds flag', () => {
expect(timeToText(60000, true)).toBe('1m 0s');
expect(timeToText(90000, true)).toBe('1m 30s');
});
test('handles zero and negative', () => {
expect(timeToText(0)).toBe('0s');
expect(timeToText(-1000)).toBe('1s');
});
test('handles complex time', () => {
const result = timeToText(90061000);
expect(result).toContain('1d');
expect(result).toContain('1h');
});
});
});

View File

@@ -0,0 +1,102 @@
import {
escapeTag,
escapeTagRecursive,
textToHex,
commaNumber,
localeIncludes,
changeLogRemoveLinks
} from '../string';
describe('String Utils', () => {
describe('escapeTag', () => {
test('escapes HTML characters', () => {
expect(escapeTag('<script>')).toBe('&#60;script&#62;');
expect(escapeTag('Hello & goodbye')).toBe('Hello &#38; goodbye');
expect(escapeTag('"test"')).toBe('&#34;test&#34;');
});
test('handles different types', () => {
expect(escapeTag('')).toBe('');
// @ts-ignore
expect(escapeTag(null)).toBe('null');
// @ts-ignore
expect(escapeTag(123)).toBe('123');
});
});
describe('escapeTagRecursive', () => {
test('escapes nested objects', () => {
const input = {
name: '<script>alert("xss")</script>',
data: { value: 'Hello & world' }
};
const result = escapeTagRecursive(input);
expect(result.name).toBe(
'&#60;script&#62;alert(&#34;xss&#34;)&#60;/script&#62;'
);
expect(result.data.value).toBe('Hello &#38; world');
});
test('handles arrays', () => {
const input = ['<script>', 'normal text'];
const result = escapeTagRecursive(input);
expect(result[0]).toBe('&#60;script&#62;');
expect(result[1]).toBe('normal text');
});
});
describe('textToHex', () => {
test('converts basic text', () => {
expect(textToHex('ABC')).toBe('41 42 43');
expect(textToHex('Hello')).toBe('48 65 6c 6c 6f');
});
test('handles special cases', () => {
expect(textToHex('')).toBe('');
// @ts-ignore
expect(textToHex(123)).toBe('31 32 33');
});
});
describe('commaNumber', () => {
test('formats numbers', () => {
expect(commaNumber(1000)).toBe('1,000');
expect(commaNumber(1234567)).toBe('1,234,567');
});
test('handles edge cases', () => {
expect(commaNumber(0)).toBe('0');
// @ts-ignore
expect(commaNumber(null)).toBe('0');
// @ts-ignore
expect(commaNumber('abc')).toBe('0');
});
});
describe('localeIncludes', () => {
const comparer = {
compare: (a, b) => a.toLowerCase().localeCompare(b.toLowerCase())
};
test('finds substrings', () => {
expect(localeIncludes('Hello World', 'hello', comparer)).toBe(true);
expect(localeIncludes('Hello World', 'xyz', comparer)).toBe(false);
});
test('handles empty search', () => {
expect(localeIncludes('Hello', '', comparer)).toBe(true);
});
});
describe('changeLogRemoveLinks', () => {
test('removes markdown links', () => {
expect(
changeLogRemoveLinks('Hello [world](http://example.com)')
).toBe('Hello ');
});
test('preserves image links', () => {
expect(changeLogRemoveLinks('![image](url)')).toBe('![image](url)');
});
});
});

View File

@@ -47,7 +47,11 @@ function commaNumber(num) {
if (!num) {
return '0';
}
const s = String(Number(num));
const numValue = Number(num);
if (isNaN(numValue)) {
return '0';
}
const s = String(numValue);
return s.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
}