All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.robtimus.junit.support.io.WriterDelegateTests Maven / Gradle / Ivy

/*
 * WriterDelegateTests.java
 * Copyright 2020 Rob Spoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.robtimus.junit.support.io;

import static com.github.robtimus.junit.support.io.IOAssertions.assertDoesNotThrowIOException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.either;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.params.provider.Arguments.arguments;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.CharBuffer;
import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.Stream;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;

/**
 * Base interface for testing that {@link Writer} implementations correctly delegate to another {@link Writer}.
 *
 * @author Rob Spoor
 */
public interface WriterDelegateTests {

    /**
     * Creates the writer to test.
     * 

* This method will be called only once for each test. This makes it possible to capture the writer to test and its delegate, and perform * additional tests after the pre-defined test has finished. * * @param delegate The delegate to test against. * @return The created writer. */ Writer wrapWriter(Writer delegate); /** * Returns the expected content written to a delegate, based on the content that was written to a {@link #wrapWriter(Writer) created writer}. * * @param written The content that was written. * @return The expected content. */ String expectedContent(String written); /** * Returns the content to write for most tests. This default implementation returns a lorem ipsum text. * * @return The content to write. */ default String contentToWrite() { return "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa."; //$NON-NLS-1$ } /** * Returns the content to write when testing writing large pieces of text. this default implementation returns {@link #contentToWrite()} * concatenated {@code 1000} times. * * @return The content to write when testing writing large pieces of text. */ default String longContentToWrite() { String content = contentToWrite(); StringBuilder sb = new StringBuilder(1000 * content.length()); for (int i = 0; i < 1000; i++) { sb.append(content); } return sb.toString(); } /** * Contains tests for {@link Writer#write(int)}. * * @author Rob Spoor */ @DisplayName("write(int)") interface WriteCharTests extends WriterDelegateTests { @Test @DisplayName("write(int)") default void testWriteChar() { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(content); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { for (int i = 0; i < content.length(); i++) { writer.write(content.charAt(i)); } } assertEquals(expectedContent, delegate.toString()); }); } } /** * Contains tests for {@link Writer#write(char[])}. * * @author Rob Spoor */ @DisplayName("write(char[])") interface WriteCharArrayTests extends WriterDelegateTests { @Test @DisplayName("write(char[])") default void testWriteCharArray() { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(content); int bufferSize = 10; char[] chars = content.toCharArray(); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { for (int i = 0; i < chars.length; i += bufferSize) { writer.write(Arrays.copyOfRange(chars, i, Math.min(i + bufferSize, chars.length))); } } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(char[]) with a large array") default void testWriteCharArrayWithLargeArray() { assertDoesNotThrowIOException(() -> { String content = longContentToWrite(); String expectedContent = expectedContent(content); char[] chars = content.toCharArray(); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { writer.write(chars); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(char[]) with an empty array") default void testWriteCharArrayWithEmptyArray() { assertDoesNotThrowIOException(() -> { String expectedContent = expectedContent(""); //$NON-NLS-1$ char[] chars = {}; StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { writer.write(chars); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(char[]) with a null array") default void testWriteCharArrayWithNullArray() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { char[] buffer = null; assertThrows(NullPointerException.class, () -> writer.write(buffer)); } assertEquals(expectedContent, delegate.toString()); }); } } /** * Contains tests for {@link Writer#write(char[], int, int)}. * * @author Rob Spoor */ @DisplayName("write(char[], int, int)") interface WriteCharArrayPortionTests extends WriterDelegateTests { @Test @DisplayName("write(char[], int, int)") default void testWriteCharArrayPortion() { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(content); int bufferSize = 10; char[] chars = content.toCharArray(); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { for (int i = 0; i < chars.length; i += bufferSize) { writer.write(chars, i, Math.min(bufferSize, chars.length - i)); } } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(char[], int, int) with a large array") default void testWriteCharArrayPortionWithLargeArray() { assertDoesNotThrowIOException(() -> { String content = longContentToWrite(); String expectedContent = expectedContent(content); char[] chars = content.toCharArray(); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { writer.write(chars, 0, chars.length); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(char[], int, int) with a null array") default void testWriteCharArrayPortionWithNullArray() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { char[] buffer = null; assertThrows(NullPointerException.class, () -> writer.write(buffer, 0, 10)); } // assert that nothing was written assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(char[], int, int) with 0 length") default void testWriteCharArrayPortionWithZeroLength() { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(""); //$NON-NLS-1$ char[] chars = content.toCharArray(); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { writer.write(chars, 5, 0); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(char[], int, int) with a negative offset") default void testWriteCharArrayPortionWithNegativeOffset() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { char[] buffer = new char[10]; Exception exception = assertThrows(Exception.class, () -> writer.write(buffer, -1, 10)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(char[], int, int) with an offset that exceeds the array length") default void testWriteCharArrayPortionWithTooHighOffset() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { char[] buffer = new char[10]; Exception exception = assertThrows(Exception.class, () -> writer.write(buffer, buffer.length + 1, 0)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(char[], int, int) with a negative length") default void testWriteCharArrayPortionWithNegativeLength() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { char[] buffer = new char[10]; Exception exception = assertThrows(Exception.class, () -> writer.write(buffer, 5, -1)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(char[], int, int) with a length that exceeds the array length") default void testWriteCharArrayPortionWithTooHighLength() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { char[] buffer = new char[10]; // don't use 0 and 11, use 1 and 10, so it's not the value of the length that triggers the error but the combination off + len Exception exception = assertThrows(Exception.class, () -> writer.write(buffer, 1, buffer.length)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } } /** * Contains tests for {@link Writer#write(String)}. * * @author Rob Spoor */ @DisplayName("write(String)") interface WriteStringTests extends WriterDelegateTests { @Test @DisplayName("write(String)") default void testWriteString() { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(content); int bufferSize = 10; StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { for (int i = 0; i < content.length(); i += bufferSize) { writer.write(content.substring(i, Math.min(i + bufferSize, content.length()))); } } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(String) with a large String") default void testWriteStringWithLargeString() { assertDoesNotThrowIOException(() -> { String content = longContentToWrite(); String expectedContent = expectedContent(content); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { writer.write(content); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(String) with an empty String") default void testWriteStringWithEmptyString() { assertDoesNotThrowIOException(() -> { String expectedContent = expectedContent(""); //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { writer.write(""); //$NON-NLS-1$ } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(String) with a null String") default void testWriteStringWithNullString() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = null; assertThrows(NullPointerException.class, () -> writer.write(string)); } assertEquals(expectedContent, delegate.toString()); }); } } /** * Contains tests for {@link Writer#write(String, int, int)}. * * @author Rob Spoor */ @DisplayName("write(String, int, int)") interface WriteStringPortionTests extends WriterDelegateTests { @Test @DisplayName("write(String, int, int)") default void testWriteStringPortion() { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(content); int bufferSize = 10; StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { for (int i = 0; i < content.length(); i += bufferSize) { writer.write(content, i, Math.min(bufferSize, content.length() - i)); } } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(String, int, int) with a large String") default void testWriteStringPortionWithLargeString() { assertDoesNotThrowIOException(() -> { String content = longContentToWrite(); String expectedContent = expectedContent(content); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { writer.write(content, 0, content.length()); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(String, int, int) with a null String") default void testWriteStringPortionWithNullString() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = null; assertThrows(NullPointerException.class, () -> writer.write(string, 0, 10)); } // assert that nothing was written assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(String, int, int) with 0 length") default void testWriteStringPortionWithZeroLength() { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(""); //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { writer.write(content, 5, 0); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(String, int, int) with a negative offset") default void testWriteStringPortionWithNegativeOffset() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = "0123456789"; //$NON-NLS-1$ Exception exception = assertThrows(Exception.class, () -> writer.write(string, -1, 10)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(String, int, int) with an offset that exceeds the String length") default void testWriteStringPortionWithTooHighOffset() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = "0123456789"; //$NON-NLS-1$ Exception exception = assertThrows(Exception.class, () -> writer.write(string, string.length() + 1, 0)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(String, int, int) with a negative length") default void testWriteStringPortionWithNegativeLength() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = "0123456789"; //$NON-NLS-1$ Exception exception = assertThrows(Exception.class, () -> writer.write(string, 5, -1)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("write(String, int, int) with a length that exceeds the String length") default void testWriteStringPortionWithTooHighLength() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = "0123456789"; //$NON-NLS-1$ // don't use 0 and 11, use 1 and 10, so it's not the value of the length that triggers the error but the combination off + len Exception exception = assertThrows(Exception.class, () -> writer.write(string, 1, string.length())); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } } /** * Contains tests for {@link Writer#append(CharSequence)}. * * @author Rob Spoor */ @DisplayName("append(CharSequence)") interface AppendCharSequenceTests extends WriterDelegateTests { @ParameterizedTest(name = "type: {0}") @ArgumentsSource(CharSequenceTransformationProvider.class) @DisplayName("append(CharSequence)") default void testAppendCharSequence(@SuppressWarnings("unused") String type, Function contentTransformation) { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(content); int bufferSize = 10; StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { for (int i = 0; i < content.length(); i += bufferSize) { String portion = content.substring(i, Math.min(i + bufferSize, content.length())); assertSame(writer, writer.append(contentTransformation.apply(portion))); } } assertEquals(expectedContent, delegate.toString()); }); } @ParameterizedTest(name = "type: {0}") @ArgumentsSource(CharSequenceTransformationProvider.class) @DisplayName("append(CharSequence) with a large CharSequence") default void testAppendCharSequenceWithLargeCharSequence(@SuppressWarnings("unused") String type, Function contentTransformation) { assertDoesNotThrowIOException(() -> { String content = longContentToWrite(); String expectedContent = expectedContent(content); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { assertSame(writer, writer.append(contentTransformation.apply(content))); } assertEquals(expectedContent, delegate.toString()); }); } @ParameterizedTest(name = "type: {0}") @ArgumentsSource(CharSequenceTransformationProvider.class) @DisplayName("append(CharSequence) with an empty CharSequence") default void testAppendCharSequenceWithEmptyCharSequence(@SuppressWarnings("unused") String type, Function contentTransformation) { assertDoesNotThrowIOException(() -> { String expectedContent = expectedContent(""); //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { assertSame(writer, writer.append(contentTransformation.apply(""))); //$NON-NLS-1$ } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("append(CharSequence) with a null CharSequence") default void testAppendCharSequenceWithNullCharSequence() { assertDoesNotThrowIOException(() -> { String expectedContent = expectedContent("null"); //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { assertSame(writer, writer.append(null)); } assertEquals(expectedContent, delegate.toString()); }); } } /** * Contains tests for {@link Writer#append(CharSequence, int, int)}. * * @author Rob Spoor */ @DisplayName("append(CharSequence, int, int)") interface AppendCharSequencePortionTests extends WriterDelegateTests { @ParameterizedTest(name = "type: {0}") @ArgumentsSource(CharSequenceTransformationProvider.class) @DisplayName("append(CharSequence, int, int)") default void testAppendCharSequencePortion(@SuppressWarnings("unused") String type, Function contentTransformation) { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(content); int bufferSize = 10; StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { for (int i = 0; i < content.length(); i += bufferSize) { assertSame(writer, writer.append(contentTransformation.apply(content), i, Math.min(i + bufferSize, content.length()))); } } assertEquals(expectedContent, delegate.toString()); }); } @ParameterizedTest(name = "type: {0}") @ArgumentsSource(CharSequenceTransformationProvider.class) @DisplayName("append(CharSequence, int, int) with a large CharSequence") default void testAppendCharSequencePortionWithLargeCharSequence(@SuppressWarnings("unused") String type, Function contentTransformation) { assertDoesNotThrowIOException(() -> { String content = longContentToWrite(); String expectedContent = expectedContent(content); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { assertSame(writer, writer.append(contentTransformation.apply(content), 0, content.length())); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("append(CharSequence, int, int) with a null CharSequence") default void testAppendCharSequencePortionWithNullCharSequence() { assertDoesNotThrowIOException(() -> { String expectedContent = expectedContent("ul"); //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { assertSame(writer, writer.append(null, 1, 3)); } // assert that nothing was written assertEquals(expectedContent, delegate.toString()); }); } @ParameterizedTest(name = "type: {0}") @ArgumentsSource(CharSequenceTransformationProvider.class) @DisplayName("append(CharSequence, int, int) with start equal to end") default void testAppendCharSequencePortionWithStartEqualToEnd(@SuppressWarnings("unused") String type, Function contentTransformation) { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(""); //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { assertSame(writer, writer.append(contentTransformation.apply(content), 5, 5)); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("append(CharSequence, int, int) with a negative start") default void testAppendCharSequencePortionWithNegativeStart() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = "0123456789"; //$NON-NLS-1$ Exception exception = assertThrows(Exception.class, () -> writer.append(string, -1, 10)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("append(CharSequence, int, int) with a start that exceeds the CharSequence length") default void testAppendCharSequencePortionWithTooHighStart() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = "0123456789"; //$NON-NLS-1$ Exception exception = assertThrows(Exception.class, () -> writer.append(string, string.length() + 1, 0)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("append(CharSequence, int, int) with a negative end") default void testAppendCharSequencePortionWithNegativeEnd() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = "0123456789"; //$NON-NLS-1$ Exception exception = assertThrows(Exception.class, () -> writer.append(string, 0, -1)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("append(CharSequence, int, int) with an end that's smaller than the start") default void testAppendCharSequencePortionWithEndSmallerThanStart() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = "0123456789"; //$NON-NLS-1$ Exception exception = assertThrows(Exception.class, () -> writer.append(string, 5, 4)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } @Test @DisplayName("append(CharSequence, int, int) with an end that exceeds the CharSequence length") default void testAppendCharSequencePortionWithTooHighEnd() { assertDoesNotThrowIOException(() -> { String expectedContent = ""; //$NON-NLS-1$ StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { String string = "0123456789"; //$NON-NLS-1$ Exception exception = assertThrows(Exception.class, () -> writer.append(string, 1, string.length() + 1)); assertThat(exception, either(instanceOf(IndexOutOfBoundsException.class)).or(instanceOf(IllegalArgumentException.class)) .or(instanceOf(IOException.class))); } assertEquals(expectedContent, delegate.toString()); }); } } /** * Contains tests for {@link Writer#append(char)}. * * @author Rob Spoor */ @DisplayName("append(Char)") interface AppendCharTests extends WriterDelegateTests { @Test @DisplayName("append(char)") default void testAppendChar() { assertDoesNotThrowIOException(() -> { String content = contentToWrite(); String expectedContent = expectedContent(content); StringWriter delegate = new StringWriter(expectedContent.length()); try (Writer writer = wrapWriter(delegate)) { for (int i = 0; i < content.length(); i++) { assertSame(writer, writer.append(content.charAt(i))); } } assertEquals(expectedContent, delegate.toString()); }); } } /** * Contains tests for {@link Writer#flush()}. * * @author Rob Spoor */ @DisplayName("flush()") interface FlushTests extends WriterDelegateTests { @Test @DisplayName("flush() delegates") @SuppressWarnings("resource") default void testFlushDelegates() { assertDoesNotThrowIOException(() -> { Writer delegate = mock(Writer.class); try (Writer writer = wrapWriter(delegate)) { writer.flush(); verify(delegate).flush(); } }); } } /** * Contains tests for {@link Writer#close()}. * * @author Rob Spoor */ @DisplayName("close()") interface CloseTests extends WriterDelegateTests { @Test @DisplayName("close() delegates") default void testCloseDelegates() { assertDoesNotThrowIOException(() -> { @SuppressWarnings("resource") Writer delegate = mock(Writer.class); try (Writer writer = wrapWriter(delegate)) { // no code necessary } verify(delegate).close(); }); } } /** * An arguments provider for {@link AppendCharSequenceTests} and {@link AppendCharSequencePortionTests}, it returns functions to transform * the test instance's {@link WriterDelegateTests#contentToWrite() content to write} or * {@link WriterDelegateTests#longContentToWrite() long content to write} into a {@code String} (identity transform), {@code StringBuilder}, * {@link StringBuffer} and a generic {@code CharSequence}. * * @author Rob Spoor */ class CharSequenceTransformationProvider implements ArgumentsProvider { @Override public Stream provideArguments(ExtensionContext context) throws Exception { return Stream.of( createArguments(String.class, Function.identity()), createArguments(StringBuilder.class, StringBuilder::new), createArguments(StringBuffer.class, StringBuffer::new), createArguments(CharSequence.class, CharBuffer::wrap)); } private Arguments createArguments(Class type, Function transformation) { return arguments(type.getSimpleName(), transformation); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy