fix(tui): make color-scheme detection fully covered and race-free

The color-scheme detection block left packages/ui/tui/src/index.ts below
the 100% per-file coverage gate on three counts: the .then callback's
`scheme === undefined` branch was reachable only via the 2s query
timeout, the .catch only via a query-write failure, and the
`editor.borderColor` assignment inside applyColorScheme was dead code —
the next line's setStatus() immediately reassigns editor.borderColor.

Register the scheme listener before firing the startup query so the
query's own reply is delivered through the listener (the same path as
later theme switches), which removes the redundant .then re-application
and its uncoverable undefined branch, and closes the theoretical window
where a synchronous reply lands before the listener exists. Drop the
dead editor.borderColor line. Cover the rest: a same-scheme report
(early return) and a terminal that throws on the query write (the
swallowed .catch).
This commit is contained in:
Turtle
2026-07-20 22:06:13 +08:00
parent aa7e8ea728
commit f81d382230
2 changed files with 36 additions and 11 deletions

View File

@@ -942,6 +942,13 @@ describe('terminal mounting', () => {
// Initial render uses dark-optimised palette: SGR 2 (dim) for dim text.
expect(result.terminal.output).toContain('\x1b[2mdeepseek-v4-flash')
// A report matching the current scheme is a no-op: no palette rebuild or
// re-render (ESC [?997;1n = dark, the startup default).
const beforeSameScheme = result.terminal.output.length
result.terminal.send('\x1b[?997;1n')
await tick()
expect(result.terminal.output.length).toBe(beforeSameScheme)
// Simulate the terminal responding with a light color scheme report
// (ESC [?997;2n = light, ESC [?997;1n = dark).
result.terminal.send('\x1b[?997;2n')
@@ -963,4 +970,23 @@ describe('terminal mounting', () => {
expect(result.terminal.output).toContain('\x1b[2mdeepseek-v4-flash')
await dispose(result)
})
it('keeps the dark palette when the terminal rejects the color-scheme query', async () => {
class QueryFailTerminal extends FakeTerminal {
override write(data: string): void {
// The device-status query is the only write that fails; the promise
// rejects and the swallowed `.catch` leaves the dark palette in place.
if (data === '\x1b[?996n') throw new Error('query write failed')
super.write(data)
}
}
const terminal = new QueryFailTerminal()
const result = await createTuiTestHarness(terminal, vi.fn(), {
config: { color: true },
cwd: process.cwd(),
})
await tick()
expect(terminal.output).toContain('\x1b[2mdeepseek-v4-flash')
await disposeTuiTestHarness(result)
})
})