From e3e13e9565e376e949b83c58e111cae755dc8f23 Mon Sep 17 00:00:00 2001 From: Jake Wang Date: Fri, 18 Sep 2026 21:10:04 -0400 Subject: [PATCH 1/2] Propagate I/O failures from UnifiedDiffWriter --- .../unifieddiff/UnifiedDiffWriter.java | 31 +++++++++-------- .../unifieddiff/UnifiedDiffWriterTest.java | 34 +++++++++++++++++++ 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/java-diff-utils/src/main/java/com/github/difflib/unifieddiff/UnifiedDiffWriter.java b/java-diff-utils/src/main/java/com/github/difflib/unifieddiff/UnifiedDiffWriter.java index aa57268..aadea70 100644 --- a/java-diff-utils/src/main/java/com/github/difflib/unifieddiff/UnifiedDiffWriter.java +++ b/java-diff-utils/src/main/java/com/github/difflib/unifieddiff/UnifiedDiffWriter.java @@ -17,14 +17,13 @@ import com.github.difflib.patch.AbstractDelta; import java.io.IOException; +import java.io.UncheckedIOException; import java.io.Writer; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.Consumer; import java.util.function.Function; -import java.util.logging.Level; -import java.util.logging.Logger; /** * @todo use an instance to store contextSize and originalLinesProvider. @@ -32,23 +31,25 @@ */ public class UnifiedDiffWriter { - private static final Logger LOG = Logger.getLogger(UnifiedDiffWriter.class.getName()); - public static void write( UnifiedDiff diff, Function> originalLinesProvider, Writer writer, int contextSize) throws IOException { Objects.requireNonNull(originalLinesProvider, "original lines provider needs to be specified"); - write( - diff, - originalLinesProvider, - line -> { - try { - writer.append(line).append("\n"); - } catch (IOException ex) { - LOG.log(Level.SEVERE, null, ex); - } - }, - contextSize); + try { + write( + diff, + originalLinesProvider, + line -> { + try { + writer.append(line).append("\n"); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + }, + contextSize); + } catch (UncheckedIOException ex) { + throw ex.getCause(); + } } public static void write( diff --git a/java-diff-utils/src/test/java/com/github/difflib/unifieddiff/UnifiedDiffWriterTest.java b/java-diff-utils/src/test/java/com/github/difflib/unifieddiff/UnifiedDiffWriterTest.java index ccbff82..e7da1da 100644 --- a/java-diff-utils/src/test/java/com/github/difflib/unifieddiff/UnifiedDiffWriterTest.java +++ b/java-diff-utils/src/test/java/com/github/difflib/unifieddiff/UnifiedDiffWriterTest.java @@ -16,12 +16,15 @@ package com.github.difflib.unifieddiff; 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 com.github.difflib.DiffUtils; import com.github.difflib.patch.Patch; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringWriter; +import java.io.Writer; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.Charset; @@ -31,6 +34,8 @@ import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; /** * @@ -81,6 +86,35 @@ public void testWriteWithNewFile() throws URISyntaxException, IOException { assertEquals("@@ -0,0 +1,2 @@", lines[2]); } + @ParameterizedTest + @ValueSource(ints = {1, 2, 9, 16}) + public void testPropagateWriterFailures(int failOnWrite) { + List original = Collections.singletonList("old"); + Patch patch = DiffUtils.diff(original, Collections.singletonList("new")); + UnifiedDiff diff = UnifiedDiff.from("header", "tail", UnifiedDiffFile.from("original", "revised", patch)); + IOException failure = new IOException("write failed"); + int[] writes = {0}; + Writer writer = new Writer() { + @Override + public void write(char[] buffer, int offset, int length) throws IOException { + if (++writes[0] == failOnWrite) { + throw failure; + } + } + + @Override + public void flush() {} + + @Override + public void close() {} + }; + + assertSame( + failure, + assertThrows(IOException.class, () -> UnifiedDiffWriter.write(diff, name -> original, writer, 0))); + assertEquals(failOnWrite, writes[0]); + } + static String readFile(URI path, Charset encoding) throws IOException { byte[] encoded = Files.readAllBytes(Paths.get(path)); return new String(encoded, encoding); From c6905d85ff2eae776dee66b904c73734248e212d Mon Sep 17 00:00:00 2001 From: Jake Wang Date: Fri, 18 Sep 2026 21:23:32 -0400 Subject: [PATCH 2/2] Document no-op methods in failing writer test --- .../github/difflib/unifieddiff/UnifiedDiffWriterTest.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/java-diff-utils/src/test/java/com/github/difflib/unifieddiff/UnifiedDiffWriterTest.java b/java-diff-utils/src/test/java/com/github/difflib/unifieddiff/UnifiedDiffWriterTest.java index e7da1da..a43c579 100644 --- a/java-diff-utils/src/test/java/com/github/difflib/unifieddiff/UnifiedDiffWriterTest.java +++ b/java-diff-utils/src/test/java/com/github/difflib/unifieddiff/UnifiedDiffWriterTest.java @@ -103,10 +103,14 @@ public void write(char[] buffer, int offset, int length) throws IOException { } @Override - public void flush() {} + public void flush() { + // No buffered output in this test writer. + } @Override - public void close() {} + public void close() { + // No resources to release. + } }; assertSame(