SPB Git

Repository Public

captions.test.ts 1.8 KB 36 lines typescript

1import { describe, expect, it } from "vitest";2import { cuesFromText, cuesFromWords, parseVtt, toVtt, wordsFromChars } from "../src/pipeline/captions";34const chars = (text: string, per = 0.06) => [...text].map((char, i) => ({ char, start: i * per, end: (i + 1) * per }));56describe("captions", () => {7  it("groups character timings into words", () => {8    const w = wordsFromChars(chars("La montre s’arrête."));9    expect(w.map((x) => x.text)).toEqual(["La", "montre", "s’arrête."]);10    expect(w[1].start).toBeCloseTo(0.18);11  });12  it("builds short cues that never overlap and respects the offset", () => {13    const cues = cuesFromWords(wordsFromChars(chars("It had measured not hours but the years he lived after pulling a sailor from the sea.")), 10);14    expect(cues.length).toBeGreaterThan(1);15    expect(cues[0].start).toBeGreaterThanOrEqual(10);16    for (const c of cues) expect(c.text.length).toBeLessThanOrEqual(34);17    for (let i = 1; i < cues.length; i++) expect(cues[i].start).toBeGreaterThanOrEqual(cues[i - 1].end);18  });19  it("spreads translated text over the spoken interval", () => {20    const cues = cuesFromText("Elle ne mesurait pas les heures, mais les années vécues après avoir sauvé un marin.", 2, 8);21    expect(cues[0].start).toBe(2);22    expect(cues.at(-1)!.end).toBeLessThanOrEqual(8.001);23    expect(cuesFromText("", 0, 5)).toEqual([]);24  });25  it("round-trips through WebVTT", () => {26    const cues = [{ start: 0.4, end: 2.05, text: "First line" }, { start: 2.1, end: 61.5, text: "Second --> line" }];27    const vtt = toVtt(cues);28    expect(vtt.startsWith("WEBVTT\n")).toBe(true);29    expect(vtt).toContain("00:00:00.400 --> 00:00:02.050");30    expect(vtt).toContain("00:01:01.500");31    const back = parseVtt(vtt);32    expect(back).toHaveLength(2);33    expect(back[1].text).toBe("Second → line");34  });35});36
Files main
Menu

Theme