1// Copyright 2018 The TCell Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use file except in compliance with the License.
5// You may obtain a copy of the license at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package terminfo
16
17import (
18	"bytes"
19	"os"
20	"testing"
21)
22
23// This terminfo entry is a stripped down version from
24// xterm-256color, but I've added some of my own entries.
25var testTerminfo = &Terminfo{
26	Name:      "simulation_test",
27	Columns:   80,
28	Lines:     24,
29	Colors:    256,
30	Bell:      "\a",
31	Blink:     "\x1b2ms$<2>",
32	Reverse:   "\x1b[7m",
33	SetFg:     "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
34	SetBg:     "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
35	AltChars:  "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
36	Mouse:     "\x1b[M",
37	MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
38	SetCursor: "\x1b[%i%p1%d;%p2%dH",
39	PadChar:   "\x00",
40}
41
42func TestTerminfoExpansion(t *testing.T) {
43
44	ti := testTerminfo
45
46	// Tests %i and basic parameter strings too
47	if ti.TGoto(7, 9) != "\x1b[10;8H" {
48		t.Error("TGoto expansion failed")
49	}
50
51	// This tests some conditionals
52	if ti.TParm("A[%p1%2.2X]B", 47) != "A[2F]B" {
53		t.Error("TParm conditionals failed")
54	}
55
56	// Color tests.
57	if ti.TParm(ti.SetFg, 7) != "\x1b[37m" {
58		t.Error("SetFg(7) failed")
59	}
60	if ti.TParm(ti.SetFg, 15) != "\x1b[97m" {
61		t.Error("SetFg(15) failed")
62	}
63	if ti.TParm(ti.SetFg, 200) != "\x1b[38;5;200m" {
64		t.Error("SetFg(200) failed")
65	}
66
67	if ti.TParm(ti.MouseMode, 1) != "\x1b[?1000h\x1b[?1003h\x1b[?1006h" {
68		t.Error("Enable mouse mode failed")
69	}
70	if ti.TParm(ti.MouseMode, 0) != "\x1b[?1000l\x1b[?1003l\x1b[?1006l" {
71		t.Error("Disable mouse mode failed")
72	}
73}
74
75func TestTerminfoBaud19200(t *testing.T) {
76	ti := testTerminfo
77	buf := bytes.NewBuffer(nil)
78	ti.TPuts(buf, ti.Blink, 19200)
79	s := string(buf.Bytes())
80	if s != "\x1b2ms\x00\x00\x00\x00" {
81		t.Error("1920 baud failed")
82	}
83}
84func TestTerminfoBaud50(t *testing.T) {
85	ti := testTerminfo
86	buf := bytes.NewBuffer(nil)
87	ti.TPuts(buf, ti.Blink, 50)
88	s := string(buf.Bytes())
89	if s != "\x1b2ms" {
90		t.Error("50 baud failed")
91	}
92}
93
94func TestTerminfoBasic(t *testing.T) {
95
96	os.Setenv("TCELLDB", "testdata/test1")
97	ti, err := LookupTerminfo("test1")
98	if ti == nil || err != nil || ti.Columns != 80 {
99		t.Errorf("Failed test1 lookup: %v", err)
100	}
101
102	ti, err = LookupTerminfo("alias1")
103	if ti == nil || err != nil || ti.Columns != 80 {
104		t.Errorf("Failed alias1 lookup: %v", err)
105	}
106
107	os.Setenv("TCELLDB", "testdata")
108	ti, err = LookupTerminfo("test2")
109	if ti == nil || err != nil || ti.Columns != 80 {
110		t.Errorf("Failed test2 lookup: %v", err)
111	}
112	if len(ti.Aliases) != 1 || ti.Aliases[0] != "alias2" {
113		t.Errorf("Alias for test2 wrong")
114	}
115}
116
117func TestTerminfoBadName(t *testing.T) {
118
119	os.Setenv("TCELLDB", "testdata")
120	if ti, err := LookupTerminfo("test3"); err == nil || ti != nil {
121		t.Error("Bad name should not have resolved")
122	}
123}
124
125func TestTerminfoLoop(t *testing.T) {
126	os.Setenv("TCELLDB", "testdata")
127	if ti, err := LookupTerminfo("loop1"); ti != nil || err == nil {
128		t.Error("Loop loop1 should not have resolved")
129	}
130}
131
132func TestTerminfoGzip(t *testing.T) {
133
134	os.Setenv("TCELLDB", "testdata")
135	if ti, err := LookupTerminfo("test-gzip"); ti == nil || err != nil ||
136		ti.Columns != 80 {
137		t.Error("test-gzip filed")
138	}
139
140	if ti, err := LookupTerminfo("alias-gzip"); ti == nil || err != nil ||
141		ti.Columns != 80 {
142		t.Error("alias-gzip failed")
143	}
144}
145
146func TestTerminfoBadAlias(t *testing.T) {
147
148	os.Setenv("TCELLDB", "testdata")
149	if ti, err := LookupTerminfo("alias-none"); err == nil || ti != nil {
150		t.Errorf("Bad alias should not have worked")
151	}
152}
153
154func TestTerminfoCombined(t *testing.T) {
155
156	os.Setenv("TCELLDB", "testdata/combined")
157
158	var values = []struct {
159		name  string
160		lines int
161	}{
162		{"combined2", 102},
163		{"alias-comb1", 101},
164		{"combined3", 103},
165		{"combined1", 101},
166	}
167	for _, v := range values {
168		if ti, e := LookupTerminfo(v.name); e != nil || ti == nil ||
169			ti.Lines != v.lines {
170			t.Errorf("Combined terminal for %s wrong", v.name)
171		}
172	}
173}
174
175func BenchmarkSetFgBg(b *testing.B) {
176	ti := testTerminfo
177
178	for i := 0; i < b.N; i++ {
179		ti.TParm(ti.SetFg, 100, 200)
180		ti.TParm(ti.SetBg, 100, 200)
181	}
182}
183