mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-30 22:39:58 +02:00
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
This commit is contained in:
@@ -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
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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,
|
||||
|
@@ -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"}}
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
||||
|
@@ -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) {
|
||||
|
@@ -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
|
||||
|
@@ -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"}}
|
||||
|
@@ -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()
|
||||
}
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user