forked from phenom/healer-man
69 lines
3.5 KiB
JavaScript
69 lines
3.5 KiB
JavaScript
const { test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { createWeaponEvidenceRecorder } = require('./weapon-evidence-recorder.cjs');
|
|
|
|
function fixture() {
|
|
let state = { combatEvents: [], mobs: {}, auras: [] };
|
|
const listeners = new Set();
|
|
return { getState: () => state, subscribe(fn) { listeners.add(fn); return () => listeners.delete(fn); },
|
|
commit(next) { state = next; for (const fn of listeners) fn(state); },
|
|
listenerCount: () => listeners.size };
|
|
}
|
|
|
|
test('retains source shout parent and child timers without recording unrelated auras', () => {
|
|
const store = fixture(), recorder = createWeaponEvidenceRecorder(store, { clock: () => 123 });
|
|
const aura = (id) => ({ instanceId: id, definition: { id }, sourceId: 'boss', targetId: 'player',
|
|
appliedAt: 100, expiresAt: 5_100, stacks: 1 });
|
|
store.commit({ combatEvents: [], mobs: {}, auras: [
|
|
aura('enemy-control:source-spell-5246'), aura('enemy-control:source-spell-20511'), aura('unrelated'),
|
|
] });
|
|
assert.deepEqual(recorder.stop().auraSamples.at(-1).auras.map((entry) => entry.definitionId), [
|
|
'enemy-control:source-spell-5246', 'enemy-control:source-spell-20511',
|
|
]);
|
|
});
|
|
|
|
test('retains consecutive results beyond the HUD ring and unsubscribes without changing state', () => {
|
|
const store = fixture(), recorder = createWeaponEvidenceRecorder(store);
|
|
let history = [];
|
|
for (let id = 1; id <= 350; id++) {
|
|
history = [...history, { id, attackHand: 'offhand', rawAmount: 30 }].slice(-200);
|
|
store.commit({ combatEvents: history, mobs: {}, auras: [] });
|
|
}
|
|
const before = store.getState(), result = recorder.stop();
|
|
assert.equal(store.getState(), before);
|
|
assert.equal(result.events.length, 350);
|
|
assert.deepEqual(result.gaps, []);
|
|
assert.equal(result.events[349].attackHand, 'offhand');
|
|
assert.equal(store.listenerCount(), 0);
|
|
store.commit({ ...before, combatEvents: [...history, { id: 351 }] });
|
|
assert.equal(recorder.stop().events.length, 350);
|
|
});
|
|
|
|
test('reports dropped IDs and capacity overflow rather than claiming complete evidence', () => {
|
|
const store = fixture(), recorder = createWeaponEvidenceRecorder(store, { capacity: 2 });
|
|
store.commit({ combatEvents: [{ id: 3 }, { id: 4 }, { id: 5 }], mobs: {}, auras: [] });
|
|
const result = recorder.stop();
|
|
assert.deepEqual(result.gaps, [{ afterId: 0, beforeId: 3 }]);
|
|
assert.equal(result.discardedEvents, 1);
|
|
assert.equal(result.events.length, 2);
|
|
});
|
|
|
|
test('copies transient weapon queues and party debuffs between checkpoints', () => {
|
|
const store = fixture(), recorder = createWeaponEvidenceRecorder(store, { clock: () => 123 });
|
|
const pending = [{ id: 'thrash', remaining: 2, sourceSpellId: 3391 }];
|
|
const state = { combatEvents: [], mobs: { boss: { id: 'boss', name: 'Boss',
|
|
engaged: true, dualWieldEnabled: true, nextEnemyOffhandAttackAt: 200,
|
|
pendingExtraAttacks: pending } }, auras: [{ instanceId: 'tank-wound',
|
|
definition: { id: 'enemy-source-spell-17230', dispelCategory: 'disease' },
|
|
targetId: 'tank', sourceId: 'boss', appliedAt: 123, expiresAt: 300123, stacks: 1 }] };
|
|
store.commit(state);
|
|
pending[0].remaining = 0;
|
|
store.commit({ ...state, mobs: { boss: { ...state.mobs.boss,
|
|
pendingExtraAttacks: [], nextEnemyOffhandAttackAt: 400 } }, auras: [] });
|
|
const result = recorder.stop();
|
|
assert.equal(result.mobSamples[0].pendingExtraAttacks[0].remaining, 2);
|
|
assert.equal(result.mobSamples[1].nextEnemyOffhandAttackAt, 400);
|
|
assert.equal(result.auraSamples[1].auras[0].targetId, 'tank');
|
|
assert.deepEqual(result.auraSamples[2].auras, []);
|
|
});
|