feat(pure): pruneHistory with strict 30-day window
This commit is contained in:
@@ -50,3 +50,10 @@ export function computeEstimate(current, target, perTrain, perDay) {
|
|||||||
|
|
||||||
return { remaining, trainsToGo, days, eta };
|
return { remaining, trainsToGo, days, eta };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const THIRTY_DAYS_MS = 30 * MS_PER_DAY;
|
||||||
|
|
||||||
|
export function pruneHistory(entries, now = Date.now()) {
|
||||||
|
const cutoff = now - THIRTY_DAYS_MS;
|
||||||
|
return entries.filter((e) => e.ts > cutoff);
|
||||||
|
}
|
||||||
|
|||||||
+28
-1
@@ -1,6 +1,9 @@
|
|||||||
import { test } from 'node:test';
|
import { test } from 'node:test';
|
||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import { parseTarget, computeEstimate } from '../src/pure.js';
|
import { parseTarget, computeEstimate, pruneHistory } from '../src/pure.js';
|
||||||
|
|
||||||
|
const DAY = 86_400_000;
|
||||||
|
const NOW = 1_700_000_000_000; // fixed reference
|
||||||
|
|
||||||
test('parseTarget: integer numbers', () => {
|
test('parseTarget: integer numbers', () => {
|
||||||
assert.equal(parseTarget(25), 25);
|
assert.equal(parseTarget(25), 25);
|
||||||
@@ -67,3 +70,27 @@ test('computeEstimate: zero perTrain or perDay does not crash', () => {
|
|||||||
assert.equal(b.days, 0);
|
assert.equal(b.days, 0);
|
||||||
assert.equal(b.eta, null);
|
assert.equal(b.eta, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('pruneHistory: keeps entries within 30 days, drops older', () => {
|
||||||
|
const entries = [
|
||||||
|
{ ts: NOW, delta: 100 },
|
||||||
|
{ ts: NOW - 1 * DAY, delta: 100 },
|
||||||
|
{ ts: NOW - 29 * DAY, delta: 100 },
|
||||||
|
{ ts: NOW - 30 * DAY, delta: 100 }, // exactly 30 days, dropped (strict <)
|
||||||
|
{ ts: NOW - 31 * DAY, delta: 100 },
|
||||||
|
];
|
||||||
|
const out = pruneHistory(entries, NOW);
|
||||||
|
assert.equal(out.length, 3);
|
||||||
|
assert.deepEqual(out.map((e) => e.ts), [NOW, NOW - 1 * DAY, NOW - 29 * DAY]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('pruneHistory: does not mutate input', () => {
|
||||||
|
const entries = [{ ts: NOW - 31 * DAY, delta: 100 }];
|
||||||
|
const copy = [...entries];
|
||||||
|
pruneHistory(entries, NOW);
|
||||||
|
assert.deepEqual(entries, copy);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('pruneHistory: empty input', () => {
|
||||||
|
assert.deepEqual(pruneHistory([], NOW), []);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user