Newer
Older
rpg / packages / engine / src / inventory / __tests__ / Inventory.test.ts
import { describe, expect, it, vi } from 'vitest';
import { Inventory, inventoryFromData } from '../Inventory';

describe('Inventory', () => {
    it('добавляет и считает предметы', () => {
        const inv = new Inventory();
        expect(inv.empty).toBe(true);
        inv.add('cloth');
        inv.add('bellflower', 2);
        expect(inv.count('cloth')).toBe(1);
        expect(inv.count('bellflower')).toBe(2);
        expect(inv.has('cloth')).toBe(true);
        expect(inv.has('salt')).toBe(false);
        expect(inv.empty).toBe(false);
    });

    it('remove вычитает и чистит пустые слоты', () => {
        const inv = new Inventory();
        inv.add('bellflower', 3);
        expect(inv.remove('bellflower', 2)).toBe(2);
        expect(inv.count('bellflower')).toBe(1);
        expect(inv.remove('bellflower', 5)).toBe(1); // нельзя убрать больше, чем есть
        expect(inv.count('bellflower')).toBe(0);
        expect(inv.has('bellflower')).toBe(false);
        expect(inv.remove('cloth')).toBe(0); // нет предмета — ничего
    });

    it('add с неположительным n — no-op', () => {
        const inv = new Inventory();
        inv.add('salt', 0);
        inv.add('salt', -1);
        expect(inv.empty).toBe(true);
    });

    it('onChange оповещает о каждом изменении, отписка работает', () => {
        const inv = new Inventory();
        const fn = vi.fn();
        const off = inv.onChange(fn);
        inv.add('cloth');
        inv.add('cloth');
        inv.remove('cloth');
        off();
        inv.add('cloth');
        expect(fn).toHaveBeenCalledTimes(3);
    });

    it('serialize/load round-trip; load игнорирует мусор', () => {
        const inv = new Inventory();
        inv.add('cloth');
        inv.add('bellflower', 3);
        const data = inv.serialize();
        const back = inventoryFromData(JSON.parse(JSON.stringify(data)));
        expect(back.all).toEqual([
            { id: 'cloth', count: 1 },
            { id: 'bellflower', count: 3 }
        ]);
        back.load({ items: { salt: 0, bad: -2, cloth: 2 } });
        expect(back.count('salt')).toBe(0);
        expect(back.count('bad')).toBe(0);
        expect(back.count('cloth')).toBe(2);
    });

    it('clear сбрасывает содержимое', () => {
        const inv = new Inventory();
        inv.add('cloth');
        inv.clear();
        expect(inv.empty).toBe(true);
    });
});