diff --git a/src/lib/serverpulsFormat.js b/src/lib/serverpulsFormat.js index 082a296..984f92c 100644 --- a/src/lib/serverpulsFormat.js +++ b/src/lib/serverpulsFormat.js @@ -57,6 +57,23 @@ export function formatNumber(v, digits = 2) { return nf(digits).format(v) } +// Richtung eines Kachel-Deltas: unter 1e-9 gilt als unverändert (flat). +export function deltaDir(d) { + return Math.abs(d) < 1e-9 ? 'flat' : d > 0 ? 'up' : 'down' +} + +// Vorzeichen zur Richtung: '+', Minuszeichen U+2212, bei flat nichts. +export function deltaSign(dir) { + return dir === 'up' ? '+' : dir === 'down' ? '−' : '' +} + +// Badge-Ton je Warnstufe; liest nur das erste Argument (.map(levelTone) reicht Index und Array mit). +const LEVEL_TONES = { ok: 'ok', medium: 'warn', critical: 'danger' } + +export function levelTone(level) { + return Object.prototype.hasOwnProperty.call(LEVEL_TONES, level) ? LEVEL_TONES[level] : 'muted' +} + // --- Zeitachsen (Europe/Berlin, de-DE) --- const TZ = 'Europe/Berlin' const dtf = (opts) => new Intl.DateTimeFormat('de-DE', { timeZone: TZ, ...opts }) diff --git a/tests/unit/serverpulsFormat.test.mjs b/tests/unit/serverpulsFormat.test.mjs index 8baae31..0379f44 100644 --- a/tests/unit/serverpulsFormat.test.mjs +++ b/tests/unit/serverpulsFormat.test.mjs @@ -2,7 +2,7 @@ import test from 'node:test' import assert from 'node:assert/strict' import { loadModule } from './load.mjs' -const { formatBytes, formatDelta, ageLabel, usedPct, axisTimeKind, formatAxisTick, formatLegendTime } = await loadModule('src/lib/serverpulsFormat.js') +const { formatBytes, formatDelta, deltaDir, deltaSign, levelTone, ageLabel, usedPct, axisTimeKind, formatAxisTick, formatLegendTime } = await loadModule('src/lib/serverpulsFormat.js') test('formatBytes: de-DE, Basis 1024', () => { assert.equal(formatBytes(1288490189), '1,2 GB') @@ -20,6 +20,19 @@ test('formatDelta', () => { assert.equal(formatDelta(0).dir, 'flat') }) +test('deltaDir und deltaSign: Richtung und Vorzeichen der Kachel-Deltas', () => { + assert.deepEqual([deltaDir(0), deltaDir(5e-10), deltaDir(-5e-10)], ['flat', 'flat', 'flat']) + assert.equal(deltaDir(0.4), 'up') + assert.equal(deltaDir(-0.4), 'down') + assert.deepEqual([deltaSign('up'), deltaSign('down'), deltaSign('flat')], ['+', '−', '']) +}) + +test('levelTone: Badge-Ton je Stufe', () => { + assert.deepEqual(['ok', 'medium', 'critical'].map(levelTone), ['ok', 'warn', 'danger']) + assert.deepEqual([levelTone('low'), levelTone(undefined), levelTone('x')], ['muted', 'muted', 'muted']) + assert.deepEqual([levelTone('constructor'), levelTone('toString'), levelTone('__proto__')], ['muted', 'muted', 'muted']) +}) + test('ageLabel: stale ab > 15 Min.', () => { const now = 1_000_000_000_000 const a16 = ageLabel(now - 16 * 60000, now)