80 lines
3.3 KiB
TypeScript
80 lines
3.3 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { rectangle } from '../src/lib/defaults';
|
|
import { insertWallAfter, moveWall } from '../src/lib/wall-editing';
|
|
|
|
const ids = (room: ReturnType<typeof rectangle>) => room.walls.map((wall) => wall.id);
|
|
|
|
describe('inserting walls', () => {
|
|
it.each([0, 1, 3])(
|
|
'inserts after wall index %i without changing existing measurements or doors',
|
|
(index) => {
|
|
const room = rectangle();
|
|
const original = structuredClone(room);
|
|
const inserted = insertWallAfter(room, room.walls[index].id);
|
|
expect(inserted.walls).toHaveLength(room.walls.length + 1);
|
|
expect(inserted.walls[index + 1]).toMatchObject({ length: 1000, turn: 90, doors: [] });
|
|
expect(new Set(ids(inserted)).size).toBe(inserted.walls.length);
|
|
expect(inserted.walls.filter((wall) => room.walls.includes(wall))).toEqual(room.walls);
|
|
for (const wall of room.walls)
|
|
expect(inserted.walls.find((candidate) => candidate.id === wall.id)).toBe(wall);
|
|
expect(room).toEqual(original);
|
|
expect(inserted.id).toBe(room.id);
|
|
expect(inserted.name).toBe(room.name);
|
|
expect(inserted.direction).toBe(room.direction);
|
|
},
|
|
);
|
|
|
|
it('assigns deterministic, unique IDs when repeatedly inserting in the same position', () => {
|
|
const room = rectangle();
|
|
const first = insertWallAfter(room, room.walls[0].id);
|
|
const second = insertWallAfter(first, room.walls[0].id);
|
|
expect(insertWallAfter(room, room.walls[0].id)).toEqual(first);
|
|
expect(new Set(ids(second)).size).toBe(6);
|
|
expect(second.walls[2]).toBe(first.walls[1]);
|
|
});
|
|
|
|
it('ignores an unknown wall and the wall-count limit without creating replacement state', () => {
|
|
const room = rectangle();
|
|
expect(insertWallAfter(room, 'missing')).toBe(room);
|
|
const full = {
|
|
...room,
|
|
walls: Array.from({ length: 100 }, (_, i) => ({ ...room.walls[0], id: `wall-${i}` })),
|
|
};
|
|
expect(insertWallAfter(full, 'wall-3')).toBe(full);
|
|
});
|
|
});
|
|
|
|
describe('reordering walls', () => {
|
|
it.each([
|
|
[0, 3],
|
|
[3, 0],
|
|
[1, 2],
|
|
[2, 1],
|
|
])(
|
|
'moves index %i to index %i while preserving all walls and their attached doors',
|
|
(from, to) => {
|
|
const room = rectangle();
|
|
const original = structuredClone(room);
|
|
const moved = moveWall(room, room.walls[from].id, to);
|
|
expect(moved.walls[to]).toBe(room.walls[from]);
|
|
expect([...ids(moved)].sort()).toEqual([...ids(room)].sort());
|
|
for (const wall of room.walls) {
|
|
const result = moved.walls.find((candidate) => candidate.id === wall.id)!;
|
|
expect(result).toBe(wall);
|
|
expect(result.doors).toBe(wall.doors);
|
|
}
|
|
expect(room).toEqual(original);
|
|
expect(moveWall(moved, room.walls[from].id, from).walls).toEqual(room.walls);
|
|
},
|
|
);
|
|
|
|
it('clamps destinations and treats missing, unchanged or non-finite positions as no-ops', () => {
|
|
const room = rectangle();
|
|
expect(moveWall(room, room.walls[0].id, -10)).toBe(room);
|
|
expect(moveWall(room, room.walls[0].id, 100).walls.at(-1)).toBe(room.walls[0]);
|
|
expect(moveWall(room, room.walls[3].id, -10).walls[0]).toBe(room.walls[3]);
|
|
expect(moveWall(room, 'missing', 2)).toBe(room);
|
|
expect(moveWall(room, room.walls[1].id, 1)).toBe(room);
|
|
expect(moveWall(room, room.walls[1].id, Number.NaN)).toBe(room);
|
|
});
|
|
});
|