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']); }); });