Skip to content

Commit 84b5123

Browse files
committed
tpl/collections: Add an integration test for collections.D
Also * improve the handling if invalid input * add a sanity check for number of elements asked for in D (1000000).
1 parent 2912415 commit 84b5123

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

tpl/collections/collections.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,11 @@ func (ns *Namespace) Reverse(l any) (any, error) {
409409
return sliceCopy.Interface(), nil
410410
}
411411

412+
// Sanity check for slices created by Seq and D.
413+
const maxSeqSize = 1000000
414+
415+
var errSeqSizeExceedsLimit = errors.New("size of result exceeds limit")
416+
412417
// Seq creates a sequence of integers from args. It's named and used as GNU's seq.
413418
//
414419
// Examples:
@@ -462,14 +467,14 @@ func (ns *Namespace) Seq(args ...any) ([]int, error) {
462467
}
463468

464469
// sanity check
465-
if last < -100000 {
466-
return nil, errors.New("size of result exceeds limit")
470+
if last < -maxSeqSize {
471+
return nil, errSeqSizeExceedsLimit
467472
}
468473
size := ((last - first) / inc) + 1
469474

470475
// sanity check
471-
if size <= 0 || size > 2000 {
472-
return nil, errors.New("size of result exceeds limit")
476+
if size <= 0 || size > maxSeqSize {
477+
return nil, errSeqSizeExceedsLimit
473478
}
474479

475480
seq := make([]int, size)
@@ -536,6 +541,12 @@ type dKey struct {
536541
// See https://getkerf.wordpress.com/2016/03/30/the-best-algorithm-no-one-knows-about/
537542
func (ns *Namespace) D(seed, n, hi any) []int {
538543
key := dKey{seed: cast.ToUint64(seed), n: cast.ToInt(n), hi: cast.ToInt(hi)}
544+
if key.n <= 0 || key.hi <= 0 || key.n > key.hi {
545+
return nil
546+
}
547+
if key.n > maxSeqSize {
548+
panic(errSeqSizeExceedsLimit)
549+
}
539550
v, _ := ns.dCache.GetOrCreate(key, func() ([]int, error) {
540551
prng := rand.New(rand.NewPCG(key.seed, 0))
541552
result := make([]int, 0, key.n)

tpl/collections/collections_integration_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,3 +298,33 @@ All|{{ .Title }}|
298298

299299
b.AssertFileContent("public/index.html", "Len: 1|")
300300
}
301+
302+
func TestD(t *testing.T) {
303+
t.Parallel()
304+
files := `
305+
-- hugo.toml --
306+
-- layouts/home.html --
307+
{{ $p := site.RegularPages }}
308+
5 random pages: {{ range collections.D 42 5 ($p | len) }}{{ with (index $p .) }}{{ .RelPermalink }}|{{ end }}{{ end }}$
309+
-- content/a.md --
310+
-- content/b.md --
311+
-- content/c.md --
312+
-- content/d.md --
313+
-- content/e.md --
314+
-- content/f.md --
315+
-- content/g.md --
316+
-- content/h.md --
317+
-- content/i.md --
318+
-- content/j.md --
319+
-- content/k.md --
320+
-- content/l.md --
321+
-- content/m.md --
322+
-- content/n.md --
323+
-- content/o.md --
324+
-- content/p.md --
325+
326+
`
327+
b := hugolib.Test(t, files)
328+
329+
b.AssertFileContentExact("public/index.html", "5 random pages: /b/|/g/|/j/|/k/|/l/|$")
330+
}

tpl/collections/collections_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ func TestSeq(t *testing.T) {
536536
{[]any{1, -1, 2}, false},
537537
{[]any{2, 1, 1}, false},
538538
{[]any{2, 1, 1, 1}, false},
539-
{[]any{2001}, false},
539+
{[]any{-1000001}, false},
540540
{[]any{}, false},
541541
{[]any{0, -1000000}, false},
542542
{[]any{tstNoStringer{}}, false},
@@ -795,6 +795,15 @@ func TestD(t *testing.T) {
795795

796796
c.Assert(ns.D(42, 5, 100), qt.DeepEquals, []int{24, 34, 66, 82, 96})
797797
c.Assert(ns.D(31, 5, 100), qt.DeepEquals, []int{12, 37, 38, 69, 98})
798+
c.Assert(ns.D(42, 9, 10), qt.DeepEquals, []int{0, 1, 2, 3, 4, 6, 7, 8, 9})
799+
c.Assert(ns.D(42, 10, 10), qt.DeepEquals, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9})
800+
c.Assert(ns.D(42, 11, 10), qt.IsNil) // n > hi
801+
c.Assert(ns.D(42, -5, 100), qt.IsNil)
802+
c.Assert(ns.D(42, 0, 100), qt.IsNil)
803+
c.Assert(ns.D(42, 5, 0), qt.IsNil)
804+
c.Assert(ns.D(42, 5, -10), qt.IsNil)
805+
c.Assert(ns.D(42, 5, 3000000), qt.DeepEquals, []int{720363, 1041693, 2009179, 2489106, 2873969})
806+
c.Assert(func() { ns.D(31, 2000000, 3000000) }, qt.PanicMatches, "size of result exceeds limit")
798807
}
799808

800809
func BenchmarkD2(b *testing.B) {

0 commit comments

Comments
 (0)