github.com/neohugo/neohugo@v0.123.8/hugolib/dates_test.go (about)

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