From f91892b8f1180f43c6b0cf18cc118d42f3648a1a Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sat, 30 Oct 2021 20:15:50 +1100 Subject: [PATCH] fix truncation --- pkg/utils/formatting.go | 16 ++++++++ pkg/utils/formatting_test.go | 73 +++++++++++++++++++++++++++++++++++- pkg/utils/utils.go | 27 ------------- 3 files changed, 88 insertions(+), 28 deletions(-) diff --git a/pkg/utils/formatting.go b/pkg/utils/formatting.go index 45836da61..55c04c85f 100644 --- a/pkg/utils/formatting.go +++ b/pkg/utils/formatting.go @@ -66,3 +66,19 @@ func getPadWidths(stringArrays [][]string) []int { } return padWidths } + +// TruncateWithEllipsis returns a string, truncated to a certain length, with an ellipsis +func TruncateWithEllipsis(str string, limit int) string { + if runewidth.StringWidth(str) > limit && limit <= 3 { + return strings.Repeat(".", limit) + } + return runewidth.Truncate(str, limit, "...") +} + +func SafeTruncate(str string, limit int) string { + if len(str) > limit { + return str[0:limit] + } else { + return str + } +} diff --git a/pkg/utils/formatting_test.go b/pkg/utils/formatting_test.go index 66fdfffad..c07f1ed22 100644 --- a/pkg/utils/formatting_test.go +++ b/pkg/utils/formatting_test.go @@ -58,7 +58,6 @@ func TestGetPaddedDisplayStrings(t *testing.T) { } } -// TestGetPadWidths is a function. func TestGetPadWidths(t *testing.T) { type scenario struct { input [][]string @@ -91,3 +90,75 @@ func TestGetPadWidths(t *testing.T) { } } } + +func TestTruncateWithEllipsis(t *testing.T) { + // will need to check chinese characters as well + // important that we have a three dot ellipsis within the limit + type scenario struct { + str string + limit int + expected string + } + + scenarios := []scenario{ + { + "hello world !", + 1, + ".", + }, + { + "hello world !", + 2, + "..", + }, + { + "hello world !", + 3, + "...", + }, + { + "hello world !", + 4, + "h...", + }, + { + "hello world !", + 5, + "he...", + }, + { + "hello world !", + 12, + "hello wor...", + }, + { + "hello world !", + 13, + "hello world !", + }, + { + "hello world !", + 14, + "hello world !", + }, + { + "大大大大", + 5, + "大...", + }, + { + "大大大大", + 2, + "..", + }, + { + "大大大大", + 0, + "", + }, + } + + for _, s := range scenarios { + assert.EqualValues(t, s.expected, TruncateWithEllipsis(s.str, s.limit)) + } +} diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 7b5a3071c..67debdf3a 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -68,33 +68,6 @@ func ModuloWithWrap(n, max int) int { } } -// TruncateWithEllipsis returns a string, truncated to a certain length, with an ellipsis -func TruncateWithEllipsis(str string, limit int) string { - if limit == 1 && len(str) > 1 { - return "." - } - - if limit == 2 && len(str) > 2 { - return ".." - } - - ellipsis := "..." - if len(str) <= limit { - return str - } - - remainingLength := limit - len(ellipsis) - return str[0:remainingLength] + "..." -} - -func SafeTruncate(str string, limit int) string { - if len(str) > limit { - return str[0:limit] - } else { - return str - } -} - func FindStringSubmatch(str string, regexpStr string) (bool, []string) { re := regexp.MustCompile(regexpStr) match := re.FindStringSubmatch(str)