aboutsummaryrefslogtreecommitdiffhomepage
path: root/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'helpers')
-rw-r--r--helpers/content.go37
-rw-r--r--helpers/content_test.go71
-rw-r--r--helpers/general.go14
-rw-r--r--helpers/general_test.go79
-rw-r--r--helpers/path.go17
-rw-r--r--helpers/path_test.go85
-rw-r--r--helpers/pathspec.go11
-rw-r--r--helpers/pathspec_test.go62
-rw-r--r--helpers/testhelpers_test.go58
-rw-r--r--helpers/url.go33
-rw-r--r--helpers/url_test.go142
11 files changed, 220 insertions, 389 deletions
diff --git a/helpers/content.go b/helpers/content.go
index d04e34a07..510d496b9 100644
--- a/helpers/content.go
+++ b/helpers/content.go
@@ -50,30 +50,18 @@ type ContentSpec struct {
anchorNameSanitizer converter.AnchorNameSanitizer
getRenderer func(t hooks.RendererType, id any) any
- // SummaryLength is the length of the summary that Hugo extracts from a content.
- summaryLength int
-
- BuildFuture bool
- BuildExpired bool
- BuildDrafts bool
-
- Cfg config.Provider
+ Cfg config.AllProvider
}
// NewContentSpec returns a ContentSpec initialized
// with the appropriate fields from the given config.Provider.
-func NewContentSpec(cfg config.Provider, logger loggers.Logger, contentFs afero.Fs, ex *hexec.Exec) (*ContentSpec, error) {
+func NewContentSpec(cfg config.AllProvider, logger loggers.Logger, contentFs afero.Fs, ex *hexec.Exec) (*ContentSpec, error) {
spec := &ContentSpec{
- summaryLength: cfg.GetInt("summaryLength"),
- BuildFuture: cfg.GetBool("buildFuture"),
- BuildExpired: cfg.GetBool("buildExpired"),
- BuildDrafts: cfg.GetBool("buildDrafts"),
-
Cfg: cfg,
}
converterProvider, err := markup.NewConverterProvider(converter.ProviderConfig{
- Cfg: cfg,
+ Conf: cfg,
ContentFs: contentFs,
Logger: logger,
Exec: ex,
@@ -157,6 +145,9 @@ func (c *ContentSpec) SanitizeAnchorName(s string) string {
}
func (c *ContentSpec) ResolveMarkup(in string) string {
+ if c == nil {
+ panic("nil ContentSpec")
+ }
in = strings.ToLower(in)
switch in {
case "md", "markdown", "mdown":
@@ -194,17 +185,17 @@ func (c *ContentSpec) TruncateWordsByRune(in []string) (string, bool) {
count := 0
for index, word := range words {
- if count >= c.summaryLength {
+ if count >= c.Cfg.SummaryLength() {
return strings.Join(words[:index], " "), true
}
runeCount := utf8.RuneCountInString(word)
if len(word) == runeCount {
count++
- } else if count+runeCount < c.summaryLength {
+ } else if count+runeCount < c.Cfg.SummaryLength() {
count += runeCount
} else {
for ri := range word {
- if count >= c.summaryLength {
+ if count >= c.Cfg.SummaryLength() {
truncatedWords := append(words[:index], word[:ri])
return strings.Join(truncatedWords, " "), true
}
@@ -229,7 +220,7 @@ func (c *ContentSpec) TruncateWordsToWholeSentence(s string) (string, bool) {
wordCount++
lastWordIndex = i
- if wordCount >= c.summaryLength {
+ if wordCount >= c.Cfg.SummaryLength() {
break
}
@@ -283,19 +274,19 @@ func isEndOfSentence(r rune) bool {
func (c *ContentSpec) truncateWordsToWholeSentenceOld(content string) (string, bool) {
words := strings.Fields(content)
- if c.summaryLength >= len(words) {
+ if c.Cfg.SummaryLength() >= len(words) {
return strings.Join(words, " "), false
}
- for counter, word := range words[c.summaryLength:] {
+ for counter, word := range words[c.Cfg.SummaryLength():] {
if strings.HasSuffix(word, ".") ||
strings.HasSuffix(word, "?") ||
strings.HasSuffix(word, ".\"") ||
strings.HasSuffix(word, "!") {
- upper := c.summaryLength + counter + 1
+ upper := c.Cfg.SummaryLength() + counter + 1
return strings.Join(words[:upper], " "), (upper < len(words))
}
}
- return strings.Join(words[:c.summaryLength], " "), true
+ return strings.Join(words[:c.Cfg.SummaryLength()], " "), true
}
diff --git a/helpers/content_test.go b/helpers/content_test.go
index 54b7ef3f9..2909c0266 100644
--- a/helpers/content_test.go
+++ b/helpers/content_test.go
@@ -1,4 +1,4 @@
-// Copyright 2019 The Hugo Authors. All rights reserved.
+// Copyright 2023 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.
@@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package helpers
+package helpers_test
import (
"bytes"
@@ -19,12 +19,9 @@ import (
"strings"
"testing"
- "github.com/spf13/afero"
-
- "github.com/gohugoio/hugo/common/loggers"
- "github.com/gohugoio/hugo/config"
-
qt "github.com/frankban/quicktest"
+ "github.com/gohugoio/hugo/config"
+ "github.com/gohugoio/hugo/helpers"
)
const tstHTMLContent = "<!DOCTYPE html><html><head><script src=\"http://two/foobar.js\"></script></head><body><nav><ul><li hugo-nav=\"section_0\"></li><li hugo-nav=\"section_1\"></li></ul></nav><article>content <a href=\"http://two/foobar\">foobar</a>. Follow up</article><p>This is some text.<br>And some more.</p></body></html>"
@@ -43,7 +40,7 @@ func TestTrimShortHTML(t *testing.T) {
{[]byte("<p>Hello</p>\n<ul>\n<li>list1</li>\n<li>list2</li>\n</ul>"), []byte("<p>Hello</p>\n<ul>\n<li>list1</li>\n<li>list2</li>\n</ul>")},
}
- c := newTestContentSpec()
+ c := newTestContentSpec(nil)
for i, test := range tests {
output := c.TrimShortHTML(test.input)
if !bytes.Equal(test.output, output) {
@@ -52,55 +49,23 @@ func TestTrimShortHTML(t *testing.T) {
}
}
-func TestStripEmptyNav(t *testing.T) {
- c := qt.New(t)
- cleaned := stripEmptyNav([]byte("do<nav>\n</nav>\n\nbedobedo"))
- c.Assert(cleaned, qt.DeepEquals, []byte("dobedobedo"))
-}
-
func TestBytesToHTML(t *testing.T) {
c := qt.New(t)
- c.Assert(BytesToHTML([]byte("dobedobedo")), qt.Equals, template.HTML("dobedobedo"))
-}
-
-func TestNewContentSpec(t *testing.T) {
- cfg := config.NewWithTestDefaults()
- c := qt.New(t)
-
- cfg.Set("summaryLength", 32)
- cfg.Set("buildFuture", true)
- cfg.Set("buildExpired", true)
- cfg.Set("buildDrafts", true)
-
- spec, err := NewContentSpec(cfg, loggers.NewErrorLogger(), afero.NewMemMapFs(), nil)
-
- c.Assert(err, qt.IsNil)
- c.Assert(spec.summaryLength, qt.Equals, 32)
- c.Assert(spec.BuildFuture, qt.Equals, true)
- c.Assert(spec.BuildExpired, qt.Equals, true)
- c.Assert(spec.BuildDrafts, qt.Equals, true)
+ c.Assert(helpers.BytesToHTML([]byte("dobedobedo")), qt.Equals, template.HTML("dobedobedo"))
}
var benchmarkTruncateString = strings.Repeat("This is a sentence about nothing.", 20)
func BenchmarkTestTruncateWordsToWholeSentence(b *testing.B) {
- c := newTestContentSpec()
+ c := newTestContentSpec(nil)
b.ResetTimer()
for i := 0; i < b.N; i++ {
c.TruncateWordsToWholeSentence(benchmarkTruncateString)
}
}
-func BenchmarkTestTruncateWordsToWholeSentenceOld(b *testing.B) {
- c := newTestContentSpec()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- c.truncateWordsToWholeSentenceOld(benchmarkTruncateString)
- }
-}
-
func TestTruncateWordsToWholeSentence(t *testing.T) {
- c := newTestContentSpec()
+
type test struct {
input, expected string
max int
@@ -118,7 +83,9 @@ func TestTruncateWordsToWholeSentence(t *testing.T) {
{"This... is a more difficult test?", "This... is a more difficult test?", 1, false},
}
for i, d := range data {
- c.summaryLength = d.max
+ cfg := config.New()
+ cfg.Set("summaryLength", d.max)
+ c := newTestContentSpec(cfg)
output, truncated := c.TruncateWordsToWholeSentence(d.input)
if d.expected != output {
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
@@ -131,7 +98,7 @@ func TestTruncateWordsToWholeSentence(t *testing.T) {
}
func TestTruncateWordsByRune(t *testing.T) {
- c := newTestContentSpec()
+
type test struct {
input, expected string
max int
@@ -153,7 +120,9 @@ func TestTruncateWordsByRune(t *testing.T) {
{" \nThis is not a sentence\n ", "This is not", 3, true},
}
for i, d := range data {
- c.summaryLength = d.max
+ cfg := config.New()
+ cfg.Set("summaryLength", d.max)
+ c := newTestContentSpec(cfg)
output, truncated := c.TruncateWordsByRune(strings.Fields(d.input))
if d.expected != output {
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
@@ -168,7 +137,7 @@ func TestTruncateWordsByRune(t *testing.T) {
func TestExtractTOCNormalContent(t *testing.T) {
content := []byte("<nav>\n<ul>\nTOC<li><a href=\"#")
- actualTocLessContent, actualToc := ExtractTOC(content)
+ actualTocLessContent, actualToc := helpers.ExtractTOC(content)
expectedTocLess := []byte("TOC<li><a href=\"#")
expectedToc := []byte("<nav id=\"TableOfContents\">\n<ul>\n")
@@ -184,7 +153,7 @@ func TestExtractTOCNormalContent(t *testing.T) {
func TestExtractTOCGreaterThanSeventy(t *testing.T) {
content := []byte("<nav>\n<ul>\nTOC This is a very long content which will definitely be greater than seventy, I promise you that.<li><a href=\"#")
- actualTocLessContent, actualToc := ExtractTOC(content)
+ actualTocLessContent, actualToc := helpers.ExtractTOC(content)
// Because the start of Toc is greater than 70+startpoint of <li> content and empty TOC will be returned
expectedToc := []byte("")
@@ -200,7 +169,7 @@ func TestExtractTOCGreaterThanSeventy(t *testing.T) {
func TestExtractNoTOC(t *testing.T) {
content := []byte("TOC")
- actualTocLessContent, actualToc := ExtractTOC(content)
+ actualTocLessContent, actualToc := helpers.ExtractTOC(content)
expectedToc := []byte("")
if !bytes.Equal(actualTocLessContent, content) {
@@ -225,7 +194,7 @@ func TestTotalWords(t *testing.T) {
{"One, Two, Three", 3},
{totalWordsBenchmarkString, 400},
} {
- actualWordCount := TotalWords(this.s)
+ actualWordCount := helpers.TotalWords(this.s)
if actualWordCount != this.words {
t.Errorf("[%d] Actual word count (%d) for test string (%s) did not match %d", i, actualWordCount, this.s, this.words)
@@ -236,7 +205,7 @@ func TestTotalWords(t *testing.T) {
func BenchmarkTotalWords(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
- wordCount := TotalWords(totalWordsBenchmarkString)
+ wordCount := helpers.TotalWords(totalWordsBenchmarkString)
if wordCount != 400 {
b.Fatal("Wordcount error")
}
diff --git a/helpers/general.go b/helpers/general.go
index 920376227..e8d8bdecc 100644
--- a/helpers/general.go
+++ b/helpers/general.go
@@ -43,20 +43,6 @@ import (
// FilePathSeparator as defined by os.Separator.
const FilePathSeparator = string(filepath.Separator)
-// FindAvailablePort returns an available and valid TCP port.
-func FindAvailablePort() (*net.TCPAddr, error) {
- l, err := net.Listen("tcp", ":0")
- if err == nil {
- defer l.Close()
- addr := l.Addr()
- if a, ok := addr.(*net.TCPAddr); ok {
- return a, nil
- }
- return nil, fmt.Errorf("unable to obtain a valid tcp port: %v", addr)
- }
- return nil, err
-}
-
// TCPListen starts listening on a valid TCP port.
func TCPListen() (net.Listener, *net.TCPAddr, error) {
l, err := net.Listen("tcp", ":0")
diff --git a/helpers/general_test.go b/helpers/general_test.go
index b2ee03f15..9b2e4fc58 100644
--- a/helpers/general_test.go
+++ b/helpers/general_test.go
@@ -1,4 +1,4 @@
-// Copyright 2019 The Hugo Authors. All rights reserved.
+// Copyright 2023 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.
@@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package helpers
+package helpers_test
import (
"fmt"
@@ -21,17 +21,14 @@ import (
"time"
"github.com/gohugoio/hugo/common/loggers"
- "github.com/gohugoio/hugo/config"
+ "github.com/gohugoio/hugo/helpers"
qt "github.com/frankban/quicktest"
"github.com/spf13/afero"
)
func TestResolveMarkup(t *testing.T) {
- c := qt.New(t)
- cfg := config.NewWithTestDefaults()
- spec, err := NewContentSpec(cfg, loggers.NewErrorLogger(), afero.NewMemMapFs(), nil)
- c.Assert(err, qt.IsNil)
+ spec := newTestContentSpec(nil)
for i, this := range []struct {
in string
@@ -61,7 +58,7 @@ func TestResolveMarkup(t *testing.T) {
func TestDistinctLoggerDoesNotLockOnWarningPanic(t *testing.T) {
// Testing to make sure logger mutex doesn't lock if warnings cause panics.
// func Warnf() of DistinctLogger is defined in general.go
- l := NewDistinctLogger(loggers.NewWarningLogger())
+ l := helpers.NewDistinctLogger(loggers.NewWarningLogger())
// Set PanicOnWarning to true to reproduce issue 9380
// Ensure global variable loggers.PanicOnWarning is reset to old value after test
@@ -123,7 +120,7 @@ func TestFirstUpper(t *testing.T) {
{"", ""},
{"å", "Å"},
} {
- result := FirstUpper(this.in)
+ result := helpers.FirstUpper(this.in)
if result != this.expect {
t.Errorf("[%d] got %s but expected %s", i, result, this.expect)
}
@@ -143,7 +140,7 @@ func TestHasStringsPrefix(t *testing.T) {
{[]string{"abra", "ca", "dabra"}, []string{"abra", "ca"}, true},
{[]string{"abra", "ca"}, []string{"abra", "ca", "dabra"}, false},
} {
- result := HasStringsPrefix(this.s, this.prefix)
+ result := helpers.HasStringsPrefix(this.s, this.prefix)
if result != this.expect {
t.Fatalf("[%d] got %t but expected %t", i, result, this.expect)
}
@@ -162,7 +159,7 @@ func TestHasStringsSuffix(t *testing.T) {
{[]string{"abra", "ca", "dabra"}, []string{"abra", "ca"}, false},
{[]string{"abra", "ca", "dabra"}, []string{"ca", "dabra"}, true},
} {
- result := HasStringsSuffix(this.s, this.suffix)
+ result := helpers.HasStringsSuffix(this.s, this.suffix)
if result != this.expect {
t.Fatalf("[%d] got %t but expected %t", i, result, this.expect)
}
@@ -239,7 +236,7 @@ func TestSliceToLower(t *testing.T) {
}
for _, test := range tests {
- res := SliceToLower(test.value)
+ res := helpers.SliceToLower(test.value)
for i, val := range res {
if val != test.expected[i] {
t.Errorf("Case mismatch. Expected %s, got %s", test.expected[i], res[i])
@@ -251,34 +248,34 @@ func TestSliceToLower(t *testing.T) {
func TestReaderContains(t *testing.T) {
c := qt.New(t)
for i, this := range append(containsBenchTestData, containsAdditionalTestData...) {
- result := ReaderContains(strings.NewReader(this.v1), this.v2)
+ result := helpers.ReaderContains(strings.NewReader(this.v1), this.v2)
if result != this.expect {
t.Errorf("[%d] got %t but expected %t", i, result, this.expect)
}
}
- c.Assert(ReaderContains(nil, []byte("a")), qt.Equals, false)
- c.Assert(ReaderContains(nil, nil), qt.Equals, false)
+ c.Assert(helpers.ReaderContains(nil, []byte("a")), qt.Equals, false)
+ c.Assert(helpers.ReaderContains(nil, nil), qt.Equals, false)
}
func TestGetTitleFunc(t *testing.T) {
title := "somewhere over the rainbow"
c := qt.New(t)
- c.Assert(GetTitleFunc("go")(title), qt.Equals, "Somewhere Over The Rainbow")
- c.Assert(GetTitleFunc("chicago")(title), qt.Equals, "Somewhere over the Rainbow")
- c.Assert(GetTitleFunc("Chicago")(title), qt.Equals, "Somewhere over the Rainbow")
- c.Assert(GetTitleFunc("ap")(title), qt.Equals, "Somewhere Over the Rainbow")
- c.Assert(GetTitleFunc("ap")(title), qt.Equals, "Somewhere Over the Rainbow")
- c.Assert(GetTitleFunc("")(title), qt.Equals, "Somewhere Over the Rainbow")
- c.Assert(GetTitleFunc("unknown")(title), qt.Equals, "Somewhere Over the Rainbow")
+ c.Assert(helpers.GetTitleFunc("go")(title), qt.Equals, "Somewhere Over The Rainbow")
+ c.Assert(helpers.GetTitleFunc("chicago")(title), qt.Equals, "Somewhere over the Rainbow")
+ c.Assert(helpers.GetTitleFunc("Chicago")(title), qt.Equals, "Somewhere over the Rainbow")
+ c.Assert(helpers.GetTitleFunc("ap")(title), qt.Equals, "Somewhere Over the Rainbow")
+ c.Assert(helpers.GetTitleFunc("ap")(title), qt.Equals, "Somewhere Over the Rainbow")
+ c.Assert(helpers.GetTitleFunc("")(title), qt.Equals, "Somewhere Over the Rainbow")
+ c.Assert(helpers.GetTitleFunc("unknown")(title), qt.Equals, "Somewhere Over the Rainbow")
}
func BenchmarkReaderContains(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
for i, this := range containsBenchTestData {
- result := ReaderContains(strings.NewReader(this.v1), this.v2)
+ result := helpers.ReaderContains(strings.NewReader(this.v1), this.v2)
if result != this.expect {
b.Errorf("[%d] got %t but expected %t", i, result, this.expect)
}
@@ -288,7 +285,7 @@ func BenchmarkReaderContains(b *testing.B) {
func TestUniqueStrings(t *testing.T) {
in := []string{"a", "b", "a", "b", "c", "", "a", "", "d"}
- output := UniqueStrings(in)
+ output := helpers.UniqueStrings(in)
expected := []string{"a", "b", "c", "", "d"}
if !reflect.DeepEqual(output, expected) {
t.Errorf("Expected %#v, got %#v\n", expected, output)
@@ -297,7 +294,7 @@ func TestUniqueStrings(t *testing.T) {
func TestUniqueStringsReuse(t *testing.T) {
in := []string{"a", "b", "a", "b", "c", "", "a", "", "d"}
- output := UniqueStringsReuse(in)
+ output := helpers.UniqueStringsReuse(in)
expected := []string{"a", "b", "c", "", "d"}
if !reflect.DeepEqual(output, expected) {
t.Errorf("Expected %#v, got %#v\n", expected, output)
@@ -307,18 +304,10 @@ func TestUniqueStringsReuse(t *testing.T) {
func TestUniqueStringsSorted(t *testing.T) {
c := qt.New(t)
in := []string{"a", "a", "b", "c", "b", "", "a", "", "d"}
- output := UniqueStringsSorted(in)
+ output := helpers.UniqueStringsSorted(in)
expected := []string{"", "a", "b", "c", "d"}
c.Assert(output, qt.DeepEquals, expected)
- c.Assert(UniqueStringsSorted(nil), qt.IsNil)
-}
-
-func TestFindAvailablePort(t *testing.T) {
- c := qt.New(t)
- addr, err := FindAvailablePort()
- c.Assert(err, qt.IsNil)
- c.Assert(addr, qt.Not(qt.IsNil))
- c.Assert(addr.Port > 0, qt.Equals, true)
+ c.Assert(helpers.UniqueStringsSorted(nil), qt.IsNil)
}
func TestFastMD5FromFile(t *testing.T) {
@@ -357,23 +346,23 @@ func TestFastMD5FromFile(t *testing.T) {
defer bf1.Close()
defer bf2.Close()
- m1, err := MD5FromFileFast(sf1)
+ m1, err := helpers.MD5FromFileFast(sf1)
c.Assert(err, qt.IsNil)
c.Assert(m1, qt.Equals, "e9c8989b64b71a88b4efb66ad05eea96")
- m2, err := MD5FromFileFast(sf2)
+ m2, err := helpers.MD5FromFileFast(sf2)
c.Assert(err, qt.IsNil)
c.Assert(m2, qt.Not(qt.Equals), m1)
- m3, err := MD5FromFileFast(bf1)
+ m3, err := helpers.MD5FromFileFast(bf1)
c.Assert(err, qt.IsNil)
c.Assert(m3, qt.Not(qt.Equals), m2)
- m4, err := MD5FromFileFast(bf2)
+ m4, err := helpers.MD5FromFileFast(bf2)
c.Assert(err, qt.IsNil)
c.Assert(m4, qt.Not(qt.Equals), m3)
- m5, err := MD5FromReader(bf2)
+ m5, err := helpers.MD5FromReader(bf2)
c.Assert(err, qt.IsNil)
c.Assert(m5, qt.Not(qt.Equals), m4)
}
@@ -394,11 +383,11 @@ func BenchmarkMD5FromFileFast(b *testing.B) {
}
b.StartTimer()
if full {
- if _, err := MD5FromReader(f); err != nil {
+ if _, err := helpers.MD5FromReader(f); err != nil {
b.Fatal(err)
}
} else {
- if _, err := MD5FromFileFast(f); err != nil {
+ if _, err := helpers.MD5FromFileFast(f); err != nil {
b.Fatal(err)
}
}
@@ -413,7 +402,7 @@ func BenchmarkUniqueStrings(b *testing.B) {
b.Run("Safe", func(b *testing.B) {
for i := 0; i < b.N; i++ {
- result := UniqueStrings(input)
+ result := helpers.UniqueStrings(input)
if len(result) != 6 {
b.Fatal(fmt.Sprintf("invalid count: %d", len(result)))
}
@@ -432,7 +421,7 @@ func BenchmarkUniqueStrings(b *testing.B) {
for i := 0; i < b.N; i++ {
inputc := inputs[i]
- result := UniqueStringsReuse(inputc)
+ result := helpers.UniqueStringsReuse(inputc)
if len(result) != 6 {
b.Fatal(fmt.Sprintf("invalid count: %d", len(result)))
}
@@ -451,7 +440,7 @@ func BenchmarkUniqueStrings(b *testing.B) {
for i := 0; i < b.N; i++ {
inputc := inputs[i]
- result := UniqueStringsSorted(inputc)
+ result := helpers.UniqueStringsSorted(inputc)
if len(result) != 6 {
b.Fatal(fmt.Sprintf("invalid count: %d", len(result)))
}
diff --git a/helpers/path.go b/helpers/path.go
index 7bc216ec8..00c541bab 100644
--- a/helpers/path.go
+++ b/helpers/path.go
@@ -1,4 +1,4 @@
-// Copyright 2019 The Hugo Authors. All rights reserved.
+// Copyright 2023 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.
@@ -28,8 +28,6 @@ import (
"github.com/gohugoio/hugo/common/herrors"
"github.com/gohugoio/hugo/common/text"
- "github.com/gohugoio/hugo/config"
-
"github.com/gohugoio/hugo/hugofs"
"github.com/gohugoio/hugo/common/hugio"
@@ -54,7 +52,7 @@ func (p *PathSpec) MakePathsSanitized(paths []string) {
// MakePathSanitized creates a Unicode-sanitized string, with the spaces replaced
func (p *PathSpec) MakePathSanitized(s string) string {
- if p.DisablePathToLower {
+ if p.Cfg.DisablePathToLower() {
return p.MakePath(s)
}
return strings.ToLower(p.MakePath(s))
@@ -91,7 +89,7 @@ func ishex(c rune) bool {
// Hyphens in the original input are maintained.
// Spaces will be replaced with a single hyphen, and sequential replacement hyphens will be reduced to one.
func (p *PathSpec) UnicodeSanitize(s string) string {
- if p.RemovePathAccents {
+ if p.Cfg.RemovePathAccents() {
s = text.RemoveAccentsString(s)
}
@@ -128,7 +126,7 @@ func (p *PathSpec) UnicodeSanitize(s string) string {
return string(target)
}
-func makePathRelative(inPath string, possibleDirectories ...string) (string, error) {
+func MakePathRelative(inPath string, possibleDirectories ...string) (string, error) {
for _, currentPath := range possibleDirectories {
if strings.HasPrefix(inPath, currentPath) {
return strings.TrimPrefix(inPath, currentPath), nil
@@ -394,8 +392,8 @@ func OpenFileForWriting(fs afero.Fs, filename string) (afero.File, error) {
// GetCacheDir returns a cache dir from the given filesystem and config.
// The dir will be created if it does not exist.
-func GetCacheDir(fs afero.Fs, cfg config.Provider) (string, error) {
- cacheDir := getCacheDir(cfg)
+func GetCacheDir(fs afero.Fs, cacheDir string) (string, error) {
+ cacheDir = cacheDirDefault(cacheDir)
if cacheDir != "" {
exists, err := DirExists(cacheDir, fs)
if err != nil {
@@ -414,9 +412,8 @@ func GetCacheDir(fs afero.Fs, cfg config.Provider) (string, error) {
return GetTempDir("hugo_cache", fs), nil
}
-func getCacheDir(cfg config.Provider) string {
+func cacheDirDefault(cacheDir string) string {
// Always use the cacheDir config if set.
- cacheDir := cfg.GetString("cacheDir")
if len(cacheDir) > 1 {
return addTrailingFileSeparator(cacheDir)
}
diff --git a/helpers/path_test.go b/helpers/path_test.go
index 1f206a881..85081c5be 100644
--- a/helpers/path_test.go
+++ b/helpers/path_test.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The Hugo Authors. All rights reserved.
+// Copyright 2023 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.
@@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package helpers
+package helpers_test
import (
"fmt"
@@ -24,16 +24,12 @@ import (
"testing"
"time"
- "github.com/gohugoio/hugo/langs"
-
qt "github.com/frankban/quicktest"
-
- "github.com/gohugoio/hugo/hugofs"
+ "github.com/gohugoio/hugo/helpers"
"github.com/spf13/afero"
)
func TestMakePath(t *testing.T) {
- c := qt.New(t)
tests := []struct {
input string
expected string
@@ -60,13 +56,7 @@ func TestMakePath(t *testing.T) {
}
for _, test := range tests {
- v := newTestCfg()
- v.Set("removePathAccents", test.removeAccents)
-
- l := langs.NewDefaultLanguage(v)
- p, err := NewPathSpec(hugofs.NewMem(v), l, nil)
- c.Assert(err, qt.IsNil)
-
+ p := newTestPathSpec("removePathAccents", test.removeAccents)
output := p.MakePath(test.input)
if output != test.expected {
t.Errorf("Expected %#v, got %#v\n", test.expected, output)
@@ -75,9 +65,7 @@ func TestMakePath(t *testing.T) {
}
func TestMakePathSanitized(t *testing.T) {
- v := newTestCfg()
-
- p, _ := NewPathSpec(hugofs.NewMem(v), v, nil)
+ p := newTestPathSpec()
tests := []struct {
input string
@@ -100,12 +88,7 @@ func TestMakePathSanitized(t *testing.T) {
}
func TestMakePathSanitizedDisablePathToLower(t *testing.T) {
- v := newTestCfg()
-
- v.Set("disablePathToLower", true)
-
- l := langs.NewDefaultLanguage(v)
- p, _ := NewPathSpec(hugofs.NewMem(v), l, nil)
+ p := newTestPathSpec("disablePathToLower", true)
tests := []struct {
input string
@@ -138,12 +121,12 @@ func TestMakePathRelative(t *testing.T) {
}
for i, d := range data {
- output, _ := makePathRelative(d.inPath, d.path1, d.path2)
+ output, _ := helpers.MakePathRelative(d.inPath, d.path1, d.path2)
if d.output != output {
t.Errorf("Test #%d failed. Expected %q got %q", i, d.output, output)
}
}
- _, error := makePathRelative("a/b/c.ss", "/a/c", "/d/c", "/e/f")
+ _, error := helpers.MakePathRelative("a/b/c.ss", "/a/c", "/d/c", "/e/f")
if error == nil {
t.Errorf("Test failed, expected error")
@@ -181,7 +164,7 @@ func doTestGetDottedRelativePath(urlFixer func(string) string, t *testing.T) {
{"/404.html", "./"},
}
for i, d := range data {
- output := GetDottedRelativePath(d.input)
+ output := helpers.GetDottedRelativePath(d.input)
if d.expected != output {
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
}
@@ -198,7 +181,7 @@ func TestMakeTitle(t *testing.T) {
{"make_title", "make_title"},
}
for i, d := range data {
- output := MakeTitle(d.input)
+ output := helpers.MakeTitle(d.input)
if d.expected != output {
t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
}
@@ -219,7 +202,7 @@ func TestDirExists(t *testing.T) {
{"./..", true},
{"./../", true},
{os.TempDir(), true},
- {os.TempDir() + FilePathSeparator, true},
+ {os.TempDir() + helpers.FilePathSeparator, true},
{"/", true},
{"/some-really-random-directory-name", false},
{"/some/really/random/directory/name", false},
@@ -228,7 +211,7 @@ func TestDirExists(t *testing.T) {
}
for i, d := range data {
- exists, _ := DirExists(filepath.FromSlash(d.input), new(afero.OsFs))
+ exists, _ := helpers.DirExists(filepath.FromSlash(d.input), new(afero.OsFs))
if d.expected != exists {
t.Errorf("Test %d failed. Expected %t got %t", i, d.expected, exists)
}
@@ -249,7 +232,7 @@ func TestIsDir(t *testing.T) {
for i, d := range data {
- exists, _ := IsDir(d.input, new(afero.OsFs))
+ exists, _ := helpers.IsDir(d.input, new(afero.OsFs))
if d.expected != exists {
t.Errorf("Test %d failed. Expected %t got %t", i, d.expected, exists)
}
@@ -310,7 +293,7 @@ func TestExists(t *testing.T) {
{nonExistentDir, false, nil},
}
for i, d := range data {
- exists, err := Exists(d.input, new(afero.OsFs))
+ exists, err := helpers.Exists(d.input, new(afero.OsFs))
if d.expectedResult != exists {
t.Errorf("Test %d failed. Expected result %t got %t", i, d.expectedResult, exists)
}
@@ -341,7 +324,7 @@ func TestAbsPathify(t *testing.T) {
for i, d := range data {
// todo see comment in AbsPathify
- ps := newTestDefaultPathSpec("workingDir", d.workingDir)
+ ps := newTestPathSpec("workingDir", d.workingDir)
expected := ps.AbsPathify(d.inPath)
if d.expected != expected {
@@ -351,7 +334,7 @@ func TestAbsPathify(t *testing.T) {
t.Logf("Running platform specific path tests for %s", runtime.GOOS)
if runtime.GOOS == "windows" {
for i, d := range windowsData {
- ps := newTestDefaultPathSpec("workingDir", d.workingDir)
+ ps := newTestPathSpec("workingDir", d.workingDir)
expected := ps.AbsPathify(d.inPath)
if d.expected != expected {
@@ -360,7 +343,7 @@ func TestAbsPathify(t *testing.T) {
}
} else {
for i, d := range unixData {
- ps := newTestDefaultPathSpec("workingDir", d.workingDir)
+ ps := newTestPathSpec("workingDir", d.workingDir)
expected := ps.AbsPathify(d.inPath)
if d.expected != expected {
@@ -383,7 +366,7 @@ func TestExtractAndGroupRootPaths(t *testing.T) {
inCopy := make([]string, len(in))
copy(inCopy, in)
- result := ExtractAndGroupRootPaths(in)
+ result := helpers.ExtractAndGroupRootPaths(in)
c := qt.New(t)
c.Assert(fmt.Sprint(result), qt.Equals, filepath.FromSlash("[/a/b/{c,e} /c/d/e]"))
@@ -405,7 +388,7 @@ func TestExtractRootPaths(t *testing.T) {
}}
for _, test := range tests {
- output := ExtractRootPaths(test.input)
+ output := helpers.ExtractRootPaths(test.input)
if !reflect.DeepEqual(output, test.expected) {
t.Errorf("Expected %#v, got %#v\n", test.expected, output)
}
@@ -426,7 +409,7 @@ func TestFindCWD(t *testing.T) {
// I really don't know a better way to test this function. - SPF 2014.11.04
}
for i, d := range data {
- dir, err := FindCWD()
+ dir, err := helpers.FindCWD()
if d.expectedDir != dir {
t.Errorf("Test %d failed. Expected %q but got %q", i, d.expectedDir, dir)
}
@@ -459,7 +442,7 @@ func TestSafeWriteToDisk(t *testing.T) {
}
for i, d := range data {
- e := SafeWriteToDisk(d.filename, reader, new(afero.OsFs))
+ e := helpers.SafeWriteToDisk(d.filename, reader, new(afero.OsFs))
if d.expectedErr != nil {
if d.expectedErr.Error() != e.Error() {
t.Errorf("Test %d failed. Expected error %q but got %q", i, d.expectedErr.Error(), e.Error())
@@ -498,7 +481,7 @@ func TestWriteToDisk(t *testing.T) {
}
for i, d := range data {
- e := WriteToDisk(d.filename, reader, new(afero.OsFs))
+ e := helpers.WriteToDisk(d.filename, reader, new(afero.OsFs))
if d.expectedErr != e {
t.Errorf("Test %d failed. WriteToDisk Error Expected %q but got %q", i, d.expectedErr, e)
}
@@ -515,27 +498,27 @@ func TestWriteToDisk(t *testing.T) {
func TestGetTempDir(t *testing.T) {
dir := os.TempDir()
- if FilePathSeparator != dir[len(dir)-1:] {
- dir = dir + FilePathSeparator
+ if helpers.FilePathSeparator != dir[len(dir)-1:] {
+ dir = dir + helpers.FilePathSeparator
}
- testDir := "hugoTestFolder" + FilePathSeparator
+ testDir := "hugoTestFolder" + helpers.FilePathSeparator
tests := []struct {
input string
expected string
}{
{"", dir},
- {testDir + " Foo bar ", dir + testDir + " Foo bar " + FilePathSeparator},
- {testDir + "Foo.Bar/foo_Bar-Foo", dir + testDir + "Foo.Bar/foo_Bar-Foo" + FilePathSeparator},
- {testDir + "fOO,bar:foo%bAR", dir + testDir + "fOObarfoo%bAR" + FilePathSeparator},
- {testDir + "fOO,bar:foobAR", dir + testDir + "fOObarfoobAR" + FilePathSeparator},
- {testDir + "FOo/BaR.html", dir + testDir + "FOo/BaR.html" + FilePathSeparator},
- {testDir + "трям/трям", dir + testDir + "трям/трям" + FilePathSeparator},
- {testDir + "은행", dir + testDir + "은행" + FilePathSeparator},
- {testDir + "Банковский кассир", dir + testDir + "Банковский кассир" + FilePathSeparator},
+ {testDir + " Foo bar ", dir + testDir + " Foo bar " + helpers.FilePathSeparator},
+ {testDir + "Foo.Bar/foo_Bar-Foo", dir + testDir + "Foo.Bar/foo_Bar-Foo" + helpers.FilePathSeparator},
+ {testDir + "fOO,bar:foo%bAR", dir + testDir + "fOObarfoo%bAR" + helpers.FilePathSeparator},
+ {testDir + "fOO,bar:foobAR", dir + testDir + "fOObarfoobAR" + helpers.FilePathSeparator},
+ {testDir + "FOo/BaR.html", dir + testDir + "FOo/BaR.html" + helpers.FilePathSeparator},
+ {testDir + "трям/трям", dir + testDir + "трям/трям" + helpers.FilePathSeparator},
+ {testDir + "은행", dir + testDir + "은행" + helpers.FilePathSeparator},
+ {testDir + "Банковский кассир", dir + testDir + "Банковский кассир" + helpers.FilePathSeparator},
}
for _, test := range tests {
- output := GetTempDir(test.input, new(afero.MemMapFs))
+ output := helpers.GetTempDir(test.input, new(afero.MemMapFs))
if output != test.expected {
t.Errorf("Expected %#v, got %#v\n", test.expected, output)
}
diff --git a/helpers/pathspec.go b/helpers/pathspec.go
index 28b5f71c3..c9bb49038 100644
--- a/helpers/pathspec.go
+++ b/helpers/pathspec.go
@@ -34,17 +34,17 @@ type PathSpec struct {
Fs *hugofs.Fs
// The config provider to use
- Cfg config.Provider
+ Cfg config.AllProvider
}
// NewPathSpec creates a new PathSpec from the given filesystems and language.
-func NewPathSpec(fs *hugofs.Fs, cfg config.Provider, logger loggers.Logger) (*PathSpec, error) {
+func NewPathSpec(fs *hugofs.Fs, cfg config.AllProvider, logger loggers.Logger) (*PathSpec, error) {
return NewPathSpecWithBaseBaseFsProvided(fs, cfg, logger, nil)
}
// NewPathSpecWithBaseBaseFsProvided creates a new PathSpec from the given filesystems and language.
// If an existing BaseFs is provided, parts of that is reused.
-func NewPathSpecWithBaseBaseFsProvided(fs *hugofs.Fs, cfg config.Provider, logger loggers.Logger, baseBaseFs *filesystems.BaseFs) (*PathSpec, error) {
+func NewPathSpecWithBaseBaseFsProvided(fs *hugofs.Fs, cfg config.AllProvider, logger loggers.Logger, baseBaseFs *filesystems.BaseFs) (*PathSpec, error) {
p, err := paths.New(fs, cfg)
if err != nil {
return nil, err
@@ -69,11 +69,6 @@ func NewPathSpecWithBaseBaseFsProvided(fs *hugofs.Fs, cfg config.Provider, logge
ProcessingStats: NewProcessingStats(p.Lang()),
}
- basePath := ps.BaseURL.Path()
- if basePath != "" && basePath != "/" {
- ps.BasePath = basePath
- }
-
return ps, nil
}
diff --git a/helpers/pathspec_test.go b/helpers/pathspec_test.go
deleted file mode 100644
index 84448050d..000000000
--- a/helpers/pathspec_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 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 helpers
-
-import (
- "path/filepath"
- "testing"
-
- qt "github.com/frankban/quicktest"
- "github.com/gohugoio/hugo/hugofs"
-
- "github.com/gohugoio/hugo/langs"
-)
-
-func TestNewPathSpecFromConfig(t *testing.T) {
- c := qt.New(t)
- v := newTestCfg()
- l := langs.NewLanguage("no", v)
- v.Set("disablePathToLower", true)
- v.Set("removePathAccents", true)
- v.Set("uglyURLs", true)
- v.Set("canonifyURLs", true)
- v.Set("paginatePath", "side")
- v.Set("baseURL", "http://base.com/foo")
- v.Set("themesDir", "thethemes")
- v.Set("layoutDir", "thelayouts")
- v.Set("workingDir", "thework")
- v.Set("staticDir", "thestatic")
- v.Set("theme", "thetheme")
- langs.LoadLanguageSettings(v, nil)
-
- fs := hugofs.NewMem(v)
- fs.Source.MkdirAll(filepath.FromSlash("thework/thethemes/thetheme"), 0777)
-
- p, err := NewPathSpec(fs, l, nil)
-
- c.Assert(err, qt.IsNil)
- c.Assert(p.CanonifyURLs, qt.Equals, true)
- c.Assert(p.DisablePathToLower, qt.Equals, true)
- c.Assert(p.RemovePathAccents, qt.Equals, true)
- c.Assert(p.UglyURLs, qt.Equals, true)
- c.Assert(p.Language.Lang, qt.Equals, "no")
- c.Assert(p.PaginatePath, qt.Equals, "side")
-
- c.Assert(p.BaseURL.String(), qt.Equals, "http://base.com/foo")
- c.Assert(p.BaseURLString, qt.Equals, "http://base.com/foo")
- c.Assert(p.BaseURLNoPathString, qt.Equals, "http://base.com")
-
- c.Assert(p.ThemesDir, qt.Equals, "thethemes")
- c.Assert(p.WorkingDir, qt.Equals, "thework")
-}
diff --git a/helpers/testhelpers_test.go b/helpers/testhelpers_test.go
index 00be3db25..be8983fdb 100644
--- a/helpers/testhelpers_test.go
+++ b/helpers/testhelpers_test.go
@@ -1,47 +1,47 @@
-package helpers
+package helpers_test
import (
"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/config"
- "github.com/spf13/afero"
-
+ "github.com/gohugoio/hugo/config/testconfig"
+ "github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugofs"
- "github.com/gohugoio/hugo/langs"
- "github.com/gohugoio/hugo/modules"
+ "github.com/spf13/afero"
)
-func newTestPathSpec(fs *hugofs.Fs, v config.Provider) *PathSpec {
- l := langs.NewDefaultLanguage(v)
- ps, _ := NewPathSpec(fs, l, nil)
+func newTestPathSpecFromCfgAndLang(cfg config.Provider, lang string) *helpers.PathSpec {
+ mfs := afero.NewMemMapFs()
+
+ configs := testconfig.GetTestConfigs(mfs, cfg)
+ var conf config.AllProvider
+ if lang == "" {
+ conf = configs.GetFirstLanguageConfig()
+ } else {
+ conf = configs.GetByLang(lang)
+ if conf == nil {
+ panic("no config for lang " + lang)
+ }
+ }
+ fs := hugofs.NewFrom(mfs, conf.BaseConfig())
+ ps, err := helpers.NewPathSpec(fs, conf, loggers.NewErrorLogger())
+ if err != nil {
+ panic(err)
+ }
return ps
}
-func newTestDefaultPathSpec(configKeyValues ...any) *PathSpec {
- cfg := newTestCfg()
- fs := hugofs.NewMem(cfg)
-
+func newTestPathSpec(configKeyValues ...any) *helpers.PathSpec {
+ cfg := config.New()
for i := 0; i < len(configKeyValues); i += 2 {
cfg.Set(configKeyValues[i].(string), configKeyValues[i+1])
}
- return newTestPathSpec(fs, cfg)
-}
-
-func newTestCfg() config.Provider {
- v := config.NewWithTestDefaults()
- langs.LoadLanguageSettings(v, nil)
- langs.LoadLanguageSettings(v, nil)
- mod, err := modules.CreateProjectModule(v)
- if err != nil {
- panic(err)
- }
- v.Set("allModules", modules.Modules{mod})
-
- return v
+ return newTestPathSpecFromCfgAndLang(cfg, "")
}
-func newTestContentSpec() *ContentSpec {
- v := config.NewWithTestDefaults()
- spec, err := NewContentSpec(v, loggers.NewErrorLogger(), afero.NewMemMapFs(), nil)
+func newTestContentSpec(cfg config.Provider) *helpers.ContentSpec {
+ fs := afero.NewMemMapFs()
+ conf := testconfig.GetTestConfig(fs, cfg)
+ spec, err := helpers.NewContentSpec(conf, loggers.NewErrorLogger(), fs, nil)
if err != nil {
panic(err)
}
diff --git a/helpers/url.go b/helpers/url.go
index 7cb998ca2..a4c20c6ad 100644
--- a/helpers/url.go
+++ b/helpers/url.go
@@ -71,8 +71,9 @@ func SanitizeURLKeepTrailingSlash(in string) string {
// URLize is similar to MakePath, but with Unicode handling
// Example:
-// uri: Vim (text editor)
-// urlize: vim-text-editor
+//
+// uri: Vim (text editor)
+// urlize: vim-text-editor
func (p *PathSpec) URLize(uri string) string {
return p.URLEscape(p.MakePathSanitized(uri))
}
@@ -141,16 +142,16 @@ func (p *PathSpec) AbsURL(in string, addLanguage bool) string {
func (p *PathSpec) getBaseURLRoot(path string) string {
if strings.HasPrefix(path, "/") {
// Treat it as relative to the server root.
- return p.BaseURLNoPathString
+ return p.Cfg.BaseURL().WithoutPath
} else {
// Treat it as relative to the baseURL.
- return p.BaseURLString
+ return p.Cfg.BaseURL().WithPath
}
}
func (p *PathSpec) RelURL(in string, addLanguage bool) string {
baseURL := p.getBaseURLRoot(in)
- canonifyURLs := p.CanonifyURLs
+ canonifyURLs := p.Cfg.CanonifyURLs()
if (!strings.HasPrefix(in, baseURL) && strings.HasPrefix(in, "http")) || strings.HasPrefix(in, "//") {
return in
}
@@ -217,25 +218,3 @@ func (p *PathSpec) PrependBasePath(rel string, isAbs bool) string {
}
return rel
}
-
-// URLizeAndPrep applies misc sanitation to the given URL to get it in line
-// with the Hugo standard.
-func (p *PathSpec) URLizeAndPrep(in string) string {
- return p.URLPrep(p.URLize(in))
-}
-
-// URLPrep applies misc sanitation to the given URL.
-func (p *PathSpec) URLPrep(in string) string {
- if p.UglyURLs {
- return paths.Uglify(SanitizeURL(in))
- }
- pretty := paths.PrettifyURL(SanitizeURL(in))
- if path.Ext(pretty) == ".xml" {
- return pretty
- }
- url, err := purell.NormalizeURLString(pretty, purell.FlagAddTrailingSlash)
- if err != nil {
- return pretty
- }
- return url
-}
diff --git a/helpers/url_test.go b/helpers/url_test.go
index e248036ae..787cdd6e8 100644
--- a/helpers/url_test.go
+++ b/helpers/url_test.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The Hugo Authors. All rights reserved.
+// Copyright 2023 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.
@@ -11,21 +11,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package helpers
+package helpers_test
import (
+ "fmt"
"strings"
"testing"
qt "github.com/frankban/quicktest"
- "github.com/gohugoio/hugo/hugofs"
- "github.com/gohugoio/hugo/langs"
+ "github.com/gohugoio/hugo/config"
+ "github.com/gohugoio/hugo/helpers"
)
func TestURLize(t *testing.T) {
- v := newTestCfg()
- l := langs.NewDefaultLanguage(v)
- p, _ := NewPathSpec(hugofs.NewMem(v), l, nil)
+ p := newTestPathSpec()
tests := []struct {
input string
@@ -61,10 +60,6 @@ func TestAbsURL(t *testing.T) {
func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool, lang string) {
c := qt.New(t)
- v := newTestCfg()
- v.Set("multilingual", multilingual)
- v.Set("defaultContentLanguage", "en")
- v.Set("defaultContentLanguageInSubdir", defaultInSubDir)
tests := []struct {
input string
@@ -103,24 +98,42 @@ func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
}
for _, test := range tests {
- v.Set("baseURL", test.baseURL)
- v.Set("contentDir", "content")
- l := langs.NewLanguage(lang, v)
- p, _ := NewPathSpec(hugofs.NewMem(v), l, nil)
-
- output := p.AbsURL(test.input, addLanguage)
- expected := test.expected
- if multilingual && addLanguage {
- if !defaultInSubDir && lang == "en" {
- expected = strings.Replace(expected, "MULTI", "", 1)
+ c.Run(fmt.Sprintf("%v/%t-%t-%t/%s", test, defaultInSubDir, addLanguage, multilingual, lang), func(c *qt.C) {
+ v := config.New()
+ if multilingual {
+ v.Set("languages", map[string]any{
+ "fr": map[string]interface{}{
+ "weight": 20,
+ },
+ "en": map[string]interface{}{
+ "weight": 10,
+ },
+ })
+ }
+ v.Set("defaultContentLanguage", "en")
+ v.Set("defaultContentLanguageInSubdir", defaultInSubDir)
+ v.Set("baseURL", test.baseURL)
+
+ var configLang string
+ if multilingual {
+ configLang = lang
+ }
+ p := newTestPathSpecFromCfgAndLang(v, configLang)
+
+ output := p.AbsURL(test.input, addLanguage)
+ expected := test.expected
+ if multilingual && addLanguage {
+ if !defaultInSubDir && lang == "en" {
+ expected = strings.Replace(expected, "MULTI", "", 1)
+ } else {
+ expected = strings.Replace(expected, "MULTI", lang+"/", 1)
+ }
} else {
- expected = strings.Replace(expected, "MULTI", lang+"/", 1)
+ expected = strings.Replace(expected, "MULTI", "", 1)
}
- } else {
- expected = strings.Replace(expected, "MULTI", "", 1)
- }
- c.Assert(output, qt.Equals, expected)
+ c.Assert(output, qt.Equals, expected)
+ })
}
}
@@ -137,9 +150,19 @@ func TestRelURL(t *testing.T) {
}
func doTestRelURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool, lang string) {
+ t.Helper()
c := qt.New(t)
- v := newTestCfg()
- v.Set("multilingual", multilingual)
+ v := config.New()
+ if multilingual {
+ v.Set("languages", map[string]any{
+ "fr": map[string]interface{}{
+ "weight": 20,
+ },
+ "en": map[string]interface{}{
+ "weight": 10,
+ },
+ })
+ }
v.Set("defaultContentLanguage", "en")
v.Set("defaultContentLanguageInSubdir", defaultInSubDir)
@@ -182,25 +205,31 @@ func doTestRelURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
}
for i, test := range tests {
- v.Set("baseURL", test.baseURL)
- v.Set("canonifyURLs", test.canonify)
- l := langs.NewLanguage(lang, v)
- p, _ := NewPathSpec(hugofs.NewMem(v), l, nil)
+ c.Run(fmt.Sprintf("%v/%t%t%t/%s", test, defaultInSubDir, addLanguage, multilingual, lang), func(c *qt.C) {
- output := p.RelURL(test.input, addLanguage)
+ v.Set("baseURL", test.baseURL)
+ v.Set("canonifyURLs", test.canonify)
+ var configLang string
+ if multilingual {
+ configLang = lang
+ }
+ p := newTestPathSpecFromCfgAndLang(v, configLang)
- expected := test.expected
- if multilingual && addLanguage {
- if !defaultInSubDir && lang == "en" {
- expected = strings.Replace(expected, "MULTI", "", 1)
+ output := p.RelURL(test.input, addLanguage)
+
+ expected := test.expected
+ if multilingual && addLanguage {
+ if !defaultInSubDir && lang == "en" {
+ expected = strings.Replace(expected, "MULTI", "", 1)
+ } else {
+ expected = strings.Replace(expected, "MULTI", "/"+lang, 1)
+ }
} else {
- expected = strings.Replace(expected, "MULTI", "/"+lang, 1)
+ expected = strings.Replace(expected, "MULTI", "", 1)
}
- } else {
- expected = strings.Replace(expected, "MULTI", "", 1)
- }
- c.Assert(output, qt.Equals, expected, qt.Commentf("[%d] %s", i, test.input))
+ c.Assert(output, qt.Equals, expected, qt.Commentf("[%d] %s", i, test.input))
+ })
}
}
@@ -216,8 +245,8 @@ func TestSanitizeURL(t *testing.T) {
}
for i, test := range tests {
- o1 := SanitizeURL(test.input)
- o2 := SanitizeURLKeepTrailingSlash(test.input)
+ o1 := helpers.SanitizeURL(test.input)
+ o2 := helpers.SanitizeURLKeepTrailingSlash(test.input)
expected2 := test.expected
@@ -233,28 +262,3 @@ func TestSanitizeURL(t *testing.T) {
}
}
}
-
-func TestURLPrep(t *testing.T) {
- type test struct {
- ugly bool
- input string
- output string
- }
-
- data := []test{
- {false, "/section/name.html", "/section/name/"},
- {true, "/section/name/index.html", "/section/name.html"},
- }
-
- for i, d := range data {
- v := newTestCfg()
- v.Set("uglyURLs", d.ugly)
- l := langs.NewDefaultLanguage(v)
- p, _ := NewPathSpec(hugofs.NewMem(v), l, nil)
-
- output := p.URLPrep(d.input)
- if d.output != output {
- t.Errorf("Test #%d failed. Expected %q got %q", i, d.output, output)
- }
- }
-}