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 java.io.File;
20  import java.io.FileInputStream;
21  import java.io.FileOutputStream;
22  import java.io.FileReader;
23  import java.io.FileWriter;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.InputStreamReader;
27  import java.io.Reader;
28  import java.util.Arrays;
29  import java.util.List;
30  
31  import org.apache.commons.io.testtools.FileBasedTestCase;
32  
33  // Note: jdk1.2 dependency
34  
35  /**
36   * This is used to test IOUtils for correctness. The following checks are performed:
37   * <ul>
38   *   <li>The return must not be null, must be the same type and equals() to the method's second arg</li>
39   *   <li>All bytes must have been read from the source (available() == 0)</li>
40   *   <li>The source and destination content must be identical (byte-wise comparison check)</li>
41   *   <li>The output stream must not have been closed (a byte/char is written to test this, and
42   *   subsequent size checked)</li>
43   * </ul>
44   * Due to interdependencies in IOUtils and IOUtilsTestlet, one bug may cause
45   * multiple tests to fail.
46   *
47   * @author <a href="mailto:jefft@apache.org">Jeff Turner</a>
48   * @author Gareth Davis
49   * @author Ian Springer
50   */
51  public class IOUtilsTestCase extends FileBasedTestCase {
52      
53      /** Determine if this is windows. */
54      private static final boolean WINDOWS = (File.separatorChar == '\\');
55      /*
56       * Note: this is not particularly beautiful code. A better way to check for
57       * flush and close status would be to implement "trojan horse" wrapper
58       * implementations of the various stream classes, which set a flag when
59       * relevant methods are called. (JT)
60       */
61  
62      private static final int FILE_SIZE = 1024 * 4 + 1;
63  
64      private File m_testFile;
65  
66      public void setUp()
67      {
68          try
69          {
70              getTestDirectory().mkdirs();
71              m_testFile = new File( getTestDirectory(), "file2-test.txt" );
72  
73              createFile( m_testFile, FILE_SIZE );
74          }
75          catch( IOException ioe )
76          {
77              throw new RuntimeException( "Can't run this test because "
78                      + "environment could not be built: " + ioe.getMessage());
79          }
80      }
81  
82      public void tearDown()
83      {
84          try
85          {
86              FileUtils.deleteDirectory( getTestDirectory() );
87          }
88          catch( IOException ioe )
89          {
90              // Ignore, because by this time, it is too late.
91          }
92      }
93  
94      public IOUtilsTestCase( String name )
95      {
96          super( name );
97      }
98  
99      //-----------------------------------------------------------------------
100     public void testConstants() throws Exception {
101         assertEquals('/', IOUtils.DIR_SEPARATOR_UNIX);
102         assertEquals('\\', IOUtils.DIR_SEPARATOR_WINDOWS);
103         assertEquals("\n", IOUtils.LINE_SEPARATOR_UNIX);
104         assertEquals("\r\n", IOUtils.LINE_SEPARATOR_WINDOWS);
105         if (WINDOWS) {
106             assertEquals('\\', IOUtils.DIR_SEPARATOR);
107             assertEquals("\r\n", IOUtils.LINE_SEPARATOR);
108         } else {
109             assertEquals('/', IOUtils.DIR_SEPARATOR);
110             assertEquals("\n", IOUtils.LINE_SEPARATOR);
111         }
112     }
113 
114     //-----------------------------------------------------------------------
115     /** Assert that the contents of two byte arrays are the same. */
116     private void assertEqualContent( byte[] b0, byte[] b1 )
117         throws IOException
118     {
119         assertTrue( "Content not equal according to java.util.Arrays#equals()", Arrays.equals( b0, b1 ) );
120     }
121 
122     public void testInputStreamToString()
123         throws Exception
124     {
125         FileInputStream fin = new FileInputStream( m_testFile );
126         try {
127             String out = IOUtils.toString( fin );
128             assertNotNull( out );
129             assertTrue( "Not all bytes were read", fin.available() == 0 );
130             assertTrue( "Wrong output size: out.length()=" + out.length() +
131                         "!=" + FILE_SIZE, out.length() == FILE_SIZE );
132         } finally {
133             fin.close();
134         }
135     }
136 
137     public void testReaderToString()
138         throws Exception
139     {
140         FileReader fin = new FileReader( m_testFile );
141         try {
142             String out = IOUtils.toString( fin );
143             assertNotNull( out );
144             assertTrue( "Wrong output size: out.length()=" +
145                         out.length() + "!=" + FILE_SIZE,
146                         out.length() == FILE_SIZE );
147         } finally {
148             fin.close();
149         }
150     }
151 
152     public void testStringToOutputStream()
153         throws Exception
154     {
155         File destination = newFile( "copy5.txt" );
156         FileReader fin = new FileReader( m_testFile );
157         String str;
158         try {
159             // Create our String. Rely on testReaderToString() to make sure this is valid.
160             str = IOUtils.toString( fin );
161         } finally {
162             fin.close();
163         }
164         
165         FileOutputStream fout = new FileOutputStream( destination );
166         try {
167             CopyUtils.copy( str, fout );
168             //Note: this method *does* flush. It is equivalent to:
169             //  OutputStreamWriter _out = new OutputStreamWriter(fout);
170             //  CopyUtils.copy( str, _out, 4096 ); // copy( Reader, Writer, int );
171             //  _out.flush();
172             //  out = fout;
173             // note: we don't flush here; this IOUtils method does it for us
174 
175             checkFile( destination, m_testFile );
176             checkWrite( fout );
177         } finally {
178             fout.close();
179         }
180         deleteFile( destination );
181     }
182 
183     public void testStringToWriter()
184         throws Exception
185     {
186         File destination = newFile( "copy6.txt" );
187         FileReader fin = new FileReader( m_testFile );
188         String str;
189         try {
190             // Create our String. Rely on testReaderToString() to make sure this is valid.
191             str = IOUtils.toString( fin );
192         } finally {
193             fin.close();
194         }
195         
196         FileWriter fout = new FileWriter( destination );
197         try {
198             CopyUtils.copy( str, fout );
199             fout.flush();
200 
201             checkFile( destination, m_testFile );
202             checkWrite( fout );
203         } finally {
204             fout.close();
205         }
206         deleteFile( destination );
207     }
208 
209     public void testInputStreamToByteArray()
210         throws Exception
211     {
212         FileInputStream fin = new FileInputStream( m_testFile );
213         try {
214             byte[] out = IOUtils.toByteArray( fin );
215             assertNotNull( out );
216             assertTrue( "Not all bytes were read", fin.available() == 0 );
217             assertTrue( "Wrong output size: out.length=" + out.length +
218                         "!=" + FILE_SIZE, out.length == FILE_SIZE );
219             assertEqualContent( out, m_testFile );
220         } finally {
221             fin.close();
222         }
223     }
224 
225     public void testStringToByteArray()
226         throws Exception
227     {
228         FileReader fin = new FileReader( m_testFile );
229         try {
230             // Create our String. Rely on testReaderToString() to make sure this is valid.
231             String str = IOUtils.toString( fin );
232 
233             byte[] out = IOUtils.toByteArray( str );
234             assertEqualContent( str.getBytes(), out );
235         } finally {
236             fin.close();
237         }
238     }
239 
240     public void testByteArrayToWriter()
241         throws Exception
242     {
243         File destination = newFile( "copy7.txt" );
244         FileInputStream fin = new FileInputStream( m_testFile );
245         byte[] in;
246         try {
247             // Create our byte[]. Rely on testInputStreamToByteArray() to make sure this is valid.
248             in = IOUtils.toByteArray( fin );
249         } finally {
250             fin.close();
251         }
252 
253         FileWriter fout = new FileWriter( destination );
254         try {
255             CopyUtils.copy( in, fout );
256             fout.flush();
257             checkFile( destination, m_testFile );
258             checkWrite( fout );
259         } finally {
260             fout.close();
261         }
262         deleteFile( destination );
263     }
264 
265     public void testByteArrayToString()
266         throws Exception
267     {
268         FileInputStream fin = new FileInputStream( m_testFile );
269         try {
270             byte[] in = IOUtils.toByteArray( fin );
271             // Create our byte[]. Rely on testInputStreamToByteArray() to make sure this is valid.
272             String str = IOUtils.toString( in );
273             assertEqualContent( in, str.getBytes() );
274         } finally {
275             fin.close();
276         }
277     }
278 
279     /**
280      * Test for {@link IOUtils#toInputStream(String)} and {@link IOUtils#toInputStream(String, String)}.
281      * Note, this test utilizes on {@link IOUtils#toByteArray(java.io.InputStream)} and so relies on
282      * {@link #testInputStreamToByteArray()} to ensure this method functions correctly.
283      *
284      * @throws Exception on error
285      */
286     public void testStringToInputStream() throws Exception {
287         String str = "Abc123Xyz!";
288         InputStream inStream = IOUtils.toInputStream(str);
289         byte[] bytes = IOUtils.toByteArray(inStream);
290         assertEqualContent(str.getBytes(), bytes);
291         inStream = IOUtils.toInputStream(str, null);
292         bytes = IOUtils.toByteArray(inStream);
293         assertEqualContent(str.getBytes(), bytes);
294         inStream = IOUtils.toInputStream(str, "UTF-8");
295         bytes = IOUtils.toByteArray(inStream);
296         assertEqualContent(str.getBytes("UTF-8"), bytes);
297     }
298 
299     public void testByteArrayToOutputStream()
300         throws Exception
301     {
302         File destination = newFile( "copy8.txt" );
303         FileInputStream fin = new FileInputStream( m_testFile );
304         byte[] in;
305         try {
306             // Create our byte[]. Rely on testInputStreamToByteArray() to make sure this is valid.
307             in = IOUtils.toByteArray( fin );
308         } finally {
309             fin.close();
310         }
311 
312         FileOutputStream fout = new FileOutputStream( destination );
313         try {
314             CopyUtils.copy( in, fout );
315 
316             fout.flush();
317 
318             checkFile( destination, m_testFile );
319             checkWrite( fout );
320         } finally {
321             fout.close();
322         }
323         deleteFile( destination );
324     }
325 
326     public void testInputStreamToCharArray()
327             throws Exception
328     {
329         FileInputStream fin = new FileInputStream( m_testFile );
330         try {
331             char[] out = IOUtils.toCharArray( fin );
332             assertNotNull( out );
333             assertTrue( "Not all chars were read", fin.available() == 0 );
334             assertTrue( "Wrong output size: out.length=" + out.length +
335                         "!=" + FILE_SIZE, out.length == FILE_SIZE );
336             assertEqualContent( out, m_testFile );
337         } finally {
338             fin.close();
339         }
340     }
341 
342     public void testInputStreamToCharArrayWithEncoding()
343             throws Exception
344     {
345         FileInputStream fin = new FileInputStream( m_testFile );
346         try {
347             char[] out = IOUtils.toCharArray( fin , "UTF-8" );
348             assertNotNull( out );
349             assertTrue( "Not all chars were read", fin.available() == 0 );
350             assertTrue( "Wrong output size: out.length=" + out.length +
351                         "!=" + FILE_SIZE, out.length == FILE_SIZE );
352             assertEqualContent( out, m_testFile );
353         } finally {
354             fin.close();
355         }
356     }
357 
358     public void testReaderToCharArray()
359             throws Exception
360     {
361         FileReader fr = new FileReader( m_testFile );
362         try {
363             char[] out = IOUtils.toCharArray( fr );
364             assertNotNull( out );
365             assertTrue( "Wrong output size: out.length=" + out.length +
366                         "!=" + FILE_SIZE, out.length == FILE_SIZE );
367             assertEqualContent( out, m_testFile );
368         } finally {
369             fr.close();
370         }
371     }
372 
373     //-----------------------------------------------------------------------
374     public void testReadLines_InputStream() throws Exception {
375         File file = newFile("lines.txt");
376         InputStream in = null;
377         try {
378             String[] data = new String[] {"hello", "world", "", "this is", "some text"};
379             createLineBasedFile(file, data);
380             
381             in = new FileInputStream(file);
382             List lines = IOUtils.readLines(in);
383             assertEquals(Arrays.asList(data), lines);
384             assertEquals(-1, in.read());
385         } finally {
386             IOUtils.closeQuietly(in);
387             deleteFile(file);
388         }
389     }
390 
391     //-----------------------------------------------------------------------
392     public void testReadLines_InputStream_String() throws Exception {
393         File file = newFile("lines.txt");
394         InputStream in = null;
395         try {
396             String[] data = new String[] {"hello", "/u1234", "", "this is", "some text"};
397             createLineBasedFile(file, data);
398             
399             in = new FileInputStream(file);
400             List lines = IOUtils.readLines(in, "UTF-8");
401             assertEquals(Arrays.asList(data), lines);
402             assertEquals(-1, in.read());
403         } finally {
404             IOUtils.closeQuietly(in);
405             deleteFile(file);
406         }
407     }
408 
409     //-----------------------------------------------------------------------
410     public void testReadLines_Reader() throws Exception {
411         File file = newFile("lines.txt");
412         Reader in = null;
413         try {
414             String[] data = new String[] {"hello", "/u1234", "", "this is", "some text"};
415             createLineBasedFile(file, data);
416             
417             in = new InputStreamReader(new FileInputStream(file));
418             List lines = IOUtils.readLines(in);
419             assertEquals(Arrays.asList(data), lines);
420             assertEquals(-1, in.read());
421         } finally {
422             IOUtils.closeQuietly(in);
423             deleteFile(file);
424         }
425     }
426 
427 }