import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { AGENT_FLOAT_COUNT } from '../pipelines/agents/agent-generation/agent'; import { createIntroTitleAgents } from './intro-title-agents'; const installCanvasMask = () => { Object.defineProperty(globalThis, 'document', { configurable: true, value: { createElement: vi.fn(() => { const canvas = { width: 0, height: 0, getContext: vi.fn(() => ({ clearRect: vi.fn(), fillStyle: '', fillText: vi.fn(), font: '', getImageData: vi.fn(() => { const data = new Uint8ClampedArray(canvas.width * canvas.height * 4); for (let i = 3; i < data.length; i += 4) { data[i] = 255; } return { data }; }), lineJoin: '', lineWidth: 0, measureText: vi.fn((text: string) => ({ actualBoundingBoxAscent: 10, actualBoundingBoxDescent: 4, width: text.length * 10, })), strokeStyle: '', strokeText: vi.fn(), textAlign: '', textBaseline: '', })), }; return canvas; }), }, }); }; describe('createIntroTitleAgents', () => { beforeEach(() => { installCanvasMask(); }); afterEach(() => { Reflect.deleteProperty(globalThis, 'document'); }); it('creates deterministic agents for the same seed and progress', () => { const first = createIntroTitleAgents({ count: 4, height: 32, progress: 0.4, seed: 123, width: 64, }); const second = createIntroTitleAgents({ count: 4, height: 32, progress: 0.4, seed: 123, width: 64, }); expect(Array.from(first)).toEqual(Array.from(second)); }); it('preserves targets while advancing positions for a later intro progress', () => { const initial = createIntroTitleAgents({ count: 1, height: 32, progress: 0, seed: 456, width: 64, }); const later = createIntroTitleAgents({ count: 1, height: 32, progress: 0.8, seed: 456, width: 64, }); expect(later[0]).not.toBe(initial[0]); expect(later[1]).not.toBe(initial[1]); expect(later[4]).toBe(initial[4]); expect(later[5]).toBe(initial[5]); expect(later[7]).toBe(initial[7]); expect(later.length).toBe(AGENT_FLOAT_COUNT); }); });