1 use gix_attributes
::State
;
2 use gix_pathspec
::{MagicSignature, SearchMode}
;
4 use crate::parse
::{check_against_baseline, check_valid_inputs, NormalizedPattern}
;
7 fn repeated_matcher_keywords() {
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
)),
17 check_valid_inputs(input
);
21 fn glob_negations_are_always_literal() {
22 check_valid_inputs([("!a", pat_with_path("!a")), ("\\!a", pat_with_path("\\!a"))]);
26 fn literal_default_prevents_parsing() {
27 let pattern
= gix_pathspec
::parse(
29 gix_pathspec
::Defaults
{
30 signature
: MagicSignature
::EXCLUDE
,
31 search_mode
: SearchMode
::PathAwareGlob
,
36 assert
!(!pattern
.is_nil());
37 assert_eq
!(pattern
.path(), ":");
38 assert
!(matches
!(pattern
.search_mode
, SearchMode
::Literal
));
40 let input
= ":(literal)f[o][o]";
41 let pattern
= gix_pathspec
::parse(
43 gix_pathspec
::Defaults
{
44 signature
: MagicSignature
::TOP
,
45 search_mode
: SearchMode
::Literal
,
50 assert_eq
!(pattern
.path(), input
, "no parsing happens at all");
51 assert
!(matches
!(pattern
.search_mode
, SearchMode
::Literal
));
53 let pattern
= gix_pathspec
::parse(
55 gix_pathspec
::Defaults
{
56 signature
: MagicSignature
::TOP
,
57 search_mode
: SearchMode
::Literal
,
62 assert_eq
!(pattern
.path(), "f[o][o]", "in literal default mode, we still parse");
63 assert
!(matches
!(pattern
.search_mode
, SearchMode
::Literal
));
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());
72 let actual
: NormalizedPattern
= pattern
.into();
73 assert_eq
!(actual
, pat_with_path(""));
75 let pattern
= gix_pathspec
::parse(
77 gix_pathspec
::Defaults
{
78 signature
: MagicSignature
::EXCLUDE
,
79 search_mode
: SearchMode
::PathAwareGlob
,
84 assert
!(pattern
.is_nil());
88 fn defaults_are_used() -> crate::Result
{
89 let defaults
= gix_pathspec
::Defaults
{
90 signature
: MagicSignature
::EXCLUDE
,
91 search_mode
: SearchMode
::Literal
,
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());
104 fn literal_from_defaults_is_overridden_by_element_glob() -> crate::Result
{
105 let defaults
= gix_pathspec
::Defaults
{
106 search_mode
: SearchMode
::Literal
,
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());
119 fn glob_from_defaults_is_overridden_by_element_glob() -> crate::Result
{
120 let defaults
= gix_pathspec
::Defaults
{
121 search_mode
: SearchMode
::PathAwareGlob
,
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());
134 fn empty_signatures() {
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")),
145 check_valid_inputs(inputs
)
149 fn whitespace_in_pathspec() {
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")),
160 pat_with_path_and_sig(" some/path", MagicSignature
::EXCLUDE
),
164 pat_with_path_and_sig("some/path", MagicSignature
::EXCLUDE
),
168 check_valid_inputs(inputs
)
172 fn short_signatures() {
174 (":/some/path", pat_with_path_and_sig("some/path", MagicSignature
::TOP
)),
177 pat_with_path_and_sig("some/path", MagicSignature
::EXCLUDE
),
181 pat_with_path_and_sig("some/path", MagicSignature
::EXCLUDE
),
185 pat_with_path_and_sig("some/path", MagicSignature
::TOP
| MagicSignature
::EXCLUDE
),
189 pat_with_path_and_sig("some/path", MagicSignature
::TOP
| MagicSignature
::EXCLUDE
),
193 check_valid_inputs(inputs
)
197 fn trailing_slash_is_turned_into_magic_signature_and_removed() {
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
)),
205 fn signatures_and_searchmodes() {
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
)),
215 pat_with_sig(MagicSignature
::TOP
| MagicSignature
::EXCLUDE
),
219 pat("", MagicSignature
::ICASE
, SearchMode
::Literal
, vec
![]),
222 ":!(literal)some/*path",
223 pat("some/*path", MagicSignature
::EXCLUDE
, SearchMode
::Literal
, vec
![]),
226 ":(top,literal,icase,attr,exclude)some/path",
229 MagicSignature
::TOP
| MagicSignature
::EXCLUDE
| MagicSignature
::ICASE
,
235 ":(top,glob,icase,attr,exclude)some/path",
238 MagicSignature
::TOP
| MagicSignature
::EXCLUDE
| MagicSignature
::ICASE
,
239 SearchMode
::PathAwareGlob
,
245 check_valid_inputs(inputs
);
249 fn attributes_in_signature() {
251 (":(attr:someAttr)", pat_with_attrs(vec
![("someAttr", State
::Set
)])),
254 pat_with_attrs(vec
![("someAttr", State
::Unspecified
)]),
256 (":(attr:-someAttr)", pat_with_attrs(vec
![("someAttr", State
::Unset
)])),
258 ":(attr:someAttr=value)",
259 pat_with_attrs(vec
![("someAttr", State
::Value("value".into()))]),
263 pat_with_attrs(vec
![("a", State
::Value("one".into())), ("b", State
::Value("".into()))]),
267 pat_with_attrs(vec
![("a", State
::Value("".into())), ("b", State
::Value("two".into()))]),
270 ":(attr:a=one b=two)",
272 ("a", State
::Value("one".into())),
273 ("b", State
::Value("two".into())),
277 ":(attr:a=one b=two)",
279 ("a", State
::Value("one".into())),
280 ("b", State
::Value("two".into())),
284 ":(attr:someAttr anotherAttr)",
285 pat_with_attrs(vec
![("someAttr", State
::Set
), ("anotherAttr", State
::Set
)]),
289 check_valid_inputs(inputs
)
293 fn attributes_with_escape_chars_in_state_values() {
297 pat_with_attrs(vec
![("v", State
::Value(r
"one-".into()))]),
301 pat_with_attrs(vec
![("v", State
::Value(r
"one_".into()))]),
305 pat_with_attrs(vec
![("v", State
::Value(r
"one,".into()))]),
308 r
":(attr:v=one\,two\,three)",
309 pat_with_attrs(vec
![("v", State
::Value(r
"one,two,three".into()))]),
312 r
":(attr:a=\d b= c=\d)",
314 ("a", State
::Value(r
"d".into())),
315 ("b", State
::Value(r
"".into())),
316 ("c", State
::Value(r
"d".into())),
321 check_valid_inputs(inputs
)
324 fn pat_with_path(path
: &str) -> NormalizedPattern
{
325 pat_with_path_and_sig(path
, MagicSignature
::empty())
328 fn pat_with_path_and_sig(path
: &str, signature
: MagicSignature
) -> NormalizedPattern
{
329 pat(path
, signature
, SearchMode
::ShellGlob
, vec
![])
332 fn pat_with_sig(signature
: MagicSignature
) -> NormalizedPattern
{
333 pat("", signature
, SearchMode
::ShellGlob
, vec
![])
336 fn pat_with_attrs(attrs
: Vec
<(&'
static str, State
)>) -> NormalizedPattern
{
337 pat("", MagicSignature
::empty(), SearchMode
::ShellGlob
, attrs
)
340 fn pat_with_search_mode(search_mode
: SearchMode
) -> NormalizedPattern
{
341 pat("", MagicSignature
::empty(), search_mode
, vec
![])
346 signature
: MagicSignature
,
347 search_mode
: SearchMode
,
348 attributes
: Vec
<(&str, State
)>,
349 ) -> NormalizedPattern
{
354 attributes
: attributes
356 .map(|(attr
, state
)| (attr
.into(), state
))