OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package path | 5 package path |
6 | 6 |
7 import ( | 7 import ( |
8 » "os"; | 8 » "os" |
9 » "testing"; | 9 » "testing" |
10 ) | 10 ) |
11 | 11 |
12 type CleanTest struct { | 12 type CleanTest struct { |
13 » path, clean string; | 13 » path, clean string |
14 } | 14 } |
15 | 15 |
16 var cleantests = []CleanTest{ | 16 var cleantests = []CleanTest{ |
17 // Already clean | 17 // Already clean |
18 CleanTest{"", "."}, | 18 CleanTest{"", "."}, |
19 CleanTest{"abc", "abc"}, | 19 CleanTest{"abc", "abc"}, |
20 CleanTest{"abc/def", "abc/def"}, | 20 CleanTest{"abc/def", "abc/def"}, |
21 CleanTest{"a/b/c", "a/b/c"}, | 21 CleanTest{"a/b/c", "a/b/c"}, |
22 CleanTest{".", "."}, | 22 CleanTest{".", "."}, |
23 CleanTest{"..", ".."}, | 23 CleanTest{"..", ".."}, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 | 65 |
66 func TestClean(t *testing.T) { | 66 func TestClean(t *testing.T) { |
67 for _, test := range cleantests { | 67 for _, test := range cleantests { |
68 if s := Clean(test.path); s != test.clean { | 68 if s := Clean(test.path); s != test.clean { |
69 t.Errorf("Clean(%q) = %q, want %q", test.path, s, test.c
lean) | 69 t.Errorf("Clean(%q) = %q, want %q", test.path, s, test.c
lean) |
70 } | 70 } |
71 } | 71 } |
72 } | 72 } |
73 | 73 |
74 type SplitTest struct { | 74 type SplitTest struct { |
75 » path, dir, file string; | 75 » path, dir, file string |
76 } | 76 } |
77 | 77 |
78 var splittests = []SplitTest{ | 78 var splittests = []SplitTest{ |
79 SplitTest{"a/b", "a/", "b"}, | 79 SplitTest{"a/b", "a/", "b"}, |
80 SplitTest{"a/b/", "a/b/", ""}, | 80 SplitTest{"a/b/", "a/b/", ""}, |
81 SplitTest{"a/", "a/", ""}, | 81 SplitTest{"a/", "a/", ""}, |
82 SplitTest{"a", "", "a"}, | 82 SplitTest{"a", "", "a"}, |
83 SplitTest{"/", "/", ""}, | 83 SplitTest{"/", "/", ""}, |
84 } | 84 } |
85 | 85 |
86 func TestSplit(t *testing.T) { | 86 func TestSplit(t *testing.T) { |
87 for _, test := range splittests { | 87 for _, test := range splittests { |
88 if d, f := Split(test.path); d != test.dir || f != test.file { | 88 if d, f := Split(test.path); d != test.dir || f != test.file { |
89 t.Errorf("Split(%q) = %q, %q, want %q, %q", test.path, d
, f, test.dir, test.file) | 89 t.Errorf("Split(%q) = %q, %q, want %q, %q", test.path, d
, f, test.dir, test.file) |
90 } | 90 } |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 type JoinTest struct { | 94 type JoinTest struct { |
95 » dir, file, path string; | 95 » dir, file, path string |
96 } | 96 } |
97 | 97 |
98 var jointests = []JoinTest{ | 98 var jointests = []JoinTest{ |
99 JoinTest{"a", "b", "a/b"}, | 99 JoinTest{"a", "b", "a/b"}, |
100 JoinTest{"a", "", "a"}, | 100 JoinTest{"a", "", "a"}, |
101 JoinTest{"", "b", "b"}, | 101 JoinTest{"", "b", "b"}, |
102 JoinTest{"/", "a", "/a"}, | 102 JoinTest{"/", "a", "/a"}, |
103 JoinTest{"/", "", "/"}, | 103 JoinTest{"/", "", "/"}, |
104 JoinTest{"a/", "b", "a/b"}, | 104 JoinTest{"a/", "b", "a/b"}, |
105 JoinTest{"a/", "", "a"}, | 105 JoinTest{"a/", "", "a"}, |
106 } | 106 } |
107 | 107 |
108 func TestJoin(t *testing.T) { | 108 func TestJoin(t *testing.T) { |
109 for _, test := range jointests { | 109 for _, test := range jointests { |
110 if p := Join(test.dir, test.file); p != test.path { | 110 if p := Join(test.dir, test.file); p != test.path { |
111 t.Errorf("Join(%q, %q) = %q, want %q", test.dir, test.fi
le, p, test.path) | 111 t.Errorf("Join(%q, %q) = %q, want %q", test.dir, test.fi
le, p, test.path) |
112 } | 112 } |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 type ExtTest struct { | 116 type ExtTest struct { |
117 » path, ext string; | 117 » path, ext string |
118 } | 118 } |
119 | 119 |
120 var exttests = []ExtTest{ | 120 var exttests = []ExtTest{ |
121 ExtTest{"path.go", ".go"}, | 121 ExtTest{"path.go", ".go"}, |
122 ExtTest{"path.pb.go", ".go"}, | 122 ExtTest{"path.pb.go", ".go"}, |
123 ExtTest{"a.dir/b", ""}, | 123 ExtTest{"a.dir/b", ""}, |
124 ExtTest{"a.dir/b.go", ".go"}, | 124 ExtTest{"a.dir/b.go", ".go"}, |
125 ExtTest{"a.dir/", ""}, | 125 ExtTest{"a.dir/", ""}, |
126 } | 126 } |
127 | 127 |
128 func TestExt(t *testing.T) { | 128 func TestExt(t *testing.T) { |
129 for _, test := range exttests { | 129 for _, test := range exttests { |
130 if x := Ext(test.path); x != test.ext { | 130 if x := Ext(test.path); x != test.ext { |
131 t.Errorf("Ext(%q) = %q, want %q", test.path, x, test.ext
) | 131 t.Errorf("Ext(%q) = %q, want %q", test.path, x, test.ext
) |
132 } | 132 } |
133 } | 133 } |
134 } | 134 } |
135 | 135 |
136 type Node struct { | 136 type Node struct { |
137 » name» string; | 137 » name string |
138 » entries»[]*Node;» // nil if the entry is a file | 138 » entries []*Node // nil if the entry is a file |
139 » mark» int; | 139 » mark int |
140 } | 140 } |
141 | 141 |
142 var tree = &Node{ | 142 var tree = &Node{ |
143 "testdata", | 143 "testdata", |
144 []*Node{ | 144 []*Node{ |
145 &Node{"a", nil, 0}, | 145 &Node{"a", nil, 0}, |
146 &Node{"b", []*Node{}, 0}, | 146 &Node{"b", []*Node{}, 0}, |
147 &Node{"c", nil, 0}, | 147 &Node{"c", nil, 0}, |
148 &Node{ | 148 &Node{ |
149 "d", | 149 "d", |
150 []*Node{ | 150 []*Node{ |
151 &Node{"x", nil, 0}, | 151 &Node{"x", nil, 0}, |
152 &Node{"y", []*Node{}, 0}, | 152 &Node{"y", []*Node{}, 0}, |
153 &Node{ | 153 &Node{ |
154 "z", | 154 "z", |
155 []*Node{ | 155 []*Node{ |
156 &Node{"u", nil, 0}, | 156 &Node{"u", nil, 0}, |
157 &Node{"v", nil, 0}, | 157 &Node{"v", nil, 0}, |
158 }, | 158 }, |
159 0, | 159 0, |
160 }, | 160 }, |
161 }, | 161 }, |
162 0, | 162 0, |
163 }, | 163 }, |
164 }, | 164 }, |
165 0, | 165 0, |
166 } | 166 } |
167 | 167 |
168 func walkTree(n *Node, path string, f func(path string, n *Node)) { | 168 func walkTree(n *Node, path string, f func(path string, n *Node)) { |
169 » f(path, n); | 169 » f(path, n) |
170 for _, e := range n.entries { | 170 for _, e := range n.entries { |
171 walkTree(e, Join(path, e.name), f) | 171 walkTree(e, Join(path, e.name), f) |
172 } | 172 } |
173 } | 173 } |
174 | 174 |
175 func makeTree(t *testing.T) { | 175 func makeTree(t *testing.T) { |
176 walkTree(tree, tree.name, func(path string, n *Node) { | 176 walkTree(tree, tree.name, func(path string, n *Node) { |
177 if n.entries == nil { | 177 if n.entries == nil { |
178 » » » fd, err := os.Open(path, os.O_CREAT, 0660); | 178 » » » fd, err := os.Open(path, os.O_CREAT, 0660) |
179 if err != nil { | 179 if err != nil { |
180 t.Errorf("makeTree: %v", err) | 180 t.Errorf("makeTree: %v", err) |
181 } | 181 } |
182 » » » fd.Close(); | 182 » » » fd.Close() |
183 } else { | 183 } else { |
184 os.Mkdir(path, 0770) | 184 os.Mkdir(path, 0770) |
185 } | 185 } |
186 }) | 186 }) |
187 } | 187 } |
188 | 188 |
189 func markTree(n *Node)» { walkTree(n, "", func(path string, n *Node) { n.mark++
}) } | 189 func markTree(n *Node) { walkTree(n, "", func(path string, n *Node) { n.mark++ }
) } |
190 | 190 |
191 func checkMarks(t *testing.T) { | 191 func checkMarks(t *testing.T) { |
192 walkTree(tree, tree.name, func(path string, n *Node) { | 192 walkTree(tree, tree.name, func(path string, n *Node) { |
193 if n.mark != 1 { | 193 if n.mark != 1 { |
194 t.Errorf("node %s mark = %d; expected 1", path, n.mark) | 194 t.Errorf("node %s mark = %d; expected 1", path, n.mark) |
195 } | 195 } |
196 » » n.mark = 0; | 196 » » n.mark = 0 |
197 }) | 197 }) |
198 } | 198 } |
199 | 199 |
200 // Assumes that each node name is unique. Good enough for a test. | 200 // Assumes that each node name is unique. Good enough for a test. |
201 func mark(name string) { | 201 func mark(name string) { |
202 walkTree(tree, tree.name, func(path string, n *Node) { | 202 walkTree(tree, tree.name, func(path string, n *Node) { |
203 if n.name == name { | 203 if n.name == name { |
204 n.mark++ | 204 n.mark++ |
205 } | 205 } |
206 }) | 206 }) |
207 } | 207 } |
208 | 208 |
209 type TestVisitor struct{} | 209 type TestVisitor struct{} |
210 | 210 |
211 func (v *TestVisitor) VisitDir(path string, d *os.Dir) bool { | 211 func (v *TestVisitor) VisitDir(path string, d *os.Dir) bool { |
212 » mark(d.Name); | 212 » mark(d.Name) |
213 » return true; | 213 » return true |
214 } | 214 } |
215 | 215 |
216 func (v *TestVisitor) VisitFile(path string, d *os.Dir) { | 216 func (v *TestVisitor) VisitFile(path string, d *os.Dir) { |
217 mark(d.Name) | 217 mark(d.Name) |
218 } | 218 } |
219 | 219 |
220 func TestWalk(t *testing.T) { | 220 func TestWalk(t *testing.T) { |
221 » makeTree(t); | 221 » makeTree(t) |
222 | 222 |
223 // 1) ignore error handling, expect none | 223 // 1) ignore error handling, expect none |
224 » v := &TestVisitor{}; | 224 » v := &TestVisitor{} |
225 » Walk(tree.name, v, nil); | 225 » Walk(tree.name, v, nil) |
226 » checkMarks(t); | 226 » checkMarks(t) |
227 | 227 |
228 // 2) handle errors, expect none | 228 // 2) handle errors, expect none |
229 » errors := make(chan os.Error, 64); | 229 » errors := make(chan os.Error, 64) |
230 » Walk(tree.name, v, errors); | 230 » Walk(tree.name, v, errors) |
231 if err, ok := <-errors; ok { | 231 if err, ok := <-errors; ok { |
232 t.Errorf("no error expected, found: s", err) | 232 t.Errorf("no error expected, found: s", err) |
233 } | 233 } |
234 » checkMarks(t); | 234 » checkMarks(t) |
235 | 235 |
236 if os.Getuid() != 0 { | 236 if os.Getuid() != 0 { |
237 // introduce 2 errors: chmod top-level directories to 0 | 237 // introduce 2 errors: chmod top-level directories to 0 |
238 » » os.Chmod(Join(tree.name, tree.entries[1].name), 0); | 238 » » os.Chmod(Join(tree.name, tree.entries[1].name), 0) |
239 » » os.Chmod(Join(tree.name, tree.entries[3].name), 0); | 239 » » os.Chmod(Join(tree.name, tree.entries[3].name), 0) |
240 // mark respective subtrees manually | 240 // mark respective subtrees manually |
241 » » markTree(tree.entries[1]); | 241 » » markTree(tree.entries[1]) |
242 » » markTree(tree.entries[3]); | 242 » » markTree(tree.entries[3]) |
243 // correct double-marking of directory itself | 243 // correct double-marking of directory itself |
244 » » tree.entries[1].mark--; | 244 » » tree.entries[1].mark-- |
245 » » tree.entries[3].mark--; | 245 » » tree.entries[3].mark-- |
246 | 246 |
247 // 3) handle errors, expect two | 247 // 3) handle errors, expect two |
248 » » errors = make(chan os.Error, 64); | 248 » » errors = make(chan os.Error, 64) |
249 » » os.Chmod(Join(tree.name, tree.entries[1].name), 0); | 249 » » os.Chmod(Join(tree.name, tree.entries[1].name), 0) |
250 » » Walk(tree.name, v, errors); | 250 » » Walk(tree.name, v, errors) |
251 for i := 1; i <= 2; i++ { | 251 for i := 1; i <= 2; i++ { |
252 if _, ok := <-errors; !ok { | 252 if _, ok := <-errors; !ok { |
253 » » » » t.Errorf("%d. error expected, none found", i); | 253 » » » » t.Errorf("%d. error expected, none found", i) |
254 » » » » break; | 254 » » » » break |
255 } | 255 } |
256 } | 256 } |
257 if err, ok := <-errors; ok { | 257 if err, ok := <-errors; ok { |
258 t.Errorf("only two errors expected, found 3rd: %v", err) | 258 t.Errorf("only two errors expected, found 3rd: %v", err) |
259 } | 259 } |
260 // the inaccessible subtrees were marked manually | 260 // the inaccessible subtrees were marked manually |
261 » » checkMarks(t); | 261 » » checkMarks(t) |
262 } | 262 } |
263 | 263 |
264 // cleanup | 264 // cleanup |
265 » os.Chmod(Join(tree.name, tree.entries[1].name), 0770); | 265 » os.Chmod(Join(tree.name, tree.entries[1].name), 0770) |
266 » os.Chmod(Join(tree.name, tree.entries[3].name), 0770); | 266 » os.Chmod(Join(tree.name, tree.entries[3].name), 0770) |
267 if err := os.RemoveAll(tree.name); err != nil { | 267 if err := os.RemoveAll(tree.name); err != nil { |
268 t.Errorf("removeTree: %v", err) | 268 t.Errorf("removeTree: %v", err) |
269 } | 269 } |
270 } | 270 } |
OLD | NEW |