OpenJDK / jigsaw / jake / jdk
changeset 8209:c30dc8e7744e
8024341: j.u.regex.Pattern.splitAsStream() doesn't correspond to split() method if using an example from the spec
Reviewed-by: alanb
author | psandoz |
---|---|
date | Fri, 20 Sep 2013 17:11:32 -0700 |
parents | 2552cd270350 |
children | 56d247821694 a3b17b91127d |
files | src/share/classes/java/util/regex/Pattern.java test/java/util/regex/PatternStreamTest.java test/java/util/regex/PatternTest.java |
diffstat | 3 files changed, 212 insertions(+), 156 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/util/regex/Pattern.java Fri Sep 20 15:12:05 2013 -0700 +++ b/src/share/classes/java/util/regex/Pattern.java Fri Sep 20 17:11:32 2013 -0700 @@ -5755,7 +5755,8 @@ * input sequence that is terminated by another subsequence that matches * this pattern or is terminated by the end of the input sequence. The * substrings in the stream are in the order in which they occur in the - * input. + * input. Trailing empty strings will be discarded and not encountered in + * the stream. * * <p> If this pattern does not match any subsequence of the input then * the resulting stream has just one element, namely the input sequence in @@ -5781,6 +5782,8 @@ private int current; // null if the next element, if any, needs to obtained private String nextElement; + // > 0 if there are N next empty elements + private int emptyElementCount; MatcherIterator() { this.matcher = matcher(input); @@ -5790,26 +5793,46 @@ if (!hasNext()) throw new NoSuchElementException(); - String n = nextElement; - nextElement = null; - return n; + if (emptyElementCount == 0) { + String n = nextElement; + nextElement = null; + return n; + } else { + emptyElementCount--; + return ""; + } } public boolean hasNext() { - if (nextElement != null) + if (nextElement != null || emptyElementCount > 0) return true; if (current == input.length()) return false; - if (matcher.find()) { + // Consume the next matching element + // Count sequence of matching empty elements + while (matcher.find()) { nextElement = input.subSequence(current, matcher.start()).toString(); current = matcher.end(); + if (!nextElement.isEmpty()) { + return true; + } else { + emptyElementCount++; + } + } + + // Consume last matching element + nextElement = input.subSequence(current, input.length()).toString(); + current = input.length(); + if (!nextElement.isEmpty()) { + return true; } else { - nextElement = input.subSequence(current, input.length()).toString(); - current = input.length(); + // Ignore a terminal sequence of matching empty elements + emptyElementCount = 0; + nextElement = null; + return false; } - return true; } } return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/regex/PatternStreamTest.java Fri Sep 20 17:11:32 2013 -0700 @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8016846 8024341 + * @summary Unit tests for wrapping classes should delegate to default methods + * @library ../stream/bootlib + * @build java.util.stream.OpTestCase + * @run testng/othervm PatternStreamTest + */ + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; +import java.util.regex.Pattern; +import java.util.stream.LambdaTestHelpers; +import java.util.stream.OpTestCase; +import java.util.stream.Stream; +import java.util.stream.TestData; + +@Test +public class PatternStreamTest extends OpTestCase { + + @DataProvider(name = "Stream<String>") + public static Object[][] makeStreamTestData() { + List<Object[]> data = new ArrayList<>(); + + String description = ""; + String input = "awgqwefg1fefw4vssv1vvv1"; + Pattern pattern = Pattern.compile("4"); + List<String> expected = new ArrayList<>(); + expected.add("awgqwefg1fefw"); + expected.add("vssv1vvv1"); + + // Must match the type signature of the consumer of this data, testStrings + // String, String, Pattern, List<String> + data.add(new Object[]{description, input, pattern, expected}); + + input = "afbfq\u00a3abgwgb\u00a3awngnwggw\u00a3a\u00a3ahjrnhneerh"; + pattern = Pattern.compile("\u00a3a"); + expected = new ArrayList<>(); + expected.add("afbfq"); + expected.add("bgwgb"); + expected.add("wngnwggw"); + expected.add(""); + expected.add("hjrnhneerh"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "awgqwefg1fefw4vssv1vvv1"; + pattern = Pattern.compile("1"); + expected = new ArrayList<>(); + expected.add("awgqwefg"); + expected.add("fefw4vssv"); + expected.add("vvv"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "a\u4ebafg1fefw\u4eba4\u9f9cvssv\u9f9c1v\u672c\u672cvv"; + pattern = Pattern.compile("1"); + expected = new ArrayList<>(); + expected.add("a\u4ebafg"); + expected.add("fefw\u4eba4\u9f9cvssv\u9f9c"); + expected.add("v\u672c\u672cvv"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "1\u56da23\u56da456\u56da7890"; + pattern = Pattern.compile("\u56da"); + expected = new ArrayList<>(); + expected.add("1"); + expected.add("23"); + expected.add("456"); + expected.add("7890"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = "1\u56da23\u9f9c\u672c\u672c\u56da456\u56da\u9f9c\u672c7890"; + pattern = Pattern.compile("\u56da"); + expected = new ArrayList<>(); + expected.add("1"); + expected.add("23\u9f9c\u672c\u672c"); + expected.add("456"); + expected.add("\u9f9c\u672c7890"); + + data.add(new Object[]{description, input, pattern, expected}); + + + input = ""; + pattern = Pattern.compile("\u56da"); + expected = new ArrayList<>(); + + data.add(new Object[]{description, input, pattern, expected}); + + + description = "Multiple separators"; + input = "This is,testing: with\tdifferent separators."; + pattern = Pattern.compile("[ \t,:.]"); + expected = new ArrayList<>(); + expected.add("This"); + expected.add("is"); + expected.add("testing"); + expected.add(""); + expected.add("with"); + expected.add("different"); + expected.add("separators"); + + + description = "Repeated separators within and at end"; + input = "boo:and:foo"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("b"); + expected.add(""); + expected.add(":and:f"); + + + description = "Many repeated separators within and at end"; + input = "booooo:and:fooooo"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("b"); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(":and:f"); + + description = "Many repeated separators before last match"; + input = "fooooo:"; + pattern = Pattern.compile("o"); + expected = new ArrayList<>(); + expected.add("f"); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(""); + expected.add(":"); + + data.add(new Object[] {description, input, pattern, expected}); + return data.toArray(new Object[0][]); + } + + @Test(dataProvider = "Stream<String>") + public void testStrings(String description, String input, Pattern pattern, List<String> expected) { + Supplier<Stream<String>> ss = () -> pattern.splitAsStream(input); + withData(TestData.Factory.ofSupplier(description, ss)) + .stream(LambdaTestHelpers.identity()) + .expectedResult(expected) + .exercise(); + } +}
--- a/test/java/util/regex/PatternTest.java Fri Sep 20 15:12:05 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test - * @summary Unit tests for wrapping classes should delegate to default methods - * @library ../stream/bootlib - * @build java.util.stream.OpTestCase - * @run testng/othervm PatternTest - */ - -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Supplier; -import java.util.regex.Pattern; -import java.util.stream.LambdaTestHelpers; -import java.util.stream.OpTestCase; -import java.util.stream.Stream; -import java.util.stream.TestData; - -@Test -public class PatternTest extends OpTestCase { - - @DataProvider(name = "Stream<String>") - public static Object[][] makeStreamTestData() { - List<Object[]> data = new ArrayList<>(); - - String description = ""; - String input = "awgqwefg1fefw4vssv1vvv1"; - Pattern pattern = Pattern.compile("4"); - List<String> expected = new ArrayList<>(); - expected.add("awgqwefg1fefw"); - expected.add("vssv1vvv1"); - - // Must match the type signature of the consumer of this data, testStrings - // String, String, Pattern, List<String> - data.add(new Object[]{description, input, pattern, expected}); - - input = "afbfq\u00a3abgwgb\u00a3awngnwggw\u00a3a\u00a3ahjrnhneerh"; - pattern = Pattern.compile("\u00a3a"); - expected = new ArrayList<>(); - expected.add("afbfq"); - expected.add("bgwgb"); - expected.add("wngnwggw"); - expected.add(""); - expected.add("hjrnhneerh"); - - data.add(new Object[]{description, input, pattern, expected}); - - - input = "awgqwefg1fefw4vssv1vvv1"; - pattern = Pattern.compile("1"); - expected = new ArrayList<>(); - expected.add("awgqwefg"); - expected.add("fefw4vssv"); - expected.add("vvv"); - - data.add(new Object[]{description, input, pattern, expected}); - - - input = "a\u4ebafg1fefw\u4eba4\u9f9cvssv\u9f9c1v\u672c\u672cvv"; - pattern = Pattern.compile("1"); - expected = new ArrayList<>(); - expected.add("a\u4ebafg"); - expected.add("fefw\u4eba4\u9f9cvssv\u9f9c"); - expected.add("v\u672c\u672cvv"); - - data.add(new Object[]{description, input, pattern, expected}); - - - input = "1\u56da23\u56da456\u56da7890"; - pattern = Pattern.compile("\u56da"); - expected = new ArrayList<>(); - expected.add("1"); - expected.add("23"); - expected.add("456"); - expected.add("7890"); - - data.add(new Object[]{description, input, pattern, expected}); - - - input = "1\u56da23\u9f9c\u672c\u672c\u56da456\u56da\u9f9c\u672c7890"; - pattern = Pattern.compile("\u56da"); - expected = new ArrayList<>(); - expected.add("1"); - expected.add("23\u9f9c\u672c\u672c"); - expected.add("456"); - expected.add("\u9f9c\u672c7890"); - - data.add(new Object[]{description, input, pattern, expected}); - - - input = ""; - pattern = Pattern.compile("\u56da"); - expected = new ArrayList<>(); - - data.add(new Object[]{description, input, pattern, expected}); - - - description = "Multiple separators"; - input = "This is,testing: with\tdifferent separators."; - pattern = Pattern.compile("[ \t,:.]"); - expected = new ArrayList<>(); - expected.add("This"); - expected.add("is"); - expected.add("testing"); - expected.add(""); - expected.add("with"); - expected.add("different"); - expected.add("separators"); - - data.add(new Object[] {description, input, pattern, expected}); - return data.toArray(new Object[0][]); - } - - @Test(dataProvider = "Stream<String>") - public void testStrings(String description, String input, Pattern pattern, List<String> expected) { - Supplier<Stream<String>> ss = () -> pattern.splitAsStream(input); - withData(TestData.Factory.ofSupplier(description, ss)) - .stream(LambdaTestHelpers.identity()) - .expectedResult(expected) - .exercise(); - } -}