// Generated, do not edit. sha256:615ef8a5d598742e85ea7f2f5b84abfb3e5a2087d59fe201265eaa5faea109f0 import { describe, it, mock } from 'node:test'; import assert from 'node:assert/strict'; import { vasteRekenvaluta } from '../helpers/rekenvaluta.mjs'; await vasteRekenvaluta(mock, 'EUR'); const { fmtUnit, fmtAmount, fmtPct, pctTone, fmtBaseSigned, colouredSigns, fmtPrice, fmtMoney, currencyName, isBaseAsset, subline, toBaseByFactor } = await import('../../client/ui/format.js'); const { setAppSetting } = await import('../../client/app-settings.js'); import { CONFIG } from '../../shared/config.js'; const EUR = { symbol: 'EUR', kind: 'fiat', decimals: 2, unit: 'EUR', subunit: 'cent', displayUnit: 'unit' }; const BTC = { kind: 'crypto', decimals: 8, unit: 'BTC', subunit: 'sat', displayUnit: 'unit' }; const GOUD = { kind: 'metal', unit: 'ozt', subunit: 'g', displayUnit: 'unit' }; describe('fmtUnit bij geld', () => { it('houdt de decimalen van het asset vast, ook als het nullen zijn', () => { assert.equal(fmtUnit(130_000, EUR), '1.300,00 EUR'); assert.equal(fmtUnit(100_530, EUR), '1.005,30 EUR'); assert.equal(fmtUnit(0, EUR), '0,00 EUR'); }); it('laat een negatief bedrag heel (een boeking mag omlaag)', () => { assert.equal(fmtUnit(-2_882_490, EUR), '-28.824,90 EUR'); }); it('volgt het asset en niet de aanname dat geld twee decimalen heeft', () => { const zonderCenten = { kind: 'fiat', decimals: 0, unit: 'JPY', subunit: null, displayUnit: 'unit' }; assert.equal(fmtUnit(1_300, zonderCenten), '1.300 JPY'); }); it('telt in de ondereenheid gewoon hele centen', () => { assert.equal(fmtUnit(100_530, { ...EUR, displayUnit: 'subunit' }), '100.530 cent'); }); }); describe('fmtUnit bij crypto en metaal blijft ongewijzigd', () => { it('laat overtollige nullen bij crypto juist wél weg', () => { assert.equal(fmtUnit(50_000_000, BTC), '0,5 BTC'); assert.equal(fmtUnit(100_000_000, BTC), '1 BTC'); assert.equal(fmtUnit(1, BTC), '0,00000001 BTC'); }); it('laat het metaal-pad ongemoeid (dat rekent met factoren, niet met 10^decimals)', () => { assert.equal(fmtUnit(toBaseByFactor(1, 'ozt'), GOUD), '1 ozt'); assert.equal(fmtUnit(toBaseByFactor(2.5, 'ozt'), GOUD), '2,5 ozt'); }); }); describe('fmtAmount volgt dezelfde regel', () => { it('geeft bij geld een hoofdbedrag met vaste decimalen en de centen ernaast', () => { assert.deepEqual(fmtAmount(130_000, EUR), { primary: '1.300,00 EUR', secondary: '130.000 cent' }); }); it('en bij crypto niet', () => { assert.deepEqual(fmtAmount(50_000_000, BTC), { primary: '0,5 BTC', secondary: '50.000.000 sat' }); }); }); describe('isBaseAsset: is dit de eenheid waarin de app rekent', () => { it('herkent het reken-asset op zijn symbool', () => { assert.equal(isBaseAsset(EUR), true); assert.equal(isBaseAsset(BTC), false); }); it('kijkt NIET naar de asset-soort', () => { const USD = { symbol: 'USD', kind: 'fiat', decimals: 2, unit: 'USD', subunit: 'cent', displayUnit: 'unit' }; assert.equal(isBaseAsset(USD), false); }); it('is onwaar zonder asset', () => { assert.equal(isBaseAsset(undefined), false); assert.equal(isBaseAsset(null), false); }); }); describe('subline: de tweede regel onder een waarde', () => { it('rendert niets als er niets te tonen is', () => { assert.equal(subline(''), ''); assert.equal(subline(null), ''); assert.equal(subline(undefined), ''); }); it('rendert de regel wél als er inhoud is', () => { assert.equal(subline('€ 1,00'), '
€ 1,00
'); }); }); describe('fmtPrice: de decimalen volgen de grootte', () => { it('houdt een grote prijs op twee decimalen', () => { assert.equal(fmtPrice(74884.62115428, 'eur'), '€ 74.884,62'); }); it('houdt twee decimalen vast als er niets achter de komma staat', () => { assert.equal(fmtPrice(40000, 'eur'), '€ 40.000,00'); }); it('geeft een kleine prijs zijn cijfers', () => { assert.equal(fmtPrice(0.00012345, 'eur'), '€ 0,00012345'); assert.equal(fmtPrice(1.23456789, 'eur'), '€ 1,2346'); }); it('weigert een onbekende munt in plaats van iets te verzinnen', () => { assert.throws(() => fmtPrice(1, 'xyz'), /Unknown currency/); }); }); describe('fmtMoney: symbool en decimalen per munt', () => { it('laat euro en dollar ongewijzigd', () => { assert.equal(fmtMoney(1234.5, 'eur'), '€ 1.234,50'); assert.equal(fmtMoney(1234.5, 'USD'), '$ 1.234,50'); assert.equal(fmtMoney(0.001, 'eur'), '€ 0,001', 'onder een halve cent komen er cijfers bij'); }); it('volgt de decimalen van de munt: een yen heeft er geen', () => { assert.equal(fmtMoney(1234.5, 'JPY'), '¥ 1.235'); assert.equal(fmtPrice(1234.5, 'JPY'), '¥ 1.234,5'); }); it('kent elke munt uit de lijst, en weigert een code daarbuiten', () => { for (const code of CONFIG.PORTFOLIO.BASE_CURRENCIES) assert.doesNotThrow(() => fmtMoney(1, code), code); assert.throws(() => fmtMoney(1, 'XYZ'), /Unknown currency/); }); }); describe('currencyName', () => { it('geeft elke munt uit de lijst een Nederlandse naam met hoofdletter', () => { assert.equal(currencyName('eur'), 'Euro'); for (const code of CONFIG.PORTFOLIO.BASE_CURRENCIES) { const naam = currencyName(code); assert.match(naam, /^[A-Z]/, `${code}: '${naam}'`); assert.notEqual(naam, code, `${code} heeft geen naam van Intl gekregen`); } }); it('weigert een code buiten de lijst, net als fmtMoney', () => { assert.throws(() => currencyName('XYZ'), /Unknown currency/); }); }); describe('fmtPct', () => { it('schrijft Nederlands: een komma en één decimaal', () => { assert.equal(fmtPct(0.306), '+30,6%'); assert.equal(fmtPct(0.1), '+10,0%'); }); it('gebruikt het echte minteken en niet een koppelteken', () => { assert.equal(fmtPct(-0.008), '−0,8%'); assert.ok(!fmtPct(-0.008).includes('-'), 'een koppelteken hoort er niet in te staan'); }); it('geeft een waarde die op nul afrondt GEEN teken, ook als hij echt negatief is', () => { assert.equal(fmtPct(0), '0,0%'); assert.equal(fmtPct(-0.000167), '0,0%'); assert.equal(fmtPct(0.0004), '0,0%'); }); it('fine: twee decimalen alleen als één decimaal de beweging verbergt', () => { assert.equal(fmtPct(0.0004, { fine: true }), '+0,04%'); assert.equal(fmtPct(-0.000167, { fine: true }), '−0,02%'); assert.equal(fmtPct(0.014, { fine: true }), '+1,4%', 'een gewone dagbeweging houdt één decimaal'); assert.equal(fmtPct(0.0006, { fine: true }), '+0,1%', 'wat op één decimaal te zien is, blijft zo'); assert.equal(fmtPct(0.00004, { fine: true }), '0,0%', 'ook op twee decimalen nul: dan blijft het 0,0%'); }); it('pctTone: rood bij −0,1%, geen kleur bij wat als 0,0% staat', () => { assert.equal(pctTone(-0.001), 't-neg'); assert.equal(pctTone(0.001), 't-pos'); assert.equal(pctTone(-0.0004), '', 'staat als 0,0%'); assert.equal(pctTone(-0.0004, { fine: true }), 't-neg', 'met twee decimalen staat er −0,04%'); }); it('signs: geen, alleen negatief of allebei; de kleur blijft in elke stand', () => { assert.equal(fmtPct(0.306), '+30,6%', 'zonder kleur beide tekens'); assert.equal(fmtPct(0.306, { signs: 'negative' }), '30,6%'); assert.equal(fmtPct(-0.008, { signs: 'negative' }), '−0,8%'); assert.equal(fmtPct(-0.008, { signs: 'none' }), '0,8%'); assert.equal(fmtPct(0.306, { signs: 'both' }), '+30,6%'); assert.equal(fmtPct(0.0004, { fine: true, signs: 'negative' }), '0,04%'); assert.equal(pctTone(-0.001, { signs: 'none' }), 't-neg'); assert.equal(pctTone(0.001, { signs: 'none' }), 't-pos'); }); it('fmtBaseSigned: euroteken, spatie, teken, bedrag; onder een cent geen teken', () => { assert.equal(fmtBaseSigned(-4.77, 'negative'), '€ −4,77'); assert.equal(fmtBaseSigned(31.51, 'negative'), '€ 31,51'); assert.equal(fmtBaseSigned(31.51, 'both'), '€ +31,51'); assert.equal(fmtBaseSigned(-4.77, 'none'), '€ 4,77'); assert.equal(fmtBaseSigned(-1234.5, 'both'), '€ −1.234,50'); assert.equal(fmtBaseSigned(-0.004, 'both'), '€ 0,00'); }); it('colouredSigns leest de instelling', async () => { await setAppSetting('result_signs', 'none'); assert.equal(colouredSigns(), 'none'); await setAppSetting('result_signs', 'both'); assert.equal(colouredSigns(), 'both'); }); it('houdt het teken zodra er wél iets te zien is', () => { assert.equal(fmtPct(0.0006), '+0,1%'); assert.equal(fmtPct(-0.0006), '−0,1%'); }); it('rondt af op één decimaal en niet meer', () => { assert.equal(fmtPct(0.12345), '+12,3%'); assert.equal(fmtPct(0.12678), '+12,7%'); }); it('geeft een lege tekst als er geen getal is, want dat is iets anders dan nul', () => { assert.equal(fmtPct(null), ''); assert.equal(fmtPct(undefined), ''); assert.equal(fmtPct(NaN), ''); assert.equal(fmtPct(Infinity), ''); }); it('valt niet over een groot percentage met een duizendtalscheiding', () => { assert.equal(fmtPct(10), '+1.000,0%'); assert.equal(fmtPct(20000), '+2.000.000,0%'); }); }); const { parseLocaleNumber } = await import('../../client/ui/format.js'); const { setLocale } = await import('../../client/i18n/index.js'); describe('opmaak en invoer volgen de taal', () => { const inTaal = (code, fn) => { setLocale(code); try { fn(); } finally { setLocale('nl'); } }; it('leest de eigen opmaak terug, in het Nederlands en in het Engels', () => { assert.equal(parseLocaleNumber('1.000,50'), 1000.5); assert.equal(parseLocaleNumber('100.000.000'), 1e8); inTaal('en', () => { assert.equal(parseLocaleNumber('1,000.50'), 1000.5); assert.equal(parseLocaleNumber('100,000,000'), 1e8); }); }); it('neemt één scheidingsteken zonder drie cijfers erachter als decimaalteken, in elke taal', () => { assert.equal(parseLocaleNumber('3.5'), 3.5); assert.equal(parseLocaleNumber('0.500'), 0.5, 'na een kale nul is het geen duizendtal'); assert.equal(parseLocaleNumber('3,5'), 3.5); inTaal('en', () => { assert.equal(parseLocaleNumber('3,5'), 3.5); assert.equal(parseLocaleNumber('1,000'), 1000); }); }); it('geeft NaN zonder cijfers, zodat de aanroeper zelf kiest', () => { assert.ok(Number.isNaN(parseLocaleNumber(''))); assert.ok(Number.isNaN(parseLocaleNumber('€ -'))); assert.equal(parseLocaleNumber('-1.234,5'), -1234.5); }); it('formatteert in de actieve taal, ook na een wissel terug', () => { inTaal('en', () => { assert.equal(fmtMoney(1234.5, 'EUR'), '€ 1,234.50'); assert.equal(fmtPct(10), '+1,000.0%'); assert.equal(currencyName('USD'), 'US Dollar'); }); assert.equal(fmtMoney(1234.5, 'EUR'), '€ 1.234,50'); assert.equal(currencyName('USD'), 'Amerikaanse dollar'); }); });