airship-phaser/tests/wiring.test.mjs

69 lines
3.2 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { readFile } from 'node:fs/promises';
const read = (path) => readFile(new URL(`../${path}`, import.meta.url), 'utf8');
test('mobile HUD uses split helm frame and knob assets', async () => {
const source = await read('src/mobile-hud.js');
assert.match(source, /import helmFrameSrc from '.\/assets\/controller\/helm-frame\.js'/);
assert.match(source, /import helmKnobSrc from '.\/assets\/controller\/helm-knob\.js'/);
assert.doesNotMatch(source, /helmSpriteSheetSrc/);
assert.doesNotMatch(source, /helm-sheet\.webp/);
assert.doesNotMatch(source, /backgroundPosition = .*column/);
});
test('drag control emits and HUD consumes one shared helm vector event', async () => {
const [index, hud] = await Promise.all([
read('index.html'),
read('src/mobile-hud.js'),
]);
assert.match(index, /CustomEvent\('airship:helm-vector'/);
assert.match(index, /emitHelmVector\(dx \/ radius, dy \/ radius\)/);
assert.match(index, /emitHelmVector\(0, 0\)/);
assert.match(hud, /addEventListener\('airship:helm-vector'/);
assert.match(hud, /setHelmKnob\(event\.detail\?\.x \?\? 0, event\.detail\?\.y \?\? 0\)/);
});
test('top HUD and cannon controls use direct image modules', async () => {
const source = await read('src/mobile-hud.js');
assert.match(source, /import topHudSrc from '.\/assets\/controller\/top-hud\.js'/);
assert.match(source, /import cannonRoundelSrc from '.\/assets\/controller\/cannon-roundel\.js'/);
assert.match(source, /addPiece\('steam-top', topHudSrc/);
assert.match(source, /addPiece\('steam-cannon-port', cannonRoundelSrc/);
assert.match(source, /addPiece\('steam-cannon-starboard', cannonRoundelSrc/);
});
test('player collision callback queues hits and processing occurs in scene update', async () => {
const source = await read('src/game-v4.js');
assert.match(source, /this\.pendingPlayerHits\.push\(\{ shot, damage \}\)/);
assert.match(source, /this\.processPlayerHits\(\)/);
assert.match(source, /processQueuedPlayerHits\(\{/);
assert.match(source, /combat:player-hit-queued/);
assert.match(source, /combat:player-hit-processed/);
});
test('wide-screen HUD keeps visual controls aligned with touch hit-zones', async () => {
const source = await read('src/mobile-hud.js');
assert.match(source, /@media \(min-width: 700px\)/);
assert.match(source, /--steam-wide-helm-size:/);
assert.match(source, /--steam-wide-cannon-size:/);
assert.match(source, /\.steam-radar-wrap,\s*#mobile-controls\.controller-active #drag-stick/);
assert.match(source, /\.steam-cannon-port,\s*\.steam-cannon-starboard,\s*#mobile-controls\.controller-active \.mobile-control\.port,\s*#mobile-controls\.controller-active \.mobile-control\.starboard/);
assert.match(source, /right: calc\(var\(--steam-wide-edge-right\) \+ var\(--steam-wide-cannon-size\) \+ 14px\)/);
});
test('wide-screen HUD caps portrait-scaled artwork instead of stretching with viewport width', async () => {
const source = await read('src/mobile-hud.js');
assert.match(source, /\.steam-top \{[\s\S]*?width: min\(64vw, 560px\)/);
assert.match(source, /\.steam-player-card \{[\s\S]*?width: min\(34vw, 360px\)/);
assert.match(source, /\.steam-enemy-card \{[\s\S]*?width: min\(30vw, 330px\)/);
});