View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.io.output;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertTrue;
21  import static org.junit.jupiter.api.Assertions.fail;
22  import static org.mockito.Mockito.mock;
23  import static org.mockito.Mockito.verify;
24  
25  import java.io.IOException;
26  import java.io.StringWriter;
27  import java.io.Writer;
28  import java.util.Arrays;
29  import java.util.Collection;
30  
31  import org.apache.commons.io.IOExceptionList;
32  import org.apache.commons.io.IOIndexedException;
33  import org.junit.jupiter.api.Test;
34  
35  /**
36   * Tests {@link ProxyCollectionWriter}.
37   */
38  public class ProxyCollectionWriterTest {
39  
40      @Test
41      public void testArrayIOExceptionOnAppendChar1() throws IOException {
42          final Writer badW = BrokenWriter.INSTANCE;
43          final StringWriter goodW = mock(StringWriter.class);
44          @SuppressWarnings("resource") // not necessary to close this
45          final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null);
46          final char data = 'A';
47          try {
48              tw.append(data);
49              fail("Expected " + IOException.class.getName());
50          } catch (final IOExceptionList e) {
51              verify(goodW).append(data);
52              assertEquals(1, e.getCauseList().size());
53              assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex());
54          }
55      }
56  
57      @Test
58      public void testArrayIOExceptionOnAppendChar2() throws IOException {
59          final Writer badW = BrokenWriter.INSTANCE;
60          final StringWriter goodW = mock(StringWriter.class);
61          @SuppressWarnings("resource") // not necessary to close this
62          final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null);
63          final char data = 'A';
64          try {
65              tw.append(data);
66              fail("Expected " + IOException.class.getName());
67          } catch (final IOExceptionList e) {
68              verify(goodW).append(data);
69              assertEquals(1, e.getCauseList().size());
70              assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
71          }
72      }
73  
74      @Test
75      public void testArrayIOExceptionOnAppendCharSequence1() throws IOException {
76          final Writer badW = BrokenWriter.INSTANCE;
77          final StringWriter goodW = mock(StringWriter.class);
78          @SuppressWarnings("resource") // not necessary to close this
79          final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null);
80          final CharSequence data = "A";
81          try {
82              tw.append(data);
83              fail("Expected " + IOException.class.getName());
84          } catch (final IOExceptionList e) {
85              verify(goodW).append(data);
86              assertEquals(1, e.getCauseList().size());
87              assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex());
88          }
89      }
90  
91      @Test
92      public void testArrayIOExceptionOnAppendCharSequence2() throws IOException {
93          final Writer badW = BrokenWriter.INSTANCE;
94          final StringWriter goodW = mock(StringWriter.class);
95          @SuppressWarnings("resource") // not necessary to close this
96          final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null);
97          final CharSequence data = "A";
98          try {
99              tw.append(data);
100             fail("Expected " + IOException.class.getName());
101         } catch (final IOExceptionList e) {
102             verify(goodW).append(data);
103             assertEquals(1, e.getCauseList().size());
104             assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
105         }
106     }
107 
108     @Test
109     public void testArrayIOExceptionOnAppendCharSequenceIntInt1() throws IOException {
110         final Writer badW = BrokenWriter.INSTANCE;
111         final StringWriter goodW = mock(StringWriter.class);
112         @SuppressWarnings("resource") // not necessary to close this
113         final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null);
114         final CharSequence data = "A";
115         try {
116             tw.append(data, 0, 0);
117             fail("Expected " + IOException.class.getName());
118         } catch (final IOExceptionList e) {
119             verify(goodW).append(data, 0, 0);
120             assertEquals(1, e.getCauseList().size());
121             assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex());
122         }
123     }
124 
125     @Test
126     public void testArrayIOExceptionOnAppendCharSequenceIntInt2() throws IOException {
127         final Writer badW = BrokenWriter.INSTANCE;
128         final StringWriter goodW = mock(StringWriter.class);
129         @SuppressWarnings("resource") // not necessary to close this
130         final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null);
131         final CharSequence data = "A";
132         try {
133             tw.append(data, 0, 0);
134             fail("Expected " + IOException.class.getName());
135         } catch (final IOExceptionList e) {
136             verify(goodW).append(data, 0, 0);
137             assertEquals(1, e.getCauseList().size());
138             assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
139         }
140     }
141 
142     @Test
143     public void testArrayIOExceptionOnClose1() throws IOException {
144         final Writer badW = BrokenWriter.INSTANCE;
145         final StringWriter goodW = mock(StringWriter.class);
146         @SuppressWarnings("resource") // not necessary to close this
147         final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null);
148         try {
149             tw.close();
150             fail("Expected " + IOException.class.getName());
151         } catch (final IOExceptionList e) {
152             verify(goodW).close();
153             assertEquals(1, e.getCauseList().size());
154             assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex());
155         }
156     }
157 
158     @Test
159     public void testArrayIOExceptionOnClose2() throws IOException {
160         final Writer badW = BrokenWriter.INSTANCE;
161         final StringWriter goodW = mock(StringWriter.class);
162         @SuppressWarnings("resource") // not necessary to close this
163         final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null);
164         try {
165             tw.close();
166             fail("Expected " + IOException.class.getName());
167         } catch (final IOExceptionList e) {
168             verify(goodW).close();
169             assertEquals(1, e.getCauseList().size());
170             assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
171         }
172     }
173 
174     @Test
175     public void testArrayIOExceptionOnFlush1() throws IOException {
176         final Writer badW = BrokenWriter.INSTANCE;
177         final StringWriter goodW = mock(StringWriter.class);
178         @SuppressWarnings("resource") // not necessary to close this
179         final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null);
180         try {
181             tw.flush();
182             fail("Expected " + IOException.class.getName());
183         } catch (final IOExceptionList e) {
184             verify(goodW).flush();
185             assertEquals(1, e.getCauseList().size());
186             assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex());
187         }
188     }
189 
190     @Test
191     public void testArrayIOExceptionOnFlush2() throws IOException {
192         final Writer badW = BrokenWriter.INSTANCE;
193         final StringWriter goodW = mock(StringWriter.class);
194         @SuppressWarnings("resource") // not necessary to close this
195         final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null);
196         try {
197             tw.flush();
198             fail("Expected " + IOException.class.getName());
199         } catch (final IOExceptionList e) {
200             verify(goodW).flush();
201             assertEquals(1, e.getCauseList().size());
202             assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
203         }
204     }
205 
206     @Test
207     public void testArrayIOExceptionOnWriteCharArray1() throws IOException {
208         final Writer badW = BrokenWriter.INSTANCE;
209         final StringWriter goodW = mock(StringWriter.class);
210         @SuppressWarnings("resource") // not necessary to close this
211         final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null);
212         final char[] data = { 'a' };
213         try {
214             tw.write(data);
215             fail("Expected " + IOException.class.getName());
216         } catch (final IOExceptionList e) {
217             verify(goodW).write(data);
218             assertEquals(1, e.getCauseList().size());
219             assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex());
220         }
221     }
222 
223     @Test
224     public void testArrayIOExceptionOnWriteCharArray2() throws IOException {
225         final Writer badW = BrokenWriter.INSTANCE;
226         final StringWriter goodW = mock(StringWriter.class);
227         @SuppressWarnings("resource") // not necessary to close this
228         final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null);
229         final char[] data = { 'a' };
230         try {
231             tw.write(data);
232             fail("Expected " + IOException.class.getName());
233         } catch (final IOExceptionList e) {
234             verify(goodW).write(data);
235             assertEquals(1, e.getCauseList().size());
236             assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
237         }
238     }
239 
240     @Test
241     public void testArrayIOExceptionOnWriteCharArrayIntInt1() throws IOException {
242         final Writer badW = BrokenWriter.INSTANCE;
243         final StringWriter goodW = mock(StringWriter.class);
244         @SuppressWarnings("resource") // not necessary to close this
245         final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null);
246         final char[] data = { 'a' };
247         try {
248             tw.write(data, 0, 0);
249             fail("Expected " + IOException.class.getName());
250         } catch (final IOExceptionList e) {
251             verify(goodW).write(data, 0, 0);
252             assertEquals(1, e.getCauseList().size());
253             assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex());
254         }
255     }
256 
257     @Test
258     public void testArrayIOExceptionOnWriteCharArrayIntInt2() throws IOException {
259         final Writer badW = BrokenWriter.INSTANCE;
260         final StringWriter goodW = mock(StringWriter.class);
261         @SuppressWarnings("resource") // not necessary to close this
262         final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null);
263         final char[] data = { 'a' };
264         try {
265             tw.write(data, 0, 0);
266             fail("Expected " + IOException.class.getName());
267         } catch (final IOExceptionList e) {
268             verify(goodW).write(data, 0, 0);
269             assertEquals(1, e.getCauseList().size());
270             assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
271         }
272     }
273 
274     @Test
275     public void testArrayIOExceptionOnWriteInt1() throws IOException {
276         final Writer badW = BrokenWriter.INSTANCE;
277         final StringWriter goodW = mock(StringWriter.class);
278         @SuppressWarnings("resource") // not necessary to close this
279         final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null);
280         final int data = 32;
281         try {
282             tw.write(data);
283             fail("Expected " + IOException.class.getName());
284         } catch (final IOExceptionList e) {
285             verify(goodW).write(data);
286             assertEquals(1, e.getCauseList().size());
287             assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex());
288         }
289     }
290 
291     @Test
292     public void testArrayIOExceptionOnWriteInt2() throws IOException {
293         final Writer badW = BrokenWriter.INSTANCE;
294         final StringWriter goodW = mock(StringWriter.class);
295         @SuppressWarnings("resource") // not necessary to close this
296         final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null);
297         try {
298             tw.write(32);
299             fail("Expected " + IOException.class.getName());
300         } catch (final IOExceptionList e) {
301             verify(goodW).write(32);
302             assertEquals(1, e.getCauseList().size());
303             assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
304 
305         }
306     }
307 
308     @Test
309     public void testArrayIOExceptionOnWriteString1() throws IOException {
310         final Writer badW = BrokenWriter.INSTANCE;
311         final StringWriter goodW = mock(StringWriter.class);
312         @SuppressWarnings("resource") // not necessary to close this
313         final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null);
314         final String data = "A";
315         try {
316             tw.write(data);
317             fail("Expected " + IOException.class.getName());
318         } catch (final IOExceptionList e) {
319             verify(goodW).write(data);
320             assertEquals(1, e.getCauseList().size());
321             assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex());
322         }
323     }
324 
325     @Test
326     public void testArrayIOExceptionOnWriteString2() throws IOException {
327         final Writer badW = BrokenWriter.INSTANCE;
328         final StringWriter goodW = mock(StringWriter.class);
329         @SuppressWarnings("resource") // not necessary to close this
330         final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null);
331         final String data = "A";
332         try {
333             tw.write(data);
334             fail("Expected " + IOException.class.getName());
335         } catch (final IOExceptionList e) {
336             verify(goodW).write(data);
337             assertEquals(1, e.getCauseList().size());
338             assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
339 
340         }
341     }
342 
343     @Test
344     public void testArrayIOExceptionOnWriteStringIntInt1() throws IOException {
345         final Writer badW = BrokenWriter.INSTANCE;
346         final StringWriter goodW = mock(StringWriter.class);
347         @SuppressWarnings("resource") // not necessary to close this
348         final ProxyCollectionWriter tw = new ProxyCollectionWriter(badW, goodW, null);
349         final String data = "A";
350         try {
351             tw.write(data, 0, 0);
352             fail("Expected " + IOException.class.getName());
353         } catch (final IOExceptionList e) {
354             verify(goodW).write(data, 0, 0);
355             assertEquals(1, e.getCauseList().size());
356             assertEquals(0, e.getCause(0, IOIndexedException.class).getIndex());
357         }
358     }
359 
360     @Test
361     public void testArrayIOExceptionOnWriteStringIntInt2() throws IOException {
362         final Writer badW = BrokenWriter.INSTANCE;
363         final StringWriter goodW = mock(StringWriter.class);
364         @SuppressWarnings("resource") // not necessary to close this
365         final ProxyCollectionWriter tw = new ProxyCollectionWriter(goodW, badW, null);
366         final String data = "A";
367         try {
368             tw.write(data, 0, 0);
369             fail("Expected " + IOException.class.getName());
370         } catch (final IOExceptionList e) {
371             verify(goodW).write(data, 0, 0);
372             assertEquals(1, e.getCauseList().size());
373             assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
374 
375         }
376     }
377 
378     @Test
379     public void testCollectionCloseBranchIOException() throws IOException {
380         final Writer badW = BrokenWriter.INSTANCE;
381         final StringWriter goodW = mock(StringWriter.class);
382         @SuppressWarnings("resource") // not necessary to close this
383         final ProxyCollectionWriter tw = new ProxyCollectionWriter(Arrays.asList(goodW, badW, null));
384         try {
385             tw.close();
386             fail("Expected " + IOException.class.getName());
387         } catch (final IOExceptionList e) {
388             verify(goodW).close();
389             assertEquals(1, e.getCauseList().size());
390             assertEquals(1, e.getCause(0, IOIndexedException.class).getIndex());
391 
392         }
393     }
394 
395     @Test
396     public void testConstructorsNull() throws IOException {
397         try (ProxyCollectionWriter teeWriter = new ProxyCollectionWriter((Writer[]) null)) {
398             // Call any method, should not throw
399             teeWriter.append('a');
400             teeWriter.flush();
401         }
402         try (ProxyCollectionWriter teeWriter = new ProxyCollectionWriter((Collection<Writer>) null)) {
403             // Call any method, should not throw
404             teeWriter.append('a');
405             teeWriter.flush();
406         }
407         assertTrue(true, "Dummy to show test completed OK");
408     }
409 
410     @Test
411     public void testTee() throws IOException {
412         try (StringBuilderWriter sbw1 = new StringBuilderWriter();
413                 StringBuilderWriter sbw2 = new StringBuilderWriter();
414                 StringBuilderWriter expected = new StringBuilderWriter();
415                 ProxyCollectionWriter tw = new ProxyCollectionWriter(sbw1, sbw2, null)) {
416             for (int i = 0; i < 20; i++) {
417                 tw.write(i);
418                 expected.write(i);
419             }
420             assertEquals(expected.toString(), sbw1.toString(), "ProxyCollectionWriter.write(int)");
421             assertEquals(expected.toString(), sbw2.toString(), "ProxyCollectionWriter.write(int)");
422 
423             final char[] array = new char[10];
424             for (int i = 20; i < 30; i++) {
425                 array[i - 20] = (char) i;
426             }
427             tw.write(array);
428             expected.write(array);
429             assertEquals(expected.toString(), sbw1.toString(), "ProxyCollectionWriter.write(char[])");
430             assertEquals(expected.toString(), sbw2.toString(), "ProxyCollectionWriter.write(char[])");
431 
432             for (int i = 25; i < 35; i++) {
433                 array[i - 25] = (char) i;
434             }
435             tw.write(array, 5, 5);
436             expected.write(array, 5, 5);
437             assertEquals(expected.toString(), sbw1.toString(), "TeeOutputStream.write(byte[], int, int)");
438             assertEquals(expected.toString(), sbw2.toString(), "TeeOutputStream.write(byte[], int, int)");
439 
440             for (int i = 0; i < 20; i++) {
441                 tw.append((char) i);
442                 expected.append((char) i);
443             }
444             assertEquals(expected.toString(), sbw1.toString(), "ProxyCollectionWriter.append(char)");
445             assertEquals(expected.toString(), sbw2.toString(), "ProxyCollectionWriter.append(char)");
446 
447             for (int i = 20; i < 30; i++) {
448                 array[i - 20] = (char) i;
449             }
450             tw.append(new String(array));
451             expected.append(new String(array));
452             assertEquals(expected.toString(), sbw1.toString(), "ProxyCollectionWriter.append(CharSequence)");
453             assertEquals(expected.toString(), sbw2.toString(), "ProxyCollectionWriter.write(CharSequence)");
454 
455             for (int i = 25; i < 35; i++) {
456                 array[i - 25] = (char) i;
457             }
458             tw.append(new String(array), 5, 5);
459             expected.append(new String(array), 5, 5);
460             assertEquals(expected.toString(), sbw1.toString(), "ProxyCollectionWriter.append(CharSequence, int, int)");
461             assertEquals(expected.toString(), sbw2.toString(), "ProxyCollectionWriter.append(CharSequence, int, int)");
462 
463             expected.flush();
464             expected.close();
465 
466             tw.flush();
467         }
468     }
469 
470 }