package parse_test
import (
"os"
"testing"
"git.sr.ht/~rjarry/aerc/lib/parse"
"github.com/stretchr/testify/assert"
)
func TestParser(t *testing.T) {
//nolint:errcheck // we'll fail the test if this fails
_ = os.Setenv("COLORTERM", "truecolor")
tests := []struct {
name string
input string
expectedString string
expectedLen int
}{
{
name: "no style",
input: "hello, world",
expectedString: "hello, world",
expectedLen: 12,
},
{
name: "bold",
input: "\x1b[1mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[1mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "dim",
input: "\x1b[2mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[2mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "bold and dim",
input: "\x1b[1;2mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[1m\x1b[2mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "italic",
input: "\x1b[3mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[3mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "underline",
input: "\x1b[4mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[4mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "blink",
input: "\x1b[5mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[5mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "fast blink",
input: "\x1b[6mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[5mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "reverse",
input: "\x1b[7mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[7mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "hidden",
input: "\x1b[8mhello, world",
expectedString: "hello, world",
expectedLen: 12,
},
{
name: "strikethrough",
input: "\x1b[9mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[9mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "bold hello, normal world",
input: "\x1b[1mhello, \x1b[21mworld",
expectedString: "\x1b(B\x1b[m\x1b[1mhello, \x1b(B\x1b[mworld\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "bold hello, normal world v2",
input: "\x1b[1mhello, \x1b[mworld",
expectedString: "\x1b(B\x1b[m\x1b[1mhello, \x1b(B\x1b[mworld\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "8 bit color: foreground",
input: "\x1b[30mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[30mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "8 bit color: background",
input: "\x1b[41mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[41mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "8 bit color: foreground and background",
input: "\x1b[31;41mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[31;41mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "16 bit color: foreground",
input: "\x1b[90mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[90mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "16 bit color: background",
input: "\x1b[101mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[101mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "16 bit color: foreground and background",
input: "\x1b[91;101mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[91;101mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "256 color: foreground",
input: "\x1b[38;5;2mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[32mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "256 color: foreground",
input: "\x1b[38;5;132mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[38;5;132mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "256 color: background",
input: "\x1b[48;5;132mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[48;5;132mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "256 color: foreground and background",
input: "\x1b[38;5;20;48;5;20mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[38;5;20;48;5;20mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "256 color: background",
input: "\x1b[48;5;2mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[42mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "true color: foreground",
input: "\x1b[38;2;0;0;0mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[38;2;0;0;0mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "true color: foreground with color space",
input: "\x1b[38;2;;0;0;0mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[38;2;0;0;0mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "true color: foreground with color space and colons",
input: "\x1b[38:2::0:0:0mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[38;2;0;0;0mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "true color: background",
input: "\x1b[48;2;0;0;0mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[48;2;0;0;0mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "true color: background with color space",
input: "\x1b[48;2;;0;0;0mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[48;2;0;0;0mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
{
name: "true color: foreground and background",
input: "\x1b[38;2;200;200;200;48;2;0;0;0mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[38;2;200;200;200;48;2;0;0;0mhello, world\x1b(B\x1b[m",
expectedLen: 12,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
buf := parse.ParseANSI(test.input)
assert.Equal(t, test.expectedString, buf.String())
assert.Equal(t, test.expectedLen, buf.Len())
})
}
}
func TestTruncate(t *testing.T) {
tests := []struct {
name string
input string
expectedString string
}{
{
name: "no style, truncate at 5",
input: "hello, world",
expectedString: "hello",
},
{
name: "bold, truncate at 5",
input: "\x1b[1mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[1mhello\x1b(B\x1b[m",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
buf := parse.ParseANSI(test.input)
assert.Equal(t, test.expectedString, buf.Truncate(5, 0))
})
}
}
func TestTruncateHead(t *testing.T) {
tests := []struct {
name string
input string
expectedString string
expectedLen int
}{
{
name: "no style, truncate head at 5",
input: "hello, world",
expectedString: "world",
},
{
name: "bold, truncate head at 5",
input: "\x1b[1mhello, world",
expectedString: "\x1b(B\x1b[m\x1b[1mworld\x1b(B\x1b[m",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
buf := parse.ParseANSI(test.input)
assert.Equal(t, test.expectedString, buf.TruncateHead(5, 0))
})
}
}