Add test for TrimForSummary
This commit is contained in:
@@ -13,7 +13,6 @@ func Apply(cfg *config.Config, title string, text string) (string, string, strin
|
||||
}
|
||||
head := text[0]
|
||||
|
||||
|
||||
// Detect markup by very first character of input text.
|
||||
// * '=' : Creole
|
||||
// * '#' : Markdown
|
||||
|
||||
@@ -1,46 +1,54 @@
|
||||
package format
|
||||
|
||||
import "strings"
|
||||
import (
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// TrimForSummary trims text to specified length with ellipsis.
|
||||
// Spaces are compressed.
|
||||
func TrimForSummary(text string, length int) string {
|
||||
if length < 0 {
|
||||
// TrimForSummary trims text to specified rune length with ".." ellipsis.
|
||||
// It also compresses all whitespace (including tabs/newlines)
|
||||
// into single spaces.
|
||||
func TrimForSummary(text string, limit int) string {
|
||||
if limit < 0 {
|
||||
panic("program error")
|
||||
}
|
||||
if length < 1 {
|
||||
if limit < 1 {
|
||||
return ""
|
||||
}
|
||||
if length < 2 {
|
||||
|
||||
runeCount := utf8.RuneCountInString(text)
|
||||
|
||||
if limit < 2 {
|
||||
if runeCount < 2 {
|
||||
return text
|
||||
}
|
||||
return "."
|
||||
}
|
||||
|
||||
var buf strings.Builder
|
||||
overflowed := false
|
||||
space := false
|
||||
i := 0
|
||||
var (
|
||||
buf = make([]rune, 0, limit)
|
||||
prevSpace = false
|
||||
count = 0
|
||||
)
|
||||
|
||||
for _, r := range text {
|
||||
if i >= length-2 {
|
||||
overflowed = true
|
||||
break
|
||||
}
|
||||
if r == '\r' || r == '\n' || r == '\t' {
|
||||
if space {
|
||||
i++
|
||||
if unicode.IsSpace(r) {
|
||||
if prevSpace {
|
||||
continue
|
||||
}
|
||||
r = ' '
|
||||
space = true
|
||||
prevSpace = true
|
||||
} else {
|
||||
space = false
|
||||
prevSpace = false
|
||||
}
|
||||
buf.WriteRune(r)
|
||||
i++
|
||||
|
||||
if count >= limit-2 && count+2 < runeCount {
|
||||
return string(buf) + ".."
|
||||
}
|
||||
|
||||
buf = append(buf, r)
|
||||
count++
|
||||
}
|
||||
|
||||
if overflowed {
|
||||
return buf.String() + ".."
|
||||
} else {
|
||||
return buf.String()
|
||||
}
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
173
internal/format/summary_test.go
Normal file
173
internal/format/summary_test.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package format
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestTrimForSummaryCrash(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("expected panic, but function returned normally")
|
||||
}
|
||||
}()
|
||||
|
||||
text := "This is a test."
|
||||
_ = TrimForSummary(text, -1)
|
||||
}
|
||||
|
||||
func TestTrimForSummaryCrash2(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
defer func() {
|
||||
if r := recover(); r == nil {
|
||||
t.Errorf("expected panic, but function returned normally")
|
||||
}
|
||||
}()
|
||||
|
||||
text := "This is a test."
|
||||
_ = TrimForSummary(text, -10)
|
||||
}
|
||||
|
||||
func TestTrimForSummary(t *testing.T) {
|
||||
var text, got, want string
|
||||
|
||||
text = "This is a test."
|
||||
got = TrimForSummary(text, 0)
|
||||
want = ""
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 0) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "これはテストです。"
|
||||
got = TrimForSummary(text, 0)
|
||||
want = ""
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 0) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "This is a test."
|
||||
got = TrimForSummary(text, 1)
|
||||
want = "."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 1) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "これはテストです。"
|
||||
got = TrimForSummary(text, 1)
|
||||
want = "."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 1) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "A"
|
||||
got = TrimForSummary(text, 1)
|
||||
want = "A"
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 1) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "あ"
|
||||
got = TrimForSummary(text, 1)
|
||||
want = "あ"
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 1) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "This is a test."
|
||||
got = TrimForSummary(text, 2)
|
||||
want = ".."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 2) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "これはテストです。"
|
||||
got = TrimForSummary(text, 2)
|
||||
want = ".."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 2) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "AB"
|
||||
got = TrimForSummary(text, 2)
|
||||
want = "AB"
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 2) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "あい"
|
||||
got = TrimForSummary(text, 2)
|
||||
want = "あい"
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 2) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "This is a test."
|
||||
got = TrimForSummary(text, 3)
|
||||
want = "T.."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 3) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "これはテストです。"
|
||||
got = TrimForSummary(text, 3)
|
||||
want = "こ.."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 3) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "This is a test."
|
||||
got = TrimForSummary(text, 10)
|
||||
want = "This is .."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 10) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "これはテストです。"
|
||||
got = TrimForSummary(text, 5)
|
||||
want = "これは.."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 10) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "This is a test."
|
||||
got = TrimForSummary(text, 14)
|
||||
want = "This is a te.."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 14) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "これはテストです。"
|
||||
got = TrimForSummary(text, 8)
|
||||
want = "これはテスト.."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 14) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "This is a test."
|
||||
got = TrimForSummary(text, 15)
|
||||
want = "This is a test."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 15) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "これはテストです。"
|
||||
got = TrimForSummary(text, 9)
|
||||
want = "これはテストです。"
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 15) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "This is a test."
|
||||
got = TrimForSummary(text, 20)
|
||||
want = "This is a test."
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 20) = %s; want %s", got, want)
|
||||
}
|
||||
|
||||
text = "これはテストです。"
|
||||
got = TrimForSummary(text, 15)
|
||||
want = "これはテストです。"
|
||||
if got != want {
|
||||
t.Errorf("TrimForSummary(text, 20) = %s; want %s", got, want)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user