diff --git a/src/transforms/case.test.ts b/src/transforms/case.test.ts new file mode 100644 index 0000000..3d1a20a --- /dev/null +++ b/src/transforms/case.test.ts @@ -0,0 +1,19 @@ +import { describe, it, expect } from "vitest"; +import { latinize, slugify, toTitleCase } from "./case"; + +describe("unicode case handling", () => { + it("should title-case words with Polish diacritics without mangling letters", () => { + const input = "Weryfikacja reżimu podatkowego"; + expect(toTitleCase(input)).toBe("Weryfikacja Reżimu Podatkowego"); + }); + + it("should strip combining marks while preserving letters, numbers, whitespace, and underscores", () => { + expect(latinize("Reżym 123_test")).toBe("Rezym 123_test"); + }); + + it("should slugify Unicode words into a URL-friendly string", () => { + expect(slugify("Weryfikacja reżimu podatkowego")).toBe( + "weryfikacja-rezimu-podatkowego" + ); + }); +}); diff --git a/src/transforms/case.ts b/src/transforms/case.ts index d7e36e0..730d2d0 100644 --- a/src/transforms/case.ts +++ b/src/transforms/case.ts @@ -79,7 +79,7 @@ export function toDotCase(text: string): string { export function toTitleCase(text: string): string { return perLine(text, (line) => line.replace( - /\b\w+/g, + /[\p{L}\p{N}]+/gu, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase() ) ); @@ -135,7 +135,9 @@ export function reverseLines(text: string): string { /** Removes diacritic marks — e.g. "café" → "cafe", "Ñoño" → "Nono" */ export function latinize(text: string): string { - return text.normalize("NFD").replace(/[\u0300-\u036f]/g, ""); + return text + .normalize("NFD") + .replace(/[^\p{L}\p{N}_\s]+/gu, ""); } /** URL-friendly slug: lowercase, ASCII, spaces→dashes */