224 lines
6.5 KiB
TypeScript
224 lines
6.5 KiB
TypeScript
import { describe, expect, it } from 'bun:test';
|
|
import {
|
|
combinations,
|
|
getMiddleElement,
|
|
groupBy,
|
|
multArray,
|
|
multBy,
|
|
replaceChar,
|
|
sumArray,
|
|
sumBy,
|
|
unique
|
|
} from './array.ts';
|
|
|
|
describe('array utils', () => {
|
|
it('sumArray number array', () => {
|
|
const array = [1, 2, 3];
|
|
const sum = sumArray(array);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(1 + 2 + 3);
|
|
|
|
expect(sumArray([])).toBeNumber();
|
|
expect(sumArray([])).toBeFinite();
|
|
expect(sumArray([])).toBe(0);
|
|
});
|
|
it('sumArray read-only number array', () => {
|
|
const array = [1, 2, 3] as const;
|
|
const sum = sumArray(array);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(1 + 2 + 3);
|
|
|
|
expect(sumArray([])).toBeNumber();
|
|
expect(sumArray([])).toBeFinite();
|
|
expect(sumArray([])).toBe(0);
|
|
});
|
|
it('sumBy number array', () => {
|
|
const array = [1, 2, 3];
|
|
const sum = sumBy(array, (e) => e);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(1 + 2 + 3);
|
|
});
|
|
it('sumBy read-only number array', () => {
|
|
const array = [1, 2, 3] as const;
|
|
const sum = sumBy(array, (e) => e);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(1 + 2 + 3);
|
|
});
|
|
it('sumBy mixed array', () => {
|
|
const array = [1, '2', 3.1, ''];
|
|
|
|
const sum = sumBy(array, (e) => e);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(1 + 2 + 3.1);
|
|
});
|
|
it('sumBy object array', () => {
|
|
const array: (
|
|
| { value: number | string }
|
|
| { differentValue: number | string }
|
|
)[] = [{ value: 3 }, { value: '2' }, { differentValue: '-2.44' }];
|
|
|
|
const sum = sumBy(array, (e) =>
|
|
'differentValue' in e ? e.differentValue : e.value
|
|
);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(3 + 2 - 2.44);
|
|
});
|
|
it('sumBy empty array', () => {
|
|
expect(sumBy([], (e) => e)).toBeNumber();
|
|
expect(sumBy([], (e) => e)).toBeFinite();
|
|
expect(sumBy([], (e) => e)).toBe(0);
|
|
});
|
|
|
|
it('multArray number array', () => {
|
|
const array = [1, 2, 3];
|
|
const sum = multArray(array);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(2 * 3);
|
|
|
|
expect(multArray([])).toBeNumber();
|
|
expect(multArray([])).toBeFinite();
|
|
expect(multArray([])).toBe(0);
|
|
});
|
|
it('multArray read-only number array', () => {
|
|
const array = [1, 2, 3] as const;
|
|
const sum = multArray(array);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(2 * 3);
|
|
|
|
expect(multArray([])).toBeNumber();
|
|
expect(multArray([])).toBeFinite();
|
|
expect(multArray([])).toBe(0);
|
|
});
|
|
it('multBy number array', () => {
|
|
const array = [1, 2, 3];
|
|
const sum = sumBy(array, (e) => e);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(1 + 2 + 3);
|
|
});
|
|
it('multBy read-only number array', () => {
|
|
const array = [1, 2, 3] as const;
|
|
const sum = multBy(array, (e) => e);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(1 + 2 + 3);
|
|
});
|
|
it('multBy mixed array', () => {
|
|
const array = [1, '2', 3.1, ''];
|
|
|
|
const sum = multBy(array, (e) => e);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(0);
|
|
});
|
|
it('multBy object array', () => {
|
|
const array: (
|
|
| { value: number | string }
|
|
| { differentValue: number | string }
|
|
)[] = [{ value: 3 }, { value: '2' }, { differentValue: '-2.44' }];
|
|
|
|
const sum = multBy(array, (e) =>
|
|
'differentValue' in e ? e.differentValue : e.value
|
|
);
|
|
expect(sum).toBeNumber();
|
|
expect(sum).toBeFinite();
|
|
expect(sum).toBe(3 * 2 * -2.44);
|
|
});
|
|
it('multBy empty array', () => {
|
|
expect(multBy([], (e) => e)).toBeNumber();
|
|
expect(multBy([], (e) => e)).toBeFinite();
|
|
expect(multBy([], (e) => e)).toBe(0);
|
|
});
|
|
it('groupBy', () => {
|
|
const arr = [0, 1, 2, 2, 1, 3];
|
|
const actual = groupBy(arr, (e) => e);
|
|
const expected = [
|
|
{ key: 0, elements: [0] },
|
|
{ key: 1, elements: [1, 1] },
|
|
{ key: 2, elements: [2, 2] },
|
|
{ key: 3, elements: [3] }
|
|
];
|
|
|
|
expect(actual).toHaveLength(actual.length);
|
|
expect(Object.keys(actual.map((e) => e.key))).toEqual(
|
|
expect.arrayContaining(Object.keys(expected.map((e) => e.key)))
|
|
);
|
|
expected.forEach(({ key, elements }) => {
|
|
const actualGroup = actual.find((e) => e.key === key);
|
|
expect(actualGroup).toBeTruthy();
|
|
expect(actualGroup).toBeObject();
|
|
expect(actualGroup?.elements || []).toHaveLength(elements.length);
|
|
expect(actualGroup?.elements || []).toEqual(
|
|
expect.arrayContaining(elements)
|
|
);
|
|
});
|
|
});
|
|
it('getMiddleElement', () => {
|
|
expect(getMiddleElement([1, 2, 3, 4])).toBe(3);
|
|
expect(getMiddleElement([1, 2, 3])).toBe(2);
|
|
expect(getMiddleElement([1])).toBe(1);
|
|
expect(getMiddleElement([])).toBeUndefined();
|
|
});
|
|
it('combinations', () => {
|
|
const numbers = [0, 1, 2];
|
|
const n = numbers.length;
|
|
const actual = combinations(numbers);
|
|
const expected = [
|
|
{ a: 0, b: 1 },
|
|
{ a: 0, b: 2 },
|
|
{ a: 1, b: 0 },
|
|
{ a: 1, b: 2 },
|
|
{ a: 2, b: 0 },
|
|
{ a: 2, b: 1 }
|
|
];
|
|
expect(actual).toHaveLength(n * (n - 1));
|
|
expect(actual).toEqual(expect.arrayContaining(expected));
|
|
expect(expected).toEqual(expect.arrayContaining(actual));
|
|
});
|
|
it('unique numbers', () => {
|
|
const arr = [0, 1, 2, 2, 1, 3];
|
|
const actual = arr.filter(unique());
|
|
const expected = [0, 1, 2, 3];
|
|
|
|
expect(actual).toHaveLength(actual.length);
|
|
expect(actual).toEqual(expect.arrayContaining(expected));
|
|
expect(expected).toEqual(expect.arrayContaining(actual));
|
|
});
|
|
it('unique objects', () => {
|
|
const arr = [{ a: 0 }, { a: 1 }, { a: 2 }, { a: 2 }, { a: 1 }, { a: 3 }];
|
|
const actual = arr.filter(unique((a, b) => a.a === b.a));
|
|
const expected = [{ a: 0 }, { a: 1 }, { a: 2 }, { a: 3 }];
|
|
|
|
expect(actual).toHaveLength(actual.length);
|
|
expect(actual).toEqual(expect.arrayContaining(expected));
|
|
expect(expected).toEqual(expect.arrayContaining(actual));
|
|
|
|
// should just pass everything through since objects equality check is by reference
|
|
expect(arr.filter(unique())).toHaveLength(arr.length);
|
|
});
|
|
it('replaceChar', () => {
|
|
const input = `000000
|
|
111111
|
|
222222
|
|
333333`;
|
|
const rows = input.split('\n');
|
|
replaceChar(rows, 1, 2, 'b');
|
|
const actual = rows.join('\n');
|
|
const expected = `000000
|
|
111111
|
|
2b2222
|
|
333333`;
|
|
|
|
expect(actual).toHaveLength(expected.length);
|
|
expect(actual).toEqual(expected);
|
|
});
|
|
});
|