You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.1 KiB
112 lines
3.1 KiB
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
import { OcaPlayback } from '../src/lib/oca-playback.js';
|
|
import type { Room } from '../src/lib/types.js';
|
|
import { paletteForRoom } from '../shared/player-colors.mjs';
|
|
afterEach(() => vi.useRealTimers());
|
|
function fixture() {
|
|
vi.useFakeTimers();
|
|
const frame = vi.fn(),
|
|
busy = vi.fn(),
|
|
sound = vi.fn(),
|
|
arrival = vi.fn();
|
|
const playback = new OcaPlayback({
|
|
frame,
|
|
busy,
|
|
sound,
|
|
arrival,
|
|
reducedMotion: () => false,
|
|
});
|
|
const room = {
|
|
id: 'oca',
|
|
seat: 0,
|
|
players: [
|
|
{ seat: 0, userId: 'one' },
|
|
{ seat: 1, userId: 'two' },
|
|
],
|
|
state: { positions: [0, 0] },
|
|
events: [],
|
|
} as unknown as Room;
|
|
playback.receive(room);
|
|
frame.mockClear();
|
|
const roll = (sequence: number, player = 0) =>
|
|
({
|
|
...room,
|
|
state: {
|
|
...room.state,
|
|
lastPlayer: player,
|
|
positions: player ? [0, 3] : [3, 0],
|
|
lastPath: [1, 2, 3, 3],
|
|
lastEffect: null,
|
|
},
|
|
events: [
|
|
{
|
|
sequence,
|
|
type: 'roll',
|
|
actorId: player ? 'two' : 'one',
|
|
createdAt: new Date().toISOString(),
|
|
},
|
|
],
|
|
}) as Room;
|
|
return { playback, frame, busy, sound, arrival, roll };
|
|
}
|
|
describe('presentación de las tiradas de la oca', () => {
|
|
it('espera al cierre del resultado y recorre cada casilla sin repetir la llegada', () => {
|
|
const { playback, frame, sound, roll, busy } = fixture();
|
|
playback.receive(roll(1));
|
|
vi.advanceTimersByTime(60000);
|
|
expect(frame).not.toHaveBeenCalled();
|
|
expect(sound).not.toHaveBeenCalled();
|
|
playback.release(1);
|
|
vi.runAllTimers();
|
|
expect(frame.mock.calls.map((c) => c[0])).toEqual([
|
|
[1, 0],
|
|
[2, 0],
|
|
[3, 0],
|
|
]);
|
|
expect(busy).toHaveBeenLastCalledWith(false);
|
|
playback.dispose();
|
|
});
|
|
it('conserva una tirada rival que llega antes de cerrar el dado propio', () => {
|
|
const { playback, frame, roll } = fixture();
|
|
playback.receive(roll(1));
|
|
playback.receive(roll(2, 1));
|
|
vi.advanceTimersByTime(1000);
|
|
expect(frame).not.toHaveBeenCalled();
|
|
playback.release(1);
|
|
vi.runAllTimers();
|
|
expect(frame.mock.calls.map((c) => c[0])).toEqual([
|
|
[1, 0],
|
|
[2, 0],
|
|
[3, 0],
|
|
[3, 1],
|
|
[3, 2],
|
|
[3, 3],
|
|
]);
|
|
playback.dispose();
|
|
});
|
|
it('presenta la tirada rival después del dado y cancela el recorrido al salir', () => {
|
|
const { playback, frame, roll } = fixture();
|
|
playback.receive(roll(1, 1));
|
|
vi.advanceTimersByTime(799);
|
|
expect(frame).not.toHaveBeenCalled();
|
|
vi.advanceTimersByTime(2);
|
|
expect(frame).toHaveBeenCalledOnce();
|
|
playback.dispose();
|
|
vi.runAllTimers();
|
|
expect(frame).toHaveBeenCalledOnce();
|
|
});
|
|
it('prepara ocho colores únicos para juegos con más participantes', () => {
|
|
expect(paletteForRoom({ maxPlayers: 4 })).toHaveLength(4);
|
|
expect(paletteForRoom({ maxPlayers: 8 }).map((c) => c.id)).toEqual([
|
|
'amarillo',
|
|
'azul',
|
|
'rojo',
|
|
'verde',
|
|
'negro',
|
|
'naranja',
|
|
'violeta',
|
|
'gris',
|
|
]);
|
|
});
|
|
});
|