diff --git a/src/lib/financeUi.js b/src/lib/financeUi.js new file mode 100644 index 0000000..7cad0b0 --- /dev/null +++ b/src/lib/financeUi.js @@ -0,0 +1,17 @@ +// Kleine Darstellungs-Helfer fuer die Finanzen-Seiten (kein React, keine Abhaengigkeit, unter Node testbar). + +const MINUS = '−' // U+2212, das Minus aus financeFormat.js + +/** Wahr, wenn der angezeigte Text mit dem Minuszeichen (U+2212) beginnt. Nur dann wird ein Betrag rot (`fin-neg`). */ +export function isNegText(text) { + return typeof text === 'string' && text.startsWith(MINUS) +} + +/** Ton ('ok' | 'warn' | sonst) -> Klasse und Rolle einer Meldung; `extra` wird mit Leerzeichen an die Klasse gehaengt. */ +export function noticeProps(tone, extra = '') { + const base = tone === 'ok' ? 'msg ok' : tone === 'warn' ? 'msg warn' : 'msg muted' + return { + className: extra ? `${base} ${extra}` : base, + role: tone === 'warn' ? 'alert' : 'status', + } +} diff --git a/tests/unit/financeUi.test.mjs b/tests/unit/financeUi.test.mjs new file mode 100644 index 0000000..8c82929 --- /dev/null +++ b/tests/unit/financeUi.test.mjs @@ -0,0 +1,24 @@ +import test from 'node:test' +import assert from 'node:assert/strict' +import { loadModule } from './load.mjs' + +const { isNegText, noticeProps } = await loadModule('src/lib/financeUi.js') +const { euro, euroWhole, signedEuro } = await loadModule('src/lib/financeFormat.js') + +test('isNegText: nur das angezeigte Minus zählt', () => { + assert.equal(isNegText(euro(-449)), true) + assert.equal(isNegText(signedEuro(-449)), true) + assert.equal(isNegText(euroWhole(-123456)), true) + assert.equal(isNegText(euroWhole(-40)), false) // „0 €“: Rundung auf 0 trägt kein Vorzeichen + assert.equal(isNegText(signedEuro(16879)), false) + assert.equal(isNegText(euro(null)), false) // „–“ (U+2013) + for (const v of ['-4,49 €', '', undefined, null, 5]) assert.equal(isNegText(v), false) +}) + +test('noticeProps: Klasse und Rolle je Ton', () => { + assert.deepEqual(noticeProps('ok'), { className: 'msg ok', role: 'status' }) + assert.deepEqual(noticeProps('warn'), { className: 'msg warn', role: 'alert' }) + assert.deepEqual(noticeProps('info'), { className: 'msg muted', role: 'status' }) + assert.deepEqual(noticeProps(undefined), { className: 'msg muted', role: 'status' }) + assert.deepEqual(noticeProps('warn', 'fin-notice'), { className: 'msg warn fin-notice', role: 'alert' }) +})