import { describe, expect, it } from 'vitest';
import {
dialogueLayer,
enemiesLayer,
gameLayer,
heroLayer,
npcsLayer,
type EnemySnapshot,
type NpcSnapshot
} from '../snapshot';
describe('снапшот агента — слои', () => {
it('герой: позиция округляется до 3 знаков, остальное копируется', () => {
const layer = heroLayer({
tile: { x: 12, y: 8 },
pos: { x: 1.23456, y: 5.0001 },
hp: 9,
maxHp: 12,
facing: 'side',
moving: false,
invuln: false,
inHazard: null
});
expect(layer.hero).toMatchObject({
tile: { x: 12, y: 8 },
pos: { x: 1.235, y: 5 },
hp: 9,
maxHp: 12,
facing: 'side'
});
});
it('враги: поля на месте, позиция округлена', () => {
const e: EnemySnapshot = {
kind: 'ash',
state: 'chase',
hp: 4,
pos: { x: 0.123456, y: 2.5 },
asleep: true,
dead: false
};
const layer = enemiesLayer([e]);
expect(layer.enemies).toEqual([
{ kind: 'ash', state: 'chase', hp: 4, pos: { x: 0.123, y: 2.5 }, asleep: true, dead: false }
]);
});
it('NPC: копия с met, без ссылок на источник', () => {
const n: NpcSnapshot = { id: 'elder', name: 'Ирвин', tile: { x: 20, y: 12 }, met: false };
const layer = npcsLayer([n]);
const out = (layer.npcs as unknown as NpcSnapshot[])[0]!;
expect(out).toEqual(n);
expect(out).not.toBe(n);
});
it('диалог: объект проходит, null остаётся null', () => {
const d = { id: 'elder', nodeId: 'n1', speaker: 'Ирвин', text: 'Привет', choices: [], waitingForChoice: false };
expect(dialogueLayer(d).dialogue).toEqual(d);
expect(dialogueLayer(null).dialogue).toBeNull();
});
it('слой игры: флаги/вары/сумка копируются защитно', () => {
const flags = ['metElder'];
const vars = { flowers: 2 };
const inv = [{ id: 'flower', count: 2 }];
const layer = gameLayer({ flags, vars, inventory: inv });
expect(layer).toEqual({ flags: ['metElder'], vars: { flowers: 2 }, inventory: [{ id: 'flower', count: 2 }] });
// Мутация источника не меняет слой.
flags.push('x');
vars.flowers = 99;
inv[0]!.count = 99;
expect(layer.flags).toEqual(['metElder']);
expect(layer.vars).toEqual({ flowers: 2 });
expect(layer.inventory[0]!.count).toBe(2);
});
});