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	"time"
22)
23
24// This terminfo entry is a stripped down version from
25// xterm-256color, but I've added some of my own entries.
26var testTerminfo = &Terminfo{
27	Name:      "simulation_test",
28	Columns:   80,
29	Lines:     24,
30	Colors:    256,
31	Bell:      "\a",
32	Blink:     "\x1b2ms$<20>something",
33	Reverse:   "\x1b[7m",
34	SetFg:     "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
35	SetBg:     "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
36	AltChars:  "``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
37	Mouse:     "\x1b[M",
38	MouseMode: "%?%p1%{1}%=%t%'h'%Pa%e%'l'%Pa%;\x1b[?1000%ga%c\x1b[?1003%ga%c\x1b[?1006%ga%c",
39	SetCursor: "\x1b[%i%p1%d;%p2%dH",
40	PadChar:   "\x00",
41}
42
43func TestTerminfoExpansion(t *testing.T) {
44
45	ti := testTerminfo
46
47	// Tests %i and basic parameter strings too
48	if ti.TGoto(7, 9) != "\x1b[10;8H" {
49		t.Error("TGoto expansion failed")
50	}
51
52	// This tests some conditionals
53	if ti.TParm("A[%p1%2.2X]B", 47) != "A[2F]B" {
54		t.Error("TParm conditionals failed")
55	}
56
57	// Color tests.
58	if ti.TParm(ti.SetFg, 7) != "\x1b[37m" {
59		t.Error("SetFg(7) failed")
60	}
61	if ti.TParm(ti.SetFg, 15) != "\x1b[97m" {
62		t.Error("SetFg(15) failed")
63	}
64	if ti.TParm(ti.SetFg, 200) != "\x1b[38;5;200m" {
65		t.Error("SetFg(200) failed")
66	}
67
68	if ti.TParm(ti.MouseMode, 1) != "\x1b[?1000h\x1b[?1003h\x1b[?1006h" {
69		t.Error("Enable mouse mode failed")
70	}
71	if ti.TParm(ti.MouseMode, 0) != "\x1b[?1000l\x1b[?1003l\x1b[?1006l" {
72		t.Error("Disable mouse mode failed")
73	}
74}
75
76func TestTerminfoDelay(t *testing.T) {
77	ti := testTerminfo
78	buf := bytes.NewBuffer(nil)
79	now := time.Now()
80	ti.TPuts(buf, ti.Blink, 19200)
81	then := time.Now()
82	s := string(buf.Bytes())
83	if s != "\x1b2mssomething" {
84		t.Errorf("Terminfo delay failed: %s", s)
85	}
86	if then.Sub(now) < time.Millisecond*20 {
87		t.Error("Too short delay")
88	}
89	if then.Sub(now) > time.Millisecond*50 {
90		t.Error("Too late delay")
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