1 use std::fs;
2 use std::path::PathBuf;
3
4 use crate::tests::util::Dir;
5 use crate::WalkDir;
6
7 #[test]
send_sync_traits()8 fn send_sync_traits() {
9 use crate::{FilterEntry, IntoIter};
10
11 fn assert_send<T: Send>() {}
12 fn assert_sync<T: Sync>() {}
13
14 assert_send::<WalkDir>();
15 assert_sync::<WalkDir>();
16 assert_send::<IntoIter>();
17 assert_sync::<IntoIter>();
18 assert_send::<FilterEntry<IntoIter, u8>>();
19 assert_sync::<FilterEntry<IntoIter, u8>>();
20 }
21
22 #[test]
empty()23 fn empty() {
24 let dir = Dir::tmp();
25 let wd = WalkDir::new(dir.path());
26 let r = dir.run_recursive(wd);
27 r.assert_no_errors();
28
29 assert_eq!(1, r.ents().len());
30 let ent = &r.ents()[0];
31 assert!(ent.file_type().is_dir());
32 assert!(!ent.path_is_symlink());
33 assert_eq!(0, ent.depth());
34 assert_eq!(dir.path(), ent.path());
35 assert_eq!(dir.path().file_name().unwrap(), ent.file_name());
36 }
37
38 #[test]
empty_follow()39 fn empty_follow() {
40 let dir = Dir::tmp();
41 let wd = WalkDir::new(dir.path()).follow_links(true);
42 let r = dir.run_recursive(wd);
43 r.assert_no_errors();
44
45 assert_eq!(1, r.ents().len());
46 let ent = &r.ents()[0];
47 assert!(ent.file_type().is_dir());
48 assert!(!ent.path_is_symlink());
49 assert_eq!(0, ent.depth());
50 assert_eq!(dir.path(), ent.path());
51 assert_eq!(dir.path().file_name().unwrap(), ent.file_name());
52 }
53
54 #[test]
empty_file()55 fn empty_file() {
56 let dir = Dir::tmp();
57 dir.touch("a");
58
59 let wd = WalkDir::new(dir.path().join("a"));
60 let r = dir.run_recursive(wd);
61 r.assert_no_errors();
62
63 assert_eq!(1, r.ents().len());
64 let ent = &r.ents()[0];
65 assert!(ent.file_type().is_file());
66 assert!(!ent.path_is_symlink());
67 assert_eq!(0, ent.depth());
68 assert_eq!(dir.join("a"), ent.path());
69 assert_eq!("a", ent.file_name());
70 }
71
72 #[test]
empty_file_follow()73 fn empty_file_follow() {
74 let dir = Dir::tmp();
75 dir.touch("a");
76
77 let wd = WalkDir::new(dir.path().join("a")).follow_links(true);
78 let r = dir.run_recursive(wd);
79 r.assert_no_errors();
80
81 assert_eq!(1, r.ents().len());
82 let ent = &r.ents()[0];
83 assert!(ent.file_type().is_file());
84 assert!(!ent.path_is_symlink());
85 assert_eq!(0, ent.depth());
86 assert_eq!(dir.join("a"), ent.path());
87 assert_eq!("a", ent.file_name());
88 }
89
90 #[test]
one_dir()91 fn one_dir() {
92 let dir = Dir::tmp();
93 dir.mkdirp("a");
94
95 let wd = WalkDir::new(dir.path());
96 let r = dir.run_recursive(wd);
97 r.assert_no_errors();
98
99 let ents = r.ents();
100 assert_eq!(2, ents.len());
101 let ent = &ents[1];
102 assert_eq!(dir.join("a"), ent.path());
103 assert_eq!(1, ent.depth());
104 assert_eq!("a", ent.file_name());
105 assert!(ent.file_type().is_dir());
106 }
107
108 #[test]
one_file()109 fn one_file() {
110 let dir = Dir::tmp();
111 dir.touch("a");
112
113 let wd = WalkDir::new(dir.path());
114 let r = dir.run_recursive(wd);
115 r.assert_no_errors();
116
117 let ents = r.ents();
118 assert_eq!(2, ents.len());
119 let ent = &ents[1];
120 assert_eq!(dir.join("a"), ent.path());
121 assert_eq!(1, ent.depth());
122 assert_eq!("a", ent.file_name());
123 assert!(ent.file_type().is_file());
124 }
125
126 #[test]
one_dir_one_file()127 fn one_dir_one_file() {
128 let dir = Dir::tmp();
129 dir.mkdirp("foo");
130 dir.touch("foo/a");
131
132 let wd = WalkDir::new(dir.path());
133 let r = dir.run_recursive(wd);
134 r.assert_no_errors();
135
136 let expected = vec![
137 dir.path().to_path_buf(),
138 dir.join("foo"),
139 dir.join("foo").join("a"),
140 ];
141 assert_eq!(expected, r.sorted_paths());
142 }
143
144 #[test]
many_files()145 fn many_files() {
146 let dir = Dir::tmp();
147 dir.mkdirp("foo");
148 dir.touch_all(&["foo/a", "foo/b", "foo/c"]);
149
150 let wd = WalkDir::new(dir.path());
151 let r = dir.run_recursive(wd);
152 r.assert_no_errors();
153
154 let expected = vec![
155 dir.path().to_path_buf(),
156 dir.join("foo"),
157 dir.join("foo").join("a"),
158 dir.join("foo").join("b"),
159 dir.join("foo").join("c"),
160 ];
161 assert_eq!(expected, r.sorted_paths());
162 }
163
164 #[test]
many_dirs()165 fn many_dirs() {
166 let dir = Dir::tmp();
167 dir.mkdirp("foo/a");
168 dir.mkdirp("foo/b");
169 dir.mkdirp("foo/c");
170
171 let wd = WalkDir::new(dir.path());
172 let r = dir.run_recursive(wd);
173 r.assert_no_errors();
174
175 let expected = vec![
176 dir.path().to_path_buf(),
177 dir.join("foo"),
178 dir.join("foo").join("a"),
179 dir.join("foo").join("b"),
180 dir.join("foo").join("c"),
181 ];
182 assert_eq!(expected, r.sorted_paths());
183 }
184
185 #[test]
many_mixed()186 fn many_mixed() {
187 let dir = Dir::tmp();
188 dir.mkdirp("foo/a");
189 dir.mkdirp("foo/c");
190 dir.mkdirp("foo/e");
191 dir.touch_all(&["foo/b", "foo/d", "foo/f"]);
192
193 let wd = WalkDir::new(dir.path());
194 let r = dir.run_recursive(wd);
195 r.assert_no_errors();
196
197 let expected = vec![
198 dir.path().to_path_buf(),
199 dir.join("foo"),
200 dir.join("foo").join("a"),
201 dir.join("foo").join("b"),
202 dir.join("foo").join("c"),
203 dir.join("foo").join("d"),
204 dir.join("foo").join("e"),
205 dir.join("foo").join("f"),
206 ];
207 assert_eq!(expected, r.sorted_paths());
208 }
209
210 #[test]
nested()211 fn nested() {
212 let nested =
213 PathBuf::from("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
214 let dir = Dir::tmp();
215 dir.mkdirp(&nested);
216 dir.touch(nested.join("A"));
217
218 let wd = WalkDir::new(dir.path());
219 let r = dir.run_recursive(wd);
220 r.assert_no_errors();
221
222 let expected = vec![
223 dir.path().to_path_buf(),
224 dir.join("a"),
225 dir.join("a/b"),
226 dir.join("a/b/c"),
227 dir.join("a/b/c/d"),
228 dir.join("a/b/c/d/e"),
229 dir.join("a/b/c/d/e/f"),
230 dir.join("a/b/c/d/e/f/g"),
231 dir.join("a/b/c/d/e/f/g/h"),
232 dir.join("a/b/c/d/e/f/g/h/i"),
233 dir.join("a/b/c/d/e/f/g/h/i/j"),
234 dir.join("a/b/c/d/e/f/g/h/i/j/k"),
235 dir.join("a/b/c/d/e/f/g/h/i/j/k/l"),
236 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m"),
237 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n"),
238 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o"),
239 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p"),
240 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q"),
241 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r"),
242 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s"),
243 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t"),
244 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u"),
245 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v"),
246 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w"),
247 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x"),
248 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y"),
249 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z"),
250 dir.join(&nested).join("A"),
251 ];
252 assert_eq!(expected, r.sorted_paths());
253 }
254
255 #[test]
nested_small_max_open()256 fn nested_small_max_open() {
257 let nested =
258 PathBuf::from("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z");
259 let dir = Dir::tmp();
260 dir.mkdirp(&nested);
261 dir.touch(nested.join("A"));
262
263 let wd = WalkDir::new(dir.path()).max_open(1);
264 let r = dir.run_recursive(wd);
265 r.assert_no_errors();
266
267 let expected = vec![
268 dir.path().to_path_buf(),
269 dir.join("a"),
270 dir.join("a/b"),
271 dir.join("a/b/c"),
272 dir.join("a/b/c/d"),
273 dir.join("a/b/c/d/e"),
274 dir.join("a/b/c/d/e/f"),
275 dir.join("a/b/c/d/e/f/g"),
276 dir.join("a/b/c/d/e/f/g/h"),
277 dir.join("a/b/c/d/e/f/g/h/i"),
278 dir.join("a/b/c/d/e/f/g/h/i/j"),
279 dir.join("a/b/c/d/e/f/g/h/i/j/k"),
280 dir.join("a/b/c/d/e/f/g/h/i/j/k/l"),
281 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m"),
282 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n"),
283 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o"),
284 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p"),
285 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q"),
286 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r"),
287 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s"),
288 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t"),
289 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u"),
290 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v"),
291 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w"),
292 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x"),
293 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y"),
294 dir.join("a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z"),
295 dir.join(&nested).join("A"),
296 ];
297 assert_eq!(expected, r.sorted_paths());
298 }
299
300 #[test]
siblings()301 fn siblings() {
302 let dir = Dir::tmp();
303 dir.mkdirp("foo");
304 dir.mkdirp("bar");
305 dir.touch_all(&["foo/a", "foo/b"]);
306 dir.touch_all(&["bar/a", "bar/b"]);
307
308 let wd = WalkDir::new(dir.path());
309 let r = dir.run_recursive(wd);
310 r.assert_no_errors();
311
312 let expected = vec![
313 dir.path().to_path_buf(),
314 dir.join("bar"),
315 dir.join("bar").join("a"),
316 dir.join("bar").join("b"),
317 dir.join("foo"),
318 dir.join("foo").join("a"),
319 dir.join("foo").join("b"),
320 ];
321 assert_eq!(expected, r.sorted_paths());
322 }
323
324 #[test]
sym_root_file_nofollow()325 fn sym_root_file_nofollow() {
326 let dir = Dir::tmp();
327 dir.touch("a");
328 dir.symlink_file("a", "a-link");
329
330 let wd = WalkDir::new(dir.join("a-link"));
331 let r = dir.run_recursive(wd);
332 r.assert_no_errors();
333
334 let ents = r.sorted_ents();
335 assert_eq!(1, ents.len());
336 let link = &ents[0];
337
338 assert_eq!(dir.join("a-link"), link.path());
339
340 assert!(link.path_is_symlink());
341
342 assert_eq!(dir.join("a"), fs::read_link(link.path()).unwrap());
343
344 assert_eq!(0, link.depth());
345
346 assert!(link.file_type().is_symlink());
347 assert!(!link.file_type().is_file());
348 assert!(!link.file_type().is_dir());
349
350 assert!(link.metadata().unwrap().file_type().is_symlink());
351 assert!(!link.metadata().unwrap().is_file());
352 assert!(!link.metadata().unwrap().is_dir());
353 }
354
355 #[test]
sym_root_file_follow()356 fn sym_root_file_follow() {
357 let dir = Dir::tmp();
358 dir.touch("a");
359 dir.symlink_file("a", "a-link");
360
361 let wd = WalkDir::new(dir.join("a-link")).follow_links(true);
362 let r = dir.run_recursive(wd);
363 r.assert_no_errors();
364
365 let ents = r.sorted_ents();
366 let link = &ents[0];
367
368 assert_eq!(dir.join("a-link"), link.path());
369
370 assert!(link.path_is_symlink());
371
372 assert_eq!(dir.join("a"), fs::read_link(link.path()).unwrap());
373
374 assert_eq!(0, link.depth());
375
376 assert!(!link.file_type().is_symlink());
377 assert!(link.file_type().is_file());
378 assert!(!link.file_type().is_dir());
379
380 assert!(!link.metadata().unwrap().file_type().is_symlink());
381 assert!(link.metadata().unwrap().is_file());
382 assert!(!link.metadata().unwrap().is_dir());
383 }
384
385 #[test]
sym_root_dir_nofollow()386 fn sym_root_dir_nofollow() {
387 let dir = Dir::tmp();
388 dir.mkdirp("a");
389 dir.symlink_dir("a", "a-link");
390 dir.touch("a/zzz");
391
392 let wd = WalkDir::new(dir.join("a-link"));
393 let r = dir.run_recursive(wd);
394 r.assert_no_errors();
395
396 let ents = r.sorted_ents();
397 assert_eq!(2, ents.len());
398 let link = &ents[0];
399
400 assert_eq!(dir.join("a-link"), link.path());
401
402 assert!(link.path_is_symlink());
403
404 assert_eq!(dir.join("a"), fs::read_link(link.path()).unwrap());
405
406 assert_eq!(0, link.depth());
407
408 assert!(link.file_type().is_symlink());
409 assert!(!link.file_type().is_file());
410 assert!(!link.file_type().is_dir());
411
412 assert!(link.metadata().unwrap().file_type().is_symlink());
413 assert!(!link.metadata().unwrap().is_file());
414 assert!(!link.metadata().unwrap().is_dir());
415
416 let link_zzz = &ents[1];
417 assert_eq!(dir.join("a-link").join("zzz"), link_zzz.path());
418 assert!(!link_zzz.path_is_symlink());
419 }
420
421 #[test]
sym_root_dir_follow()422 fn sym_root_dir_follow() {
423 let dir = Dir::tmp();
424 dir.mkdirp("a");
425 dir.symlink_dir("a", "a-link");
426 dir.touch("a/zzz");
427
428 let wd = WalkDir::new(dir.join("a-link")).follow_links(true);
429 let r = dir.run_recursive(wd);
430 r.assert_no_errors();
431
432 let ents = r.sorted_ents();
433 assert_eq!(2, ents.len());
434 let link = &ents[0];
435
436 assert_eq!(dir.join("a-link"), link.path());
437
438 assert!(link.path_is_symlink());
439
440 assert_eq!(dir.join("a"), fs::read_link(link.path()).unwrap());
441
442 assert_eq!(0, link.depth());
443
444 assert!(!link.file_type().is_symlink());
445 assert!(!link.file_type().is_file());
446 assert!(link.file_type().is_dir());
447
448 assert!(!link.metadata().unwrap().file_type().is_symlink());
449 assert!(!link.metadata().unwrap().is_file());
450 assert!(link.metadata().unwrap().is_dir());
451
452 let link_zzz = &ents[1];
453 assert_eq!(dir.join("a-link").join("zzz"), link_zzz.path());
454 assert!(!link_zzz.path_is_symlink());
455 }
456
457 #[test]
sym_file_nofollow()458 fn sym_file_nofollow() {
459 let dir = Dir::tmp();
460 dir.touch("a");
461 dir.symlink_file("a", "a-link");
462
463 let wd = WalkDir::new(dir.path());
464 let r = dir.run_recursive(wd);
465 r.assert_no_errors();
466
467 let ents = r.sorted_ents();
468 assert_eq!(3, ents.len());
469 let (src, link) = (&ents[1], &ents[2]);
470
471 assert_eq!(dir.join("a"), src.path());
472 assert_eq!(dir.join("a-link"), link.path());
473
474 assert!(!src.path_is_symlink());
475 assert!(link.path_is_symlink());
476
477 assert_eq!(dir.join("a"), fs::read_link(link.path()).unwrap());
478
479 assert_eq!(1, src.depth());
480 assert_eq!(1, link.depth());
481
482 assert!(src.file_type().is_file());
483 assert!(link.file_type().is_symlink());
484 assert!(!link.file_type().is_file());
485 assert!(!link.file_type().is_dir());
486
487 assert!(src.metadata().unwrap().is_file());
488 assert!(link.metadata().unwrap().file_type().is_symlink());
489 assert!(!link.metadata().unwrap().is_file());
490 assert!(!link.metadata().unwrap().is_dir());
491 }
492
493 #[test]
sym_file_follow()494 fn sym_file_follow() {
495 let dir = Dir::tmp();
496 dir.touch("a");
497 dir.symlink_file("a", "a-link");
498
499 let wd = WalkDir::new(dir.path()).follow_links(true);
500 let r = dir.run_recursive(wd);
501 r.assert_no_errors();
502
503 let ents = r.sorted_ents();
504 assert_eq!(3, ents.len());
505 let (src, link) = (&ents[1], &ents[2]);
506
507 assert_eq!(dir.join("a"), src.path());
508 assert_eq!(dir.join("a-link"), link.path());
509
510 assert!(!src.path_is_symlink());
511 assert!(link.path_is_symlink());
512
513 assert_eq!(dir.join("a"), fs::read_link(link.path()).unwrap());
514
515 assert_eq!(1, src.depth());
516 assert_eq!(1, link.depth());
517
518 assert!(src.file_type().is_file());
519 assert!(!link.file_type().is_symlink());
520 assert!(link.file_type().is_file());
521 assert!(!link.file_type().is_dir());
522
523 assert!(src.metadata().unwrap().is_file());
524 assert!(!link.metadata().unwrap().file_type().is_symlink());
525 assert!(link.metadata().unwrap().is_file());
526 assert!(!link.metadata().unwrap().is_dir());
527 }
528
529 #[test]
sym_dir_nofollow()530 fn sym_dir_nofollow() {
531 let dir = Dir::tmp();
532 dir.mkdirp("a");
533 dir.symlink_dir("a", "a-link");
534 dir.touch("a/zzz");
535
536 let wd = WalkDir::new(dir.path());
537 let r = dir.run_recursive(wd);
538 r.assert_no_errors();
539
540 let ents = r.sorted_ents();
541 assert_eq!(4, ents.len());
542 let (src, link) = (&ents[1], &ents[3]);
543
544 assert_eq!(dir.join("a"), src.path());
545 assert_eq!(dir.join("a-link"), link.path());
546
547 assert!(!src.path_is_symlink());
548 assert!(link.path_is_symlink());
549
550 assert_eq!(dir.join("a"), fs::read_link(link.path()).unwrap());
551
552 assert_eq!(1, src.depth());
553 assert_eq!(1, link.depth());
554
555 assert!(src.file_type().is_dir());
556 assert!(link.file_type().is_symlink());
557 assert!(!link.file_type().is_file());
558 assert!(!link.file_type().is_dir());
559
560 assert!(src.metadata().unwrap().is_dir());
561 assert!(link.metadata().unwrap().file_type().is_symlink());
562 assert!(!link.metadata().unwrap().is_file());
563 assert!(!link.metadata().unwrap().is_dir());
564 }
565
566 #[test]
sym_dir_follow()567 fn sym_dir_follow() {
568 let dir = Dir::tmp();
569 dir.mkdirp("a");
570 dir.symlink_dir("a", "a-link");
571 dir.touch("a/zzz");
572
573 let wd = WalkDir::new(dir.path()).follow_links(true);
574 let r = dir.run_recursive(wd);
575 r.assert_no_errors();
576
577 let ents = r.sorted_ents();
578 assert_eq!(5, ents.len());
579 let (src, link) = (&ents[1], &ents[3]);
580
581 assert_eq!(dir.join("a"), src.path());
582 assert_eq!(dir.join("a-link"), link.path());
583
584 assert!(!src.path_is_symlink());
585 assert!(link.path_is_symlink());
586
587 assert_eq!(dir.join("a"), fs::read_link(link.path()).unwrap());
588
589 assert_eq!(1, src.depth());
590 assert_eq!(1, link.depth());
591
592 assert!(src.file_type().is_dir());
593 assert!(!link.file_type().is_symlink());
594 assert!(!link.file_type().is_file());
595 assert!(link.file_type().is_dir());
596
597 assert!(src.metadata().unwrap().is_dir());
598 assert!(!link.metadata().unwrap().file_type().is_symlink());
599 assert!(!link.metadata().unwrap().is_file());
600 assert!(link.metadata().unwrap().is_dir());
601
602 let (src_zzz, link_zzz) = (&ents[2], &ents[4]);
603 assert_eq!(dir.join("a").join("zzz"), src_zzz.path());
604 assert_eq!(dir.join("a-link").join("zzz"), link_zzz.path());
605 assert!(!src_zzz.path_is_symlink());
606 assert!(!link_zzz.path_is_symlink());
607 }
608
609 #[test]
sym_noloop()610 fn sym_noloop() {
611 let dir = Dir::tmp();
612 dir.mkdirp("a/b/c");
613 dir.symlink_dir("a", "a/b/c/a-link");
614
615 let wd = WalkDir::new(dir.path());
616 let r = dir.run_recursive(wd);
617 // There's no loop if we aren't following symlinks.
618 r.assert_no_errors();
619
620 assert_eq!(5, r.ents().len());
621 }
622
623 #[test]
sym_loop_detect()624 fn sym_loop_detect() {
625 let dir = Dir::tmp();
626 dir.mkdirp("a/b/c");
627 dir.symlink_dir("a", "a/b/c/a-link");
628
629 let wd = WalkDir::new(dir.path()).follow_links(true);
630 let r = dir.run_recursive(wd);
631
632 let (ents, errs) = (r.sorted_ents(), r.errs());
633 assert_eq!(4, ents.len());
634 assert_eq!(1, errs.len());
635
636 let err = &errs[0];
637
638 let expected = dir.join("a/b/c/a-link");
639 assert_eq!(Some(&*expected), err.path());
640
641 let expected = dir.join("a");
642 assert_eq!(Some(&*expected), err.loop_ancestor());
643
644 assert_eq!(4, err.depth());
645 assert!(err.io_error().is_none());
646 }
647
648 #[test]
sym_self_loop_no_error()649 fn sym_self_loop_no_error() {
650 let dir = Dir::tmp();
651 dir.symlink_file("a", "a");
652
653 let wd = WalkDir::new(dir.path());
654 let r = dir.run_recursive(wd);
655 // No errors occur because even though the symlink points to nowhere, it
656 // is never followed, and thus no error occurs.
657 r.assert_no_errors();
658 assert_eq!(2, r.ents().len());
659
660 let ent = &r.ents()[1];
661 assert_eq!(dir.join("a"), ent.path());
662 assert!(ent.path_is_symlink());
663
664 assert!(ent.file_type().is_symlink());
665 assert!(!ent.file_type().is_file());
666 assert!(!ent.file_type().is_dir());
667
668 assert!(ent.metadata().unwrap().file_type().is_symlink());
669 assert!(!ent.metadata().unwrap().file_type().is_file());
670 assert!(!ent.metadata().unwrap().file_type().is_dir());
671 }
672
673 #[test]
sym_file_self_loop_io_error()674 fn sym_file_self_loop_io_error() {
675 let dir = Dir::tmp();
676 dir.symlink_file("a", "a");
677
678 let wd = WalkDir::new(dir.path()).follow_links(true);
679 let r = dir.run_recursive(wd);
680
681 let (ents, errs) = (r.sorted_ents(), r.errs());
682 assert_eq!(1, ents.len());
683 assert_eq!(1, errs.len());
684
685 let err = &errs[0];
686
687 let expected = dir.join("a");
688 assert_eq!(Some(&*expected), err.path());
689 assert_eq!(1, err.depth());
690 assert!(err.loop_ancestor().is_none());
691 assert!(err.io_error().is_some());
692 }
693
694 #[test]
sym_dir_self_loop_io_error()695 fn sym_dir_self_loop_io_error() {
696 let dir = Dir::tmp();
697 dir.symlink_dir("a", "a");
698
699 let wd = WalkDir::new(dir.path()).follow_links(true);
700 let r = dir.run_recursive(wd);
701
702 let (ents, errs) = (r.sorted_ents(), r.errs());
703 assert_eq!(1, ents.len());
704 assert_eq!(1, errs.len());
705
706 let err = &errs[0];
707
708 let expected = dir.join("a");
709 assert_eq!(Some(&*expected), err.path());
710 assert_eq!(1, err.depth());
711 assert!(err.loop_ancestor().is_none());
712 assert!(err.io_error().is_some());
713 }
714
715 #[test]
min_depth_1()716 fn min_depth_1() {
717 let dir = Dir::tmp();
718 dir.mkdirp("a/b");
719
720 let wd = WalkDir::new(dir.path()).min_depth(1);
721 let r = dir.run_recursive(wd);
722 r.assert_no_errors();
723
724 let expected = vec![dir.join("a"), dir.join("a").join("b")];
725 assert_eq!(expected, r.sorted_paths());
726 }
727
728 #[test]
min_depth_2()729 fn min_depth_2() {
730 let dir = Dir::tmp();
731 dir.mkdirp("a/b");
732
733 let wd = WalkDir::new(dir.path()).min_depth(2);
734 let r = dir.run_recursive(wd);
735 r.assert_no_errors();
736
737 let expected = vec![dir.join("a").join("b")];
738 assert_eq!(expected, r.sorted_paths());
739 }
740
741 #[test]
max_depth_0()742 fn max_depth_0() {
743 let dir = Dir::tmp();
744 dir.mkdirp("a/b");
745
746 let wd = WalkDir::new(dir.path()).max_depth(0);
747 let r = dir.run_recursive(wd);
748 r.assert_no_errors();
749
750 let expected = vec![dir.path().to_path_buf()];
751 assert_eq!(expected, r.sorted_paths());
752 }
753
754 #[test]
max_depth_1()755 fn max_depth_1() {
756 let dir = Dir::tmp();
757 dir.mkdirp("a/b");
758
759 let wd = WalkDir::new(dir.path()).max_depth(1);
760 let r = dir.run_recursive(wd);
761 r.assert_no_errors();
762
763 let expected = vec![dir.path().to_path_buf(), dir.join("a")];
764 assert_eq!(expected, r.sorted_paths());
765 }
766
767 #[test]
max_depth_2()768 fn max_depth_2() {
769 let dir = Dir::tmp();
770 dir.mkdirp("a/b");
771
772 let wd = WalkDir::new(dir.path()).max_depth(2);
773 let r = dir.run_recursive(wd);
774 r.assert_no_errors();
775
776 let expected =
777 vec![dir.path().to_path_buf(), dir.join("a"), dir.join("a").join("b")];
778 assert_eq!(expected, r.sorted_paths());
779 }
780
781 // FIXME: This test seems wrong. It should return nothing!
782 #[test]
min_max_depth_diff_nada()783 fn min_max_depth_diff_nada() {
784 let dir = Dir::tmp();
785 dir.mkdirp("a/b/c");
786
787 let wd = WalkDir::new(dir.path()).min_depth(3).max_depth(2);
788 let r = dir.run_recursive(wd);
789 r.assert_no_errors();
790
791 let expected = vec![dir.join("a").join("b").join("c")];
792 assert_eq!(expected, r.sorted_paths());
793 }
794
795 #[test]
min_max_depth_diff_0()796 fn min_max_depth_diff_0() {
797 let dir = Dir::tmp();
798 dir.mkdirp("a/b/c");
799
800 let wd = WalkDir::new(dir.path()).min_depth(2).max_depth(2);
801 let r = dir.run_recursive(wd);
802 r.assert_no_errors();
803
804 let expected = vec![dir.join("a").join("b")];
805 assert_eq!(expected, r.sorted_paths());
806 }
807
808 #[test]
min_max_depth_diff_1()809 fn min_max_depth_diff_1() {
810 let dir = Dir::tmp();
811 dir.mkdirp("a/b/c");
812
813 let wd = WalkDir::new(dir.path()).min_depth(1).max_depth(2);
814 let r = dir.run_recursive(wd);
815 r.assert_no_errors();
816
817 let expected = vec![dir.join("a"), dir.join("a").join("b")];
818 assert_eq!(expected, r.sorted_paths());
819 }
820
821 #[test]
contents_first()822 fn contents_first() {
823 let dir = Dir::tmp();
824 dir.touch("a");
825
826 let wd = WalkDir::new(dir.path()).contents_first(true);
827 let r = dir.run_recursive(wd);
828 r.assert_no_errors();
829
830 let expected = vec![dir.join("a"), dir.path().to_path_buf()];
831 assert_eq!(expected, r.paths());
832 }
833
834 #[test]
skip_current_dir()835 fn skip_current_dir() {
836 let dir = Dir::tmp();
837 dir.mkdirp("foo/bar/baz");
838 dir.mkdirp("quux");
839
840 let mut paths = vec![];
841 let mut it = WalkDir::new(dir.path()).into_iter();
842 while let Some(result) = it.next() {
843 let ent = result.unwrap();
844 paths.push(ent.path().to_path_buf());
845 if ent.file_name() == "bar" {
846 it.skip_current_dir();
847 }
848 }
849 paths.sort();
850
851 let expected = vec![
852 dir.path().to_path_buf(),
853 dir.join("foo"),
854 dir.join("foo").join("bar"),
855 dir.join("quux"),
856 ];
857 assert_eq!(expected, paths);
858 }
859
860 #[test]
filter_entry()861 fn filter_entry() {
862 let dir = Dir::tmp();
863 dir.mkdirp("foo/bar/baz/abc");
864 dir.mkdirp("quux");
865
866 let wd = WalkDir::new(dir.path())
867 .into_iter()
868 .filter_entry(|ent| ent.file_name() != "baz");
869 let r = dir.run_recursive(wd);
870 r.assert_no_errors();
871
872 let expected = vec![
873 dir.path().to_path_buf(),
874 dir.join("foo"),
875 dir.join("foo").join("bar"),
876 dir.join("quux"),
877 ];
878 assert_eq!(expected, r.sorted_paths());
879 }
880
881 #[test]
sort_by()882 fn sort_by() {
883 let dir = Dir::tmp();
884 dir.mkdirp("foo/bar/baz/abc");
885 dir.mkdirp("quux");
886
887 let wd = WalkDir::new(dir.path())
888 .sort_by(|a, b| a.file_name().cmp(b.file_name()).reverse());
889 let r = dir.run_recursive(wd);
890 r.assert_no_errors();
891
892 let expected = vec![
893 dir.path().to_path_buf(),
894 dir.join("quux"),
895 dir.join("foo"),
896 dir.join("foo").join("bar"),
897 dir.join("foo").join("bar").join("baz"),
898 dir.join("foo").join("bar").join("baz").join("abc"),
899 ];
900 assert_eq!(expected, r.paths());
901 }
902
903 #[test]
sort_by_key()904 fn sort_by_key() {
905 let dir = Dir::tmp();
906 dir.mkdirp("foo/bar/baz/abc");
907 dir.mkdirp("quux");
908
909 let wd =
910 WalkDir::new(dir.path()).sort_by_key(|a| a.file_name().to_owned());
911 let r = dir.run_recursive(wd);
912 r.assert_no_errors();
913
914 let expected = vec![
915 dir.path().to_path_buf(),
916 dir.join("foo"),
917 dir.join("foo").join("bar"),
918 dir.join("foo").join("bar").join("baz"),
919 dir.join("foo").join("bar").join("baz").join("abc"),
920 dir.join("quux"),
921 ];
922 assert_eq!(expected, r.paths());
923 }
924
925 #[test]
sort_by_file_name()926 fn sort_by_file_name() {
927 let dir = Dir::tmp();
928 dir.mkdirp("foo/bar/baz/abc");
929 dir.mkdirp("quux");
930
931 let wd = WalkDir::new(dir.path()).sort_by_file_name();
932 let r = dir.run_recursive(wd);
933 r.assert_no_errors();
934
935 let expected = vec![
936 dir.path().to_path_buf(),
937 dir.join("foo"),
938 dir.join("foo").join("bar"),
939 dir.join("foo").join("bar").join("baz"),
940 dir.join("foo").join("bar").join("baz").join("abc"),
941 dir.join("quux"),
942 ];
943 assert_eq!(expected, r.paths());
944 }
945
946 #[test]
sort_max_open()947 fn sort_max_open() {
948 let dir = Dir::tmp();
949 dir.mkdirp("foo/bar/baz/abc");
950 dir.mkdirp("quux");
951
952 let wd = WalkDir::new(dir.path())
953 .max_open(1)
954 .sort_by(|a, b| a.file_name().cmp(b.file_name()).reverse());
955 let r = dir.run_recursive(wd);
956 r.assert_no_errors();
957
958 let expected = vec![
959 dir.path().to_path_buf(),
960 dir.join("quux"),
961 dir.join("foo"),
962 dir.join("foo").join("bar"),
963 dir.join("foo").join("bar").join("baz"),
964 dir.join("foo").join("bar").join("baz").join("abc"),
965 ];
966 assert_eq!(expected, r.paths());
967 }
968
969 #[cfg(target_os = "linux")]
970 #[test]
same_file_system()971 fn same_file_system() {
972 use std::path::Path;
973
974 // This test is a little weird since it's not clear whether it's a good
975 // idea to setup a distinct mounted volume in these tests. Instead, we
976 // probe for an existing one.
977 if !Path::new("/sys").is_dir() {
978 return;
979 }
980
981 let dir = Dir::tmp();
982 dir.touch("a");
983 dir.symlink_dir("/sys", "sys-link");
984
985 // First, do a sanity check that things work without following symlinks.
986 let wd = WalkDir::new(dir.path());
987 let r = dir.run_recursive(wd);
988 r.assert_no_errors();
989
990 let expected =
991 vec![dir.path().to_path_buf(), dir.join("a"), dir.join("sys-link")];
992 assert_eq!(expected, r.sorted_paths());
993
994 // ... now follow symlinks and ensure we don't descend into /sys.
995 let wd =
996 WalkDir::new(dir.path()).same_file_system(true).follow_links(true);
997 let r = dir.run_recursive(wd);
998 r.assert_no_errors();
999
1000 let expected =
1001 vec![dir.path().to_path_buf(), dir.join("a"), dir.join("sys-link")];
1002 assert_eq!(expected, r.sorted_paths());
1003 }
1004
1005 // Tests that skip_current_dir doesn't destroy internal invariants.
1006 //
1007 // See: https://github.com/BurntSushi/walkdir/issues/118
1008 #[test]
regression_skip_current_dir()1009 fn regression_skip_current_dir() {
1010 let dir = Dir::tmp();
1011 dir.mkdirp("foo/a/b");
1012 dir.mkdirp("foo/1/2");
1013
1014 let mut wd = WalkDir::new(dir.path()).max_open(1).into_iter();
1015 wd.next();
1016 wd.next();
1017 wd.next();
1018 wd.next();
1019
1020 wd.skip_current_dir();
1021 wd.skip_current_dir();
1022 wd.next();
1023 }
1024