Files
ctrld/cmd/cli/log_reader_ansi_test.go
T

70 lines
2.2 KiB
Go

package cli
import (
"io"
"strings"
"testing"
)
// splitReader yields its text in the pieces that the test names, one piece
// for each Read, so a test puts a chunk boundary where it wants one.
type splitReader struct {
pieces []string
}
func (r *splitReader) Read(p []byte) (int, error) {
if len(r.pieces) == 0 {
return 0, io.EOF
}
n := copy(p, r.pieces[0])
if n < len(r.pieces[0]) {
r.pieces[0] = r.pieces[0][n:]
} else {
r.pieces = r.pieces[1:]
}
return n, nil
}
func Test_ansiStripReader_stripsSequencesSplitAcrossReads(t *testing.T) {
const red, reset = "\x1b[31m", "\x1b[0m"
for _, tc := range []struct {
name string
pieces []string
want string
}{
{"one read", []string{"a " + red + "b" + reset + " c"}, "a b c"},
{"split after the escape byte", []string{"a \x1b", "[31mb" + reset}, "a b"},
{"split after the bracket", []string{"a \x1b[", "31mb"}, "a b"},
{"split inside the parameters", []string{"a \x1b[3", "1mb"}, "a b"},
{"split before the final byte", []string{"a \x1b[31", "mb"}, "a b"},
{"two sequences in a row across a read", []string{"a " + red + "\x1b[", "1mb"}, "a b"},
{"sequence open at the end of the source", []string{"a \x1b[31"}, "a \x1b[31"},
{"lone escape at the end of the source", []string{"a \x1b"}, "a \x1b"},
{"escape that starts no color sequence", []string{"a \x1bXb"}, "a \x1bXb"},
{"letters inside the parameters stay", []string{"a \x1b[inva", "lidm b"}, "a \x1b[invalidm b"},
{"empty source", nil, ""},
} {
t.Run(tc.name, func(t *testing.T) {
got, err := io.ReadAll(newANSIStripReader(&splitReader{pieces: tc.pieces}))
if err != nil {
t.Fatalf("read: %v", err)
}
if string(got) != tc.want {
t.Fatalf("got %q, want %q", got, tc.want)
}
})
}
}
func Test_ansiStripReader_holdsALongTailAcrossTheChunkSize(t *testing.T) {
// The escape byte lands as the last byte of one chunk.
head := strings.Repeat("x", ansiStripChunkSize-1)
got, err := io.ReadAll(newANSIStripReader(&splitReader{pieces: []string{head + "\x1b", "[32my"}}))
if err != nil {
t.Fatalf("read: %v", err)
}
if string(got) != head+"y" {
t.Fatalf("got %d bytes ending in %q, want the text without the color", len(got), got[len(got)-4:])
}
}