summaryrefslogtreecommitdiff
path: root/internal/tui/tui_test.go
blob: a3640acd74f9176824006fbcc62f3356fef8b179 (plain) (blame)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// SPDX-License-Identifier: GPL-3.0-or-later

package tui

import (
	"bytes"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func TestColourNeedsTerminalAndNoNOCOLOR(t *testing.T) {
	var buf bytes.Buffer
	if Colour(&buf) {
		t.Error("colour on a non-terminal writer")
	}

	old := isTerminal
	t.Cleanup(func() { isTerminal = old })
	isTerminal = func(fd int) bool { return true }

	t.Setenv("NO_COLOR", "")
	os.Unsetenv("NO_COLOR")
	if !Colour(os.Stdout) {
		t.Error("no colour on a terminal with NO_COLOR unset")
	}
	t.Setenv("NO_COLOR", "1")
	if Colour(os.Stdout) {
		t.Error("colour emitted with NO_COLOR set")
	}
	t.Setenv("NO_COLOR", "")
	if Colour(os.Stdout) {
		t.Error("NO_COLOR set to the empty string must still disable colour")
	}
}

func TestHeight(t *testing.T) {
	var buf bytes.Buffer
	if h := height(&buf); h != 0 {
		t.Errorf("height on a non-terminal writer = %d, want 0", h)
	}

	oldT, oldS := isTerminal, termSize
	t.Cleanup(func() { isTerminal, termSize = oldT, oldS })
	isTerminal = func(fd int) bool { return true }
	termSize = func(fd int) (int, int, error) { return 80, 24, nil }

	if h := height(os.Stdout); h != 24 {
		t.Errorf("height = %d, want 24", h)
	}
}

func TestPageUsesPagerOnlyWhenTaller(t *testing.T) {
	dir := t.TempDir()
	marker := filepath.Join(dir, "paged")
	// A pager that records what it was given.
	t.Setenv("PAGER", "tee "+marker)

	oldT, oldS := isTerminal, termSize
	t.Cleanup(func() { isTerminal, termSize = oldT, oldS })
	isTerminal = func(fd int) bool { return true }
	termSize = func(fd int) (int, int, error) { return 80, 5, nil }

	var buf bytes.Buffer
	if err := Page(&buf, "one\ntwo\n"); err != nil {
		t.Fatal(err)
	}
	if _, err := os.Stat(marker); !os.IsNotExist(err) {
		t.Error("short text went through the pager")
	}
	if buf.String() != "one\ntwo\n" {
		t.Errorf("short text = %q", buf.String())
	}

	tall := strings.Repeat("line\n", 20)
	if err := Page(&buf, tall); err != nil {
		t.Fatal(err)
	}
	b, err := os.ReadFile(marker)
	if err != nil {
		t.Fatalf("tall text did not reach the pager: %v", err)
	}
	if string(b) != tall {
		t.Errorf("the pager received %q", b)
	}
}

func TestPageCountsFinalLineWithoutTrailingNewline(t *testing.T) {
	dir := t.TempDir()
	marker := filepath.Join(dir, "paged")
	t.Setenv("PAGER", "tee "+marker)

	oldT, oldS := isTerminal, termSize
	t.Cleanup(func() { isTerminal, termSize = oldT, oldS })
	isTerminal = func(fd int) bool { return true }
	termSize = func(fd int) (int, int, error) { return 80, 5, nil }

	// Six lines but only five newlines: one more line than the terminal's
	// height, with no trailing newline after the last one.
	text := "one\ntwo\nthree\nfour\nfive\nsix"

	var buf bytes.Buffer
	if err := Page(&buf, text); err != nil {
		t.Fatal(err)
	}
	b, err := os.ReadFile(marker)
	if err != nil {
		t.Fatalf("six lines with no trailing newline, one more than the terminal's height, did not reach the pager: %v", err)
	}
	if string(b) != text {
		t.Errorf("the pager received %q", b)
	}
}

func TestReadKeyOnAPipeReadsOneByte(t *testing.T) {
	r, w, err := os.Pipe()
	if err != nil {
		t.Fatal(err)
	}
	go func() { w.WriteString("ay"); w.Close() }()
	got, err := ReadKey(r)
	if err != nil {
		t.Fatal(err)
	}
	if got != 'a' {
		t.Errorf("key = %q, want 'a'", got)
	}
}