mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-24 15:28:54 +00:00
committed by
Bjørn Erik Pedersen
parent
7a43b928a6
commit
1a1b062a01
@@ -221,3 +221,24 @@ func (ns *Namespace) JoinPath(elements ...any) (string, error) {
|
|||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PathEscape returns the given string, applying percent-encoding to special
|
||||||
|
// characters and reserved delimiters so it can be safely used as a segment
|
||||||
|
// within a URL path.
|
||||||
|
func (ns *Namespace) PathEscape(s any) (string, error) {
|
||||||
|
ss, err := cast.ToStringE(s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return url.PathEscape(ss), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathUnescape returns the given string, replacing all percent-encoded
|
||||||
|
// sequences with the corresponding unescaped characters.
|
||||||
|
func (ns *Namespace) PathUnescape(s any) (string, error) {
|
||||||
|
ss, err := cast.ToStringE(s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return url.PathUnescape(ss)
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ package urls
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/config/testconfig"
|
"github.com/gohugoio/hugo/config/testconfig"
|
||||||
@@ -105,3 +106,82 @@ func TestJoinPath(t *testing.T) {
|
|||||||
c.Assert(result, qt.Equals, test.expect)
|
c.Assert(result, qt.Equals, test.expect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPathEscape(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
c := qt.New(t)
|
||||||
|
ns := newNs()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input any
|
||||||
|
want string
|
||||||
|
wantErr bool
|
||||||
|
errCheck string
|
||||||
|
}{
|
||||||
|
{"string", "A/b/c?d=é&f=g+h", "A%2Fb%2Fc%3Fd=%C3%A9&f=g+h", false, ""},
|
||||||
|
{"empty string", "", "", false, ""},
|
||||||
|
{"integer", 6, "6", false, ""},
|
||||||
|
{"float", 7.42, "7.42", false, ""},
|
||||||
|
{"nil", nil, "", false, ""},
|
||||||
|
{"slice", []int{}, "", true, "unable to cast"},
|
||||||
|
{"map", map[string]string{}, "", true, "unable to cast"},
|
||||||
|
{"struct", tstNoStringer{}, "", true, "unable to cast"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
c.Run(tt.name, func(c *qt.C) {
|
||||||
|
got, err := ns.PathEscape(tt.input)
|
||||||
|
if tt.wantErr {
|
||||||
|
c.Assert(err, qt.IsNotNil, qt.Commentf("PathEscape(%v) should have failed", tt.input))
|
||||||
|
if tt.errCheck != "" {
|
||||||
|
c.Assert(err, qt.ErrorMatches, ".*"+regexp.QuoteMeta(tt.errCheck)+".*")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.Assert(err, qt.IsNil)
|
||||||
|
c.Assert(got, qt.Equals, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPathUnescape(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
c := qt.New(t)
|
||||||
|
ns := newNs()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input any
|
||||||
|
want string
|
||||||
|
wantErr bool
|
||||||
|
errCheck string
|
||||||
|
}{
|
||||||
|
{"string", "A%2Fb%2Fc%3Fd=%C3%A9&f=g+h", "A/b/c?d=é&f=g+h", false, ""},
|
||||||
|
{"empty string", "", "", false, ""},
|
||||||
|
{"integer", 6, "6", false, ""},
|
||||||
|
{"float", 7.42, "7.42", false, ""},
|
||||||
|
{"nil", nil, "", false, ""},
|
||||||
|
{"slice", []int{}, "", true, "unable to cast"},
|
||||||
|
{"map", map[string]string{}, "", true, "unable to cast"},
|
||||||
|
{"struct", tstNoStringer{}, "", true, "unable to cast"},
|
||||||
|
{"malformed hex", "bad%g0escape", "", true, "invalid URL escape"},
|
||||||
|
{"incomplete hex", "trailing%", "", true, "invalid URL escape"},
|
||||||
|
{"single hex digit", "trail%1", "", true, "invalid URL escape"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
c.Run(tt.name, func(c *qt.C) {
|
||||||
|
got, err := ns.PathUnescape(tt.input)
|
||||||
|
if tt.wantErr {
|
||||||
|
c.Assert(err, qt.Not(qt.IsNil), qt.Commentf("PathUnescape(%v) should have failed", tt.input))
|
||||||
|
if tt.errCheck != "" {
|
||||||
|
c.Assert(err, qt.ErrorMatches, ".*"+regexp.QuoteMeta(tt.errCheck)+".*")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.Assert(err, qt.IsNil)
|
||||||
|
c.Assert(got, qt.Equals, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user