From d79bab2997350de8f7a8f7216eaa0599567775ae Mon Sep 17 00:00:00 2001 From: Savely Krasovsky Date: Fri, 21 Sep 2018 05:11:13 +0300 Subject: Fix invalid output when truncating Unicode text in templates --- template/functions.go | 15 ++++++--------- template/functions_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 template/functions_test.go (limited to 'template') diff --git a/template/functions.go b/template/functions.go index d20b445..13c57aa 100644 --- a/template/functions.go +++ b/template/functions.go @@ -5,7 +5,6 @@ package template // import "miniflux.app/template" import ( - "bytes" "html/template" "net/mail" "strings" @@ -80,15 +79,13 @@ func (f *funcMap) Map() template.FuncMap { }, "dict": dict, "truncate": func(str string, max int) string { - if len(str) > max { - var buffer bytes.Buffer - - buffer.WriteString(str[:max-1]) - buffer.WriteString("…") - - return buffer.String() + runes := 0 + for i := range str { + runes++ + if runes > max { + return str[:i] + "…" + } } - return str }, "theme_color": func(theme string) string { diff --git a/template/functions_test.go b/template/functions_test.go new file mode 100644 index 0000000..a475036 --- /dev/null +++ b/template/functions_test.go @@ -0,0 +1,48 @@ +// Copyright 2018 Frédéric Guillot. All rights reserved. +// Use of this source code is governed by the Apache 2.0 +// license that can be found in the LICENSE file. + +package template // import "miniflux.app/template" + +import ( + "testing" +) + +func TestTruncate(t *testing.T) { + fm := funcMap{} + if f, ok := fm.Map()["truncate"]; ok { + if truncate := f.(func(str string, max int) string); ok { + shortEnglishText := "Short text" + shortUnicodeText := "Короткий текст" + + // edge case + if truncate(shortEnglishText, len(shortEnglishText)) != shortEnglishText { + t.Fatal("Invalid truncation") + } + // real case + if truncate(shortEnglishText, 25) != shortEnglishText { + t.Fatal("Invalid truncation") + } + if truncate(shortUnicodeText, len(shortUnicodeText)) != shortUnicodeText { + t.Fatal("Invalid truncation") + } + if truncate(shortUnicodeText, 25) != shortUnicodeText { + t.Fatal("Invalid truncation") + } + + longEnglishText := "This is really pretty long English text" + longRussianText := "Это реально очень длинный русский текст" + + if truncate(longEnglishText, 25) != "This is really pretty lon…" { + t.Fatal("Invalid truncation") + } + if truncate(longRussianText, 25) != "Это реально очень длинный…" { + t.Fatal("Invalid truncation") + } + } else { + t.Fatal("Type assetion for this func is failed, check func, maybe it was changed") + } + } else { + t.Fatal("There is no such function in this map, check key, maybe it was changed") + } +} -- cgit v1.2.3