Skip to content

Commit

Permalink
Cleanup and enhance exception message
Browse files Browse the repository at this point in the history
  • Loading branch information
sleberknight committed Jul 31, 2024
1 parent 89557a0 commit 92e16f9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 11 deletions.
14 changes: 8 additions & 6 deletions src/main/java/org/kiwiproject/io/KiwiIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,23 +235,25 @@ public static void closeObjectsQuietly(String closeMethodName, Object... objects
return;
}

checkDoesNotContainAnyCloseableResources(objects);
checkDoesNotContainAnyCloseableResources(closeMethodName, objects);

Arrays.stream(objects)
.filter(Objects::nonNull)
.map(object -> new CloseableResource(object, List.of(closeMethodName)))
.forEach(KiwiIO::closeQuietly);
}

private static void checkDoesNotContainAnyCloseableResources(Object... objects) {
private static void checkDoesNotContainAnyCloseableResources(String closeMethodName, Object... objects) {
for (var object : objects) {
checkIsNotCloseableResource(object);
checkIsNotCloseableResource(closeMethodName, object);
}
}

private static void checkIsNotCloseableResource(Object object) {
checkArgument(isNotCloseableResource(object),
"objects should not contain any instances of CloseableResource when a single closeMethodName is specified");
private static void checkIsNotCloseableResource(String closeMethodName, Object object) {
checkArgument(
isNotCloseableResource(object),
"objects should not contain any instances of CloseableResource when a single closeMethodName (%s) is specified",
closeMethodName);
}

private static boolean isNotCloseableResource(Object object) {
Expand Down
39 changes: 34 additions & 5 deletions src/test/java/org/kiwiproject/io/KiwiIOTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.BeforeEach;
Expand All @@ -21,7 +23,6 @@
import org.kiwiproject.io.KiwiIO.CloseableResource;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
Expand Down Expand Up @@ -71,6 +72,7 @@ void shouldClose_Reader_WhenThrowsOnClose() throws IOException {
var reader = mock(Reader.class);
doThrow(new IOException("I cannot read")).when(reader).close();
assertThatCode(() -> KiwiIO.closeQuietly(reader)).doesNotThrowAnyException();
verify(reader).close();
}

@SuppressWarnings("ConstantValue")
Expand All @@ -91,6 +93,7 @@ void shouldClose_Writer_WhenThrowsOnClose() throws IOException {
var writer = mock(Writer.class);
doThrow(new IOException("I cannot write")).when(writer).close();
assertThatCode(() -> KiwiIO.closeQuietly(writer)).doesNotThrowAnyException();
verify(writer).close();
}

@SuppressWarnings("ConstantValue")
Expand All @@ -111,6 +114,7 @@ void shouldClose_InputStream_WhenThrowsOnClose() throws IOException {
var stream = mock(InputStream.class);
doThrow(new IOException("I cannot read")).when(stream).close();
assertThatCode(() -> KiwiIO.closeQuietly(stream)).doesNotThrowAnyException();
verify(stream).close();
}

@SuppressWarnings("ConstantValue")
Expand All @@ -131,6 +135,7 @@ void shouldClose_OutputStream_WhenThrowsOnClose() throws IOException {
var stream = mock(OutputStream.class);
doThrow(new IOException("I cannot stream")).when(stream).close();
assertThatCode(() -> KiwiIO.closeQuietly(stream)).doesNotThrowAnyException();
verify(stream).close();
}

@SuppressWarnings("ConstantValue")
Expand All @@ -152,6 +157,7 @@ void shouldClose_Socket_WhenThrowsOnClose() throws IOException {
var socket = mock(Socket.class);
doThrow(new IOException("I cannot read")).when(socket).close();
assertThatCode(() -> KiwiIO.closeQuietly(socket)).doesNotThrowAnyException();
verify(socket).close();
}

@SuppressWarnings("ConstantValue")
Expand All @@ -170,9 +176,10 @@ void shouldClose_Selector() throws IOException {

@Test
void shouldClose_Selector_WhenThrowsOnClose() throws IOException {
var socket = mock(Selector.class);
doThrow(new IOException("I cannot select")).when(socket).close();
assertThatCode(() -> KiwiIO.closeQuietly(socket)).doesNotThrowAnyException();
var selector = mock(Selector.class);
doThrow(new IOException("I cannot select")).when(selector).close();
assertThatCode(() -> KiwiIO.closeQuietly(selector)).doesNotThrowAnyException();
verify(selector).close();
}

@SuppressWarnings("ConstantValue")
Expand All @@ -194,6 +201,7 @@ void shouldClose_ServerSocket_WhenThrowsOnClose() throws IOException {
var serverSocket = mock(ServerSocket.class);
doThrow(new IOException("I cannot read")).when(serverSocket).close();
assertThatCode(() -> KiwiIO.closeQuietly(serverSocket)).doesNotThrowAnyException();
verify(serverSocket).close();
}

@SuppressWarnings("ConstantValue")
Expand Down Expand Up @@ -235,6 +243,10 @@ void shouldClose_Closeables_WhenThrowOnClose() throws IOException {
doThrow(new IOException("I cannot read")).when(serverSocket).close();

assertThatCode(() -> KiwiIO.closeQuietly(socket, selector, serverSocket)).doesNotThrowAnyException();

verify(socket).close();
verify(selector).close();
verify(serverSocket).close();
}

@SuppressWarnings("ConstantValue")
Expand All @@ -255,6 +267,7 @@ void shouldClose_XMLStreamReader_WhenThrowsOnClose() throws XMLStreamException {
var xmlStreamReader = mock(XMLStreamReader.class);
doThrow(new XMLStreamException("I cannot stream XML")).when(xmlStreamReader).close();
assertThatCode(() -> KiwiIO.closeQuietly(xmlStreamReader)).doesNotThrowAnyException();
verify(xmlStreamReader).close();
}

@SuppressWarnings("ConstantValue")
Expand All @@ -266,15 +279,18 @@ void shouldClose_NullXMLStreamWriter() {

@Test
void shouldClose_XMLStreamWriter() throws XMLStreamException {
var xmlStreamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(new StringWriter());
var xmlStreamWriter = mock(XMLStreamWriter.class);
doNothing().when(xmlStreamWriter).close();
assertThatCode(() -> KiwiIO.closeQuietly(xmlStreamWriter)).doesNotThrowAnyException();
verify(xmlStreamWriter).close();
}

@Test
void shouldClose_XMLStreamWriter_WhenThrowsOnClose() throws XMLStreamException {
var xmlStreamWriter = mock(XMLStreamWriter.class);
doThrow(new XMLStreamException("I cannot stream XML")).when(xmlStreamWriter).close();
assertThatCode(() -> KiwiIO.closeQuietly(xmlStreamWriter)).doesNotThrowAnyException();
verify(xmlStreamWriter).close();
}
}

Expand Down Expand Up @@ -406,6 +422,19 @@ void shouldCloseManyObjects_WithSameCloseMethodName() {
);
}

@Test
void shouldNotAllow_CloseableResource_WhenGivenExplicit_CloseMethodName() {
var halter1 = new Halter();
var halter2 = new Halter();
var terminator = new Terminator();
var terminatorResource = new CloseableResource(terminator, "terminate");

var closeMethodName = "halt";
assertThatIllegalArgumentException()
.isThrownBy(() -> KiwiIO.closeObjectsQuietly(closeMethodName, halter1, halter2, terminatorResource))
.withMessage("objects should not contain any instances of CloseableResource when a single closeMethodName (%s) is specified", closeMethodName);
}

@Test
void shouldCloseManyObjects_WithDifferingCloseMethodName() {
var closer = new Closer();
Expand Down

0 comments on commit 92e16f9

Please sign in to comment.