diff --git a/style.go b/style.go index 6bfb8be8..846b92f8 100644 --- a/style.go +++ b/style.go @@ -271,15 +271,15 @@ func (s Style) Render(strs ...string) string { maxWidth = s.getAsInt(maxWidthKey) maxHeight = s.getAsInt(maxHeightKey) - underlineSpaces = underline && s.getAsBool(underlineSpacesKey, true) - strikethroughSpaces = strikethrough && s.getAsBool(strikethroughSpacesKey, true) + underlineSpaces = s.getAsBool(underlineSpacesKey, false) || (underline && s.getAsBool(underlineSpacesKey, true)) + strikethroughSpaces = s.getAsBool(strikethroughSpacesKey, false) || (strikethrough && s.getAsBool(strikethroughSpacesKey, true)) // Do we need to style whitespace (padding and space outside // paragraphs) separately? styleWhitespace = reverse // Do we need to style spaces separately? - useSpaceStyler = underlineSpaces || strikethroughSpaces + useSpaceStyler = (underline && !underlineSpaces) || (strikethrough && !strikethroughSpaces) || underlineSpaces || strikethroughSpaces transform = s.getAsTransform(transformKey) ) diff --git a/style_test.go b/style_test.go index f22b3590..75366873 100644 --- a/style_test.go +++ b/style_test.go @@ -9,6 +9,84 @@ import ( "github.com/muesli/termenv" ) +func TestUnderline(t *testing.T) { + r := NewRenderer(io.Discard) + r.SetColorProfile(termenv.TrueColor) + r.SetHasDarkBackground(true) + t.Parallel() + + tt := []struct { + style Style + expected string + }{ + { + r.NewStyle().Underline(true), + "\x1b[4;4ma\x1b[0m\x1b[4;4mb\x1b[0m\x1b[4m \x1b[0m\x1b[4;4mc\x1b[0m", + }, + { + r.NewStyle().Underline(true).UnderlineSpaces(true), + "\x1b[4;4ma\x1b[0m\x1b[4;4mb\x1b[0m\x1b[4m \x1b[0m\x1b[4;4mc\x1b[0m", + }, + { + r.NewStyle().Underline(true).UnderlineSpaces(false), + "\x1b[4;4ma\x1b[0m\x1b[4;4mb\x1b[0m \x1b[4;4mc\x1b[0m", + }, + { + r.NewStyle().UnderlineSpaces(true), + "ab\x1b[4m \x1b[0mc", + }, + } + + for i, tc := range tt { + s := tc.style.Copy().SetString("ab c") + res := s.Render() + 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 TestStrikethrough(t *testing.T) { + r := NewRenderer(io.Discard) + r.SetColorProfile(termenv.TrueColor) + r.SetHasDarkBackground(true) + t.Parallel() + + tt := []struct { + style Style + expected string + }{ + { + r.NewStyle().Strikethrough(true), + "\x1b[9ma\x1b[0m\x1b[9mb\x1b[0m\x1b[9m \x1b[0m\x1b[9mc\x1b[0m", + }, + { + r.NewStyle().Strikethrough(true).StrikethroughSpaces(true), + "\x1b[9ma\x1b[0m\x1b[9mb\x1b[0m\x1b[9m \x1b[0m\x1b[9mc\x1b[0m", + }, + { + r.NewStyle().Strikethrough(true).StrikethroughSpaces(false), + "\x1b[9ma\x1b[0m\x1b[9mb\x1b[0m \x1b[9mc\x1b[0m", + }, + { + r.NewStyle().StrikethroughSpaces(true), + "ab\x1b[9m \x1b[0mc", + }, + } + + for i, tc := range tt { + s := tc.style.Copy().SetString("ab c") + res := s.Render() + 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 TestStyleRender(t *testing.T) { r := NewRenderer(io.Discard) r.SetColorProfile(termenv.TrueColor) @@ -154,7 +232,9 @@ func TestStyleInherit(t *testing.T) { requireEqual(t, s.GetBold(), i.GetBold()) requireEqual(t, s.GetItalic(), i.GetItalic()) requireEqual(t, s.GetUnderline(), i.GetUnderline()) + requireEqual(t, s.GetUnderlineSpaces(), i.GetUnderlineSpaces()) requireEqual(t, s.GetStrikethrough(), i.GetStrikethrough()) + requireEqual(t, s.GetStrikethroughSpaces(), i.GetStrikethroughSpaces()) requireEqual(t, s.GetBlink(), i.GetBlink()) requireEqual(t, s.GetFaint(), i.GetFaint()) requireEqual(t, s.GetForeground(), i.GetForeground()) @@ -191,7 +271,9 @@ func TestStyleCopy(t *testing.T) { requireEqual(t, s.GetBold(), i.GetBold()) requireEqual(t, s.GetItalic(), i.GetItalic()) requireEqual(t, s.GetUnderline(), i.GetUnderline()) + requireEqual(t, s.GetUnderlineSpaces(), i.GetUnderlineSpaces()) requireEqual(t, s.GetStrikethrough(), i.GetStrikethrough()) + requireEqual(t, s.GetStrikethroughSpaces(), i.GetStrikethroughSpaces()) requireEqual(t, s.GetBlink(), i.GetBlink()) requireEqual(t, s.GetFaint(), i.GetFaint()) requireEqual(t, s.GetForeground(), i.GetForeground()) @@ -226,11 +308,21 @@ func TestStyleUnset(t *testing.T) { s = s.UnsetUnderline() requireFalse(t, s.GetUnderline()) + s = NewStyle().UnderlineSpaces(true) + requireTrue(t, s.GetUnderlineSpaces()) + s = s.UnsetUnderlineSpaces() + requireFalse(t, s.GetUnderlineSpaces()) + s = NewStyle().Strikethrough(true) requireTrue(t, s.GetStrikethrough()) s = s.UnsetStrikethrough() requireFalse(t, s.GetStrikethrough()) + s = NewStyle().StrikethroughSpaces(true) + requireTrue(t, s.GetStrikethroughSpaces()) + s = s.UnsetStrikethroughSpaces() + requireFalse(t, s.GetStrikethroughSpaces()) + s = NewStyle().Reverse(true) requireTrue(t, s.GetReverse()) s = s.UnsetReverse()