mirror of
https://github.com/stablyai/orca.git
synced 2026-10-08 08:02:32 +00:00
158 lines
4.8 KiB
TypeScript
158 lines
4.8 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
TerminalStreamOpcode,
|
|
decodeTerminalStreamFrame,
|
|
decodeTerminalStreamJson,
|
|
decodeTerminalStreamText,
|
|
encodeTerminalStreamFrame,
|
|
encodeTerminalStreamJson,
|
|
encodeTerminalStreamText
|
|
} from './terminal-stream-protocol'
|
|
|
|
describe('terminal-stream-protocol', () => {
|
|
it('round-trips fixed-width binary frame headers and payloads', () => {
|
|
const payload = encodeTerminalStreamText('hello terminal')
|
|
const encoded = encodeTerminalStreamFrame({
|
|
opcode: TerminalStreamOpcode.Output,
|
|
streamId: 42,
|
|
seq: 9,
|
|
payload
|
|
})
|
|
|
|
const decoded = decodeTerminalStreamFrame(encoded)
|
|
|
|
expect(decoded?.opcode).toBe(TerminalStreamOpcode.Output)
|
|
expect(decoded?.streamId).toBe(42)
|
|
expect(decoded?.seq).toBe(9)
|
|
expect(decoded ? decodeTerminalStreamText(decoded.payload) : '').toBe('hello terminal')
|
|
})
|
|
|
|
it('round-trips snapshot metadata JSON payloads', () => {
|
|
const encoded = encodeTerminalStreamFrame({
|
|
opcode: TerminalStreamOpcode.SnapshotStart,
|
|
streamId: 7,
|
|
seq: 1,
|
|
payload: encodeTerminalStreamJson({ kind: 'scrollback', cols: 49, rows: 28 })
|
|
})
|
|
|
|
const decoded = decodeTerminalStreamFrame(encoded)
|
|
|
|
expect(decoded && decodeTerminalStreamJson(decoded.payload)).toEqual({
|
|
kind: 'scrollback',
|
|
cols: 49,
|
|
rows: 28
|
|
})
|
|
})
|
|
|
|
it('round-trips terminal input and resize frames', () => {
|
|
const input = decodeTerminalStreamFrame(
|
|
encodeTerminalStreamFrame({
|
|
opcode: TerminalStreamOpcode.Input,
|
|
streamId: 11,
|
|
seq: 1,
|
|
payload: encodeTerminalStreamText('a')
|
|
})
|
|
)
|
|
const resize = decodeTerminalStreamFrame(
|
|
encodeTerminalStreamFrame({
|
|
opcode: TerminalStreamOpcode.Resize,
|
|
streamId: 11,
|
|
seq: 2,
|
|
payload: encodeTerminalStreamJson({ cols: 120, rows: 40 })
|
|
})
|
|
)
|
|
|
|
expect(input?.opcode).toBe(TerminalStreamOpcode.Input)
|
|
expect(input ? decodeTerminalStreamText(input.payload) : '').toBe('a')
|
|
expect(resize?.opcode).toBe(TerminalStreamOpcode.Resize)
|
|
expect(resize && decodeTerminalStreamJson(resize.payload)).toEqual({ cols: 120, rows: 40 })
|
|
})
|
|
|
|
it('round-trips terminal metadata frames', () => {
|
|
const metadata = decodeTerminalStreamFrame(
|
|
encodeTerminalStreamFrame({
|
|
opcode: TerminalStreamOpcode.Metadata,
|
|
streamId: 11,
|
|
seq: 4,
|
|
payload: encodeTerminalStreamJson({ cwd: '/repo/src' })
|
|
})
|
|
)
|
|
|
|
expect(metadata?.opcode).toBe(TerminalStreamOpcode.Metadata)
|
|
expect(metadata && decodeTerminalStreamJson(metadata.payload)).toEqual({ cwd: '/repo/src' })
|
|
})
|
|
|
|
it('round-trips multiplex subscribe, snapshot request, and unsubscribe frames', () => {
|
|
const subscribe = decodeTerminalStreamFrame(
|
|
encodeTerminalStreamFrame({
|
|
opcode: TerminalStreamOpcode.Subscribe,
|
|
streamId: 0,
|
|
seq: 1,
|
|
payload: encodeTerminalStreamJson({
|
|
streamId: 12,
|
|
terminal: 'terminal-1',
|
|
viewport: { cols: 120, rows: 40 }
|
|
})
|
|
})
|
|
)
|
|
const unsubscribe = decodeTerminalStreamFrame(
|
|
encodeTerminalStreamFrame({
|
|
opcode: TerminalStreamOpcode.Unsubscribe,
|
|
streamId: 12,
|
|
seq: 2,
|
|
payload: new Uint8Array()
|
|
})
|
|
)
|
|
const snapshotRequest = decodeTerminalStreamFrame(
|
|
encodeTerminalStreamFrame({
|
|
opcode: TerminalStreamOpcode.SnapshotRequest,
|
|
streamId: 12,
|
|
seq: 3,
|
|
payload: new Uint8Array()
|
|
})
|
|
)
|
|
|
|
expect(subscribe?.opcode).toBe(TerminalStreamOpcode.Subscribe)
|
|
expect(subscribe && decodeTerminalStreamJson(subscribe.payload)).toMatchObject({
|
|
streamId: 12,
|
|
terminal: 'terminal-1'
|
|
})
|
|
expect(snapshotRequest?.opcode).toBe(TerminalStreamOpcode.SnapshotRequest)
|
|
expect(snapshotRequest?.streamId).toBe(12)
|
|
expect(unsubscribe?.opcode).toBe(TerminalStreamOpcode.Unsubscribe)
|
|
expect(unsubscribe?.streamId).toBe(12)
|
|
})
|
|
|
|
it('round-trips output acknowledgement frames', () => {
|
|
const ack = decodeTerminalStreamFrame(
|
|
encodeTerminalStreamFrame({
|
|
opcode: TerminalStreamOpcode.Ack,
|
|
streamId: 12,
|
|
seq: 4,
|
|
payload: encodeTerminalStreamJson({ bytes: 4096 })
|
|
})
|
|
)
|
|
|
|
expect(ack?.opcode).toBe(TerminalStreamOpcode.Ack)
|
|
expect(ack?.streamId).toBe(12)
|
|
expect(ack && decodeTerminalStreamJson(ack.payload)).toEqual({ bytes: 4096 })
|
|
})
|
|
|
|
it('rejects unknown frame versions and opcodes', () => {
|
|
const encoded = encodeTerminalStreamFrame({
|
|
opcode: TerminalStreamOpcode.Output,
|
|
streamId: 1,
|
|
seq: 1,
|
|
payload: new Uint8Array()
|
|
})
|
|
|
|
const badVersion = encoded.slice()
|
|
badVersion[1] = 99
|
|
expect(decodeTerminalStreamFrame(badVersion)).toBeNull()
|
|
|
|
const badOpcode = encoded.slice()
|
|
badOpcode[2] = 99
|
|
expect(decodeTerminalStreamFrame(badOpcode)).toBeNull()
|
|
})
|
|
})
|