Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions src/arrays.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { describe, it, expect } from 'vitest';
import {
chunk,
compact,
uniq,
uniqBy,
flatten,
flattenDeep,
difference,
intersection,
groupBy,
partition,
sample,
shuffle,
} from '../src/arrays';

describe('chunk', () => {
it('splits array into chunks of given size', () => {
expect(chunk([1, 2, 3, 4, 5], 2)).toEqual([[1, 2], [3, 4], [5]]);
});
it('handles size larger than array', () => {
expect(chunk([1, 2], 5)).toEqual([[1, 2]]);
});
it('handles empty array', () => {
expect(chunk([], 3)).toEqual([]);
});
});

describe('compact', () => {
it('removes falsy values', () => {
expect(compact([0, 1, false, 2, '', 3])).toEqual([1, 2, 3]);
});
it('handles all falsy', () => {
expect(compact([false, null, undefined, 0, ''])).toEqual([]);
});
});

describe('uniq', () => {
it('removes duplicates', () => {
expect(uniq([1, 2, 2, 3, 3, 3])).toEqual([1, 2, 3]);
});
it('handles empty array', () => {
expect(uniq([])).toEqual([]);
});
});

describe('uniqBy', () => {
it('removes duplicates by key', () => {
const arr = [{ id: 1 }, { id: 2 }, { id: 1 }];
expect(uniqBy(arr, 'id')).toEqual([{ id: 1 }, { id: 2 }]);
});
});

describe('flatten', () => {
it('flattens one level', () => {
expect(flatten([[1, 2], [3, 4]])).toEqual([1, 2, 3, 4]);
});
});

describe('flattenDeep', () => {
it('flattens all levels', () => {
expect(flattenDeep([1, [2, [3, [4]]]])).toEqual([1, 2, 3, 4]);
});
});

describe('difference', () => {
it('returns items not in second array', () => {
expect(difference([1, 2, 3, 4], [2, 4])).toEqual([1, 3]);
});
});

describe('intersection', () => {
it('returns common items', () => {
expect(intersection([1, 2, 3], [2, 3, 4])).toEqual([2, 3]);
});
});

describe('groupBy', () => {
it('groups by key', () => {
const arr = [{ type: 'a' }, { type: 'b' }, { type: 'a' }];
const result = groupBy(arr, 'type');
expect(result.a).toHaveLength(2);
expect(result.b).toHaveLength(1);
});
});

describe('partition', () => {
it('splits by predicate', () => {
const [evens, odds] = partition([1, 2, 3, 4], n => n % 2 === 0);
expect(evens).toEqual([2, 4]);
expect(odds).toEqual([1, 3]);
});
});

describe('sample', () => {
it('returns element from array', () => {
const arr = [1, 2, 3];
const result = sample(arr);
expect(arr).toContain(result);
});
it('handles empty array', () => {
expect(sample([])).toBeUndefined();
});
});

describe('shuffle', () => {
it('returns array with same elements', () => {
const arr = [1, 2, 3, 4, 5];
const result = shuffle(arr);
expect(result.sort()).toEqual([1, 2, 3, 4, 5]);
});
});
81 changes: 81 additions & 0 deletions src/dates.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { describe, it, expect } from 'vitest';
import {
formatDate,
formatRelative,
isToday,
isYesterday,
daysBetween,
addDays,
} from '../src/dates';

describe('formatDate', () => {
it('formats a date string', () => {
const result = formatDate('2026-05-27T10:00:00Z');
expect(result).toBeTruthy();
expect(typeof result).toBe('string');
});
it('handles invalid date', () => {
expect(formatDate('invalid')).toBeFalsy();
});
});

describe('formatRelative', () => {
it('returns relative time string', () => {
const result = formatRelative(new Date().toISOString());
expect(result).toBeTruthy();
expect(typeof result).toBe('string');
});
it('handles past dates', () => {
const past = new Date(Date.now() - 86400000).toISOString();
const result = formatRelative(past);
expect(result).toBeTruthy();
});
it('handles future dates', () => {
const future = new Date(Date.now() + 86400000).toISOString();
const result = formatRelative(future);
expect(result).toBeTruthy();
});
});

describe('isToday', () => {
it('returns true for today', () => {
expect(isToday(new Date().toISOString())).toBe(true);
});
it('returns false for yesterday', () => {
const yesterday = new Date(Date.now() - 86400000).toISOString();
expect(isToday(yesterday)).toBe(false);
});
});

describe('isYesterday', () => {
it('returns true for yesterday', () => {
const yesterday = new Date(Date.now() - 86400000).toISOString();
expect(isYesterday(yesterday)).toBe(true);
});
it('returns false for today', () => {
expect(isYesterday(new Date().toISOString())).toBe(false);
});
});

describe('daysBetween', () => {
it('calculates days between dates', () => {
const start = '2026-05-01T00:00:00Z';
const end = '2026-05-05T00:00:00Z';
expect(daysBetween(start, end)).toBe(4);
});
it('returns 0 for same date', () => {
const date = '2026-05-01T00:00:00Z';
expect(daysBetween(date, date)).toBe(0);
});
});

describe('addDays', () => {
it('adds days to date', () => {
const result = addDays('2026-05-01T00:00:00Z', 5);
expect(result.includes('2026-05-06')).toBe(true);
});
it('subtracts days with negative', () => {
const result = addDays('2026-05-01T00:00:00Z', -5);
expect(result.includes('2026-04-26')).toBe(true);
});
});
80 changes: 80 additions & 0 deletions src/money.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { describe, it, expect } from 'vitest';
import {
formatMoney,
parseMoney,
toCents,
fromCents,
addMoney,
subtractMoney,
multiplyMoney,
divideMoney,
} from '../src/money';

describe('formatMoney', () => {
it('formats cents to dollars', () => {
expect(formatMoney(1234)).toBe('$12.34');
});
it('handles zero', () => {
expect(formatMoney(0)).toBe('$0.00');
});
it('handles negative', () => {
expect(formatMoney(-500)).toBe('-$5.00');
});
});

describe('parseMoney', () => {
it('parses dollar string to cents', () => {
expect(parseMoney('$12.34')).toBe(1234);
});
it('parses without dollar sign', () => {
expect(parseMoney('12.34')).toBe(1234);
});
it('handles invalid input', () => {
expect(parseMoney('abc')).toBe(0);
});
});

describe('toCents', () => {
it('converts dollars to cents', () => {
expect(toCents(12.34)).toBe(1234);
});
it('handles whole dollars', () => {
expect(toCents(100)).toBe(10000);
});
});

describe('fromCents', () => {
it('converts cents to dollars', () => {
expect(fromCents(1234)).toBe(12.34);
});
it('handles zero', () => {
expect(fromCents(0)).toBe(0);
});
});

describe('addMoney', () => {
it('adds two amounts in cents', () => {
expect(addMoney(1000, 500)).toBe(1500);
});
});

describe('subtractMoney', () => {
it('subtracts two amounts in cents', () => {
expect(subtractMoney(1000, 300)).toBe(700);
});
});

describe('multiplyMoney', () => {
it('multiplies cents by factor', () => {
expect(multiplyMoney(1000, 3)).toBe(3000);
});
});

describe('divideMoney', () => {
it('divides cents by factor', () => {
expect(divideMoney(1000, 4)).toBe(250);
});
it('handles division by zero', () => {
expect(divideMoney(1000, 0)).toBe(0);
});
});