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(CharSequence)} and {@link IOUtils#toInputStream(CharSequence, 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 testCharSequenceToInputStream() throws Exception {
287         CharSequence csq = new StringBuilder("Abc123Xyz!");
288         InputStream inStream = IOUtils.toInputStream(csq);
289         byte[] bytes = IOUtils.toByteArray(inStream);
290         assertEqualContent(csq.toString().getBytes(), bytes);
291         inStream = IOUtils.toInputStream(csq, null);
292         bytes = IOUtils.toByteArray(inStream);
293         assertEqualContent(csq.toString().getBytes(), bytes);
294         inStream = IOUtils.toInputStream(csq, "UTF-8");
295         bytes = IOUtils.toByteArray(inStream);
296         assertEqualContent(csq.toString().getBytes("UTF-8"), bytes);
297     }
298 
299     /**
300      * Test for {@link IOUtils#toInputStream(String)} and {@link IOUtils#toInputStream(String, String)}.
301      * Note, this test utilizes on {@link IOUtils#toByteArray(java.io.InputStream)} and so relies on
302      * {@link #testInputStreamToByteArray()} to ensure this method functions correctly.
303      *
304      * @throws Exception on error
305      */
306     public void testStringToInputStream() throws Exception {
307         String str = "Abc123Xyz!";
308         InputStream inStream = IOUtils.toInputStream(str);
309         byte[] bytes = IOUtils.toByteArray(inStream);
310         assertEqualContent(str.getBytes(), bytes);
311         inStream = IOUtils.toInputStream(str, null);
312         bytes = IOUtils.toByteArray(inStream);
313         assertEqualContent(str.getBytes(), bytes);
314         inStream = IOUtils.toInputStream(str, "UTF-8");
315         bytes = IOUtils.toByteArray(inStream);
316         assertEqualContent(str.getBytes("UTF-8"), bytes);
317     }
318 
319     public void testByteArrayToOutputStream()
320         throws Exception
321     {
322         File destination = newFile( "copy8.txt" );
323         FileInputStream fin = new FileInputStream( m_testFile );
324         byte[] in;
325         try {
326             // Create our byte[]. Rely on testInputStreamToByteArray() to make sure this is valid.
327             in = IOUtils.toByteArray( fin );
328         } finally {
329             fin.close();
330         }
331 
332         FileOutputStream fout = new FileOutputStream( destination );
333         try {
334             CopyUtils.copy( in, fout );
335 
336             fout.flush();
337 
338             checkFile( destination, m_testFile );
339             checkWrite( fout );
340         } finally {
341             fout.close();
342         }
343         deleteFile( destination );
344     }
345 
346     public void testInputStreamToCharArray()
347             throws Exception
348     {
349         FileInputStream fin = new FileInputStream( m_testFile );
350         try {
351             char[] out = IOUtils.toCharArray( fin );
352             assertNotNull( out );
353             assertTrue( "Not all chars were read", fin.available() == 0 );
354             assertTrue( "Wrong output size: out.length=" + out.length +
355                         "!=" + FILE_SIZE, out.length == FILE_SIZE );
356             assertEqualContent( out, m_testFile );
357         } finally {
358             fin.close();
359         }
360     }
361 
362     public void testInputStreamToCharArrayWithEncoding()
363             throws Exception
364     {
365         FileInputStream fin = new FileInputStream( m_testFile );
366         try {
367             char[] out = IOUtils.toCharArray( fin , "UTF-8" );
368             assertNotNull( out );
369             assertTrue( "Not all chars were read", fin.available() == 0 );
370             assertTrue( "Wrong output size: out.length=" + out.length +
371                         "!=" + FILE_SIZE, out.length == FILE_SIZE );
372             assertEqualContent( out, m_testFile );
373         } finally {
374             fin.close();
375         }
376     }
377 
378     public void testReaderToCharArray()
379             throws Exception
380     {
381         FileReader fr = new FileReader( m_testFile );
382         try {
383             char[] out = IOUtils.toCharArray( fr );
384             assertNotNull( out );
385             assertTrue( "Wrong output size: out.length=" + out.length +
386                         "!=" + FILE_SIZE, out.length == FILE_SIZE );
387             assertEqualContent( out, m_testFile );
388         } finally {
389             fr.close();
390         }
391     }
392 
393     //-----------------------------------------------------------------------
394     public void testReadLines_InputStream() throws Exception {
395         File file = newFile("lines.txt");
396         InputStream in = null;
397         try {
398             String[] data = new String[] {"hello", "world", "", "this is", "some text"};
399             createLineBasedFile(file, data);
400             
401             in = new FileInputStream(file);
402             List lines = IOUtils.readLines(in);
403             assertEquals(Arrays.asList(data), lines);
404             assertEquals(-1, in.read());
405         } finally {
406             IOUtils.closeQuietly(in);
407             deleteFile(file);
408         }
409     }
410 
411     //-----------------------------------------------------------------------
412     public void testReadLines_InputStream_String() throws Exception {
413         File file = newFile("lines.txt");
414         InputStream in = null;
415         try {
416             String[] data = new String[] {"hello", "/u1234", "", "this is", "some text"};
417             createLineBasedFile(file, data);
418             
419             in = new FileInputStream(file);
420             List lines = IOUtils.readLines(in, "UTF-8");
421             assertEquals(Arrays.asList(data), lines);
422             assertEquals(-1, in.read());
423         } finally {
424             IOUtils.closeQuietly(in);
425             deleteFile(file);
426         }
427     }
428 
429     //-----------------------------------------------------------------------
430     public void testReadLines_Reader() throws Exception {
431         File file = newFile("lines.txt");
432         Reader in = null;
433         try {
434             String[] data = new String[] {"hello", "/u1234", "", "this is", "some text"};
435             createLineBasedFile(file, data);
436             
437             in = new InputStreamReader(new FileInputStream(file));
438             List lines = IOUtils.readLines(in);
439             assertEquals(Arrays.asList(data), lines);
440             assertEquals(-1, in.read());
441         } finally {
442             IOUtils.closeQuietly(in);
443             deleteFile(file);
444         }
445     }
446 
447 }