test(web): cover the cursor replay's remaining branches
CI's coverage gate caught `ansi.ts` at 95.31% branches. My local check had scoped coverage to that one file, which measures a different test set than the gate does — the gate is the authority and it was right. Three branches. Two are now pinned, each verified in a real terminal first: `ab\r` + U+0301 + `x` shows `xb` — the redraw leaves the cursor at column 0, so a combining mark has no cell to attach to and the terminal shows nothing for it. It also revealed that the mark was kept when `cursor` was 0, which is fixed. `ab\rX\x1b[31m` then a plain line shows `Xb` unstyled and the next line RED: the mirror of the reset case, where the scan ends styled while the last cell is not, so the convergence has to OPEN the run at the line end for it to reach the following line. The third was `?? ''` on a `String.split` result, which always yields at least one element — removed rather than tested, since no input can reach it.
This commit is contained in:
2 files changed
+28
-4
No files matched your search
@@ -177,9 +177,10 @@ function replayLine(line: string, entrySgr: string): { text: string; sgr: string
|
||||
if (ZERO_WIDTH.test(char)) {
|
||||
// No column of its own: it attaches to the cell already written, so a
|
||||
// redraw that covers that cell covers the mark with it.
|
||||
const at = Math.max(0, cursor - 1)
|
||||
const base = columns[at]
|
||||
if (base !== undefined) columns[at] = { sgr: base.sgr, char: base.char + char }
|
||||
// With no cell to attach to (line start, or straight after a redraw to
|
||||
// column 0) a terminal shows nothing rather than a lone accent.
|
||||
const base = cursor > 0 ? columns[cursor - 1] : undefined
|
||||
if (base !== undefined) columns[cursor - 1] = { sgr: base.sgr, char: base.char + char }
|
||||
continue
|
||||
}
|
||||
columns[cursor] = { sgr, char }
|
||||
@@ -207,7 +208,7 @@ function replayLine(line: string, entrySgr: string): { text: string; sgr: string
|
||||
// later write can still land past them.
|
||||
// Only the FIRST parameter selects the mode; a terminal ignores the rest
|
||||
// (`1;2K` erases exactly as `1K` does — verified against a real terminal).
|
||||
const mode = params.split(';')[0] ?? ''
|
||||
const mode = String(params.split(';')[0])
|
||||
if (mode === '1') for (let index = 0; index <= cursor; index++) columns[index] = { sgr, char: ' ' }
|
||||
else columns.length = mode === '2' ? 0 : cursor
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user