1 /*
2  * Copyright (C) 2013 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 java.io.IOException;
20 import java.nio.CharBuffer;
21 import junit.framework.TestCase;
22 
23 /**
24  * Tests for {@link CharSequenceReader}.
25  *
26  * @author Colin Decker
27  */
28 public class CharSequenceReaderTest extends TestCase {
29 
testReadEmptyString()30   public void testReadEmptyString() throws IOException {
31     assertReadsCorrectly("");
32   }
33 
testReadsStringsCorrectly()34   public void testReadsStringsCorrectly() throws IOException {
35     assertReadsCorrectly("abc");
36     assertReadsCorrectly("abcde");
37     assertReadsCorrectly("abcdefghijkl");
38     assertReadsCorrectly(
39         ""
40             + "abcdefghijklmnopqrstuvwxyz\n"
41             + "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r"
42             + "0123456789\r\n"
43             + "!@#$%^&*()-=_+\t[]{};':\",./<>?\\| ");
44   }
45 
testMarkAndReset()46   public void testMarkAndReset() throws IOException {
47     String string = "abcdefghijklmnopqrstuvwxyz";
48     CharSequenceReader reader = new CharSequenceReader(string);
49     assertTrue(reader.markSupported());
50 
51     assertEquals(string, readFully(reader));
52     assertFullyRead(reader);
53 
54     // reset and read again
55     reader.reset();
56     assertEquals(string, readFully(reader));
57     assertFullyRead(reader);
58 
59     // reset, skip, mark, then read the rest
60     reader.reset();
61     assertEquals(5, reader.skip(5));
62     reader.mark(Integer.MAX_VALUE);
63     assertEquals(string.substring(5), readFully(reader));
64     assertFullyRead(reader);
65 
66     // reset to the mark and then read the rest
67     reader.reset();
68     assertEquals(string.substring(5), readFully(reader));
69     assertFullyRead(reader);
70   }
71 
testIllegalArguments()72   public void testIllegalArguments() throws IOException {
73     CharSequenceReader reader = new CharSequenceReader("12345");
74 
75     char[] buf = new char[10];
76     try {
77       reader.read(buf, 0, 11);
78       fail();
79     } catch (IndexOutOfBoundsException expected) {
80     }
81 
82     try {
83       reader.read(buf, 10, 1);
84       fail();
85     } catch (IndexOutOfBoundsException expected) {
86     }
87 
88     try {
89       reader.read(buf, 11, 0);
90       fail();
91     } catch (IndexOutOfBoundsException expected) {
92     }
93 
94     try {
95       reader.read(buf, -1, 5);
96       fail();
97     } catch (IndexOutOfBoundsException expected) {
98     }
99 
100     try {
101       reader.read(buf, 5, -1);
102       fail();
103     } catch (IndexOutOfBoundsException expected) {
104     }
105 
106     try {
107       reader.read(buf, 0, 11);
108       fail();
109     } catch (IndexOutOfBoundsException expected) {
110     }
111 
112     try {
113       reader.skip(-1);
114       fail();
115     } catch (IllegalArgumentException expected) {
116     }
117 
118     try {
119       reader.mark(-1);
120       fail();
121     } catch (IllegalArgumentException expected) {
122     }
123   }
124 
testMethodsThrowWhenClosed()125   public void testMethodsThrowWhenClosed() throws IOException {
126     CharSequenceReader reader = new CharSequenceReader("");
127     reader.close();
128 
129     try {
130       reader.read();
131       fail();
132     } catch (IOException expected) {
133     }
134 
135     try {
136       reader.read(new char[10]);
137       fail();
138     } catch (IOException expected) {
139     }
140 
141     try {
142       reader.read(new char[10], 0, 10);
143       fail();
144     } catch (IOException expected) {
145     }
146 
147     try {
148       reader.read(CharBuffer.allocate(10));
149       fail();
150     } catch (IOException expected) {
151     }
152 
153     try {
154       reader.skip(10);
155       fail();
156     } catch (IOException expected) {
157     }
158 
159     try {
160       reader.ready();
161       fail();
162     } catch (IOException expected) {
163     }
164 
165     try {
166       reader.mark(10);
167       fail();
168     } catch (IOException expected) {
169     }
170 
171     try {
172       reader.reset();
173       fail();
174     } catch (IOException expected) {
175     }
176   }
177 
178   /**
179    * Creates a CharSequenceReader wrapping the given CharSequence and tests that the reader produces
180    * the same sequence when read using each type of read method it provides.
181    */
assertReadsCorrectly(CharSequence charSequence)182   private static void assertReadsCorrectly(CharSequence charSequence) throws IOException {
183     String expected = charSequence.toString();
184 
185     // read char by char
186     CharSequenceReader reader = new CharSequenceReader(charSequence);
187     for (int i = 0; i < expected.length(); i++) {
188       assertEquals(expected.charAt(i), reader.read());
189     }
190     assertFullyRead(reader);
191 
192     // read all to one array
193     reader = new CharSequenceReader(charSequence);
194     char[] buf = new char[expected.length()];
195     assertEquals(expected.length() == 0 ? -1 : expected.length(), reader.read(buf));
196     assertEquals(expected, new String(buf));
197     assertFullyRead(reader);
198 
199     // read in chunks to fixed array
200     reader = new CharSequenceReader(charSequence);
201     buf = new char[5];
202     StringBuilder builder = new StringBuilder();
203     int read;
204     while ((read = reader.read(buf, 0, buf.length)) != -1) {
205       builder.append(buf, 0, read);
206     }
207     assertEquals(expected, builder.toString());
208     assertFullyRead(reader);
209 
210     // read all to one CharBuffer
211     reader = new CharSequenceReader(charSequence);
212     CharBuffer buf2 = CharBuffer.allocate(expected.length());
213     assertEquals(expected.length() == 0 ? -1 : expected.length(), reader.read(buf2));
214     buf2.flip();
215     assertEquals(expected, buf2.toString());
216     assertFullyRead(reader);
217 
218     // read in chunks to fixed CharBuffer
219     reader = new CharSequenceReader(charSequence);
220     buf2 = CharBuffer.allocate(5);
221     builder = new StringBuilder();
222     while (reader.read(buf2) != -1) {
223       buf2.flip();
224       builder.append(buf2);
225       buf2.clear();
226     }
227     assertEquals(expected, builder.toString());
228     assertFullyRead(reader);
229 
230     // skip fully
231     reader = new CharSequenceReader(charSequence);
232     assertEquals(expected.length(), reader.skip(Long.MAX_VALUE));
233     assertFullyRead(reader);
234 
235     // skip 5 and read the rest
236     if (expected.length() > 5) {
237       reader = new CharSequenceReader(charSequence);
238       assertEquals(5, reader.skip(5));
239 
240       buf = new char[expected.length() - 5];
241       assertEquals(buf.length, reader.read(buf, 0, buf.length));
242       assertEquals(expected.substring(5), new String(buf));
243       assertFullyRead(reader);
244     }
245   }
246 
assertFullyRead(CharSequenceReader reader)247   private static void assertFullyRead(CharSequenceReader reader) throws IOException {
248     assertEquals(-1, reader.read());
249     assertEquals(-1, reader.read(new char[10], 0, 10));
250     assertEquals(-1, reader.read(CharBuffer.allocate(10)));
251     assertEquals(0, reader.skip(10));
252   }
253 
readFully(CharSequenceReader reader)254   private static String readFully(CharSequenceReader reader) throws IOException {
255     StringBuilder builder = new StringBuilder();
256     int read;
257     while ((read = reader.read()) != -1) {
258       builder.append((char) read);
259     }
260     return builder.toString();
261   }
262 }
263