dates_test.go (7570B)
1 // Copyright 2021 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package hugolib
15
16 import (
17 "fmt"
18
19 qt "github.com/frankban/quicktest"
20
21 "strings"
22 "testing"
23 )
24
25 func TestDateFormatMultilingual(t *testing.T) {
26 b := newTestSitesBuilder(t)
27 b.WithConfigFile("toml", `
28 baseURL = "https://example.org"
29
30 defaultContentLanguage = "en"
31 defaultContentLanguageInSubDir = true
32
33 [languages]
34 [languages.en]
35 weight=10
36 [languages.nn]
37 weight=20
38
39 `)
40
41 pageWithDate := `---
42 title: Page
43 date: 2021-07-18
44 ---
45 `
46
47 b.WithContent(
48 "_index.en.md", pageWithDate,
49 "_index.nn.md", pageWithDate,
50 )
51
52 b.WithTemplatesAdded("index.html", `
53 Date: {{ .Date | time.Format ":date_long" }}
54 `)
55
56 b.Build(BuildCfg{})
57
58 b.AssertFileContent("public/en/index.html", `Date: July 18, 2021`)
59 b.AssertFileContent("public/nn/index.html", `Date: 18. juli 2021`)
60
61 }
62
63 func TestTimeZones(t *testing.T) {
64 b := newTestSitesBuilder(t)
65 b.WithConfigFile("toml", `
66 baseURL = "https://example.org"
67
68 defaultContentLanguage = "en"
69 defaultContentLanguageInSubDir = true
70
71 [languages]
72 [languages.en]
73 timeZone="UTC"
74 weight=10
75 [languages.nn]
76 timeZone="America/Antigua"
77 weight=20
78
79 `)
80
81 const (
82 pageTemplYaml = `---
83 title: Page
84 date: %s
85 lastMod: %s
86 publishDate: %s
87 expiryDate: %s
88 ---
89 `
90
91 pageTemplTOML = `+++
92 title="Page"
93 date=%s
94 lastMod=%s
95 publishDate=%s
96 expiryDate=%s
97 +++
98 `
99
100 shortDateTempl = `%d-07-%d`
101 longDateTempl = `%d-07-%d 15:28:01`
102 )
103
104 createPageContent := func(pageTempl, dateTempl string, quoted bool) string {
105 createDate := func(year, i int) string {
106 d := fmt.Sprintf(dateTempl, year, i)
107 if quoted {
108 return fmt.Sprintf("%q", d)
109 }
110
111 return d
112 }
113
114 return fmt.Sprintf(
115 pageTempl,
116 createDate(2021, 10),
117 createDate(2021, 11),
118 createDate(2021, 12),
119 createDate(2099, 13), // This test will fail in 2099 :-)
120 )
121 }
122
123 b.WithContent(
124 // YAML
125 "short-date-yaml-unqouted.en.md", createPageContent(pageTemplYaml, shortDateTempl, false),
126 "short-date-yaml-unqouted.nn.md", createPageContent(pageTemplYaml, shortDateTempl, false),
127 "short-date-yaml-qouted.en.md", createPageContent(pageTemplYaml, shortDateTempl, true),
128 "short-date-yaml-qouted.nn.md", createPageContent(pageTemplYaml, shortDateTempl, true),
129 "long-date-yaml-unqouted.en.md", createPageContent(pageTemplYaml, longDateTempl, false),
130 "long-date-yaml-unqouted.nn.md", createPageContent(pageTemplYaml, longDateTempl, false),
131 // TOML
132 "short-date-toml-unqouted.en.md", createPageContent(pageTemplTOML, shortDateTempl, false),
133 "short-date-toml-unqouted.nn.md", createPageContent(pageTemplTOML, shortDateTempl, false),
134 "short-date-toml-qouted.en.md", createPageContent(pageTemplTOML, shortDateTempl, true),
135 "short-date-toml-qouted.nn.md", createPageContent(pageTemplTOML, shortDateTempl, true),
136 )
137
138 const datesTempl = `
139 Date: {{ .Date | safeHTML }}
140 Lastmod: {{ .Lastmod | safeHTML }}
141 PublishDate: {{ .PublishDate | safeHTML }}
142 ExpiryDate: {{ .ExpiryDate | safeHTML }}
143
144 `
145
146 b.WithTemplatesAdded(
147 "_default/single.html", datesTempl,
148 )
149
150 b.Build(BuildCfg{})
151
152 expectShortDateEn := `
153 Date: 2021-07-10 00:00:00 +0000 UTC
154 Lastmod: 2021-07-11 00:00:00 +0000 UTC
155 PublishDate: 2021-07-12 00:00:00 +0000 UTC
156 ExpiryDate: 2099-07-13 00:00:00 +0000 UTC`
157
158 expectShortDateNn := strings.ReplaceAll(expectShortDateEn, "+0000 UTC", "-0400 AST")
159
160 expectLongDateEn := `
161 Date: 2021-07-10 15:28:01 +0000 UTC
162 Lastmod: 2021-07-11 15:28:01 +0000 UTC
163 PublishDate: 2021-07-12 15:28:01 +0000 UTC
164 ExpiryDate: 2099-07-13 15:28:01 +0000 UTC`
165
166 expectLongDateNn := strings.ReplaceAll(expectLongDateEn, "+0000 UTC", "-0400 AST")
167
168 // TODO(bep) create a common proposal for go-yaml, go-toml
169 // for a custom date parser hook to handle these time zones.
170 // JSON is omitted from this test as JSON does no (to my knowledge)
171 // have date literals.
172
173 // YAML
174 // Note: This is with go-yaml v2, I suspect v3 will fail with the unquouted values.
175 b.AssertFileContent("public/en/short-date-yaml-unqouted/index.html", expectShortDateEn)
176 b.AssertFileContent("public/nn/short-date-yaml-unqouted/index.html", expectShortDateNn)
177 b.AssertFileContent("public/en/short-date-yaml-qouted/index.html", expectShortDateEn)
178 b.AssertFileContent("public/nn/short-date-yaml-qouted/index.html", expectShortDateNn)
179
180 b.AssertFileContent("public/en/long-date-yaml-unqouted/index.html", expectLongDateEn)
181 b.AssertFileContent("public/nn/long-date-yaml-unqouted/index.html", expectLongDateNn)
182
183 // TOML
184 // These fails: TOML (Burnt Sushi) defaults to local timezone.
185 // TODO(bep) check go-toml
186 b.AssertFileContent("public/en/short-date-toml-unqouted/index.html", expectShortDateEn)
187 b.AssertFileContent("public/nn/short-date-toml-unqouted/index.html", expectShortDateNn)
188 b.AssertFileContent("public/en/short-date-toml-qouted/index.html", expectShortDateEn)
189 b.AssertFileContent("public/nn/short-date-toml-qouted/index.html", expectShortDateNn)
190
191 }
192
193 // Issue 8832
194 func TestTimeZoneInvalid(t *testing.T) {
195 b := newTestSitesBuilder(t)
196
197 b.WithConfigFile("toml", `
198
199 timeZone = "America/LosAngeles" # Should be America/Los_Angeles
200 `)
201
202 err := b.CreateSitesE()
203 b.Assert(err, qt.Not(qt.IsNil))
204 b.Assert(err.Error(), qt.Contains, `failed to load config: invalid timeZone for language "en": unknown time zone America/LosAngeles`)
205 }
206
207 // Issue 8835
208 func TestTimeOnError(t *testing.T) {
209 b := newTestSitesBuilder(t)
210
211 b.WithTemplates("index.html", `time: {{ time "2020-10-20" "invalid-timezone" }}`)
212 b.WithContent("p1.md", "")
213
214 b.Assert(b.BuildE(BuildCfg{}), qt.Not(qt.IsNil))
215
216 }
217
218 func TestTOMLDates(t *testing.T) {
219 t.Parallel()
220
221 files := `
222 -- config.toml --
223 timeZone = "America/Los_Angeles"
224 -- content/_index.md --
225 ---
226 date: "2020-10-20"
227 ---
228 -- content/p1.md --
229 +++
230 title = "TOML Date with UTC offset"
231 date = 2021-08-16T06:00:00+00:00
232 +++
233
234
235 ## Foo
236 -- data/mydata.toml --
237 date = 2020-10-20
238 talks = [
239 { date = 2017-01-23, name = "Past talk 1" },
240 { date = 2017-01-24, name = "Past talk 2" },
241 { date = 2017-01-26, name = "Past talk 3" },
242 { date = 2050-02-12, name = "Future talk 1" },
243 { date = 2050-02-13, name = "Future talk 2" },
244 ]
245 -- layouts/index.html --
246 {{ $futureTalks := where site.Data.mydata.talks "date" ">" now }}
247 {{ $pastTalks := where site.Data.mydata.talks "date" "<" now }}
248
249 {{ $homeDate := site.Home.Date }}
250 {{ $p1Date := (site.GetPage "p1").Date }}
251 Future talks: {{ len $futureTalks }}
252 Past talks: {{ len $pastTalks }}
253
254 Home's Date should be greater than past: {{ gt $homeDate (index $pastTalks 0).date }}
255 Home's Date should be less than future: {{ lt $homeDate (index $futureTalks 0).date }}
256 Home's Date should be equal mydata date: {{ eq $homeDate site.Data.mydata.date }}
257 Full time: {{ $p1Date | time.Format ":time_full" }}
258 `
259
260 b := NewIntegrationTestBuilder(
261 IntegrationTestConfig{
262 T: t,
263 TxtarString: files,
264 },
265 ).Build()
266
267 b.AssertFileContent("public/index.html", `
268 Future talks: 2
269 Past talks: 3
270 Home's Date should be greater than past: true
271 Home's Date should be less than future: true
272 Home's Date should be equal mydata date: true
273 Full time: 6:00:00 am UTC
274 `)
275 }