Files
AtreidesAssetsFree/tests/ui/format.test.mjs
T
2026-10-29 11:57:29 +01:00

265 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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('<span class="val">€ 1,00</span>'),
'<div class="t-muted-cell t-subline"><span class="val">€ 1,00</span></div>');
});
});
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');
});
});