// Generated, do not edit. sha256:039e04e27156f848885588b6e6606b98400d17636d393358e29be3da504be7d4 import { describe, it, beforeEach, mock } from 'node:test'; import assert from 'node:assert/strict'; const OPGESLAGEN = new Map(); let SCHRIJVEN = 0; mock.module('../../client/data/preferences.js', { namedExports: { getPref: async (scope, key, d) => (OPGESLAGEN.has(`${scope}|${key}`) ? structuredClone(OPGESLAGEN.get(`${scope}|${key}`)) : d), setPref: async (scope, key, v) => { SCHRIJVEN++; OPGESLAGEN.set(`${scope}|${key}`, structuredClone(v)); }, }, }); const { MOMENTUM, addPrice, restore, tally, loadMomentum, recordSpot, momentumOf, clearMomentum } = await import('../../client/price/momentum.js'); const MIN = 60000; function reeks(prijzen, start = 0) { return prijzen.reduce((b, p, i) => addPrice(b, p, start + i * MIN), null); } describe('addPrice en tally', () => { it('telt een stijging en een daling als twee bewegingen', () => { const t = tally(reeks([100, 101, 100]), 3 * MIN); assert.deepEqual([t.up, t.down], [1, 1]); }); it('een ongewijzigde prijs is geen beweging', () => { const t = tally(reeks([100, 100, 100, 101, 101]), 5 * MIN); assert.deepEqual([t.up, t.down], [1, 0]); }); it('houdt alleen de laatste SIZE bewegingen', () => { const prijzen = []; for (let i = 0; i <= MOMENTUM.SIZE; i++) prijzen.push(1000 - i); for (let i = 1; i <= 10; i++) prijzen.push(1000 - MOMENTUM.SIZE + i); const t = tally(reeks(prijzen), prijzen.length * MIN); assert.equal(t.up + t.down, MOMENTUM.SIZE); assert.deepEqual([t.up, t.down], [10, MOMENTUM.SIZE - 10]); }); it('een sprong na een oude referentie is geen beweging', () => { let b = addPrice(null, 100, 0); b = addPrice(b, 200, MOMENTUM.MAX_AGE_MS + MIN); assert.deepEqual(b.moves, [], 'de nacht ertussen telt niet'); assert.equal(b.last, 200, 'maar de nieuwe prijs is wel de referentie'); }); it('oude bewegingen vallen uit de telling', () => { const b = reeks([100, 101, 102]); assert.equal(tally(b, 2 * MIN).up, 2); assert.equal(tally(b, 2 * MIN + MOMENTUM.MAX_AGE_MS + 1).up, 0); }); it('een ongeldige prijs laat de buffer staan', () => { const b = reeks([100, 101]); assert.equal(addPrice(b, null, 3 * MIN), b); assert.equal(addPrice(b, 0, 3 * MIN), b); assert.equal(addPrice(b, NaN, 3 * MIN), b); }); }); describe('de richting', () => { it('zonder beweging geen richting', () => { assert.equal(tally(reeks([100]), 0).tone, null); assert.equal(tally(reeks([100, 100]), 0).tone, null); }); it('één beweging is al een richting', () => { assert.equal(tally(reeks([100, 101]), 0).tone, 'up'); assert.equal(tally(reeks([100, 99]), 0).tone, 'down'); }); it('de meerderheid wint, ook als de laatste beweging de andere kant op gaat', () => { assert.equal(tally(reeks([100, 101, 102, 50]), 0).tone, 'up'); }); it('gelijke stand houdt wat er stond: eerst omhoog dan omlaag blijft groen', () => { const t = tally(reeks([100, 101, 100]), 0); assert.equal(t.up, t.down); assert.equal(t.tone, 'up'); }); it('en andersom blijft rood', () => { assert.equal(tally(reeks([100, 99, 100]), 0).tone, 'down'); }); it('gelijke stand na een omslag houdt de laatste richting, niet de eerste', () => { assert.equal(tally(reeks([100, 101, 102, 101, 100, 99, 100]), 0).tone, 'down'); }); }); describe('restore: een opgeslagen buffer terug in het geheugen', () => { it('laat verlopen bewegingen weg en houdt de rest', () => { const nu = MOMENTUM.MAX_AGE_MS + 10 * MIN; const b = restore({ last: 100, lastAt: nu - MIN, moves: [{ at: 0, dir: 1 }, { at: nu - 2 * MIN, dir: -1 }] }, nu); assert.deepEqual(b.moves, [{ at: nu - 2 * MIN, dir: -1 }]); assert.equal(b.lastAt, nu - MIN, 'de leeftijd van de referentie gaat mee'); }); it('weigert wat geen buffer is', () => { for (const fout of [null, 'x', {}, { last: 100, lastAt: 0 }, { last: 'a', lastAt: 0, moves: [] }]) { assert.equal(restore(fout, 0), null, JSON.stringify(fout)); } }); it('laat een kapotte beweging weg in plaats van de hele buffer', () => { const b = restore({ last: 100, lastAt: 0, moves: [{ at: 0, dir: 1 }, { at: 0, dir: 7 }, null] }, 0); assert.deepEqual(b.moves, [{ at: 0, dir: 1 }]); }); }); describe('de opslag per asset', () => { beforeEach(() => { clearMomentum(); OPGESLAGEN.clear(); SCHRIJVEN = 0; }); it('houdt twee assets apart', async () => { await recordSpot(1, 100, 0); await recordSpot(1, 101, MIN); await recordSpot(2, 100, 0); await recordSpot(2, 99, MIN); assert.deepEqual([momentumOf(1, MIN).up, momentumOf(1, MIN).down], [1, 0]); assert.deepEqual([momentumOf(2, MIN).up, momentumOf(2, MIN).down], [0, 1]); }); it('een asset zonder bewegingen heeft geen richting', () => { assert.deepEqual(momentumOf(9), { up: 0, down: 0, tone: null }); }); it('schrijft de buffer weg, en niet bij een ongewijzigde prijs', async () => { await recordSpot(1, 100, 0); await recordSpot(1, 101, MIN); assert.equal(SCHRIJVEN, 2); await recordSpot(1, 101, 2 * MIN); assert.equal(SCHRIJVEN, 2, 'dezelfde prijs is geen schrijfactie'); assert.equal(OPGESLAGEN.get('momentum|1').moves.length, 1); }); it('een nieuwe sessie gaat verder met de opgeslagen buffer', async () => { await recordSpot(1, 100, 0); await recordSpot(1, 101, MIN); clearMomentum(); assert.equal(momentumOf(1, MIN).up, 0, 'nog niet geladen'); await loadMomentum(1, 2 * MIN); assert.equal(momentumOf(1, 2 * MIN).up, 1, 'geladen'); await recordSpot(1, 102, 2 * MIN); assert.equal(momentumOf(1, 2 * MIN).up, 2, 'en een nieuwe prijs telt erbij in plaats van eroverheen'); }); it('een buffer van gisteren telt niet mee, en zijn referentie ook niet', async () => { const gisteren = 0; const vandaag = MOMENTUM.MAX_AGE_MS + 60 * MIN; const prijzen = Array.from({ length: 9 }, (_, i) => 100 + i); for (let i = 0; i < prijzen.length; i++) await recordSpot(1, prijzen[i], gisteren + i * MIN); clearMomentum(); await loadMomentum(1, vandaag); assert.deepEqual(momentumOf(1, vandaag), { up: 0, down: 0, tone: null }); await recordSpot(1, 50, vandaag); assert.equal(momentumOf(1, vandaag).down, 0, 'de val sinds gisteravond is geen beweging'); }); it('een onleesbare opgeslagen waarde begint gewoon leeg', async () => { OPGESLAGEN.set('momentum|3', 'geen buffer'); await recordSpot(3, 100, 0); await recordSpot(3, 101, MIN); assert.equal(momentumOf(3, MIN).up, 1); }); });