Files
feuerwerk/tests/core/list.test.ts
T

75 lines
2.4 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { moveItem, removeById, removeFirst, restoreAt } from '../../src/core/util/list';
const items = () => [{ id: 'a' }, { id: 'b' }, { id: 'c' }];
describe('removeFirst', () => {
it('takes the match out and reports the index it had', () => {
const list = items();
expect(removeFirst(list, (i) => i.id === 'b')).toEqual({ item: { id: 'b' }, index: 1 });
expect(list.map((i) => i.id)).toEqual(['a', 'c']);
});
it('stops at the first match', () => {
const list = [{ id: 'a' }, { id: 'a' }];
expect(removeFirst(list, (i) => i.id === 'a')?.index).toBe(0);
expect(list).toHaveLength(1);
});
it('leaves the list untouched when nothing matches', () => {
const list = items();
expect(removeFirst(list, (i) => i.id === 'zz')).toBeUndefined();
expect(list.map((i) => i.id)).toEqual(['a', 'b', 'c']);
});
it('round-trips with restoreAt', () => {
const list = items();
const removed = removeFirst(list, (i) => i.id === 'b');
restoreAt(list, removed ? [removed] : []);
expect(list.map((i) => i.id)).toEqual(['a', 'b', 'c']);
});
});
describe('moveItem', () => {
const ids = (list: { id: string }[]) => list.map((i) => i.id);
it('moves forwards and backwards, and the reverse move restores the order', () => {
const list = items();
expect(moveItem(list, 0, 2)).toBe(true);
expect(ids(list)).toEqual(['b', 'c', 'a']);
expect(moveItem(list, 2, 0)).toBe(true);
expect(ids(list)).toEqual(['a', 'b', 'c']);
moveItem(list, 2, 1);
expect(ids(list)).toEqual(['a', 'c', 'b']);
});
it('refuses a place outside the list or between two places and leaves the list as it was', () => {
for (const [from, to] of [
[-1, 0],
[3, 0],
[0, -1],
[0, 3],
[0.5, 1],
[0, 1.5],
] as const) {
const list = items();
expect(moveItem(list, from, to)).toBe(false);
expect(ids(list)).toEqual(['a', 'b', 'c']);
}
});
});
describe('removeById', () => {
it('returns a new list without that item and does not mutate the old one', () => {
const list = items();
const next = removeById(list, 'a');
expect(next.map((i) => i.id)).toEqual(['b', 'c']);
expect(list).toHaveLength(3);
expect(next).not.toBe(list);
});
it('keeps every item when the id is unknown', () => {
expect(removeById(items(), 'zz').map((i) => i.id)).toEqual(['a', 'b', 'c']);
});
});