fix(daily): count the ellipsis toward the lead budget

Text with no space inside the budget was cut at 160 characters and then
given an ellipsis, so the lead came out 161 long. The ellipsis now counts
toward the budget: a space at the edge still ends a whole word, and
unbroken text is cut one short.
This commit is contained in:
Marc-André Bombeck committed 2026-10-05 13:11:29 +02:00
1 parent 2a3bd67b68
commit abb1c9f8a9
2 files changed
+25 -3

No files matched your search

@@ -864,3 +864,21 @@ describe("signal line — a metric is named by whole words, not by fragments", (
expect(lineFor(lead, metric)).toEqual({ headline: null, delta: DELTA });
});
});
describe("lead length — the ellipsis counts toward the budget", () => {
it("stays within 160 characters for text without a single space", () => {
// A digit keeps it from reading as a greeting (too few words).
const unbroken = `${"a".repeat(400)}1.`;
const lead = firstSubstantiveSentence(unbroken, null) ?? "";
expect(lead.endsWith("…")).toBe(true);
expect(lead.length).toBeLessThanOrEqual(160);
});
it("stays within 160 characters when the last space sits at the budget", () => {
const text = `${"b".repeat(159)} ${"c".repeat(39)}1.`;
const lead = firstSubstantiveSentence(text, null) ?? "";
expect(lead.length).toBeLessThanOrEqual(160);
// The space at the edge still ends a whole word.
expect(lead).toBe(`${"b".repeat(159)}…`);
});
});
+7 -3
View File
@@ -275,9 +275,13 @@ function fitsLead(text: string): boolean {
*/
function shortenAtWord(text: string): string {
if (fitsLead(text)) return text;
const room = text.slice(0, MAX_LEAD_LENGTH);
const space = room.lastIndexOf(" ");
const head = (space > 0 ? room.slice(0, space) : room)
// One character of the budget goes to the ellipsis itself, so the kept
// head is at most MAX - 1 long: a space at that index still ends a whole
// word, and text with no space at all is cut hard one short of the budget.
const space = text.slice(0, MAX_LEAD_LENGTH).lastIndexOf(" ");
const head = (
space > 0 ? text.slice(0, space) : text.slice(0, MAX_LEAD_LENGTH - 1)
)
.trimEnd()
.replace(/[\s,;:–—-]+$/u, "");
return `${head}…`;