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;
18  
19  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.io.Reader;
26  import java.io.StringWriter;
27  import java.io.Writer;
28  import java.nio.charset.StandardCharsets;
29  
30  import org.apache.commons.io.input.CharSequenceInputStream;
31  import org.apache.commons.io.output.ByteArrayOutputStream;
32  import org.apache.commons.io.test.TestUtils;
33  import org.apache.commons.io.test.ThrowOnCloseInputStream;
34  import org.apache.commons.io.test.ThrowOnFlushAndCloseOutputStream;
35  import org.junit.jupiter.api.Test;
36  
37  @SuppressWarnings("deprecation") // these are test cases for the deprecated CopyUtils
38  
39  /**
40   * Test for {@link CopyUtils}.
41   *
42   * @see CopyUtils
43   */
44  public class CopyUtilsTest {
45  
46      /*
47       * NOTE this is not particularly beautiful code. A better way to check for
48       * flush and close status would be to implement "trojan horse" wrapper
49       * implementations of the various stream classes, which set a flag when
50       * relevant methods are called. (JT)
51       */
52  
53      private static final int FILE_SIZE = 1024 * 4 + 1;
54  
55      private final byte[] inData = TestUtils.generateTestData(FILE_SIZE);
56  
57      @Test
58      public void testCopy_byteArrayToOutputStream() throws Exception {
59          final ByteArrayOutputStream baout = new ByteArrayOutputStream();
60          final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true);
61  
62          CopyUtils.copy(inData, out);
63  
64          assertEquals(inData.length, baout.size(), "Sizes differ");
65          assertArrayEquals(inData, baout.toByteArray(), "Content differs");
66      }
67  
68      @Test
69      public void testCopy_byteArrayToWriter() throws Exception {
70          final ByteArrayOutputStream baout = new ByteArrayOutputStream();
71          final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true);
72          final Writer writer = new java.io.OutputStreamWriter(out, StandardCharsets.US_ASCII);
73  
74          CopyUtils.copy(inData, writer);
75          writer.flush();
76  
77          assertEquals(inData.length, baout.size(), "Sizes differ");
78          assertArrayEquals(inData, baout.toByteArray(), "Content differs");
79      }
80  
81      @Test
82      public void testCopy_byteArrayToWriterWithEncoding() throws Exception {
83          final String inDataStr = "data";
84          final String charsetName = StandardCharsets.UTF_8.name();
85          final StringWriter writer = new StringWriter();
86          CopyUtils.copy(inDataStr.getBytes(charsetName), writer, charsetName);
87          assertEquals(inDataStr, writer.toString());
88      }
89  
90      @SuppressWarnings("resource") // 'in' is deliberately not closed
91      @Test
92      public void testCopy_inputStreamToOutputStream() throws Exception {
93          InputStream in = new ByteArrayInputStream(inData);
94          in = new ThrowOnCloseInputStream(in);
95  
96          final ByteArrayOutputStream baout = new ByteArrayOutputStream();
97          final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true);
98  
99          final int count = CopyUtils.copy(in, out);
100 
101         assertEquals(0, in.available(), "Not all bytes were read");
102         assertEquals(inData.length, baout.size(), "Sizes differ");
103         assertArrayEquals(inData, baout.toByteArray(), "Content differs");
104         assertEquals(inData.length, count);
105     }
106 
107     @SuppressWarnings("resource") // 'in' is deliberately not closed
108     @Test
109     public void testCopy_inputStreamToWriter() throws Exception {
110         InputStream in = new ByteArrayInputStream(inData);
111         in = new ThrowOnCloseInputStream(in);
112 
113         final ByteArrayOutputStream baout = new ByteArrayOutputStream();
114         final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true);
115         final Writer writer = new java.io.OutputStreamWriter(out, StandardCharsets.US_ASCII);
116 
117         CopyUtils.copy(in, writer);
118         writer.flush();
119 
120         assertEquals(0, in.available(), "Not all bytes were read");
121         assertEquals(inData.length, baout.size(), "Sizes differ");
122         assertArrayEquals(inData, baout.toByteArray(), "Content differs");
123     }
124 
125     @Test
126     public void testCopy_inputStreamToWriterWithEncoding() throws Exception {
127         final String inDataStr = "data";
128         final String charsetName = StandardCharsets.UTF_8.name();
129         final StringWriter writer = new StringWriter();
130         CopyUtils.copy(new CharSequenceInputStream.Builder().setCharSequence(inDataStr).setCharset(charsetName).get(), writer, charsetName);
131         assertEquals(inDataStr, writer.toString());
132     }
133 
134     @SuppressWarnings("resource") // 'in' is deliberately not closed
135     @Test
136     public void testCopy_readerToOutputStream() throws Exception {
137         InputStream in = new ByteArrayInputStream(inData);
138         in = new ThrowOnCloseInputStream(in);
139         final Reader reader = new java.io.InputStreamReader(in, StandardCharsets.US_ASCII);
140 
141         final ByteArrayOutputStream baout = new ByteArrayOutputStream();
142         final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true);
143 
144         CopyUtils.copy(reader, out);
145         //Note: this method *does* flush. It is equivalent to:
146         //  OutputStreamWriter _out = new OutputStreamWriter(fout);
147         //  IOUtils.copy( fin, _out, 4096 ); // copy( Reader, Writer, int );
148         //  _out.flush();
149         //  out = fout;
150 
151         // Note: rely on the method to flush
152         assertEquals(inData.length, baout.size(), "Sizes differ");
153         assertArrayEquals(inData, baout.toByteArray(), "Content differs");
154     }
155 
156     @SuppressWarnings("resource") // 'in' is deliberately not closed
157     @Test
158     public void testCopy_readerToOutputStreamString() throws Exception {
159         InputStream in = new ByteArrayInputStream(inData);
160         in = new ThrowOnCloseInputStream(in);
161         final Reader reader = new java.io.InputStreamReader(in, StandardCharsets.US_ASCII);
162 
163         final ByteArrayOutputStream baout = new ByteArrayOutputStream();
164         final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true);
165 
166         CopyUtils.copy(reader, out, StandardCharsets.US_ASCII.name());
167         //Note: this method *does* flush. It is equivalent to:
168         //  OutputStreamWriter _out = new OutputStreamWriter(fout);
169         //  IOUtils.copy( fin, _out, 4096 ); // copy( Reader, Writer, int );
170         //  _out.flush();
171         //  out = fout;
172 
173         // Note: rely on the method to flush
174         assertEquals(inData.length, baout.size(), "Sizes differ");
175         assertArrayEquals(inData, baout.toByteArray(), "Content differs");
176     }
177 
178     @SuppressWarnings("resource") // 'in' is deliberately not closed
179     @Test
180     public void testCopy_readerToWriter() throws Exception {
181         InputStream in = new ByteArrayInputStream(inData);
182         in = new ThrowOnCloseInputStream(in);
183         final Reader reader = new java.io.InputStreamReader(in, StandardCharsets.US_ASCII);
184 
185         final ByteArrayOutputStream baout = new ByteArrayOutputStream();
186         final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true);
187         final Writer writer = new java.io.OutputStreamWriter(out, StandardCharsets.US_ASCII);
188 
189         final int count = CopyUtils.copy(reader, writer);
190         writer.flush();
191         assertEquals(inData.length, count, "The number of characters returned by copy is wrong");
192         assertEquals(inData.length, baout.size(), "Sizes differ");
193         assertArrayEquals(inData, baout.toByteArray(), "Content differs");
194     }
195 
196     @Test
197     public void testCopy_stringToOutputStream() throws Exception {
198         final String str = new String(inData, StandardCharsets.US_ASCII);
199 
200         final ByteArrayOutputStream baout = new ByteArrayOutputStream();
201         final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true);
202 
203         CopyUtils.copy(str, out);
204         //Note: this method *does* flush. It is equivalent to:
205         //  OutputStreamWriter _out = new OutputStreamWriter(fout);
206         //  IOUtils.copy( str, _out, 4096 ); // copy( Reader, Writer, int );
207         //  _out.flush();
208         //  out = fout;
209         // note: we don't flush here; this IOUtils method does it for us
210 
211         assertEquals(inData.length, baout.size(), "Sizes differ");
212         assertArrayEquals(inData, baout.toByteArray(), "Content differs");
213     }
214 
215     @Test
216     public void testCopy_stringToOutputStreamString() throws Exception {
217         final String str = new String(inData, StandardCharsets.US_ASCII);
218 
219         final ByteArrayOutputStream baout = new ByteArrayOutputStream();
220         final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true);
221 
222         CopyUtils.copy(str, out, StandardCharsets.US_ASCII.name());
223         //Note: this method *does* flush. It is equivalent to:
224         //  OutputStreamWriter _out = new OutputStreamWriter(fout);
225         //  IOUtils.copy( str, _out, 4096 ); // copy( Reader, Writer, int );
226         //  _out.flush();
227         //  out = fout;
228         // note: we don't flush here; this IOUtils method does it for us
229 
230         assertEquals(inData.length, baout.size(), "Sizes differ");
231         assertArrayEquals(inData, baout.toByteArray(), "Content differs");
232     }
233 
234     @Test
235     public void testCopy_stringToWriter() throws Exception {
236         final String str = new String(inData, StandardCharsets.US_ASCII);
237 
238         final ByteArrayOutputStream baout = new ByteArrayOutputStream();
239         final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true);
240         final Writer writer = new java.io.OutputStreamWriter(out, StandardCharsets.US_ASCII);
241 
242         CopyUtils.copy(str, writer);
243         writer.flush();
244 
245         assertEquals(inData.length, baout.size(), "Sizes differ");
246         assertArrayEquals(inData, baout.toByteArray(), "Content differs");
247     }
248 
249     @Test
250     public void testCtor() {
251         new CopyUtils();
252         // Nothing to assert, the constructor is public and does not blow up.
253     }
254 
255 }