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 copy_byteArrayToOutputStream()58 public void copy_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 copy_byteArrayToWriter()69 public void copy_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 @SuppressWarnings("resource") // 'in' is deliberately not closed 82 @Test copy_inputStreamToWriter()83 public void copy_inputStreamToWriter() throws Exception { 84 InputStream in = new ByteArrayInputStream(inData); 85 in = new ThrowOnCloseInputStream(in); 86 87 final ByteArrayOutputStream baout = new ByteArrayOutputStream(); 88 final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true); 89 final Writer writer = new java.io.OutputStreamWriter(out, StandardCharsets.US_ASCII); 90 91 CopyUtils.copy(in, writer); 92 writer.flush(); 93 94 assertEquals(0, in.available(), "Not all bytes were read"); 95 assertEquals(inData.length, baout.size(), "Sizes differ"); 96 assertArrayEquals(inData, baout.toByteArray(), "Content differs"); 97 } 98 99 @Test copy_inputStreamToWriterWithEncoding()100 public void copy_inputStreamToWriterWithEncoding() throws Exception { 101 final String inDataStr = "data"; 102 final String charsetName = StandardCharsets.UTF_8.name(); 103 final StringWriter writer = new StringWriter(); 104 CopyUtils.copy(new CharSequenceInputStream.Builder().setCharSequence(inDataStr).setCharset(charsetName).get(), writer, charsetName); 105 assertEquals(inDataStr, writer.toString()); 106 } 107 108 @SuppressWarnings("resource") // 'in' is deliberately not closed 109 @Test copy_readerToWriter()110 public void copy_readerToWriter() throws Exception { 111 InputStream in = new ByteArrayInputStream(inData); 112 in = new ThrowOnCloseInputStream(in); 113 final Reader reader = new java.io.InputStreamReader(in, StandardCharsets.US_ASCII); 114 115 final ByteArrayOutputStream baout = new ByteArrayOutputStream(); 116 final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true); 117 final Writer writer = new java.io.OutputStreamWriter(out, StandardCharsets.US_ASCII); 118 119 final int count = CopyUtils.copy(reader, writer); 120 writer.flush(); 121 assertEquals(inData.length, count, "The number of characters returned by copy is wrong"); 122 assertEquals(inData.length, baout.size(), "Sizes differ"); 123 assertArrayEquals(inData, baout.toByteArray(), "Content differs"); 124 } 125 126 @Test copy_stringToOutputStream()127 public void copy_stringToOutputStream() throws Exception { 128 final String str = new String(inData, StandardCharsets.US_ASCII); 129 130 final ByteArrayOutputStream baout = new ByteArrayOutputStream(); 131 final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true); 132 133 CopyUtils.copy(str, out); 134 //Note: this method *does* flush. It is equivalent to: 135 // OutputStreamWriter _out = new OutputStreamWriter(fout); 136 // IOUtils.copy( str, _out, 4096 ); // copy( Reader, Writer, int ); 137 // _out.flush(); 138 // out = fout; 139 // note: we don't flush here; this IOUtils method does it for us 140 141 assertEquals(inData.length, baout.size(), "Sizes differ"); 142 assertArrayEquals(inData, baout.toByteArray(), "Content differs"); 143 } 144 145 @Test copy_stringToOutputStreamString()146 public void copy_stringToOutputStreamString() throws Exception { 147 final String str = new String(inData, StandardCharsets.US_ASCII); 148 149 final ByteArrayOutputStream baout = new ByteArrayOutputStream(); 150 final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true); 151 152 CopyUtils.copy(str, out, StandardCharsets.US_ASCII.name()); 153 //Note: this method *does* flush. It is equivalent to: 154 // OutputStreamWriter _out = new OutputStreamWriter(fout); 155 // IOUtils.copy( str, _out, 4096 ); // copy( Reader, Writer, int ); 156 // _out.flush(); 157 // out = fout; 158 // note: we don't flush here; this IOUtils method does it for us 159 160 assertEquals(inData.length, baout.size(), "Sizes differ"); 161 assertArrayEquals(inData, baout.toByteArray(), "Content differs"); 162 } 163 164 @Test copy_stringToWriter()165 public void copy_stringToWriter() throws Exception { 166 final String str = new String(inData, StandardCharsets.US_ASCII); 167 168 final ByteArrayOutputStream baout = new ByteArrayOutputStream(); 169 final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true); 170 final Writer writer = new java.io.OutputStreamWriter(out, StandardCharsets.US_ASCII); 171 172 CopyUtils.copy(str, writer); 173 writer.flush(); 174 175 assertEquals(inData.length, baout.size(), "Sizes differ"); 176 assertArrayEquals(inData, baout.toByteArray(), "Content differs"); 177 } 178 179 @Test testCopy_byteArrayToWriterWithEncoding()180 public void testCopy_byteArrayToWriterWithEncoding() throws Exception { 181 final String inDataStr = "data"; 182 final String charsetName = StandardCharsets.UTF_8.name(); 183 final StringWriter writer = new StringWriter(); 184 CopyUtils.copy(inDataStr.getBytes(charsetName), writer, charsetName); 185 assertEquals(inDataStr, writer.toString()); 186 } 187 188 @SuppressWarnings("resource") // 'in' is deliberately not closed 189 @Test testCopy_inputStreamToOutputStream()190 public void testCopy_inputStreamToOutputStream() throws Exception { 191 InputStream in = new ByteArrayInputStream(inData); 192 in = new ThrowOnCloseInputStream(in); 193 194 final ByteArrayOutputStream baout = new ByteArrayOutputStream(); 195 final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true); 196 197 final int count = CopyUtils.copy(in, out); 198 199 assertEquals(0, in.available(), "Not all bytes were read"); 200 assertEquals(inData.length, baout.size(), "Sizes differ"); 201 assertArrayEquals(inData, baout.toByteArray(), "Content differs"); 202 assertEquals(inData.length, count); 203 } 204 205 @SuppressWarnings("resource") // 'in' is deliberately not closed 206 @Test testCopy_readerToOutputStream()207 public void testCopy_readerToOutputStream() throws Exception { 208 InputStream in = new ByteArrayInputStream(inData); 209 in = new ThrowOnCloseInputStream(in); 210 final Reader reader = new java.io.InputStreamReader(in, StandardCharsets.US_ASCII); 211 212 final ByteArrayOutputStream baout = new ByteArrayOutputStream(); 213 final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true); 214 215 CopyUtils.copy(reader, out); 216 //Note: this method *does* flush. It is equivalent to: 217 // OutputStreamWriter _out = new OutputStreamWriter(fout); 218 // IOUtils.copy( fin, _out, 4096 ); // copy( Reader, Writer, int ); 219 // _out.flush(); 220 // out = fout; 221 222 // Note: rely on the method to flush 223 assertEquals(inData.length, baout.size(), "Sizes differ"); 224 assertArrayEquals(inData, baout.toByteArray(), "Content differs"); 225 } 226 227 @SuppressWarnings("resource") // 'in' is deliberately not closed 228 @Test testCopy_readerToOutputStreamString()229 public void testCopy_readerToOutputStreamString() throws Exception { 230 InputStream in = new ByteArrayInputStream(inData); 231 in = new ThrowOnCloseInputStream(in); 232 final Reader reader = new java.io.InputStreamReader(in, StandardCharsets.US_ASCII); 233 234 final ByteArrayOutputStream baout = new ByteArrayOutputStream(); 235 final OutputStream out = new ThrowOnFlushAndCloseOutputStream(baout, false, true); 236 237 CopyUtils.copy(reader, out, StandardCharsets.US_ASCII.name()); 238 //Note: this method *does* flush. It is equivalent to: 239 // OutputStreamWriter _out = new OutputStreamWriter(fout); 240 // IOUtils.copy( fin, _out, 4096 ); // copy( Reader, Writer, int ); 241 // _out.flush(); 242 // out = fout; 243 244 // Note: rely on the method to flush 245 assertEquals(inData.length, baout.size(), "Sizes differ"); 246 assertArrayEquals(inData, baout.toByteArray(), "Content differs"); 247 } 248 249 @Test testCtor()250 public void testCtor() { 251 new CopyUtils(); 252 // Nothing to assert, the constructor is public and does not blow up. 253 } 254 255 } 256