Files
MujicaUI/terminal_test.go
T

193 lines
5.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package mujica
import (
"runtime"
"strings"
"testing"
"github.com/egoist/mygo/ui"
)
func TestTerminalStateText(t *testing.T) {
var s TerminalState
s.Resize(10, 3)
s.Write("hello\r\nwor")
s.Write("ld\x1b[31m!\x1b[0m")
if got := s.LineText(0); got != "hello" {
t.Fatalf("line 0 %q", got)
}
if got := s.LineText(1); got != "world!" {
t.Fatalf("line 1 %q", got)
}
if st := s.screen[1][5].st; st.FG.Index != 1 || st.FG.Kind == 0 {
t.Fatalf("'!' style %+v, want red", st)
}
if st := s.screen[1][4].st; st.FG.Kind != 0 {
t.Fatalf("'d' style %+v, want default", st)
}
}
func TestTerminalStateCursorAndErase(t *testing.T) {
var s TerminalState
s.Resize(10, 3)
s.Write("abcdef\x1b[3D")
if x, _ := s.Cursor(); x != 3 {
t.Fatalf("cursor after 3D at %d, want 3", x)
}
s.Write("\x1b[K")
if got := s.LineText(0); got != "abc" {
t.Fatalf("after erase-to-end %q", got)
}
s.Write("\x1b[2;4HX")
if got := s.LineText(1); got != " X" {
t.Fatalf("after CUP %q", got)
}
s.Write("\x1b[2J")
if s.LineText(0) != "" || s.LineText(1) != "" {
t.Fatal("2J left text")
}
// A sequence split across writes completes on the next one.
s.Write("\x1b[")
s.Write("1;1Hz")
if got := s.LineText(0); got != "z" {
t.Fatalf("split CUP gave %q", got)
}
}
func TestTerminalStateScrollback(t *testing.T) {
var s TerminalState
s.Resize(8, 2)
for _, l := range []string{"one", "two", "three", "four"} {
s.Write(l + "\r\n")
}
if s.Lines() != 5 || s.LineText(0) != "one" || s.LineText(3) != "four" {
t.Fatalf("lines %d: %q %q", s.Lines(), s.LineText(0), s.LineText(3))
}
s.ScrollBack(10)
if s.Offset() != 3 {
t.Fatalf("offset %d, want the 3 scrollback lines", s.Offset())
}
s.ScrollBack(-1)
if s.Offset() != 2 {
t.Fatalf("offset %d after scrolling down one", s.Offset())
}
}
func TestTerminalStateWrapsLongLines(t *testing.T) {
var s TerminalState
s.Resize(4, 3)
s.Write("abcdefg")
if s.LineText(0) != "abcd" || s.LineText(1) != "efg" {
t.Fatalf("wrapped %q %q", s.LineText(0), s.LineText(1))
}
}
func terminalTester(s *TerminalState, opts *TerminalOptions, typed *[]string) *ui.Tester {
opts.Input = func(d string) { *typed = append(*typed, d) }
return ui.NewTester(func(c *ui.Context) {
Use(c, Settings{})
Terminal(c, s, *opts).Size(400, 200)
}, 420, 220)
}
func TestTerminalInputAndResize(t *testing.T) {
var s TerminalState
var typed []string
var size [2]int
opts := TerminalOptions{Resized: func(cols, rows int) { size = [2]int{cols, rows} }}
tt := terminalTester(&s, &opts, &typed)
if size[0] < 30 || size[1] < 5 {
t.Fatalf("resize reported %v for a 400×200 view", size)
}
if cols, rows := s.Size(); cols != size[0] || rows != size[1] {
t.Fatalf("state %d×%d, reported %v", cols, rows, size)
}
tt.Key(0, ui.KeyTab)
if !tt.Focused("Terminal") {
t.Fatal("Tab did not focus the terminal")
}
tt.Type("ls")
tt.Key(0, ui.KeyEnter)
tt.Key(ui.Ctrl, ui.KeyC)
tt.Key(0, ui.KeyUp)
want := []string{"ls", "\r", "\x03", "\x1b[A"}
if strings.Join(typed, "|") != strings.Join(want, "|") {
t.Fatalf("typed %q, want %q", typed, want)
}
}
func TestTerminalSelectCopyPaste(t *testing.T) {
var s TerminalState
var typed []string
tt := terminalTester(&s, &TerminalOptions{}, &typed)
s.Write("alpha beta")
tt.Frame()
cw, _, _ := terminalMetrics(ui.Font{Family: "monospace", Size: 13})
y := float32(terminalPad + 5)
tt.Press(terminalPad+1+cw*0.5, y)
tt.Move(terminalPad+1+cw*4.5, y)
tt.Release(terminalPad+1+cw*4.5, y)
if got := s.Selection(); got != "alpha" {
t.Fatalf("selection %q, want alpha", got)
}
mod := ui.Super
if runtime.GOOS != "darwin" {
mod = ui.Ctrl | ui.Shift
}
tt.Key(mod, ui.KeyC)
if tt.Clipboard() != "alpha" {
t.Fatalf("clipboard %q", tt.Clipboard())
}
tt.SetClipboard("echo hi")
tt.Key(mod, ui.KeyV)
if len(typed) != 1 || typed[0] != "echo hi" {
t.Fatalf("paste sent %q", typed)
}
}
func TestTerminalDisabledSendsNothing(t *testing.T) {
var s TerminalState
var typed []string
tt := terminalTester(&s, &TerminalOptions{Disabled: true}, &typed)
tt.Key(0, ui.KeyTab)
tt.Type("x")
tt.Key(0, ui.KeyEnter)
if len(typed) != 0 {
t.Fatalf("disabled terminal sent %q", typed)
}
}
func TestTerminalScrollbackKeys(t *testing.T) {
var s TerminalState
var typed []string
tt := terminalTester(&s, &TerminalOptions{}, &typed)
for range 40 {
s.Write("line\r\n")
}
tt.Frame()
tt.Key(0, ui.KeyTab)
tt.Key(ui.Shift, ui.KeyPageUp)
if s.Offset() == 0 {
t.Fatal("Shift+PageUp did not scroll back")
}
tt.Type("q")
if s.Offset() != 0 {
t.Fatal("typing did not return to the bottom")
}
}
func TestTerminalSnapshot(t *testing.T) {
snapshot(t, "terminal", 420, 160, func(c *ui.Context) {
s := ui.Local(c.Root(), "snap", func() *TerminalState {
s := &TerminalState{}
s.Resize(50, 7)
s.Write("\x1b[1m~/court\x1b[0m $ ls\r\n\x1b[34mchronicles\x1b[0m decrees.txt \x1b[32mrun.sh\x1b[0m\r\n")
s.Write("\x1b[33mwarning:\x1b[0m ledger is \x1b[7mlocked\x1b[0m\r\n\x1b[31merror\x1b[0m: missing seal\r\n\x1b[1m~/court\x1b[0m $ ")
return s
})
ui.Column(c).Padding(12).Children(func() {
Terminal(c, *s, TerminalOptions{}).Height(136)
})
})
}