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