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