diff --git a/README.md b/README.md index 71cca2d..068d2c2 100644 --- a/README.md +++ b/README.md @@ -220,7 +220,7 @@ void Scanner_reads_text_from_System_in( withTextFromSystemIn("first line", "second line") .execute(() -> { Scanner scanner = new Scanner(System.in); - scanner.nextLine(); + assertEquals("first line", scanner.nextLine()); assertEquals("second line", scanner.nextLine()); }); } diff --git a/src/main/java/com/github/stefanbirkner/systemlambda/SystemLambda.java b/src/main/java/com/github/stefanbirkner/systemlambda/SystemLambda.java index f6c28c8..fb33219 100644 --- a/src/main/java/com/github/stefanbirkner/systemlambda/SystemLambda.java +++ b/src/main/java/com/github/stefanbirkner/systemlambda/SystemLambda.java @@ -1,8 +1,10 @@ package com.github.stefanbirkner.systemlambda; +import javax.print.DocFlavor; import java.io.*; import java.lang.reflect.Field; import java.net.InetAddress; +import java.nio.charset.StandardCharsets; import java.security.Permission; import java.util.*; import java.util.concurrent.Callable; @@ -913,16 +915,16 @@ public void execute( private static class ReplacementInputStream extends InputStream { - private final StringReader reader; private final IOException ioException; private final RuntimeException runtimeException; + private final ByteArrayInputStream byteArrayInputStream; ReplacementInputStream( String text, IOException ioException, RuntimeException runtimeException ) { - this.reader = new StringReader(text); + this.byteArrayInputStream = new ByteArrayInputStream(text.getBytes(defaultCharset())); this.ioException = ioException; this.runtimeException = runtimeException; } @@ -930,12 +932,21 @@ private static class ReplacementInputStream extends InputStream { @Override public int read( ) throws IOException { - int character = reader.read(); + int character = byteArrayInputStream.read(); if (character == -1) handleEmptyReader(); return character; } + @Override + public int read(byte[] b, int off, int len) throws IOException { + int bytesRead = byteArrayInputStream.read(b, off, len); + if (len > 0 && bytesRead < 0) + handleEmptyReader(); + + return bytesRead; + } + private void handleEmptyReader( ) throws IOException { if (ioException != null) @@ -943,66 +954,6 @@ private void handleEmptyReader( else if (runtimeException != null) throw runtimeException; } - - @Override - public int read( - byte[] buffer, - int offset, - int len - ) throws IOException { - if (buffer == null) - throw new NullPointerException(); - else if (offset < 0 || len < 0 || len > buffer.length - offset) - throw new IndexOutOfBoundsException(); - else if (len == 0) - return 0; - else - return readNextLine(buffer, offset, len); - } - - private int readNextLine( - byte[] buffer, - int offset, - int len - ) throws IOException { - int c = read(); - if (c == -1) - return -1; - buffer[offset] = (byte) c; - - int i = 1; - for (; (i < len) && !isCompleteLineWritten(buffer, i - 1); ++i) { - byte read = (byte) read(); - if (read == -1) - break; - else - buffer[offset + i] = read; - } - return i; - } - - private boolean isCompleteLineWritten( - byte[] buffer, - int indexLastByteWritten - ) { - byte[] separator = getProperty("line.separator") - .getBytes(defaultCharset()); - int indexFirstByteOfSeparator = indexLastByteWritten - - separator.length + 1; - return indexFirstByteOfSeparator >= 0 - && contains(buffer, separator, indexFirstByteOfSeparator); - } - - private boolean contains( - byte[] array, - byte[] pattern, - int indexStart - ) { - for (int i = 0; i < pattern.length; ++i) - if (array[indexStart + i] != pattern[i]) - return false; - return true; - } } } diff --git a/src/test/java/com/github/stefanbirkner/systemlambda/WithTextFromSystemInTest.java b/src/test/java/com/github/stefanbirkner/systemlambda/WithTextFromSystemInTest.java index 69b1db4..3cb7bfa 100644 --- a/src/test/java/com/github/stefanbirkner/systemlambda/WithTextFromSystemInTest.java +++ b/src/test/java/com/github/stefanbirkner/systemlambda/WithTextFromSystemInTest.java @@ -37,18 +37,19 @@ static void checkArrayConstants() { @Test void provided_text_is_available_from_system_in( ) throws Exception { + AtomicReference firstLineCapture = new AtomicReference<>(); AtomicReference secondLineCapture = new AtomicReference<>(); withTextFromSystemIn( "first line", "second line" ).execute(() -> { - Scanner firstScanner = new Scanner(in); - firstScanner.nextLine(); - Scanner secondScanner = new Scanner(in); - secondLineCapture.set(secondScanner.nextLine()); + Scanner scanner = new Scanner(in); + firstLineCapture.set(scanner.nextLine()); + secondLineCapture.set(scanner.nextLine()); }); + assertThat(firstLineCapture).hasValue("first line"); assertThat(secondLineCapture).hasValue("second line"); } @@ -201,24 +202,24 @@ void system_in_throws_IndexOutOfBoundsException_when_read_is_called_with_oversiz } @Test - void system_in_reads_zero_bytes_even_if_mock_should_throw_IOException_on_input_end( + void system_in_reads_no_bytes_even_if_mock_should_throw_IOException_on_input_end( ) throws Exception { withTextFromSystemIn() .andExceptionThrownOnInputEnd(DUMMY_IO_EXCEPTION) .execute(() -> { int numBytesRead = System.in.read(DUMMY_ARRAY, VALID_OFFSET, 0); - assertThat(numBytesRead).isZero(); + assertThat(numBytesRead).isEqualTo(-1); }); } @Test - void system_in_reads_zero_bytes_even_if_mock_should_throw_RuntimeException_on_input_end( + void system_in_reads_no_bytes_even_if_mock_should_throw_RuntimeException_on_input_end( ) throws Exception { withTextFromSystemIn() .andExceptionThrownOnInputEnd(DUMMY_RUNTIME_EXCEPTION) .execute(() -> { int numBytesRead = System.in.read(DUMMY_ARRAY, VALID_OFFSET, 0); - assertThat(numBytesRead).isZero(); + assertThat(numBytesRead).isEqualTo(-1); }); }