hugo/hugolib/dates_test.go
2024-07-01 21:48:12 +02:00

351 lines
8.9 KiB
Go

// Copyright 2021 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package hugolib
import (
"fmt"
"strings"
"testing"
qt "github.com/frankban/quicktest"
)
func TestDateFormatMultilingual(t *testing.T) {
b := newTestSitesBuilder(t)
b.WithConfigFile("toml", `
baseURL = "https://example.org"
defaultContentLanguage = "en"
defaultContentLanguageInSubDir = true
[languages]
[languages.en]
weight=10
[languages.nn]
weight=20
`)
pageWithDate := `---
title: Page
date: 2021-07-18
---
`
b.WithContent(
"_index.en.md", pageWithDate,
"_index.nn.md", pageWithDate,
)
b.WithTemplatesAdded("index.html", `
Date: {{ .Date | time.Format ":date_long" }}
`)
b.Build(BuildCfg{})
b.AssertFileContent("public/en/index.html", `Date: July 18, 2021`)
b.AssertFileContent("public/nn/index.html", `Date: 18. juli 2021`)
}
func TestTimeZones(t *testing.T) {
b := newTestSitesBuilder(t)
b.WithConfigFile("toml", `
baseURL = "https://example.org"
defaultContentLanguage = "en"
defaultContentLanguageInSubDir = true
[languages]
[languages.en]
timeZone="UTC"
weight=10
[languages.nn]
timeZone="America/Antigua"
weight=20
`)
const (
pageTemplYaml = `---
title: Page
date: %s
lastMod: %s
publishDate: %s
expiryDate: %s
---
`
pageTemplTOML = `+++
title="Page"
date=%s
lastMod=%s
publishDate=%s
expiryDate=%s
+++
`
shortDateTempl = `%d-07-%d`
longDateTempl = `%d-07-%d 15:28:01`
)
createPageContent := func(pageTempl, dateTempl string, quoted bool) string {
createDate := func(year, i int) string {
d := fmt.Sprintf(dateTempl, year, i)
if quoted {
return fmt.Sprintf("%q", d)
}
return d
}
return fmt.Sprintf(
pageTempl,
createDate(2021, 10),
createDate(2021, 11),
createDate(2021, 12),
createDate(2099, 13), // This test will fail in 2099 :-)
)
}
b.WithContent(
// YAML
"short-date-yaml-unqouted.en.md", createPageContent(pageTemplYaml, shortDateTempl, false),
"short-date-yaml-unqouted.nn.md", createPageContent(pageTemplYaml, shortDateTempl, false),
"short-date-yaml-qouted.en.md", createPageContent(pageTemplYaml, shortDateTempl, true),
"short-date-yaml-qouted.nn.md", createPageContent(pageTemplYaml, shortDateTempl, true),
"long-date-yaml-unqouted.en.md", createPageContent(pageTemplYaml, longDateTempl, false),
"long-date-yaml-unqouted.nn.md", createPageContent(pageTemplYaml, longDateTempl, false),
// TOML
"short-date-toml-unqouted.en.md", createPageContent(pageTemplTOML, shortDateTempl, false),
"short-date-toml-unqouted.nn.md", createPageContent(pageTemplTOML, shortDateTempl, false),
"short-date-toml-qouted.en.md", createPageContent(pageTemplTOML, shortDateTempl, true),
"short-date-toml-qouted.nn.md", createPageContent(pageTemplTOML, shortDateTempl, true),
)
const datesTempl = `
Date: {{ .Date | safeHTML }}
Lastmod: {{ .Lastmod | safeHTML }}
PublishDate: {{ .PublishDate | safeHTML }}
ExpiryDate: {{ .ExpiryDate | safeHTML }}
`
b.WithTemplatesAdded(
"_default/single.html", datesTempl,
)
b.Build(BuildCfg{})
expectShortDateEn := `
Date: 2021-07-10 00:00:00 +0000 UTC
Lastmod: 2021-07-11 00:00:00 +0000 UTC
PublishDate: 2021-07-12 00:00:00 +0000 UTC
ExpiryDate: 2099-07-13 00:00:00 +0000 UTC`
expectShortDateNn := strings.ReplaceAll(expectShortDateEn, "+0000 UTC", "-0400 AST")
expectLongDateEn := `
Date: 2021-07-10 15:28:01 +0000 UTC
Lastmod: 2021-07-11 15:28:01 +0000 UTC
PublishDate: 2021-07-12 15:28:01 +0000 UTC
ExpiryDate: 2099-07-13 15:28:01 +0000 UTC`
expectLongDateNn := strings.ReplaceAll(expectLongDateEn, "+0000 UTC", "-0400 AST")
// TODO(bep) create a common proposal for go-yaml, go-toml
// for a custom date parser hook to handle these time zones.
// JSON is omitted from this test as JSON does no (to my knowledge)
// have date literals.
// YAML
// Note: This is with go-yaml v2, I suspect v3 will fail with the unquoted values.
b.AssertFileContent("public/en/short-date-yaml-unqouted/index.html", expectShortDateEn)
b.AssertFileContent("public/nn/short-date-yaml-unqouted/index.html", expectShortDateNn)
b.AssertFileContent("public/en/short-date-yaml-qouted/index.html", expectShortDateEn)
b.AssertFileContent("public/nn/short-date-yaml-qouted/index.html", expectShortDateNn)
b.AssertFileContent("public/en/long-date-yaml-unqouted/index.html", expectLongDateEn)
b.AssertFileContent("public/nn/long-date-yaml-unqouted/index.html", expectLongDateNn)
// TOML
// These fails: TOML (Burnt Sushi) defaults to local timezone.
// TODO(bep) check go-toml
b.AssertFileContent("public/en/short-date-toml-unqouted/index.html", expectShortDateEn)
b.AssertFileContent("public/nn/short-date-toml-unqouted/index.html", expectShortDateNn)
b.AssertFileContent("public/en/short-date-toml-qouted/index.html", expectShortDateEn)
b.AssertFileContent("public/nn/short-date-toml-qouted/index.html", expectShortDateNn)
}
// Issue 8832
func TestTimeZoneInvalid(t *testing.T) {
b := newTestSitesBuilder(t)
b.WithConfigFile("toml", `
timeZone = "America/LosAngeles" # Should be America/Los_Angeles
`)
err := b.CreateSitesE()
b.Assert(err, qt.Not(qt.IsNil))
b.Assert(err.Error(), qt.Contains, `invalid timeZone for language "en": unknown time zone America/LosAngeles`)
}
// Issue 8835
func TestTimeOnError(t *testing.T) {
b := newTestSitesBuilder(t)
b.WithTemplates("index.html", `time: {{ time "2020-10-20" "invalid-timezone" }}`)
b.WithContent("p1.md", "")
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 }}
Home date: {{ $homeDate }}
mydata.date: {{ site.Data.mydata.date }}
Full time: {{ $p1Date | time.Format ":time_full" }}
`
b := Test(t, files)
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
`)
}
func TestPublisDateRollupIssue12438(t *testing.T) {
t.Parallel()
// To future Hugo maintainers, this test will start to fail in 2099.
files := `
-- hugo.toml --
disableKinds = ['home','rss','sitemap']
[taxonomies]
tag = 'tags'
-- layouts/_default/list.html --
Date: {{ .Date.Format "2006-01-02" }}
PublishDate: {{ .PublishDate.Format "2006-01-02" }}
Lastmod: {{ .Lastmod.Format "2006-01-02" }}
-- layouts/_default/single.html --
{{ .Title }}
-- content/s1/p1.md --
---
title: p1
date: 2024-03-01
lastmod: 2024-03-02
tags: [t1]
---
-- content/s1/p2.md --
---
title: p2
date: 2024-04-03
lastmod: 2024-04-04
tags: [t1]
---
-- content/s1/p3.md --
---
title: p3
lastmod: 2099-05-06
tags: [t1]
---
`
// Test without publishDate in front matter.
b := Test(t, files)
b.AssertFileContent("public/s1/index.html", `
Date: 2099-05-06
PublishDate: 2024-04-03
Lastmod: 2099-05-06
`)
b.AssertFileContent("public/tags/index.html", `
Date: 2024-04-03
PublishDate: 2024-04-03
Lastmod: 2024-04-04
`)
b.AssertFileContent("public/tags/t1/index.html", `
Date: 2024-04-03
PublishDate: 2024-04-03
Lastmod: 2024-04-04
`)
// Test with publishDate in front matter.
files = strings.ReplaceAll(files, "lastmod", "publishDate")
b = Test(t, files)
b.AssertFileContent("public/s1/index.html", `
Date: 2099-05-06
PublishDate: 2024-04-04
Lastmod: 2099-05-06
`)
b.AssertFileContent("public/tags/index.html", `
Date: 2024-04-03
PublishDate: 2024-04-04
Lastmod: 2024-04-03
`)
b.AssertFileContent("public/tags/t1/index.html", `
Date: 2024-04-03
PublishDate: 2024-04-04
Lastmod: 2024-04-03
`)
}