go.sdls.io/sin@v0.0.9/pkg/sin/path_test.go (about) 1 // Copyright 2013 Julien Schmidt. All rights reserved. 2 // Based on the path package, Copyright 2009 The Go Authors. 3 // Use of this source code is governed by a BSD-style license that can be found 4 // at https://github.com/julienschmidt/httprouter/blob/master/LICENSE 5 6 package sin 7 8 import ( 9 "strings" 10 "testing" 11 12 "github.com/stretchr/testify/assert" 13 ) 14 15 type cleanPathTest struct { 16 path, result string 17 } 18 19 var cleanTests = []cleanPathTest{ 20 // Already clean 21 {"/", "/"}, 22 {"/abc", "/abc"}, 23 {"/a/b/c", "/a/b/c"}, 24 {"/abc/", "/abc/"}, 25 {"/a/b/c/", "/a/b/c/"}, 26 27 // missing root 28 {"", "/"}, 29 {"a/", "/a/"}, 30 {"abc", "/abc"}, 31 {"abc/def", "/abc/def"}, 32 {"a/b/c", "/a/b/c"}, 33 34 // Remove doubled slash 35 {"//", "/"}, 36 {"/abc//", "/abc/"}, 37 {"/abc/def//", "/abc/def/"}, 38 {"/a/b/c//", "/a/b/c/"}, 39 {"/abc//def//ghi", "/abc/def/ghi"}, 40 {"//abc", "/abc"}, 41 {"///abc", "/abc"}, 42 {"//abc//", "/abc/"}, 43 44 // Remove . elements 45 {".", "/"}, 46 {"./", "/"}, 47 {"/abc/./def", "/abc/def"}, 48 {"/./abc/def", "/abc/def"}, 49 {"/abc/.", "/abc/"}, 50 51 // Remove .. elements 52 {"..", "/"}, 53 {"../", "/"}, 54 {"../../", "/"}, 55 {"../..", "/"}, 56 {"../../abc", "/abc"}, 57 {"/abc/def/ghi/../jkl", "/abc/def/jkl"}, 58 {"/abc/def/../ghi/../jkl", "/abc/jkl"}, 59 {"/abc/def/..", "/abc"}, 60 {"/abc/def/../..", "/"}, 61 {"/abc/def/../../..", "/"}, 62 {"/abc/def/../../..", "/"}, 63 {"/abc/def/../../../ghi/jkl/../../../mno", "/mno"}, 64 65 // Combinations 66 {"abc/./../def", "/def"}, 67 {"abc//./../def", "/def"}, 68 {"abc/../../././../def", "/def"}, 69 } 70 71 func TestPathClean(t *testing.T) { 72 for _, test := range cleanTests { 73 assert.Equal(t, test.result, cleanPath(test.path)) 74 assert.Equal(t, test.result, cleanPath(test.result)) 75 } 76 } 77 78 func TestPathCleanMallocs(t *testing.T) { 79 if testing.Short() { 80 t.Skip("skipping malloc count in short mode") 81 } 82 83 for _, test := range cleanTests { 84 allocs := testing.AllocsPerRun(100, func() { cleanPath(test.result) }) 85 assert.EqualValues(t, allocs, 0) 86 } 87 } 88 89 func BenchmarkPathClean(b *testing.B) { 90 b.ReportAllocs() 91 92 for i := 0; i < b.N; i++ { 93 for _, test := range cleanTests { 94 cleanPath(test.path) 95 } 96 } 97 } 98 99 func genLongPaths() (testPaths []cleanPathTest) { 100 for i := 1; i <= 1234; i++ { 101 ss := strings.Repeat("a", i) 102 103 correctPath := "/" + ss 104 testPaths = append(testPaths, cleanPathTest{ 105 path: correctPath, 106 result: correctPath, 107 }, cleanPathTest{ 108 path: ss, 109 result: correctPath, 110 }, cleanPathTest{ 111 path: "//" + ss, 112 result: correctPath, 113 }, cleanPathTest{ 114 path: "/" + ss + "/b/..", 115 result: correctPath, 116 }) 117 } 118 return 119 } 120 121 func TestPathCleanLong(t *testing.T) { 122 cleanTests := genLongPaths() 123 124 for _, test := range cleanTests { 125 assert.Equal(t, test.result, cleanPath(test.path)) 126 assert.Equal(t, test.result, cleanPath(test.result)) 127 } 128 } 129 130 func BenchmarkPathCleanLong(b *testing.B) { 131 cleanTests := genLongPaths() 132 b.ResetTimer() 133 b.ReportAllocs() 134 135 for i := 0; i < b.N; i++ { 136 for _, test := range cleanTests { 137 cleanPath(test.path) 138 } 139 } 140 }