fix: Ponder: add test infrastructure + coverage for helpers (target 95%) (#287)

- vitest.config.ts: add statements/functions/branches thresholds alongside
  lines so the coverage gate catches regressions in all four dimensions
- tests/stats.test.ts: replace weak "> 0n" / "toBeDefined()" assertions with
  exact expected values derived from the ring buffer algebra:
  - hour-advanced path: mintedLastWeek=480n, mintedLastDay=220n,
    burnedLastWeek=240n, burnedLastDay=110n, mintNextHourProjected=68n,
    burnNextHourProjected=34n, netSupplyChangeDay=110n,
    netSupplyChangeWeek=240n
  - same-hour projection path: mintNextHourProjected=140n (elapsed-seconds
    scaling verified), burnNextHourProjected=0n (medium=0 fallback path)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
openhands 2026-02-25 23:28:25 +00:00
parent 76560fd26b
commit 16dc1827c9
2 changed files with 23 additions and 8 deletions

View file

@ -287,11 +287,20 @@ describe('updateHourlyData', () => {
const dbMock = ctx as unknown as { db: { update: ReturnType<typeof vi.fn> } };
const setArg = (dbMock.db.update as ReturnType<typeof vi.fn>).mock.results[0].value.set.mock.calls[0][0];
// mintedLastWeek and mintedLastDay should be positive
expect(setArg.mintedLastWeek).toBeGreaterThan(0n);
expect(setArg.mintedLastDay).toBeGreaterThan(0n);
expect(setArg.burnedLastWeek).toBeGreaterThan(0n);
expect(setArg.burnedLastDay).toBeGreaterThan(0n);
// After advancing 2 hours (new pointer=7), slots 6+7 are cleared (were already 0).
// Filled slots: i=2..49 from pointer=7 (48 slots × 10n minted / 5n burned).
// mintedLastDay: i<24 → i=2..23 = 22 slots × 10n = 220n
// mintedLastWeek: 48 × 10n = 480n
// mintNextHourProjected = mintedWeek / 7n = 480n / 7n = 68n (BigInt truncation)
// burnNextHourProjected = burnedWeek / 7n = 240n / 7n = 34n
expect(setArg.mintedLastWeek).toBe(480n);
expect(setArg.mintedLastDay).toBe(220n);
expect(setArg.burnedLastWeek).toBe(240n);
expect(setArg.burnedLastDay).toBe(110n);
expect(setArg.mintNextHourProjected).toBe(68n);
expect(setArg.burnNextHourProjected).toBe(34n);
expect(setArg.netSupplyChangeDay).toBe(110n);
expect(setArg.netSupplyChangeWeek).toBe(240n);
});
it('carries forward holderCount into new ring buffer slots', async () => {
@ -333,9 +342,12 @@ describe('updateHourlyData', () => {
const dbMock = ctx as unknown as { db: { update: ReturnType<typeof vi.fn> } };
expect(dbMock.db.update).toHaveBeenCalled();
const setArg = (dbMock.db.update as ReturnType<typeof vi.fn>).mock.results[0].value.set.mock.calls[0][0];
// Projections should be computed
expect(setArg.mintNextHourProjected).toBeDefined();
expect(setArg.burnNextHourProjected).toBeDefined();
// elapsed = 1800s (30 min); current minted = 100n, prev minted = 80n
// projectedTotal = (100n * 3600n) / 1800n = 200n
// medium = (80n + 200n) / 2n = 140n → mintProjection = 140n
// burn: current=0n, prev=0n → medium=0n → fallback: mintedWeek/7 = 0n
expect(setArg.mintNextHourProjected).toBe(140n);
expect(setArg.burnNextHourProjected).toBe(0n);
});
it('handles zero elapsedSeconds in projection (exact hour boundary)', async () => {

View file

@ -14,6 +14,9 @@ export default defineConfig({
reporter: ['text', 'lcov'],
thresholds: {
lines: 95,
statements: 95,
functions: 95,
branches: 80,
},
},
},