mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
test(runtime): enforce ANSI preview-final pre-filter invariant (#27376)
Follow-up to #27344. isTerminalPreviewLineControl now gates on isTerminalPreviewLineControlFinal, so the normalizeTerminalChunk pre-filter cannot drop a final the predicate accepts. Add a test over every CSI final 0x40-0x7e and replace String.prototype.charCodeAt spies with behavior assertions.
This commit is contained in:
@@ -197,7 +197,7 @@ function trimPendingAnsiControl(value: string): string {
|
||||
return `${introducer}${value.slice(-suffixBudget)}`
|
||||
}
|
||||
|
||||
/** CSI controls that affect retained preview rows. */
|
||||
/** CSI finals that affect retained preview rows; the sole gate for isTerminalPreviewLineControl. */
|
||||
function isTerminalPreviewLineControlFinal(code: number): boolean {
|
||||
return (
|
||||
code === 0x4b ||
|
||||
@@ -214,12 +214,16 @@ function isTerminalPreviewLineControl(parsed: {
|
||||
params: string
|
||||
firstParam: number | null
|
||||
}): boolean {
|
||||
if (!hasCanonicalNumericCsiParams(parsed.params)) {
|
||||
// Why: normalizeTerminalChunk pre-filters on this predicate, so any final accepted here must pass it first.
|
||||
if (
|
||||
!isTerminalPreviewLineControlFinal(parsed.final.charCodeAt(0)) ||
|
||||
!hasCanonicalNumericCsiParams(parsed.params)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
if (parsed.final === 'K') {
|
||||
const mode = parsed.firstParam ?? 0
|
||||
return mode === 0 || mode === 1 || mode === 2
|
||||
}
|
||||
return isTerminalPreviewLineControlFinal(parsed.final.charCodeAt(0))
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import {
|
||||
containsTerminalVerticalLineControl,
|
||||
normalizeTerminalChunk
|
||||
@@ -6,20 +6,42 @@ import {
|
||||
import { appendNormalizedToTailBuffer } from './terminal-tail-buffer'
|
||||
|
||||
describe('terminal vertical-control scanning', () => {
|
||||
it('scans retained CSI parameters once while normalizing', () => {
|
||||
it('keeps a line control with long retained CSI parameters', () => {
|
||||
const input = `\x1b[${'1;'.repeat(2048)}A`
|
||||
const charCodeAt = vi.spyOn(String.prototype, 'charCodeAt')
|
||||
let normalized: ReturnType<typeof normalizeTerminalChunk>
|
||||
let inspections: number
|
||||
try {
|
||||
normalized = normalizeTerminalChunk(input)
|
||||
inspections = charCodeAt.mock.calls.length
|
||||
} finally {
|
||||
charCodeAt.mockRestore()
|
||||
}
|
||||
expect(normalizeTerminalChunk(input)).toEqual({
|
||||
text: input,
|
||||
pendingAnsi: ''
|
||||
})
|
||||
})
|
||||
|
||||
expect(normalized).toEqual({ text: input, pendingAnsi: '' })
|
||||
expect(inspections).toBeLessThanOrEqual(input.length + 8)
|
||||
it('retains exactly the preview line-control CSI finals', () => {
|
||||
const retained: string[] = []
|
||||
for (let code = 0x40; code <= 0x7e; code += 1) {
|
||||
const final = String.fromCharCode(code)
|
||||
for (const params of ['', '2']) {
|
||||
const control = `\x1b[${params}${final}`
|
||||
const { text } = normalizeTerminalChunk(`a${control}b`)
|
||||
if (text === `a${control}b`) {
|
||||
retained.push(control)
|
||||
} else {
|
||||
expect(text).toBe('ab')
|
||||
}
|
||||
}
|
||||
}
|
||||
expect(retained).toEqual([
|
||||
'\x1b[A',
|
||||
'\x1b[2A',
|
||||
'\x1b[C',
|
||||
'\x1b[2C',
|
||||
'\x1b[D',
|
||||
'\x1b[2D',
|
||||
'\x1b[G',
|
||||
'\x1b[2G',
|
||||
'\x1b[K',
|
||||
'\x1b[2K',
|
||||
'\x1b[`',
|
||||
'\x1b[2`'
|
||||
])
|
||||
})
|
||||
|
||||
it('preserves printable spans and carried controls across chunk boundaries', () => {
|
||||
@@ -35,19 +57,8 @@ describe('terminal vertical-control scanning', () => {
|
||||
['plain', 'log output '.repeat(8192), false],
|
||||
['nonvertical CSI', `\x1b[31m${'log output '.repeat(8192)}\x1b[0m`, false],
|
||||
['vertical CSI', `${'漢字😀 output '.repeat(8192)}\x1b[2A`, true]
|
||||
] as const)('bounds code-unit inspections on %s output', (_name, input, expected) => {
|
||||
const charCodeAt = vi.spyOn(String.prototype, 'charCodeAt')
|
||||
let actual: boolean
|
||||
let inspections: number
|
||||
try {
|
||||
actual = containsTerminalVerticalLineControl(input)
|
||||
inspections = charCodeAt.mock.calls.length
|
||||
} finally {
|
||||
charCodeAt.mockRestore()
|
||||
}
|
||||
|
||||
expect(actual).toBe(expected)
|
||||
expect(inspections).toBeLessThan(16)
|
||||
] as const)('detects vertical controls in %s output', (_name, input, expected) => {
|
||||
expect(containsTerminalVerticalLineControl(input)).toBe(expected)
|
||||
})
|
||||
|
||||
it.each([
|
||||
|
||||
Reference in New Issue
Block a user