SPB Git

spb/earth-now Public License

earth-now.co — real-time planetary dashboard: live world metrics modeled, not streamed.

TypeScript 93% Shell 2.3% SQL 1.4% JavaScript 1.3% Dockerfile 1.2% CSS 0.8%
3.0 KB · 86 lines typescript
Raw Blame History
1/**2 * earth-now.co3 * Author:  Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File:    packages/counter/test/format.test.ts6 * Purpose: Formatting tests — sigFigs honesty cap, locales, rates, fallback on non-finite values7 */89import { describe, expect, it } from "vitest";10import {11  formatCompact,12  formatRate,13  formatUncertainty,14  formatValue,15  roundToSigFigs,16} from "../src/index";1718describe("roundToSigFigs", () => {19  it("caps significant digits", () => {20    expect(roundToSigFigs(8_231_456_789, 7)).toBe(8_231_457_000);21    expect(roundToSigFigs(426.912345, 5)).toBeCloseTo(426.91, 9);22    expect(roundToSigFigs(0.0012349, 3)).toBeCloseTo(0.00123, 12);23    expect(roundToSigFigs(-1234, 2)).toBe(-1200);24    expect(roundToSigFigs(0, 3)).toBe(0);25  });26});2728describe("formatValue", () => {29  it("applies sigFigs then decimals", () => {30    const s = formatValue(8_231_456_789, { decimals: 0, sigFigs: 7, unit: "people" });31    expect(s).toBe("8,231,457,000");32  });3334  it("keeps full precision when applySigFigs=false (animated ticker)", () => {35    const s = formatValue(8_231_456_789, { decimals: 0, sigFigs: 7, unit: "people" }, {36      applySigFigs: false,37    });38    expect(s).toBe("8,231,456,789");39  });4041  it("honors locale", () => {42    const s = formatValue(1234.5, { decimals: 1, unit: "t" }, { locale: "fr" });43    // fr uses narrow no-break space grouping and comma decimal.44    expect(s).toMatch(/1[\s  ]234,5/);45  });4647  it("falls back on non-finite values (never NaN on screen)", () => {48    expect(formatValue(Number.NaN, { decimals: 0, unit: "x" })).toBe("—");49    expect(formatValue(Infinity, { decimals: 0, unit: "x" })).toBe("—");50  });51});5253describe("formatRate", () => {54  it("chooses a human cadence", () => {55    expect(formatRate(4.2, { decimals: 0, unit: "people" })).toBe("4.2/s");56    expect(formatRate(0.5, { decimals: 0, unit: "people" })).toBe("30/min");57    expect(formatRate(0.002, { decimals: 0, unit: "people" })).toBe("7.2/h");58  });5960  it("applies the display scale in every cadence band", () => {61    // 1027 MWh/s with scale 1e-6 → 0.001027 TWh/s → shown per hour: 3.7 TWh/h.62    expect(formatRate(1027, { decimals: 2, unit: "TWh", scale: 0.000001 })).toBe("3.7/h");63    // 500 m/s with scale 1e-3 → 0.5 km/s → per minute: 30 km/min.64    expect(formatRate(500, { decimals: 0, unit: "km", scale: 0.001 })).toBe("30/min");65  });66});6768describe("formatCompact", () => {69  it("compacts axis-tick values with scale and sigFigs cap", () => {70    expect(formatCompact(8_310_000_000, { decimals: 0, sigFigs: 3, unit: "people" })).toBe(71      "8.31B",72    );73    expect(74      formatCompact(23_400_000_000, { decimals: 0, sigFigs: 4, unit: "Gt", scale: 1e-9 }),75    ).toBe("23.4");76    expect(formatCompact(Number.NaN, { decimals: 0, unit: "x" })).toBe("—");77  });78});7980describe("formatUncertainty", () => {81  it("renders a CI range", () => {82    const s = formatUncertainty(8.1e9, 8.3e9, { decimals: 0, sigFigs: 3, unit: "people" });83    expect(s).toBe("8,100,000,000 – 8,300,000,000");84  });85});86