This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-text.git
The following commit(s) were added to refs/heads/master by this push: new 2ac5d09 More tests, more edge cases. 2ac5d09 is described below commit 2ac5d09e862b096470164e47b72cd6c66379aa99 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Sat Jul 18 11:59:52 2020 -0400 More tests, more edge cases. --- .../commons/text/io/StringSubstitutorReader.java | 10 ++-- .../text/io/StringSubstitutorFilterReaderTest.java | 67 +++++++++++++++++++--- 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/apache/commons/text/io/StringSubstitutorReader.java b/src/main/java/org/apache/commons/text/io/StringSubstitutorReader.java index aea901c..35307d5 100644 --- a/src/main/java/org/apache/commons/text/io/StringSubstitutorReader.java +++ b/src/main/java/org/apache/commons/text/io/StringSubstitutorReader.java @@ -209,8 +209,8 @@ public class StringSubstitutorReader extends FilterReader { // read less than minReadLenPrefix, no variable possible final int drainCount = drain(target, targetIndex, targetLength); targetIndex += drainCount; - targetLength -= drainCount; - return eos && targetIndex == 0 ? EOS : targetIndex; + final int targetSize = targetIndex - targetIndexIn; + return eos && targetSize <= 0 ? EOS : targetSize; } if (eos) { // EOS @@ -218,8 +218,8 @@ public class StringSubstitutorReader extends FilterReader { toDrain = buffer.size(); final int drainCount = drain(target, targetIndex, targetLength); targetIndex += drainCount; - targetLength -= drainCount; - return eos && targetIndex == 0 ? EOS : targetIndex; + final int targetSize = targetIndex - targetIndexIn; + return eos && targetSize <= 0 ? EOS : targetSize; } // PREFIX // buffer and drain until we find a variable start, escaped or plain. @@ -301,7 +301,7 @@ public class StringSubstitutorReader extends FilterReader { // only drain up to what we've substituted toDrain = pos; drain(target, targetIndex, drainLen); - return targetIndex + drainLen; + return targetIndex - targetIndexIn + drainLen; } /** diff --git a/src/test/java/org/apache/commons/text/io/StringSubstitutorFilterReaderTest.java b/src/test/java/org/apache/commons/text/io/StringSubstitutorFilterReaderTest.java index 6559f19..fd246b8 100644 --- a/src/test/java/org/apache/commons/text/io/StringSubstitutorFilterReaderTest.java +++ b/src/test/java/org/apache/commons/text/io/StringSubstitutorFilterReaderTest.java @@ -56,10 +56,17 @@ public class StringSubstitutorFilterReaderTest extends StringSubstitutorTest { private void doTestNoReplaceInSteps(final String replaceTemplate, final StringSubstitutor substitutor) throws IOException { doTestReplaceInCharSteps(substitutor, replaceTemplate, replaceTemplate, false); - final int minStepSize = 1; - final int maxStepSize = 8192; - for (int stepSize = minStepSize; stepSize < maxStepSize; stepSize++) { - doTestReplaceInCharArraySteps(substitutor, replaceTemplate, replaceTemplate, false, stepSize); + final int minTargetSize = 1; + int maxTargetSize = 1024 * 8; + for (int targetSize = minTargetSize; targetSize <= maxTargetSize; targetSize++) { + doTestReplaceInCharArraySteps(substitutor, replaceTemplate, replaceTemplate, false, targetSize); + } + maxTargetSize = 400; + for (int targetSize = minTargetSize; targetSize <= maxTargetSize; targetSize++) { + for (int targetIndex = 0; targetIndex < targetSize; targetIndex++) { + doTestReplaceInCharArrayAtSteps(substitutor, replaceTemplate, replaceTemplate, false, targetIndex, + targetSize); + } } } @@ -70,16 +77,58 @@ public class StringSubstitutorFilterReaderTest extends StringSubstitutorTest { super.doTestReplace(sub, expectedResult, replaceTemplate, substring); } + private void doTestReplaceInCharArrayAtSteps(final StringSubstitutor substitutor, final String expectedResult, + final String replaceTemplate, final boolean substring, final int targetIndex, final int targetSize) + throws IOException { + final StringWriter actualResultWriter = new StringWriter(); + final StringWriter expectedResultWriter = new StringWriter(); + final AtomicInteger index = new AtomicInteger(); + final int expectedResultLen = StringUtils.length(expectedResult); + try (Reader expectedResultReader = toReader(expectedResult); + Reader actualReader = new StringSubstitutorReader(toReader(replaceTemplate), substitutor)) { + final char[] actualCh = new char[targetSize]; + final char[] expectedCh = new char[targetSize]; + int actualCount; + while ((actualCount = actualReader.read(actualCh, targetIndex, targetSize - targetIndex)) != -1) { + final int expectedCount = expectedResultReader.read(expectedCh, targetIndex, targetSize - targetIndex); + if (expectedCount != -1) { + expectedResultWriter.write(expectedCh, targetIndex, expectedCount); + } + // stream can chunk in smaller sizes + if (expectedCount == actualCount) { + assertEquals(expectedCount, actualCount, () -> String.format("Step size %,d", targetSize)); + assertArrayEquals(expectedCh, actualCh, + () -> String.format("[%,d] '%s' != '%s', result so far: \"%s\"", index.get(), + String.valueOf(expectedCh), String.valueOf(actualCh), actualResultWriter.toString())); + } else if (actualCount < expectedCount) { + assertTrue(expectedResultWriter.toString().startsWith(actualResultWriter.toString())); + } + if (actualCount != -1) { + actualResultWriter.write(actualCh, targetIndex, actualCount); + } else { + // fails + assertEquals(expectedCount, actualCount, () -> String.format("Step size %,d", targetSize)); + } + index.incrementAndGet(); + assertFalse(index.get() > expectedResultLen, () -> "Index: " + index.get()); + // simpler to debug if we zero out the buffers. + Arrays.fill(actualCh, (char) 0); + Arrays.fill(expectedCh, (char) 0); + } + } + assertEquals(Objects.toString(expectedResult, StringUtils.EMPTY), actualResultWriter.toString()); + } + private void doTestReplaceInCharArraySteps(final StringSubstitutor substitutor, final String expectedResult, - final String replaceTemplate, final boolean substring, final int stepSize) throws IOException { + final String replaceTemplate, final boolean substring, final int targetSize) throws IOException { final StringWriter actualResultWriter = new StringWriter(); final StringWriter expectedResultWriter = new StringWriter(); final AtomicInteger index = new AtomicInteger(); final int expectedResultLen = StringUtils.length(expectedResult); try (Reader expectedResultReader = toReader(expectedResult); Reader actualReader = new StringSubstitutorReader(toReader(replaceTemplate), substitutor)) { - final char[] actualCh = new char[stepSize]; - final char[] expectedCh = new char[stepSize]; + final char[] actualCh = new char[targetSize]; + final char[] expectedCh = new char[targetSize]; int actualCount; while ((actualCount = actualReader.read(actualCh)) != -1) { final int expectedCount = expectedResultReader.read(expectedCh); @@ -88,7 +137,7 @@ public class StringSubstitutorFilterReaderTest extends StringSubstitutorTest { } // stream can chunk in smaller sizes if (expectedCount == actualCount) { - assertEquals(expectedCount, actualCount, () -> String.format("Step size %,d", stepSize)); + assertEquals(expectedCount, actualCount, () -> String.format("Step size %,d", targetSize)); assertArrayEquals(expectedCh, actualCh, () -> String.format("[%,d] '%s' != '%s', result so far: \"%s\"", index.get(), String.valueOf(expectedCh), String.valueOf(actualCh), actualResultWriter.toString())); @@ -99,7 +148,7 @@ public class StringSubstitutorFilterReaderTest extends StringSubstitutorTest { actualResultWriter.write(actualCh, 0, actualCount); } else { // fails - assertEquals(expectedCount, actualCount, () -> String.format("Step size %,d", stepSize)); + assertEquals(expectedCount, actualCount, () -> String.format("Step size %,d", targetSize)); } index.incrementAndGet(); assertFalse(index.get() > expectedResultLen, () -> "Index: " + index.get());