mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05: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:
parent
534e7155bb
commit
0566bbf7c7
18 changed files with 216 additions and 87 deletions
|
@ -20,7 +20,9 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gohugoio/hugo/common/htime"
|
||||||
"github.com/gohugoio/hugo/common/types"
|
"github.com/gohugoio/hugo/common/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -168,6 +170,44 @@ func GetMethodIndexByName(tp reflect.Type, name string) int {
|
||||||
return m.Index
|
return m.Index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
|
||||||
|
asTimeProviderType = reflect.TypeOf((*htime.AsTimeProvider)(nil)).Elem()
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsTime returns whether tp is a time.Time type or if it can be converted into one
|
||||||
|
// in ToTime.
|
||||||
|
func IsTime(tp reflect.Type) bool {
|
||||||
|
if tp == timeType {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if tp.Implements(asTimeProviderType) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsTime returns v as a time.Time if possible.
|
||||||
|
// The given location is only used if the value implements AsTimeProvider (e.g. go-toml local).
|
||||||
|
// A zero Time and false is returned if this isn't possible.
|
||||||
|
// Note that this function does not accept string dates.
|
||||||
|
func AsTime(v reflect.Value, loc *time.Location) (time.Time, bool) {
|
||||||
|
if v.Kind() == reflect.Interface {
|
||||||
|
return AsTime(v.Elem(), loc)
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Type() == timeType {
|
||||||
|
return v.Interface().(time.Time), true
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Type().Implements(asTimeProviderType) {
|
||||||
|
return v.Interface().(htime.AsTimeProvider).AsTime(loc), true
|
||||||
|
}
|
||||||
|
|
||||||
|
return time.Time{}, false
|
||||||
|
}
|
||||||
|
|
||||||
// Based on: https://github.com/golang/go/blob/178a2c42254166cffed1b25fb1d3c7a5727cada6/src/text/template/exec.go#L931
|
// Based on: https://github.com/golang/go/blob/178a2c42254166cffed1b25fb1d3c7a5727cada6/src/text/template/exec.go#L931
|
||||||
func indirectInterface(v reflect.Value) reflect.Value {
|
func indirectInterface(v reflect.Value) reflect.Value {
|
||||||
if v.Kind() != reflect.Interface {
|
if v.Kind() != reflect.Interface {
|
||||||
|
|
|
@ -20,8 +20,6 @@ import (
|
||||||
"github.com/bep/clock"
|
"github.com/bep/clock"
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
|
|
||||||
toml "github.com/pelletier/go-toml/v2"
|
|
||||||
|
|
||||||
"github.com/gohugoio/locales"
|
"github.com/gohugoio/locales"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -139,13 +137,12 @@ func (f TimeFormatter) Format(t time.Time, layout string) string {
|
||||||
|
|
||||||
func ToTimeInDefaultLocationE(i any, location *time.Location) (tim time.Time, err error) {
|
func ToTimeInDefaultLocationE(i any, location *time.Location) (tim time.Time, err error) {
|
||||||
switch vv := i.(type) {
|
switch vv := i.(type) {
|
||||||
case toml.LocalDate:
|
case AsTimeProvider:
|
||||||
return vv.AsTime(location), nil
|
|
||||||
case toml.LocalDateTime:
|
|
||||||
return vv.AsTime(location), nil
|
return vv.AsTime(location), nil
|
||||||
// issue #8895
|
// issue #8895
|
||||||
// datetimes parsed by `go-toml` have empty zone name
|
// datetimes parsed by `go-toml` have empty zone name
|
||||||
// convert back them into string and use `cast`
|
// convert back them into string and use `cast`
|
||||||
|
// TODO(bep) add tests, make sure we really need this.
|
||||||
case time.Time:
|
case time.Time:
|
||||||
i = vv.Format(time.RFC3339)
|
i = vv.Format(time.RFC3339)
|
||||||
}
|
}
|
||||||
|
@ -161,3 +158,8 @@ func Now() time.Time {
|
||||||
func Since(t time.Time) time.Duration {
|
func Since(t time.Time) time.Duration {
|
||||||
return Clock.Since(t)
|
return Clock.Since(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AsTimeProvider is implemented by go-toml's LocalDate and LocalDateTime.
|
||||||
|
type AsTimeProvider interface {
|
||||||
|
AsTime(zone *time.Location) time.Time
|
||||||
|
}
|
||||||
|
|
|
@ -214,3 +214,62 @@ func TestTimeOnError(t *testing.T) {
|
||||||
b.Assert(b.BuildE(BuildCfg{}), qt.Not(qt.IsNil))
|
b.Assert(b.BuildE(BuildCfg{}), qt.Not(qt.IsNil))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTOMLDates(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- config.toml --
|
||||||
|
timeZone = "America/Los_Angeles"
|
||||||
|
-- content/_index.md --
|
||||||
|
---
|
||||||
|
date: "2020-10-20"
|
||||||
|
---
|
||||||
|
-- content/p1.md --
|
||||||
|
+++
|
||||||
|
title = "TOML Date with UTC offset"
|
||||||
|
date = 2021-08-16T06:00:00+00:00
|
||||||
|
+++
|
||||||
|
|
||||||
|
|
||||||
|
## Foo
|
||||||
|
-- data/mydata.toml --
|
||||||
|
date = 2020-10-20
|
||||||
|
talks = [
|
||||||
|
{ date = 2017-01-23, name = "Past talk 1" },
|
||||||
|
{ date = 2017-01-24, name = "Past talk 2" },
|
||||||
|
{ date = 2017-01-26, name = "Past talk 3" },
|
||||||
|
{ date = 2050-02-12, name = "Future talk 1" },
|
||||||
|
{ date = 2050-02-13, name = "Future talk 2" },
|
||||||
|
]
|
||||||
|
-- layouts/index.html --
|
||||||
|
{{ $futureTalks := where site.Data.mydata.talks "date" ">" now }}
|
||||||
|
{{ $pastTalks := where site.Data.mydata.talks "date" "<" now }}
|
||||||
|
|
||||||
|
{{ $homeDate := site.Home.Date }}
|
||||||
|
{{ $p1Date := (site.GetPage "p1").Date }}
|
||||||
|
Future talks: {{ len $futureTalks }}
|
||||||
|
Past talks: {{ len $pastTalks }}
|
||||||
|
|
||||||
|
Home's Date should be greater than past: {{ gt $homeDate (index $pastTalks 0).date }}
|
||||||
|
Home's Date should be less than future: {{ lt $homeDate (index $futureTalks 0).date }}
|
||||||
|
Home's Date should be equal mydata date: {{ eq $homeDate site.Data.mydata.date }}
|
||||||
|
Full time: {{ $p1Date | time.Format ":time_full" }}
|
||||||
|
`
|
||||||
|
|
||||||
|
b := NewIntegrationTestBuilder(
|
||||||
|
IntegrationTestConfig{
|
||||||
|
T: t,
|
||||||
|
TxtarString: files,
|
||||||
|
},
|
||||||
|
).Build()
|
||||||
|
|
||||||
|
b.AssertFileContent("public/index.html", `
|
||||||
|
Future talks: 2
|
||||||
|
Past talks: 3
|
||||||
|
Home's Date should be greater than past: true
|
||||||
|
Home's Date should be less than future: true
|
||||||
|
Home's Date should be equal mydata date: true
|
||||||
|
Full time: 6:00:00 am UTC
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
|
@ -18,7 +18,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
|
"github.com/gohugoio/hugo/config"
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
|
"github.com/gohugoio/hugo/langs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Also see tests in common/collection.
|
// Also see tests in common/collection.
|
||||||
|
@ -26,7 +28,7 @@ func TestAppend(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
start any
|
start any
|
||||||
|
|
|
@ -21,7 +21,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
|
"github.com/gohugoio/hugo/config"
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
|
"github.com/gohugoio/hugo/langs"
|
||||||
"github.com/gohugoio/hugo/output"
|
"github.com/gohugoio/hugo/output"
|
||||||
"github.com/gohugoio/hugo/tpl"
|
"github.com/gohugoio/hugo/tpl"
|
||||||
)
|
)
|
||||||
|
@ -67,7 +69,7 @@ func (templateFinder) GetFunc(name string) (reflect.Value, bool) {
|
||||||
func TestApply(t *testing.T) {
|
func TestApply(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
d := &deps.Deps{}
|
d := &deps.Deps{Language: langs.NewDefaultLanguage(config.New())}
|
||||||
d.SetTmpl(new(templateFinder))
|
d.SetTmpl(new(templateFinder))
|
||||||
ns := New(d)
|
ns := New(d)
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ import (
|
||||||
"github.com/gohugoio/hugo/common/types"
|
"github.com/gohugoio/hugo/common/types"
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
"github.com/gohugoio/hugo/helpers"
|
"github.com/gohugoio/hugo/helpers"
|
||||||
|
"github.com/gohugoio/hugo/langs"
|
||||||
|
"github.com/gohugoio/hugo/tpl/compare"
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -41,13 +43,23 @@ func init() {
|
||||||
|
|
||||||
// New returns a new instance of the collections-namespaced template functions.
|
// New returns a new instance of the collections-namespaced template functions.
|
||||||
func New(deps *deps.Deps) *Namespace {
|
func New(deps *deps.Deps) *Namespace {
|
||||||
|
if deps.Language == nil {
|
||||||
|
panic("language must be set")
|
||||||
|
}
|
||||||
|
|
||||||
|
loc := langs.GetLocation(deps.Language)
|
||||||
|
|
||||||
return &Namespace{
|
return &Namespace{
|
||||||
|
loc: loc,
|
||||||
|
sortComp: compare.New(loc, true),
|
||||||
deps: deps,
|
deps: deps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Namespace provides template functions for the "collections" namespace.
|
// Namespace provides template functions for the "collections" namespace.
|
||||||
type Namespace struct {
|
type Namespace struct {
|
||||||
|
loc *time.Location
|
||||||
|
sortComp *compare.Namespace
|
||||||
deps *deps.Deps
|
deps *deps.Deps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ func TestAfter(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
index any
|
index any
|
||||||
|
@ -97,7 +97,7 @@ func (g *tstGrouper2) Group(key any, items any) (any, error) {
|
||||||
func TestGroup(t *testing.T) {
|
func TestGroup(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
key any
|
key any
|
||||||
|
@ -187,7 +187,7 @@ func TestDelimit(t *testing.T) {
|
||||||
func TestDictionary(t *testing.T) {
|
func TestDictionary(t *testing.T) {
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
values []any
|
values []any
|
||||||
|
@ -226,7 +226,7 @@ func TestDictionary(t *testing.T) {
|
||||||
func TestReverse(t *testing.T) {
|
func TestReverse(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
s := []string{"a", "b", "c"}
|
s := []string{"a", "b", "c"}
|
||||||
reversed, err := ns.Reverse(s)
|
reversed, err := ns.Reverse(s)
|
||||||
|
@ -245,7 +245,7 @@ func TestEchoParam(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
a any
|
a any
|
||||||
|
@ -277,7 +277,7 @@ func TestFirst(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
limit any
|
limit any
|
||||||
|
@ -315,7 +315,7 @@ func TestIn(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
l1 any
|
l1 any
|
||||||
|
@ -391,7 +391,7 @@ func TestIntersect(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
l1, l2 any
|
l1, l2 any
|
||||||
|
@ -518,7 +518,7 @@ func TestLast(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
limit any
|
limit any
|
||||||
|
@ -557,7 +557,7 @@ func TestLast(t *testing.T) {
|
||||||
func TestQuerify(t *testing.T) {
|
func TestQuerify(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
params []any
|
params []any
|
||||||
|
@ -591,7 +591,7 @@ func TestQuerify(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkQuerify(b *testing.B) {
|
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", " &"}
|
params := []any{"a", "b", "c", "d", "f", " &"}
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
@ -604,7 +604,7 @@ func BenchmarkQuerify(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkQuerifySlice(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", " &"}
|
params := []string{"a", "b", "c", "d", "f", " &"}
|
||||||
|
|
||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
@ -619,7 +619,7 @@ func BenchmarkQuerifySlice(b *testing.B) {
|
||||||
func TestSeq(t *testing.T) {
|
func TestSeq(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
args []any
|
args []any
|
||||||
|
@ -663,7 +663,7 @@ func TestSeq(t *testing.T) {
|
||||||
func TestShuffle(t *testing.T) {
|
func TestShuffle(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
seq any
|
seq any
|
||||||
|
@ -703,7 +703,7 @@ func TestShuffle(t *testing.T) {
|
||||||
func TestShuffleRandomising(t *testing.T) {
|
func TestShuffleRandomising(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
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
|
// 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
|
// 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) {
|
func TestSlice(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
args []any
|
args []any
|
||||||
|
@ -758,7 +758,7 @@ func TestUnion(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
l1 any
|
l1 any
|
||||||
|
@ -847,7 +847,7 @@ func TestUnion(t *testing.T) {
|
||||||
func TestUniq(t *testing.T) {
|
func TestUniq(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
l any
|
l any
|
||||||
expect any
|
expect any
|
||||||
|
@ -979,6 +979,7 @@ func newDeps(cfg config.Provider) *deps.Deps {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return &deps.Deps{
|
return &deps.Deps{
|
||||||
|
Language: l,
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
Fs: hugofs.NewMem(l),
|
Fs: hugofs.NewMem(l),
|
||||||
ContentSpec: cs,
|
ContentSpec: cs,
|
||||||
|
|
|
@ -17,7 +17,9 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gohugoio/hugo/config"
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
|
"github.com/gohugoio/hugo/langs"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
)
|
)
|
||||||
|
@ -34,7 +36,7 @@ func TestComplement(t *testing.T) {
|
||||||
|
|
||||||
c := qt.New(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"}}
|
s1 := []TstX{{A: "a"}, {A: "b"}, {A: "d"}, {A: "e"}}
|
||||||
s2 := []TstX{{A: "b"}, {A: "e"}}
|
s2 := []TstX{{A: "b"}, {A: "e"}}
|
||||||
|
|
|
@ -18,6 +18,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/common/maps"
|
"github.com/gohugoio/hugo/common/maps"
|
||||||
|
"github.com/gohugoio/hugo/config"
|
||||||
|
"github.com/gohugoio/hugo/langs"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
|
@ -26,7 +28,7 @@ import (
|
||||||
func TestIndex(t *testing.T) {
|
func TestIndex(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
item any
|
item any
|
||||||
|
|
|
@ -19,7 +19,9 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/common/maps"
|
"github.com/gohugoio/hugo/common/maps"
|
||||||
|
"github.com/gohugoio/hugo/config"
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
|
"github.com/gohugoio/hugo/langs"
|
||||||
"github.com/gohugoio/hugo/parser"
|
"github.com/gohugoio/hugo/parser"
|
||||||
"github.com/gohugoio/hugo/parser/metadecoders"
|
"github.com/gohugoio/hugo/parser/metadecoders"
|
||||||
|
|
||||||
|
@ -27,7 +29,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMerge(t *testing.T) {
|
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}
|
simpleMap := map[string]any{"a": 1, "b": 2}
|
||||||
|
|
||||||
|
@ -161,7 +163,7 @@ func TestMerge(t *testing.T) {
|
||||||
|
|
||||||
func TestMergeDataFormats(t *testing.T) {
|
func TestMergeDataFormats(t *testing.T) {
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
toml1 := `
|
toml1 := `
|
||||||
V1 = "v1_1"
|
V1 = "v1_1"
|
||||||
|
|
|
@ -16,7 +16,6 @@ package collections
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
@ -26,7 +25,6 @@ import (
|
||||||
var (
|
var (
|
||||||
zero reflect.Value
|
zero reflect.Value
|
||||||
errorType = reflect.TypeOf((*error)(nil)).Elem()
|
errorType = reflect.TypeOf((*error)(nil)).Elem()
|
||||||
timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func numberToFloat(v reflect.Value) (float64, error) {
|
func numberToFloat(v reflect.Value) (float64, error) {
|
||||||
|
|
|
@ -25,8 +25,6 @@ import (
|
||||||
"github.com/spf13/cast"
|
"github.com/spf13/cast"
|
||||||
)
|
)
|
||||||
|
|
||||||
var sortComp = compare.New(true)
|
|
||||||
|
|
||||||
// Sort returns a sorted sequence.
|
// Sort returns a sorted sequence.
|
||||||
func (ns *Namespace) Sort(seq any, args ...any) (any, error) {
|
func (ns *Namespace) Sort(seq any, args ...any) (any, error) {
|
||||||
if seq == nil {
|
if seq == nil {
|
||||||
|
@ -51,7 +49,7 @@ func (ns *Namespace) Sort(seq any, args ...any) (any, error) {
|
||||||
collator := langs.GetCollator(ns.deps.Language)
|
collator := langs.GetCollator(ns.deps.Language)
|
||||||
|
|
||||||
// Create a list of pairs that will be used to do the sort
|
// 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())
|
p.Pairs = make([]pair, seqv.Len())
|
||||||
|
|
||||||
var sortByField string
|
var sortByField string
|
||||||
|
@ -145,6 +143,7 @@ type pair struct {
|
||||||
// A slice of pairs that implements sort.Interface to sort by Value.
|
// A slice of pairs that implements sort.Interface to sort by Value.
|
||||||
type pairList struct {
|
type pairList struct {
|
||||||
Collator *langs.Collator
|
Collator *langs.Collator
|
||||||
|
sortComp *compare.Namespace
|
||||||
Pairs []pair
|
Pairs []pair
|
||||||
SortAsc bool
|
SortAsc bool
|
||||||
SliceType reflect.Type
|
SliceType reflect.Type
|
||||||
|
@ -159,16 +158,16 @@ func (p pairList) Less(i, j int) bool {
|
||||||
if iv.IsValid() {
|
if iv.IsValid() {
|
||||||
if jv.IsValid() {
|
if jv.IsValid() {
|
||||||
// can only call Interface() on valid reflect Values
|
// 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
|
// 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 jv.IsValid() {
|
||||||
// if i is invalid, test j against j's zero value
|
// 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
|
return false
|
||||||
|
|
|
@ -17,7 +17,9 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gohugoio/hugo/config"
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
|
"github.com/gohugoio/hugo/langs"
|
||||||
|
|
||||||
qt "github.com/frankban/quicktest"
|
qt "github.com/frankban/quicktest"
|
||||||
)
|
)
|
||||||
|
@ -27,7 +29,7 @@ func TestSymDiff(t *testing.T) {
|
||||||
|
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
s1 := []TstX{{A: "a"}, {A: "b"}}
|
s1 := []TstX{{A: "a"}, {A: "b"}}
|
||||||
s2 := []TstX{{A: "a"}, {A: "e"}}
|
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()
|
fmv := mv.Float()
|
||||||
fmvp = &fmv
|
fmvp = &fmv
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
switch v.Type() {
|
if hreflect.IsTime(v.Type()) {
|
||||||
case timeType:
|
iv := ns.toTimeUnix(v)
|
||||||
iv := toTimeUnix(v)
|
|
||||||
ivp = &iv
|
ivp = &iv
|
||||||
imv := toTimeUnix(mv)
|
imv := ns.toTimeUnix(mv)
|
||||||
imvp = &imv
|
imvp = &imv
|
||||||
}
|
}
|
||||||
case reflect.Array, reflect.Slice:
|
case reflect.Array, reflect.Slice:
|
||||||
|
@ -167,12 +166,11 @@ func (ns *Namespace) checkCondition(v, mv reflect.Value, op string) (bool, error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
switch v.Type() {
|
if hreflect.IsTime(v.Type()) {
|
||||||
case timeType:
|
iv := ns.toTimeUnix(v)
|
||||||
iv := toTimeUnix(v)
|
|
||||||
ivp = &iv
|
ivp = &iv
|
||||||
for i := 0; i < mv.Len(); i++ {
|
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:
|
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")
|
return "", errors.New("unable to convert value to string")
|
||||||
}
|
}
|
||||||
|
|
||||||
func toTimeUnix(v reflect.Value) int64 {
|
func (ns *Namespace) toTimeUnix(v reflect.Value) int64 {
|
||||||
if v.Kind() == reflect.Interface {
|
t, ok := hreflect.AsTime(v, ns.loc)
|
||||||
return toTimeUnix(v.Elem())
|
if !ok {
|
||||||
}
|
|
||||||
if v.Type() != timeType {
|
|
||||||
panic("coding error: argument must be time.Time type reflect Value")
|
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"
|
"time"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/common/maps"
|
"github.com/gohugoio/hugo/common/maps"
|
||||||
|
"github.com/gohugoio/hugo/config"
|
||||||
|
"github.com/gohugoio/hugo/langs"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
)
|
)
|
||||||
|
@ -29,7 +31,7 @@ import (
|
||||||
func TestWhere(t *testing.T) {
|
func TestWhere(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
type Mid struct {
|
type Mid struct {
|
||||||
Tst TstX
|
Tst TstX
|
||||||
|
@ -683,7 +685,7 @@ func TestWhere(t *testing.T) {
|
||||||
func TestCheckCondition(t *testing.T) {
|
func TestCheckCondition(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
ns := New(&deps.Deps{})
|
ns := New(&deps.Deps{Language: langs.NewDefaultLanguage(config.New())})
|
||||||
|
|
||||||
type expect struct {
|
type expect struct {
|
||||||
result bool
|
result bool
|
||||||
|
|
|
@ -23,16 +23,19 @@ import (
|
||||||
"github.com/gohugoio/hugo/compare"
|
"github.com/gohugoio/hugo/compare"
|
||||||
"github.com/gohugoio/hugo/langs"
|
"github.com/gohugoio/hugo/langs"
|
||||||
|
|
||||||
|
"github.com/gohugoio/hugo/common/hreflect"
|
||||||
|
"github.com/gohugoio/hugo/common/htime"
|
||||||
"github.com/gohugoio/hugo/common/types"
|
"github.com/gohugoio/hugo/common/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New returns a new instance of the compare-namespaced template functions.
|
// New returns a new instance of the compare-namespaced template functions.
|
||||||
func New(caseInsensitive bool) *Namespace {
|
func New(loc *time.Location, caseInsensitive bool) *Namespace {
|
||||||
return &Namespace{caseInsensitive: caseInsensitive}
|
return &Namespace{loc: loc, caseInsensitive: caseInsensitive}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Namespace provides template functions for the "compare" namespace.
|
// Namespace provides template functions for the "compare" namespace.
|
||||||
type Namespace struct {
|
type Namespace struct {
|
||||||
|
loc *time.Location
|
||||||
// Enable to do case insensitive string compares.
|
// Enable to do case insensitive string compares.
|
||||||
caseInsensitive bool
|
caseInsensitive bool
|
||||||
}
|
}
|
||||||
|
@ -101,6 +104,11 @@ func (n *Namespace) Eq(first any, others ...any) bool {
|
||||||
if types.IsNil(v) {
|
if types.IsNil(v) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if at, ok := v.(htime.AsTimeProvider); ok {
|
||||||
|
return at.AsTime(n.loc)
|
||||||
|
}
|
||||||
|
|
||||||
vv := reflect.ValueOf(v)
|
vv := reflect.ValueOf(v)
|
||||||
switch vv.Kind() {
|
switch vv.Kind() {
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
@ -269,9 +277,8 @@ func (ns *Namespace) compareGetWithCollator(collator *langs.Collator, a any, b a
|
||||||
leftStr = &str
|
leftStr = &str
|
||||||
}
|
}
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
switch av.Type() {
|
if hreflect.IsTime(av.Type()) {
|
||||||
case timeType:
|
left = float64(ns.toTimeUnix(av))
|
||||||
left = float64(toTimeUnix(av))
|
|
||||||
}
|
}
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
left = 0
|
left = 0
|
||||||
|
@ -297,9 +304,8 @@ func (ns *Namespace) compareGetWithCollator(collator *langs.Collator, a any, b a
|
||||||
rightStr = &str
|
rightStr = &str
|
||||||
}
|
}
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
switch bv.Type() {
|
if hreflect.IsTime(bv.Type()) {
|
||||||
case timeType:
|
right = float64(ns.toTimeUnix(bv))
|
||||||
right = float64(toTimeUnix(bv))
|
|
||||||
}
|
}
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
right = 0
|
right = 0
|
||||||
|
@ -337,14 +343,10 @@ func (ns *Namespace) compareGetWithCollator(collator *langs.Collator, a any, b a
|
||||||
return left, right
|
return left, right
|
||||||
}
|
}
|
||||||
|
|
||||||
var timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
|
func (ns *Namespace) toTimeUnix(v reflect.Value) int64 {
|
||||||
|
t, ok := hreflect.AsTime(v, ns.loc)
|
||||||
func toTimeUnix(v reflect.Value) int64 {
|
if !ok {
|
||||||
if v.Kind() == reflect.Interface {
|
|
||||||
return toTimeUnix(v.Elem())
|
|
||||||
}
|
|
||||||
if v.Type() != timeType {
|
|
||||||
panic("coding error: argument must be time.Time type reflect Value")
|
panic("coding error: argument must be time.Time type reflect Value")
|
||||||
}
|
}
|
||||||
return v.MethodByName("Unix").Call([]reflect.Value{})[0].Int()
|
return t.Unix()
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,7 +88,7 @@ func TestDefaultFunc(t *testing.T) {
|
||||||
|
|
||||||
then := time.Now()
|
then := time.Now()
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
ns := New(false)
|
ns := New(time.UTC, false)
|
||||||
|
|
||||||
for i, test := range []struct {
|
for i, test := range []struct {
|
||||||
dflt any
|
dflt any
|
||||||
|
@ -147,7 +147,7 @@ func TestDefaultFunc(t *testing.T) {
|
||||||
func TestCompare(t *testing.T) {
|
func TestCompare(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
n := New(false)
|
n := New(time.UTC, false)
|
||||||
|
|
||||||
twoEq := func(a, b any) bool {
|
twoEq := func(a, b any) bool {
|
||||||
return n.Eq(a, b)
|
return n.Eq(a, b)
|
||||||
|
@ -269,7 +269,7 @@ func TestEqualExtend(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(false)
|
ns := New(time.UTC, false)
|
||||||
|
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
first any
|
first any
|
||||||
|
@ -294,7 +294,7 @@ func TestNotEqualExtend(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(false)
|
ns := New(time.UTC, false)
|
||||||
|
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
first any
|
first any
|
||||||
|
@ -314,7 +314,7 @@ func TestGreaterEqualExtend(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(false)
|
ns := New(time.UTC, false)
|
||||||
|
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
first any
|
first any
|
||||||
|
@ -335,7 +335,7 @@ func TestGreaterThanExtend(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(false)
|
ns := New(time.UTC, false)
|
||||||
|
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
first any
|
first any
|
||||||
|
@ -355,7 +355,7 @@ func TestLessEqualExtend(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(false)
|
ns := New(time.UTC, false)
|
||||||
|
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
first any
|
first any
|
||||||
|
@ -376,7 +376,7 @@ func TestLessThanExtend(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(false)
|
ns := New(time.UTC, false)
|
||||||
|
|
||||||
for _, test := range []struct {
|
for _, test := range []struct {
|
||||||
first any
|
first any
|
||||||
|
@ -395,7 +395,7 @@ func TestLessThanExtend(t *testing.T) {
|
||||||
|
|
||||||
func TestCase(t *testing.T) {
|
func TestCase(t *testing.T) {
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
n := New(false)
|
n := New(time.UTC, false)
|
||||||
|
|
||||||
c.Assert(n.Eq("az", "az"), qt.Equals, true)
|
c.Assert(n.Eq("az", "az"), qt.Equals, true)
|
||||||
c.Assert(n.Eq("az", stringType("az")), qt.Equals, true)
|
c.Assert(n.Eq("az", stringType("az")), qt.Equals, true)
|
||||||
|
@ -403,7 +403,7 @@ func TestCase(t *testing.T) {
|
||||||
|
|
||||||
func TestStringType(t *testing.T) {
|
func TestStringType(t *testing.T) {
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
n := New(true)
|
n := New(time.UTC, true)
|
||||||
|
|
||||||
c.Assert(n.Lt("az", "Za"), qt.Equals, true)
|
c.Assert(n.Lt("az", "Za"), qt.Equals, true)
|
||||||
c.Assert(n.Gt("ab", "Ab"), qt.Equals, true)
|
c.Assert(n.Gt("ab", "Ab"), qt.Equals, true)
|
||||||
|
@ -411,11 +411,12 @@ func TestStringType(t *testing.T) {
|
||||||
|
|
||||||
func TestTimeUnix(t *testing.T) {
|
func TestTimeUnix(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
n := New(time.UTC, false)
|
||||||
var sec int64 = 1234567890
|
var sec int64 = 1234567890
|
||||||
tv := reflect.ValueOf(time.Unix(sec, 0))
|
tv := reflect.ValueOf(time.Unix(sec, 0))
|
||||||
i := 1
|
i := 1
|
||||||
|
|
||||||
res := toTimeUnix(tv)
|
res := n.toTimeUnix(tv)
|
||||||
if sec != res {
|
if sec != res {
|
||||||
t.Errorf("[%d] timeUnix got %v but expected %v", i, res, sec)
|
t.Errorf("[%d] timeUnix got %v but expected %v", i, res, sec)
|
||||||
}
|
}
|
||||||
|
@ -428,13 +429,13 @@ func TestTimeUnix(t *testing.T) {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
iv := reflect.ValueOf(sec)
|
iv := reflect.ValueOf(sec)
|
||||||
toTimeUnix(iv)
|
n.toTimeUnix(iv)
|
||||||
}(t)
|
}(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConditional(t *testing.T) {
|
func TestConditional(t *testing.T) {
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
n := New(false)
|
n := New(time.UTC, false)
|
||||||
a, b := "a", "b"
|
a, b := "a", "b"
|
||||||
|
|
||||||
c.Assert(n.Conditional(true, a, b), qt.Equals, a)
|
c.Assert(n.Conditional(true, a, b), qt.Equals, a)
|
||||||
|
@ -446,7 +447,7 @@ func TestComparisonArgCount(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
||||||
ns := New(false)
|
ns := New(time.UTC, false)
|
||||||
|
|
||||||
panicMsg := "missing arguments for comparison"
|
panicMsg := "missing arguments for comparison"
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ package compare
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gohugoio/hugo/deps"
|
"github.com/gohugoio/hugo/deps"
|
||||||
|
"github.com/gohugoio/hugo/langs"
|
||||||
"github.com/gohugoio/hugo/tpl/internal"
|
"github.com/gohugoio/hugo/tpl/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,7 +23,11 @@ const name = "compare"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
|
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
|
||||||
ctx := New(false)
|
if d.Language == nil {
|
||||||
|
panic("language must be set")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := New(langs.GetLocation(d.Language), false)
|
||||||
|
|
||||||
ns := &internal.TemplateFuncsNamespace{
|
ns := &internal.TemplateFuncsNamespace{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
|
Loading…
Reference in a new issue