import { readFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import { SIZES, SLOTS } from '../sizes.mjs';
/**
* Реестр размеров (sizes.mjs) — единственный источник размеров спрайтов
* для gen.mjs и lint-art.mjs. Здесь проверяется сам реестр и его
* согласованность с фактическими ассетами (манифест AI-атласов).
*/
const here = dirname(fileURLToPath(import.meta.url));
const dim = (s: { w: number } | number[]) => (Array.isArray(s) ? `${s[0]}x${s[1]}` : `${s.w}x${s.h}`);
describe('реестр размеров спрайтов', () => {
it('все группы дают валидные слоты «ширина x высота»', () => {
for (const group of Object.values(SIZES)) {
const sizes = 'w' in group ? [group] : Object.values(group);
for (const s of sizes) {
expect(dim(s as never)).toMatch(/^\d+x\d+$/);
}
}
});
it('базовые слоты арт-библии на месте', () => {
for (const slot of ['32x16', '16x24', '20x20', '32x48', '32x56', '32x80', '64x80']) {
expect(SLOTS.has(slot), slot).toBe(true);
}
});
it('frameSize манифеста AI-атласов входит в слоты', () => {
const manifest = JSON.parse(
readFileSync(resolve(here, '../../aiart/atlas-manifest.json'), 'utf8')
) as Record<string, { frameSize?: [number, number] }>;
for (const [id, entry] of Object.entries(manifest)) {
const fs = entry.frameSize;
if (!fs) continue;
expect(SLOTS.has(`${fs[0]}x${fs[1]}`), id).toBe(true);
}
});
});