src/pending/memory.test.ts
v0.2.1 · 3.3 KB
import { describe, expect, it } from 'vitest';
import { ORDER_ID_A, ORDER_ID_B } from '../testing/fixtures.js';
import {
applyPendingToRead,
createPendingMemory,
DEFAULT_ECHO_TTL_MS,
DEFAULT_FAR_FROM_MARK_TTL_MS,
placeKey,
} from './memory.js';
describe('placeKey', () => {
it('is coin + side + price string, without size', () => {
expect(placeKey('ETH', true, '1650.00')).toBe('ETH|B|1650.00');
expect(placeKey('ETH', false, '1650.00')).toBe('ETH|A|1650.00');
// the same order with a different size is the same key: that is the point
expect(placeKey('ETH', true, '1650.00')).toBe(placeKey('ETH', true, '1650.00'));
});
});
describe('createPendingMemory', () => {
it('remembers a placed key for the echo TTL and forgets it when it shows up', () => {
const m = createPendingMemory();
const t0 = 1_000_000;
const key = placeKey('ETH', true, '1650.00');
m.notePlaced(key, t0);
expect(m.isPlaced(key, t0 + 1)).toBe(true);
expect(m.isPlaced(key, t0 + DEFAULT_ECHO_TTL_MS - 1)).toBe(true);
expect(m.isPlaced(key, t0 + DEFAULT_ECHO_TTL_MS)).toBe(false);
m.notePlaced(key, t0);
m.forgetPlaced(key);
expect(m.isPlaced(key, t0 + 1)).toBe(false);
});
it('remembers a confirmed cancel by exact id', () => {
const m = createPendingMemory({ echoTtlMs: 100 });
m.noteCancelled(ORDER_ID_A, 0);
expect(m.isCancelled(ORDER_ID_A, 50)).toBe(true);
expect(m.isCancelled(ORDER_ID_B, 50)).toBe(false); // rounds to the same double, but the memory is by string
expect(m.isCancelled(ORDER_ID_A, 100)).toBe(false);
});
it('remembers a far-from-mark key for minutes, longer than the echo', () => {
const m = createPendingMemory();
const key = placeKey('X', true, '0.0200');
m.noteFarFromMark(key, 0);
expect(m.isFarFromMark(key, DEFAULT_ECHO_TTL_MS + 1)).toBe(true);
expect(m.isFarFromMark(key, DEFAULT_FAR_FROM_MARK_TTL_MS - 1)).toBe(true);
expect(m.isFarFromMark(key, DEFAULT_FAR_FROM_MARK_TTL_MS)).toBe(false);
});
it('uses the injected clock and reports counts', () => {
let t = 0;
const m = createPendingMemory({ echoTtlMs: 10, farFromMarkTtlMs: 20, now: () => t });
m.notePlaced('a');
m.noteCancelled('1');
m.noteFarFromMark('b');
expect(m.counts()).toEqual({ placed: 1, cancelled: 1, farFromMark: 1 });
t = 10;
expect(m.counts()).toEqual({ placed: 0, cancelled: 0, farFromMark: 1 });
t = 20;
expect(m.counts()).toEqual({ placed: 0, cancelled: 0, farFromMark: 0 });
m.notePlaced('a');
m.reset();
expect(m.counts()).toEqual({ placed: 0, cancelled: 0, farFromMark: 0 });
});
});
describe('applyPendingToRead', () => {
it('strikes out confirmed cancels and releases placed keys that appeared', () => {
const m = createPendingMemory({ echoTtlMs: 1000 });
const seen = { orderId: ORDER_ID_A, coin: 'ETH', isBuy: true, priceStr: '1650.00' };
const gone = { orderId: ORDER_ID_B, coin: 'ETH', isBuy: false, priceStr: '1700.00' };
m.notePlaced(placeKey('ETH', true, '1650.00'), 0);
m.notePlaced(placeKey('ETH', true, '1600.00'), 0); // not yet in the book
m.noteCancelled(ORDER_ID_B, 0);
const out = applyPendingToRead([seen, gone], m, 1);
expect(out).toEqual([seen]);
expect(m.isPlaced(placeKey('ETH', true, '1650.00'), 1)).toBe(false);
expect(m.isPlaced(placeKey('ETH', true, '1600.00'), 1)).toBe(true);
});
});