feat(store): recordTrain with pruning and getSummary
This commit is contained in:
+16
-1
@@ -1,4 +1,4 @@
|
||||
import { parseTarget } from './pure.js';
|
||||
import { parseTarget, pruneHistory, summary as computeSummary } from './pure.js';
|
||||
|
||||
const KEY_TARGETS = 'tat.targets';
|
||||
const KEY_HISTORY = 'tat.history';
|
||||
@@ -78,4 +78,19 @@ export class Store {
|
||||
this.prefs.pos = { x: pos.x, y: pos.y };
|
||||
return this._saveJson(KEY_PREFS, this.prefs);
|
||||
}
|
||||
|
||||
recordTrain(attr, delta, ts = Date.now()) {
|
||||
if (typeof delta !== 'number' || !Number.isFinite(delta) || delta <= 0) {
|
||||
return false;
|
||||
}
|
||||
const list = this.history[attr] || [];
|
||||
list.push({ ts, delta });
|
||||
this.history[attr] = pruneHistory(list, ts);
|
||||
return this._saveJson(KEY_HISTORY, this.history);
|
||||
}
|
||||
|
||||
getSummary(attr, now = Date.now()) {
|
||||
const list = this.history[attr] || [];
|
||||
return computeSummary(list, now);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { Store } from '../src/store.js';
|
||||
import { MS_PER_DAY } from '../src/pure.js';
|
||||
import { createLocalStorage } from './localstorage-shim.js';
|
||||
|
||||
const DAY = MS_PER_DAY;
|
||||
const NOW = 1_700_000_000_000;
|
||||
|
||||
function freshStore() {
|
||||
return new Store({ storage: createLocalStorage() });
|
||||
}
|
||||
@@ -70,3 +74,28 @@ test('Store: latches off further saves after a storage write failure', () => {
|
||||
assert.equal(s.getTarget('strength'), 25_000_000);
|
||||
assert.equal(s.getTarget('speed'), 50_000_000);
|
||||
});
|
||||
|
||||
test('Store: recordTrain appends to per-attribute history', () => {
|
||||
const s = freshStore();
|
||||
s.recordTrain('strength', 247, NOW);
|
||||
s.recordTrain('strength', 250, NOW - 1000);
|
||||
assert.equal(s.history.strength.length, 2);
|
||||
assert.equal(s.history.strength[0].delta, 247);
|
||||
});
|
||||
|
||||
test('Store: recordTrain prunes entries older than 30 days', () => {
|
||||
const s = freshStore();
|
||||
s.recordTrain('strength', 100, NOW - 31 * DAY);
|
||||
s.recordTrain('strength', 200, NOW);
|
||||
assert.equal(s.history.strength.length, 1);
|
||||
assert.equal(s.history.strength[0].delta, 200);
|
||||
});
|
||||
|
||||
test('Store: getSummary returns computed summary for attribute', () => {
|
||||
const s = freshStore();
|
||||
s.recordTrain('strength', 247, NOW - 1000);
|
||||
s.recordTrain('strength', 247, NOW - 2000);
|
||||
const sum = s.getSummary('strength', NOW);
|
||||
assert.equal(sum.trainsToday, 2);
|
||||
assert.equal(sum.perDay, Math.floor((2 / 7) * 247));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user