import { describe, it, expect } from "vitest"; import { formatQuantity, scaleQuantity } from "../fractions"; describe("formatQuantity", () => { it("returns '0' for 0", () => { expect(formatQuantity(0)).toBe("0"); }); it("returns whole numbers as strings", () => { expect(formatQuantity(1)).toBe("1"); expect(formatQuantity(4)).toBe("4"); }); it("rounds near-integer values up", () => { expect(formatQuantity(0.97)).toBe("1"); expect(formatQuantity(2.96)).toBe("3"); }); it("formats known fractions with unicode symbols", () => { expect(formatQuantity(0.5)).toBe("½"); expect(formatQuantity(0.25)).toBe("¼"); expect(formatQuantity(0.75)).toBe("¾"); expect(formatQuantity(0.333)).toBe("⅓"); expect(formatQuantity(0.667)).toBe("⅔"); expect(formatQuantity(0.125)).toBe("⅛"); }); it("formats mixed numbers", () => { expect(formatQuantity(1.5)).toBe("1 ½"); expect(formatQuantity(2.25)).toBe("2 ¼"); expect(formatQuantity(3.75)).toBe("3 ¾"); }); it("falls back to one decimal for values that don't match a fraction", () => { // 0.4375 is midpoint between ⅜ (0.375) and ½ (0.5), diff=0.0625 from both — exceeds 0.06 threshold expect(formatQuantity(0.4375)).toMatch(/^0\.\d$/); }); }); describe("scaleQuantity", () => { it("returns empty string for null/empty base quantity", () => { expect(scaleQuantity(null, 4, 2)).toBe(""); expect(scaleQuantity("", 4, 2)).toBe(""); }); it("returns base quantity unchanged for non-numeric strings", () => { expect(scaleQuantity("to taste", 4, 2)).toBe("to taste"); }); it("scales down by half", () => { expect(scaleQuantity("4", 4, 2)).toBe("2"); }); it("scales up by double", () => { expect(scaleQuantity("2", 2, 4)).toBe("4"); }); it("handles base=0 gracefully (no division by zero)", () => { expect(scaleQuantity("3", 0, 4)).toBe("3"); }); it("produces fraction symbols when result is fractional", () => { expect(scaleQuantity("1", 2, 1)).toBe("½"); }); });