Add combat regression tests
This commit is contained in:
parent
44663ba869
commit
90e44264a2
109
tests/game-logic.test.mjs
Normal file
109
tests/game-logic.test.mjs
Normal file
@ -0,0 +1,109 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
import {
|
||||
DEFAULT_PIRATE_SHOT_DAMAGE,
|
||||
PLAYER_HIT_COOLDOWN_MS,
|
||||
PLAYER_MAX_HULL,
|
||||
normalizePlayerDamage,
|
||||
reducePlayerHitQueue,
|
||||
} from '../src/game-logic.js';
|
||||
|
||||
test('first pirate hit removes exactly the default damage and does not end the game', () => {
|
||||
const result = reducePlayerHitQueue({
|
||||
hull: PLAYER_MAX_HULL,
|
||||
lastHitAt: -Infinity,
|
||||
now: 1000,
|
||||
damages: [DEFAULT_PIRATE_SHOT_DAMAGE],
|
||||
});
|
||||
|
||||
assert.equal(result.hull, 94);
|
||||
assert.equal(result.appliedHits, 1);
|
||||
assert.equal(result.ignoredHits, 0);
|
||||
assert.equal(result.totalDamage, 6);
|
||||
assert.equal(result.gameOver, false);
|
||||
});
|
||||
|
||||
test('three cannonballs arriving in one broadside only apply one hull hit', () => {
|
||||
const result = reducePlayerHitQueue({
|
||||
hull: 100,
|
||||
lastHitAt: -Infinity,
|
||||
now: 2000,
|
||||
damages: [6, 6, 6],
|
||||
});
|
||||
|
||||
assert.equal(result.hull, 94);
|
||||
assert.equal(result.appliedHits, 1);
|
||||
assert.equal(result.ignoredHits, 2);
|
||||
});
|
||||
|
||||
test('hit inside cooldown is ignored and exact cooldown boundary is accepted', () => {
|
||||
const blocked = reducePlayerHitQueue({
|
||||
hull: 94,
|
||||
lastHitAt: 1000,
|
||||
now: 1000 + PLAYER_HIT_COOLDOWN_MS - 1,
|
||||
damages: [6],
|
||||
});
|
||||
|
||||
assert.equal(blocked.hull, 94);
|
||||
assert.equal(blocked.appliedHits, 0);
|
||||
assert.equal(blocked.ignoredHits, 1);
|
||||
|
||||
const accepted = reducePlayerHitQueue({
|
||||
hull: 94,
|
||||
lastHitAt: 1000,
|
||||
now: 1000 + PLAYER_HIT_COOLDOWN_MS,
|
||||
damages: [6],
|
||||
});
|
||||
|
||||
assert.equal(accepted.hull, 88);
|
||||
assert.equal(accepted.appliedHits, 1);
|
||||
});
|
||||
|
||||
test('damage normalization handles invalid and extreme values safely', () => {
|
||||
assert.equal(normalizePlayerDamage(undefined), 6);
|
||||
assert.equal(normalizePlayerDamage('not-a-number'), 6);
|
||||
assert.equal(normalizePlayerDamage(999), 25);
|
||||
assert.equal(normalizePlayerDamage(-12), 1);
|
||||
assert.equal(normalizePlayerDamage('8'), 8);
|
||||
});
|
||||
|
||||
test('invalid hull state recovers from max hull before applying damage', () => {
|
||||
const result = reducePlayerHitQueue({
|
||||
hull: Number.NaN,
|
||||
lastHitAt: -Infinity,
|
||||
now: 3000,
|
||||
damages: [6],
|
||||
});
|
||||
|
||||
assert.equal(result.hull, 94);
|
||||
assert.equal(result.gameOver, false);
|
||||
});
|
||||
|
||||
test('lethal hit clamps hull at zero and reports game over', () => {
|
||||
const result = reducePlayerHitQueue({
|
||||
hull: 5,
|
||||
lastHitAt: -Infinity,
|
||||
now: 4000,
|
||||
damages: [6],
|
||||
});
|
||||
|
||||
assert.equal(result.hull, 0);
|
||||
assert.equal(result.totalDamage, 6);
|
||||
assert.equal(result.gameOver, true);
|
||||
});
|
||||
|
||||
test('empty hit queue is a no-op', () => {
|
||||
const result = reducePlayerHitQueue({
|
||||
hull: 72,
|
||||
lastHitAt: 1234,
|
||||
now: 5000,
|
||||
damages: [],
|
||||
});
|
||||
|
||||
assert.equal(result.hull, 72);
|
||||
assert.equal(result.lastHitAt, 1234);
|
||||
assert.equal(result.appliedHits, 0);
|
||||
assert.equal(result.ignoredHits, 0);
|
||||
assert.equal(result.gameOver, false);
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user