Skip to content

Commit

Permalink
Add style tests.
Browse files Browse the repository at this point in the history
Also this fixes charmbracelet#111.
  • Loading branch information
knz committed Sep 3, 2022
1 parent c8fa446 commit 5a991e5
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 7 deletions.
5 changes: 5 additions & 0 deletions get.go
Expand Up @@ -165,6 +165,11 @@ func (s Style) GetMarginLeft() int {
return s.getAsInt(marginLeftKey)
}

// GetMarginBackground returns the style's margin background color.
func (s Style) GetMarginBackground() TerminalColor {
return s.getAsColor(marginBackgroundKey)
}

// GetHorizontalMargins returns the style's left and right margins. Unset
// values are measured as 0.
func (s Style) GetHorizontalMargins() int {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -3,6 +3,7 @@ module github.com/charmbracelet/lipgloss
go 1.15

require (
github.com/knz/lipgloss-convert v0.1.1
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
Expand Down
17 changes: 17 additions & 0 deletions go.sum
@@ -1,3 +1,14 @@
github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/knz/lipgloss-convert v0.1.1 h1:11Wfcdif9jyyI5H3ohANyqkmIpVPjiBoGZdCzPWz9fA=
github.com/knz/lipgloss-convert v0.1.1/go.mod h1:S14GmtoiW/VAHqB7xEzuZOt0/G6GQ2dfjJN0fHpm30Q=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
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=
Expand All @@ -9,8 +20,14 @@ 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/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
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 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
106 changes: 103 additions & 3 deletions style_test.go
@@ -1,15 +1,115 @@
package lipgloss
package lipgloss_test

import (
"strings"
"testing"

"github.com/charmbracelet/lipgloss"
lipglossc "github.com/knz/lipgloss-convert"
)

func BenchmarkStyleRender(b *testing.B) {
s := NewStyle().
s := lipgloss.NewStyle().
Bold(true).
Foreground(Color("#ffffff"))
Foreground(lipgloss.Color("#ffffff"))

for i := 0; i < b.N; i++ {
s.Render("Hello world")
}
}

type S = lipgloss.Style

func TestStyle(t *testing.T) {
td := []struct {
changeStyle func(S) S
repr string
}{
{func(s S) S { return s.Align(0.5) }, `align: 0.5;`},
{func(s S) S { return s.Background(lipgloss.Color("#0f0")) }, `background: #0f0;`},
{func(s S) S { return s.Blink(true) }, `blink: true;`},
{func(s S) S { return s.Bold(true) }, `bold: true;`},
{func(s S) S { return s.BorderBottom(true) }, `border-bottom: true;`},
{func(s S) S { return s.BorderBottomBackground(lipgloss.Color("#0f0")) }, `border-bottom-background: #0f0;`},
{func(s S) S { return s.BorderBottomForeground(lipgloss.Color("#0f0")) }, `border-bottom-foreground: #0f0;`},
{func(s S) S { return s.BorderLeft(true) }, `border-left: true;`},
{func(s S) S { return s.BorderLeftBackground(lipgloss.Color("#0f0")) }, `border-left-background: #0f0;`},
{func(s S) S { return s.BorderLeftForeground(lipgloss.Color("#0f0")) }, `border-left-foreground: #0f0;`},
{func(s S) S { return s.BorderRight(true) }, `border-right: true;`},
{func(s S) S { return s.BorderRightBackground(lipgloss.Color("#0f0")) }, `border-right-background: #0f0;`},
{func(s S) S { return s.BorderRightForeground(lipgloss.Color("#0f0")) }, `border-right-foreground: #0f0;`},
{func(s S) S {
return s.BorderStyle(lipgloss.Border{"a", "b", "c", "d", "e", "f", "g", "h"})
}, `border-style: border("a","b","c","d","e","f","g","h");`},
{func(s S) S { return s.BorderTop(true) }, `border-top: true;`},
{func(s S) S { return s.BorderTopBackground(lipgloss.Color("#0f0")) }, `border-top-background: #0f0;`},
{func(s S) S { return s.BorderTopForeground(lipgloss.Color("#0f0")) }, `border-top-foreground: #0f0;`},
{func(s S) S {
return s.Border(lipgloss.Border{"a", "b", "c", "d", "e", "f", "g", "h"}, true)
}, `border-bottom: true; border-left: true; border-right: true; ` +
`border-style: border("a","b","c","d","e","f","g","h"); ` +
`border-top: true;`},
{func(s S) S { return s.BorderBackground(lipgloss.Color("#0f0")) }, `border-bottom-background: #0f0; border-left-background: #0f0; border-right-background: #0f0; border-top-background: #0f0;`},
{func(s S) S { return s.BorderForeground(lipgloss.Color("#0f0")) }, `border-bottom-foreground: #0f0; border-left-foreground: #0f0; border-right-foreground: #0f0; border-top-foreground: #0f0;`},

{func(s S) S { return s.ColorWhitespace(true) }, `color-whitespace: true;`},
{func(s S) S { return s.Faint(true) }, `faint: true;`},
{func(s S) S { return s.Foreground(lipgloss.Color("#0f0")) }, `foreground: #0f0;`},
{func(s S) S { return s.Height(3) }, `height: 3;`},
{func(s S) S { return s.Inline(true) }, `inline: true;`},
{func(s S) S { return s.Italic(true) }, `italic: true;`},
{func(s S) S { return s.Margin(1, 2, 3, 4) }, `margin-bottom: 3; margin-left: 4; margin-right: 2; margin-top: 1;`},
{func(s S) S { return s.MarginBottom(3) }, `margin-bottom: 3;`},
{func(s S) S { return s.MarginLeft(3) }, `margin-left: 3;`},
{func(s S) S { return s.MarginRight(3) }, `margin-right: 3;`},
{func(s S) S { return s.MarginTop(3) }, `margin-top: 3;`},
{func(s S) S { return s.MarginBackground(lipgloss.Color("#0f0")) }, `margin-background: #0f0;`},
{func(s S) S { return s.MaxHeight(3) }, `max-height: 3;`},
{func(s S) S { return s.MaxWidth(3) }, `max-width: 3;`},
{func(s S) S { return s.Padding(1, 2, 3, 4) }, `padding-bottom: 3; padding-left: 4; padding-right: 2; padding-top: 1;`},
{func(s S) S { return s.PaddingBottom(3) }, `padding-bottom: 3;`},
{func(s S) S { return s.PaddingLeft(3) }, `padding-left: 3;`},
{func(s S) S { return s.PaddingRight(3) }, `padding-right: 3;`},
{func(s S) S { return s.PaddingTop(3) }, `padding-top: 3;`},
{func(s S) S { return s.Reverse(true) }, `reverse: true;`},
{func(s S) S { return s.Strikethrough(true) }, `strikethrough: true;`},
{func(s S) S { return s.StrikethroughSpaces(true) }, `strikethrough-spaces: true;`},
{func(s S) S { return s.Underline(true) }, `underline: true;`},
{func(s S) S { return s.UnderlineSpaces(true) }, `underline-spaces: true;`},
{func(s S) S { return s.Width(3) }, `width: 3;`},
}

for _, tc := range td {
// Apply the style change and compare to the reference.
s := lipgloss.NewStyle()
s = tc.changeStyle(s)
repr := lipglossc.Export(s)
if repr != tc.repr {
t.Errorf("expected %q, got %q", tc.repr, repr)
continue
}

// Apply the unset function and assert the resulting style is
// empty.
r := strings.Split(tc.repr, ":")
if len(r) > 2 {
// Special case: border-background / border-foreground.
if strings.HasPrefix(r[0], "border-") && strings.HasSuffix(r[0], "ground") {
r[0] = "border-" + r[0][strings.LastIndexByte(r[0], '-')+1:]
} else {
// Special case: padding, margin, border etc.
r[0] = r[0][:strings.IndexByte(r[0], '-')]
}
}
unset := r[0] + ": unset"
u, err := lipglossc.Import(s, unset)
if err != nil {
t.Error(err)
continue
}
repr = lipglossc.Export(u)
if repr != "" {
t.Errorf("expected empty style, got %q", repr)
}
}
}
30 changes: 26 additions & 4 deletions unset.go
Expand Up @@ -111,15 +111,21 @@ func (s Style) UnsetColorWhitespace() Style {
return s
}

// UnsetMargins removes all margin style rules.
func (s Style) UnsetMargins() Style {
// UnsetMargin removes all margin style rules.
func (s Style) UnsetMargin() Style {
delete(s.rules, marginLeftKey)
delete(s.rules, marginRightKey)
delete(s.rules, marginTopKey)
delete(s.rules, marginBottomKey)
return s
}

// UnsetMargins is the old name for UnsetMargin.
// Preserved for compatibility.
func (s Style) UnsetMargins() Style {
return s.UnsetMargin()
}

// UnsetMarginLeft removes the left margin style rule, if set.
func (s Style) UnsetMarginLeft() Style {
delete(s.rules, marginLeftKey)
Expand Down Expand Up @@ -152,6 +158,16 @@ func (s Style) UnsetMarginBackground() Style {
return s
}

// UnsetBorder removes the border properties, if set.
func (s Style) UnsetBorder() Style {
delete(s.rules, borderTopKey)
delete(s.rules, borderBottomKey)
delete(s.rules, borderLeftKey)
delete(s.rules, borderRightKey)
delete(s.rules, borderStyleKey)
return s
}

// UnsetBorderStyle removes the border style rule, if set.
func (s Style) UnsetBorderStyle() Style {
delete(s.rules, borderStyleKey)
Expand Down Expand Up @@ -229,13 +245,19 @@ func (s Style) UnsetBorderBackground() Style {
return s
}

// UnsetBorderTopBackgroundColor removes the top border background color rule,
// UnsetBorderTopBackground removes the top border background color rule,
// if set.
func (s Style) UnsetBorderTopBackgroundColor() Style {
func (s Style) UnsetBorderTopBackground() Style {
delete(s.rules, borderTopBackgroundKey)
return s
}

// UnsetBorderTopBackgroundColor is an old name for UnsetBorderTopBackground.
// Preserved for compatibility.
func (s Style) UnsetBorderTopBackgroundColor() Style {
return s.UnsetBorderTopBackground()
}

// UnsetBorderRightBackground removes the right border background color
// rule, if set.
func (s Style) UnsetBorderRightBackground() Style {
Expand Down

0 comments on commit 5a991e5

Please sign in to comment.