refactor: cut cyclomatic complexity of five hot spots and pin their behavior with tests

Risk labels, menu callback parsing, settings callbacks, table cell width and
markdown link targets now use tables and small helpers (CC <= 10).
This commit is contained in:
evandro committed 2026-10-10 03:59:46 -03:00
1 parent bf4a2021e8
commit 6a6e75fe32
8 files changed
+648 -294

No files matched your search

+116 -90
View File
@@ -191,81 +191,94 @@ function findMarkdownClosingBracket(
return undefined;
}
function skipMarkdownWhitespace(text: string, index: number): number {
while (index < text.length && /\s/.test(text[index] ?? "")) {
index += 1;
}
return index;
}
/** Index of the first unescaped `closing` character at or after `index`, or text length */
function findUnescapedMarkdownCharacter(
text: string,
index: number,
closing: string,
): number {
while (
index < text.length &&
(isEscapedMarkdownCharacter(text, index) || text[index] !== closing)
) {
index += 1;
}
return index;
}
function parseMarkdownAngleDestination(
text: string,
openIndex: number,
): { destination: string; nextIndex: number } | undefined {
const closeIndex = findUnescapedMarkdownCharacter(text, openIndex + 1, ">");
if (closeIndex >= text.length) return undefined;
return {
destination: text.slice(openIndex + 1, closeIndex).trim(),
nextIndex: closeIndex + 1,
};
}
function parseMarkdownBareDestination(
text: string,
startIndex: number,
): { destination: string; nextIndex: number } {
let index = startIndex;
let parenDepth = 0;
while (index < text.length) {
if (isEscapedMarkdownCharacter(text, index)) {
index += 1;
continue;
}
const char = text[index] ?? "";
if (parenDepth === 0 && (char === ")" || /\s/.test(char))) break;
if (char === "(") parenDepth += 1;
if (char === ")") parenDepth -= 1;
index += 1;
}
return { destination: text.slice(startIndex, index).trim(), nextIndex: index };
}
/** Skips an optional quoted or parenthesized title; undefined when it is unterminated */
function skipMarkdownLinkTitle(
text: string,
index: number,
): number | undefined {
const titleDelimiter = text[index];
if (titleDelimiter !== '"' && titleDelimiter !== "'" && titleDelimiter !== "(") {
return index;
}
const closingDelimiter = titleDelimiter === "(" ? ")" : titleDelimiter;
const closeIndex = findUnescapedMarkdownCharacter(
text,
index + 1,
closingDelimiter,
);
if (closeIndex >= text.length) return undefined;
return skipMarkdownWhitespace(text, closeIndex + 1);
}
function parseMarkdownLinkTarget(
text: string,
openParenIndex: number,
): { destination: string; endIndex: number } | undefined {
let index = openParenIndex + 1;
while (index < text.length && /\s/.test(text[index] ?? "")) {
index += 1;
}
if (index >= text.length) return undefined;
let destination = "";
if (text[index] === "<") {
const destinationStart = index + 1;
index += 1;
while (index < text.length) {
if (!isEscapedMarkdownCharacter(text, index) && text[index] === ">") {
break;
}
index += 1;
}
if (index >= text.length) return undefined;
destination = text.slice(destinationStart, index).trim();
index += 1;
} else {
const destinationStart = index;
let parenDepth = 0;
while (index < text.length) {
if (isEscapedMarkdownCharacter(text, index)) {
index += 1;
continue;
}
const char = text[index] ?? "";
if (/\s/.test(char) && parenDepth === 0) break;
if (char === "(") {
parenDepth += 1;
index += 1;
continue;
}
if (char === ")") {
if (parenDepth === 0) break;
parenDepth -= 1;
index += 1;
continue;
}
index += 1;
}
destination = text.slice(destinationStart, index).trim();
}
if (!destination) return undefined;
while (index < text.length && /\s/.test(text[index] ?? "")) {
index += 1;
}
if (
index < text.length &&
(text[index] === '"' || text[index] === "'" || text[index] === "(")
) {
const titleDelimiter = text[index] ?? '"';
const closingTitleDelimiter = titleDelimiter === "(" ? ")" : titleDelimiter;
index += 1;
while (index < text.length) {
if (
!isEscapedMarkdownCharacter(text, index) &&
text[index] === closingTitleDelimiter
) {
break;
}
index += 1;
}
if (index >= text.length) return undefined;
index += 1;
while (index < text.length && /\s/.test(text[index] ?? "")) {
index += 1;
}
}
if (text[index] !== ")") return undefined;
return { destination, endIndex: index };
const destinationIndex = skipMarkdownWhitespace(text, openParenIndex + 1);
if (destinationIndex >= text.length) return undefined;
const parsed =
text[destinationIndex] === "<"
? parseMarkdownAngleDestination(text, destinationIndex)
: parseMarkdownBareDestination(text, destinationIndex);
if (!parsed?.destination) return undefined;
const titleIndex = skipMarkdownWhitespace(text, parsed.nextIndex);
const endIndex = skipMarkdownLinkTitle(text, titleIndex);
if (endIndex === undefined || text[endIndex] !== ")") return undefined;
return { destination: parsed.destination, endIndex };
}
function isSupportedMarkdownLinkDestination(destination: string): boolean {
@@ -715,27 +728,40 @@ function isTelegramTableEmojiGrapheme(grapheme: string): boolean {
);
}
/** Inclusive code point ranges that occupy two terminal columns */
const TELEGRAM_TABLE_WIDE_CODE_POINT_RANGES: ReadonlyArray<
readonly [number, number]
> = [
[0x1100, 0x115f],
[0x2329, 0x232a],
[0x2e80, 0xa4cf],
[0xac00, 0xd7a3],
[0xf900, 0xfaff],
[0xfe10, 0xfe19],
[0xfe30, 0xfe6f],
[0xff00, 0xff60],
[0xffe0, 0xffe6],
];
function isTelegramTableZeroWidthCodePoint(
codePoint: number,
char: string,
): boolean {
return (
codePoint < 32 ||
codePoint === 0x200d ||
(codePoint >= 0xfe00 && codePoint <= 0xfe0f) ||
/\p{Mark}/u.test(char)
);
}
function getTelegramTableCodePointWidth(char: string): number {
const codePoint = char.codePointAt(0) ?? 0;
if (codePoint === 0 || codePoint < 32) return 0;
if (/\p{Mark}/u.test(char)) return 0;
if ((codePoint >= 0xfe00 && codePoint <= 0xfe0f) || codePoint === 0x200d)
return 0;
if (
(codePoint >= 0x1100 && codePoint <= 0x115f) ||
codePoint === 0x2329 ||
codePoint === 0x232a ||
(codePoint >= 0x2e80 && codePoint <= 0xa4cf) ||
(codePoint >= 0xac00 && codePoint <= 0xd7a3) ||
(codePoint >= 0xf900 && codePoint <= 0xfaff) ||
(codePoint >= 0xfe10 && codePoint <= 0xfe19) ||
(codePoint >= 0xfe30 && codePoint <= 0xfe6f) ||
(codePoint >= 0xff00 && codePoint <= 0xff60) ||
(codePoint >= 0xffe0 && codePoint <= 0xffe6)
) {
return 2;
}
return 1;
if (isTelegramTableZeroWidthCodePoint(codePoint, char)) return 0;
const isWide = TELEGRAM_TABLE_WIDE_CODE_POINT_RANGES.some(
([start, end]) => codePoint >= start && codePoint <= end,
);
return isWide ? 2 : 1;
}
function getTelegramTableGraphemes(text: string): string[] {