import { describe, it, expect } from 'vitest';
import { ListCursor } from '../listCursor';

describe('ListCursor', () => {
    it('move зацикливается по кругу', () => {
        const c = new ListCursor(3);
        c.move(1);
        expect(c.index).toBe(1);
        c.move(1);
        c.move(1);
        expect(c.index).toBe(0); // 2 + 1 -> 0
        c.move(-1);
        expect(c.index).toBe(2);
    });

    it('пустой список не двигается', () => {
        const c = new ListCursor(0);
        c.move(1);
        c.move(-1);
        expect(c.empty).toBe(true);
        expect(c.index).toBe(0);
    });

    it('setCount зажимает курсор при уменьшении списка', () => {
        const c = new ListCursor(5);
        c.move(4);
        expect(c.index).toBe(4);
        c.setCount(2);
        expect(c.index).toBe(1);
    });

    it('setCount с ростом списка сохраняет индекс', () => {
        const c = new ListCursor(2);
        c.move(1);
        c.setCount(4);
        expect(c.index).toBe(1);
    });

    it('home/end ставят крайние позиции', () => {
        const c = new ListCursor(4);
        c.end();
        expect(c.index).toBe(3);
        c.home();
        expect(c.index).toBe(0);
    });

    it('предикат выбираемости пропускает недоступные пункты', () => {
        const c = new ListCursor(4, (i) => i !== 1 && i !== 2); // 1 и 2 — disabled
        c.setCount(4);
        c.move(1); // 0 -> 3 (1 и 2 пропущены)
        expect(c.index).toBe(3);
        c.move(1); // 3 -> 0 (по кругу, через 1 и 2)
        expect(c.index).toBe(0);
        c.move(-1); // 0 -> 3
        expect(c.index).toBe(3);
    });

    it('setCount на недоступном пункте сдвигается к выбираемому', () => {
        const c = new ListCursor(3, (i) => i !== 1);
        c.index = 1;
        c.setCount(3);
        expect(c.index).toBe(2);
    });

    it('все пункты недоступны — курсор стоит на месте', () => {
        const c = new ListCursor(2, () => false);
        c.move(1);
        c.move(-1);
        expect(c.index).toBe(0);
    });
});