src/history/cache.test.ts
v0.3.0 · 1.7 KB
import { describe, expect, it } from 'vitest';
import { HOUR_MS, candleCacheKey, fillsCacheKey, lookbackWindow, quantizeWindow } from './cache.js';
const T = Date.UTC(2026, 8, 15, 10, 0, 0);
describe('window quantization', () => {
it('two "now" requests within one hour share a cache key', () => {
const a = candleCacheKey({ coin: 'BTC', interval: '1h', startTime: T - 7 * 86_400_000 + 1234, endTime: T + 1234 });
const b = candleCacheKey({ coin: 'BTC', interval: '1h', startTime: T - 7 * 86_400_000 + 59 * 60_000, endTime: T + 59 * 60_000 });
expect(a.key).toBe(b.key);
expect(a.window).toEqual({ startTime: T - 7 * 86_400_000, endTime: T });
const c = candleCacheKey({ coin: 'BTC', interval: '1h', startTime: T, endTime: T + HOUR_MS });
expect(c.key).not.toBe(a.key);
});
it('floors both ends, never inverts the window, validates the quantum', () => {
expect(quantizeWindow({ startTime: 1_500, endTime: 2_500 }, 1_000)).toEqual({ startTime: 1_000, endTime: 2_000 });
expect(quantizeWindow({ startTime: 1_900, endTime: 1_950 }, 1_000)).toEqual({ startTime: 1_000, endTime: 1_000 });
expect(() => quantizeWindow({ startTime: 0, endTime: 1 }, 0)).toThrow(RangeError);
});
it('lookbackWindow: periodStart = quantized periodEnd - lookback', () => {
expect(lookbackWindow(T + 30 * 60_000, 2 * HOUR_MS)).toEqual({ startTime: T - 2 * HOUR_MS, endTime: T });
expect(lookbackWindow(1_000, 10 * HOUR_MS).startTime).toBe(0);
});
it('fills key lowercases the address and has no dex', () => {
const k = fillsCacheKey('0xYOUR_ADDRESS', { startTime: T + 5, endTime: T + HOUR_MS + 5 });
expect(k.key).toBe(`fills|0xyour_address|${T}|${T + HOUR_MS}`);
});
});