/** * Tests for energy/format.ts — formatMetricValue helper. * * Coverage: * 1. energy device_class → 3 decimal places. * 2. non-energy device_class → 2 decimal places. * 3. null value → "—" placeholder. * 4. undefined value → "—" placeholder. * 5. NaN value → "—" placeholder. * 6. Missing / null metric metadata → default 2 decimal places. * 7. Integer value still rendered with correct decimal places. * 8. String numeric value is coerced and formatted. */ import { describe, it, expect } from 'vitest' import { formatMetricValue, VALUE_PLACEHOLDER } from './format' import type { MetricInfo } from './hooks' // --------------------------------------------------------------------------- // Fixtures // --------------------------------------------------------------------------- function makeMetric(overrides: Partial = {}): MetricInfo { return { key: 'voltage', label: 'Voltage', unit: 'V', device_class: 'voltage', ...overrides, } } const energyMetric = makeMetric({ key: 'import_energy', label: 'Import Energy', unit: 'kWh', device_class: 'energy' }) const voltageMetric = makeMetric() const powerMetric = makeMetric({ key: 'active_power', label: 'Active Power', unit: 'W', device_class: 'power' }) const powerFactorMetric = makeMetric({ key: 'power_factor', label: 'Power Factor', unit: '', device_class: 'power_factor' }) // --------------------------------------------------------------------------- // Tests // --------------------------------------------------------------------------- describe('formatMetricValue — energy device_class → 3 decimal places', () => { it('formats kWh energy value to 3 decimal places', () => { expect(formatMetricValue(123.4567, energyMetric)).toBe('123.457') }) it('formats a whole-number energy value to 3 decimal places', () => { expect(formatMetricValue(123, energyMetric)).toBe('123.000') }) it('formats zero energy value to 3 decimal places', () => { expect(formatMetricValue(0, energyMetric)).toBe('0.000') }) }) describe('formatMetricValue — non-energy device_class → 2 decimal places', () => { it('formats voltage to 2 decimal places', () => { expect(formatMetricValue(230.2567, voltageMetric)).toBe('230.26') }) it('formats power to 2 decimal places', () => { expect(formatMetricValue(295.0, powerMetric)).toBe('295.00') }) it('formats power factor to 2 decimal places', () => { expect(formatMetricValue(0.98, powerFactorMetric)).toBe('0.98') }) it('formats current to 2 decimal places', () => { const currentMetric = makeMetric({ key: 'current', label: 'Current', unit: 'A', device_class: 'current' }) expect(formatMetricValue(1.3456, currentMetric)).toBe('1.35') }) }) describe('formatMetricValue — null/undefined/NaN → placeholder', () => { it('returns placeholder for null', () => { expect(formatMetricValue(null, voltageMetric)).toBe(VALUE_PLACEHOLDER) }) it('returns placeholder for undefined', () => { expect(formatMetricValue(undefined, voltageMetric)).toBe(VALUE_PLACEHOLDER) }) it('returns placeholder for NaN', () => { expect(formatMetricValue(NaN, voltageMetric)).toBe(VALUE_PLACEHOLDER) }) it('returns placeholder for non-numeric string', () => { expect(formatMetricValue('not-a-number', voltageMetric)).toBe(VALUE_PLACEHOLDER) }) it('returns placeholder for Infinity', () => { expect(formatMetricValue(Infinity, voltageMetric)).toBe(VALUE_PLACEHOLDER) }) }) describe('formatMetricValue — missing metric metadata → default 2 decimal places', () => { it('falls back to 2 decimal places when metric is undefined', () => { expect(formatMetricValue(230.2567)).toBe('230.26') }) it('falls back to 2 decimal places when metric is null', () => { expect(formatMetricValue(230.2567, null)).toBe('230.26') }) it('returns placeholder for null value even without metric', () => { expect(formatMetricValue(null)).toBe(VALUE_PLACEHOLDER) }) }) describe('formatMetricValue — numeric string coercion', () => { it('coerces a numeric string to number and formats it', () => { // API could theoretically return strings; we handle them gracefully. expect(formatMetricValue('230.2567', voltageMetric)).toBe('230.26') }) it('coerces a numeric string for energy metric → 3 decimals', () => { expect(formatMetricValue('123.4567', energyMetric)).toBe('123.457') }) })