Add test for TrimForSummary

This commit is contained in:
2025-11-16 17:56:18 +09:00
parent 714fca369e
commit 4eaa8f2a70
3 changed files with 208 additions and 28 deletions

View File

@@ -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

View File

@@ -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)
}

View 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)
}
}