View Javadoc
1   /*
2    * Copyright (C) 2008, Florian Köberle <florianskarten@web.de> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  package org.eclipse.jgit.ignore;
11  
12  import static org.junit.Assert.assertEquals;
13  import static org.junit.Assume.assumeTrue;
14  
15  import org.junit.Test;
16  
17  @SuppressWarnings({ "boxing" })
18  public class IgnoreRuleSpecialCasesTest {
19  
20  	private void assertMatch(final String pattern, final String input,
21  			final boolean matchExpected, Boolean... assume) {
22  		boolean assumeDir = input.endsWith("/");
23  		FastIgnoreRule matcher = new FastIgnoreRule(pattern);
24  		if (assume.length == 0 || !assume[0].booleanValue()) {
25  			assertEquals(matchExpected, matcher.isMatch(input, assumeDir));
26  		} else {
27  			assumeTrue(matchExpected == matcher.isMatch(input, assumeDir));
28  		}
29  	}
30  
31  	private void assertFileNameMatch(final String pattern, final String input,
32  			final boolean matchExpected) {
33  		boolean assumeDir = input.endsWith("/");
34  		FastIgnoreRule matcher = new FastIgnoreRule(pattern);
35  		assertEquals(matchExpected, matcher.isMatch(input, assumeDir));
36  	}
37  
38  	@Test
39  	public void testVerySimplePatternCase0() throws Exception {
40  		assertMatch("", "", false);
41  	}
42  
43  	@Test
44  	public void testVerySimplePatternCase1() throws Exception {
45  		assertMatch("ab", "a", false);
46  	}
47  
48  	@Test
49  	public void testVerySimplePatternCase2() throws Exception {
50  		assertMatch("ab", "ab", true);
51  	}
52  
53  	@Test
54  	public void testVerySimplePatternCase3() throws Exception {
55  		assertMatch("ab", "ac", false);
56  	}
57  
58  	@Test
59  	public void testVerySimplePatternCase4() throws Exception {
60  		assertMatch("ab", "abc", false);
61  	}
62  
63  	@Test
64  	public void testVerySimpleWildcardCase0() throws Exception {
65  		assertMatch("?", "a", true);
66  	}
67  
68  	@Test
69  	public void testVerySimpleWildCardCase1() throws Exception {
70  		assertMatch("??", "a", false);
71  	}
72  
73  	@Test
74  	public void testVerySimpleWildCardCase2() throws Exception {
75  		assertMatch("??", "ab", true);
76  	}
77  
78  	@Test
79  	public void testVerySimpleWildCardCase3() throws Exception {
80  		assertMatch("??", "abc", false);
81  	}
82  
83  	@Test
84  	public void testVerySimpleStarCase0() throws Exception {
85  		// can't happen, but blank lines should never match
86  		assertMatch("*", "", false);
87  	}
88  
89  	@Test
90  	public void testVerySimpleStarCase1() throws Exception {
91  		assertMatch("*", "a", true);
92  	}
93  
94  	@Test
95  	public void testVerySimpleStarCase2() throws Exception {
96  		assertMatch("*", "ab", true);
97  	}
98  
99  	@Test
100 	public void testSimpleStarCase0() throws Exception {
101 		assertMatch("a*b", "a", false);
102 	}
103 
104 	@Test
105 	public void testSimpleStarCase1() throws Exception {
106 		assertMatch("a*c", "ac", true);
107 	}
108 
109 	@Test
110 	public void testSimpleStarCase2() throws Exception {
111 		assertMatch("a*c", "ab", false);
112 	}
113 
114 	@Test
115 	public void testSimpleStarCase3() throws Exception {
116 		assertMatch("a*c", "abc", true);
117 	}
118 
119 	@Test
120 	public void testManySolutionsCase0() throws Exception {
121 		assertMatch("a*a*a", "aaa", true);
122 	}
123 
124 	@Test
125 	public void testManySolutionsCase1() throws Exception {
126 		assertMatch("a*a*a", "aaaa", true);
127 	}
128 
129 	@Test
130 	public void testManySolutionsCase2() throws Exception {
131 		assertMatch("a*a*a", "ababa", true);
132 	}
133 
134 	@Test
135 	public void testManySolutionsCase3() throws Exception {
136 		assertMatch("a*a*a", "aaaaaaaa", true);
137 	}
138 
139 	@Test
140 	public void testManySolutionsCase4() throws Exception {
141 		assertMatch("a*a*a", "aaaaaaab", false);
142 	}
143 
144 	@Test
145 	public void testVerySimpleGroupCase0() throws Exception {
146 		assertMatch("[ab]", "a", true);
147 	}
148 
149 	@Test
150 	public void testVerySimpleGroupCase1() throws Exception {
151 		assertMatch("[ab]", "b", true);
152 	}
153 
154 	@Test
155 	public void testVerySimpleGroupCase2() throws Exception {
156 		assertMatch("[ab]", "ab", false);
157 	}
158 
159 	@Test
160 	public void testVerySimpleGroupRangeCase0() throws Exception {
161 		assertMatch("[b-d]", "a", false);
162 	}
163 
164 	@Test
165 	public void testVerySimpleGroupRangeCase1() throws Exception {
166 		assertMatch("[b-d]", "b", true);
167 	}
168 
169 	@Test
170 	public void testVerySimpleGroupRangeCase2() throws Exception {
171 		assertMatch("[b-d]", "c", true);
172 	}
173 
174 	@Test
175 	public void testVerySimpleGroupRangeCase3() throws Exception {
176 		assertMatch("[b-d]", "d", true);
177 	}
178 
179 	@Test
180 	public void testVerySimpleGroupRangeCase4() throws Exception {
181 		assertMatch("[b-d]", "e", false);
182 	}
183 
184 	@Test
185 	public void testVerySimpleGroupRangeCase5() throws Exception {
186 		assertMatch("[b-d]", "-", false);
187 	}
188 
189 	@Test
190 	public void testTwoGroupsCase0() throws Exception {
191 		assertMatch("[b-d][ab]", "bb", true);
192 	}
193 
194 	@Test
195 	public void testTwoGroupsCase1() throws Exception {
196 		assertMatch("[b-d][ab]", "ca", true);
197 	}
198 
199 	@Test
200 	public void testTwoGroupsCase2() throws Exception {
201 		assertMatch("[b-d][ab]", "fa", false);
202 	}
203 
204 	@Test
205 	public void testTwoGroupsCase3() throws Exception {
206 		assertMatch("[b-d][ab]", "bc", false);
207 	}
208 
209 	@Test
210 	public void testTwoRangesInOneGroupCase0() throws Exception {
211 		assertMatch("[b-ce-e]", "a", false);
212 	}
213 
214 	@Test
215 	public void testTwoRangesInOneGroupCase1() throws Exception {
216 		assertMatch("[b-ce-e]", "b", true);
217 	}
218 
219 	@Test
220 	public void testTwoRangesInOneGroupCase2() throws Exception {
221 		assertMatch("[b-ce-e]", "c", true);
222 	}
223 
224 	@Test
225 	public void testTwoRangesInOneGroupCase3() throws Exception {
226 		assertMatch("[b-ce-e]", "d", false);
227 	}
228 
229 	@Test
230 	public void testTwoRangesInOneGroupCase4() throws Exception {
231 		assertMatch("[b-ce-e]", "e", true);
232 	}
233 
234 	@Test
235 	public void testTwoRangesInOneGroupCase5() throws Exception {
236 		assertMatch("[b-ce-e]", "f", false);
237 	}
238 
239 	@Test
240 	public void testIncompleteRangesInOneGroupCase0() throws Exception {
241 		assertMatch("a[b-]", "ab", true);
242 	}
243 
244 	@Test
245 	public void testIncompleteRangesInOneGroupCase1() throws Exception {
246 		assertMatch("a[b-]", "ac", false);
247 	}
248 
249 	@Test
250 	public void testIncompleteRangesInOneGroupCase2() throws Exception {
251 		assertMatch("a[b-]", "a-", true);
252 	}
253 
254 	@Test
255 	public void testCombinedRangesInOneGroupCase0() throws Exception {
256 		assertMatch("[a-c-e]", "b", true);
257 	}
258 
259 	/**
260 	 * The c belongs to the range a-c. "-e" is no valid range so d should not
261 	 * match.
262 	 *
263 	 * @throws Exception
264 	 *             for some reasons
265 	 */
266 	@Test
267 	public void testCombinedRangesInOneGroupCase1() throws Exception {
268 		assertMatch("[a-c-e]", "d", false);
269 	}
270 
271 	@Test
272 	public void testCombinedRangesInOneGroupCase2() throws Exception {
273 		assertMatch("[a-c-e]", "e", true);
274 	}
275 
276 	@Test
277 	public void testInversedGroupCase0() throws Exception {
278 		assertMatch("[!b-c]", "a", true);
279 	}
280 
281 	@Test
282 	public void testInversedGroupCase1() throws Exception {
283 		assertMatch("[!b-c]", "b", false);
284 	}
285 
286 	@Test
287 	public void testInversedGroupCase2() throws Exception {
288 		assertMatch("[!b-c]", "c", false);
289 	}
290 
291 	@Test
292 	public void testInversedGroupCase3() throws Exception {
293 		assertMatch("[!b-c]", "d", true);
294 	}
295 
296 	@Test
297 	public void testAlphaGroupCase0() throws Exception {
298 		assertMatch("[[:alpha:]]", "d", true);
299 	}
300 
301 	@Test
302 	public void testAlphaGroupCase1() throws Exception {
303 		assertMatch("[[:alpha:]]", ":", false);
304 	}
305 
306 	@Test
307 	public void testAlphaGroupCase2() throws Exception {
308 		// \u00f6 = 'o' with dots on it
309 		assertMatch("[[:alpha:]]", "\u00f6", true);
310 	}
311 
312 	@Test
313 	public void test2AlphaGroupsCase0() throws Exception {
314 		// \u00f6 = 'o' with dots on it
315 		assertMatch("[[:alpha:]][[:alpha:]]", "a\u00f6", true);
316 		assertMatch("[[:alpha:]][[:alpha:]]", "a1", false);
317 	}
318 
319 	@Test
320 	public void testAlnumGroupCase0() throws Exception {
321 		assertMatch("[[:alnum:]]", "a", true);
322 	}
323 
324 	@Test
325 	public void testAlnumGroupCase1() throws Exception {
326 		assertMatch("[[:alnum:]]", "1", true);
327 	}
328 
329 	@Test
330 	public void testAlnumGroupCase2() throws Exception {
331 		assertMatch("[[:alnum:]]", ":", false);
332 	}
333 
334 	@Test
335 	public void testBlankGroupCase0() throws Exception {
336 		assertMatch("[[:blank:]]", " ", true);
337 	}
338 
339 	@Test
340 	public void testBlankGroupCase1() throws Exception {
341 		assertMatch("[[:blank:]]", "\t", true);
342 	}
343 
344 	@Test
345 	public void testBlankGroupCase2() throws Exception {
346 		assertMatch("[[:blank:]]", "\r", false);
347 	}
348 
349 	@Test
350 	public void testBlankGroupCase3() throws Exception {
351 		assertMatch("[[:blank:]]", "\n", false);
352 	}
353 
354 	@Test
355 	public void testBlankGroupCase4() throws Exception {
356 		assertMatch("[[:blank:]]", "a", false);
357 	}
358 
359 	@Test
360 	public void testCntrlGroupCase0() throws Exception {
361 		assertMatch("[[:cntrl:]]", "a", false);
362 	}
363 
364 	@Test
365 	public void testCntrlGroupCase1() throws Exception {
366 		assertMatch("[[:cntrl:]]", String.valueOf((char) 7), true);
367 	}
368 
369 	@Test
370 	public void testDigitGroupCase0() throws Exception {
371 		assertMatch("[[:digit:]]", "0", true);
372 	}
373 
374 	@Test
375 	public void testDigitGroupCase1() throws Exception {
376 		assertMatch("[[:digit:]]", "5", true);
377 	}
378 
379 	@Test
380 	public void testDigitGroupCase2() throws Exception {
381 		assertMatch("[[:digit:]]", "9", true);
382 	}
383 
384 	@Test
385 	public void testDigitGroupCase3() throws Exception {
386 		// \u06f9 = EXTENDED ARABIC-INDIC DIGIT NINE
387 		assertMatch("[[:digit:]]", "\u06f9", true);
388 	}
389 
390 	@Test
391 	public void testDigitGroupCase4() throws Exception {
392 		assertMatch("[[:digit:]]", "a", false);
393 	}
394 
395 	@Test
396 	public void testDigitGroupCase5() throws Exception {
397 		assertMatch("[[:digit:]]", "]", false);
398 	}
399 
400 	@Test
401 	public void testGraphGroupCase0() throws Exception {
402 		assertMatch("[[:graph:]]", "]", true);
403 	}
404 
405 	@Test
406 	public void testGraphGroupCase1() throws Exception {
407 		assertMatch("[[:graph:]]", "a", true);
408 	}
409 
410 	@Test
411 	public void testGraphGroupCase2() throws Exception {
412 		assertMatch("[[:graph:]]", ".", true);
413 	}
414 
415 	@Test
416 	public void testGraphGroupCase3() throws Exception {
417 		assertMatch("[[:graph:]]", "0", true);
418 	}
419 
420 	@Test
421 	public void testGraphGroupCase4() throws Exception {
422 		assertMatch("[[:graph:]]", " ", false);
423 	}
424 
425 	@Test
426 	public void testGraphGroupCase5() throws Exception {
427 		// \u00f6 = 'o' with dots on it
428 		assertMatch("[[:graph:]]", "\u00f6", true);
429 	}
430 
431 	@Test
432 	public void testLowerGroupCase0() throws Exception {
433 		assertMatch("[[:lower:]]", "a", true);
434 	}
435 
436 	@Test
437 	public void testLowerGroupCase1() throws Exception {
438 		assertMatch("[[:lower:]]", "h", true);
439 	}
440 
441 	@Test
442 	public void testLowerGroupCase2() throws Exception {
443 		assertMatch("[[:lower:]]", "A", false);
444 	}
445 
446 	@Test
447 	public void testLowerGroupCase3() throws Exception {
448 		assertMatch("[[:lower:]]", "H", false);
449 	}
450 
451 	@Test
452 	public void testLowerGroupCase4() throws Exception {
453 		// \u00e4 = small 'a' with dots on it
454 		assertMatch("[[:lower:]]", "\u00e4", true);
455 	}
456 
457 	@Test
458 	public void testLowerGroupCase5() throws Exception {
459 		assertMatch("[[:lower:]]", ".", false);
460 	}
461 
462 	@Test
463 	public void testPrintGroupCase0() throws Exception {
464 		assertMatch("[[:print:]]", "]", true);
465 	}
466 
467 	@Test
468 	public void testPrintGroupCase1() throws Exception {
469 		assertMatch("[[:print:]]", "a", true);
470 	}
471 
472 	@Test
473 	public void testPrintGroupCase2() throws Exception {
474 		assertMatch("[[:print:]]", ".", true);
475 	}
476 
477 	@Test
478 	public void testPrintGroupCase3() throws Exception {
479 		assertMatch("[[:print:]]", "0", true);
480 	}
481 
482 	@Test
483 	public void testPrintGroupCase4() throws Exception {
484 		assertMatch("[[:print:]]", " ", true);
485 	}
486 
487 	@Test
488 	public void testPrintGroupCase5() throws Exception {
489 		// \u00f6 = 'o' with dots on it
490 		assertMatch("[[:print:]]", "\u00f6", true);
491 	}
492 
493 	@Test
494 	public void testPunctGroupCase0() throws Exception {
495 		assertMatch("[[:punct:]]", ".", true);
496 	}
497 
498 	@Test
499 	public void testPunctGroupCase1() throws Exception {
500 		assertMatch("[[:punct:]]", "@", true);
501 	}
502 
503 	@Test
504 	public void testPunctGroupCase2() throws Exception {
505 		assertMatch("[[:punct:]]", " ", false);
506 	}
507 
508 	@Test
509 	public void testPunctGroupCase3() throws Exception {
510 		assertMatch("[[:punct:]]", "a", false);
511 	}
512 
513 	@Test
514 	public void testSpaceGroupCase0() throws Exception {
515 		assertMatch("[[:space:]]", " ", true);
516 	}
517 
518 	@Test
519 	public void testSpaceGroupCase1() throws Exception {
520 		assertMatch("[[:space:]]", "\t", true);
521 	}
522 
523 	@Test
524 	public void testSpaceGroupCase2() throws Exception {
525 		assertMatch("[[:space:]]", "\r", true);
526 	}
527 
528 	@Test
529 	public void testSpaceGroupCase3() throws Exception {
530 		assertMatch("[[:space:]]", "\n", true);
531 	}
532 
533 	@Test
534 	public void testSpaceGroupCase4() throws Exception {
535 		assertMatch("[[:space:]]", "a", false);
536 	}
537 
538 	@Test
539 	public void testUpperGroupCase0() throws Exception {
540 		assertMatch("[[:upper:]]", "a", false);
541 	}
542 
543 	@Test
544 	public void testUpperGroupCase1() throws Exception {
545 		assertMatch("[[:upper:]]", "h", false);
546 	}
547 
548 	@Test
549 	public void testUpperGroupCase2() throws Exception {
550 		assertMatch("[[:upper:]]", "A", true);
551 	}
552 
553 	@Test
554 	public void testUpperGroupCase3() throws Exception {
555 		assertMatch("[[:upper:]]", "H", true);
556 	}
557 
558 	@Test
559 	public void testUpperGroupCase4() throws Exception {
560 		// \u00c4 = 'A' with dots on it
561 		assertMatch("[[:upper:]]", "\u00c4", true);
562 	}
563 
564 	@Test
565 	public void testUpperGroupCase5() throws Exception {
566 		assertMatch("[[:upper:]]", ".", false);
567 	}
568 
569 	@Test
570 	public void testXDigitGroupCase0() throws Exception {
571 		assertMatch("[[:xdigit:]]", "a", true);
572 	}
573 
574 	@Test
575 	public void testXDigitGroupCase1() throws Exception {
576 		assertMatch("[[:xdigit:]]", "d", true);
577 	}
578 
579 	@Test
580 	public void testXDigitGroupCase2() throws Exception {
581 		assertMatch("[[:xdigit:]]", "f", true);
582 	}
583 
584 	@Test
585 	public void testXDigitGroupCase3() throws Exception {
586 		assertMatch("[[:xdigit:]]", "0", true);
587 	}
588 
589 	@Test
590 	public void testXDigitGroupCase4() throws Exception {
591 		assertMatch("[[:xdigit:]]", "5", true);
592 	}
593 
594 	@Test
595 	public void testXDigitGroupCase5() throws Exception {
596 		assertMatch("[[:xdigit:]]", "9", true);
597 	}
598 
599 	@Test
600 	public void testXDigitGroupCase6() throws Exception {
601 		assertMatch("[[:xdigit:]]", "۹", false);
602 	}
603 
604 	@Test
605 	public void testXDigitGroupCase7() throws Exception {
606 		assertMatch("[[:xdigit:]]", ".", false);
607 	}
608 
609 	@Test
610 	public void testWordGroupCase0() throws Exception {
611 		assertMatch("[[:word:]]", "g", true);
612 	}
613 
614 	@Test
615 	public void testWordGroupCase1() throws Exception {
616 		// \u00f6 = 'o' with dots on it
617 		assertMatch("[[:word:]]", "\u00f6", true);
618 	}
619 
620 	@Test
621 	public void testWordGroupCase2() throws Exception {
622 		assertMatch("[[:word:]]", "5", true);
623 	}
624 
625 	@Test
626 	public void testWordGroupCase3() throws Exception {
627 		assertMatch("[[:word:]]", "_", true);
628 	}
629 
630 	@Test
631 	public void testWordGroupCase4() throws Exception {
632 		assertMatch("[[:word:]]", " ", false);
633 	}
634 
635 	@Test
636 	public void testWordGroupCase5() throws Exception {
637 		assertMatch("[[:word:]]", ".", false);
638 	}
639 
640 	@Test
641 	public void testMixedGroupCase0() throws Exception {
642 		assertMatch("[A[:lower:]C3-5]", "A", true);
643 	}
644 
645 	@Test
646 	public void testMixedGroupCase1() throws Exception {
647 		assertMatch("[A[:lower:]C3-5]", "C", true);
648 	}
649 
650 	@Test
651 	public void testMixedGroupCase2() throws Exception {
652 		assertMatch("[A[:lower:]C3-5]", "e", true);
653 	}
654 
655 	@Test
656 	public void testMixedGroupCase3() throws Exception {
657 		assertMatch("[A[:lower:]C3-5]", "3", true);
658 	}
659 
660 	@Test
661 	public void testMixedGroupCase4() throws Exception {
662 		assertMatch("[A[:lower:]C3-5]", "4", true);
663 	}
664 
665 	@Test
666 	public void testMixedGroupCase5() throws Exception {
667 		assertMatch("[A[:lower:]C3-5]", "5", true);
668 	}
669 
670 	@Test
671 	public void testMixedGroupCase6() throws Exception {
672 		assertMatch("[A[:lower:]C3-5]", "B", false);
673 	}
674 
675 	@Test
676 	public void testMixedGroupCase7() throws Exception {
677 		assertMatch("[A[:lower:]C3-5]", "2", false);
678 	}
679 
680 	@Test
681 	public void testMixedGroupCase8() throws Exception {
682 		assertMatch("[A[:lower:]C3-5]", "6", false);
683 	}
684 
685 	@Test
686 	public void testMixedGroupCase9() throws Exception {
687 		assertMatch("[A[:lower:]C3-5]", ".", false);
688 	}
689 
690 	@Test
691 	public void testSpecialGroupCase0() throws Exception {
692 		assertMatch("[[]", "[", true);
693 	}
694 
695 	@Test
696 	public void testSpecialGroupCase1() throws Exception {
697 		assertMatch("[]]", "]", true);
698 	}
699 
700 	@Test
701 	public void testSpecialGroupCase2() throws Exception {
702 		assertMatch("[]a]", "]", true);
703 	}
704 
705 	@Test
706 	public void testSpecialGroupCase3() throws Exception {
707 		assertMatch("[a[]", "[", true);
708 	}
709 
710 	@Test
711 	public void testSpecialGroupCase4() throws Exception {
712 		assertMatch("[a[]", "a", true);
713 	}
714 
715 	@Test
716 	public void testSpecialGroupCase5() throws Exception {
717 		assertMatch("[!]]", "]", false);
718 	}
719 
720 	@Test
721 	public void testSpecialGroupCase6() throws Exception {
722 		assertMatch("[!]]", "x", true);
723 	}
724 
725 	@Test
726 	public void testSpecialGroupCase7() throws Exception {
727 		assertMatch("[:]]", ":]", true);
728 	}
729 
730 	@Test
731 	public void testSpecialGroupCase8() throws Exception {
732 		assertMatch("[:]]", ":", false);
733 	}
734 
735 	@Test
736 	public void testSpecialGroupCase9() throws Exception {
737 		assertMatch("][", "][", false);
738 	}
739 
740 	@Test
741 	public void testSpecialGroupCase10() throws Exception {
742 		// Second bracket is threated literally, so both [ and : should match
743 		assertMatch("[[:]", ":", true);
744 		assertMatch("[[:]", "[", true);
745 	}
746 
747 	@Test
748 	public void testUnsupportedGroupCase0() throws Exception {
749 		assertMatch("[[=a=]]", "a", false);
750 		assertMatch("[[=a=]]", "=", false);
751 		assertMatch("[=a=]", "a", true);
752 		assertMatch("[=a=]", "=", true);
753 	}
754 
755 	@Test
756 	public void testUnsupportedGroupCase01() throws Exception {
757 		assertMatch("[.a.]*[.a.]", "aha", true);
758 	}
759 
760 	@Test
761 	public void testUnsupportedGroupCase1() throws Exception {
762 		assertMatch("[[.a.]]", "a", false);
763 		assertMatch("[[.a.]]", ".", false);
764 		assertMatch("[.a.]", "a", true);
765 		assertMatch("[.a.]", ".", true);
766 	}
767 
768 	@Test
769 	public void testEscapedBracket1() throws Exception {
770 		assertMatch("\\[", "[", true);
771 	}
772 
773 	@Test
774 	public void testEscapedBracket2() throws Exception {
775 		assertMatch("\\[[a]", "[", false);
776 	}
777 
778 	@Test
779 	public void testEscapedBracket3() throws Exception {
780 		assertMatch("\\[[a]", "a", false);
781 	}
782 
783 	@Test
784 	public void testEscapedBracket4() throws Exception {
785 		assertMatch("\\[[a]", "[a", true);
786 	}
787 
788 	@Test
789 	public void testEscapedBracket5() throws Exception {
790 		assertMatch("[a\\]]", "]", true);
791 	}
792 
793 	@Test
794 	public void testEscapedBracket6() throws Exception {
795 		assertMatch("[a\\]]", "a", true);
796 	}
797 
798 	@Test
799 	public void testIgnoredBackslash() throws Exception {
800 		// In Git CLI a\b\c is equal to abc
801 		assertMatch("a\\b\\c", "abc", true);
802 	}
803 
804 	@Test
805 	public void testEscapedBackslash() throws Exception {
806 		// In Git CLI a\\b matches a\b file
807 		assertMatch("a\\\\b", "a\\b", true);
808 		assertMatch("a\\\\b\\c", "a\\bc", true);
809 
810 	}
811 
812 	@Test
813 	public void testEscapedExclamationMark() throws Exception {
814 		assertMatch("\\!b!.txt", "!b!.txt", true);
815 		assertMatch("a\\!b!.txt", "a!b!.txt", true);
816 	}
817 
818 	@Test
819 	public void testEscapedHash() throws Exception {
820 		assertMatch("\\#b", "#b", true);
821 		assertMatch("a\\#", "a#", true);
822 	}
823 
824 	@Test
825 	public void testEscapedTrailingSpaces() throws Exception {
826 		assertMatch("\\ ", " ", true);
827 		assertMatch("a\\ ", "a ", true);
828 	}
829 
830 	@Test
831 	public void testNotEscapingBackslash() throws Exception {
832 		assertMatch("\\out", "out", true);
833 		assertMatch("\\out", "a/out", true);
834 		assertMatch("c:\\/", "c:/", true);
835 		assertMatch("c:\\/", "a/c:/", true);
836 		assertMatch("c:\\tmp", "c:tmp", true);
837 		assertMatch("c:\\tmp", "a/c:tmp", true);
838 	}
839 
840 	@Test
841 	public void testMultipleEscapedCharacters1() throws Exception {
842 		assertMatch("\\]a?c\\*\\[d\\?\\]", "]abc*[d?]", true);
843 	}
844 
845 	@Test
846 	public void testBackslash() throws Exception {
847 		assertMatch("a\\", "a", true);
848 		assertMatch("\\a", "a", true);
849 		assertMatch("a/\\", "a/", true);
850 		assertMatch("a/b\\", "a/b", true);
851 		assertMatch("\\a/b", "a/b", true);
852 		assertMatch("/\\a", "/a", true);
853 		assertMatch("\\a\\b\\c\\", "abc", true);
854 		assertMatch("/\\a/\\b/\\c\\", "a/b/c", true);
855 
856 		// empty path segment doesn't match
857 		assertMatch("\\/a", "/a", false);
858 		assertMatch("\\/a", "a", false);
859 	}
860 
861 	@Test
862 	public void testDollar() throws Exception {
863 		assertMatch("$", "$", true);
864 		assertMatch("$x", "$x", true);
865 		assertMatch("$x", "x$", false);
866 		assertMatch("$x", "$", false);
867 
868 		assertMatch("$x.*", "$x.a", true);
869 		assertMatch("*$", "x$", true);
870 		assertMatch("*.$", "x.$", true);
871 
872 		assertMatch("$*x", "$ax", true);
873 		assertMatch("x*$", "xa$", true);
874 		assertMatch("x*$", "xa", false);
875 		assertMatch("[a$b]", "$", true);
876 	}
877 
878 	@Test
879 	public void testCaret() throws Exception {
880 		assertMatch("^", "^", true);
881 		assertMatch("^x", "^x", true);
882 		assertMatch("^x", "x^", false);
883 		assertMatch("^x", "^", false);
884 
885 		assertMatch("^x.*", "^x.a", true);
886 		assertMatch("*^", "x^", true);
887 		assertMatch("*.^", "x.^", true);
888 
889 		assertMatch("x*^", "xa^", true);
890 		assertMatch("^*x", "^ax", true);
891 		assertMatch("^*x", "ax", false);
892 		assertMatch("[a^b]", "^", true);
893 	}
894 
895 	@Test
896 	public void testPlus() throws Exception {
897 		assertMatch("+", "+", true);
898 		assertMatch("+x", "+x", true);
899 		assertMatch("+x", "x+", false);
900 		assertMatch("+x", "+", false);
901 		assertMatch("x+", "xx", false);
902 
903 		assertMatch("+x.*", "+x.a", true);
904 		assertMatch("*+", "x+", true);
905 		assertMatch("*.+", "x.+", true);
906 
907 		assertMatch("x*+", "xa+", true);
908 		assertMatch("+*x", "+ax", true);
909 		assertMatch("+*x", "ax", false);
910 		assertMatch("[a+b]", "+", true);
911 	}
912 
913 	@Test
914 	public void testPipe() throws Exception {
915 		assertMatch("|", "|", true);
916 		assertMatch("|x", "|x", true);
917 		assertMatch("|x", "x|", false);
918 		assertMatch("|x", "|", false);
919 		assertMatch("x|x", "xx", false);
920 
921 		assertMatch("x|x.*", "x|x.a", true);
922 		assertMatch("*|", "x|", true);
923 		assertMatch("*.|", "x.|", true);
924 
925 		assertMatch("x*|a", "xb|a", true);
926 		assertMatch("b|*x", "b|ax", true);
927 		assertMatch("b|*x", "ax", false);
928 		assertMatch("[a|b]", "|", true);
929 	}
930 
931 	@Test
932 	public void testBrackets() throws Exception {
933 		assertMatch("{}*()", "{}x()", true);
934 		assertMatch("[a{}()b][a{}()b]?[a{}()b][a{}()b]", "{}x()", true);
935 		assertMatch("x*{x}3", "xa{x}3", true);
936 		assertMatch("a*{x}3", "axxx", false);
937 
938 		assertMatch("?", "[", true);
939 		assertMatch("*", "[", true);
940 
941 		// Escaped bracket matches, but see weird things below...
942 		assertMatch("\\[", "[", true);
943 	}
944 
945 	/**
946 	 * The ignore rules here <b>do not match</b> any paths because single '['
947 	 * begins character group and the entire rule cannot be parsed due the
948 	 * invalid glob pattern. See
949 	 * http://article.gmane.org/gmane.comp.version-control.git/278699.
950 	 *
951 	 * @throws Exception
952 	 */
953 	@Test
954 	public void testBracketsUnmatched1() throws Exception {
955 		assertMatch("[", "[", false);
956 		assertMatch("[*", "[", false);
957 		assertMatch("*[", "[", false);
958 		assertMatch("*[", "a[", false);
959 		assertMatch("[a][", "a[", false);
960 		assertMatch("*[", "a", false);
961 		assertMatch("[a", "a", false);
962 		assertMatch("[*", "a", false);
963 		assertMatch("[*a", "a", false);
964 	}
965 
966 	/**
967 	 * Single ']' is treated here literally, not as an and of a character group
968 	 *
969 	 * @throws Exception
970 	 */
971 	@Test
972 	public void testBracketsUnmatched2() throws Exception {
973 		assertMatch("*]", "a", false);
974 		assertMatch("]a", "a", false);
975 		assertMatch("]*", "a", false);
976 		assertMatch("]*a", "a", false);
977 
978 		assertMatch("]", "]", true);
979 		assertMatch("]*", "]", true);
980 		assertMatch("]*", "]a", true);
981 		assertMatch("*]", "]", true);
982 		assertMatch("*]", "a]", true);
983 	}
984 
985 	@Test
986 	public void testBracketsRandom() throws Exception {
987 		assertMatch("[\\]", "[$0+//r4a\\d]", false);
988 		assertMatch("[:]]sZX]", "[:]]sZX]", false);
989 		assertMatch("[:]]:]]]", "[:]]:]]]", false);
990 	}
991 
992 	@Test
993 	public void testFilePathSimpleCase() throws Exception {
994 		assertFileNameMatch("a/b", "a/b", true);
995 	}
996 
997 	@Test
998 	public void testFilePathCase0() throws Exception {
999 		assertFileNameMatch("a*b", "a/b", false);
1000 	}
1001 
1002 	@Test
1003 	public void testFilePathCase1() throws Exception {
1004 		assertFileNameMatch("a?b", "a/b", false);
1005 	}
1006 
1007 	@Test
1008 	public void testFilePathCase2() throws Exception {
1009 		assertFileNameMatch("a*b", "a\\b", true);
1010 	}
1011 
1012 	@Test
1013 	public void testFilePathCase3() throws Exception {
1014 		assertFileNameMatch("a?b", "a\\b", true);
1015 	}
1016 
1017 }