File: parser_test.go

package info (click to toggle)
golang-github-charmbracelet-x 0.0~git20240809.9ab0ca0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,004 kB
  • sloc: sh: 55; makefile: 5
file content (109 lines) | stat: -rw-r--r-- 1,999 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package ansi

import (
	"os"
	"reflect"
	"testing"
)

type testCase struct {
	name     string
	input    string
	expected []Sequence
}

type testDispatcher struct {
	dispatched []Sequence
}

func (d *testDispatcher) Dispatch(s Sequence) {
	d.dispatched = append(d.dispatched, s.Clone())
}

func testParser(d *testDispatcher) *Parser {
	p := NewParser(16, 0)
	return p
}

func TestControlSequence(t *testing.T) {
	cases := []testCase{
		{
			name:  "just_esc",
			input: "\x1b",
			expected: []Sequence{
				ControlCode(0x1b),
			},
		},
		{
			name:  "double_esc",
			input: "\x1b\x1b",
			expected: []Sequence{
				ControlCode(0x1b),
				ControlCode(0x1b),
			},
		},
		{
			name:  "esc_bracket",
			input: "\x1b[",
			expected: []Sequence{
				EscSequence('['),
			},
		},
		{
			name:  "csi_rune_esc_bracket",
			input: "\x1b[1;2;3mabc\x1b\x1bP",
			expected: []Sequence{
				CsiSequence{
					Params: []int{1, 2, 3},
					Cmd:    'm',
				},
				Rune('a'),
				Rune('b'),
				Rune('c'),
				ControlCode(0x1b),
				EscSequence('P'),
			},
		},
	}
	for _, c := range cases {
		t.Run(c.name, func(t *testing.T) {
			dispatcher := &testDispatcher{}
			parser := testParser(dispatcher)
			parser.Parse(dispatcher.Dispatch, []byte(c.input))
			assertEqual(t, len(c.expected), len(dispatcher.dispatched))
			for i := range c.expected {
				assertEqual(t, c.expected[i], dispatcher.dispatched[i])
			}
		})
	}
}

func BenchmarkNext(bm *testing.B) {
	bts, err := os.ReadFile("./fixtures/demo.vte")
	if err != nil {
		bm.Fatalf("Error: %v", err)
	}

	bm.ResetTimer()

	var parser Parser
	parser.Parse(nil, bts)
}

func BenchmarkStateChanges(bm *testing.B) {
	input := "\x1b]2;X\x1b\\ \x1b[0m \x1bP0@\x1b\\"

	for i := 0; i < bm.N; i++ {
		var parser Parser
		for i := 0; i < 1000; i++ {
			parser.Parse(nil, []byte(input))
		}
	}
}

func assertEqual[T any](t *testing.T, expected, got T) {
	t.Helper()
	if !reflect.DeepEqual(expected, got) {
		t.Fatalf("expected:\n  %#v, got:\n  %#v", expected, got)
	}
}