Only build OutputCapture strings when necessary
Update `OutputCapture` so that expensive build operations are only performed when necessary. This update is especially important for Kotlin users calling `"Expected String" in output` since this results in a call to Kotlin's `CharSequence.contains` which calls the `length()` and `charAt()` methods many times. Closes gh-32033
This commit is contained in:
@@ -19,6 +19,7 @@ package org.springframework.boot.test.system;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -42,7 +43,7 @@ class OutputCaptureTests {
|
||||
|
||||
private TestPrintStream systemErr;
|
||||
|
||||
private OutputCapture output = new OutputCapture();
|
||||
private TestOutputCapture output = new TestOutputCapture();
|
||||
|
||||
@BeforeEach
|
||||
void replaceSystemStreams() {
|
||||
@@ -129,38 +130,69 @@ class OutputCaptureTests {
|
||||
|
||||
@Test
|
||||
void getAllReturnsAllCapturedOutput() {
|
||||
this.output.push();
|
||||
System.out.print("A");
|
||||
System.err.print("B");
|
||||
System.out.print("C");
|
||||
pushAndPrint();
|
||||
assertThat(this.output.getAll()).isEqualTo("ABC");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringReturnsAllCapturedOutput() {
|
||||
this.output.push();
|
||||
System.out.print("A");
|
||||
System.err.print("B");
|
||||
System.out.print("C");
|
||||
pushAndPrint();
|
||||
assertThat(this.output.toString()).isEqualTo("ABC");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getErrReturnsOnlyCapturedErrOutput() {
|
||||
this.output.push();
|
||||
System.out.print("A");
|
||||
System.err.print("B");
|
||||
System.out.print("C");
|
||||
pushAndPrint();
|
||||
assertThat(this.output.getErr()).isEqualTo("B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getOutReturnsOnlyCapturedOutOutput() {
|
||||
pushAndPrint();
|
||||
assertThat(this.output.getOut()).isEqualTo("AC");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllUsesCache() {
|
||||
pushAndPrint();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assertThat(this.output.getAll()).isEqualTo("ABC");
|
||||
}
|
||||
assertThat(this.output.buildCount).isEqualTo(1);
|
||||
System.out.print("X");
|
||||
assertThat(this.output.getAll()).isEqualTo("ABCX");
|
||||
assertThat(this.output.buildCount).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getOutUsesCache() {
|
||||
pushAndPrint();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assertThat(this.output.getOut()).isEqualTo("AC");
|
||||
}
|
||||
assertThat(this.output.buildCount).isEqualTo(1);
|
||||
System.out.print("X");
|
||||
assertThat(this.output.getOut()).isEqualTo("ACX");
|
||||
assertThat(this.output.buildCount).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getErrUsesCache() {
|
||||
pushAndPrint();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assertThat(this.output.getErr()).isEqualTo("B");
|
||||
}
|
||||
assertThat(this.output.buildCount).isEqualTo(1);
|
||||
System.err.print("X");
|
||||
assertThat(this.output.getErr()).isEqualTo("BX");
|
||||
assertThat(this.output.buildCount).isEqualTo(2);
|
||||
}
|
||||
|
||||
private void pushAndPrint() {
|
||||
this.output.push();
|
||||
System.out.print("A");
|
||||
System.err.print("B");
|
||||
System.out.print("C");
|
||||
assertThat(this.output.getOut()).isEqualTo("AC");
|
||||
}
|
||||
|
||||
static class TestPrintStream extends PrintStream {
|
||||
@@ -176,4 +208,16 @@ class OutputCaptureTests {
|
||||
|
||||
}
|
||||
|
||||
static class TestOutputCapture extends OutputCapture {
|
||||
|
||||
int buildCount;
|
||||
|
||||
@Override
|
||||
String build(Predicate<Type> filter) {
|
||||
this.buildCount++;
|
||||
return super.build(filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user