From abae509d908bbf97129af556b1e8075889032eb5 Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Thu, 24 Oct 2024 18:39:32 -0400 Subject: [PATCH 1/4] fix: border size getters when implicit borders are present When a border style is set and no borders have been explicitly enabled or disabled, a border is implicitly applied to all sides of the block. Prior to this fix border size getters would incorrectly return 0 when an implicit border is set. This revision corrects that behavior. --- borders.go | 7 +------ get.go | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/borders.go b/borders.go index deb6b35a..a5e668d0 100644 --- a/borders.go +++ b/borders.go @@ -228,11 +228,6 @@ func HiddenBorder() Border { func (s Style) applyBorder(str string) string { var ( - topSet = s.isSet(borderTopKey) - rightSet = s.isSet(borderRightKey) - bottomSet = s.isSet(borderBottomKey) - leftSet = s.isSet(borderLeftKey) - border = s.getBorderStyle() hasTop = s.getAsBool(borderTopKey, false) hasRight = s.getAsBool(borderRightKey, false) @@ -252,7 +247,7 @@ func (s Style) applyBorder(str string) string { // If a border is set and no sides have been specifically turned on or off // render borders on all sides. - if border != noBorder && !(topSet || rightSet || bottomSet || leftSet) { + if s.implicitBorders() { hasTop = true hasRight = true hasBottom = true diff --git a/get.go b/get.go index 9c2f06fe..86dcf4d2 100644 --- a/get.go +++ b/get.go @@ -300,7 +300,7 @@ func (s Style) GetBorderTopWidth() int { // runes of varying widths, the widest rune is returned. If no border exists on // the top edge, 0 is returned. func (s Style) GetBorderTopSize() int { - if !s.getAsBool(borderTopKey, false) { + if !s.getAsBool(borderTopKey, false) && !s.implicitBorders() { return 0 } return s.getBorderStyle().GetTopSize() @@ -310,7 +310,7 @@ func (s Style) GetBorderTopSize() int { // runes of varying widths, the widest rune is returned. If no border exists on // the left edge, 0 is returned. func (s Style) GetBorderLeftSize() int { - if !s.getAsBool(borderLeftKey, false) { + if !s.getAsBool(borderLeftKey, false) && !s.implicitBorders() { return 0 } return s.getBorderStyle().GetLeftSize() @@ -320,7 +320,7 @@ func (s Style) GetBorderLeftSize() int { // contain runes of varying widths, the widest rune is returned. If no border // exists on the left edge, 0 is returned. func (s Style) GetBorderBottomSize() int { - if !s.getAsBool(borderBottomKey, false) { + if !s.getAsBool(borderBottomKey, false) && !s.implicitBorders() { return 0 } return s.getBorderStyle().GetBottomSize() @@ -330,7 +330,7 @@ func (s Style) GetBorderBottomSize() int { // contain runes of varying widths, the widest rune is returned. If no border // exists on the right edge, 0 is returned. func (s Style) GetBorderRightSize() int { - if !s.getAsBool(borderRightKey, false) { + if !s.getAsBool(borderRightKey, false) && !s.implicitBorders() { return 0 } return s.getBorderStyle().GetRightSize() @@ -519,6 +519,23 @@ func (s Style) getBorderStyle() Border { return s.borderStyle } +// Returns whether or not the style has implicit borders. This happens when +// a border style has been set but no border sides have been explicitly turned +// on or off. +func (s Style) implicitBorders() bool { + var ( + borderStyle = s.getBorderStyle() + topSet = s.isSet(borderTopKey) + rightSet = s.isSet(borderRightKey) + bottomSet = s.isSet(borderBottomKey) + leftSet = s.isSet(borderLeftKey) + ) + if borderStyle != noBorder && !(topSet || rightSet || bottomSet || leftSet) { + return true + } + return false +} + func (s Style) getAsTransform(propKey) func(string) string { if !s.isSet(transformKey) { return nil From f1b5ff5a2d57dac8f7c34f2249e161d2df9c02e5 Mon Sep 17 00:00:00 2001 From: bashbunni <15822994+bashbunni@users.noreply.github.com> Date: Tue, 19 Nov 2024 12:45:10 -0800 Subject: [PATCH 2/4] refactor: remove redundant conditional check --- get.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/get.go b/get.go index 86dcf4d2..86b2f762 100644 --- a/get.go +++ b/get.go @@ -530,7 +530,7 @@ func (s Style) implicitBorders() bool { bottomSet = s.isSet(borderBottomKey) leftSet = s.isSet(borderLeftKey) ) - if borderStyle != noBorder && !(topSet || rightSet || bottomSet || leftSet) { + return borderStyle != noBorder && !(topSet || rightSet || bottomSet || leftSet) return true } return false From 57433d8828e3ed67be943527e0681f8b1239bda0 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 20 Nov 2024 10:14:40 -0500 Subject: [PATCH 3/4] Update get.go --- get.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/get.go b/get.go index 86b2f762..422b4ce9 100644 --- a/get.go +++ b/get.go @@ -531,9 +531,6 @@ func (s Style) implicitBorders() bool { leftSet = s.isSet(borderLeftKey) ) return borderStyle != noBorder && !(topSet || rightSet || bottomSet || leftSet) - return true - } - return false } func (s Style) getAsTransform(propKey) func(string) string { From 16bb4767cc3bdf9dff1052669972f30f37003750 Mon Sep 17 00:00:00 2001 From: bashbunni Date: Wed, 20 Nov 2024 08:13:20 -0800 Subject: [PATCH 4/4] test: add border tests --- borders_test.go | 96 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 borders_test.go diff --git a/borders_test.go b/borders_test.go new file mode 100644 index 00000000..44b95d0c --- /dev/null +++ b/borders_test.go @@ -0,0 +1,96 @@ +package lipgloss + +import "testing" + +func TestStyle_GetBorderSizes(t *testing.T) { + tests := []struct { + name string + style Style + wantX int + wantY int + }{ + { + name: "Default style", + style: NewStyle(), + wantX: 0, + wantY: 0, + }, + { + name: "Border(NormalBorder())", + style: NewStyle().Border(NormalBorder()), + wantX: 2, + wantY: 2, + }, + { + name: "Border(NormalBorder(), true)", + style: NewStyle().Border(NormalBorder(), true), + wantX: 2, + wantY: 2, + }, + { + name: "Border(NormalBorder(), true, false)", + style: NewStyle().Border(NormalBorder(), true, false), + wantX: 0, + wantY: 2, + }, + { + name: "Border(NormalBorder(), true, true, false)", + style: NewStyle().Border(NormalBorder(), true, true, false), + wantX: 2, + wantY: 1, + }, + { + name: "Border(NormalBorder(), true, true, false, false)", + style: NewStyle().Border(NormalBorder(), true, true, false, false), + wantX: 1, + wantY: 1, + }, + { + name: "BorderTop(true).BorderStyle(NormalBorder())", + style: NewStyle().BorderTop(true).BorderStyle(NormalBorder()), + wantX: 0, + wantY: 1, + }, + { + name: "BorderStyle(NormalBorder())", + style: NewStyle().BorderStyle(NormalBorder()), + wantX: 2, + wantY: 2, + }, + { + name: "Custom BorderStyle", + style: NewStyle().BorderStyle(Border{Left: "123456789"}), + wantX: 1, // left and right borders are laid out vertically, one rune per row + wantY: 0, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotX := tt.style.GetHorizontalBorderSize() + if gotX != tt.wantX { + t.Errorf("Style.GetHorizontalBorderSize() got %d, want %d", gotX, tt.wantX) + } + + gotY := tt.style.GetVerticalBorderSize() + if gotY != tt.wantY { + t.Errorf("Style.GetVerticalBorderSize() got %d, want %d", gotY, tt.wantY) + } + + gotX = tt.style.GetHorizontalFrameSize() + if gotX != tt.wantX { + t.Errorf("Style.GetHorizontalFrameSize() got %d, want %d", gotX, tt.wantX) + } + + gotY = tt.style.GetVerticalFrameSize() + if gotY != tt.wantY { + t.Errorf("Style.GetVerticalFrameSize() got %d, want %d", gotY, tt.wantY) + } + + gotX, gotY = tt.style.GetFrameSize() + if gotX != tt.wantX || gotY != tt.wantY { + t.Errorf("Style.GetFrameSize() got (%d, %d), want (%d, %d)", gotX, gotY, tt.wantX, tt.wantY) + } + }) + } +}