• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static com.google.common.base.Charsets.UTF_8;
20 import static com.google.common.io.CharStreams.copy;
21 import static com.google.common.io.CharStreams.newReaderSupplier;
22 
23 import com.google.common.base.Charsets;
24 import com.google.common.collect.ImmutableList;
25 import com.google.common.collect.ImmutableSet;
26 import com.google.common.testing.TestLogHandler;
27 
28 import java.io.ByteArrayInputStream;
29 import java.io.EOFException;
30 import java.io.FilterReader;
31 import java.io.FilterWriter;
32 import java.io.IOException;
33 import java.io.InputStreamReader;
34 import java.io.Reader;
35 import java.io.StringReader;
36 import java.io.StringWriter;
37 import java.io.Writer;
38 import java.util.List;
39 
40 /**
41  * Unit test for {@link CharStreams}.
42  *
43  * @author Chris Nokleberg
44  */
45 public class CharStreamsTest extends IoTestCase {
46   private static final String TEXT
47       = "The quick brown fox jumped over the lazy dog.";
48 
49   static final InputSupplier<? extends Reader> BROKEN_READ
50       = CharStreams.newReaderSupplier(ByteStreamsTest.BROKEN_READ, UTF_8);
51 
52   static final OutputSupplier<? extends Writer> BROKEN_WRITE
53       = CharStreams.newWriterSupplier(ByteStreamsTest.BROKEN_WRITE, UTF_8);
54 
55   static final InputSupplier<? extends Reader> BROKEN_CLOSE_INPUT
56       = CharStreams.newReaderSupplier(ByteStreamsTest.BROKEN_CLOSE_INPUT, UTF_8);
57 
58   static final OutputSupplier<? extends Writer> BROKEN_CLOSE_OUTPUT
59       = CharStreams.newWriterSupplier(ByteStreamsTest.BROKEN_CLOSE_OUTPUT, UTF_8);
60 
61   static final InputSupplier<? extends Reader> BROKEN_GET_INPUT
62       = CharStreams.newReaderSupplier(ByteStreamsTest.BROKEN_GET_INPUT, UTF_8);
63 
64   static final OutputSupplier<? extends Writer> BROKEN_GET_OUTPUT
65       = CharStreams.newWriterSupplier(ByteStreamsTest.BROKEN_GET_OUTPUT, UTF_8);
66 
67   private static final ImmutableSet<InputSupplier<? extends Reader>> BROKEN_INPUTS =
68       ImmutableSet.of(BROKEN_CLOSE_INPUT, BROKEN_GET_INPUT, BROKEN_READ);
69   private static final ImmutableSet<OutputSupplier<? extends Writer>> BROKEN_OUTPUTS
70       = ImmutableSet.of(BROKEN_CLOSE_OUTPUT, BROKEN_GET_OUTPUT, BROKEN_WRITE);
71 
testToString()72   public void testToString() throws IOException {
73     assertEquals(TEXT, CharStreams.toString(new StringReader(TEXT)));
74     assertEquals(TEXT,
75         CharStreams.toString(CharStreams.newReaderSupplier(TEXT)));
76   }
77 
testSkipFully_blockingRead()78   public void testSkipFully_blockingRead() throws IOException {
79     Reader reader = new NonSkippingReader("abcdef");
80     CharStreams.skipFully(reader, 6);
81     assertEquals(-1, reader.read());
82   }
83 
84   private static class NonSkippingReader extends StringReader {
NonSkippingReader(String s)85     NonSkippingReader(String s) {
86       super(s);
87     }
88 
89     @Override
skip(long n)90     public long skip(long n) {
91       return 0;
92     }
93   }
94 
testReadLines_fromReadable()95   public void testReadLines_fromReadable() throws IOException {
96     byte[] bytes = "a\nb\nc".getBytes(Charsets.UTF_8.name());
97     List<String> lines = CharStreams.readLines(
98         new InputStreamReader(new ByteArrayInputStream(bytes), Charsets.UTF_8));
99     assertEquals(ImmutableList.of("a", "b", "c"), lines);
100   }
101 
testReadLines_withLineProcessor()102   public void testReadLines_withLineProcessor() throws IOException {
103     InputSupplier<StringReader> r = CharStreams.newReaderSupplier("a\nb\nc");
104 
105     // Test a LineProcessor that always returns false.
106     LineProcessor<Integer> alwaysFalse = new LineProcessor<Integer>() {
107       int seen;
108       @Override
109       public boolean processLine(String line) {
110         seen++;
111         return false;
112       }
113       @Override
114       public Integer getResult() {
115         return seen;
116       }
117     };
118     assertEquals("processLine was called more than once", 1,
119         CharStreams.readLines(r, alwaysFalse).intValue());
120 
121     // Test a LineProcessor that always returns true.
122     LineProcessor<Integer> alwaysTrue = new LineProcessor<Integer>() {
123       int seen;
124       @Override
125       public boolean processLine(String line) {
126         seen++;
127         return true;
128       }
129       @Override
130       public Integer getResult() {
131         return seen;
132       }
133     };
134     assertEquals("processLine was not called for all the lines", 3,
135         CharStreams.readLines(r, alwaysTrue).intValue());
136 
137     // Test a LineProcessor that is conditional.
138     final StringBuilder sb = new StringBuilder();
139     LineProcessor<Integer> conditional = new LineProcessor<Integer>() {
140       int seen;
141       @Override
142       public boolean processLine(String line) {
143         seen++;
144         sb.append(line);
145         return seen < 2;
146       }
147       @Override
148       public Integer getResult() {
149         return seen;
150       }
151     };
152     assertEquals(2, CharStreams.readLines(r, conditional).intValue());
153     assertEquals("ab", sb.toString());
154   }
155 
testAlwaysCloses()156   public void testAlwaysCloses() throws IOException {
157     CheckCloseSupplier.Input<Reader> okRead
158         = newCheckReader(CharStreams.newReaderSupplier(TEXT));
159     CheckCloseSupplier.Output<Writer> okWrite
160         = newCheckWriter(new OutputSupplier<Writer>() {
161           @Override
162           public Writer getOutput() {
163             return new StringWriter();
164           }
165         });
166     CheckCloseSupplier.Input<Reader> brokenRead = newCheckReader(BROKEN_READ);
167     CheckCloseSupplier.Output<Writer> brokenWrite
168         = newCheckWriter(BROKEN_WRITE);
169 
170     CharStreams.copy(okRead, okWrite);
171     assertTrue(okRead.areClosed());
172     assertTrue(okWrite.areClosed());
173 
174     try {
175       CharStreams.copy(okRead, brokenWrite);
176       fail("expected exception");
177     } catch (Exception e) {
178       assertEquals("broken write", e.getMessage());
179     }
180     assertTrue(okRead.areClosed());
181     assertTrue(brokenWrite.areClosed());
182 
183     try {
184       CharStreams.copy(brokenRead, okWrite);
185       fail("expected exception");
186     } catch (Exception e) {
187       assertEquals("broken read", e.getMessage());
188     }
189     assertTrue(brokenRead.areClosed());
190     assertTrue(okWrite.areClosed());
191 
192     try {
193       CharStreams.copy(brokenRead, brokenWrite);
194       fail("expected exception");
195     } catch (Exception e) {
196       assertEquals("broken read", e.getMessage());
197     }
198     assertTrue(brokenRead.areClosed());
199     assertTrue(brokenWrite.areClosed());
200 
201     assertEquals(TEXT, CharStreams.toString(okRead));
202     assertTrue(okRead.areClosed());
203 
204     try {
205       CharStreams.toString(brokenRead);
206       fail("expected exception");
207     } catch (Exception e) {
208       assertEquals("broken read", e.getMessage());
209     }
210     assertTrue(brokenRead.areClosed());
211 
212     try {
213       CharStreams.write("hello world", brokenWrite);
214       fail("expected exception");
215     } catch (Exception e) {
216       assertEquals("broken write", e.getMessage());
217     }
218     assertTrue(brokenWrite.areClosed());
219   }
220 
getAndResetRecords(TestLogHandler logHandler)221   private static int getAndResetRecords(TestLogHandler logHandler) {
222     int records = logHandler.getStoredLogRecords().size();
223     logHandler.clear();
224     return records;
225   }
226 
runFailureTest( InputSupplier<? extends Reader> in, OutputSupplier<? extends Writer> out)227   private static void runFailureTest(
228       InputSupplier<? extends Reader> in, OutputSupplier<? extends Writer> out) {
229     try {
230       copy(in, out);
231       fail();
232     } catch (IOException expected) {
233     }
234   }
235 
newStringWriterSupplier()236   private static OutputSupplier<Writer> newStringWriterSupplier() {
237     return new OutputSupplier<Writer>() {
238       @Override public Writer getOutput() {
239         return new StringWriter();
240       }
241     };
242   }
243 
244   public void testSkipFully_EOF() throws IOException {
245     Reader reader = new StringReader("abcde");
246     try {
247       CharStreams.skipFully(reader, 6);
248       fail("expected EOFException");
249     } catch (EOFException e) {
250       // expected
251     }
252   }
253 
254   public void testSkipFully() throws IOException {
255     String testString = "abcdef";
256     Reader reader = new StringReader(testString);
257 
258     assertEquals(testString.charAt(0), reader.read());
259     CharStreams.skipFully(reader, 1);
260     assertEquals(testString.charAt(2), reader.read());
261     CharStreams.skipFully(reader, 2);
262     assertEquals(testString.charAt(5), reader.read());
263 
264     assertEquals(-1, reader.read());
265   }
266 
267   public void testAsWriter() {
268     // Should wrap Appendable in a new object
269     Appendable plainAppendable = new StringBuilder();
270     Writer result = CharStreams.asWriter(plainAppendable);
271     assertNotSame(plainAppendable, result);
272     assertNotNull(result);
273 
274     // A Writer should not be wrapped
275     Appendable secretlyAWriter = new StringWriter();
276     result = CharStreams.asWriter(secretlyAWriter);
277     assertSame(secretlyAWriter, result);
278   }
279 
280   public void testWriteString() throws IOException {
281     final StringWriter sw = new StringWriter();
282     String expected = "foo";
283     CharStreams.write(expected, new OutputSupplier<Writer>() {
284       @Override public Writer getOutput() {
285         return sw;
286       }
287     });
288     assertEquals(expected, sw.toString());
289   }
290 
291   private static CheckCloseSupplier.Input<Reader> newCheckReader(
292       InputSupplier<? extends Reader> delegate) {
293     return new CheckCloseSupplier.Input<Reader>(delegate) {
294       @Override protected Reader wrap(Reader object, final Callback callback) {
295         return new FilterReader(object) {
296           @Override public void close() throws IOException {
297             callback.delegateClosed();
298             super.close();
299           }
300         };
301       }
302     };
303   }
304 
305   private static CheckCloseSupplier.Output<Writer> newCheckWriter(
306       OutputSupplier<? extends Writer> delegate) {
307     return new CheckCloseSupplier.Output<Writer>(delegate) {
308       @Override protected Writer wrap(Writer object, final Callback callback) {
309         return new FilterWriter(object) {
310           @Override public void close() throws IOException {
311             callback.delegateClosed();
312             super.close();
313           }
314         };
315       }
316     };
317   }
318 }
319