import { describe, it, expect } from 'vitest'; import { idx, inBounds, isWall, isBlocked, tryDestructTile } from '../world/world-logic'; import { type World, type Tile } from '../../core/types'; import { TileType } from '../../core/terrain'; describe('World Utilities', () => { const createTestWorld = (width: number, height: number, tiles: Tile[]): World => ({ width, height, tiles, exit: { x: 0, y: 0 }, trackPath: [] }); describe('idx', () => { it('should calculate correct index for 2D coordinates', () => { const world = createTestWorld(10, 10, []); expect(idx(world, 0, 0)).toBe(0); expect(idx(world, 5, 0)).toBe(5); expect(idx(world, 0, 1)).toBe(10); expect(idx(world, 5, 3)).toBe(35); }); }); describe('inBounds', () => { it('should return true for coordinates within bounds', () => { const world = createTestWorld(10, 10, []); expect(inBounds(world, 0, 0)).toBe(true); expect(inBounds(world, 5, 5)).toBe(true); expect(inBounds(world, 9, 9)).toBe(true); }); it('should return false for coordinates outside bounds', () => { const world = createTestWorld(10, 10, []); expect(inBounds(world, -1, 0)).toBe(false); expect(inBounds(world, 0, -1)).toBe(false); expect(inBounds(world, 10, 0)).toBe(false); expect(inBounds(world, 0, 10)).toBe(false); expect(inBounds(world, 11, 11)).toBe(false); }); }); describe('isWall', () => { it('should return true for wall tiles', () => { const tiles: Tile[] = new Array(100).fill(TileType.EMPTY); tiles[0] = TileType.WALL; // wall at 0,0 tiles[55] = TileType.WALL; // wall at 5,5 const world = createTestWorld(10, 10, tiles); expect(isWall(world, 0, 0)).toBe(true); expect(isWall(world, 5, 5)).toBe(true); }); it('should return false for floor tiles', () => { const tiles: Tile[] = new Array(100).fill(TileType.EMPTY); const world = createTestWorld(10, 10, tiles); expect(isWall(world, 3, 3)).toBe(false); expect(isWall(world, 7, 7)).toBe(false); }); it('should return false for out of bounds coordinates', () => { const world = createTestWorld(10, 10, new Array(100).fill(0)); expect(isWall(world, -1, 0)).toBe(false); expect(isWall(world, 10, 10)).toBe(false); }); }); describe('isBlocked', () => { it('should return true for walls', () => { const tiles: Tile[] = new Array(100).fill(TileType.EMPTY); tiles[55] = TileType.WALL; // wall at 5,5 const world = createTestWorld(10, 10, tiles); const mockAccessor = { getActorsAt: () => [] } as any; expect(isBlocked(world, 5, 5, mockAccessor)).toBe(true); }); it('should return true for actor positions', () => { const world = createTestWorld(10, 10, new Array(100).fill(0)); const mockAccessor = { getActorsAt: (x: number, y: number) => { if (x === 3 && y === 3) return [{ category: "combatant" }]; return []; } } as any; expect(isBlocked(world, 3, 3, mockAccessor)).toBe(true); }); it('should return false for empty floor tiles', () => { const world = createTestWorld(10, 10, new Array(100).fill(0)); const mockAccessor = { getActorsAt: () => [] } as any; expect(isBlocked(world, 3, 3, mockAccessor)).toBe(false); expect(isBlocked(world, 7, 7, mockAccessor)).toBe(false); }); it('should return true for out of bounds', () => { const world = createTestWorld(10, 10, new Array(100).fill(0)); const mockAccessor = { getActorsAt: () => [] } as any; expect(isBlocked(world, -1, 0, mockAccessor)).toBe(true); expect(isBlocked(world, 10, 10, mockAccessor)).toBe(true); }); }); describe('tryDestructTile', () => { it('should destruct a destructible tile', () => { const tiles = new Array(100).fill(TileType.EMPTY); tiles[0] = TileType.GRASS; const world = createTestWorld(10, 10, tiles); const result = tryDestructTile(world, 0, 0); expect(result).toBe(true); expect(world.tiles[0]).toBe(TileType.GRASS_SAPLINGS); }); it('should not destruct a non-destructible tile', () => { const tiles = new Array(100).fill(TileType.EMPTY); tiles[0] = TileType.WALL; const world = createTestWorld(10, 10, tiles); const result = tryDestructTile(world, 0, 0); expect(result).toBe(false); expect(world.tiles[0]).toBe(TileType.WALL); }); it('should return false for out of bounds', () => { const world = createTestWorld(10, 10, new Array(100).fill(TileType.EMPTY)); expect(tryDestructTile(world, -1, 0)).toBe(false); }); }); });