import { describe, it, expect, vi } from 'vitest'; /** * G4 (gap closure 02-06) — assert gate-renderer adds a faint vertical * wall band primitive at the gate's column. * * Phaser-Scene-mock pattern from Plan 02-06 Task 3 (avoids the Phaser 4 / * happy-dom canvas.getContext incompatibility per Plan 02-02 SUMMARY). * vi.mock('phaser') short-circuits the Phaser bundle import so this test * can exercise drawGate's call surface in isolation; BlendModes.ADD is * mocked as a sentinel value. */ vi.mock('phaser', () => ({ default: { BlendModes: { ADD: 1 } }, BlendModes: { ADD: 1 }, })); const { drawGate, WALL_BAND_X, WALL_BAND_WIDTH, WALL_BAND_HEIGHT, WALL_BAND_ALPHA, WALL_BAND_COLOR, } = await import('./gate-renderer'); type Scene = Parameters[0]; function makeRectangleMock(): { setInteractive: ReturnType; on: ReturnType; setData: ReturnType; setBlendMode: ReturnType; setAlpha: ReturnType; } { const r = { setInteractive: vi.fn().mockReturnThis(), on: vi.fn().mockReturnThis(), setData: vi.fn().mockReturnThis(), setBlendMode: vi.fn().mockReturnThis(), setAlpha: vi.fn().mockReturnThis(), }; return r; } function makeScene(): Scene { const rectangle = makeRectangleMock(); return { add: { rectangle: vi.fn(() => rectangle), }, tweens: { add: vi.fn() }, } as unknown as Scene; } describe('gate-renderer (Plan 02-06 G4 closure)', () => { it('exports the wall band geometry constants with expected values', () => { expect(WALL_BAND_X).toBe(880); // matches GATE_X expect(WALL_BAND_HEIGHT).toBe(768); // matches Phaser canvas height expect(WALL_BAND_ALPHA).toBeGreaterThanOrEqual(0.15); // fix_shape range expect(WALL_BAND_ALPHA).toBeLessThanOrEqual(0.2); // fix_shape range expect(WALL_BAND_COLOR).toBe(0x6e6e75); // same hue as GATE_COLOR expect(WALL_BAND_WIDTH).toBeGreaterThan(0); }); it('drawGate adds the wall primitive at the gate column with low alpha', () => { const scene = makeScene(); drawGate(scene); // First scene.add.rectangle call is the wall band (per drawGate // implementation order — wall is drawn behind everything else). const firstCall = (scene.add.rectangle as ReturnType).mock.calls[0]; // Signature: (x, y, width, height, fillColor, fillAlpha) expect(firstCall[0]).toBe(WALL_BAND_X); // x expect(firstCall[1]).toBe(WALL_BAND_HEIGHT / 2); // y-centered expect(firstCall[2]).toBe(WALL_BAND_WIDTH); // width expect(firstCall[3]).toBe(WALL_BAND_HEIGHT); // height = canvas height (full vertical span) expect(firstCall[4]).toBe(WALL_BAND_COLOR); // color expect(firstCall[5]).toBe(WALL_BAND_ALPHA); // alpha — low (0.18) }); it('drawGate creates 4 rectangles total (wall + body + glow + hit)', () => { const scene = makeScene(); drawGate(scene); expect(scene.add.rectangle as ReturnType).toHaveBeenCalledTimes(4); }); it('returned GateGameObjects exposes the wall handle', () => { const scene = makeScene(); const gate = drawGate(scene); expect(gate.wall).toBeDefined(); expect(gate.body).toBeDefined(); expect(gate.glow).toBeDefined(); expect(gate.hit).toBeDefined(); expect(gate.glowTween).toBeNull(); }); });