Allow txt export with timestampts

This commit is contained in:
Lucas Winther
2026-07-17 14:14:43 +02:00
parent a5cfd219f6
commit 770cfc9ff7
3 changed files with 121 additions and 2 deletions
+69
View File
@@ -1,8 +1,10 @@
import { describe, expect, test } from "bun:test";
import {
exportFilename,
formatClockTimestamp,
formatSrtTimestamp,
transcriptToSrt,
transcriptToTimestampedTxt,
transcriptToTxt,
} from "../src/lib/export";
import type { TranscriptChunk } from "../src/worker/protocol";
@@ -100,6 +102,64 @@ describe("transcriptToSrt", () => {
});
});
describe("formatClockTimestamp", () => {
test("zero", () => {
expect(formatClockTimestamp(0)).toBe("00:00.0");
});
test("pads minutes and seconds", () => {
expect(formatClockTimestamp(3.21)).toBe("00:03.2");
expect(formatClockTimestamp(65.4)).toBe("01:05.4");
});
test("rounding to tenths carries into the minutes", () => {
expect(formatClockTimestamp(59.96)).toBe("01:00.0");
});
test("minutes keep growing past an hour", () => {
expect(formatClockTimestamp(3661.5)).toBe("61:01.5");
});
test("clamps negatives to zero", () => {
expect(formatClockTimestamp(-1)).toBe("00:00.0");
});
});
describe("transcriptToTimestampedTxt", () => {
const chunk = (
text: string,
start: number,
end: number | null,
): TranscriptChunk => ({ text, timestamp: [start, end] });
test("one bracketed range per line, trailing newline", () => {
const txt = transcriptToTimestampedTxt([
chunk(" Hello.", 3.21, 7.9),
chunk(" World.", 7.9, 12),
]);
expect(txt).toBe("[00:03.2 – 00:07.9] Hello.\n[00:07.9 – 00:12.0] World.\n");
});
test("null end omits the range end", () => {
expect(transcriptToTimestampedTxt([chunk("Tail", 10, null)])).toBe(
"[00:10.0] Tail\n",
);
});
test("skips empty and whitespace-only chunks", () => {
const txt = transcriptToTimestampedTxt([
chunk(" ", 0, 1),
chunk("Kept", 1, 2),
]);
expect(txt).toBe("[00:01.0 – 00:02.0] Kept\n");
});
test("no captioned chunks yields an empty string", () => {
expect(transcriptToTimestampedTxt([])).toBe("");
expect(transcriptToTimestampedTxt([chunk(" ", 0, 1)])).toBe("");
});
});
describe("exportFilename", () => {
test("swaps the extension", () => {
expect(exportFilename("talk.m4a", "srt")).toBe("talk.srt");
@@ -120,6 +180,15 @@ describe("exportFilename", () => {
expect(exportFilename(".bashrc", "txt")).toBe(".bashrc.txt");
});
test("compound extension keeps timestamped exports distinct", () => {
expect(exportFilename("talk.m4a", "timestamps.txt")).toBe(
"talk.timestamps.txt",
);
expect(exportFilename(null, "timestamps.txt")).toBe(
"transcript.timestamps.txt",
);
});
test("null, undefined, and blank fall back to transcript.*", () => {
expect(exportFilename(null, "srt")).toBe("transcript.srt");
expect(exportFilename(undefined, "txt")).toBe("transcript.txt");