Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/arrays.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { describe, expect, it } from "vitest";
import { chunk, dedupe, groupBy } from "./arrays";

describe("chunk", () => {
it("splits arrays into fixed-size chunks", () => {
expect(chunk([1, 2, 3, 4, 5], 2)).toEqual([[1, 2], [3, 4], [5]]);
});

it("returns an empty array for non-positive chunk sizes", () => {
expect(chunk([1, 2, 3], 0)).toEqual([]);
expect(chunk([1, 2, 3], -1)).toEqual([]);
});
});

describe("dedupe", () => {
it("keeps first occurrences in insertion order", () => {
expect(dedupe(["a", "b", "a", "c", "b"])).toEqual(["a", "b", "c"]);
});
});

describe("groupBy", () => {
it("groups values by the key returned from the callback", () => {
const grouped = groupBy(
[
{ type: "fruit", name: "apple" },
{ type: "veg", name: "carrot" },
{ type: "fruit", name: "banana" },
],
(item) => item.type,
);

expect(grouped).toEqual({
fruit: [
{ type: "fruit", name: "apple" },
{ type: "fruit", name: "banana" },
],
veg: [{ type: "veg", name: "carrot" }],
});
});
});
41 changes: 41 additions & 0 deletions src/dates.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { describe, expect, it } from "vitest";
import { addDays, daysBetween, isWeekend, startOfDayUTC } from "./dates";

describe("daysBetween", () => {
it("returns rounded absolute day differences", () => {
const start = new Date("2026-01-01T00:00:00.000Z");
const end = new Date("2026-01-03T12:00:00.000Z");

expect(daysBetween(start, end)).toBe(3);
expect(daysBetween(end, start)).toBe(3);
});
});

describe("isWeekend", () => {
it("detects Saturday and Sunday as weekends", () => {
expect(isWeekend(new Date("2026-05-30T12:00:00.000Z"))).toBe(true);
expect(isWeekend(new Date("2026-05-31T12:00:00.000Z"))).toBe(true);
});

it("detects weekdays as non-weekends", () => {
expect(isWeekend(new Date("2026-05-29T12:00:00.000Z"))).toBe(false);
});
});

describe("addDays", () => {
it("returns a new date advanced by the requested number of days", () => {
const original = new Date("2026-01-10T00:00:00.000Z");
const result = addDays(original, 5);

expect(result.toISOString()).toBe("2026-01-15T00:00:00.000Z");
expect(original.toISOString()).toBe("2026-01-10T00:00:00.000Z");
});
});

describe("startOfDayUTC", () => {
it("returns midnight UTC for the given date", () => {
const result = startOfDayUTC(new Date("2026-05-31T19:45:30.000Z"));

expect(result.toISOString()).toBe("2026-05-31T00:00:00.000Z");
});
});
41 changes: 41 additions & 0 deletions src/money.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { describe, expect, it } from "vitest";
import { formatCents, netPayoutCents, platformFeeCents, splitEvenly } from "./money";

describe("formatCents", () => {
it("formats USD and EUR with currency symbols", () => {
expect(formatCents(1234)).toBe("$12.34");
expect(formatCents(1234, "EUR")).toBe("€12.34");
});

it("prefixes unsupported currencies with the currency code", () => {
expect(formatCents(1234, "GBP")).toBe("GBP 12.34");
});
});

describe("platformFeeCents", () => {
it("returns zero when gross amount or basis points are non-positive", () => {
expect(platformFeeCents(0, 250)).toBe(0);
expect(platformFeeCents(1000, 0)).toBe(0);
});

it("rounds percentage fees to the nearest cent", () => {
expect(platformFeeCents(999, 250)).toBe(25);
});
});

describe("netPayoutCents", () => {
it("subtracts the calculated platform fee", () => {
expect(netPayoutCents(1000, 250)).toBe(975);
});
});

describe("splitEvenly", () => {
it("splits cents evenly and distributes the remainder first", () => {
expect(splitEvenly(10, 3)).toEqual([4, 3, 3]);
});

it("returns an empty list for non-positive recipient counts", () => {
expect(splitEvenly(10, 0)).toEqual([]);
expect(splitEvenly(10, -1)).toEqual([]);
});
});
46 changes: 44 additions & 2 deletions src/strings.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,49 @@
import { describe, it, expect } from "vitest";
import { slugify } from "./strings";
import { describe, expect, it } from "vitest";
import { escapeHtml, slugify, titleCase, truncate } from "./strings";

describe("slugify", () => {
it("lowercases and dashifies basic input", () => {
expect(slugify("Hello World")).toBe("hello-world");
});

it("removes punctuation and collapses duplicate dashes", () => {
expect(slugify(" Hello, --- Tiny Utils!!! ")).toBe("hello-tiny-utils");
});
});

describe("truncate", () => {
it("returns an empty string for non-positive limits", () => {
expect(truncate("hello", 0)).toBe("");
expect(truncate("hello", -1)).toBe("");
});

it("returns short input unchanged", () => {
expect(truncate("hello", 5)).toBe("hello");
});

it("adds a suffix when input exceeds the limit", () => {
expect(truncate("hello world", 8, "...")).toBe("hello...");
});

it("handles suffixes longer than the limit", () => {
expect(truncate("hello", 2, "...")).toBe("...");
});
});

describe("titleCase", () => {
it("capitalizes each word and lowercases the rest", () => {
expect(titleCase("hELLO tiny UTILS")).toBe("Hello Tiny Utils");
});

it("preserves spacing behavior from split and join", () => {
expect(titleCase("hello world")).toBe("Hello World");
});
});

describe("escapeHtml", () => {
it("escapes HTML-sensitive characters", () => {
expect(escapeHtml(`Tom & "Jerry" <cat>'s>`)).toBe(
"Tom &amp; &quot;Jerry&quot; &lt;cat&gt;&#39;s&gt;",
);
});
});