]> git.proxmox.com Git - rustc.git/blob - vendor/gix-pathspec/tests/parse/valid.rs
New upstream version 1.74.1+dfsg1
[rustc.git] / vendor / gix-pathspec / tests / parse / valid.rs
1 use gix_attributes::State;
2 use gix_pathspec::{MagicSignature, SearchMode};
3
4 use crate::parse::{check_against_baseline, check_valid_inputs, NormalizedPattern};
5
6 #[test]
7 fn repeated_matcher_keywords() {
8 let input = vec![
9 (":(glob,glob)", pat_with_search_mode(SearchMode::PathAwareGlob)),
10 (":(literal,literal)", pat_with_search_mode(SearchMode::Literal)),
11 (":(top,top)", pat_with_sig(MagicSignature::TOP)),
12 (":(icase,icase)", pat_with_sig(MagicSignature::ICASE)),
13 (":(attr,attr)", pat_with_attrs(vec![])),
14 (":!^(exclude,exclude)", pat_with_sig(MagicSignature::EXCLUDE)),
15 ];
16
17 check_valid_inputs(input);
18 }
19
20 #[test]
21 fn glob_negations_are_always_literal() {
22 check_valid_inputs([("!a", pat_with_path("!a")), ("\\!a", pat_with_path("\\!a"))]);
23 }
24
25 #[test]
26 fn literal_default_prevents_parsing() {
27 let pattern = gix_pathspec::parse(
28 ":".as_bytes(),
29 gix_pathspec::Defaults {
30 signature: MagicSignature::EXCLUDE,
31 search_mode: SearchMode::PathAwareGlob,
32 literal: true,
33 },
34 )
35 .expect("valid");
36 assert!(!pattern.is_nil());
37 assert_eq!(pattern.path(), ":");
38 assert!(matches!(pattern.search_mode, SearchMode::Literal));
39
40 let input = ":(literal)f[o][o]";
41 let pattern = gix_pathspec::parse(
42 input.as_bytes(),
43 gix_pathspec::Defaults {
44 signature: MagicSignature::TOP,
45 search_mode: SearchMode::Literal,
46 literal: true,
47 },
48 )
49 .expect("valid");
50 assert_eq!(pattern.path(), input, "no parsing happens at all");
51 assert!(matches!(pattern.search_mode, SearchMode::Literal));
52
53 let pattern = gix_pathspec::parse(
54 input.as_bytes(),
55 gix_pathspec::Defaults {
56 signature: MagicSignature::TOP,
57 search_mode: SearchMode::Literal,
58 literal: false,
59 },
60 )
61 .expect("valid");
62 assert_eq!(pattern.path(), "f[o][o]", "in literal default mode, we still parse");
63 assert!(matches!(pattern.search_mode, SearchMode::Literal));
64 }
65
66 #[test]
67 fn there_is_no_pathspec_pathspec() {
68 check_against_baseline(":");
69 let pattern = gix_pathspec::parse(":".as_bytes(), Default::default()).expect("valid");
70 assert!(pattern.is_nil());
71
72 let actual: NormalizedPattern = pattern.into();
73 assert_eq!(actual, pat_with_path(""));
74
75 let pattern = gix_pathspec::parse(
76 ":".as_bytes(),
77 gix_pathspec::Defaults {
78 signature: MagicSignature::EXCLUDE,
79 search_mode: SearchMode::PathAwareGlob,
80 literal: false,
81 },
82 )
83 .expect("valid");
84 assert!(pattern.is_nil());
85 }
86
87 #[test]
88 fn defaults_are_used() -> crate::Result {
89 let defaults = gix_pathspec::Defaults {
90 signature: MagicSignature::EXCLUDE,
91 search_mode: SearchMode::Literal,
92 literal: false,
93 };
94 let p = gix_pathspec::parse(".".as_bytes(), defaults)?;
95 assert_eq!(p.path(), ".");
96 assert_eq!(p.signature, defaults.signature);
97 assert_eq!(p.search_mode, defaults.search_mode);
98 assert!(p.attributes.is_empty());
99 assert!(!p.is_nil());
100 Ok(())
101 }
102
103 #[test]
104 fn literal_from_defaults_is_overridden_by_element_glob() -> crate::Result {
105 let defaults = gix_pathspec::Defaults {
106 search_mode: SearchMode::Literal,
107 ..Default::default()
108 };
109 let p = gix_pathspec::parse(":(glob)*override".as_bytes(), defaults)?;
110 assert_eq!(p.path(), "*override");
111 assert_eq!(p.signature, MagicSignature::default());
112 assert_eq!(p.search_mode, SearchMode::PathAwareGlob, "this is the element override");
113 assert!(p.attributes.is_empty());
114 assert!(!p.is_nil());
115 Ok(())
116 }
117
118 #[test]
119 fn glob_from_defaults_is_overridden_by_element_glob() -> crate::Result {
120 let defaults = gix_pathspec::Defaults {
121 search_mode: SearchMode::PathAwareGlob,
122 ..Default::default()
123 };
124 let p = gix_pathspec::parse(":(literal)*override".as_bytes(), defaults)?;
125 assert_eq!(p.path(), "*override");
126 assert_eq!(p.signature, MagicSignature::default());
127 assert_eq!(p.search_mode, SearchMode::Literal, "this is the element override");
128 assert!(p.attributes.is_empty());
129 assert!(!p.is_nil());
130 Ok(())
131 }
132
133 #[test]
134 fn empty_signatures() {
135 let inputs = vec![
136 (".", pat_with_path(".")),
137 ("some/path", pat_with_path("some/path")),
138 (":some/path", pat_with_path("some/path")),
139 (":()some/path", pat_with_path("some/path")),
140 ("::some/path", pat_with_path("some/path")),
141 (":::some/path", pat_with_path(":some/path")),
142 (":():some/path", pat_with_path(":some/path")),
143 ];
144
145 check_valid_inputs(inputs)
146 }
147
148 #[test]
149 fn whitespace_in_pathspec() {
150 let inputs = vec![
151 (" some/path", pat_with_path(" some/path")),
152 ("some/ path", pat_with_path("some/ path")),
153 ("some/path ", pat_with_path("some/path ")),
154 (": some/path", pat_with_path(" some/path")),
155 (": !some/path", pat_with_path(" !some/path")),
156 (": :some/path", pat_with_path(" :some/path")),
157 (": ()some/path", pat_with_path(" ()some/path")),
158 (
159 ":! some/path",
160 pat_with_path_and_sig(" some/path", MagicSignature::EXCLUDE),
161 ),
162 (
163 ":!!some/path",
164 pat_with_path_and_sig("some/path", MagicSignature::EXCLUDE),
165 ),
166 ];
167
168 check_valid_inputs(inputs)
169 }
170
171 #[test]
172 fn short_signatures() {
173 let inputs = vec![
174 (":/some/path", pat_with_path_and_sig("some/path", MagicSignature::TOP)),
175 (
176 ":^some/path",
177 pat_with_path_and_sig("some/path", MagicSignature::EXCLUDE),
178 ),
179 (
180 ":!some/path",
181 pat_with_path_and_sig("some/path", MagicSignature::EXCLUDE),
182 ),
183 (
184 ":/!some/path",
185 pat_with_path_and_sig("some/path", MagicSignature::TOP | MagicSignature::EXCLUDE),
186 ),
187 (
188 ":!/^/:some/path",
189 pat_with_path_and_sig("some/path", MagicSignature::TOP | MagicSignature::EXCLUDE),
190 ),
191 ];
192
193 check_valid_inputs(inputs)
194 }
195
196 #[test]
197 fn trailing_slash_is_turned_into_magic_signature_and_removed() {
198 check_valid_inputs([
199 ("a/b/", pat_with_path_and_sig("a/b", MagicSignature::MUST_BE_DIR)),
200 ("a/", pat_with_path_and_sig("a", MagicSignature::MUST_BE_DIR)),
201 ]);
202 }
203
204 #[test]
205 fn signatures_and_searchmodes() {
206 let inputs = vec![
207 (":(top)", pat_with_sig(MagicSignature::TOP)),
208 (":(icase)", pat_with_sig(MagicSignature::ICASE)),
209 (":(attr)", pat_with_path("")),
210 (":(exclude)", pat_with_sig(MagicSignature::EXCLUDE)),
211 (":(literal)", pat_with_search_mode(SearchMode::Literal)),
212 (":(glob)", pat_with_search_mode(SearchMode::PathAwareGlob)),
213 (
214 ":(top,exclude)",
215 pat_with_sig(MagicSignature::TOP | MagicSignature::EXCLUDE),
216 ),
217 (
218 ":(icase,literal)",
219 pat("", MagicSignature::ICASE, SearchMode::Literal, vec![]),
220 ),
221 (
222 ":!(literal)some/*path",
223 pat("some/*path", MagicSignature::EXCLUDE, SearchMode::Literal, vec![]),
224 ),
225 (
226 ":(top,literal,icase,attr,exclude)some/path",
227 pat(
228 "some/path",
229 MagicSignature::TOP | MagicSignature::EXCLUDE | MagicSignature::ICASE,
230 SearchMode::Literal,
231 vec![],
232 ),
233 ),
234 (
235 ":(top,glob,icase,attr,exclude)some/path",
236 pat(
237 "some/path",
238 MagicSignature::TOP | MagicSignature::EXCLUDE | MagicSignature::ICASE,
239 SearchMode::PathAwareGlob,
240 vec![],
241 ),
242 ),
243 ];
244
245 check_valid_inputs(inputs);
246 }
247
248 #[test]
249 fn attributes_in_signature() {
250 let inputs = vec![
251 (":(attr:someAttr)", pat_with_attrs(vec![("someAttr", State::Set)])),
252 (
253 ":(attr:!someAttr)",
254 pat_with_attrs(vec![("someAttr", State::Unspecified)]),
255 ),
256 (":(attr:-someAttr)", pat_with_attrs(vec![("someAttr", State::Unset)])),
257 (
258 ":(attr:someAttr=value)",
259 pat_with_attrs(vec![("someAttr", State::Value("value".into()))]),
260 ),
261 (
262 ":(attr:a=one b=)",
263 pat_with_attrs(vec![("a", State::Value("one".into())), ("b", State::Value("".into()))]),
264 ),
265 (
266 ":(attr:a= b=two)",
267 pat_with_attrs(vec![("a", State::Value("".into())), ("b", State::Value("two".into()))]),
268 ),
269 (
270 ":(attr:a=one b=two)",
271 pat_with_attrs(vec![
272 ("a", State::Value("one".into())),
273 ("b", State::Value("two".into())),
274 ]),
275 ),
276 (
277 ":(attr:a=one b=two)",
278 pat_with_attrs(vec![
279 ("a", State::Value("one".into())),
280 ("b", State::Value("two".into())),
281 ]),
282 ),
283 (
284 ":(attr:someAttr anotherAttr)",
285 pat_with_attrs(vec![("someAttr", State::Set), ("anotherAttr", State::Set)]),
286 ),
287 ];
288
289 check_valid_inputs(inputs)
290 }
291
292 #[test]
293 fn attributes_with_escape_chars_in_state_values() {
294 let inputs = vec![
295 (
296 r":(attr:v=one\-)",
297 pat_with_attrs(vec![("v", State::Value(r"one-".into()))]),
298 ),
299 (
300 r":(attr:v=one\_)",
301 pat_with_attrs(vec![("v", State::Value(r"one_".into()))]),
302 ),
303 (
304 r":(attr:v=one\,)",
305 pat_with_attrs(vec![("v", State::Value(r"one,".into()))]),
306 ),
307 (
308 r":(attr:v=one\,two\,three)",
309 pat_with_attrs(vec![("v", State::Value(r"one,two,three".into()))]),
310 ),
311 (
312 r":(attr:a=\d b= c=\d)",
313 pat_with_attrs(vec![
314 ("a", State::Value(r"d".into())),
315 ("b", State::Value(r"".into())),
316 ("c", State::Value(r"d".into())),
317 ]),
318 ),
319 ];
320
321 check_valid_inputs(inputs)
322 }
323
324 fn pat_with_path(path: &str) -> NormalizedPattern {
325 pat_with_path_and_sig(path, MagicSignature::empty())
326 }
327
328 fn pat_with_path_and_sig(path: &str, signature: MagicSignature) -> NormalizedPattern {
329 pat(path, signature, SearchMode::ShellGlob, vec![])
330 }
331
332 fn pat_with_sig(signature: MagicSignature) -> NormalizedPattern {
333 pat("", signature, SearchMode::ShellGlob, vec![])
334 }
335
336 fn pat_with_attrs(attrs: Vec<(&'static str, State)>) -> NormalizedPattern {
337 pat("", MagicSignature::empty(), SearchMode::ShellGlob, attrs)
338 }
339
340 fn pat_with_search_mode(search_mode: SearchMode) -> NormalizedPattern {
341 pat("", MagicSignature::empty(), search_mode, vec![])
342 }
343
344 fn pat(
345 path: &str,
346 signature: MagicSignature,
347 search_mode: SearchMode,
348 attributes: Vec<(&str, State)>,
349 ) -> NormalizedPattern {
350 NormalizedPattern {
351 path: path.into(),
352 signature,
353 search_mode,
354 attributes: attributes
355 .into_iter()
356 .map(|(attr, state)| (attr.into(), state))
357 .collect(),
358 }
359 }