1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.tests.java.util.regex;
19
20import java.util.regex.Matcher;
21import java.util.regex.Pattern;
22
23import junit.framework.TestCase;
24
25@SuppressWarnings("nls")
26public class MatcherTest extends TestCase {
27    String[] testPatterns = {
28            "(a|b)*abb",
29            "(1*2*3*4*)*567",
30            "(a|b|c|d)*aab",
31            "(1|2|3|4|5|6|7|8|9|0)(1|2|3|4|5|6|7|8|9|0)*",
32            "(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)*",
33            "(a|b)*(a|b)*A(a|b)*lice.*",
34            "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)(a|b|c|d|e|f|g|h|"
35                    + "i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)*(1|2|3|4|5|6|7|8|9|0)*|while|for|struct|if|do" };
36
37    String[] groupPatterns = { "(a|b)*aabb", "((a)|b)*aabb", "((a|b)*)a(abb)",
38            "(((a)|(b))*)aabb", "(((a)|(b))*)aa(b)b", "(((a)|(b))*)a(a(b)b)" };
39
40    public MatcherTest(String name) {
41        super(name);
42    }
43
44    public void testRegionsIntInt() {
45        Pattern p = Pattern.compile("x*");
46        Matcher m = p.matcher("axxxxxa");
47        assertFalse(m.matches());
48
49        m.region(1, 6);
50        assertEquals(1, m.regionStart());
51        assertEquals(6, m.regionEnd());
52        assertTrue(m.matches());
53
54        try {
55            m.region(1, 0);
56            fail("expected an IOOBE");
57        } catch(IndexOutOfBoundsException e) {
58        }
59
60        try {
61            m.region(-1, 2);
62            fail("expected an IOOBE");
63        } catch(IndexOutOfBoundsException e) {
64        }
65
66        try {
67            m.region(10, 11);
68            fail("expected an IOOBE");
69        } catch(IndexOutOfBoundsException e) {
70        }
71
72        try {
73            m.region(1, 10);
74            fail("expected an IOOBE");
75        } catch(IndexOutOfBoundsException e) {
76        }
77    }
78
79    public void testAppendReplacement() {
80        Pattern pat = Pattern.compile("XX");
81        Matcher m = pat.matcher("Today is XX-XX-XX ...");
82        StringBuffer sb = new StringBuffer();
83
84        for (int i = 0; m.find(); i++) {
85            m.appendReplacement(sb, new Integer(i * 10 + i).toString());
86        }
87        m.appendTail(sb);
88        assertEquals("Today is 0-11-22 ...", sb.toString());
89    }
90
91    public void testAppendReplacementRef() {
92        Pattern p = Pattern.compile("xx (rur|\\$)");
93        Matcher m = p.matcher("xx $ equals to xx rur.");
94        StringBuffer sb = new StringBuffer();
95        for (int i = 1; m.find(); i *= 30) {
96            String rep = new Integer(i).toString() + " $1";
97            m.appendReplacement(sb, rep);
98        }
99        m.appendTail(sb);
100        assertEquals("1 $ equals to 30 rur.", sb.toString());
101    }
102
103    public void testReplaceAll() {
104        String input = "aabfooaabfooabfoob";
105        String pattern = "a*b";
106        Pattern pat = Pattern.compile(pattern);
107        Matcher mat = pat.matcher(input);
108
109        assertEquals("-foo-foo-foo-", mat.replaceAll("-"));
110    }
111
112    /*
113     * Class under test for Matcher reset(CharSequence)
114     */
115    public void testResetCharSequence() {
116        Pattern p = Pattern.compile("abcd");
117        Matcher m = p.matcher("abcd");
118        assertTrue(m.matches());
119        m.reset("efgh");
120        assertFalse(m.matches());
121
122        try {
123            m.reset(null);
124            fail("expected a NPE");
125        } catch (NullPointerException e) {
126        }
127    }
128
129    public void testAppendSlashes() {
130        Pattern p = Pattern.compile("\\\\");
131        Matcher m = p.matcher("one\\cat\\two\\cats\\in\\the\\yard");
132        StringBuffer sb = new StringBuffer();
133        while (m.find()) {
134            m.appendReplacement(sb, "\\\\");
135        }
136        m.appendTail(sb);
137        assertEquals("one\\cat\\two\\cats\\in\\the\\yard", sb.toString());
138
139    }
140
141    public void testReplaceFirst() {
142        String input = "zzzdogzzzdogzzz";
143        String pattern = "dog";
144        Pattern pat = Pattern.compile(pattern);
145        Matcher mat = pat.matcher(input);
146
147        assertEquals("zzzcatzzzdogzzz", mat.replaceFirst("cat"));
148    }
149
150    public void testPattern() {
151        for (String element : testPatterns) {
152            Pattern test = Pattern.compile(element);
153            assertEquals(test, test.matcher("aaa").pattern());
154        }
155
156        for (String element : testPatterns) {
157            assertEquals(element, Pattern.compile(element).matcher("aaa")
158                    .pattern().toString());
159        }
160    }
161
162    /*
163     * Class under test for Matcher reset()
164     */
165    public void testReset() {
166    }
167
168    /*
169     * Class under test for String group(int)
170     */
171    public void testGroupint() {
172        String positiveTestString = "ababababbaaabb";
173
174        // test IndexOutOfBoundsException
175        // //
176        for (int i = 0; i < groupPatterns.length; i++) {
177            Pattern test = Pattern.compile(groupPatterns[i]);
178            Matcher mat = test.matcher(positiveTestString);
179            mat.matches();
180            try {
181                // groupPattern <index + 1> equals to number of groups
182                // of the specified pattern
183                // //
184                mat.group(i + 2);
185                fail("IndexOutBoundsException expected");
186                mat.group(i + 100);
187                fail("IndexOutBoundsException expected");
188                mat.group(-1);
189                fail("IndexOutBoundsException expected");
190                mat.group(-100);
191                fail("IndexOutBoundsException expected");
192            } catch (IndexOutOfBoundsException iobe) {
193            }
194        }
195
196        String[][] groupResults = { { "a" }, { "a", "a" },
197                { "ababababba", "a", "abb" }, { "ababababba", "a", "a", "b" },
198                { "ababababba", "a", "a", "b", "b" },
199                { "ababababba", "a", "a", "b", "abb", "b" }, };
200
201        for (int i = 0; i < groupPatterns.length; i++) {
202            Pattern test = Pattern.compile(groupPatterns[i]);
203            Matcher mat = test.matcher(positiveTestString);
204            mat.matches();
205            for (int j = 0; j < groupResults[i].length; j++) {
206                assertEquals("i: " + i + " j: " + j, groupResults[i][j], mat
207                        .group(j + 1));
208            }
209
210        }
211
212    }
213
214    public void testGroup() {
215        String positiveTestString = "ababababbaaabb";
216        String negativeTestString = "gjhfgdsjfhgcbv";
217        for (String element : groupPatterns) {
218            Pattern test = Pattern.compile(element);
219            Matcher mat = test.matcher(positiveTestString);
220            mat.matches();
221            // test result
222            assertEquals(positiveTestString, mat.group());
223
224            // test equal to group(0) result
225            assertEquals(mat.group(0), mat.group());
226        }
227
228        for (String element : groupPatterns) {
229            Pattern test = Pattern.compile(element);
230            Matcher mat = test.matcher(negativeTestString);
231            mat.matches();
232            try {
233                mat.group();
234                fail("IllegalStateException expected for <false> matches result");
235            } catch (IllegalStateException ise) {
236            }
237        }
238    }
239
240    public void testGroupPossessive() {
241        Pattern pat = Pattern.compile("((a)|(b))++c");
242        Matcher mat = pat.matcher("aac");
243
244        mat.matches();
245        assertEquals("a", mat.group(1));
246    }
247
248    /*
249     * Class under test for boolean find(int)
250     */
251    public void testFindint() {
252    }
253
254    /*
255     * Class under test for int start(int)
256     */
257    public void testStartint() {
258    }
259
260    /*
261     * Class under test for int end(int)
262     */
263    public void testEndint() {
264    }
265
266    public void testMatchesMisc() {
267        String[][] posSeq = {
268                { "abb", "ababb", "abababbababb", "abababbababbabababbbbbabb" },
269                { "213567", "12324567", "1234567", "213213567",
270                        "21312312312567", "444444567" },
271                { "abcdaab", "aab", "abaab", "cdaab", "acbdadcbaab" },
272                { "213234567", "3458", "0987654", "7689546432", "0398576",
273                        "98432", "5" },
274                {
275                        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
276                        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
277                                + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" },
278                { "ababbaAabababblice", "ababbaAliceababab", "ababbAabliceaaa",
279                        "abbbAbbbliceaaa", "Alice" },
280                { "a123", "bnxnvgds156", "for", "while", "if", "struct" }
281
282        };
283
284        for (int i = 0; i < testPatterns.length; i++) {
285            Pattern pat = Pattern.compile(testPatterns[i]);
286            for (int j = 0; j < posSeq[i].length; j++) {
287                Matcher mat = pat.matcher(posSeq[i][j]);
288                assertTrue("Incorrect match: " + testPatterns[i] + " vs "
289                        + posSeq[i][j], mat.matches());
290            }
291        }
292    }
293
294    public void testMatchesQuantifiers() {
295        String[] testPatternsSingles = { "a{5}", "a{2,4}", "a{3,}" };
296        String[] testPatternsMultiple = { "((a)|(b)){1,2}abb",
297                "((a)|(b)){2,4}", "((a)|(b)){3,}" };
298
299        String[][] stringSingles = { { "aaaaa", "aaa" },
300                { "aa", "a", "aaa", "aaaaaa", "aaaa", "aaaaa" },
301                { "aaa", "a", "aaaa", "aa" }, };
302
303        String[][] stringMultiples = { { "ababb", "aba" },
304                { "ab", "b", "bab", "ababa", "abba", "abababbb" },
305                { "aba", "b", "abaa", "ba" }, };
306
307        for (int i = 0; i < testPatternsSingles.length; i++) {
308            Pattern pat = Pattern.compile(testPatternsSingles[i]);
309            for (int j = 0; j < stringSingles.length / 2; j++) {
310                assertTrue("Match expected, but failed: " + pat.pattern()
311                        + " : " + stringSingles[i][j], pat.matcher(
312                        stringSingles[i][j * 2]).matches());
313                assertFalse("Match failure expected, but match succeed: "
314                        + pat.pattern() + " : " + stringSingles[i][j * 2 + 1],
315                        pat.matcher(stringSingles[i][j * 2 + 1]).matches());
316            }
317        }
318
319        for (int i = 0; i < testPatternsMultiple.length; i++) {
320            Pattern pat = Pattern.compile(testPatternsMultiple[i]);
321            for (int j = 0; j < stringMultiples.length / 2; j++) {
322                assertTrue("Match expected, but failed: " + pat.pattern()
323                        + " : " + stringMultiples[i][j], pat.matcher(
324                        stringMultiples[i][j * 2]).matches());
325                assertFalse(
326                        "Match failure expected, but match succeed: "
327                                + pat.pattern() + " : "
328                                + stringMultiples[i][j * 2 + 1], pat.matcher(
329                                stringMultiples[i][j * 2 + 1]).matches());
330            }
331        }
332    }
333
334    public void testQuantVsGroup() {
335        String patternString = "(d{1,3})((a|c)*)(d{1,3})((a|c)*)(d{1,3})";
336        String testString = "dacaacaacaaddaaacaacaaddd";
337
338        Pattern pat = Pattern.compile(patternString);
339        Matcher mat = pat.matcher(testString);
340
341        mat.matches();
342        assertEquals("dacaacaacaaddaaacaacaaddd", mat.group());
343        assertEquals("d", mat.group(1));
344        assertEquals("acaacaacaa", mat.group(2));
345        assertEquals("dd", mat.group(4));
346        assertEquals("aaacaacaa", mat.group(5));
347        assertEquals("ddd", mat.group(7));
348    }
349
350    public void testLookingAt() {
351    }
352
353    /*
354     * Class under test for boolean find()
355     */
356    public void testFind() {
357        String testPattern = "(abb)";
358        String testString = "cccabbabbabbabbabb";
359        Pattern pat = Pattern.compile(testPattern);
360        Matcher mat = pat.matcher(testString);
361        int start = 3;
362        int end = 6;
363        while (mat.find()) {
364            assertEquals(start, mat.start(1));
365            assertEquals(end, mat.end(1));
366
367            start = end;
368            end += 3;
369        }
370
371        testPattern = "(\\d{1,3})";
372        testString = "aaaa123456789045";
373
374        Pattern pat2 = Pattern.compile(testPattern);
375        Matcher mat2 = pat2.matcher(testString);
376        start = 4;
377        int length = 3;
378        while (mat2.find()) {
379            assertEquals(testString.substring(start, start + length), mat2
380                    .group(1));
381            start += length;
382        }
383    }
384
385    public void testSEOLsymbols() {
386        Pattern pat = Pattern.compile("^a\\(bb\\[$");
387        Matcher mat = pat.matcher("a(bb[");
388
389        assertTrue(mat.matches());
390    }
391
392    /*
393     * Class under test for int start()
394     */
395    public void testStart() {
396    }
397
398    public void testGroupCount() {
399        for (int i = 0; i < groupPatterns.length; i++) {
400            Pattern test = Pattern.compile(groupPatterns[i]);
401            Matcher mat = test.matcher("ababababbaaabb");
402            mat.matches();
403            assertEquals(i + 1, mat.groupCount());
404
405        }
406    }
407
408    public void testRelactantQuantifiers() {
409        Pattern pat = Pattern.compile("(ab*)*b");
410        Matcher mat = pat.matcher("abbbb");
411
412        if (mat.matches()) {
413            assertEquals("abbb", mat.group(1));
414        } else {
415            fail("Match expected: (ab*)*b vs abbbb");
416        }
417    }
418
419    public void testEnhancedFind() {
420        String input = "foob";
421        String pattern = "a*b";
422        Pattern pat = Pattern.compile(pattern);
423        Matcher mat = pat.matcher(input);
424
425        mat.find();
426        assertEquals("b", mat.group());
427    }
428
429    public void testPosCompositeGroup() {
430        String[] posExamples = { "aabbcc", "aacc", "bbaabbcc" };
431        String[] negExamples = { "aabb", "bb", "bbaabb" };
432        Pattern posPat = Pattern.compile("(aa|bb){1,3}+cc");
433        Pattern negPat = Pattern.compile("(aa|bb){1,3}+bb");
434
435        Matcher mat;
436        for (String element : posExamples) {
437            mat = posPat.matcher(element);
438            assertTrue(mat.matches());
439        }
440
441        for (String element : negExamples) {
442            mat = negPat.matcher(element);
443            assertFalse(mat.matches());
444        }
445
446        assertTrue(Pattern.matches("(aa|bb){1,3}+bb", "aabbaabb"));
447
448    }
449
450    public void testPosAltGroup() {
451        String[] posExamples = { "aacc", "bbcc", "cc" };
452        String[] negExamples = { "bb", "aa" };
453        Pattern posPat = Pattern.compile("(aa|bb)?+cc");
454        Pattern negPat = Pattern.compile("(aa|bb)?+bb");
455
456        Matcher mat;
457        for (String element : posExamples) {
458            mat = posPat.matcher(element);
459            assertTrue(posPat.toString() + " vs: " + element, mat.matches());
460        }
461
462        for (String element : negExamples) {
463            mat = negPat.matcher(element);
464            assertFalse(mat.matches());
465        }
466
467        assertTrue(Pattern.matches("(aa|bb)?+bb", "aabb"));
468    }
469
470    public void testRelCompGroup() {
471
472        Matcher mat;
473        Pattern pat;
474        String res = "";
475        for (int i = 0; i < 4; i++) {
476            pat = Pattern.compile("((aa|bb){" + i + ",3}?).*cc");
477            mat = pat.matcher("aaaaaacc");
478            assertTrue(pat.toString() + " vs: " + "aaaaaacc", mat.matches());
479            assertEquals(res, mat.group(1));
480            res += "aa";
481        }
482    }
483
484    public void testRelAltGroup() {
485
486        Matcher mat;
487        Pattern pat;
488
489        pat = Pattern.compile("((aa|bb)??).*cc");
490        mat = pat.matcher("aacc");
491        assertTrue(pat.toString() + " vs: " + "aacc", mat.matches());
492        assertEquals("", mat.group(1));
493
494        pat = Pattern.compile("((aa|bb)??)cc");
495        mat = pat.matcher("aacc");
496        assertTrue(pat.toString() + " vs: " + "aacc", mat.matches());
497        assertEquals("aa", mat.group(1));
498    }
499
500    public void testIgnoreCase() {
501        Pattern pat = Pattern.compile("(aa|bb)*", Pattern.CASE_INSENSITIVE);
502        Matcher mat = pat.matcher("aAbb");
503
504        assertTrue(mat.matches());
505
506        pat = Pattern.compile("(a|b|c|d|e)*", Pattern.CASE_INSENSITIVE);
507        mat = pat.matcher("aAebbAEaEdebbedEccEdebbedEaedaebEbdCCdbBDcdcdADa");
508        assertTrue(mat.matches());
509
510        pat = Pattern.compile("[a-e]*", Pattern.CASE_INSENSITIVE);
511        mat = pat.matcher("aAebbAEaEdebbedEccEdebbedEaedaebEbdCCdbBDcdcdADa");
512        assertTrue(mat.matches());
513
514    }
515
516    public void testQuoteReplacement() {
517        assertEquals("\\\\aaCC\\$1", Matcher.quoteReplacement("\\aaCC$1"));
518    }
519
520    public void testOverFlow() {
521        Pattern tp = Pattern.compile("(a*)*");
522        Matcher tm = tp.matcher("aaa");
523        assertTrue(tm.matches());
524        assertEquals("", tm.group(1));
525
526        assertTrue(Pattern.matches("(1+)\\1+", "11"));
527        assertTrue(Pattern.matches("(1+)(2*)\\2+", "11"));
528
529        Pattern pat = Pattern.compile("(1+)\\1*");
530        Matcher mat = pat.matcher("11");
531
532        assertTrue(mat.matches());
533        assertEquals("11", mat.group(1));
534
535        pat = Pattern.compile("((1+)|(2+))(\\2+)");
536        mat = pat.matcher("11");
537
538        assertTrue(mat.matches());
539        assertEquals("1", mat.group(2));
540        assertEquals("1", mat.group(1));
541        assertEquals("1", mat.group(4));
542        assertNull(mat.group(3));
543
544    }
545
546    public void testUnicode() {
547
548        assertTrue(Pattern.matches("\\x61a", "aa"));
549        assertTrue(Pattern.matches("\\u0061a", "aa"));
550        assertTrue(Pattern.matches("\\0141a", "aa"));
551        assertTrue(Pattern.matches("\\0777", "?7"));
552
553    }
554
555    public void testUnicodeCategory() {
556        assertTrue(Pattern.matches("\\p{Ll}", "k")); // Unicode lower case
557        assertTrue(Pattern.matches("\\P{Ll}", "K")); // Unicode non-lower
558        // case
559        assertTrue(Pattern.matches("\\p{Lu}", "K")); // Unicode upper case
560        assertTrue(Pattern.matches("\\P{Lu}", "k")); // Unicode non-upper
561        // case
562        // combinations
563        assertTrue(Pattern.matches("[\\p{L}&&[^\\p{Lu}]]", "k"));
564        assertTrue(Pattern.matches("[\\p{L}&&[^\\p{Ll}]]", "K"));
565        assertFalse(Pattern.matches("[\\p{L}&&[^\\p{Lu}]]", "K"));
566        assertFalse(Pattern.matches("[\\p{L}&&[^\\p{Ll}]]", "k"));
567
568        // category/character combinations
569        assertFalse(Pattern.matches("[\\p{L}&&[^a-z]]", "k"));
570        assertTrue(Pattern.matches("[\\p{L}&&[^a-z]]", "K"));
571
572        assertTrue(Pattern.matches("[\\p{Lu}a-z]", "k"));
573        assertTrue(Pattern.matches("[a-z\\p{Lu}]", "k"));
574
575        assertFalse(Pattern.matches("[\\p{Lu}a-d]", "k"));
576        assertTrue(Pattern.matches("[a-d\\p{Lu}]", "K"));
577
578        // assertTrue(Pattern.matches("[\\p{L}&&[^\\p{Lu}&&[^K]]]", "K"));
579        assertFalse(Pattern.matches("[\\p{L}&&[^\\p{Lu}&&[^G]]]", "K"));
580
581    }
582
583    public void testSplitEmpty() {
584
585        Pattern pat = Pattern.compile("");
586        String[] s = pat.split("", -1);
587
588        assertEquals(1, s.length);
589        assertEquals("", s[0]);
590    }
591
592    public void testFindDollar() {
593        Matcher mat = Pattern.compile("a$").matcher("a\n");
594        assertTrue(mat.find());
595        assertEquals("a", mat.group());
596    }
597
598    /*
599     * Verify if the Matcher can match the input when region is changed
600     */
601    public void testMatchesRegionChanged() {
602        // Regression for HARMONY-610
603        String input = " word ";
604        Pattern pattern = Pattern.compile("\\w+");
605        Matcher matcher = pattern.matcher(input);
606        matcher.region(1, 5);
607        assertTrue(matcher.matches());
608    }
609
610    public void testAllCodePoints() {
611        // Regression for HARMONY-3145
612        int[] codePoint = new int[1];
613        Pattern p = Pattern.compile("(\\p{all})+");
614        boolean res = true;
615        int cnt = 0;
616        String s;
617        for (int i = 0; i < 0x110000; i++) {
618            codePoint[0] = i;
619            s = new String(codePoint, 0, 1);
620            if (!s.matches(p.toString())) {
621                cnt++;
622                res = false;
623            }
624        }
625        assertTrue(res);
626        assertEquals(0, cnt);
627
628        p = Pattern.compile("(\\P{all})+");
629        res = true;
630        cnt = 0;
631
632        for (int i = 0; i < 0x110000; i++) {
633            codePoint[0] = i;
634            s = new String(codePoint, 0, 1);
635            if (!s.matches(p.toString())) {
636                cnt++;
637                res = false;
638            }
639        }
640
641        assertFalse(res);
642        assertEquals(0x110000, cnt);
643    }
644
645    /*
646     * Verify if the Matcher behaves correct when region is changed
647     */
648    public void testFindRegionChanged() {
649        // Regression for HARMONY-625
650        Pattern pattern = Pattern.compile("(?s).*");
651        Matcher matcher = pattern.matcher("abcde");
652        matcher.find();
653        assertEquals("abcde", matcher.group());
654
655        matcher = pattern.matcher("abcde");
656        matcher.region(0, 2);
657        matcher.find();
658        assertEquals("ab", matcher.group());
659
660    }
661
662    /*
663     * Verify if the Matcher behaves correct with pattern "c" when region is
664     * changed
665     */
666    public void testFindRegionChanged2() {
667        // Regression for HARMONY-713
668        Pattern pattern = Pattern.compile("c");
669
670        String inputStr = "aabb.c";
671        Matcher matcher = pattern.matcher(inputStr);
672        matcher.region(0, 3);
673
674        assertFalse(matcher.find());
675    }
676
677    /*
678     * Regression test for HARMONY-674
679     */
680    public void testPatternMatcher() throws Exception {
681        Pattern pattern = Pattern.compile("(?:\\d+)(?:pt)");
682        assertTrue(pattern.matcher("14pt").matches());
683    }
684
685    /**
686     * Inspired by HARMONY-3360
687     */
688    public void test3360() {
689        String str = "!\"#%&'(),-./";
690        Pattern p = Pattern.compile("\\s");
691        Matcher m = p.matcher(str);
692
693        assertFalse(m.find());
694    }
695
696    /**
697     * Regression test for HARMONY-3360
698     */
699    public void testGeneralPunctuationCategory() {
700        String[] s = { ",", "!", "\"", "#", "%", "&", "'", "(", ")", "-", ".",
701                "/" };
702        String regexp = "\\p{P}";
703
704        for (int i = 0; i < s.length; i++) {
705            Pattern pattern = Pattern.compile(regexp);
706            Matcher matcher = pattern.matcher(s[i]);
707            assertTrue(matcher.find());
708        }
709    }
710
711    /**
712     * Regression test for HARMONY-4396
713     */
714    public void testHitEndAfterFind() {
715        hitEndTest(true, "#01.0", "r((ege)|(geg))x", "regexx", false);
716        hitEndTest(true, "#01.1", "r((ege)|(geg))x", "regex", false);
717        hitEndTest(true, "#01.2", "r((ege)|(geg))x", "rege", true);
718        hitEndTest(true, "#01.2", "r((ege)|(geg))x", "xregexx", false);
719
720        hitEndTest(true, "#02.0", "regex", "rexreger", true);
721        hitEndTest(true, "#02.1", "regex", "raxregexr", false);
722
723        String floatRegex = getHexFloatRegex();
724        hitEndTest(true, "#03.0", floatRegex, Double.toHexString(-1.234d), true);
725        hitEndTest(true, "#03.1", floatRegex, "1 ABC"
726                + Double.toHexString(Double.NaN) + "buhuhu", false);
727        hitEndTest(true, "#03.2", floatRegex, Double.toHexString(-0.0) + "--",
728                false);
729        hitEndTest(true, "#03.3", floatRegex, "--"
730                + Double.toHexString(Double.MIN_VALUE) + "--", false);
731
732        hitEndTest(true, "#04.0", "(\\d+) fish (\\d+) fish (\\w+) fish (\\d+)",
733                "1 fish 2 fish red fish 5", true);
734        hitEndTest(true, "#04.1", "(\\d+) fish (\\d+) fish (\\w+) fish (\\d+)",
735                "----1 fish 2 fish red fish 5----", false);
736    }
737
738    /*
739     * Test if Matcher's toString conatain pattern information
740     */
741    public void testToString() {
742        String result = Pattern.compile("(\\d{1,3})").matcher(
743                "aaaa123456789045").toString();
744        assertTrue("The result doesn't contain pattern info", result
745                .contains("(\\d{1,3})"));
746    }
747
748    private void hitEndTest(boolean callFind, String testNo, String regex,
749            String input, boolean hit) {
750        Pattern pattern = Pattern.compile(regex);
751        Matcher matcher = pattern.matcher(input);
752        if (callFind) {
753            matcher.find();
754        } else {
755            matcher.matches();
756        }
757        boolean h = matcher.hitEnd();
758
759        assertTrue(testNo, h == hit);
760    }
761
762    private String getHexFloatRegex() {
763        String hexDecimal = "(-|\\+)?0[xX][0-9a-fA-F]*\\.[0-9a-fA-F]+([pP](-|\\+)?[0-9]+)?";
764        String notANumber = "((-|\\+)?Infinity)|([nN]a[nN])";
765        return new StringBuilder("((").append(hexDecimal).append(")|(").append(
766                notANumber).append("))").toString();
767    }
768}
769