Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 1 | // Copyright 2009 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | package path |
| 6 | |
| 7 | import ( |
Albert Strasheim | 0a71a5b | 2013-03-06 15:52:32 -0800 | [diff] [blame] | 8 | "runtime" |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 9 | "testing" |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 10 | ) |
| 11 | |
Rob Pike | b6122b0 | 2011-12-22 14:08:34 -0800 | [diff] [blame] | 12 | type PathTest struct { |
| 13 | path, result string |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 14 | } |
| 15 | |
Rob Pike | b6122b0 | 2011-12-22 14:08:34 -0800 | [diff] [blame] | 16 | var cleantests = []PathTest{ |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 17 | // Already clean |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 18 | {"", "."}, |
| 19 | {"abc", "abc"}, |
| 20 | {"abc/def", "abc/def"}, |
| 21 | {"a/b/c", "a/b/c"}, |
| 22 | {".", "."}, |
| 23 | {"..", ".."}, |
| 24 | {"../..", "../.."}, |
| 25 | {"../../abc", "../../abc"}, |
| 26 | {"/abc", "/abc"}, |
| 27 | {"/", "/"}, |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 28 | |
| 29 | // Remove trailing slash |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 30 | {"abc/", "abc"}, |
| 31 | {"abc/def/", "abc/def"}, |
| 32 | {"a/b/c/", "a/b/c"}, |
| 33 | {"./", "."}, |
| 34 | {"../", ".."}, |
| 35 | {"../../", "../.."}, |
| 36 | {"/abc/", "/abc"}, |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 37 | |
| 38 | // Remove doubled slash |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 39 | {"abc//def//ghi", "abc/def/ghi"}, |
| 40 | {"//abc", "/abc"}, |
| 41 | {"///abc", "/abc"}, |
| 42 | {"//abc//", "/abc"}, |
| 43 | {"abc//", "abc"}, |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 44 | |
| 45 | // Remove . elements |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 46 | {"abc/./def", "abc/def"}, |
| 47 | {"/./abc/def", "/abc/def"}, |
| 48 | {"abc/.", "abc"}, |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 49 | |
| 50 | // Remove .. elements |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 51 | {"abc/def/ghi/../jkl", "abc/def/jkl"}, |
| 52 | {"abc/def/../ghi/../jkl", "abc/jkl"}, |
| 53 | {"abc/def/..", "abc"}, |
| 54 | {"abc/def/../..", "."}, |
| 55 | {"/abc/def/../..", "/"}, |
| 56 | {"abc/def/../../..", ".."}, |
| 57 | {"/abc/def/../../..", "/"}, |
| 58 | {"abc/def/../../../ghi/jkl/../../../mno", "../../mno"}, |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 59 | |
| 60 | // Combinations |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 61 | {"abc/./../def", "def"}, |
| 62 | {"abc//./../def", "def"}, |
| 63 | {"abc/../../././../def", "../../def"}, |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 64 | } |
| 65 | |
| 66 | func TestClean(t *testing.T) { |
Russ Cox | ca6a0fe | 2009-09-15 09:41:59 -0700 | [diff] [blame] | 67 | for _, test := range cleantests { |
Rob Pike | b6122b0 | 2011-12-22 14:08:34 -0800 | [diff] [blame] | 68 | if s := Clean(test.path); s != test.result { |
| 69 | t.Errorf("Clean(%q) = %q, want %q", test.path, s, test.result) |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 70 | } |
Russ Cox | 9525372 | 2012-06-27 16:52:36 -0400 | [diff] [blame] | 71 | if s := Clean(test.result); s != test.result { |
| 72 | t.Errorf("Clean(%q) = %q, want %q", test.result, s, test.result) |
| 73 | } |
| 74 | } |
Rob Pike | f578726 | 2013-08-21 14:00:45 +1000 | [diff] [blame] | 75 | } |
Russ Cox | 9525372 | 2012-06-27 16:52:36 -0400 | [diff] [blame] | 76 | |
Rob Pike | f578726 | 2013-08-21 14:00:45 +1000 | [diff] [blame] | 77 | func TestCleanMallocs(t *testing.T) { |
| 78 | if testing.Short() { |
| 79 | t.Skip("skipping malloc count in short mode") |
| 80 | } |
Albert Strasheim | 0a71a5b | 2013-03-06 15:52:32 -0800 | [diff] [blame] | 81 | if runtime.GOMAXPROCS(0) > 1 { |
| 82 | t.Log("skipping AllocsPerRun checks; GOMAXPROCS>1") |
| 83 | return |
| 84 | } |
| 85 | |
Kyle Lemons | 9bfd3c3 | 2013-02-02 22:52:29 -0500 | [diff] [blame] | 86 | for _, test := range cleantests { |
| 87 | allocs := testing.AllocsPerRun(100, func() { Clean(test.result) }) |
| 88 | if allocs > 0 { |
| 89 | t.Errorf("Clean(%q): %v allocs, want zero", test.result, allocs) |
Russ Cox | 9525372 | 2012-06-27 16:52:36 -0400 | [diff] [blame] | 90 | } |
| 91 | } |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 92 | } |
| 93 | |
| 94 | type SplitTest struct { |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 95 | path, dir, file string |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 96 | } |
| 97 | |
Russ Cox | 094f1d5 | 2009-10-08 15:14:54 -0700 | [diff] [blame] | 98 | var splittests = []SplitTest{ |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 99 | {"a/b", "a/", "b"}, |
| 100 | {"a/b/", "a/b/", ""}, |
| 101 | {"a/", "a/", ""}, |
| 102 | {"a", "", "a"}, |
| 103 | {"/", "/", ""}, |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 104 | } |
| 105 | |
| 106 | func TestSplit(t *testing.T) { |
Russ Cox | ca6a0fe | 2009-09-15 09:41:59 -0700 | [diff] [blame] | 107 | for _, test := range splittests { |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 108 | if d, f := Split(test.path); d != test.dir || f != test.file { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 109 | t.Errorf("Split(%q) = %q, %q, want %q, %q", test.path, d, f, test.dir, test.file) |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 110 | } |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | type JoinTest struct { |
Stephen Weinberg | bc43cc3 | 2010-02-05 02:39:33 -0800 | [diff] [blame] | 115 | elem []string |
| 116 | path string |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 117 | } |
| 118 | |
Russ Cox | 094f1d5 | 2009-10-08 15:14:54 -0700 | [diff] [blame] | 119 | var jointests = []JoinTest{ |
Stephen Weinberg | bc43cc3 | 2010-02-05 02:39:33 -0800 | [diff] [blame] | 120 | // zero parameters |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 121 | {[]string{}, ""}, |
Stephen Weinberg | bc43cc3 | 2010-02-05 02:39:33 -0800 | [diff] [blame] | 122 | |
| 123 | // one parameter |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 124 | {[]string{""}, ""}, |
| 125 | {[]string{"a"}, "a"}, |
Stephen Weinberg | bc43cc3 | 2010-02-05 02:39:33 -0800 | [diff] [blame] | 126 | |
| 127 | // two parameters |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 128 | {[]string{"a", "b"}, "a/b"}, |
| 129 | {[]string{"a", ""}, "a"}, |
| 130 | {[]string{"", "b"}, "b"}, |
| 131 | {[]string{"/", "a"}, "/a"}, |
| 132 | {[]string{"/", ""}, "/"}, |
| 133 | {[]string{"a/", "b"}, "a/b"}, |
| 134 | {[]string{"a/", ""}, "a"}, |
| 135 | {[]string{"", ""}, ""}, |
Stephen Weinberg | bc43cc3 | 2010-02-05 02:39:33 -0800 | [diff] [blame] | 136 | } |
| 137 | |
| 138 | // join takes a []string and passes it to Join. |
| 139 | func join(elem []string, args ...string) string { |
| 140 | args = elem |
Russ Cox | 2ee420f | 2010-09-24 11:55:48 -0400 | [diff] [blame] | 141 | return Join(args...) |
Russ Cox | 7cbec41 | 2009-04-07 21:53:39 -0700 | [diff] [blame] | 142 | } |
| 143 | |
| 144 | func TestJoin(t *testing.T) { |
Russ Cox | ca6a0fe | 2009-09-15 09:41:59 -0700 | [diff] [blame] | 145 | for _, test := range jointests { |
Stephen Weinberg | bc43cc3 | 2010-02-05 02:39:33 -0800 | [diff] [blame] | 146 | if p := join(test.elem); p != test.path { |
| 147 | t.Errorf("join(%q) = %q, want %q", test.elem, p, test.path) |
Russ Cox | 7cbec41 | 2009-04-07 21:53:39 -0700 | [diff] [blame] | 148 | } |
| 149 | } |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | type ExtTest struct { |
Robert Griesemer | d65a5cc | 2009-12-15 15:40:16 -0800 | [diff] [blame] | 153 | path, ext string |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 154 | } |
| 155 | |
Russ Cox | 094f1d5 | 2009-10-08 15:14:54 -0700 | [diff] [blame] | 156 | var exttests = []ExtTest{ |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 157 | {"path.go", ".go"}, |
| 158 | {"path.pb.go", ".go"}, |
| 159 | {"a.dir/b", ""}, |
| 160 | {"a.dir/b.go", ".go"}, |
| 161 | {"a.dir/", ""}, |
Russ Cox | 16b38b5 | 2009-04-07 00:40:07 -0700 | [diff] [blame] | 162 | } |
Russ Cox | 7cbec41 | 2009-04-07 21:53:39 -0700 | [diff] [blame] | 163 | |
| 164 | func TestExt(t *testing.T) { |
Russ Cox | ca6a0fe | 2009-09-15 09:41:59 -0700 | [diff] [blame] | 165 | for _, test := range exttests { |
Russ Cox | 7cbec41 | 2009-04-07 21:53:39 -0700 | [diff] [blame] | 166 | if x := Ext(test.path); x != test.ext { |
Robert Griesemer | 40621d5 | 2009-11-09 12:07:39 -0800 | [diff] [blame] | 167 | t.Errorf("Ext(%q) = %q, want %q", test.path, x, test.ext) |
Russ Cox | 7cbec41 | 2009-04-07 21:53:39 -0700 | [diff] [blame] | 168 | } |
| 169 | } |
| 170 | } |
Robert Griesemer | 4adad65 | 2009-10-19 11:48:04 -0700 | [diff] [blame] | 171 | |
Rob Pike | b6122b0 | 2011-12-22 14:08:34 -0800 | [diff] [blame] | 172 | var basetests = []PathTest{ |
Rob Pike | 62b5c7c | 2010-06-09 19:59:22 -0700 | [diff] [blame] | 173 | // Already clean |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 174 | {"", "."}, |
| 175 | {".", "."}, |
| 176 | {"/.", "."}, |
| 177 | {"/", "/"}, |
| 178 | {"////", "/"}, |
| 179 | {"x/", "x"}, |
| 180 | {"abc", "abc"}, |
| 181 | {"abc/def", "def"}, |
| 182 | {"a/b/.x", ".x"}, |
| 183 | {"a/b/c.", "c."}, |
| 184 | {"a/b/c.x", "c.x"}, |
Rob Pike | 62b5c7c | 2010-06-09 19:59:22 -0700 | [diff] [blame] | 185 | } |
| 186 | |
| 187 | func TestBase(t *testing.T) { |
| 188 | for _, test := range basetests { |
Rob Pike | b6122b0 | 2011-12-22 14:08:34 -0800 | [diff] [blame] | 189 | if s := Base(test.path); s != test.result { |
| 190 | t.Errorf("Base(%q) = %q, want %q", test.path, s, test.result) |
| 191 | } |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | var dirtests = []PathTest{ |
| 196 | {"", "."}, |
| 197 | {".", "."}, |
| 198 | {"/.", "/"}, |
| 199 | {"/", "/"}, |
| 200 | {"////", "/"}, |
| 201 | {"/foo", "/"}, |
| 202 | {"x/", "x"}, |
| 203 | {"abc", "."}, |
| 204 | {"abc/def", "abc"}, |
Rob Pike | b7627d3 | 2012-08-30 11:16:41 -0700 | [diff] [blame] | 205 | {"abc////def", "abc"}, |
Rob Pike | b6122b0 | 2011-12-22 14:08:34 -0800 | [diff] [blame] | 206 | {"a/b/.x", "a/b"}, |
| 207 | {"a/b/c.", "a/b"}, |
| 208 | {"a/b/c.x", "a/b"}, |
| 209 | } |
| 210 | |
| 211 | func TestDir(t *testing.T) { |
| 212 | for _, test := range dirtests { |
| 213 | if s := Dir(test.path); s != test.result { |
| 214 | t.Errorf("Dir(%q) = %q, want %q", test.path, s, test.result) |
Rob Pike | 62b5c7c | 2010-06-09 19:59:22 -0700 | [diff] [blame] | 215 | } |
| 216 | } |
| 217 | } |
Ivan Krasin | dfb2af6 | 2010-09-09 01:42:43 -0400 | [diff] [blame] | 218 | |
| 219 | type IsAbsTest struct { |
| 220 | path string |
| 221 | isAbs bool |
| 222 | } |
| 223 | |
| 224 | var isAbsTests = []IsAbsTest{ |
Robert Griesemer | 3478891 | 2010-10-22 10:06:33 -0700 | [diff] [blame] | 225 | {"", false}, |
| 226 | {"/", true}, |
| 227 | {"/usr/bin/gcc", true}, |
| 228 | {"..", false}, |
| 229 | {"/a/../bb", true}, |
| 230 | {".", false}, |
| 231 | {"./", false}, |
| 232 | {"lala", false}, |
Ivan Krasin | dfb2af6 | 2010-09-09 01:42:43 -0400 | [diff] [blame] | 233 | } |
| 234 | |
| 235 | func TestIsAbs(t *testing.T) { |
| 236 | for _, test := range isAbsTests { |
| 237 | if r := IsAbs(test.path); r != test.isAbs { |
| 238 | t.Errorf("IsAbs(%q) = %v, want %v", test.path, r, test.isAbs) |
| 239 | } |
| 240 | } |
| 241 | } |