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