61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { ensureUniqueSlug, slugify } from "@/lib/slug";
|
|
|
|
describe("slugify", () => {
|
|
it("lowercases and hyphenates plain titles", () => {
|
|
expect(slugify("Hello, World!")).toBe("hello-world");
|
|
});
|
|
|
|
it("collapses runs of spaces and punctuation into single hyphens", () => {
|
|
expect(slugify(" Multiple spaces &&& symbols!! ")).toBe("multiple-spaces-symbols");
|
|
});
|
|
|
|
it("strips diacritics", () => {
|
|
expect(slugify("Crème Brûlée à Paris")).toBe("creme-brulee-a-paris");
|
|
});
|
|
|
|
it("drops emoji and other non-latin symbols", () => {
|
|
expect(slugify("🎉 Party time 🎉")).toBe("party-time");
|
|
});
|
|
|
|
it("keeps digits", () => {
|
|
expect(slugify("Top 10 Things")).toBe("top-10-things");
|
|
});
|
|
|
|
it("returns an empty string when nothing survives", () => {
|
|
expect(slugify("!!! ***")).toBe("");
|
|
});
|
|
|
|
it("truncates very long titles without a trailing hyphen", () => {
|
|
const slug = slugify(`${"word ".repeat(40)}end`);
|
|
expect(slug.length).toBeLessThanOrEqual(96);
|
|
expect(slug.endsWith("-")).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("ensureUniqueSlug", () => {
|
|
const takenSet = (...taken: string[]) => {
|
|
const set = new Set(taken);
|
|
return async (slug: string) => set.has(slug);
|
|
};
|
|
|
|
it("returns the base slug when free", async () => {
|
|
expect(await ensureUniqueSlug("my-post", takenSet())).toBe("my-post");
|
|
});
|
|
|
|
it("appends -2 on the first conflict", async () => {
|
|
expect(await ensureUniqueSlug("my-post", takenSet("my-post"))).toBe("my-post-2");
|
|
});
|
|
|
|
it("keeps counting past multiple conflicts", async () => {
|
|
expect(
|
|
await ensureUniqueSlug("my-post", takenSet("my-post", "my-post-2", "my-post-3")),
|
|
).toBe("my-post-4");
|
|
});
|
|
|
|
it("falls back to 'untitled' for an empty base", async () => {
|
|
expect(await ensureUniqueSlug("", takenSet())).toBe("untitled");
|
|
expect(await ensureUniqueSlug("", takenSet("untitled"))).toBe("untitled-2");
|
|
});
|
|
});
|