Home | History | Annotate | Download | only in io
      1 /*
      2  * Copyright (C) 2007 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.io;
     18 
     19 import com.google.common.base.Strings;
     20 import com.google.common.collect.ImmutableList;
     21 
     22 import java.io.EOFException;
     23 import java.io.FilterReader;
     24 import java.io.IOException;
     25 import java.io.Reader;
     26 import java.io.StringReader;
     27 import java.io.StringWriter;
     28 import java.io.Writer;
     29 import java.util.List;
     30 
     31 /**
     32  * Unit test for {@link CharStreams}.
     33  *
     34  * @author Chris Nokleberg
     35  */
     36 public class CharStreamsTest extends IoTestCase {
     37 
     38   private static final String TEXT
     39       = "The quick brown fox jumped over the lazy dog.";
     40 
     41   public void testToString() throws IOException {
     42     assertEquals(TEXT, CharStreams.toString(new StringReader(TEXT)));
     43   }
     44 
     45   public void testSkipFully_blockingRead() throws IOException {
     46     Reader reader = new NonSkippingReader("abcdef");
     47     CharStreams.skipFully(reader, 6);
     48     assertEquals(-1, reader.read());
     49   }
     50 
     51   private static class NonSkippingReader extends StringReader {
     52     NonSkippingReader(String s) {
     53       super(s);
     54     }
     55 
     56     @Override
     57     public long skip(long n) {
     58       return 0;
     59     }
     60   }
     61 
     62   public void testReadLines() throws IOException {
     63     List<String> lines = CharStreams.readLines(
     64         new StringReader("a\nb\nc"));
     65     assertEquals(ImmutableList.of("a", "b", "c"), lines);
     66   }
     67 
     68   public void testReadLines_withLineProcessor() throws IOException {
     69     String text = "a\nb\nc";
     70 
     71     // Test a LineProcessor that always returns false.
     72     Reader r = new StringReader(text);
     73     LineProcessor<Integer> alwaysFalse = new LineProcessor<Integer>() {
     74       int seen;
     75       @Override
     76       public boolean processLine(String line) {
     77         seen++;
     78         return false;
     79       }
     80       @Override
     81       public Integer getResult() {
     82         return seen;
     83       }
     84     };
     85     assertEquals("processLine was called more than once", 1,
     86         CharStreams.readLines(r, alwaysFalse).intValue());
     87 
     88     // Test a LineProcessor that always returns true.
     89     r = new StringReader(text);
     90     LineProcessor<Integer> alwaysTrue = new LineProcessor<Integer>() {
     91       int seen;
     92       @Override
     93       public boolean processLine(String line) {
     94         seen++;
     95         return true;
     96       }
     97       @Override
     98       public Integer getResult() {
     99         return seen;
    100       }
    101     };
    102     assertEquals("processLine was not called for all the lines", 3,
    103         CharStreams.readLines(r, alwaysTrue).intValue());
    104 
    105     // Test a LineProcessor that is conditional.
    106     r = new StringReader(text);
    107     final StringBuilder sb = new StringBuilder();
    108     LineProcessor<Integer> conditional = new LineProcessor<Integer>() {
    109       int seen;
    110       @Override
    111       public boolean processLine(String line) {
    112         seen++;
    113         sb.append(line);
    114         return seen < 2;
    115       }
    116       @Override
    117       public Integer getResult() {
    118         return seen;
    119       }
    120     };
    121     assertEquals(2, CharStreams.readLines(r, conditional).intValue());
    122     assertEquals("ab", sb.toString());
    123   }
    124 
    125   public void testSkipFully_EOF() throws IOException {
    126     Reader reader = new StringReader("abcde");
    127     try {
    128       CharStreams.skipFully(reader, 6);
    129       fail("expected EOFException");
    130     } catch (EOFException e) {
    131       // expected
    132     }
    133   }
    134 
    135   public void testSkipFully() throws IOException {
    136     String testString = "abcdef";
    137     Reader reader = new StringReader(testString);
    138 
    139     assertEquals(testString.charAt(0), reader.read());
    140     CharStreams.skipFully(reader, 1);
    141     assertEquals(testString.charAt(2), reader.read());
    142     CharStreams.skipFully(reader, 2);
    143     assertEquals(testString.charAt(5), reader.read());
    144 
    145     assertEquals(-1, reader.read());
    146   }
    147 
    148   public void testAsWriter() {
    149     // Should wrap Appendable in a new object
    150     Appendable plainAppendable = new StringBuilder();
    151     Writer result = CharStreams.asWriter(plainAppendable);
    152     assertNotSame(plainAppendable, result);
    153     assertNotNull(result);
    154 
    155     // A Writer should not be wrapped
    156     Appendable secretlyAWriter = new StringWriter();
    157     result = CharStreams.asWriter(secretlyAWriter);
    158     assertSame(secretlyAWriter, result);
    159   }
    160 
    161   public void testCopy() throws IOException {
    162     StringBuilder builder = new StringBuilder();
    163     long copied = CharStreams.copy(new StringReader(ASCII), builder);
    164     assertEquals(ASCII, builder.toString());
    165     assertEquals(ASCII.length(), copied);
    166 
    167     StringBuilder builder2 = new StringBuilder();
    168     copied = CharStreams.copy(new StringReader(I18N), builder2);
    169     assertEquals(I18N, builder2.toString());
    170     assertEquals(I18N.length(), copied);
    171   }
    172 
    173   /**
    174    * Test for Guava issue 1061: http://code.google.com/p/guava-libraries/issues/detail?id=1061
    175    *
    176    * <p>CharStreams.copy was failing to clear its CharBuffer after each read call, which effectively
    177    * reduced the available size of the buffer each time a call to read didn't fill up the available
    178    * space in the buffer completely. In general this is a performance problem since the buffer size
    179    * is permanently reduced, but with certain Reader implementations it could also cause the buffer
    180    * size to reach 0, causing an infinite loop.
    181    */
    182   public void testCopyWithReaderThatDoesNotFillBuffer() throws IOException {
    183     // need a long enough string for the buffer to hit 0 remaining before the copy completes
    184     String string = Strings.repeat("0123456789", 100);
    185     StringBuilder b = new StringBuilder();
    186     // the main assertion of this test is here... the copy will fail if the buffer size goes down
    187     // each time it is not filled completely
    188     long copied = CharStreams.copy(newNonBufferFillingReader(new StringReader(string)), b);
    189     assertEquals(string, b.toString());
    190     assertEquals(string.length(), copied);
    191   }
    192 
    193   public void testNullWriter() throws Exception {
    194     // create a null writer
    195     Writer nullWriter = CharStreams.nullWriter();
    196     // write to the writer
    197     nullWriter.write('n');
    198     String test = "Test string for NullWriter";
    199     nullWriter.write(test);
    200     nullWriter.write(test, 2, 10);
    201     // nothing really to assert?
    202     assertSame(CharStreams.nullWriter(), CharStreams.nullWriter());
    203   }
    204 
    205   /**
    206    * Returns a reader wrapping the given reader that only reads half of the maximum number of
    207    * characters that it could read in read(char[], int, int).
    208    */
    209   private static Reader newNonBufferFillingReader(Reader reader) {
    210     return new FilterReader(reader) {
    211       @Override
    212       public int read(char[] cbuf, int off, int len) throws IOException {
    213         // if a buffer isn't being cleared correctly, this method will eventually start being called
    214         // with a len of 0 forever
    215         if (len <= 0) {
    216           fail("read called with a len of " + len);
    217         }
    218         // read fewer than the max number of chars to read
    219         // shouldn't be a problem unless the buffer is shrinking each call
    220         return in.read(cbuf, off, Math.max(len - 1024, 0));
    221       }
    222     };
    223   }
    224 }
    225