Skip to content
markpaper

src/history/cache.test.ts

v0.3.0 · 1.7 KB

Download file
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}`);
  });
});
All files