1package client
2
3import (
4 "testing"
5
6 "github.com/stretchr/testify/require"
7)
8
9func TestResumeInputDecoder(t *testing.T) {
10 for _, tt := range []struct {
11 name, input string
12 cancel bool
13 }{
14 {"grouped ctrl-c", "text\x03tail", true},
15 {"paste escape followed by cancel", "\x1b[200~a\x1b\x1b[201~\x03", true},
16 {"back to back escape", "\x1b\x1b[27u", true},
17 {"ctrl-c in unfinished CSI", "\x1b[\x03", true},
18 {"kitty ctrl-c", "\x1b[99;5u", true},
19 {"kitty escape", "\x1b[27u", true},
20 {"arrow", "\x1b[A", false},
21 {"function", "\x1bOP", false},
22 {"paste", "\x1b[200~a\x03\x1b[27u\x1b[201~", false},
23 {"text", "hello", false},
24 {"alt enter", "\x1b\r", false},
25 {"alt tab", "\x1b\t", false},
26 } {
27 t.Run(tt.name, func(t *testing.T) {
28 for split := 0; split <= len(tt.input); split++ {
29 var d resumeInputDecoder
30 first, cancelled := d.feed([]byte(tt.input[:split]))
31 second := []byte(nil)
32 if !cancelled {
33 second, cancelled = d.feed([]byte(tt.input[split:]))
34 }
35 require.Equal(t, tt.cancel, cancelled, "split %d", split)
36 if !tt.cancel {
37 got := append(first, second...)
38 got = append(got, d.flush()...)
39 require.Equal(t, tt.input, string(got), "split %d", split)
40 }
41 }
42 })
43 }
44}
45
46func TestResumeInputDecoderUndecidedEscape(t *testing.T) {
47 var d resumeInputDecoder
48 held, cancel := d.feed([]byte("\x1b"))
49 require.Empty(t, held)
50 require.False(t, cancel)
51 require.True(t, d.loneEscape())
52 require.Equal(t, []byte{0x1b}, d.flush())
53 require.False(t, d.loneEscape())
54}