import { describe, expect, it } from 'vitest';
import type { TileMapData } from '../IsometricTileMap';
import { renderMinimap } from '../minimap';
/** Карта 3×2: два разных тайла + заблокированная клетка. */
function tinyMap(): TileMapData {
return {
width: 3,
height: 2,
tiles: [1, 2, 1, 2, 1, 2],
blocked: [0, 0, 1, 0, 0, 0],
};
}
const px = (img: { width: number; rgba: Uint8Array }, x: number, y: number): [number, number, number] => {
const i = (y * img.width + x) * 4;
return [img.rgba[i]!, img.rgba[i + 1]!, img.rgba[i + 2]!];
};
describe('renderMinimap', () => {
it('размер картинки = карта × cell', () => {
const img = renderMinimap(tinyMap(), { colors: { 1: 0x101010, 2: 0x202020 }, cell: 3 });
expect(img.width).toBe(9);
expect(img.height).toBe(6);
expect(img.rgba.length).toBe(9 * 6 * 4);
});
it('клетка целиком красится цветом своего тайла', () => {
const img = renderMinimap(tinyMap(), { colors: { 1: 0xff0000, 2: 0x00ff00 }, cell: 2 });
// Тайл (0,0) = id 1, тайл (1,0) = id 2.
expect(px(img, 0, 0)).toEqual([255, 0, 0]);
expect(px(img, 1, 1)).toEqual([255, 0, 0]);
expect(px(img, 2, 0)).toEqual([0, 255, 0]);
expect(px(img, 5, 3)).toEqual([0, 255, 0]);
});
it('незаданный тайл — fallbackColor', () => {
const img = renderMinimap(tinyMap(), { colors: { 1: 0xff0000 }, fallbackColor: 0x0a0b0c, cell: 2 });
expect(px(img, 2, 0)).toEqual([10, 11, 12]);
// И без явного fallback — тёмный по умолчанию.
const plain = renderMinimap(tinyMap(), { colors: { 1: 0xff0000 }, cell: 2 });
expect(px(plain, 2, 0)[0]).toBeLessThan(64);
});
it('маркер перекрашивает свою клетку с тёмной рамкой', () => {
const img = renderMinimap(tinyMap(), {
colors: { 1: 0x101010, 2: 0x101010 },
cell: 3,
markers: [{ x: 1, y: 1, color: 0xffff00 }],
});
// Центр клетки — цвет маркера, угол — рамка.
expect(px(img, 4, 4)).toEqual([255, 255, 0]);
expect(px(img, 3, 3)[0]).toBeLessThan(64);
// Соседняя клетка не задета.
expect(px(img, 7, 4)).toEqual([16, 16, 16]);
});
it('маркер вне карты молча пропускается', () => {
const img = renderMinimap(tinyMap(), {
colors: { 1: 0x101010, 2: 0x101010 },
cell: 2,
markers: [{ x: 9, y: 9, color: 0xffff00 }],
});
expect(px(img, 0, 0)).toEqual([16, 16, 16]);
});
it('проп красит весь footprint своим цветом поверх тайлов', () => {
const map = { ...tinyMap(), props: [{ id: 7, x: 0, y: 0, w: 2, h: 2 }] };
const img = renderMinimap(map, { colors: { 1: 0xff0000, 2: 0x00ff00, 7: 0x0000ff }, cell: 3 });
// Клетки (0,0) и (1,1) — под пропом, тайл 1/2 перекрашен синим.
expect(px(img, 0, 0)).toEqual([0, 0, 255]);
expect(px(img, 4, 4)).toEqual([0, 0, 255]);
// Клетка вне footprint осталась цветом своего тайла (id 1 — красный).
expect(px(img, 7, 0)).toEqual([255, 0, 0]);
});
it('проп без записи в colors — fallbackColor', () => {
const map = { ...tinyMap(), props: [{ id: 7, x: 2, y: 1, w: 1, h: 1 }] };
const img = renderMinimap(map, { colors: { 1: 0x101010, 2: 0x101010 }, fallbackColor: 0x3c3c48, cell: 3 });
expect(px(img, 8, 4)).toEqual([60, 60, 72]);
});
it('footprint у края карты не выходит за границы', () => {
// Проп 3×3 от (1,0): правый столбец клеток вылезает за ширину 3.
const map = { ...tinyMap(), props: [{ id: 7, x: 1, y: 0, w: 3, h: 3 }] };
const img = renderMinimap(map, { colors: { 1: 0x101010, 7: 0x0000ff }, cell: 3 });
expect(() => px(img, 8, 5)).not.toThrow();
// Клетка (2,0) под пропом покрашена, выход за карту не рисуется.
expect(px(img, 8, 0)).toEqual([0, 0, 255]);
});
});