diff --git a/modules/highlight/highlight_test.go b/modules/highlight/highlight_test.go index 5d371bb26c643..bd4aae6ee8288 100644 --- a/modules/highlight/highlight_test.go +++ b/modules/highlight/highlight_test.go @@ -80,9 +80,12 @@ c=2 for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - lines, err := File(tt.name, "", []byte(tt.code)) + out, err := File(tt.name, "", []byte(tt.code)) assert.NoError(t, err) - assert.EqualValues(t, strings.Join(tt.want, "\n"), strings.Join(lines, "\n")) + expected := strings.Join(tt.want, "\n") + actual := strings.Join(out, "\n") + assert.Equal(t, strings.Count(actual, "")) + assert.EqualValues(t, expected, actual) }) } } @@ -134,14 +137,22 @@ b='' {space} c=2 `), "{space}", " "), - want: strings.Split("def: \n a=1 \n \nb='' \n \nc=2", "\n"), + want: lines(` +def: + a=1 + +b='' + +c=2`), }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - lines := PlainText([]byte(tt.code)) - assert.EqualValues(t, strings.Join(tt.want, "\n"), strings.Join(lines, "\n")) + out := PlainText([]byte(tt.code)) + expected := strings.Join(tt.want, "\n") + actual := strings.Join(out, "\n") + assert.EqualValues(t, expected, actual) }) } } diff --git a/modules/util/util.go b/modules/util/util.go index 97ed56d3cf0ee..be60fe4b4bbdf 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -9,6 +9,7 @@ import ( "crypto/rand" "errors" "math/big" + "regexp" "strconv" "strings" @@ -192,6 +193,38 @@ func ToTitleCase(s string) string { return titleCaser.String(s) } +var ( + whitespaceOnly = regexp.MustCompile("(?m)^[ \t]+$") + leadingWhitespace = regexp.MustCompile("(?m)(^[ \t]*)(?:[^ \t\n])") +) + +// Dedent removes common indentation of a multi-line string along with whitespace around it +// Based on https://github.com/lithammer/dedent +func Dedent(s string) string { + var margin string + + s = whitespaceOnly.ReplaceAllString(s, "") + indents := leadingWhitespace.FindAllStringSubmatch(s, -1) + + for i, indent := range indents { + if i == 0 { + margin = indent[1] + } else if strings.HasPrefix(indent[1], margin) { + continue + } else if strings.HasPrefix(margin, indent[1]) { + margin = indent[1] + } else { + margin = "" + break + } + } + + if margin != "" { + s = regexp.MustCompile("(?m)^"+margin).ReplaceAllString(s, "") + } + return strings.TrimSpace(s) +} + // NumberIntoInt64 transform a given int into int64. func NumberIntoInt64(number interface{}) int64 { var value int64 diff --git a/modules/util/util_test.go b/modules/util/util_test.go index ca5bd87eaebe3..91b0ef9455e1d 100644 --- a/modules/util/util_test.go +++ b/modules/util/util_test.go @@ -225,3 +225,10 @@ func TestToTitleCase(t *testing.T) { assert.Equal(t, ToTitleCase(`foo bar baz`), `Foo Bar Baz`) assert.Equal(t, ToTitleCase(`FOO BAR BAZ`), `Foo Bar Baz`) } + +func TestDedent(t *testing.T) { + assert.Equal(t, Dedent(` + foo + bar + `), "foo\n\tbar") +}