From 7d9642523b06c20dcd4cc41cad1bd1543cd404ef Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sun, 27 May 2018 12:51:42 +0200 Subject: [PATCH] termstatus: Fix panic for non-terminal runs Closes #1803 --- internal/ui/termstatus/status.go | 22 +++++++++++++----- internal/ui/termstatus/status_test.go | 32 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 internal/ui/termstatus/status_test.go diff --git a/internal/ui/termstatus/status.go b/internal/ui/termstatus/status.go index 870fb9977..d997d6bb1 100644 --- a/internal/ui/termstatus/status.go +++ b/internal/ui/termstatus/status.go @@ -290,6 +290,20 @@ func (t *Terminal) Errorf(msg string, args ...interface{}) { t.Error(s) } +// truncate returns a string that has at most maxlen characters. If maxlen is +// negative, the empty string is returned. +func truncate(s string, maxlen int) string { + if maxlen < 0 { + return "" + } + + if len(s) < maxlen { + return s + } + + return s[:maxlen] +} + // SetStatus updates the status lines. func (t *Terminal) SetStatus(lines []string) { if len(lines) == 0 { @@ -297,7 +311,7 @@ func (t *Terminal) SetStatus(lines []string) { } width, _, err := getTermSize(t.fd) - if err != nil || width < 0 { + if err != nil || width <= 0 { // use 80 columns by default width = 80 } @@ -305,11 +319,7 @@ func (t *Terminal) SetStatus(lines []string) { // make sure that all lines have a line break and are not too long for i, line := range lines { line = strings.TrimRight(line, "\n") - - if len(line) >= width-2 { - line = line[:width-2] - } - line += "\n" + line = truncate(line, width-2) + "\n" lines[i] = line } diff --git a/internal/ui/termstatus/status_test.go b/internal/ui/termstatus/status_test.go new file mode 100644 index 000000000..6238d0532 --- /dev/null +++ b/internal/ui/termstatus/status_test.go @@ -0,0 +1,32 @@ +package termstatus + +import "testing" + +func TestTruncate(t *testing.T) { + var tests = []struct { + input string + maxlen int + output string + }{ + {"", 80, ""}, + {"", 0, ""}, + {"", -1, ""}, + {"foo", 80, "foo"}, + {"foo", 4, "foo"}, + {"foo", 3, "foo"}, + {"foo", 2, "fo"}, + {"foo", 1, "f"}, + {"foo", 0, ""}, + {"foo", -1, ""}, + } + + for _, test := range tests { + t.Run("", func(t *testing.T) { + out := truncate(test.input, test.maxlen) + if out != test.output { + t.Fatalf("wrong output for input %v, maxlen %d: want %q, got %q", + test.input, test.maxlen, test.output, out) + } + }) + } +}