From 73a0bfdadbe3dc753021048ca5a1a59bc963605c Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Tue, 13 Nov 2018 17:26:04 +0100 Subject: [PATCH] fix symbols DisplaySize() + Align() + tests --- internal/clifmt/symbols.go | 30 ++++++++------- internal/clifmt/symbols_test.go | 66 ++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 14 deletions(-) diff --git a/internal/clifmt/symbols.go b/internal/clifmt/symbols.go index 4642edf..b9ecf96 100644 --- a/internal/clifmt/symbols.go +++ b/internal/clifmt/symbols.go @@ -47,25 +47,21 @@ func Align(s string) { s = strings.Join(tabs, " ") // 2. get real size - size := displaySize(s) - + size := DisplaySize(s) offset := alignOffset - if size > alignOffset-6 { + if size > alignOffset-2 { - for i, l := 0, len(s); i < l; i++ { // find when real size is right under - next := fmt.Sprintf("%s\033[0m… ", s[0:i+1]) - if displaySize(next) >= alignOffset-5 { + for i := len(s) - 1; i > 0; i-- { // find when real size is right under + next := fmt.Sprintf("%s\033[0m… ", s[0:i]) + + if DisplaySize(next) <= alignOffset { s = next + size = DisplaySize(s) break } } - size = displaySize(s) - - } else { - // fix - offset -= 2 } // 3. print string @@ -78,9 +74,10 @@ func Align(s string) { } var re = regexp.MustCompile(`(?m)\[(?:\d+;)*\d+m`) +var reDots = regexp.MustCompile(`(?m)…`) -// displaySize returns the real size escaping special characters -func displaySize(s string) int { +// DisplaySize returns the real size escaping special characters +func DisplaySize(s string) int { // 1. get actual size size := len(s) @@ -91,5 +88,12 @@ func displaySize(s string) int { size -= len(m) } + // 3. Remove unicode character (len of 3 instead of 1) + matches = reDots.FindAllString(s, -1) + for _, m := range matches { + size -= len(m) + size += 1 + } + return size } diff --git a/internal/clifmt/symbols_test.go b/internal/clifmt/symbols_test.go index d8b14c6..487476a 100644 --- a/internal/clifmt/symbols_test.go +++ b/internal/clifmt/symbols_test.go @@ -8,7 +8,7 @@ import ( var lastPrint = "" func mockupPrinter(format string, args ...interface{}) (int, error) { - lastPrint = fmt.Sprintf(format, args...) + lastPrint = fmt.Sprintf("%s%s", lastPrint, fmt.Sprintf(format, args...)) return 0, nil } @@ -33,6 +33,7 @@ func TestSpecial(t *testing.T) { for i, test := range tests { if test.Pre != nil { + lastPrint = "" test.Pre() test.Processed = lastPrint } @@ -43,3 +44,66 @@ func TestSpecial(t *testing.T) { } } +func TestAlign(t *testing.T) { + defaultPrinter = mockupPrinter + + tests := []struct { + Offset int + Text string + Expect string + }{ + {12, "1234567890 ", "1234567890 "}, + {12, "12345678901 ", "1234567890\033[0m… "}, + {12, "123456789012", "1234567890\033[0m… "}, + {12, "1234567890123", "1234567890\033[0m… "}, + } + + for i, test := range tests { + + lastPrint = "" + alignOffset = test.Offset + Align(test.Text) + + if DisplaySize(lastPrint) != alignOffset { + t.Errorf("[%d] expected output to be %d chars, got %d (%s)", i, alignOffset, DisplaySize(lastPrint), escape(lastPrint)) + } + + if lastPrint != test.Expect { + t.Errorf("[%d] expected '%s', got '%s'", i, escape(test.Expect), escape(lastPrint)) + } + + } +} + +func TestDisplaySize(t *testing.T) { + tests := []struct { + Text string + Expect int + }{ + {"", 0}, + {"\033[32m\033[0m", 0}, + {"\033[0;32m\033[0m", 0}, + + {"1", 1}, + {"\033[32m1\033[0m", 1}, + {"\033[0;32m1\033[0m", 1}, + {"\033[0;32m1\033[0m\033[0;32m\033[1;31m\033[0m", 1}, + + {"123", 3}, + {"…123", 4}, + {"123…", 4}, + {"…123…", 5}, + + {"123456789", 9}, + {"1234567890", 10}, + {"1234567890\033[0m… ", 12}, + } + + for i, test := range tests { + + if DisplaySize(test.Text) != test.Expect { + t.Errorf("[%d] expected output to be %d chars, got %d (%s)", i, test.Expect, DisplaySize(test.Text), escape(lastPrint)) + } + + } +}