From aaa46b5372b748da982aa7f77635d0be772847ae Mon Sep 17 00:00:00 2001 From: Richard Hull Date: Sat, 8 Nov 2025 00:48:27 +0000 Subject: [PATCH 1/2] test: Test empty string input handling Adds a test case to `TestStringWrap` to verify that an empty string input correctly yields an empty string output. --- stringwrap_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/stringwrap_test.go b/stringwrap_test.go index 0231184..44c03fa 100644 --- a/stringwrap_test.go +++ b/stringwrap_test.go @@ -129,6 +129,13 @@ func TestStringWrap(t *testing.T) { trimWhitespace: true, splitWord: true, }, + { + input: "", + wrapped: "", + limit: 5, + trimWhitespace: true, + splitWord: true, + }, } for idx, tt := range tests { From 4b4b23fbd981a53184c757b04b61313fedcb9292 Mon Sep 17 00:00:00 2001 From: Richard Hull Date: Sat, 8 Nov 2025 10:21:19 +0000 Subject: [PATCH 2/2] fix: sidestep panic accessing last wrapped line of empty sequence The function `lastWrappedLine` is updated to safely return `nil` if the internal sequence of wrapped lines is empty, avoiding a runtime panic (index out of bounds). The main wrapping logic now checks for a `nil` return before accessing the line properties. Testing logic for zero-length wrapped strings was also fixed to correctly assert line counts for empty output. --- stringwrap.go | 8 ++++++-- stringwrap_test.go | 6 +++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/stringwrap.go b/stringwrap.go index bedf92e..ab9c8d8 100644 --- a/stringwrap.go +++ b/stringwrap.go @@ -89,7 +89,11 @@ type WrappedStringSeq struct { // lastWrappedLine pulls the last wrapped line that has been parsed func (s *WrappedStringSeq) lastWrappedLine() *WrappedString { - return &s.WrappedLines[len(s.WrappedLines)-1] + n := len(s.WrappedLines) + if n == 0 { + return nil + } + return &s.WrappedLines[n-1] } // appendWrappedSeq adds a new WrappedString to the existing slice @@ -489,7 +493,7 @@ func stringWrap( // remove the last new line from the wrapped buffer // if the last line is not a hard break. lastWrappedLine := wrappedStringSeq.lastWrappedLine() - if !lastWrappedLine.IsHardBreak { + if lastWrappedLine != nil && !lastWrappedLine.IsHardBreak { stateMachine.buffer.Truncate(stateMachine.buffer.Len() - 1) lastWrappedLine.LastSegmentInOrig = true } diff --git a/stringwrap_test.go b/stringwrap_test.go index 44c03fa..e400575 100644 --- a/stringwrap_test.go +++ b/stringwrap_test.go @@ -141,8 +141,12 @@ func TestStringWrap(t *testing.T) { for idx, tt := range tests { t.Run(fmt.Sprintf("Wrapped String Test %d", idx+1), func(t *testing.T) { wrapped, seq, err := wrapString(tt) + expectedLines := 0 + if wrapped != "" { + expectedLines = len(strings.Split(wrapped, "\n")) + } assert.Nil(t, err) - assert.Equal(t, len(seq.WrappedLines), len(strings.Split(wrapped, "\n"))) + assert.Equal(t, expectedLines, len(seq.WrappedLines)) assert.Equal(t, tt.wrapped, wrapped) }) }