Merge remote-tracking branch 'origin/master' into feat/web-terminal-card
# Conflicts: # packages/client/ui-conversation/README.i18n.yaml
This commit is contained in:
@@ -8,6 +8,7 @@ import { describe, expect, it } from 'vitest'
|
||||
import { parseAnsiLines } from '../src/ansi.ts'
|
||||
|
||||
const ESC = '\u001b'
|
||||
const BS = '\u0008'
|
||||
|
||||
/** Paint `text` with the SGR `codes`, then reset. */
|
||||
function sgr(codes: string, text: string): string {
|
||||
@@ -170,6 +171,30 @@ describe('parseAnsiLines: carriage returns', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseAnsiLines: backspaces', () => {
|
||||
it('applies a backspace as the overwrite a terminal draws', () => {
|
||||
// `abc` then two backspaces then `XY` shows as `aXY`, not `abcXY`.
|
||||
expect(onlySpan(`abc${BS}${BS}XY`)).toEqual({ text: 'aXY', style: undefined })
|
||||
})
|
||||
|
||||
it('stops at the line start instead of eating the newline before it', () => {
|
||||
expect(parseAnsiLines(`ab\n${BS}${BS}${BS}cd`)).toEqual([
|
||||
[{ text: 'ab', style: undefined }],
|
||||
[{ text: 'cd', style: undefined }],
|
||||
])
|
||||
})
|
||||
|
||||
it('applies the overwrite after a carriage-return redraw, not before', () => {
|
||||
// The redraw wins first; the backspace then erases inside what survived.
|
||||
expect(onlySpan(`old\rnew${BS}`)).toEqual({ text: 'ne', style: undefined })
|
||||
})
|
||||
|
||||
it('keeps the run\'s style while erasing its own characters', () => {
|
||||
expect(onlySpan(sgr('31', `bad${BS}${BS}${BS}ok`)))
|
||||
.toEqual({ text: 'ok', style: { color: 'var(--dsw-alias-state-error-primary)' } })
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseAnsiLines: runs spanning lines', () => {
|
||||
it('carries one run\'s style onto every line it covers', () => {
|
||||
expect(parseAnsiLines(sgr('32', 'first\nsecond'))).toEqual([
|
||||
|
||||
@@ -217,6 +217,18 @@ describe('TerminalBlock run-state dot', () => {
|
||||
expect(promptRows(view.container)).toEqual(['$echo one', '$echo two'])
|
||||
})
|
||||
|
||||
// A heredoc or an editor-authored command commonly ends in a newline; that
|
||||
// terminator is not a further, empty command to draw a row for.
|
||||
it('drops a trailing newline instead of drawing an empty final row', () => {
|
||||
const view = render(<TerminalBlock command={'echo one\necho two\n'} output="a" exitCode={0} />)
|
||||
expect(promptRows(view.container)).toEqual(['$echo one', '$echo two'])
|
||||
})
|
||||
|
||||
it('keeps a genuinely blank command line when the command ends with two newlines', () => {
|
||||
const view = render(<TerminalBlock command={'echo one\n\n'} output="a" exitCode={0} />)
|
||||
expect(promptRows(view.container)).toEqual(['$echo one', '$'])
|
||||
})
|
||||
|
||||
// The exit status the view carries is the whole call's — bash reports no
|
||||
// per-command status — so exactly one dot and one label are correct however
|
||||
// many lines the command spans. A dot per row would assert, of a line that
|
||||
|
||||
Reference in New Issue
Block a user