1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 package org.eclipse.jgit.ignore;
44
45 import static org.eclipse.jgit.ignore.internal.Strings.split;
46 import static org.junit.Assert.assertArrayEquals;
47 import static org.junit.Assert.assertFalse;
48 import static org.junit.Assert.assertTrue;
49 import static org.junit.Assert.fail;
50
51 import org.junit.Test;
52
53 public class FastIgnoreRuleTest {
54
55 @Test
56 public void testSimpleCharClass() {
57 assertMatched("[a]", "a");
58 assertMatched("][a]", "]a");
59 assertMatched("[a]", "a/");
60 assertMatched("[a]", "a/b");
61
62 assertMatched("[a]", "b/a");
63 assertMatched("[a]", "b/a/");
64 assertMatched("[a]", "b/a/b");
65
66 assertMatched("[a]", "/a/");
67 assertMatched("[a]", "/a/b");
68
69 assertMatched("[a]", "c/a/b");
70 assertMatched("[a]", "c/b/a");
71
72 assertMatched("/[a]", "a");
73 assertMatched("/[a]", "a/");
74 assertMatched("/[a]", "a/b");
75 assertMatched("/[a]", "/a");
76 assertMatched("/[a]", "/a/");
77 assertMatched("/[a]", "/a/b");
78
79 assertMatched("[a]/", "a/");
80 assertMatched("[a]/", "a/b");
81 assertMatched("[a]/", "/a/");
82 assertMatched("[a]/", "/a/b");
83
84 assertMatched("/[a]/", "a/");
85 assertMatched("/[a]/", "a/b");
86 assertMatched("/[a]/", "/a/");
87 assertMatched("/[a]/", "/a/b");
88 }
89
90 @Test
91 public void testCharClass() {
92 assertMatched("[v-z]", "x");
93 assertMatched("[v-z]", "x/");
94 assertMatched("[v-z]", "x/b");
95
96 assertMatched("[v-z]", "b/x");
97 assertMatched("[v-z]", "b/x/");
98 assertMatched("[v-z]", "b/x/b");
99
100 assertMatched("[v-z]", "/x/");
101 assertMatched("[v-z]", "/x/b");
102
103 assertMatched("[v-z]", "c/x/b");
104 assertMatched("[v-z]", "c/b/x");
105
106 assertMatched("/[v-z]", "x");
107 assertMatched("/[v-z]", "x/");
108 assertMatched("/[v-z]", "x/b");
109 assertMatched("/[v-z]", "/x");
110 assertMatched("/[v-z]", "/x/");
111 assertMatched("/[v-z]", "/x/b");
112
113 assertMatched("[v-z]/", "x/");
114 assertMatched("[v-z]/", "x/b");
115 assertMatched("[v-z]/", "/x/");
116 assertMatched("[v-z]/", "/x/b");
117
118 assertMatched("/[v-z]/", "x/");
119 assertMatched("/[v-z]/", "x/b");
120 assertMatched("/[v-z]/", "/x/");
121 assertMatched("/[v-z]/", "/x/b");
122 }
123
124 @Test
125 public void testAsteriskDot() {
126 assertMatched("*.a", ".a");
127 assertMatched("*.a", "/.a");
128 assertMatched("*.a", "a.a");
129 assertMatched("*.a", "/b.a");
130 assertMatched("*.a", "b.a");
131 assertMatched("*.a", "/a/b.a");
132 assertMatched("*.a", "/b/.a");
133 }
134
135 @Test
136 public void testAsteriskDotDoNotMatch() {
137 assertNotMatched("*.a", ".ab");
138 assertNotMatched("*.a", "/.ab");
139 assertNotMatched("*.a", "/b.ba");
140 assertNotMatched("*.a", "a.ab");
141 assertNotMatched("*.a", "/b.ab");
142 assertNotMatched("*.a", "b.ab");
143 assertNotMatched("*.a", "/a/b.ab");
144 assertNotMatched("*.a", "/b/.ab");
145 }
146
147 @Test
148 public void testDotAsteriskMatch() {
149 assertMatched("a.*", "a.");
150 assertMatched("a.*", "a./");
151 assertMatched("a.*", "a.b");
152
153 assertMatched("a.*", "b/a.b");
154 assertMatched("a.*", "b/a.b/");
155 assertMatched("a.*", "b/a.b/b");
156
157 assertMatched("a.*", "/a.b/");
158 assertMatched("a.*", "/a.b/b");
159
160 assertMatched("a.*", "c/a.b/b");
161 assertMatched("a.*", "c/b/a.b");
162
163 assertMatched("/a.*", "a.b");
164 assertMatched("/a.*", "a.b/");
165 assertMatched("/a.*", "a.b/b");
166 assertMatched("/a.*", "/a.b");
167 assertMatched("/a.*", "/a.b/");
168 assertMatched("/a.*", "/a.b/b");
169
170 assertMatched("/a.*/b", "a.b/b");
171 assertMatched("/a.*/b", "/a.b/b");
172 assertMatched("/a.*/b", "/a.bc/b");
173 assertMatched("/a.*/b", "/a./b");
174 }
175
176 @Test
177 public void testAsterisk() {
178 assertMatched("a*", "a");
179 assertMatched("a*", "a/");
180 assertMatched("a*", "ab");
181
182 assertMatched("a*", "b/ab");
183 assertMatched("a*", "b/ab/");
184 assertMatched("a*", "b/ab/b");
185
186 assertMatched("a*", "b/abc");
187 assertMatched("a*", "b/abc/");
188 assertMatched("a*", "b/abc/b");
189
190 assertMatched("a*", "/abc/");
191 assertMatched("a*", "/abc/b");
192
193 assertMatched("a*", "c/abc/b");
194 assertMatched("a*", "c/b/abc");
195
196 assertMatched("/a*", "abc");
197 assertMatched("/a*", "abc/");
198 assertMatched("/a*", "abc/b");
199 assertMatched("/a*", "/abc");
200 assertMatched("/a*", "/abc/");
201 assertMatched("/a*", "/abc/b");
202
203 assertMatched("/a*/b", "abc/b");
204 assertMatched("/a*/b", "/abc/b");
205 assertMatched("/a*/b", "/abcd/b");
206 assertMatched("/a*/b", "/a/b");
207 }
208
209 @Test
210 public void testQuestionmark() {
211 assertMatched("a?", "ab");
212 assertMatched("a?", "ab/");
213
214 assertMatched("a?", "b/ab");
215 assertMatched("a?", "b/ab/");
216 assertMatched("a?", "b/ab/b");
217
218 assertMatched("a?", "/ab/");
219 assertMatched("a?", "/ab/b");
220
221 assertMatched("a?", "c/ab/b");
222 assertMatched("a?", "c/b/ab");
223
224 assertMatched("/a?", "ab");
225 assertMatched("/a?", "ab/");
226 assertMatched("/a?", "ab/b");
227 assertMatched("/a?", "/ab");
228 assertMatched("/a?", "/ab/");
229 assertMatched("/a?", "/ab/b");
230
231 assertMatched("/a?/b", "ab/b");
232 assertMatched("/a?/b", "/ab/b");
233 }
234
235 @Test
236 public void testQuestionmarkDoNotMatch() {
237 assertNotMatched("a?", "a/");
238 assertNotMatched("a?", "abc");
239 assertNotMatched("a?", "abc/");
240
241 assertNotMatched("a?", "b/abc");
242 assertNotMatched("a?", "b/abc/");
243
244 assertNotMatched("a?", "/abc/");
245 assertNotMatched("a?", "/abc/b");
246
247 assertNotMatched("a?", "c/abc/b");
248 assertNotMatched("a?", "c/b/abc");
249
250 assertNotMatched("/a?", "abc");
251 assertNotMatched("/a?", "abc/");
252 assertNotMatched("/a?", "abc/b");
253 assertNotMatched("/a?", "/abc");
254 assertNotMatched("/a?", "/abc/");
255 assertNotMatched("/a?", "/abc/b");
256
257 assertNotMatched("/a?/b", "abc/b");
258 assertNotMatched("/a?/b", "/abc/b");
259 assertNotMatched("/a?/b", "/a/b");
260 }
261
262 @Test
263 public void testSimplePatterns() {
264 assertMatched("a", "a");
265 assertMatched("a", "a/");
266 assertMatched("a", "a/b");
267
268 assertMatched("a", "b/a");
269 assertMatched("a", "b/a/");
270 assertMatched("a", "b/a/b");
271
272 assertMatched("a", "/a/");
273 assertMatched("a", "/a/b");
274
275 assertMatched("a", "c/a/b");
276 assertMatched("a", "c/b/a");
277
278 assertMatched("/a", "a");
279 assertMatched("/a", "a/");
280 assertMatched("/a", "a/b");
281 assertMatched("/a", "/a");
282 assertMatched("/a", "/a/");
283 assertMatched("/a", "/a/b");
284
285 assertMatched("a/", "a/");
286 assertMatched("a/", "a/b");
287 assertMatched("a/", "/a/");
288 assertMatched("a/", "/a/b");
289
290 assertMatched("/a/", "a/");
291 assertMatched("/a/", "a/b");
292 assertMatched("/a/", "/a/");
293 assertMatched("/a/", "/a/b");
294
295 }
296
297 @Test
298 public void testSimplePatternsDoNotMatch() {
299 assertNotMatched("ab", "a");
300 assertNotMatched("abc", "a/");
301 assertNotMatched("abc", "a/b");
302
303 assertNotMatched("a", "ab");
304 assertNotMatched("a", "ba");
305 assertNotMatched("a", "aa");
306
307 assertNotMatched("a", "b/ab");
308 assertNotMatched("a", "b/ba");
309
310 assertNotMatched("a", "b/ba");
311 assertNotMatched("a", "b/ab");
312
313 assertNotMatched("a", "b/ba/");
314 assertNotMatched("a", "b/ba/b");
315
316 assertNotMatched("a", "/aa");
317 assertNotMatched("a", "aa/");
318 assertNotMatched("a", "/aa/");
319
320 assertNotMatched("/a", "b/a");
321 assertNotMatched("/a", "/b/a/");
322
323 assertNotMatched("a/", "a");
324 assertNotMatched("a/", "b/a");
325
326 assertNotMatched("/a/", "a");
327 assertNotMatched("/a/", "/a");
328 assertNotMatched("/a/", "b/a");
329 }
330
331 @Test
332 public void testSegments() {
333 assertMatched("/a/b", "a/b");
334 assertMatched("/a/b", "/a/b");
335 assertMatched("/a/b", "/a/b/");
336 assertMatched("/a/b", "/a/b/c");
337
338 assertMatched("a/b", "a/b");
339 assertMatched("a/b", "/a/b");
340 assertMatched("a/b", "/a/b/");
341 assertMatched("a/b", "/a/b/c");
342
343 assertMatched("a/b/", "a/b/");
344 assertMatched("a/b/", "/a/b/");
345 assertMatched("a/b/", "/a/b/c");
346 }
347
348 @Test
349 public void testSegmentsDoNotMatch() {
350 assertNotMatched("a/b", "/a/bb");
351 assertNotMatched("a/b", "/aa/b");
352 assertNotMatched("a/b", "a/bb");
353 assertNotMatched("a/b", "aa/b");
354 assertNotMatched("a/b", "c/aa/b");
355 assertNotMatched("a/b", "c/a/bb");
356 assertNotMatched("a/b/", "/a/b");
357 assertNotMatched("/a/b/", "/a/b");
358 assertNotMatched("/a/b", "c/a/b");
359 assertNotMatched("/a/b/", "c/a/b");
360 assertNotMatched("/a/b/", "c/a/b/");
361
362
363 assertNotMatched("a/b", "c/a/b");
364 assertNotMatched("a/b", "c/a/b/");
365 assertNotMatched("a/b", "c/a/b/c");
366 assertNotMatched("a/b/", "c/a/b/");
367 assertNotMatched("a/b/", "c/a/b/c");
368 }
369
370 @Test
371 public void testWildmatch() {
372 assertMatched("**/a/b", "a/b");
373 assertMatched("**/a/b", "c/a/b");
374 assertMatched("**/a/b", "c/d/a/b");
375 assertMatched("**/**/a/b", "c/d/a/b");
376
377 assertMatched("/**/a/b", "a/b");
378 assertMatched("/**/a/b", "c/a/b");
379 assertMatched("/**/a/b", "c/d/a/b");
380 assertMatched("/**/**/a/b", "c/d/a/b");
381
382 assertMatched("a/b/**", "a/b");
383 assertMatched("a/b/**", "a/b/c");
384 assertMatched("a/b/**", "a/b/c/d/");
385 assertMatched("a/b/**/**", "a/b/c/d");
386
387 assertMatched("**/a/**/b", "c/d/a/b");
388 assertMatched("**/a/**/b", "c/d/a/e/b");
389 assertMatched("**/**/a/**/**/b", "c/d/a/e/b");
390
391 assertMatched("/**/a/**/b", "c/d/a/b");
392 assertMatched("/**/a/**/b", "c/d/a/e/b");
393 assertMatched("/**/**/a/**/**/b", "c/d/a/e/b");
394
395 assertMatched("a/**/b", "a/b");
396 assertMatched("a/**/b", "a/c/b");
397 assertMatched("a/**/b", "a/c/d/b");
398 assertMatched("a/**/**/b", "a/c/d/b");
399
400 assertMatched("a/**/b/**/c", "a/c/b/d/c");
401 assertMatched("a/**/**/b/**/**/c", "a/c/b/d/c");
402 }
403
404 @Test
405 public void testWildmatchDoNotMatch() {
406 assertNotMatched("**/a/b", "a/c/b");
407 assertNotMatched("!/**/*.zip", "c/a/b.zip");
408 assertNotMatched("!**/*.zip", "c/a/b.zip");
409 assertNotMatched("a/**/b", "a/c/bb");
410 }
411
412 @SuppressWarnings("unused")
413 @Test
414 public void testSimpleRules() {
415 try {
416 new FastIgnoreRule(null);
417 fail("Illegal input allowed!");
418 } catch (IllegalArgumentException e) {
419
420 }
421 assertFalse(new FastIgnoreRule("/").isMatch("/", false));
422 assertFalse(new FastIgnoreRule("//").isMatch("//", false));
423 assertFalse(new FastIgnoreRule("#").isMatch("#", false));
424 assertFalse(new FastIgnoreRule("").isMatch("", false));
425 assertFalse(new FastIgnoreRule(" ").isMatch(" ", false));
426 }
427
428 @Test
429 public void testSplit() {
430 try {
431 split("/", '/').toArray();
432 fail("should not allow single slash");
433 } catch (IllegalStateException e) {
434
435 }
436
437 assertArrayEquals(new String[] { "a", "b" }, split("a/b", '/')
438 .toArray());
439 assertArrayEquals(new String[] { "a", "b/" }, split("a/b/", '/')
440 .toArray());
441 assertArrayEquals(new String[] { "/a", "b" }, split("/a/b", '/')
442 .toArray());
443 assertArrayEquals(new String[] { "/a", "b/" }, split("/a/b/", '/')
444 .toArray());
445 assertArrayEquals(new String[] { "/a", "b", "c" }, split("/a/b/c", '/')
446 .toArray());
447 assertArrayEquals(new String[] { "/a", "b", "c/" },
448 split("/a/b/c/", '/').toArray());
449 }
450
451 public void assertMatched(String pattern, String path) {
452 boolean match = match(pattern, path);
453 String result = path + " is " + (match ? "ignored" : "not ignored")
454 + " via '" + pattern + "' rule";
455 if (!match) {
456 System.err.println(result);
457 }
458 assertTrue("Expected a match for: " + pattern + " with: " + path,
459 match);
460
461 if (pattern.startsWith("!")) {
462 pattern = pattern.substring(1);
463 } else {
464 pattern = "!" + pattern;
465 }
466 match = match(pattern, path);
467 assertFalse("Expected no match for: " + pattern + " with: " + path,
468 match);
469 }
470
471 public void assertNotMatched(String pattern, String path) {
472 boolean match = match(pattern, path);
473 String result = path + " is " + (match ? "ignored" : "not ignored")
474 + " via '" + pattern + "' rule";
475 if (match) {
476 System.err.println(result);
477 }
478 assertFalse("Expected no match for: " + pattern + " with: " + path,
479 match);
480
481 if (pattern.startsWith("!")) {
482 pattern = pattern.substring(1);
483 } else {
484 pattern = "!" + pattern;
485 }
486 match = match(pattern, path);
487 assertTrue("Expected a match for: " + pattern + " with: " + path,
488 match);
489 }
490
491
492
493
494
495
496
497
498
499
500
501 private boolean match(String pattern, String target) {
502 boolean isDirectory = target.endsWith("/");
503 FastIgnoreRule r = new FastIgnoreRule(pattern);
504
505
506 boolean match = r.isMatch(target, isDirectory);
507 if (r.getNegation())
508 match = !match;
509 return match;
510 }
511 }