]> git.proxmox.com Git - rustc.git/blame - library/std/src/path/tests.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / library / std / src / path / tests.rs
CommitLineData
1b1a35ee
XL
1use super::*;
2
3c0e092e
XL
3use crate::collections::hash_map::DefaultHasher;
4use crate::collections::{BTreeSet, HashSet};
5use crate::hash::Hasher;
1b1a35ee
XL
6use crate::rc::Rc;
7use crate::sync::Arc;
94222f64 8use core::hint::black_box;
1b1a35ee 9
923072b8 10#[allow(unknown_lints, unused_macro_rules)]
94222f64 11macro_rules! t (
1b1a35ee
XL
12 ($path:expr, iter: $iter:expr) => (
13 {
14 let path = Path::new($path);
15
16 // Forward iteration
17 let comps = path.iter()
18 .map(|p| p.to_string_lossy().into_owned())
19 .collect::<Vec<String>>();
20 let exp: &[&str] = &$iter;
21 let exps = exp.iter().map(|s| s.to_string()).collect::<Vec<String>>();
22 assert!(comps == exps, "iter: Expected {:?}, found {:?}",
23 exps, comps);
24
25 // Reverse iteration
26 let comps = Path::new($path).iter().rev()
27 .map(|p| p.to_string_lossy().into_owned())
28 .collect::<Vec<String>>();
29 let exps = exps.into_iter().rev().collect::<Vec<String>>();
30 assert!(comps == exps, "iter().rev(): Expected {:?}, found {:?}",
31 exps, comps);
32 }
33 );
34
35 ($path:expr, has_root: $has_root:expr, is_absolute: $is_absolute:expr) => (
36 {
37 let path = Path::new($path);
38
39 let act_root = path.has_root();
40 assert!(act_root == $has_root, "has_root: Expected {:?}, found {:?}",
41 $has_root, act_root);
42
43 let act_abs = path.is_absolute();
44 assert!(act_abs == $is_absolute, "is_absolute: Expected {:?}, found {:?}",
45 $is_absolute, act_abs);
46 }
47 );
48
49 ($path:expr, parent: $parent:expr, file_name: $file:expr) => (
50 {
51 let path = Path::new($path);
52
53 let parent = path.parent().map(|p| p.to_str().unwrap());
54 let exp_parent: Option<&str> = $parent;
55 assert!(parent == exp_parent, "parent: Expected {:?}, found {:?}",
56 exp_parent, parent);
57
58 let file = path.file_name().map(|p| p.to_str().unwrap());
59 let exp_file: Option<&str> = $file;
60 assert!(file == exp_file, "file_name: Expected {:?}, found {:?}",
61 exp_file, file);
62 }
63 );
64
65 ($path:expr, file_stem: $file_stem:expr, extension: $extension:expr) => (
66 {
67 let path = Path::new($path);
68
69 let stem = path.file_stem().map(|p| p.to_str().unwrap());
70 let exp_stem: Option<&str> = $file_stem;
71 assert!(stem == exp_stem, "file_stem: Expected {:?}, found {:?}",
72 exp_stem, stem);
73
74 let ext = path.extension().map(|p| p.to_str().unwrap());
75 let exp_ext: Option<&str> = $extension;
76 assert!(ext == exp_ext, "extension: Expected {:?}, found {:?}",
77 exp_ext, ext);
78 }
79 );
80
94222f64
XL
81 ($path:expr, file_prefix: $file_prefix:expr, extension: $extension:expr) => (
82 {
83 let path = Path::new($path);
84
85 let prefix = path.file_prefix().map(|p| p.to_str().unwrap());
86 let exp_prefix: Option<&str> = $file_prefix;
87 assert!(prefix == exp_prefix, "file_prefix: Expected {:?}, found {:?}",
88 exp_prefix, prefix);
89
90 let ext = path.extension().map(|p| p.to_str().unwrap());
91 let exp_ext: Option<&str> = $extension;
92 assert!(ext == exp_ext, "extension: Expected {:?}, found {:?}",
93 exp_ext, ext);
94 }
95 );
96
1b1a35ee
XL
97 ($path:expr, iter: $iter:expr,
98 has_root: $has_root:expr, is_absolute: $is_absolute:expr,
99 parent: $parent:expr, file_name: $file:expr,
94222f64
XL
100 file_stem: $file_stem:expr, extension: $extension:expr,
101 file_prefix: $file_prefix:expr) => (
1b1a35ee
XL
102 {
103 t!($path, iter: $iter);
104 t!($path, has_root: $has_root, is_absolute: $is_absolute);
105 t!($path, parent: $parent, file_name: $file);
106 t!($path, file_stem: $file_stem, extension: $extension);
94222f64 107 t!($path, file_prefix: $file_prefix, extension: $extension);
1b1a35ee
XL
108 }
109 );
110);
111
112#[test]
113fn into() {
114 use crate::borrow::Cow;
115
116 let static_path = Path::new("/home/foo");
117 let static_cow_path: Cow<'static, Path> = static_path.into();
118 let pathbuf = PathBuf::from("/home/foo");
119
120 {
121 let path: &Path = &pathbuf;
122 let borrowed_cow_path: Cow<'_, Path> = path.into();
123
124 assert_eq!(static_cow_path, borrowed_cow_path);
125 }
126
127 let owned_cow_path: Cow<'static, Path> = pathbuf.into();
128
129 assert_eq!(static_cow_path, owned_cow_path);
130}
131
132#[test]
133#[cfg(unix)]
134pub fn test_decompositions_unix() {
135 t!("",
136 iter: [],
137 has_root: false,
138 is_absolute: false,
139 parent: None,
140 file_name: None,
141 file_stem: None,
94222f64
XL
142 extension: None,
143 file_prefix: None
1b1a35ee
XL
144 );
145
146 t!("foo",
147 iter: ["foo"],
148 has_root: false,
149 is_absolute: false,
150 parent: Some(""),
151 file_name: Some("foo"),
152 file_stem: Some("foo"),
94222f64
XL
153 extension: None,
154 file_prefix: Some("foo")
1b1a35ee
XL
155 );
156
157 t!("/",
158 iter: ["/"],
159 has_root: true,
160 is_absolute: true,
161 parent: None,
162 file_name: None,
163 file_stem: None,
94222f64
XL
164 extension: None,
165 file_prefix: None
1b1a35ee
XL
166 );
167
168 t!("/foo",
169 iter: ["/", "foo"],
170 has_root: true,
171 is_absolute: true,
172 parent: Some("/"),
173 file_name: Some("foo"),
174 file_stem: Some("foo"),
94222f64
XL
175 extension: None,
176 file_prefix: Some("foo")
1b1a35ee
XL
177 );
178
179 t!("foo/",
180 iter: ["foo"],
181 has_root: false,
182 is_absolute: false,
183 parent: Some(""),
184 file_name: Some("foo"),
185 file_stem: Some("foo"),
94222f64
XL
186 extension: None,
187 file_prefix: Some("foo")
1b1a35ee
XL
188 );
189
190 t!("/foo/",
191 iter: ["/", "foo"],
192 has_root: true,
193 is_absolute: true,
194 parent: Some("/"),
195 file_name: Some("foo"),
196 file_stem: Some("foo"),
94222f64
XL
197 extension: None,
198 file_prefix: Some("foo")
1b1a35ee
XL
199 );
200
201 t!("foo/bar",
202 iter: ["foo", "bar"],
203 has_root: false,
204 is_absolute: false,
205 parent: Some("foo"),
206 file_name: Some("bar"),
207 file_stem: Some("bar"),
94222f64
XL
208 extension: None,
209 file_prefix: Some("bar")
1b1a35ee
XL
210 );
211
212 t!("/foo/bar",
213 iter: ["/", "foo", "bar"],
214 has_root: true,
215 is_absolute: true,
216 parent: Some("/foo"),
217 file_name: Some("bar"),
218 file_stem: Some("bar"),
94222f64
XL
219 extension: None,
220 file_prefix: Some("bar")
1b1a35ee
XL
221 );
222
223 t!("///foo///",
224 iter: ["/", "foo"],
225 has_root: true,
226 is_absolute: true,
227 parent: Some("/"),
228 file_name: Some("foo"),
229 file_stem: Some("foo"),
94222f64
XL
230 extension: None,
231 file_prefix: Some("foo")
1b1a35ee
XL
232 );
233
234 t!("///foo///bar",
235 iter: ["/", "foo", "bar"],
236 has_root: true,
237 is_absolute: true,
238 parent: Some("///foo"),
239 file_name: Some("bar"),
240 file_stem: Some("bar"),
94222f64
XL
241 extension: None,
242 file_prefix: Some("bar")
1b1a35ee
XL
243 );
244
245 t!("./.",
246 iter: ["."],
247 has_root: false,
248 is_absolute: false,
249 parent: Some(""),
250 file_name: None,
251 file_stem: None,
94222f64
XL
252 extension: None,
253 file_prefix: None
1b1a35ee
XL
254 );
255
256 t!("/..",
257 iter: ["/", ".."],
258 has_root: true,
259 is_absolute: true,
260 parent: Some("/"),
261 file_name: None,
262 file_stem: None,
94222f64
XL
263 extension: None,
264 file_prefix: None
1b1a35ee
XL
265 );
266
267 t!("../",
268 iter: [".."],
269 has_root: false,
270 is_absolute: false,
271 parent: Some(""),
272 file_name: None,
273 file_stem: None,
94222f64
XL
274 extension: None,
275 file_prefix: None
1b1a35ee
XL
276 );
277
278 t!("foo/.",
279 iter: ["foo"],
280 has_root: false,
281 is_absolute: false,
282 parent: Some(""),
283 file_name: Some("foo"),
284 file_stem: Some("foo"),
94222f64
XL
285 extension: None,
286 file_prefix: Some("foo")
1b1a35ee
XL
287 );
288
289 t!("foo/..",
290 iter: ["foo", ".."],
291 has_root: false,
292 is_absolute: false,
293 parent: Some("foo"),
294 file_name: None,
295 file_stem: None,
94222f64
XL
296 extension: None,
297 file_prefix: None
1b1a35ee
XL
298 );
299
300 t!("foo/./",
301 iter: ["foo"],
302 has_root: false,
303 is_absolute: false,
304 parent: Some(""),
305 file_name: Some("foo"),
306 file_stem: Some("foo"),
94222f64
XL
307 extension: None,
308 file_prefix: Some("foo")
1b1a35ee
XL
309 );
310
311 t!("foo/./bar",
312 iter: ["foo", "bar"],
313 has_root: false,
314 is_absolute: false,
315 parent: Some("foo"),
316 file_name: Some("bar"),
317 file_stem: Some("bar"),
94222f64
XL
318 extension: None,
319 file_prefix: Some("bar")
1b1a35ee
XL
320 );
321
322 t!("foo/../",
323 iter: ["foo", ".."],
324 has_root: false,
325 is_absolute: false,
326 parent: Some("foo"),
327 file_name: None,
328 file_stem: None,
94222f64
XL
329 extension: None,
330 file_prefix: None
1b1a35ee
XL
331 );
332
333 t!("foo/../bar",
334 iter: ["foo", "..", "bar"],
335 has_root: false,
336 is_absolute: false,
337 parent: Some("foo/.."),
338 file_name: Some("bar"),
339 file_stem: Some("bar"),
94222f64
XL
340 extension: None,
341 file_prefix: Some("bar")
1b1a35ee
XL
342 );
343
344 t!("./a",
345 iter: [".", "a"],
346 has_root: false,
347 is_absolute: false,
348 parent: Some("."),
349 file_name: Some("a"),
350 file_stem: Some("a"),
94222f64
XL
351 extension: None,
352 file_prefix: Some("a")
1b1a35ee
XL
353 );
354
355 t!(".",
356 iter: ["."],
357 has_root: false,
358 is_absolute: false,
359 parent: Some(""),
360 file_name: None,
361 file_stem: None,
94222f64
XL
362 extension: None,
363 file_prefix: None
1b1a35ee
XL
364 );
365
366 t!("./",
367 iter: ["."],
368 has_root: false,
369 is_absolute: false,
370 parent: Some(""),
371 file_name: None,
372 file_stem: None,
94222f64
XL
373 extension: None,
374 file_prefix: None
1b1a35ee
XL
375 );
376
377 t!("a/b",
378 iter: ["a", "b"],
379 has_root: false,
380 is_absolute: false,
381 parent: Some("a"),
382 file_name: Some("b"),
383 file_stem: Some("b"),
94222f64
XL
384 extension: None,
385 file_prefix: Some("b")
1b1a35ee
XL
386 );
387
388 t!("a//b",
389 iter: ["a", "b"],
390 has_root: false,
391 is_absolute: false,
392 parent: Some("a"),
393 file_name: Some("b"),
394 file_stem: Some("b"),
94222f64
XL
395 extension: None,
396 file_prefix: Some("b")
1b1a35ee
XL
397 );
398
399 t!("a/./b",
400 iter: ["a", "b"],
401 has_root: false,
402 is_absolute: false,
403 parent: Some("a"),
404 file_name: Some("b"),
405 file_stem: Some("b"),
94222f64
XL
406 extension: None,
407 file_prefix: Some("b")
1b1a35ee
XL
408 );
409
410 t!("a/b/c",
411 iter: ["a", "b", "c"],
412 has_root: false,
413 is_absolute: false,
414 parent: Some("a/b"),
415 file_name: Some("c"),
416 file_stem: Some("c"),
94222f64
XL
417 extension: None,
418 file_prefix: Some("c")
1b1a35ee
XL
419 );
420
421 t!(".foo",
422 iter: [".foo"],
423 has_root: false,
424 is_absolute: false,
425 parent: Some(""),
426 file_name: Some(".foo"),
427 file_stem: Some(".foo"),
94222f64
XL
428 extension: None,
429 file_prefix: Some(".foo")
430 );
431
432 t!("a/.foo",
433 iter: ["a", ".foo"],
434 has_root: false,
435 is_absolute: false,
436 parent: Some("a"),
437 file_name: Some(".foo"),
438 file_stem: Some(".foo"),
439 extension: None,
440 file_prefix: Some(".foo")
441 );
442
443 t!("a/.rustfmt.toml",
444 iter: ["a", ".rustfmt.toml"],
445 has_root: false,
446 is_absolute: false,
447 parent: Some("a"),
448 file_name: Some(".rustfmt.toml"),
449 file_stem: Some(".rustfmt"),
450 extension: Some("toml"),
451 file_prefix: Some(".rustfmt")
452 );
453
454 t!("a/.x.y.z",
455 iter: ["a", ".x.y.z"],
456 has_root: false,
457 is_absolute: false,
458 parent: Some("a"),
459 file_name: Some(".x.y.z"),
460 file_stem: Some(".x.y"),
461 extension: Some("z"),
462 file_prefix: Some(".x")
1b1a35ee
XL
463 );
464}
465
466#[test]
467#[cfg(windows)]
468pub fn test_decompositions_windows() {
469 t!("",
470 iter: [],
471 has_root: false,
472 is_absolute: false,
473 parent: None,
474 file_name: None,
475 file_stem: None,
94222f64
XL
476 extension: None,
477 file_prefix: None
1b1a35ee
XL
478 );
479
480 t!("foo",
481 iter: ["foo"],
482 has_root: false,
483 is_absolute: false,
484 parent: Some(""),
485 file_name: Some("foo"),
486 file_stem: Some("foo"),
94222f64
XL
487 extension: None,
488 file_prefix: Some("foo")
1b1a35ee
XL
489 );
490
491 t!("/",
492 iter: ["\\"],
493 has_root: true,
494 is_absolute: false,
495 parent: None,
496 file_name: None,
497 file_stem: None,
94222f64
XL
498 extension: None,
499 file_prefix: None
1b1a35ee
XL
500 );
501
502 t!("\\",
503 iter: ["\\"],
504 has_root: true,
505 is_absolute: false,
506 parent: None,
507 file_name: None,
508 file_stem: None,
94222f64
XL
509 extension: None,
510 file_prefix: None
1b1a35ee
XL
511 );
512
513 t!("c:",
514 iter: ["c:"],
515 has_root: false,
516 is_absolute: false,
517 parent: None,
518 file_name: None,
519 file_stem: None,
94222f64
XL
520 extension: None,
521 file_prefix: None
1b1a35ee
XL
522 );
523
524 t!("c:\\",
525 iter: ["c:", "\\"],
526 has_root: true,
527 is_absolute: true,
528 parent: None,
529 file_name: None,
530 file_stem: None,
94222f64
XL
531 extension: None,
532 file_prefix: None
1b1a35ee
XL
533 );
534
535 t!("c:/",
536 iter: ["c:", "\\"],
537 has_root: true,
538 is_absolute: true,
539 parent: None,
540 file_name: None,
541 file_stem: None,
94222f64
XL
542 extension: None,
543 file_prefix: None
1b1a35ee
XL
544 );
545
546 t!("/foo",
547 iter: ["\\", "foo"],
548 has_root: true,
549 is_absolute: false,
550 parent: Some("/"),
551 file_name: Some("foo"),
552 file_stem: Some("foo"),
94222f64
XL
553 extension: None,
554 file_prefix: Some("foo")
1b1a35ee
XL
555 );
556
557 t!("foo/",
558 iter: ["foo"],
559 has_root: false,
560 is_absolute: false,
561 parent: Some(""),
562 file_name: Some("foo"),
563 file_stem: Some("foo"),
94222f64
XL
564 extension: None,
565 file_prefix: Some("foo")
1b1a35ee
XL
566 );
567
568 t!("/foo/",
569 iter: ["\\", "foo"],
570 has_root: true,
571 is_absolute: false,
572 parent: Some("/"),
573 file_name: Some("foo"),
574 file_stem: Some("foo"),
94222f64
XL
575 extension: None,
576 file_prefix: Some("foo")
1b1a35ee
XL
577 );
578
579 t!("foo/bar",
580 iter: ["foo", "bar"],
581 has_root: false,
582 is_absolute: false,
583 parent: Some("foo"),
584 file_name: Some("bar"),
585 file_stem: Some("bar"),
94222f64
XL
586 extension: None,
587 file_prefix: Some("bar")
1b1a35ee
XL
588 );
589
590 t!("/foo/bar",
591 iter: ["\\", "foo", "bar"],
592 has_root: true,
593 is_absolute: false,
594 parent: Some("/foo"),
595 file_name: Some("bar"),
596 file_stem: Some("bar"),
94222f64
XL
597 extension: None,
598 file_prefix: Some("bar")
1b1a35ee
XL
599 );
600
601 t!("///foo///",
602 iter: ["\\", "foo"],
603 has_root: true,
604 is_absolute: false,
605 parent: Some("/"),
606 file_name: Some("foo"),
607 file_stem: Some("foo"),
94222f64
XL
608 extension: None,
609 file_prefix: Some("foo")
1b1a35ee
XL
610 );
611
612 t!("///foo///bar",
613 iter: ["\\", "foo", "bar"],
614 has_root: true,
615 is_absolute: false,
616 parent: Some("///foo"),
617 file_name: Some("bar"),
618 file_stem: Some("bar"),
94222f64
XL
619 extension: None,
620 file_prefix: Some("bar")
1b1a35ee
XL
621 );
622
623 t!("./.",
624 iter: ["."],
625 has_root: false,
626 is_absolute: false,
627 parent: Some(""),
628 file_name: None,
629 file_stem: None,
94222f64
XL
630 extension: None,
631 file_prefix: None
1b1a35ee
XL
632 );
633
634 t!("/..",
635 iter: ["\\", ".."],
636 has_root: true,
637 is_absolute: false,
638 parent: Some("/"),
639 file_name: None,
640 file_stem: None,
94222f64
XL
641 extension: None,
642 file_prefix: None
1b1a35ee
XL
643 );
644
645 t!("../",
646 iter: [".."],
647 has_root: false,
648 is_absolute: false,
649 parent: Some(""),
650 file_name: None,
651 file_stem: None,
94222f64
XL
652 extension: None,
653 file_prefix: None
1b1a35ee
XL
654 );
655
656 t!("foo/.",
657 iter: ["foo"],
658 has_root: false,
659 is_absolute: false,
660 parent: Some(""),
661 file_name: Some("foo"),
662 file_stem: Some("foo"),
94222f64
XL
663 extension: None,
664 file_prefix: Some("foo")
1b1a35ee
XL
665 );
666
667 t!("foo/..",
668 iter: ["foo", ".."],
669 has_root: false,
670 is_absolute: false,
671 parent: Some("foo"),
672 file_name: None,
673 file_stem: None,
94222f64
XL
674 extension: None,
675 file_prefix: None
1b1a35ee
XL
676 );
677
678 t!("foo/./",
679 iter: ["foo"],
680 has_root: false,
681 is_absolute: false,
682 parent: Some(""),
683 file_name: Some("foo"),
684 file_stem: Some("foo"),
94222f64
XL
685 extension: None,
686 file_prefix: Some("foo")
1b1a35ee
XL
687 );
688
689 t!("foo/./bar",
690 iter: ["foo", "bar"],
691 has_root: false,
692 is_absolute: false,
693 parent: Some("foo"),
694 file_name: Some("bar"),
695 file_stem: Some("bar"),
94222f64
XL
696 extension: None,
697 file_prefix: Some("bar")
1b1a35ee
XL
698 );
699
700 t!("foo/../",
701 iter: ["foo", ".."],
702 has_root: false,
703 is_absolute: false,
704 parent: Some("foo"),
705 file_name: None,
706 file_stem: None,
94222f64
XL
707 extension: None,
708 file_prefix: None
1b1a35ee
XL
709 );
710
711 t!("foo/../bar",
712 iter: ["foo", "..", "bar"],
713 has_root: false,
714 is_absolute: false,
715 parent: Some("foo/.."),
716 file_name: Some("bar"),
717 file_stem: Some("bar"),
94222f64
XL
718 extension: None,
719 file_prefix: Some("bar")
1b1a35ee
XL
720 );
721
722 t!("./a",
723 iter: [".", "a"],
724 has_root: false,
725 is_absolute: false,
726 parent: Some("."),
727 file_name: Some("a"),
728 file_stem: Some("a"),
94222f64
XL
729 extension: None,
730 file_prefix: Some("a")
1b1a35ee
XL
731 );
732
733 t!(".",
734 iter: ["."],
735 has_root: false,
736 is_absolute: false,
737 parent: Some(""),
738 file_name: None,
739 file_stem: None,
94222f64
XL
740 extension: None,
741 file_prefix: None
1b1a35ee
XL
742 );
743
744 t!("./",
745 iter: ["."],
746 has_root: false,
747 is_absolute: false,
748 parent: Some(""),
749 file_name: None,
750 file_stem: None,
94222f64
XL
751 extension: None,
752 file_prefix: None
1b1a35ee
XL
753 );
754
755 t!("a/b",
756 iter: ["a", "b"],
757 has_root: false,
758 is_absolute: false,
759 parent: Some("a"),
760 file_name: Some("b"),
761 file_stem: Some("b"),
94222f64
XL
762 extension: None,
763 file_prefix: Some("b")
1b1a35ee
XL
764 );
765
766 t!("a//b",
767 iter: ["a", "b"],
768 has_root: false,
769 is_absolute: false,
770 parent: Some("a"),
771 file_name: Some("b"),
772 file_stem: Some("b"),
94222f64
XL
773 extension: None,
774 file_prefix: Some("b")
1b1a35ee
XL
775 );
776
777 t!("a/./b",
778 iter: ["a", "b"],
779 has_root: false,
780 is_absolute: false,
781 parent: Some("a"),
782 file_name: Some("b"),
783 file_stem: Some("b"),
94222f64
XL
784 extension: None,
785 file_prefix: Some("b")
1b1a35ee
XL
786 );
787
788 t!("a/b/c",
789 iter: ["a", "b", "c"],
790 has_root: false,
791 is_absolute: false,
792 parent: Some("a/b"),
793 file_name: Some("c"),
794 file_stem: Some("c"),
94222f64
XL
795 extension: None,
796 file_prefix: Some("c")
797 );
1b1a35ee
XL
798
799 t!("a\\b\\c",
800 iter: ["a", "b", "c"],
801 has_root: false,
802 is_absolute: false,
803 parent: Some("a\\b"),
804 file_name: Some("c"),
805 file_stem: Some("c"),
94222f64
XL
806 extension: None,
807 file_prefix: Some("c")
1b1a35ee
XL
808 );
809
810 t!("\\a",
811 iter: ["\\", "a"],
812 has_root: true,
813 is_absolute: false,
814 parent: Some("\\"),
815 file_name: Some("a"),
816 file_stem: Some("a"),
94222f64
XL
817 extension: None,
818 file_prefix: Some("a")
1b1a35ee
XL
819 );
820
821 t!("c:\\foo.txt",
822 iter: ["c:", "\\", "foo.txt"],
823 has_root: true,
824 is_absolute: true,
825 parent: Some("c:\\"),
826 file_name: Some("foo.txt"),
827 file_stem: Some("foo"),
94222f64
XL
828 extension: Some("txt"),
829 file_prefix: Some("foo")
1b1a35ee
XL
830 );
831
832 t!("\\\\server\\share\\foo.txt",
833 iter: ["\\\\server\\share", "\\", "foo.txt"],
834 has_root: true,
835 is_absolute: true,
836 parent: Some("\\\\server\\share\\"),
837 file_name: Some("foo.txt"),
838 file_stem: Some("foo"),
94222f64
XL
839 extension: Some("txt"),
840 file_prefix: Some("foo")
1b1a35ee
XL
841 );
842
843 t!("\\\\server\\share",
844 iter: ["\\\\server\\share", "\\"],
845 has_root: true,
846 is_absolute: true,
847 parent: None,
848 file_name: None,
849 file_stem: None,
94222f64
XL
850 extension: None,
851 file_prefix: None
1b1a35ee
XL
852 );
853
854 t!("\\\\server",
855 iter: ["\\", "server"],
856 has_root: true,
857 is_absolute: false,
858 parent: Some("\\"),
859 file_name: Some("server"),
860 file_stem: Some("server"),
94222f64
XL
861 extension: None,
862 file_prefix: Some("server")
1b1a35ee
XL
863 );
864
865 t!("\\\\?\\bar\\foo.txt",
866 iter: ["\\\\?\\bar", "\\", "foo.txt"],
867 has_root: true,
868 is_absolute: true,
869 parent: Some("\\\\?\\bar\\"),
870 file_name: Some("foo.txt"),
871 file_stem: Some("foo"),
94222f64
XL
872 extension: Some("txt"),
873 file_prefix: Some("foo")
1b1a35ee
XL
874 );
875
876 t!("\\\\?\\bar",
877 iter: ["\\\\?\\bar"],
878 has_root: true,
879 is_absolute: true,
880 parent: None,
881 file_name: None,
882 file_stem: None,
94222f64
XL
883 extension: None,
884 file_prefix: None
1b1a35ee
XL
885 );
886
887 t!("\\\\?\\",
888 iter: ["\\\\?\\"],
889 has_root: true,
890 is_absolute: true,
891 parent: None,
892 file_name: None,
893 file_stem: None,
94222f64
XL
894 extension: None,
895 file_prefix: None
1b1a35ee
XL
896 );
897
898 t!("\\\\?\\UNC\\server\\share\\foo.txt",
899 iter: ["\\\\?\\UNC\\server\\share", "\\", "foo.txt"],
900 has_root: true,
901 is_absolute: true,
902 parent: Some("\\\\?\\UNC\\server\\share\\"),
903 file_name: Some("foo.txt"),
904 file_stem: Some("foo"),
94222f64
XL
905 extension: Some("txt"),
906 file_prefix: Some("foo")
1b1a35ee
XL
907 );
908
909 t!("\\\\?\\UNC\\server",
910 iter: ["\\\\?\\UNC\\server"],
911 has_root: true,
912 is_absolute: true,
913 parent: None,
914 file_name: None,
915 file_stem: None,
94222f64
XL
916 extension: None,
917 file_prefix: None
1b1a35ee
XL
918 );
919
920 t!("\\\\?\\UNC\\",
921 iter: ["\\\\?\\UNC\\"],
922 has_root: true,
923 is_absolute: true,
924 parent: None,
925 file_name: None,
926 file_stem: None,
94222f64
XL
927 extension: None,
928 file_prefix: None
1b1a35ee
XL
929 );
930
931 t!("\\\\?\\C:\\foo.txt",
932 iter: ["\\\\?\\C:", "\\", "foo.txt"],
933 has_root: true,
934 is_absolute: true,
935 parent: Some("\\\\?\\C:\\"),
936 file_name: Some("foo.txt"),
937 file_stem: Some("foo"),
94222f64
XL
938 extension: Some("txt"),
939 file_prefix: Some("foo")
1b1a35ee
XL
940 );
941
942 t!("\\\\?\\C:\\",
943 iter: ["\\\\?\\C:", "\\"],
944 has_root: true,
945 is_absolute: true,
946 parent: None,
947 file_name: None,
948 file_stem: None,
94222f64
XL
949 extension: None,
950 file_prefix: None
1b1a35ee
XL
951 );
952
953 t!("\\\\?\\C:",
954 iter: ["\\\\?\\C:"],
955 has_root: true,
956 is_absolute: true,
957 parent: None,
958 file_name: None,
959 file_stem: None,
94222f64
XL
960 extension: None,
961 file_prefix: None
1b1a35ee
XL
962 );
963
964 t!("\\\\?\\foo/bar",
965 iter: ["\\\\?\\foo/bar"],
966 has_root: true,
967 is_absolute: true,
968 parent: None,
969 file_name: None,
970 file_stem: None,
94222f64
XL
971 extension: None,
972 file_prefix: None
1b1a35ee
XL
973 );
974
04454e1e
FG
975 t!("\\\\?\\C:/foo/bar",
976 iter: ["\\\\?\\C:", "\\", "foo/bar"],
1b1a35ee
XL
977 has_root: true,
978 is_absolute: true,
04454e1e
FG
979 parent: Some("\\\\?\\C:/"),
980 file_name: Some("foo/bar"),
981 file_stem: Some("foo/bar"),
94222f64 982 extension: None,
04454e1e 983 file_prefix: Some("foo/bar")
1b1a35ee
XL
984 );
985
986 t!("\\\\.\\foo\\bar",
987 iter: ["\\\\.\\foo", "\\", "bar"],
988 has_root: true,
989 is_absolute: true,
990 parent: Some("\\\\.\\foo\\"),
991 file_name: Some("bar"),
992 file_stem: Some("bar"),
94222f64
XL
993 extension: None,
994 file_prefix: Some("bar")
1b1a35ee
XL
995 );
996
997 t!("\\\\.\\foo",
998 iter: ["\\\\.\\foo", "\\"],
999 has_root: true,
1000 is_absolute: true,
1001 parent: None,
1002 file_name: None,
1003 file_stem: None,
94222f64
XL
1004 extension: None,
1005 file_prefix: None
1b1a35ee
XL
1006 );
1007
1008 t!("\\\\.\\foo/bar",
fc512014 1009 iter: ["\\\\.\\foo", "\\", "bar"],
1b1a35ee
XL
1010 has_root: true,
1011 is_absolute: true,
fc512014
XL
1012 parent: Some("\\\\.\\foo/"),
1013 file_name: Some("bar"),
1014 file_stem: Some("bar"),
94222f64
XL
1015 extension: None,
1016 file_prefix: Some("bar")
1b1a35ee
XL
1017 );
1018
1019 t!("\\\\.\\foo\\bar/baz",
1020 iter: ["\\\\.\\foo", "\\", "bar", "baz"],
1021 has_root: true,
1022 is_absolute: true,
1023 parent: Some("\\\\.\\foo\\bar"),
1024 file_name: Some("baz"),
1025 file_stem: Some("baz"),
94222f64
XL
1026 extension: None,
1027 file_prefix: Some("baz")
1b1a35ee
XL
1028 );
1029
1030 t!("\\\\.\\",
1031 iter: ["\\\\.\\", "\\"],
1032 has_root: true,
1033 is_absolute: true,
1034 parent: None,
1035 file_name: None,
1036 file_stem: None,
94222f64
XL
1037 extension: None,
1038 file_prefix: None
1b1a35ee
XL
1039 );
1040
1041 t!("\\\\?\\a\\b\\",
1042 iter: ["\\\\?\\a", "\\", "b"],
1043 has_root: true,
1044 is_absolute: true,
1045 parent: Some("\\\\?\\a\\"),
1046 file_name: Some("b"),
1047 file_stem: Some("b"),
94222f64
XL
1048 extension: None,
1049 file_prefix: Some("b")
1050 );
1051
1052 t!("\\\\?\\C:\\foo.txt.zip",
1053 iter: ["\\\\?\\C:", "\\", "foo.txt.zip"],
1054 has_root: true,
1055 is_absolute: true,
1056 parent: Some("\\\\?\\C:\\"),
1057 file_name: Some("foo.txt.zip"),
1058 file_stem: Some("foo.txt"),
1059 extension: Some("zip"),
1060 file_prefix: Some("foo")
1061 );
1062
1063 t!("\\\\?\\C:\\.foo.txt.zip",
1064 iter: ["\\\\?\\C:", "\\", ".foo.txt.zip"],
1065 has_root: true,
1066 is_absolute: true,
1067 parent: Some("\\\\?\\C:\\"),
1068 file_name: Some(".foo.txt.zip"),
1069 file_stem: Some(".foo.txt"),
1070 extension: Some("zip"),
1071 file_prefix: Some(".foo")
1072 );
1073
1074 t!("\\\\?\\C:\\.foo",
1075 iter: ["\\\\?\\C:", "\\", ".foo"],
1076 has_root: true,
1077 is_absolute: true,
1078 parent: Some("\\\\?\\C:\\"),
1079 file_name: Some(".foo"),
1080 file_stem: Some(".foo"),
1081 extension: None,
1082 file_prefix: Some(".foo")
1083 );
1084
1085 t!("a/.x.y.z",
1086 iter: ["a", ".x.y.z"],
1087 has_root: false,
1088 is_absolute: false,
1089 parent: Some("a"),
1090 file_name: Some(".x.y.z"),
1091 file_stem: Some(".x.y"),
1092 extension: Some("z"),
1093 file_prefix: Some(".x")
1b1a35ee
XL
1094 );
1095}
1096
1097#[test]
1098pub fn test_stem_ext() {
1099 t!("foo",
1100 file_stem: Some("foo"),
1101 extension: None
1102 );
1103
1104 t!("foo.",
1105 file_stem: Some("foo"),
1106 extension: Some("")
1107 );
1108
1109 t!(".foo",
1110 file_stem: Some(".foo"),
1111 extension: None
1112 );
1113
1114 t!("foo.txt",
1115 file_stem: Some("foo"),
1116 extension: Some("txt")
1117 );
1118
1119 t!("foo.bar.txt",
1120 file_stem: Some("foo.bar"),
1121 extension: Some("txt")
1122 );
1123
1124 t!("foo.bar.",
1125 file_stem: Some("foo.bar"),
1126 extension: Some("")
1127 );
1128
1129 t!(".", file_stem: None, extension: None);
1130
1131 t!("..", file_stem: None, extension: None);
1132
94222f64
XL
1133 t!(".x.y.z", file_stem: Some(".x.y"), extension: Some("z"));
1134
1135 t!("..x.y.z", file_stem: Some("..x.y"), extension: Some("z"));
1136
1b1a35ee
XL
1137 t!("", file_stem: None, extension: None);
1138}
1139
94222f64
XL
1140#[test]
1141pub fn test_prefix_ext() {
1142 t!("foo",
1143 file_prefix: Some("foo"),
1144 extension: None
1145 );
1146
1147 t!("foo.",
1148 file_prefix: Some("foo"),
1149 extension: Some("")
1150 );
1151
1152 t!(".foo",
1153 file_prefix: Some(".foo"),
1154 extension: None
1155 );
1156
1157 t!("foo.txt",
1158 file_prefix: Some("foo"),
1159 extension: Some("txt")
1160 );
1161
1162 t!("foo.bar.txt",
1163 file_prefix: Some("foo"),
1164 extension: Some("txt")
1165 );
1166
1167 t!("foo.bar.",
1168 file_prefix: Some("foo"),
1169 extension: Some("")
1170 );
1171
1172 t!(".", file_prefix: None, extension: None);
1173
1174 t!("..", file_prefix: None, extension: None);
1175
1176 t!(".x.y.z", file_prefix: Some(".x"), extension: Some("z"));
1177
1178 t!("..x.y.z", file_prefix: Some("."), extension: Some("z"));
1179
1180 t!("", file_prefix: None, extension: None);
1181}
1182
1b1a35ee
XL
1183#[test]
1184pub fn test_push() {
94222f64 1185 macro_rules! tp (
1b1a35ee
XL
1186 ($path:expr, $push:expr, $expected:expr) => ( {
1187 let mut actual = PathBuf::from($path);
1188 actual.push($push);
1189 assert!(actual.to_str() == Some($expected),
1190 "pushing {:?} onto {:?}: Expected {:?}, got {:?}",
1191 $push, $path, $expected, actual.to_str().unwrap());
1192 });
1193 );
1194
1195 if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) {
1196 tp!("", "foo", "foo");
1197 tp!("foo", "bar", "foo/bar");
1198 tp!("foo/", "bar", "foo/bar");
1199 tp!("foo//", "bar", "foo//bar");
1200 tp!("foo/.", "bar", "foo/./bar");
1201 tp!("foo./.", "bar", "foo././bar");
1202 tp!("foo", "", "foo/");
1203 tp!("foo", ".", "foo/.");
1204 tp!("foo", "..", "foo/..");
1205 tp!("foo", "/", "/");
1206 tp!("/foo/bar", "/", "/");
1207 tp!("/foo/bar", "/baz", "/baz");
1208 tp!("/foo/bar", "./baz", "/foo/bar/./baz");
1209 } else {
1210 tp!("", "foo", "foo");
1211 tp!("foo", "bar", r"foo\bar");
1212 tp!("foo/", "bar", r"foo/bar");
1213 tp!(r"foo\", "bar", r"foo\bar");
1214 tp!("foo//", "bar", r"foo//bar");
1215 tp!(r"foo\\", "bar", r"foo\\bar");
1216 tp!("foo/.", "bar", r"foo/.\bar");
1217 tp!("foo./.", "bar", r"foo./.\bar");
1218 tp!(r"foo\.", "bar", r"foo\.\bar");
1219 tp!(r"foo.\.", "bar", r"foo.\.\bar");
1220 tp!("foo", "", "foo\\");
1221 tp!("foo", ".", r"foo\.");
1222 tp!("foo", "..", r"foo\..");
1223 tp!("foo", "/", "/");
1224 tp!("foo", r"\", r"\");
1225 tp!("/foo/bar", "/", "/");
1226 tp!(r"\foo\bar", r"\", r"\");
1227 tp!("/foo/bar", "/baz", "/baz");
1228 tp!("/foo/bar", r"\baz", r"\baz");
1229 tp!("/foo/bar", "./baz", r"/foo/bar\./baz");
1230 tp!("/foo/bar", r".\baz", r"/foo/bar\.\baz");
1231
1232 tp!("c:\\", "windows", "c:\\windows");
1233 tp!("c:", "windows", "c:windows");
1234
1235 tp!("a\\b\\c", "d", "a\\b\\c\\d");
1236 tp!("\\a\\b\\c", "d", "\\a\\b\\c\\d");
1237 tp!("a\\b", "c\\d", "a\\b\\c\\d");
1238 tp!("a\\b", "\\c\\d", "\\c\\d");
1239 tp!("a\\b", ".", "a\\b\\.");
1240 tp!("a\\b", "..\\c", "a\\b\\..\\c");
1241 tp!("a\\b", "C:a.txt", "C:a.txt");
1242 tp!("a\\b", "C:\\a.txt", "C:\\a.txt");
1243 tp!("C:\\a", "C:\\b.txt", "C:\\b.txt");
1244 tp!("C:\\a\\b\\c", "C:d", "C:d");
1245 tp!("C:a\\b\\c", "C:d", "C:d");
1246 tp!("C:", r"a\b\c", r"C:a\b\c");
1247 tp!("C:", r"..\a", r"C:..\a");
1248 tp!("\\\\server\\share\\foo", "bar", "\\\\server\\share\\foo\\bar");
1249 tp!("\\\\server\\share\\foo", "C:baz", "C:baz");
1250 tp!("\\\\?\\C:\\a\\b", "C:c\\d", "C:c\\d");
1251 tp!("\\\\?\\C:a\\b", "C:c\\d", "C:c\\d");
1252 tp!("\\\\?\\C:\\a\\b", "C:\\c\\d", "C:\\c\\d");
1253 tp!("\\\\?\\foo\\bar", "baz", "\\\\?\\foo\\bar\\baz");
1254 tp!("\\\\?\\UNC\\server\\share\\foo", "bar", "\\\\?\\UNC\\server\\share\\foo\\bar");
1255 tp!("\\\\?\\UNC\\server\\share", "C:\\a", "C:\\a");
1256 tp!("\\\\?\\UNC\\server\\share", "C:a", "C:a");
1257
1258 // Note: modified from old path API
1259 tp!("\\\\?\\UNC\\server", "foo", "\\\\?\\UNC\\server\\foo");
1260
1261 tp!("C:\\a", "\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share");
1262 tp!("\\\\.\\foo\\bar", "baz", "\\\\.\\foo\\bar\\baz");
1263 tp!("\\\\.\\foo\\bar", "C:a", "C:a");
1264 // again, not sure about the following, but I'm assuming \\.\ should be verbatim
1265 tp!("\\\\.\\foo", "..\\bar", "\\\\.\\foo\\..\\bar");
1266
1267 tp!("\\\\?\\C:", "foo", "\\\\?\\C:\\foo"); // this is a weird one
c295e0f8
XL
1268
1269 tp!(r"\\?\C:\bar", "../foo", r"\\?\C:\foo");
1270 tp!(r"\\?\C:\bar", "../../foo", r"\\?\C:\foo");
1271 tp!(r"\\?\C:\", "../foo", r"\\?\C:\foo");
1272 tp!(r"\\?\C:", r"D:\foo/./", r"D:\foo/./");
1273 tp!(r"\\?\C:", r"\\?\D:\foo\.\", r"\\?\D:\foo\.\");
1274 tp!(r"\\?\A:\x\y", "/foo", r"\\?\A:\foo");
1275 tp!(r"\\?\A:", r"..\foo\.", r"\\?\A:\foo");
1276 tp!(r"\\?\A:\x\y", r".\foo\.", r"\\?\A:\x\y\foo");
1277 tp!(r"\\?\A:\x\y", r"", r"\\?\A:\x\y\");
1b1a35ee
XL
1278 }
1279}
1280
1281#[test]
1282pub fn test_pop() {
94222f64 1283 macro_rules! tp (
1b1a35ee
XL
1284 ($path:expr, $expected:expr, $output:expr) => ( {
1285 let mut actual = PathBuf::from($path);
1286 let output = actual.pop();
1287 assert!(actual.to_str() == Some($expected) && output == $output,
1288 "popping from {:?}: Expected {:?}/{:?}, got {:?}/{:?}",
1289 $path, $expected, $output,
1290 actual.to_str().unwrap(), output);
1291 });
1292 );
1293
1294 tp!("", "", false);
1295 tp!("/", "/", false);
1296 tp!("foo", "", true);
1297 tp!(".", "", true);
1298 tp!("/foo", "/", true);
1299 tp!("/foo/bar", "/foo", true);
1300 tp!("foo/bar", "foo", true);
1301 tp!("foo/.", "", true);
1302 tp!("foo//bar", "foo", true);
1303
1304 if cfg!(windows) {
1305 tp!("a\\b\\c", "a\\b", true);
1306 tp!("\\a", "\\", true);
1307 tp!("\\", "\\", false);
1308
1309 tp!("C:\\a\\b", "C:\\a", true);
1310 tp!("C:\\a", "C:\\", true);
1311 tp!("C:\\", "C:\\", false);
1312 tp!("C:a\\b", "C:a", true);
1313 tp!("C:a", "C:", true);
1314 tp!("C:", "C:", false);
1315 tp!("\\\\server\\share\\a\\b", "\\\\server\\share\\a", true);
1316 tp!("\\\\server\\share\\a", "\\\\server\\share\\", true);
1317 tp!("\\\\server\\share", "\\\\server\\share", false);
1318 tp!("\\\\?\\a\\b\\c", "\\\\?\\a\\b", true);
1319 tp!("\\\\?\\a\\b", "\\\\?\\a\\", true);
1320 tp!("\\\\?\\a", "\\\\?\\a", false);
1321 tp!("\\\\?\\C:\\a\\b", "\\\\?\\C:\\a", true);
1322 tp!("\\\\?\\C:\\a", "\\\\?\\C:\\", true);
1323 tp!("\\\\?\\C:\\", "\\\\?\\C:\\", false);
1324 tp!("\\\\?\\UNC\\server\\share\\a\\b", "\\\\?\\UNC\\server\\share\\a", true);
1325 tp!("\\\\?\\UNC\\server\\share\\a", "\\\\?\\UNC\\server\\share\\", true);
1326 tp!("\\\\?\\UNC\\server\\share", "\\\\?\\UNC\\server\\share", false);
1327 tp!("\\\\.\\a\\b\\c", "\\\\.\\a\\b", true);
1328 tp!("\\\\.\\a\\b", "\\\\.\\a\\", true);
1329 tp!("\\\\.\\a", "\\\\.\\a", false);
1330
1331 tp!("\\\\?\\a\\b\\", "\\\\?\\a\\", true);
1332 }
1333}
1334
1335#[test]
1336pub fn test_set_file_name() {
94222f64 1337 macro_rules! tfn (
1b1a35ee
XL
1338 ($path:expr, $file:expr, $expected:expr) => ( {
1339 let mut p = PathBuf::from($path);
1340 p.set_file_name($file);
1341 assert!(p.to_str() == Some($expected),
1342 "setting file name of {:?} to {:?}: Expected {:?}, got {:?}",
1343 $path, $file, $expected,
1344 p.to_str().unwrap());
1345 });
1346 );
1347
1348 tfn!("foo", "foo", "foo");
1349 tfn!("foo", "bar", "bar");
1350 tfn!("foo", "", "");
1351 tfn!("", "foo", "foo");
1352 if cfg!(unix) || cfg!(all(target_env = "sgx", target_vendor = "fortanix")) {
1353 tfn!(".", "foo", "./foo");
1354 tfn!("foo/", "bar", "bar");
1355 tfn!("foo/.", "bar", "bar");
1356 tfn!("..", "foo", "../foo");
1357 tfn!("foo/..", "bar", "foo/../bar");
1358 tfn!("/", "foo", "/foo");
1359 } else {
1360 tfn!(".", "foo", r".\foo");
1361 tfn!(r"foo\", "bar", r"bar");
1362 tfn!(r"foo\.", "bar", r"bar");
1363 tfn!("..", "foo", r"..\foo");
1364 tfn!(r"foo\..", "bar", r"foo\..\bar");
1365 tfn!(r"\", "foo", r"\foo");
1366 }
1367}
1368
1369#[test]
1370pub fn test_set_extension() {
94222f64 1371 macro_rules! tfe (
1b1a35ee
XL
1372 ($path:expr, $ext:expr, $expected:expr, $output:expr) => ( {
1373 let mut p = PathBuf::from($path);
1374 let output = p.set_extension($ext);
1375 assert!(p.to_str() == Some($expected) && output == $output,
1376 "setting extension of {:?} to {:?}: Expected {:?}/{:?}, got {:?}/{:?}",
1377 $path, $ext, $expected, $output,
1378 p.to_str().unwrap(), output);
1379 });
1380 );
1381
1382 tfe!("foo", "txt", "foo.txt", true);
1383 tfe!("foo.bar", "txt", "foo.txt", true);
1384 tfe!("foo.bar.baz", "txt", "foo.bar.txt", true);
1385 tfe!(".test", "txt", ".test.txt", true);
1386 tfe!("foo.txt", "", "foo", true);
1387 tfe!("foo", "", "foo", true);
1388 tfe!("", "foo", "", false);
1389 tfe!(".", "foo", ".", false);
1390 tfe!("foo/", "bar", "foo.bar", true);
1391 tfe!("foo/.", "bar", "foo.bar", true);
1392 tfe!("..", "foo", "..", false);
1393 tfe!("foo/..", "bar", "foo/..", false);
1394 tfe!("/", "foo", "/", false);
1395}
1396
1397#[test]
1398fn test_eq_receivers() {
1399 use crate::borrow::Cow;
1400
1401 let borrowed: &Path = Path::new("foo/bar");
1402 let mut owned: PathBuf = PathBuf::new();
1403 owned.push("foo");
1404 owned.push("bar");
1405 let borrowed_cow: Cow<'_, Path> = borrowed.into();
1406 let owned_cow: Cow<'_, Path> = owned.clone().into();
1407
1408 macro_rules! t {
1409 ($($current:expr),+) => {
1410 $(
1411 assert_eq!($current, borrowed);
1412 assert_eq!($current, owned);
1413 assert_eq!($current, borrowed_cow);
1414 assert_eq!($current, owned_cow);
1415 )+
1416 }
1417 }
1418
1419 t!(borrowed, owned, borrowed_cow, owned_cow);
1420}
1421
1422#[test]
1423pub fn test_compare() {
1424 use crate::collections::hash_map::DefaultHasher;
1425 use crate::hash::{Hash, Hasher};
1426
1427 fn hash<T: Hash>(t: T) -> u64 {
1428 let mut s = DefaultHasher::new();
1429 t.hash(&mut s);
1430 s.finish()
1431 }
1432
94222f64 1433 macro_rules! tc (
1b1a35ee
XL
1434 ($path1:expr, $path2:expr, eq: $eq:expr,
1435 starts_with: $starts_with:expr, ends_with: $ends_with:expr,
1436 relative_from: $relative_from:expr) => ({
1437 let path1 = Path::new($path1);
1438 let path2 = Path::new($path2);
1439
1440 let eq = path1 == path2;
1441 assert!(eq == $eq, "{:?} == {:?}, expected {:?}, got {:?}",
1442 $path1, $path2, $eq, eq);
1443 assert!($eq == (hash(path1) == hash(path2)),
1444 "{:?} == {:?}, expected {:?}, got {} and {}",
1445 $path1, $path2, $eq, hash(path1), hash(path2));
1446
1447 let starts_with = path1.starts_with(path2);
1448 assert!(starts_with == $starts_with,
1449 "{:?}.starts_with({:?}), expected {:?}, got {:?}", $path1, $path2,
1450 $starts_with, starts_with);
1451
1452 let ends_with = path1.ends_with(path2);
1453 assert!(ends_with == $ends_with,
1454 "{:?}.ends_with({:?}), expected {:?}, got {:?}", $path1, $path2,
1455 $ends_with, ends_with);
1456
1457 let relative_from = path1.strip_prefix(path2)
1458 .map(|p| p.to_str().unwrap())
1459 .ok();
1460 let exp: Option<&str> = $relative_from;
1461 assert!(relative_from == exp,
1462 "{:?}.strip_prefix({:?}), expected {:?}, got {:?}",
1463 $path1, $path2, exp, relative_from);
1464 });
1465 );
1466
1467 tc!("", "",
1468 eq: true,
1469 starts_with: true,
1470 ends_with: true,
1471 relative_from: Some("")
1472 );
1473
1474 tc!("foo", "",
1475 eq: false,
1476 starts_with: true,
1477 ends_with: true,
1478 relative_from: Some("foo")
1479 );
1480
1481 tc!("", "foo",
1482 eq: false,
1483 starts_with: false,
1484 ends_with: false,
1485 relative_from: None
1486 );
1487
1488 tc!("foo", "foo",
1489 eq: true,
1490 starts_with: true,
1491 ends_with: true,
1492 relative_from: Some("")
1493 );
1494
1495 tc!("foo/", "foo",
1496 eq: true,
1497 starts_with: true,
1498 ends_with: true,
1499 relative_from: Some("")
1500 );
1501
a2a8927a
XL
1502 tc!("foo/.", "foo",
1503 eq: true,
1504 starts_with: true,
1505 ends_with: true,
1506 relative_from: Some("")
1507 );
1508
1509 tc!("foo/./bar", "foo/bar",
1510 eq: true,
1511 starts_with: true,
1512 ends_with: true,
1513 relative_from: Some("")
1514 );
1515
1b1a35ee
XL
1516 tc!("foo/bar", "foo",
1517 eq: false,
1518 starts_with: true,
1519 ends_with: false,
1520 relative_from: Some("bar")
1521 );
1522
1523 tc!("foo/bar/baz", "foo/bar",
1524 eq: false,
1525 starts_with: true,
1526 ends_with: false,
1527 relative_from: Some("baz")
1528 );
1529
1530 tc!("foo/bar", "foo/bar/baz",
1531 eq: false,
1532 starts_with: false,
1533 ends_with: false,
1534 relative_from: None
1535 );
1536
1537 tc!("./foo/bar/", ".",
1538 eq: false,
1539 starts_with: true,
1540 ends_with: false,
1541 relative_from: Some("foo/bar")
1542 );
1543
1544 if cfg!(windows) {
1545 tc!(r"C:\src\rust\cargo-test\test\Cargo.toml",
1546 r"c:\src\rust\cargo-test\test",
1547 eq: false,
1548 starts_with: true,
1549 ends_with: false,
1550 relative_from: Some("Cargo.toml")
1551 );
1552
1553 tc!(r"c:\foo", r"C:\foo",
1554 eq: true,
1555 starts_with: true,
1556 ends_with: true,
1557 relative_from: Some("")
1558 );
a2a8927a
XL
1559
1560 tc!(r"C:\foo\.\bar.txt", r"C:\foo\bar.txt",
1561 eq: true,
1562 starts_with: true,
1563 ends_with: true,
1564 relative_from: Some("")
1565 );
1566
1567 tc!(r"C:\foo\.", r"C:\foo",
1568 eq: true,
1569 starts_with: true,
1570 ends_with: true,
1571 relative_from: Some("")
1572 );
1573
1574 tc!(r"\\?\C:\foo\.\bar.txt", r"\\?\C:\foo\bar.txt",
1575 eq: false,
1576 starts_with: false,
1577 ends_with: false,
1578 relative_from: None
1579 );
1b1a35ee
XL
1580 }
1581}
1582
1583#[test]
1584fn test_components_debug() {
1585 let path = Path::new("/tmp");
1586
1587 let mut components = path.components();
1588
1589 let expected = "Components([RootDir, Normal(\"tmp\")])";
5e7ed085 1590 let actual = format!("{components:?}");
1b1a35ee
XL
1591 assert_eq!(expected, actual);
1592
1593 let _ = components.next().unwrap();
1594 let expected = "Components([Normal(\"tmp\")])";
5e7ed085 1595 let actual = format!("{components:?}");
1b1a35ee
XL
1596 assert_eq!(expected, actual);
1597
1598 let _ = components.next().unwrap();
1599 let expected = "Components([])";
5e7ed085 1600 let actual = format!("{components:?}");
1b1a35ee
XL
1601 assert_eq!(expected, actual);
1602}
1603
1604#[cfg(unix)]
1605#[test]
1606fn test_iter_debug() {
1607 let path = Path::new("/tmp");
1608
1609 let mut iter = path.iter();
1610
1611 let expected = "Iter([\"/\", \"tmp\"])";
5e7ed085 1612 let actual = format!("{iter:?}");
1b1a35ee
XL
1613 assert_eq!(expected, actual);
1614
1615 let _ = iter.next().unwrap();
1616 let expected = "Iter([\"tmp\"])";
5e7ed085 1617 let actual = format!("{iter:?}");
1b1a35ee
XL
1618 assert_eq!(expected, actual);
1619
1620 let _ = iter.next().unwrap();
1621 let expected = "Iter([])";
5e7ed085 1622 let actual = format!("{iter:?}");
1b1a35ee
XL
1623 assert_eq!(expected, actual);
1624}
1625
1626#[test]
1627fn into_boxed() {
1628 let orig: &str = "some/sort/of/path";
1629 let path = Path::new(orig);
1630 let boxed: Box<Path> = Box::from(path);
1631 let path_buf = path.to_owned().into_boxed_path().into_path_buf();
1632 assert_eq!(path, &*boxed);
1633 assert_eq!(&*boxed, &*path_buf);
1634 assert_eq!(&*path_buf, path);
1635}
1636
1637#[test]
1638fn test_clone_into() {
1639 let mut path_buf = PathBuf::from("supercalifragilisticexpialidocious");
1640 let path = Path::new("short");
1641 path.clone_into(&mut path_buf);
1642 assert_eq!(path, path_buf);
1643 assert!(path_buf.into_os_string().capacity() >= 15);
1644}
1645
1646#[test]
1647fn display_format_flags() {
1648 assert_eq!(format!("a{:#<5}b", Path::new("").display()), "a#####b");
1649 assert_eq!(format!("a{:#<5}b", Path::new("a").display()), "aa####b");
1650}
1651
1652#[test]
1653fn into_rc() {
1654 let orig = "hello/world";
1655 let path = Path::new(orig);
1656 let rc: Rc<Path> = Rc::from(path);
1657 let arc: Arc<Path> = Arc::from(path);
1658
1659 assert_eq!(&*rc, path);
1660 assert_eq!(&*arc, path);
1661
1662 let rc2: Rc<Path> = Rc::from(path.to_owned());
1663 let arc2: Arc<Path> = Arc::from(path.to_owned());
1664
1665 assert_eq!(&*rc2, path);
1666 assert_eq!(&*arc2, path);
1667}
94222f64
XL
1668
1669#[test]
1670fn test_ord() {
1671 macro_rules! ord(
1672 ($ord:ident, $left:expr, $right:expr) => ( {
3c0e092e
XL
1673 use core::cmp::Ordering;
1674
1675 let left = Path::new($left);
1676 let right = Path::new($right);
1677 assert_eq!(left.cmp(&right), Ordering::$ord);
1678 if (core::cmp::Ordering::$ord == Ordering::Equal) {
1679 assert_eq!(left, right);
1680
1681 let mut hasher = DefaultHasher::new();
1682 left.hash(&mut hasher);
1683 let left_hash = hasher.finish();
1684 hasher = DefaultHasher::new();
1685 right.hash(&mut hasher);
1686 let right_hash = hasher.finish();
1687
1688 assert_eq!(left_hash, right_hash, "hashes for {:?} and {:?} must match", left, right);
1689 } else {
1690 assert_ne!(left, right);
1691 }
94222f64
XL
1692 });
1693 );
1694
1695 ord!(Less, "1", "2");
1696 ord!(Less, "/foo/bar", "/foo./bar");
1697 ord!(Less, "foo/bar", "foo/bar.");
1698 ord!(Equal, "foo/./bar", "foo/bar/");
1699 ord!(Equal, "foo/bar", "foo/bar/");
1700 ord!(Equal, "foo/bar", "foo/bar/.");
1701 ord!(Equal, "foo/bar", "foo/bar//");
1702}
1703
5099ac24
FG
1704#[test]
1705#[cfg(unix)]
1706fn test_unix_absolute() {
1707 use crate::path::absolute;
1708
1709 assert!(absolute("").is_err());
1710
1711 let relative = "a/b";
1712 let mut expected = crate::env::current_dir().unwrap();
1713 expected.push(relative);
5e7ed085 1714 assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
5099ac24
FG
1715
1716 // Test how components are collected.
5e7ed085
FG
1717 assert_eq!(absolute("/a/b/c").unwrap().as_os_str(), Path::new("/a/b/c").as_os_str());
1718 assert_eq!(absolute("/a//b/c").unwrap().as_os_str(), Path::new("/a/b/c").as_os_str());
1719 assert_eq!(absolute("//a/b/c").unwrap().as_os_str(), Path::new("//a/b/c").as_os_str());
1720 assert_eq!(absolute("///a/b/c").unwrap().as_os_str(), Path::new("/a/b/c").as_os_str());
1721 assert_eq!(absolute("/a/b/c/").unwrap().as_os_str(), Path::new("/a/b/c/").as_os_str());
1722 assert_eq!(
1723 absolute("/a/./b/../c/.././..").unwrap().as_os_str(),
1724 Path::new("/a/b/../c/../..").as_os_str()
1725 );
1726
1727 // Test leading `.` and `..` components
1728 let curdir = crate::env::current_dir().unwrap();
1729 assert_eq!(absolute("./a").unwrap().as_os_str(), curdir.join("a").as_os_str());
1730 assert_eq!(absolute("../a").unwrap().as_os_str(), curdir.join("../a").as_os_str()); // return /pwd/../a
5099ac24
FG
1731}
1732
1733#[test]
1734#[cfg(windows)]
1735fn test_windows_absolute() {
1736 use crate::path::absolute;
1737 // An empty path is an error.
1738 assert!(absolute("").is_err());
1739
1740 let relative = r"a\b";
1741 let mut expected = crate::env::current_dir().unwrap();
1742 expected.push(relative);
5e7ed085 1743 assert_eq!(absolute(relative).unwrap().as_os_str(), expected.as_os_str());
5099ac24
FG
1744
1745 macro_rules! unchanged(
1746 ($path:expr) => {
5e7ed085 1747 assert_eq!(absolute($path).unwrap().as_os_str(), Path::new($path).as_os_str());
5099ac24
FG
1748 }
1749 );
1750
1751 unchanged!(r"C:\path\to\file");
1752 unchanged!(r"C:\path\to\file\");
1753 unchanged!(r"\\server\share\to\file");
1754 unchanged!(r"\\server.\share.\to\file");
1755 unchanged!(r"\\.\PIPE\name");
1756 unchanged!(r"\\.\C:\path\to\COM1");
1757 unchanged!(r"\\?\C:\path\to\file");
1758 unchanged!(r"\\?\UNC\server\share\to\file");
1759 unchanged!(r"\\?\PIPE\name");
1760 // Verbatim paths are always unchanged, no matter what.
1761 unchanged!(r"\\?\path.\to/file..");
1762
5e7ed085
FG
1763 assert_eq!(
1764 absolute(r"C:\path..\to.\file.").unwrap().as_os_str(),
1765 Path::new(r"C:\path..\to\file").as_os_str()
1766 );
1767 assert_eq!(absolute(r"COM1").unwrap().as_os_str(), Path::new(r"\\.\COM1").as_os_str());
5099ac24
FG
1768}
1769
94222f64
XL
1770#[bench]
1771fn bench_path_cmp_fast_path_buf_sort(b: &mut test::Bencher) {
1772 let prefix = "my/home";
1773 let mut paths: Vec<_> =
5e7ed085 1774 (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
94222f64
XL
1775
1776 paths.sort();
1777
1778 b.iter(|| {
1779 black_box(paths.as_mut_slice()).sort_unstable();
1780 });
1781}
1782
1783#[bench]
1784fn bench_path_cmp_fast_path_long(b: &mut test::Bencher) {
1785 let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
1786 let paths: Vec<_> =
5e7ed085 1787 (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
94222f64
XL
1788
1789 let mut set = BTreeSet::new();
1790
1791 paths.iter().for_each(|p| {
1792 set.insert(p.as_path());
1793 });
1794
1795 b.iter(|| {
1796 set.remove(paths[500].as_path());
1797 set.insert(paths[500].as_path());
1798 });
1799}
1800
1801#[bench]
1802fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
1803 let prefix = "my/home";
1804 let paths: Vec<_> =
5e7ed085 1805 (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
94222f64
XL
1806
1807 let mut set = BTreeSet::new();
1808
1809 paths.iter().for_each(|p| {
1810 set.insert(p.as_path());
1811 });
1812
1813 b.iter(|| {
1814 set.remove(paths[500].as_path());
1815 set.insert(paths[500].as_path());
1816 });
1817}
3c0e092e
XL
1818
1819#[bench]
1820fn bench_path_hashset(b: &mut test::Bencher) {
1821 let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
1822 let paths: Vec<_> =
5e7ed085 1823 (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
3c0e092e
XL
1824
1825 let mut set = HashSet::new();
1826
1827 paths.iter().for_each(|p| {
1828 set.insert(p.as_path());
1829 });
1830
1831 b.iter(|| {
1832 set.remove(paths[500].as_path());
1833 set.insert(black_box(paths[500].as_path()))
1834 });
1835}
1836
1837#[bench]
1838fn bench_path_hashset_miss(b: &mut test::Bencher) {
1839 let prefix = "/my/home/is/my/castle/and/my/castle/has/a/rusty/workbench/";
1840 let paths: Vec<_> =
5e7ed085 1841 (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {num}.rs"))).collect();
3c0e092e
XL
1842
1843 let mut set = HashSet::new();
1844
1845 paths.iter().for_each(|p| {
1846 set.insert(p.as_path());
1847 });
1848
1849 let probe = PathBuf::from(prefix).join("other");
1850
1851 b.iter(|| set.remove(black_box(probe.as_path())));
1852}
1853
1854#[bench]
1855fn bench_hash_path_short(b: &mut test::Bencher) {
1856 let mut hasher = DefaultHasher::new();
1857 let path = Path::new("explorer.exe");
1858
1859 b.iter(|| black_box(path).hash(&mut hasher));
1860
1861 black_box(hasher.finish());
1862}
1863
1864#[bench]
1865fn bench_hash_path_long(b: &mut test::Bencher) {
1866 let mut hasher = DefaultHasher::new();
1867 let path =
1868 Path::new("/aaaaa/aaaaaa/./../aaaaaaaa/bbbbbbbbbbbbb/ccccccccccc/ddddddddd/eeeeeee.fff");
1869
1870 b.iter(|| black_box(path).hash(&mut hasher));
1871
1872 black_box(hasher.finish());
1873}