Saltar al contenido
← Todos los ejercicios

El slug que se come las letras con acento

TypeScript · Las URL de los posts en una plataforma de blogs multilingüe · Casos límite · dificultad 2/3 · ~7 min

Un compañero de equipo le pidió al asistente de IA: "Escribe un slugify(title) para las URL de los posts. En minúsculas, solo letras ASCII y dígitos, guiones entre palabras, nada en los extremos. Las letras con acento deben conservar su letra base, porque muchos de nuestros autores escriben en francés, portugués y alemán. Añade también uniqueSlug(title, existing), que agregue -2, -3 y así sucesivamente cuando un slug ya esté ocupado."

El código llegó con tests, y todos los posts en inglés de staging tienen URL limpias. El contrato que promete el docstring:

  • La salida contiene solo a-z, 0-9 y separadores - simples, sin - al inicio ni al final.
  • Las secuencias de espacios y signos de puntuación se reducen a un solo -.
  • Las letras con acento se reducen a su letra base: "Crème brûlée" se convierte en "creme-brulee".
  • uniqueSlug devuelve el slug tal cual cuando está libre y, si no, la primera variante -n libre.

Revísalo antes de que salga a producción para los autores que no escriben en inglés.

Repara el código hasta que pasen las pruebas ocultas.

code.ts

Pruebas visibles (pasan con el código tal como está)
import { describe, it, expect } from "@debunk/harness";
import { slugify, uniqueSlug } from "./code";

describe("slugify", () => {
  it("lowercases and joins words with hyphens", () => {
    expect(slugify("Hello World")).toBe("hello-world");
  });

  it("drops punctuation and collapses runs of separators", () => {
    expect(slugify("  Rust & C++: a comparison!  ")).toBe("rust-c-a-comparison");
  });

  it("uniqueSlug appends a counter when the slug is taken", () => {
    const existing = new Set(["hello-world", "hello-world-2"]);
    expect(uniqueSlug("Hello World", existing)).toBe("hello-world-3");
  });
});