step 10.11: done

This commit is contained in:
bepis
2026-10-23 02:33:16 +11:00
parent e124266c76
commit 08d880ab73
9 changed files with 451 additions and 20 deletions
+79
View File
@@ -0,0 +1,79 @@
// Unit tests for computeHp — natural HP regeneration (+1% max HP/min, lazy computation).
const test = require('node:test');
const assert = require('node:assert');
const { computeHp } = require('../../src/game/hp');
test('computeHp: no change when clock is same', () => {
const result = computeHp(50, 100, 1000, 1000);
assert.strictEqual(result.hp, 50);
assert.strictEqual(result.updatedAtMs, 1000);
});
test('computeHp: no change when clock went backwards', () => {
const result = computeHp(50, 100, 1000, 500);
assert.strictEqual(result.hp, 50);
assert.strictEqual(result.updatedAtMs, 1000);
});
test('computeHp: no change when less than 1 minute elapsed', () => {
const result = computeHp(50, 100, 1000, 60000); // 59s elapsed
assert.strictEqual(result.hp, 50);
assert.strictEqual(result.updatedAtMs, 1000);
});
test('computeHp: +1% max HP after 1 minute', () => {
const result = computeHp(50, 100, 1000, 61000); // 60s later
assert.strictEqual(result.hp, 51); // 1% of 100 = 1
assert.strictEqual(result.updatedAtMs, 1000 + 60000);
});
test('computeHp: +5% max HP after 5 minutes', () => {
const result = computeHp(50, 100, 1000, 310000); // 300s later
assert.strictEqual(result.hp, 55); // 5% of 100 = 5
assert.strictEqual(result.updatedAtMs, 1000 + 5 * 60000);
});
test('computeHp: caps at maxHp and resets timestamp', () => {
const result = computeHp(99, 100, 1000, 121000); // 120s later → +2% → 101 → cap at 100
assert.strictEqual(result.hp, 100);
assert.strictEqual(result.updatedAtMs, 121000);
});
test('computeHp: already at max HP stays at max', () => {
const result = computeHp(100, 100, 1000, 3600000); // 1 hour later
assert.strictEqual(result.hp, 100);
assert.strictEqual(result.updatedAtMs, 3600000);
});
test('computeHp: large gap — multiple minutes', () => {
// 10 minutes later, maxHp=135 → +10% = 13 HP
const result = computeHp(20, 135, 1000, 601000); // 600s later
assert.strictEqual(result.hp, 33); // 20 + floor(10 * 135 / 100) = 20 + 13 = 33
assert.strictEqual(result.updatedAtMs, 1000 + 10 * 60000);
});
test('computeHp: large gap caps at max', () => {
// 2 hours later, maxHp=135, started at 5 → +120% → cap at 135
const result = computeHp(5, 135, 1000, 7201000); // 7200s later
assert.strictEqual(result.hp, 135);
assert.strictEqual(result.updatedAtMs, 7201000);
});
test('computeHp: fractional percent floors correctly', () => {
// maxHp=100, 1 minute → +1% = +1
const result = computeHp(0, 100, 1000, 61000);
assert.strictEqual(result.hp, 1);
});
test('computeHp: partial tick preserved in timestamp', () => {
// 90 seconds = 1 full minute + 30s partial
const result = computeHp(50, 100, 1000, 91000);
assert.strictEqual(result.hp, 51); // 1 tick
assert.strictEqual(result.updatedAtMs, 1000 + 60000); // partial 30s preserved
});
test('computeHp: zero max HP edge case', () => {
const result = computeHp(0, 0, 1000, 1000000);
assert.strictEqual(result.hp, 0);
assert.strictEqual(result.updatedAtMs, 1000000);
});