diff options
Diffstat (limited to 'tpl/strings')
-rw-r--r-- | tpl/strings/init.go | 7 | ||||
-rw-r--r-- | tpl/strings/strings.go | 21 | ||||
-rw-r--r-- | tpl/strings/strings_test.go | 36 |
3 files changed, 64 insertions, 0 deletions
diff --git a/tpl/strings/init.go b/tpl/strings/init.go index 54009b897..883ce76d1 100644 --- a/tpl/strings/init.go +++ b/tpl/strings/init.go @@ -158,6 +158,13 @@ func init() { }, ) + ns.AddMethodMapping(ctx.Repeat, + nil, + [][2]string{ + {`{{ "yo" | strings.Repeat 4 }}`, `yoyoyoyo`}, + }, + ) + ns.AddMethodMapping(ctx.ToUpper, []string{"upper"}, [][2]string{ diff --git a/tpl/strings/strings.go b/tpl/strings/strings.go index 6d423391f..796b8ff62 100644 --- a/tpl/strings/strings.go +++ b/tpl/strings/strings.go @@ -17,6 +17,7 @@ import ( "errors" "fmt" "html/template" + "math" _strings "strings" "unicode/utf8" @@ -417,3 +418,23 @@ func (ns *Namespace) TrimSuffix(suffix, s interface{}) (string, error) { return _strings.TrimSuffix(ss, sx), nil } + +// Repeat returns a new string consisting of count copies of the string s. +// The count is limited to an in16 value (up to 32767). +func (ns *Namespace) Repeat(n, s interface{}) (string, error) { + ss, err := cast.ToStringE(s) + if err != nil { + return "", err + } + + sn, err := cast.ToIntE(n) + if err != nil { + return "", err + } + + if sn > math.MaxInt16 { + return "", fmt.Errorf("Cannot repeat string more than %d times", math.MaxInt16) + } + + return _strings.Repeat(ss, sn), nil +} diff --git a/tpl/strings/strings_test.go b/tpl/strings/strings_test.go index 91e71fd01..bf19ad562 100644 --- a/tpl/strings/strings_test.go +++ b/tpl/strings/strings_test.go @@ -16,6 +16,7 @@ package strings import ( "fmt" "html/template" + "math" "testing" "github.com/gohugoio/hugo/deps" @@ -709,3 +710,38 @@ func TestTrimSuffix(t *testing.T) { assert.Equal(t, test.expect, result, errMsg) } } + +func TestRepeat(t *testing.T) { + t.Parallel() + + for i, test := range []struct { + s interface{} + n interface{} + expect interface{} + }{ + {"yo", "2", "yoyo"}, + {"~", "16", "~~~~~~~~~~~~~~~~"}, + {"<tag>", "0", ""}, + {"yay", "1", "yay"}, + {1221, "1", "1221"}, + {1221, 2, "12211221"}, + {template.HTML("<tag>"), "2", "<tag><tag>"}, + {[]byte("<tag>"), 2, "<tag><tag>"}, + // errors + {"", tstNoStringer{}, false}, + {tstNoStringer{}, "", false}, + {"hi", math.MaxInt16 + 1, false}, + } { + errMsg := fmt.Sprintf("[%d] %v", i, test) + + result, err := ns.Repeat(test.n, test.s) + + if b, ok := test.expect.(bool); ok && !b { + require.Error(t, err, errMsg) + continue + } + + require.NoError(t, err, errMsg) + assert.Equal(t, test.expect, result, errMsg) + } +} |