Files
iron-requiem/tests/scaffold.test.js
Kay Kayyali 4f0f8fcf26 feat: S1.1 project scaffold — TDD RED->GREEN (17/17 tests)
RED: scaffold.test.js — 17 tests for constants, Phaser config, fixtures
GREEN: src/constants.js (25 GDD-derived values), src/main.js (CANVAS + arcade)
GREEN: webpack.config.js + .babelrc + index.html (dark theme)
GREEN: Dockerfile (nginx:alpine) + docker-compose.yml (Traefik + CF Tunnel)
GREEN: jest-canvas-mock + tests/helpers/setup.js (headless Phaser)
Verified: npm run build -> dist/, docker deploy -> https://iron-requiem.damascusfront.net
2026-05-23 06:22:07 +00:00

145 lines
4.5 KiB
JavaScript

/**
* Scaffold tests — Slice 1 foundation verification.
*
* Tests that the project skeleton compiles, the Phaser game config
* is valid, and all game balance constants are defined and in range.
*/
const { createHeadlessGame } = require('./helpers/setup');
const { createTankState, createCrewState } = require('./helpers/fixtures');
// ---------------------------------------------------------------------------
// Constants validation
// ---------------------------------------------------------------------------
describe('Game constants', () => {
let constants;
beforeAll(() => {
constants = require('../src/constants');
});
test('TANK_MAX_SPEED is a positive number', () => {
expect(constants.TANK_MAX_SPEED).toBeGreaterThan(0);
expect(typeof constants.TANK_MAX_SPEED).toBe('number');
});
test('TANK_ACCELERATION is a positive number', () => {
expect(constants.TANK_ACCELERATION).toBeGreaterThan(0);
expect(typeof constants.TANK_ACCELERATION).toBe('number');
});
test('TANK_FRICTION is a positive number', () => {
expect(constants.TANK_FRICTION).toBeGreaterThan(0);
expect(typeof constants.TANK_FRICTION).toBe('number');
});
test('TURRET_MAX_ROTATION equals 15 deg/sec', () => {
expect(constants.TURRET_MAX_ROTATION).toBe(15);
});
test('MORALE_MAX is 100', () => {
expect(constants.MORALE_MAX).toBe(100);
});
test('MORALE_BUFF_THRESHOLD is 70', () => {
expect(constants.MORALE_BUFF_THRESHOLD).toBe(70);
});
test('MORALE_RECOVERY_RATE is a positive number', () => {
expect(constants.MORALE_RECOVERY_RATE).toBeGreaterThan(0);
expect(typeof constants.MORALE_RECOVERY_RATE).toBe('number');
});
test('HEAT_MAX is 100', () => {
expect(constants.HEAT_MAX).toBe(100);
});
test('heat rates are positive numbers', () => {
expect(constants.HEAT_IDLE_RATE).toBeGreaterThan(0);
expect(constants.HEAT_MAX_SPEED_RATE).toBeGreaterThan(0);
expect(constants.HEAT_COOLING_RATE).toBeGreaterThan(0);
});
test('PERISCOPE_FOV is 180 degrees', () => {
expect(constants.PERISCOPE_FOV).toBe(180);
});
test('PERISCOPE_RANGE is 200 pixels', () => {
expect(constants.PERISCOPE_RANGE).toBe(200);
});
test('UNBUTTONED_FOV is 270 degrees', () => {
expect(constants.UNBUTTONED_FOV).toBe(270);
});
test('UNBUTTONED_RANGE is 350 pixels', () => {
expect(constants.UNBUTTONED_RANGE).toBe(350);
});
test('all required constants are defined', () => {
const required = [
'TANK_MAX_SPEED',
'TANK_ACCELERATION',
'TANK_FRICTION',
'TURRET_MAX_ROTATION',
'MORALE_MAX',
'MORALE_BUFF_THRESHOLD',
'MORALE_RECOVERY_RATE',
'HEAT_MAX',
'HEAT_IDLE_RATE',
'HEAT_MAX_SPEED_RATE',
'HEAT_COOLING_RATE',
'PERISCOPE_FOV',
'PERISCOPE_RANGE',
'UNBUTTONED_FOV',
'UNBUTTONED_RANGE',
];
for (const key of required) {
expect(constants).toHaveProperty(key);
}
});
});
// ---------------------------------------------------------------------------
// Phaser game config
// ---------------------------------------------------------------------------
describe('Phaser game config', () => {
test('game config has the correct properties', () => {
// Verify the config object from main.js without actually booting a game
// (Phaser HEADLESS still needs a real canvas implementation in jsdom)
const config = require('../src/main').gameConfig;
expect(config.type).toBeDefined();
expect(config.width).toBe(640);
expect(config.height).toBe(360);
expect(config.pixelArt).toBe(true);
expect(config.roundPixels).toBe(true);
expect(config.physics).toBeDefined();
expect(config.physics.default).toBe('arcade');
expect(config.physics.arcade.gravity).toEqual({ x: 0, y: 0 });
expect(config.scene).toBeDefined();
});
});
// ---------------------------------------------------------------------------
// Fixtures
// ---------------------------------------------------------------------------
describe('Test fixtures', () => {
test('createTankState returns defaults and accepts overrides', () => {
const state = createTankState();
expect(state.x).toBe(320);
expect(state.y).toBe(180);
expect(state.isButtonedUp).toBe(true);
const custom = createTankState({ x: 100, isButtonedUp: false });
expect(custom.x).toBe(100);
expect(custom.isButtonedUp).toBe(false);
});
test('createCrewState defaults morale to 50', () => {
const state = createCrewState();
expect(state.morale).toBe(50);
expect(state.commanderAlive).toBe(true);
});
});