Something went wrong. Try again.
fork of charmbracelet/ultraviolet with an input fix for split OSC 5522 replies, used by albedo
Something went wrong. Try again.
ultraviolet split_string_test.go
2.2 kB · 74 lines
Go
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475package uv
import ( "io" "reflect" "strings" "testing" "time")
// Control strings split across reads, the way a large OSC 5522 clipboard// reply arrives over ssh.
// stalledReader returns one chunk per Read, pausing before each like a slow// network link.type stalledReader struct { chunks []string pause time.Duration}
func (r *stalledReader) Read(p []byte) (int, error) { if len(r.chunks) == 0 { return 0, io.EOF } time.Sleep(r.pause) n := copy(p, r.chunks[0]) r.chunks = r.chunks[1:] return n, nil}
func TestDecodeWaitsForSplitStringTerminator(t *testing.T) { for name, seq := range map[string]string{ "osc": "\x1b]5522;type=read:status=DATA;QUJD\x1b", "apc": "\x1b_Gi=1;OK\x1b", "dcs": "\x1bP1+r5463=31\x1b", } { t.Run(name, func(t *testing.T) { var d EventDecoder n, ev := d.Decode([]byte(seq)) if _, ok := ev.(UnknownEvent); !ok || n != len(seq) { t.Fatalf("Decode(%q) = %d, %T; want an incomplete UnknownEvent over the whole buffer", seq, n, ev) } }) }}
func TestStreamEventsKeepsOscAcrossStalledReads(t *testing.T) { payload := strings.Repeat("QUJD", 2000) osc := "\x1b]5522;type=read:status=DATA:id=x;" + payload + "\x1b\\" half := len(osc) / 2 chunks := []string{ osc[:half], // stall mid payload osc[half : len(osc)-1], // stall between ESC and the backslash of ST osc[len(osc)-1:] + "a", } events := testReadInputs(t, &stalledReader{chunks: chunks, pause: 4 * DefaultEscTimeout}) want := []Event{UnknownOscEvent(osc), KeyPressEvent{Code: 'a', Text: "a"}} if !reflect.DeepEqual(events, want) { t.Fatalf("events = %#v\nwant %#v", events, want) }}
func TestStreamEventsFlushesStalledClipboardOscAfterItsTimeout(t *testing.T) { saved := pendingClipboardOscTimeout pendingClipboardOscTimeout = 2 * DefaultEscTimeout t.Cleanup(func() { pendingClipboardOscTimeout = saved })
head := "\x1b]5522;type=read:status=DATA:id=x;QUJD" events := testReadInputs(t, &stalledReader{chunks: []string{head, "a"}, pause: 6 * DefaultEscTimeout}) want := []Event{UnknownEvent(head), KeyPressEvent{Code: 'a', Text: "a"}} if !reflect.DeepEqual(events, want) { t.Fatalf("events = %#v\nwant %#v", events, want) }}