// Generated, do not edit. sha256:1f71cb9dde91962b1038854fb255fb8b67bd26c20dadc041dd312c033c2e7226 import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; import { isMetal, hasSubunit, toSubunit, fromSubunit, unitToSubunit, mainToSub, subToMain, toBaseByFactor, fromBaseByFactor, metalFactor, priceToBase, priceFromBase, unitPriceToBase, totalFromPrice, priceFromTotal, amountFromTotal, } from '../../shared/units.js'; import { CONFIG } from '../../shared/config.js'; const BTC = { kind: 'crypto', decimals: 8, unit: 'BTC', subunit: 'sat', displayUnit: 'unit' }; const SATS = { ...BTC, displayUnit: 'subunit' }; const EUR = { kind: 'fiat', decimals: 2, unit: 'EUR', subunit: 'cent', displayUnit: 'unit' }; const GOUD = { kind: 'metal', decimals: 7, unit: 'ozt', subunit: 'g', displayUnit: 'unit' }; describe('unitToSubunit: altijd de hoofdeenheid van het asset', () => { it('rekent een crypto-hoeveelheid om met 10^decimals', () => { assert.equal(unitToSubunit(0.25, BTC), 25_000_000); assert.equal(unitToSubunit(1, BTC), 100_000_000); }); it('NEGEERT displayUnit, en dat is het hele bestaansrecht van deze functie', () => { assert.equal(toSubunit(0.25, SATS), 0); assert.equal(unitToSubunit(0.25, SATS), 25_000_000); }); it('rekent geld in centen', () => { assert.equal(unitToSubunit(1300, EUR), 130_000); assert.equal(unitToSubunit(1005.3, EUR), 100_530); }); it('houdt bij metaal het gram-pad aan, met de UNIT en niet de weergave-eenheid', () => { const factor = CONFIG.METALS.UNITS.ozt; assert.equal(unitToSubunit(1, GOUD), Math.round(factor * Math.pow(10, CONFIG.METALS.BASE_DECIMALS))); assert.equal(unitToSubunit(1, { ...GOUD, displayUnit: 'subunit' }), unitToSubunit(1, GOUD)); }); it('weigert een hoeveelheid die geen getal is in plaats van NaN op te slaan', () => { assert.throws(() => unitToSubunit('geen getal', BTC), (e) => e.key === 'common.invalidAmount'); assert.throws(() => unitToSubunit(undefined, BTC), (e) => e.key === 'common.invalidAmount'); }); }); describe('unitPriceToBase: de koers per hoofdeenheid naar de opslagbasis', () => { it('laat een crypto-koers ongemoeid, want die staat per hoofdeenheid', () => { assert.equal(unitPriceToBase(38000, BTC), 38000); assert.equal(unitPriceToBase(1.5, EUR), 1.5); }); it('rekent een metaalkoers van per ozt naar per gram', () => { const factor = CONFIG.METALS.UNITS.ozt; assert.equal(unitPriceToBase(2150, GOUD), 2150 / factor); assert.ok(Math.abs(priceFromBase(unitPriceToBase(2150, GOUD), GOUD) - 2150) < 1e-9); }); it('NEGEERT displayUnit, en dat is het hele bestaansrecht van deze functie', () => { const GRAMMEN = { ...GOUD, displayUnit: 'subunit' }; assert.equal(priceToBase(2150, GRAMMEN), 2150); assert.equal(unitPriceToBase(2150, GRAMMEN), unitPriceToBase(2150, GOUD)); }); it('weigert een koers die geen getal is', () => { assert.throws(() => unitPriceToBase('geen getal', GOUD), /Invalid price/); assert.throws(() => unitPriceToBase(undefined, BTC), /Invalid price/); }); }); describe('toSubunit en fromSubunit blijven elkaars omgekeerde', () => { it('doet dat voor crypto in de hoofdeenheid', () => { assert.equal(fromSubunit(toSubunit(0.5, BTC), BTC), 0.5); }); it('doet dat voor een asset dat in zijn ondereenheid getoond wordt', () => { assert.equal(fromSubunit(toSubunit(42, SATS), SATS), 42); }); it('doet dat voor metaal', () => { assert.equal(fromSubunit(toSubunit(2.5, GOUD), GOUD), 2.5); }); }); describe('de losse rekenstappen', () => { it('rondt hoofd naar sub af op hele eenheden', () => { assert.equal(mainToSub(0.000000005, 8), 1); assert.equal(mainToSub(0.000000004, 8), 0); }); it('poetst de float-ruis weg bij de terugweg', () => { assert.equal(subToMain(mainToSub(0.1, 8) + mainToSub(0.2, 8), 8), 0.3); }); it('rekent gram-basis heen en terug', () => { assert.equal(fromBaseByFactor(toBaseByFactor(3, 'g'), 'g'), 3); }); it('gooit op een eenheid die de config niet kent', () => { assert.throws(() => metalFactor('lood'), /Unknown metal unit/); }); }); describe('de twee vlaggen waarop de rekenpaden kiezen', () => { it('herkent metaal aan de soort en niet aan de eenheid', () => { assert.equal(isMetal(GOUD), true); assert.equal(isMetal(BTC), false); assert.equal(isMetal(null), false); }); it('ziet een lege subunit als geen subunit', () => { assert.equal(hasSubunit(BTC), true); assert.equal(hasSubunit({ ...BTC, subunit: null }), false); assert.equal(hasSubunit({ ...BTC, subunit: ' ' }), false); }); }); describe('totalFromPrice en priceFromTotal', () => { it('rekent een bitcoin-aankoop heen en terug', () => { assert.equal(priceFromTotal(500, 25_000_000, 8), 2000); assert.equal(totalFromPrice(25_000_000, 8, 2000), 500); }); it('rekent een metaalaankoop in de opslagbasis en niet in de getoonde eenheid', () => { const eenOzt = toSubunit(1, GOUD); const perGram = priceFromTotal(3804, eenOzt, GOUD.decimals); assert.ok(Math.abs(perGram - 3804 / metalFactor('ozt')) < 1e-9, `kreeg ${perGram}`); assert.ok(Math.abs(priceFromBase(perGram, GOUD) - 3804) < 1e-6); assert.ok(Math.abs(totalFromPrice(eenOzt, GOUD.decimals, perGram) - 3804) < 1e-6); }); it('geeft NUL terug als er niets betaald is, want dat is een geldig antwoord', () => { assert.equal(priceFromTotal(0, 25_000_000, 8), 0); assert.equal(totalFromPrice(25_000_000, 8, 0), 0); }); it('geeft null bij een hoeveelheid van nul in plaats van een deling door nul', () => { assert.equal(priceFromTotal(500, 0, 8), null); assert.equal(priceFromTotal(500, null, 8), null); }); it('geeft null bij onbruikbare invoer, en niet 0', () => { assert.equal(priceFromTotal('', 25_000_000, 8), null); assert.equal(priceFromTotal(undefined, 25_000_000, 8), null); assert.equal(totalFromPrice(25_000_000, 8, ''), null); assert.equal(totalFromPrice(NaN, 8, 100), null); }); it('telt de fee bij een AANKOOP op bij het bedrag', () => { assert.equal(totalFromPrice(25_000_000, 8, 2000, 12, 'buy'), 512); assert.equal(priceFromTotal(512, 25_000_000, 8, 12, 'buy'), 2000); }); it('haalt de fee bij een VERKOOP van het bedrag af', () => { assert.equal(totalFromPrice(25_000_000, 8, 2000, 12, 'sell'), 488); assert.equal(priceFromTotal(488, 25_000_000, 8, 12, 'sell'), 2000); }); it('laat een ontbrekende fee alles bij het oude', () => { assert.equal(totalFromPrice(25_000_000, 8, 2000, '', 'buy'), 500); assert.equal(totalFromPrice(25_000_000, 8, 2000, null, 'sell'), 500); assert.equal(priceFromTotal(500, 25_000_000, 8, '', 'buy'), 2000); }); it('geeft null als de fee groter is dan het bedrag, in plaats van een negatieve prijs', () => { assert.equal(priceFromTotal(10, 25_000_000, 8, 12, 'buy'), null); }); }); describe('amountFromTotal', () => { it('geeft de hoeveelheid in de opslagbasis', () => { assert.equal(amountFromTotal(1000, 20000, 8), 0.05 * 1e8); }); it('haalt de kosten van een AANKOOP eraf voor het delen', () => { assert.equal(amountFromTotal(1010, 20000, 8, 10, 'buy'), 0.05 * 1e8); }); it('telt de kosten van een VERKOOP erbij', () => { assert.equal(amountFromTotal(990, 20000, 8, 10, 'sell'), 0.05 * 1e8); }); it('rekent bij metaal in de opslagbasis, dus per gram', () => { assert.equal(amountFromTotal(1000, 50, 7), 20 * 1e7); }); it('geeft null bij een prijs van nul of lager', () => { assert.equal(amountFromTotal(1000, 0, 8), null); assert.equal(amountFromTotal(1000, -5, 8), null); }); it('geeft null als de kosten groter zijn dan het bedrag', () => { assert.equal(amountFromTotal(5, 20000, 8, 10, 'buy'), null); }); it('geeft null bij onleesbare invoer in plaats van NaN', () => { assert.equal(amountFromTotal('', 20000, 8), null); assert.equal(amountFromTotal(1000, '', 8), null); assert.equal(amountFromTotal('veel', 20000, 8), null); }); it('is de omgekeerde van totalFromPrice, kosten en al', () => { const basis = 0.25 * 1e8, prijs = 32000, fee = 12; const totaal = totalFromPrice(basis, 8, prijs, fee, 'buy'); assert.equal(amountFromTotal(totaal, prijs, 8, fee, 'buy'), basis); assert.equal(priceFromTotal(totaal, basis, 8, fee, 'buy'), prijs); }); });