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