/** * earth-now.co * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * File: packages/counter/test/format.test.ts * Purpose: Formatting tests — sigFigs honesty cap, locales, rates, fallback on non-finite values */ import { describe, expect, it } from "vitest"; import { formatCompact, formatRate, formatUncertainty, formatValue, roundToSigFigs, } from "../src/index"; describe("roundToSigFigs", () => { it("caps significant digits", () => { expect(roundToSigFigs(8_231_456_789, 7)).toBe(8_231_457_000); expect(roundToSigFigs(426.912345, 5)).toBeCloseTo(426.91, 9); expect(roundToSigFigs(0.0012349, 3)).toBeCloseTo(0.00123, 12); expect(roundToSigFigs(-1234, 2)).toBe(-1200); expect(roundToSigFigs(0, 3)).toBe(0); }); }); describe("formatValue", () => { it("applies sigFigs then decimals", () => { const s = formatValue(8_231_456_789, { decimals: 0, sigFigs: 7, unit: "people" }); expect(s).toBe("8,231,457,000"); }); it("keeps full precision when applySigFigs=false (animated ticker)", () => { const s = formatValue(8_231_456_789, { decimals: 0, sigFigs: 7, unit: "people" }, { applySigFigs: false, }); expect(s).toBe("8,231,456,789"); }); it("honors locale", () => { const s = formatValue(1234.5, { decimals: 1, unit: "t" }, { locale: "fr" }); // fr uses narrow no-break space grouping and comma decimal. expect(s).toMatch(/1[\s  ]234,5/); }); it("falls back on non-finite values (never NaN on screen)", () => { expect(formatValue(Number.NaN, { decimals: 0, unit: "x" })).toBe("—"); expect(formatValue(Infinity, { decimals: 0, unit: "x" })).toBe("—"); }); }); describe("formatRate", () => { it("chooses a human cadence", () => { expect(formatRate(4.2, { decimals: 0, unit: "people" })).toBe("4.2/s"); expect(formatRate(0.5, { decimals: 0, unit: "people" })).toBe("30/min"); expect(formatRate(0.002, { decimals: 0, unit: "people" })).toBe("7.2/h"); }); it("applies the display scale in every cadence band", () => { // 1027 MWh/s with scale 1e-6 → 0.001027 TWh/s → shown per hour: 3.7 TWh/h. expect(formatRate(1027, { decimals: 2, unit: "TWh", scale: 0.000001 })).toBe("3.7/h"); // 500 m/s with scale 1e-3 → 0.5 km/s → per minute: 30 km/min. expect(formatRate(500, { decimals: 0, unit: "km", scale: 0.001 })).toBe("30/min"); }); }); describe("formatCompact", () => { it("compacts axis-tick values with scale and sigFigs cap", () => { expect(formatCompact(8_310_000_000, { decimals: 0, sigFigs: 3, unit: "people" })).toBe( "8.31B", ); expect( formatCompact(23_400_000_000, { decimals: 0, sigFigs: 4, unit: "Gt", scale: 1e-9 }), ).toBe("23.4"); expect(formatCompact(Number.NaN, { decimals: 0, unit: "x" })).toBe("—"); }); }); describe("formatUncertainty", () => { it("renders a CI range", () => { const s = formatUncertainty(8.1e9, 8.3e9, { decimals: 0, sigFigs: 3, unit: "people" }); expect(s).toBe("8,100,000,000 – 8,300,000,000"); }); });