3 use crate::collections::BTreeSet;
6 use core::hint::black_box;
9 ($path:expr, iter: $iter:expr) => (
11 let path = Path::new($path);
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 {:?}",
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 {:?}",
32 ($path:expr, has_root: $has_root:expr, is_absolute: $is_absolute:expr) => (
34 let path = Path::new($path);
36 let act_root = path.has_root();
37 assert!(act_root == $has_root, "has_root: Expected {:?}, found {:?}",
40 let act_abs = path.is_absolute();
41 assert!(act_abs == $is_absolute, "is_absolute: Expected {:?}, found {:?}",
42 $is_absolute, act_abs);
46 ($path:expr, parent: $parent:expr, file_name: $file:expr) => (
48 let path = Path::new($path);
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 {:?}",
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 {:?}",
62 ($path:expr, file_stem: $file_stem:expr, extension: $extension:expr) => (
64 let path = Path::new($path);
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 {:?}",
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 {:?}",
78 ($path:expr, file_prefix: $file_prefix:expr, extension: $extension:expr) => (
80 let path = Path::new($path);
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 {:?}",
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 {:?}",
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) => (
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);
111 use crate::borrow::Cow;
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");
118 let path: &Path = &pathbuf;
119 let borrowed_cow_path: Cow<'_, Path> = path.into();
121 assert_eq!(static_cow_path, borrowed_cow_path);
124 let owned_cow_path: Cow<'static, Path> = pathbuf.into();
126 assert_eq!(static_cow_path, owned_cow_path);
131 pub fn test_decompositions_unix() {
148 file_name: Some("foo"),
149 file_stem: Some("foo"),
151 file_prefix: Some("foo")
170 file_name: Some("foo"),
171 file_stem: Some("foo"),
173 file_prefix: Some("foo")
181 file_name: Some("foo"),
182 file_stem: Some("foo"),
184 file_prefix: Some("foo")
192 file_name: Some("foo"),
193 file_stem: Some("foo"),
195 file_prefix: Some("foo")
199 iter: ["foo", "bar"],
203 file_name: Some("bar"),
204 file_stem: Some("bar"),
206 file_prefix: Some("bar")
210 iter: ["/", "foo", "bar"],
213 parent: Some("/foo"),
214 file_name: Some("bar"),
215 file_stem: Some("bar"),
217 file_prefix: Some("bar")
225 file_name: Some("foo"),
226 file_stem: Some("foo"),
228 file_prefix: Some("foo")
232 iter: ["/", "foo", "bar"],
235 parent: Some("///foo"),
236 file_name: Some("bar"),
237 file_stem: Some("bar"),
239 file_prefix: Some("bar")
280 file_name: Some("foo"),
281 file_stem: Some("foo"),
283 file_prefix: Some("foo")
302 file_name: Some("foo"),
303 file_stem: Some("foo"),
305 file_prefix: Some("foo")
309 iter: ["foo", "bar"],
313 file_name: Some("bar"),
314 file_stem: Some("bar"),
316 file_prefix: Some("bar")
331 iter: ["foo", "..", "bar"],
334 parent: Some("foo/.."),
335 file_name: Some("bar"),
336 file_stem: Some("bar"),
338 file_prefix: Some("bar")
346 file_name: Some("a"),
347 file_stem: Some("a"),
349 file_prefix: Some("a")
379 file_name: Some("b"),
380 file_stem: Some("b"),
382 file_prefix: Some("b")
390 file_name: Some("b"),
391 file_stem: Some("b"),
393 file_prefix: Some("b")
401 file_name: Some("b"),
402 file_stem: Some("b"),
404 file_prefix: Some("b")
408 iter: ["a", "b", "c"],
412 file_name: Some("c"),
413 file_stem: Some("c"),
415 file_prefix: Some("c")
423 file_name: Some(".foo"),
424 file_stem: Some(".foo"),
426 file_prefix: Some(".foo")
434 file_name: Some(".foo"),
435 file_stem: Some(".foo"),
437 file_prefix: Some(".foo")
440 t!("a/.rustfmt.toml",
441 iter: ["a", ".rustfmt.toml"],
445 file_name: Some(".rustfmt.toml"),
446 file_stem: Some(".rustfmt"),
447 extension: Some("toml"),
448 file_prefix: Some(".rustfmt")
452 iter: ["a", ".x.y.z"],
456 file_name: Some(".x.y.z"),
457 file_stem: Some(".x.y"),
458 extension: Some("z"),
459 file_prefix: Some(".x")
465 pub fn test_decompositions_windows() {
482 file_name: Some("foo"),
483 file_stem: Some("foo"),
485 file_prefix: Some("foo")
548 file_name: Some("foo"),
549 file_stem: Some("foo"),
551 file_prefix: Some("foo")
559 file_name: Some("foo"),
560 file_stem: Some("foo"),
562 file_prefix: Some("foo")
570 file_name: Some("foo"),
571 file_stem: Some("foo"),
573 file_prefix: Some("foo")
577 iter: ["foo", "bar"],
581 file_name: Some("bar"),
582 file_stem: Some("bar"),
584 file_prefix: Some("bar")
588 iter: ["\\", "foo", "bar"],
591 parent: Some("/foo"),
592 file_name: Some("bar"),
593 file_stem: Some("bar"),
595 file_prefix: Some("bar")
603 file_name: Some("foo"),
604 file_stem: Some("foo"),
606 file_prefix: Some("foo")
610 iter: ["\\", "foo", "bar"],
613 parent: Some("///foo"),
614 file_name: Some("bar"),
615 file_stem: Some("bar"),
617 file_prefix: Some("bar")
658 file_name: Some("foo"),
659 file_stem: Some("foo"),
661 file_prefix: Some("foo")
680 file_name: Some("foo"),
681 file_stem: Some("foo"),
683 file_prefix: Some("foo")
687 iter: ["foo", "bar"],
691 file_name: Some("bar"),
692 file_stem: Some("bar"),
694 file_prefix: Some("bar")
709 iter: ["foo", "..", "bar"],
712 parent: Some("foo/.."),
713 file_name: Some("bar"),
714 file_stem: Some("bar"),
716 file_prefix: Some("bar")
724 file_name: Some("a"),
725 file_stem: Some("a"),
727 file_prefix: Some("a")
757 file_name: Some("b"),
758 file_stem: Some("b"),
760 file_prefix: Some("b")
768 file_name: Some("b"),
769 file_stem: Some("b"),
771 file_prefix: Some("b")
779 file_name: Some("b"),
780 file_stem: Some("b"),
782 file_prefix: Some("b")
786 iter: ["a", "b", "c"],
790 file_name: Some("c"),
791 file_stem: Some("c"),
793 file_prefix: Some("c")
797 iter: ["a", "b", "c"],
800 parent: Some("a\\b"),
801 file_name: Some("c"),
802 file_stem: Some("c"),
804 file_prefix: Some("c")
812 file_name: Some("a"),
813 file_stem: Some("a"),
815 file_prefix: Some("a")
819 iter: ["c:", "\\", "foo.txt"],
822 parent: Some("c:\\"),
823 file_name: Some("foo.txt"),
824 file_stem: Some("foo"),
825 extension: Some("txt"),
826 file_prefix: Some("foo")
829 t!("\\\\server\\share\\foo.txt",
830 iter: ["\\\\server\\share", "\\", "foo.txt"],
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")
840 t!("\\\\server\\share",
841 iter: ["\\\\server\\share", "\\"],
852 iter: ["\\", "server"],
856 file_name: Some("server"),
857 file_stem: Some("server"),
859 file_prefix: Some("server")
862 t!("\\\\?\\bar\\foo.txt",
863 iter: ["\\\\?\\bar", "\\", "foo.txt"],
866 parent: Some("\\\\?\\bar\\"),
867 file_name: Some("foo.txt"),
868 file_stem: Some("foo"),
869 extension: Some("txt"),
870 file_prefix: Some("foo")
874 iter: ["\\\\?\\bar"],
895 t!("\\\\?\\UNC\\server\\share\\foo.txt",
896 iter: ["\\\\?\\UNC\\server\\share", "\\", "foo.txt"],
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")
906 t!("\\\\?\\UNC\\server",
907 iter: ["\\\\?\\UNC\\server"],
918 iter: ["\\\\?\\UNC\\"],
928 t!("\\\\?\\C:\\foo.txt",
929 iter: ["\\\\?\\C:", "\\", "foo.txt"],
932 parent: Some("\\\\?\\C:\\"),
933 file_name: Some("foo.txt"),
934 file_stem: Some("foo"),
935 extension: Some("txt"),
936 file_prefix: Some("foo")
940 iter: ["\\\\?\\C:", "\\"],
962 iter: ["\\\\?\\foo/bar"],
973 iter: ["\\\\?\\C:/foo"],
983 t!("\\\\.\\foo\\bar",
984 iter: ["\\\\.\\foo", "\\", "bar"],
987 parent: Some("\\\\.\\foo\\"),
988 file_name: Some("bar"),
989 file_stem: Some("bar"),
991 file_prefix: Some("bar")
995 iter: ["\\\\.\\foo", "\\"],
1005 t!("\\\\.\\foo/bar",
1006 iter: ["\\\\.\\foo", "\\", "bar"],
1009 parent: Some("\\\\.\\foo/"),
1010 file_name: Some("bar"),
1011 file_stem: Some("bar"),
1013 file_prefix: Some("bar")
1016 t!("\\\\.\\foo\\bar/baz",
1017 iter: ["\\\\.\\foo", "\\", "bar", "baz"],
1020 parent: Some("\\\\.\\foo\\bar"),
1021 file_name: Some("baz"),
1022 file_stem: Some("baz"),
1024 file_prefix: Some("baz")
1028 iter: ["\\\\.\\", "\\"],
1039 iter: ["\\\\?\\a", "\\", "b"],
1042 parent: Some("\\\\?\\a\\"),
1043 file_name: Some("b"),
1044 file_stem: Some("b"),
1046 file_prefix: Some("b")
1049 t!("\\\\?\\C:\\foo.txt.zip",
1050 iter: ["\\\\?\\C:", "\\", "foo.txt.zip"],
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")
1060 t!("\\\\?\\C:\\.foo.txt.zip",
1061 iter: ["\\\\?\\C:", "\\", ".foo.txt.zip"],
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")
1071 t!("\\\\?\\C:\\.foo",
1072 iter: ["\\\\?\\C:", "\\", ".foo"],
1075 parent: Some("\\\\?\\C:\\"),
1076 file_name: Some(".foo"),
1077 file_stem: Some(".foo"),
1079 file_prefix: Some(".foo")
1083 iter: ["a", ".x.y.z"],
1087 file_name: Some(".x.y.z"),
1088 file_stem: Some(".x.y"),
1089 extension: Some("z"),
1090 file_prefix: Some(".x")
1095 pub fn test_stem_ext() {
1097 file_stem: Some("foo"),
1102 file_stem: Some("foo"),
1107 file_stem: Some(".foo"),
1112 file_stem: Some("foo"),
1113 extension: Some("txt")
1117 file_stem: Some("foo.bar"),
1118 extension: Some("txt")
1122 file_stem: Some("foo.bar"),
1126 t!(".", file_stem: None, extension: None);
1128 t!("..", file_stem: None, extension: None);
1130 t!(".x.y.z", file_stem: Some(".x.y"), extension: Some("z"));
1132 t!("..x.y.z", file_stem: Some("..x.y"), extension: Some("z"));
1134 t!("", file_stem: None, extension: None);
1138 pub fn test_prefix_ext() {
1140 file_prefix: Some("foo"),
1145 file_prefix: Some("foo"),
1150 file_prefix: Some(".foo"),
1155 file_prefix: Some("foo"),
1156 extension: Some("txt")
1160 file_prefix: Some("foo"),
1161 extension: Some("txt")
1165 file_prefix: Some("foo"),
1169 t!(".", file_prefix: None, extension: None);
1171 t!("..", file_prefix: None, extension: None);
1173 t!(".x.y.z", file_prefix: Some(".x"), extension: Some("z"));
1175 t!("..x.y.z", file_prefix: Some("."), extension: Some("z"));
1177 t!("", file_prefix: None, extension: None);
1181 pub fn test_push() {
1183 ($path:expr, $push:expr, $expected:expr) => ( {
1184 let mut actual = PathBuf::from($path);
1186 assert!(actual.to_str() == Some($expected),
1187 "pushing {:?} onto {:?}: Expected {:?}, got {:?}",
1188 $push, $path, $expected, actual.to_str().unwrap());
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");
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");
1229 tp!("c:\\", "windows", "c:\\windows");
1230 tp!("c:", "windows", "c:windows");
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");
1255 // Note: modified from old path API
1256 tp!("\\\\?\\UNC\\server", "foo", "\\\\?\\UNC\\server\\foo");
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");
1264 tp!("\\\\?\\C:", "foo", "\\\\?\\C:\\foo"); // this is a weird one
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\");
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);
1292 tp!("/", "/", false);
1293 tp!("foo", "", 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);
1302 tp!("a\\b\\c", "a\\b", true);
1303 tp!("\\a", "\\", true);
1304 tp!("\\", "\\", false);
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);
1328 tp!("\\\\?\\a\\b\\", "\\\\?\\a\\", true);
1333 pub fn test_set_file_name() {
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());
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");
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");
1367 pub fn test_set_extension() {
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);
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);
1395 fn test_eq_receivers() {
1396 use crate::borrow::Cow;
1398 let borrowed: &Path = Path::new("foo/bar");
1399 let mut owned: PathBuf = PathBuf::new();
1402 let borrowed_cow: Cow<'_, Path> = borrowed.into();
1403 let owned_cow: Cow<'_, Path> = owned.clone().into();
1406 ($($current:expr),+) => {
1408 assert_eq!($current, borrowed);
1409 assert_eq!($current, owned);
1410 assert_eq!($current, borrowed_cow);
1411 assert_eq!($current, owned_cow);
1416 t!(borrowed, owned, borrowed_cow, owned_cow);
1420 pub fn test_compare() {
1421 use crate::collections::hash_map::DefaultHasher;
1422 use crate::hash::{Hash, Hasher};
1424 fn hash<T: Hash>(t: T) -> u64 {
1425 let mut s = DefaultHasher::new();
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);
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));
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);
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);
1454 let relative_from = path1.strip_prefix(path2)
1455 .map(|p| p.to_str().unwrap())
1457 let exp: Option<&str> = $relative_from;
1458 assert!(relative_from == exp,
1459 "{:?}.strip_prefix({:?}), expected {:?}, got {:?}",
1460 $path1, $path2, exp, relative_from);
1468 relative_from: Some("")
1475 relative_from: Some("foo")
1489 relative_from: Some("")
1496 relative_from: Some("")
1499 tc!("foo/bar", "foo",
1503 relative_from: Some("bar")
1506 tc!("foo/bar/baz", "foo/bar",
1510 relative_from: Some("baz")
1513 tc!("foo/bar", "foo/bar/baz",
1520 tc!("./foo/bar/", ".",
1524 relative_from: Some("foo/bar")
1528 tc!(r"C:\src\rust\cargo-test\test\Cargo.toml",
1529 r"c:\src\rust\cargo-test\test",
1533 relative_from: Some("Cargo.toml")
1536 tc!(r"c:\foo", r"C:\foo",
1540 relative_from: Some("")
1546 fn test_components_debug() {
1547 let path = Path::new("/tmp");
1549 let mut components = path.components();
1551 let expected = "Components([RootDir, Normal(\"tmp\")])";
1552 let actual = format!("{:?}", components);
1553 assert_eq!(expected, actual);
1555 let _ = components.next().unwrap();
1556 let expected = "Components([Normal(\"tmp\")])";
1557 let actual = format!("{:?}", components);
1558 assert_eq!(expected, actual);
1560 let _ = components.next().unwrap();
1561 let expected = "Components([])";
1562 let actual = format!("{:?}", components);
1563 assert_eq!(expected, actual);
1568 fn test_iter_debug() {
1569 let path = Path::new("/tmp");
1571 let mut iter = path.iter();
1573 let expected = "Iter([\"/\", \"tmp\"])";
1574 let actual = format!("{:?}", iter);
1575 assert_eq!(expected, actual);
1577 let _ = iter.next().unwrap();
1578 let expected = "Iter([\"tmp\"])";
1579 let actual = format!("{:?}", iter);
1580 assert_eq!(expected, actual);
1582 let _ = iter.next().unwrap();
1583 let expected = "Iter([])";
1584 let actual = format!("{:?}", iter);
1585 assert_eq!(expected, actual);
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);
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);
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");
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);
1621 assert_eq!(&*rc, path);
1622 assert_eq!(&*arc, path);
1624 let rc2: Rc<Path> = Rc::from(path.to_owned());
1625 let arc2: Arc<Path> = Arc::from(path.to_owned());
1627 assert_eq!(&*rc2, path);
1628 assert_eq!(&*arc2, path);
1634 ($ord:ident, $left:expr, $right:expr) => ( {
1635 assert_eq!(Path::new($left).cmp(&Path::new($right)), core::cmp::Ordering::$ord);
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//");
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();
1657 black_box(paths.as_mut_slice()).sort_unstable();
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/";
1665 (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {}.rs", num))).collect();
1667 let mut set = BTreeSet::new();
1669 paths.iter().for_each(|p| {
1670 set.insert(p.as_path());
1674 set.remove(paths[500].as_path());
1675 set.insert(paths[500].as_path());
1680 fn bench_path_cmp_fast_path_short(b: &mut test::Bencher) {
1681 let prefix = "my/home";
1683 (0..1000).map(|num| PathBuf::from(prefix).join(format!("file {}.rs", num))).collect();
1685 let mut set = BTreeSet::new();
1687 paths.iter().for_each(|p| {
1688 set.insert(p.as_path());
1692 set.remove(paths[500].as_path());
1693 set.insert(paths[500].as_path());