diff --git a/go.mod b/go.mod index 9e46b24..6a2966b 100644 --- a/go.mod +++ b/go.mod @@ -6,4 +6,5 @@ require ( github.com/mattn/go-runewidth v0.0.13 github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 + github.com/stretchr/testify v1.7.1 ) diff --git a/go.sum b/go.sum index ba0a481..9e2e8e6 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= @@ -9,8 +11,17 @@ github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9Fn github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 h1:STjmj0uFfRryL9fzRA/OupNppeAID6QJYPMavTL7jtY= github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/style_test.go b/style_test.go index c1ee043..825fa7a 100644 --- a/style_test.go +++ b/style_test.go @@ -2,8 +2,249 @@ package lipgloss import ( "testing" + + "github.com/muesli/termenv" + "github.com/stretchr/testify/require" ) +func TestStyleRender(t *testing.T) { + t.Parallel() + + tt := []struct { + style Style + expected string + }{ + { + NewStyle().Foreground(Color("#5A56E0")), + "\x1b[38;2;89;86;224mhello\x1b[0m", + }, + { + NewStyle().Bold(true), + "\x1b[1mhello\x1b[0m", + }, + { + NewStyle().Italic(true), + "\x1b[3mhello\x1b[0m", + }, + { + NewStyle().Underline(true), + "\x1b[4;4mh\x1b[0m\x1b[4;4me\x1b[0m\x1b[4;4ml\x1b[0m\x1b[4;4ml\x1b[0m\x1b[4;4mo\x1b[0m", + }, + { + NewStyle().Blink(true), + "\x1b[5mhello\x1b[0m", + }, + { + NewStyle().Faint(true), + "\x1b[2mhello\x1b[0m", + }, + } + + SetColorProfile(termenv.TrueColor) + for i, tc := range tt { + res := tc.style.Render("hello") + if res != tc.expected { + t.Errorf("Test %d, expected:\n\n`%s`\n`%s`\n\nActual output:\n\n`%s`\n`%s`\n\n", + i, tc.expected, formatEscapes(tc.expected), + res, formatEscapes(res)) + } + } +} + +func TestValueCopy(t *testing.T) { + t.Parallel() + + s := NewStyle(). + Bold(true) + + i := s + i.Bold(false) + + require.Equal(t, s.GetBold(), i.GetBold()) +} + +func TestStyleInherit(t *testing.T) { + t.Parallel() + + s := NewStyle(). + Bold(true). + Italic(true). + Underline(true). + Strikethrough(true). + Blink(true). + Faint(true). + Foreground(Color("#ffffff")). + Background(Color("#111111")). + Margin(1, 1, 1, 1). + Padding(1, 1, 1, 1) + + i := NewStyle().Inherit(s) + + require.Equal(t, s.GetBold(), i.GetBold()) + require.Equal(t, s.GetItalic(), i.GetItalic()) + require.Equal(t, s.GetUnderline(), i.GetUnderline()) + require.Equal(t, s.GetStrikethrough(), i.GetStrikethrough()) + require.Equal(t, s.GetBlink(), i.GetBlink()) + require.Equal(t, s.GetFaint(), i.GetFaint()) + require.Equal(t, s.GetForeground(), i.GetForeground()) + require.Equal(t, s.GetBackground(), i.GetBackground()) + + require.NotEqual(t, s.GetMarginLeft(), i.GetMarginLeft()) + require.NotEqual(t, s.GetMarginRight(), i.GetMarginRight()) + require.NotEqual(t, s.GetMarginTop(), i.GetMarginTop()) + require.NotEqual(t, s.GetMarginBottom(), i.GetMarginBottom()) + require.NotEqual(t, s.GetPaddingLeft(), i.GetPaddingLeft()) + require.NotEqual(t, s.GetPaddingRight(), i.GetPaddingRight()) + require.NotEqual(t, s.GetPaddingTop(), i.GetPaddingTop()) + require.NotEqual(t, s.GetPaddingBottom(), i.GetPaddingBottom()) +} + +func TestStyleCopy(t *testing.T) { + t.Parallel() + + s := NewStyle(). + Bold(true). + Italic(true). + Underline(true). + Strikethrough(true). + Blink(true). + Faint(true). + Foreground(Color("#ffffff")). + Background(Color("#111111")). + Margin(1, 1, 1, 1). + Padding(1, 1, 1, 1) + + i := s.Copy() + + require.Equal(t, s.GetBold(), i.GetBold()) + require.Equal(t, s.GetItalic(), i.GetItalic()) + require.Equal(t, s.GetUnderline(), i.GetUnderline()) + require.Equal(t, s.GetStrikethrough(), i.GetStrikethrough()) + require.Equal(t, s.GetBlink(), i.GetBlink()) + require.Equal(t, s.GetFaint(), i.GetFaint()) + require.Equal(t, s.GetForeground(), i.GetForeground()) + require.Equal(t, s.GetBackground(), i.GetBackground()) + + require.Equal(t, s.GetMarginLeft(), i.GetMarginLeft()) + require.Equal(t, s.GetMarginRight(), i.GetMarginRight()) + require.Equal(t, s.GetMarginTop(), i.GetMarginTop()) + require.Equal(t, s.GetMarginBottom(), i.GetMarginBottom()) + require.Equal(t, s.GetPaddingLeft(), i.GetPaddingLeft()) + require.Equal(t, s.GetPaddingRight(), i.GetPaddingRight()) + require.Equal(t, s.GetPaddingTop(), i.GetPaddingTop()) + require.Equal(t, s.GetPaddingBottom(), i.GetPaddingBottom()) +} + +func TestStyleUnset(t *testing.T) { + t.Parallel() + + s := NewStyle().Bold(true) + require.True(t, s.GetBold()) + s.UnsetBold() + require.False(t, s.GetBold()) + + s = NewStyle().Italic(true) + require.True(t, s.GetItalic()) + s.UnsetItalic() + require.False(t, s.GetItalic()) + + s = NewStyle().Underline(true) + require.True(t, s.GetUnderline()) + s.UnsetUnderline() + require.False(t, s.GetUnderline()) + + s = NewStyle().Strikethrough(true) + require.True(t, s.GetStrikethrough()) + s.UnsetStrikethrough() + require.False(t, s.GetStrikethrough()) + + s = NewStyle().Reverse(true) + require.True(t, s.GetReverse()) + s.UnsetReverse() + require.False(t, s.GetReverse()) + + s = NewStyle().Blink(true) + require.True(t, s.GetBlink()) + s.UnsetBlink() + require.False(t, s.GetBlink()) + + s = NewStyle().Faint(true) + require.True(t, s.GetFaint()) + s.UnsetFaint() + require.False(t, s.GetFaint()) + + s = NewStyle().Inline(true) + require.True(t, s.GetInline()) + s.UnsetInline() + require.False(t, s.GetInline()) + + // colors + col := Color("#ffffff") + s = NewStyle().Foreground(col) + require.Equal(t, col, s.GetForeground()) + s.UnsetForeground() + require.NotEqual(t, col, s.GetForeground()) + + s = NewStyle().Background(col) + require.Equal(t, col, s.GetBackground()) + s.UnsetBackground() + require.NotEqual(t, col, s.GetBackground()) + + // margins + s = NewStyle().Margin(1, 2, 3, 4) + require.Equal(t, 1, s.GetMarginTop()) + s.UnsetMarginTop() + require.Equal(t, 0, s.GetMarginTop()) + + require.Equal(t, 2, s.GetMarginRight()) + s.UnsetMarginRight() + require.Equal(t, 0, s.GetMarginRight()) + + require.Equal(t, 3, s.GetMarginBottom()) + s.UnsetMarginBottom() + require.Equal(t, 0, s.GetMarginBottom()) + + require.Equal(t, 4, s.GetMarginLeft()) + s.UnsetMarginLeft() + require.Equal(t, 0, s.GetMarginLeft()) + + // padding + s = NewStyle().Padding(1, 2, 3, 4) + require.Equal(t, 1, s.GetPaddingTop()) + s.UnsetPaddingTop() + require.Equal(t, 0, s.GetPaddingTop()) + + require.Equal(t, 2, s.GetPaddingRight()) + s.UnsetPaddingRight() + require.Equal(t, 0, s.GetPaddingRight()) + + require.Equal(t, 3, s.GetPaddingBottom()) + s.UnsetPaddingBottom() + require.Equal(t, 0, s.GetPaddingBottom()) + + require.Equal(t, 4, s.GetPaddingLeft()) + s.UnsetPaddingLeft() + require.Equal(t, 0, s.GetPaddingLeft()) + + // border + s = NewStyle().Border(normalBorder, true, true, true, true) + require.True(t, s.GetBorderTop()) + s.UnsetBorderTop() + require.False(t, s.GetBorderTop()) + + require.True(t, s.GetBorderRight()) + s.UnsetBorderRight() + require.False(t, s.GetBorderRight()) + + require.True(t, s.GetBorderBottom()) + s.UnsetBorderBottom() + require.False(t, s.GetBorderBottom()) + + require.True(t, s.GetBorderLeft()) + s.UnsetBorderLeft() + require.False(t, s.GetBorderLeft()) +} + func BenchmarkStyleRender(b *testing.B) { s := NewStyle(). Bold(true).