URI: 
       path_test.go - hugo - [fork] hugo port for 9front
  HTML git clone https://git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       path_test.go (9146B)
       ---
            1 // Copyright 2024 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 paths
           15 
           16 import (
           17         "path/filepath"
           18         "testing"
           19 
           20         qt "github.com/frankban/quicktest"
           21 )
           22 
           23 func TestGetRelativePath(t *testing.T) {
           24         tests := []struct {
           25                 path   string
           26                 base   string
           27                 expect any
           28         }{
           29                 {filepath.FromSlash("/a/b"), filepath.FromSlash("/a"), filepath.FromSlash("b")},
           30                 {filepath.FromSlash("/a/b/c/"), filepath.FromSlash("/a"), filepath.FromSlash("b/c/")},
           31                 {filepath.FromSlash("/c"), filepath.FromSlash("/a/b"), filepath.FromSlash("../../c")},
           32                 {filepath.FromSlash("/c"), "", false},
           33         }
           34         for i, this := range tests {
           35                 // ultimately a fancy wrapper around filepath.Rel
           36                 result, err := GetRelativePath(this.path, this.base)
           37 
           38                 if b, ok := this.expect.(bool); ok && !b {
           39                         if err == nil {
           40                                 t.Errorf("[%d] GetRelativePath didn't return an expected error", i)
           41                         }
           42                 } else {
           43                         if err != nil {
           44                                 t.Errorf("[%d] GetRelativePath failed: %s", i, err)
           45                                 continue
           46                         }
           47                         if result != this.expect {
           48                                 t.Errorf("[%d] GetRelativePath got %v but expected %v", i, result, this.expect)
           49                         }
           50                 }
           51 
           52         }
           53 }
           54 
           55 func TestMakePathRelative(t *testing.T) {
           56         type test struct {
           57                 inPath, path1, path2, output string
           58         }
           59 
           60         data := []test{
           61                 {"/abc/bcd/ab.css", "/abc/bcd", "/bbc/bcd", "/ab.css"},
           62                 {"/abc/bcd/ab.css", "/abcd/bcd", "/abc/bcd", "/ab.css"},
           63         }
           64 
           65         for i, d := range data {
           66                 output, _ := makePathRelative(d.inPath, d.path1, d.path2)
           67                 if d.output != output {
           68                         t.Errorf("Test #%d failed. Expected %q got %q", i, d.output, output)
           69                 }
           70         }
           71         _, error := makePathRelative("a/b/c.ss", "/a/c", "/d/c", "/e/f")
           72 
           73         if error == nil {
           74                 t.Errorf("Test failed, expected error")
           75         }
           76 }
           77 
           78 func TestMakeTitle(t *testing.T) {
           79         type test struct {
           80                 input, expected string
           81         }
           82         data := []test{
           83                 {"Make-Title", "Make Title"},
           84                 {"MakeTitle", "MakeTitle"},
           85                 {"make_title", "make_title"},
           86         }
           87         for i, d := range data {
           88                 output := MakeTitle(d.input)
           89                 if d.expected != output {
           90                         t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
           91                 }
           92         }
           93 }
           94 
           95 // Replace Extension is probably poorly named, but the intent of the
           96 // function is to accept a path and return only the file name with a
           97 // new extension. It's intentionally designed to strip out the path
           98 // and only provide the name. We should probably rename the function to
           99 // be more explicit at some point.
          100 func TestReplaceExtension(t *testing.T) {
          101         type test struct {
          102                 input, newext, expected string
          103         }
          104         data := []test{
          105                 // These work according to the above definition
          106                 {"/some/random/path/file.xml", "html", "file.html"},
          107                 {"/banana.html", "xml", "banana.xml"},
          108                 {"./banana.html", "xml", "banana.xml"},
          109                 {"banana/pie/index.html", "xml", "index.xml"},
          110                 {"../pies/fish/index.html", "xml", "index.xml"},
          111                 // but these all fail
          112                 {"filename-without-an-ext", "ext", "filename-without-an-ext.ext"},
          113                 {"/filename-without-an-ext", "ext", "filename-without-an-ext.ext"},
          114                 {"/directory/mydir/", "ext", ".ext"},
          115                 {"mydir/", "ext", ".ext"},
          116         }
          117 
          118         for i, d := range data {
          119                 output := ReplaceExtension(filepath.FromSlash(d.input), d.newext)
          120                 if d.expected != output {
          121                         t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
          122                 }
          123         }
          124 }
          125 
          126 func TestExtNoDelimiter(t *testing.T) {
          127         c := qt.New(t)
          128         c.Assert(ExtNoDelimiter(filepath.FromSlash("/my/data.json")), qt.Equals, "json")
          129 }
          130 
          131 func TestFilename(t *testing.T) {
          132         type test struct {
          133                 input, expected string
          134         }
          135         data := []test{
          136                 {"index.html", "index"},
          137                 {"./index.html", "index"},
          138                 {"/index.html", "index"},
          139                 {"index", "index"},
          140                 {"/tmp/index.html", "index"},
          141                 {"./filename-no-ext", "filename-no-ext"},
          142                 {"/filename-no-ext", "filename-no-ext"},
          143                 {"filename-no-ext", "filename-no-ext"},
          144                 {"directory/", ""}, // no filename case??
          145                 {"directory/.hidden.ext", ".hidden"},
          146                 {"./directory/../~/banana/gold.fish", "gold"},
          147                 {"../directory/banana.man", "banana"},
          148                 {"~/mydir/filename.ext", "filename"},
          149                 {"./directory//tmp/filename.ext", "filename"},
          150         }
          151 
          152         for i, d := range data {
          153                 output := Filename(filepath.FromSlash(d.input))
          154                 if d.expected != output {
          155                         t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, output)
          156                 }
          157         }
          158 }
          159 
          160 func TestFileAndExt(t *testing.T) {
          161         type test struct {
          162                 input, expectedFile, expectedExt string
          163         }
          164         data := []test{
          165                 {"index.html", "index", ".html"},
          166                 {"./index.html", "index", ".html"},
          167                 {"/index.html", "index", ".html"},
          168                 {"index", "index", ""},
          169                 {"/tmp/index.html", "index", ".html"},
          170                 {"./filename-no-ext", "filename-no-ext", ""},
          171                 {"/filename-no-ext", "filename-no-ext", ""},
          172                 {"filename-no-ext", "filename-no-ext", ""},
          173                 {"directory/", "", ""}, // no filename case??
          174                 {"directory/.hidden.ext", ".hidden", ".ext"},
          175                 {"./directory/../~/banana/gold.fish", "gold", ".fish"},
          176                 {"../directory/banana.man", "banana", ".man"},
          177                 {"~/mydir/filename.ext", "filename", ".ext"},
          178                 {"./directory//tmp/filename.ext", "filename", ".ext"},
          179         }
          180 
          181         for i, d := range data {
          182                 file, ext := fileAndExt(filepath.FromSlash(d.input), fpb)
          183                 if d.expectedFile != file {
          184                         t.Errorf("Test %d failed. Expected filename %q got %q.", i, d.expectedFile, file)
          185                 }
          186                 if d.expectedExt != ext {
          187                         t.Errorf("Test %d failed. Expected extension %q got %q.", i, d.expectedExt, ext)
          188                 }
          189         }
          190 }
          191 
          192 func TestSanitize(t *testing.T) {
          193         c := qt.New(t)
          194         tests := []struct {
          195                 input    string
          196                 expected string
          197         }{
          198                 {"  Foo bar  ", "Foo-bar"},
          199                 {"Foo.Bar/foo_Bar-Foo", "Foo.Bar/foo_Bar-Foo"},
          200                 {"fOO,bar:foobAR", "fOObarfoobAR"},
          201                 {"FOo/BaR.html", "FOo/BaR.html"},
          202                 {"FOo/Ba---R.html", "FOo/Ba---R.html"}, /// See #10104
          203                 {"FOo/Ba       R.html", "FOo/Ba-R.html"},
          204                 {"трям/трям", "трям/трям"},
          205                 {"은행", "은행"},
          206                 {"Банковский кассир", "Банковский-кассир"},
          207                 // Issue #1488
          208                 {"संस्कृत", "संस्कृत"},
          209                 {"a%C3%B1ame", "a%C3%B1ame"},         // Issue #1292
          210                 {"this+is+a+test", "this+is+a+test"}, // Issue #1290
          211                 {"~foo", "~foo"},                     // Issue #2177
          212 
          213         }
          214 
          215         for _, test := range tests {
          216                 c.Assert(Sanitize(test.input), qt.Equals, test.expected)
          217         }
          218 }
          219 
          220 func BenchmarkSanitize(b *testing.B) {
          221         const (
          222                 allAlowedPath = "foo/bar"
          223                 spacePath     = "foo bar"
          224         )
          225 
          226         // This should not allocate any memory.
          227         b.Run("All allowed", func(b *testing.B) {
          228                 for i := 0; i < b.N; i++ {
          229                         got := Sanitize(allAlowedPath)
          230                         if got != allAlowedPath {
          231                                 b.Fatal(got)
          232                         }
          233                 }
          234         })
          235 
          236         // This will allocate some memory.
          237         b.Run("Spaces", func(b *testing.B) {
          238                 for i := 0; i < b.N; i++ {
          239                         got := Sanitize(spacePath)
          240                         if got != "foo-bar" {
          241                                 b.Fatal(got)
          242                         }
          243                 }
          244         })
          245 }
          246 
          247 func TestDir(t *testing.T) {
          248         c := qt.New(t)
          249         c.Assert(Dir("/a/b/c/d"), qt.Equals, "/a/b/c")
          250         c.Assert(Dir("/a"), qt.Equals, "/")
          251         c.Assert(Dir("/"), qt.Equals, "/")
          252         c.Assert(Dir(""), qt.Equals, "")
          253 }
          254 
          255 func TestFieldsSlash(t *testing.T) {
          256         c := qt.New(t)
          257 
          258         c.Assert(FieldsSlash("a/b/c"), qt.DeepEquals, []string{"a", "b", "c"})
          259         c.Assert(FieldsSlash("/a/b/c"), qt.DeepEquals, []string{"a", "b", "c"})
          260         c.Assert(FieldsSlash("/a/b/c/"), qt.DeepEquals, []string{"a", "b", "c"})
          261         c.Assert(FieldsSlash("a/b/c/"), qt.DeepEquals, []string{"a", "b", "c"})
          262         c.Assert(FieldsSlash("/"), qt.DeepEquals, []string{})
          263         c.Assert(FieldsSlash(""), qt.DeepEquals, []string{})
          264 }
          265 
          266 func TestCommonDirPath(t *testing.T) {
          267         c := qt.New(t)
          268 
          269         for _, this := range []struct {
          270                 a, b, expected string
          271         }{
          272                 {"/a/b/c", "/a/b/d", "/a/b"},
          273                 {"/a/b/c", "a/b/d", "/a/b"},
          274                 {"a/b/c", "/a/b/d", "/a/b"},
          275                 {"a/b/c", "a/b/d", "a/b"},
          276                 {"/a/b/c", "/a/b/c", "/a/b/c"},
          277                 {"/a/b/c", "/a/b/c/d", "/a/b/c"},
          278                 {"/a/b/c", "/a/b", "/a/b"},
          279                 {"/a/b/c", "/a", "/a"},
          280                 {"/a/b/c", "/d/e/f", ""},
          281         } {
          282                 c.Assert(CommonDirPath(this.a, this.b), qt.Equals, this.expected, qt.Commentf("a: %s b: %s", this.a, this.b))
          283         }
          284 }
          285 
          286 func TestIsSameFilePath(t *testing.T) {
          287         c := qt.New(t)
          288 
          289         for _, this := range []struct {
          290                 a, b     string
          291                 expected bool
          292         }{
          293                 {"/a/b/c", "/a/b/c", true},
          294                 {"/a/b/c", "/a/b/c/", true},
          295                 {"/a/b/c", "/a/b/d", false},
          296                 {"/a/b/c", "/a/b", false},
          297                 {"/a/b/c", "/a/b/c/d", false},
          298                 {"/a/b/c", "/a/b/cd", false},
          299                 {"/a/b/c", "/a/b/cc", false},
          300                 {"/a/b/c", "/a/b/c/", true},
          301                 {"/a/b/c", "/a/b/c//", true},
          302                 {"/a/b/c", "/a/b/c/.", true},
          303                 {"/a/b/c", "/a/b/c/./", true},
          304                 {"/a/b/c", "/a/b/c/./.", true},
          305                 {"/a/b/c", "/a/b/c/././", true},
          306                 {"/a/b/c", "/a/b/c/././.", true},
          307                 {"/a/b/c", "/a/b/c/./././", true},
          308                 {"/a/b/c", "/a/b/c/./././.", true},
          309                 {"/a/b/c", "/a/b/c/././././", true},
          310         } {
          311                 c.Assert(IsSameFilePath(filepath.FromSlash(this.a), filepath.FromSlash(this.b)), qt.Equals, this.expected, qt.Commentf("a: %s b: %s", this.a, this.b))
          312         }
          313 }