summaryrefslogtreecommitdiffstats
path: root/tpl/collections
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2022-06-06 09:48:40 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2022-06-07 13:02:58 +0200
commit0566bbf7c7f2898fcd1d6156b27733cd48aa0449 (patch)
tree69ee0bde4d334cb0565afd5fb4e17247c946aad9 /tpl/collections
parent534e7155bb504682a37f5663d8c913e439b11e07 (diff)
Fix raw TOML dates in where/eq
Note that this has only been a problem with "raw dates" in TOML files in /data and similar. The predefined front matter dates `.Date` etc. are converted to a Go Time and has worked fine even after upgrading to v2 of the go-toml lib. Fixes #9979
Diffstat (limited to 'tpl/collections')
-rw-r--r--tpl/collections/append_test.go4
-rw-r--r--tpl/collections/apply_test.go4
-rw-r--r--tpl/collections/collections.go16
-rw-r--r--tpl/collections/collections_test.go37
-rw-r--r--tpl/collections/complement_test.go4
-rw-r--r--tpl/collections/index_test.go4
-rw-r--r--tpl/collections/merge_test.go6
-rw-r--r--tpl/collections/reflect_helpers.go2
-rw-r--r--tpl/collections/sort.go11
-rw-r--r--tpl/collections/symdiff_test.go4
-rw-r--r--tpl/collections/where.go24
-rw-r--r--tpl/collections/where_test.go6
12 files changed, 71 insertions, 51 deletions
diff --git a/tpl/collections/append_test.go b/tpl/collections/append_test.go
index 02e46039f..232781522 100644
--- a/tpl/collections/append_test.go
+++ b/tpl/collections/append_test.go
@@ -18,7 +18,9 @@ import (
"testing"
qt "github.com/frankban/quicktest"
+ "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/deps"
+ "github.com/gohugoio/hugo/langs"
)
// Also see tests in common/collection.
@@ -26,7 +28,7 @@ func TestAppend(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
start any
diff --git a/tpl/collections/apply_test.go b/tpl/collections/apply_test.go
index 315f2bc85..2c7783fd9 100644
--- a/tpl/collections/apply_test.go
+++ b/tpl/collections/apply_test.go
@@ -21,7 +21,9 @@ import (
"testing"
qt "github.com/frankban/quicktest"
+ "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/deps"
+ "github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/output"
"github.com/gohugoio/hugo/tpl"
)
@@ -67,7 +69,7 @@ func (templateFinder) GetFunc(name string) (reflect.Value, bool) {
func TestApply(t *testing.T) {
t.Parallel()
c := qt.New(t)
- d := &deps.Deps{}
+ d := &deps.Deps{Language: langs.NewDefaultLanguage(config.New())}
d.SetTmpl(new(templateFinder))
ns := New(d)
diff --git a/tpl/collections/collections.go b/tpl/collections/collections.go
index 8fdc85275..299a504f4 100644
--- a/tpl/collections/collections.go
+++ b/tpl/collections/collections.go
@@ -31,6 +31,8 @@ import (
"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/helpers"
+ "github.com/gohugoio/hugo/langs"
+ "github.com/gohugoio/hugo/tpl/compare"
"github.com/spf13/cast"
)
@@ -41,14 +43,24 @@ func init() {
// New returns a new instance of the collections-namespaced template functions.
func New(deps *deps.Deps) *Namespace {
+ if deps.Language == nil {
+ panic("language must be set")
+ }
+
+ loc := langs.GetLocation(deps.Language)
+
return &Namespace{
- deps: deps,
+ loc: loc,
+ sortComp: compare.New(loc, true),
+ deps: deps,
}
}
// Namespace provides template functions for the "collections" namespace.
type Namespace struct {
- deps *deps.Deps
+ loc *time.Location
+ sortComp *compare.Namespace
+ deps *deps.Deps
}
// After returns all the items after the first N in a rangeable list.
diff --git a/tpl/collections/collections_test.go b/tpl/collections/collections_test.go
index bcc2855c7..fd78da6d4 100644
--- a/tpl/collections/collections_test.go
+++ b/tpl/collections/collections_test.go
@@ -40,7 +40,7 @@ func TestAfter(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
index any
@@ -97,7 +97,7 @@ func (g *tstGrouper2) Group(key any, items any) (any, error) {
func TestGroup(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
key any
@@ -187,7 +187,7 @@ func TestDelimit(t *testing.T) {
func TestDictionary(t *testing.T) {
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
values []any
@@ -226,7 +226,7 @@ func TestDictionary(t *testing.T) {
func TestReverse(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
s := []string{"a", "b", "c"}
reversed, err := ns.Reverse(s)
@@ -245,7 +245,7 @@ func TestEchoParam(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
a any
@@ -277,7 +277,7 @@ func TestFirst(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
limit any
@@ -315,7 +315,7 @@ func TestIn(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
l1 any
@@ -391,7 +391,7 @@ func TestIntersect(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
l1, l2 any
@@ -518,7 +518,7 @@ func TestLast(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
limit any
@@ -557,7 +557,7 @@ func TestLast(t *testing.T) {
func TestQuerify(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
params []any
@@ -591,7 +591,7 @@ func TestQuerify(t *testing.T) {
}
func BenchmarkQuerify(b *testing.B) {
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
params := []any{"a", "b", "c", "d", "f", " &"}
b.ResetTimer()
@@ -604,7 +604,7 @@ func BenchmarkQuerify(b *testing.B) {
}
func BenchmarkQuerifySlice(b *testing.B) {
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
params := []string{"a", "b", "c", "d", "f", " &"}
b.ResetTimer()
@@ -619,7 +619,7 @@ func BenchmarkQuerifySlice(b *testing.B) {
func TestSeq(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
args []any
@@ -663,7 +663,7 @@ func TestSeq(t *testing.T) {
func TestShuffle(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
seq any
@@ -703,7 +703,7 @@ func TestShuffle(t *testing.T) {
func TestShuffleRandomising(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
// Note that this test can fail with false negative result if the shuffle
// of the sequence happens to be the same as the original sequence. However
@@ -734,7 +734,7 @@ func TestShuffleRandomising(t *testing.T) {
func TestSlice(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
args []any
@@ -758,7 +758,7 @@ func TestUnion(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
l1 any
@@ -847,7 +847,7 @@ func TestUnion(t *testing.T) {
func TestUniq(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
l any
expect any
@@ -979,6 +979,7 @@ func newDeps(cfg config.Provider) *deps.Deps {
panic(err)
}
return &deps.Deps{
+ Language: l,
Cfg: cfg,
Fs: hugofs.NewMem(l),
ContentSpec: cs,
diff --git a/tpl/collections/complement_test.go b/tpl/collections/complement_test.go
index 92565bf28..6c13ab5c4 100644
--- a/tpl/collections/complement_test.go
+++ b/tpl/collections/complement_test.go
@@ -17,7 +17,9 @@ import (
"reflect"
"testing"
+ "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/deps"
+ "github.com/gohugoio/hugo/langs"
qt "github.com/frankban/quicktest"
)
@@ -34,7 +36,7 @@ func TestComplement(t *testing.T) {
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
s1 := []TstX{{A: "a"}, {A: "b"}, {A: "d"}, {A: "e"}}
s2 := []TstX{{A: "b"}, {A: "e"}}
diff --git a/tpl/collections/index_test.go b/tpl/collections/index_test.go
index b9d5127ee..662fe6f33 100644
--- a/tpl/collections/index_test.go
+++ b/tpl/collections/index_test.go
@@ -18,6 +18,8 @@ import (
"testing"
"github.com/gohugoio/hugo/common/maps"
+ "github.com/gohugoio/hugo/config"
+ "github.com/gohugoio/hugo/langs"
qt "github.com/frankban/quicktest"
"github.com/gohugoio/hugo/deps"
@@ -26,7 +28,7 @@ import (
func TestIndex(t *testing.T) {
t.Parallel()
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
for i, test := range []struct {
item any
diff --git a/tpl/collections/merge_test.go b/tpl/collections/merge_test.go
index 14cca1ddd..e7a383126 100644
--- a/tpl/collections/merge_test.go
+++ b/tpl/collections/merge_test.go
@@ -19,7 +19,9 @@ import (
"testing"
"github.com/gohugoio/hugo/common/maps"
+ "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/deps"
+ "github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/parser"
"github.com/gohugoio/hugo/parser/metadecoders"
@@ -27,7 +29,7 @@ import (
)
func TestMerge(t *testing.T) {
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
simpleMap := map[string]any{"a": 1, "b": 2}
@@ -161,7 +163,7 @@ func TestMerge(t *testing.T) {
func TestMergeDataFormats(t *testing.T) {
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
toml1 := `
V1 = "v1_1"
diff --git a/tpl/collections/reflect_helpers.go b/tpl/collections/reflect_helpers.go
index 4178850aa..a295441ec 100644
--- a/tpl/collections/reflect_helpers.go
+++ b/tpl/collections/reflect_helpers.go
@@ -16,7 +16,6 @@ package collections
import (
"fmt"
"reflect"
- "time"
"errors"
@@ -26,7 +25,6 @@ import (
var (
zero reflect.Value
errorType = reflect.TypeOf((*error)(nil)).Elem()
- timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
)
func numberToFloat(v reflect.Value) (float64, error) {
diff --git a/tpl/collections/sort.go b/tpl/collections/sort.go
index a0c2f815b..ce76a4522 100644
--- a/tpl/collections/sort.go
+++ b/tpl/collections/sort.go
@@ -25,8 +25,6 @@ import (
"github.com/spf13/cast"
)
-var sortComp = compare.New(true)
-
// Sort returns a sorted sequence.
func (ns *Namespace) Sort(seq any, args ...any) (any, error) {
if seq == nil {
@@ -51,7 +49,7 @@ func (ns *Namespace) Sort(seq any, args ...any) (any, error) {
collator := langs.GetCollator(ns.deps.Language)
// Create a list of pairs that will be used to do the sort
- p := pairList{Collator: collator, SortAsc: true, SliceType: sliceType}
+ p := pairList{Collator: collator, sortComp: ns.sortComp, SortAsc: true, SliceType: sliceType}
p.Pairs = make([]pair, seqv.Len())
var sortByField string
@@ -145,6 +143,7 @@ type pair struct {
// A slice of pairs that implements sort.Interface to sort by Value.
type pairList struct {
Collator *langs.Collator
+ sortComp *compare.Namespace
Pairs []pair
SortAsc bool
SliceType reflect.Type
@@ -159,16 +158,16 @@ func (p pairList) Less(i, j int) bool {
if iv.IsValid() {
if jv.IsValid() {
// can only call Interface() on valid reflect Values
- return sortComp.LtCollate(p.Collator, iv.Interface(), jv.Interface())
+ return p.sortComp.LtCollate(p.Collator, iv.Interface(), jv.Interface())
}
// if j is invalid, test i against i's zero value
- return sortComp.LtCollate(p.Collator, iv.Interface(), reflect.Zero(iv.Type()))
+ return p.sortComp.LtCollate(p.Collator, iv.Interface(), reflect.Zero(iv.Type()))
}
if jv.IsValid() {
// if i is invalid, test j against j's zero value
- return sortComp.LtCollate(p.Collator, reflect.Zero(jv.Type()), jv.Interface())
+ return p.sortComp.LtCollate(p.Collator, reflect.Zero(jv.Type()), jv.Interface())
}
return false
diff --git a/tpl/collections/symdiff_test.go b/tpl/collections/symdiff_test.go
index c781ca040..e5494d5a0 100644
--- a/tpl/collections/symdiff_test.go
+++ b/tpl/collections/symdiff_test.go
@@ -17,7 +17,9 @@ import (
"reflect"
"testing"
+ "github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/deps"
+ "github.com/gohugoio/hugo/langs"
qt "github.com/frankban/quicktest"
)
@@ -27,7 +29,7 @@ func TestSymDiff(t *testing.T) {
c := qt.New(t)
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
s1 := []TstX{{A: "a"}, {A: "b"}}
s2 := []TstX{{A: "a"}, {A: "e"}}
diff --git a/tpl/collections/where.go b/tpl/collections/where.go
index 8a9df445d..2cf7227a0 100644
--- a/tpl/collections/where.go
+++ b/tpl/collections/where.go
@@ -107,11 +107,10 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
fmv := mv.Float()
fmvp = &fmv
case reflect.Struct:
- switch v.Type() {
- case timeType:
- iv := toTimeUnix(v)
+ if hreflect.IsTime(v.Type()) {
+ iv := ns.toTimeUnix(v)
ivp = &iv
- imv := toTimeUnix(mv)
+ imv := ns.toTimeUnix(mv)
imvp = &imv
}
case reflect.Array, reflect.Slice:
@@ -167,12 +166,11 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
}
}
case reflect.Struct:
- switch v.Type() {
- case timeType:
- iv := toTimeUnix(v)
+ if hreflect.IsTime(v.Type()) {
+ iv := ns.toTimeUnix(v)
ivp = &iv
for i := 0; i < mv.Len(); i++ {
- ima = append(ima, toTimeUnix(mv.Index(i)))
+ ima = append(ima, ns.toTimeUnix(mv.Index(i)))
}
}
case reflect.Array, reflect.Slice:
@@ -508,12 +506,10 @@ func toString(v reflect.Value) (string, error) {
return "", errors.New("unable to convert value to string")
}
-func toTimeUnix(v reflect.Value) int64 {
- if v.Kind() == reflect.Interface {
- return toTimeUnix(v.Elem())
- }
- if v.Type() != timeType {
+func (ns *Namespace) toTimeUnix(v reflect.Value) int64 {
+ t, ok := hreflect.AsTime(v, ns.loc)
+ if !ok {
panic("coding error: argument must be time.Time type reflect Value")
}
- return hreflect.GetMethodByName(v, "Unix").Call([]reflect.Value{})[0].Int()
+ return t.Unix()
}
diff --git a/tpl/collections/where_test.go b/tpl/collections/where_test.go
index 395a90cb1..9a65de3d5 100644
--- a/tpl/collections/where_test.go
+++ b/tpl/collections/where_test.go
@@ -22,6 +22,8 @@ import (
"time"
"github.com/gohugoio/hugo/common/maps"
+ "github.com/gohugoio/hugo/config"
+ "github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/deps"
)
@@ -29,7 +31,7 @@ import (
func TestWhere(t *testing.T) {
t.Parallel()
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
type Mid struct {
Tst TstX
@@ -683,7 +685,7 @@ func TestWhere(t *testing.T) {
func TestCheckCondition(t *testing.T) {
t.Parallel()
- ns := New(&deps.Deps{})
+ ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
type expect struct {
result bool