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