1 // Copyright (c) The camino Contributors
2 // SPDX-License-Identifier: MIT OR Apache-2.0
3 
4 use camino::{Utf8Path, Utf8PathBuf};
5 use std::{
6     collections::hash_map::DefaultHasher,
7     hash::{Hash, Hasher},
8     path::Path,
9 };
10 
11 static PATH_CORPUS: &[&str] = &[
12     "",
13     "foo",
14     "foo/bar",
15     "foo//bar",
16     "foo/bar/baz",
17     "foo/bar/./baz",
18     "foo/bar/../baz",
19     "../foo/bar/./../baz",
20     "/foo",
21     "/foo/bar",
22     "/",
23     "///",
24     // ---
25     // Windows-only paths
26     // ---
27     #[cfg(windows)]
28     "foo\\bar",
29     #[cfg(windows)]
30     "\\foo\\bar",
31     #[cfg(windows)]
32     "C:\\foo",
33     #[cfg(windows)]
34     "C:foo\\bar",
35     #[cfg(windows)]
36     "C:\\foo\\..\\.\\bar",
37     #[cfg(windows)]
38     "\\\\server\\foo\\bar",
39     #[cfg(windows)]
40     "\\\\.\\C:\\foo\\bar.txt",
41 ];
42 
43 #[test]
test_borrow_eq_ord()44 fn test_borrow_eq_ord() {
45     // Utf8PathBuf implements Borrow<Utf8Path> so equality and ordering comparisons should
46     // match.
47     for (idx, &path1) in PATH_CORPUS.iter().enumerate() {
48         for &path2 in &PATH_CORPUS[idx..] {
49             let borrowed1 = Utf8Path::new(path1);
50             let borrowed2 = Utf8Path::new(path2);
51             let owned1 = Utf8PathBuf::from(path1);
52             let owned2 = Utf8PathBuf::from(path2);
53 
54             assert_eq!(
55                 borrowed1 == borrowed2,
56                 owned1 == owned2,
57                 "Eq impls match: {} == {}",
58                 borrowed1,
59                 borrowed2
60             );
61             assert_eq!(
62                 borrowed1.cmp(borrowed2),
63                 owned1.cmp(&owned2),
64                 "Ord impls match: {} and {}",
65                 borrowed1,
66                 borrowed2
67             );
68 
69             // Also check against std paths.
70             let std1 = Path::new(path1);
71             let std2 = Path::new(path2);
72             assert_eq!(
73                 borrowed1, std1,
74                 "Eq between Path and Utf8Path: {}",
75                 borrowed1
76             );
77             assert_eq!(
78                 borrowed1 == borrowed2,
79                 std1 == std2,
80                 "Eq impl matches Path: {} == {}",
81                 borrowed1,
82                 borrowed2
83             );
84             assert_eq!(
85                 borrowed1.cmp(borrowed2),
86                 std1.cmp(std2),
87                 "Ord impl matches Path: {} and {}",
88                 borrowed1,
89                 borrowed2
90             );
91         }
92     }
93 }
94 
95 #[test]
test_borrow_hash()96 fn test_borrow_hash() {
97     // Utf8PathBuf implements Borrow<Utf8Path> so hash comparisons should match.
98     fn hash_output(x: impl Hash) -> u64 {
99         let mut hasher = DefaultHasher::new();
100         x.hash(&mut hasher);
101         hasher.finish()
102     }
103 
104     for &path in PATH_CORPUS {
105         let borrowed = Utf8Path::new(path);
106         let owned = Utf8PathBuf::from(path);
107 
108         assert_eq!(
109             hash_output(owned),
110             hash_output(borrowed),
111             "consistent Hash: {}",
112             borrowed
113         );
114     }
115 }
116