View Javadoc

1   package au.com.bytecode.opencsv;
2   
3   /**
4    Copyright 2005 Bytecode Pty Ltd.
5   
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9   
10   http://www.apache.org/licenses/LICENSE-2.0
11  
12   Unless required by applicable law or agreed to in writing, software
13   distributed under the License is distributed on an "AS IS" BASIS,
14   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   See the License for the specific language governing permissions and
16   limitations under the License.
17   */
18  
19  import static org.junit.Assert.*;
20  import org.junit.Before;
21  import org.junit.Test;
22  
23  import java.io.IOException;
24  import java.io.StringReader;
25  
26  public class CSVReaderTest {
27  
28  	CSVReader csvr;
29  
30  	
31  	/**
32  	 * Setup the test.
33  	 */
34  	@Before
35  	public void setUp() throws Exception {
36  		StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
37  		sb.append("a,b,c").append("\n");   // standard case
38  		sb.append("a,\"b,b,b\",c").append("\n");  // quoted elements
39  		sb.append(",,").append("\n"); // empty elements
40  		sb.append("a,\"PO Box 123,\nKippax,ACT. 2615.\nAustralia\",d.\n");
41  		sb.append("\"Glen \"\"The Man\"\" Smith\",Athlete,Developer\n"); // Test quoted quote chars
42  		sb.append("\"\"\"\"\"\",\"test\"\n"); // """""","test"  representing:  "", test
43  		sb.append("\"a\nb\",b,\"\nd\",e\n");
44  		csvr = new CSVReader(new StringReader(sb.toString()));
45  	}
46  
47  
48  	/**
49  	 * Tests iterating over a reader.
50  	 * 
51  	 * @throws IOException
52  	 *             if the reader fails.
53  	 */
54  	@Test
55  	public void testParseLine() throws IOException {
56  
57  		// test normal case
58  		String[] nextLine = csvr.readNext();
59  		assertEquals("a", nextLine[0]);
60  		assertEquals("b", nextLine[1]);
61  		assertEquals("c", nextLine[2]);
62  
63  		// test quoted commas
64  		nextLine = csvr.readNext();
65  		assertEquals("a", nextLine[0]);
66  		assertEquals("b,b,b", nextLine[1]);
67  		assertEquals("c", nextLine[2]);
68  
69  		// test empty elements
70  		nextLine = csvr.readNext();
71  		assertEquals(3, nextLine.length);
72  		
73  		// test multiline quoted
74  		nextLine = csvr.readNext();
75  		assertEquals(3, nextLine.length);
76  		
77  		// test quoted quote chars
78  		nextLine = csvr.readNext();
79  		assertEquals("Glen \"The Man\" Smith", nextLine[0]);
80  		
81  		nextLine = csvr.readNext();
82  		assertTrue(nextLine[0].equals("\"\"")); // check the tricky situation
83  		assertTrue(nextLine[1].equals("test")); // make sure we didn't ruin the next field..
84  		
85  		nextLine = csvr.readNext();
86  		assertEquals(4, nextLine.length);
87  		
88  		//test end of stream
89  		assertNull(csvr.readNext());
90  
91  	}
92  
93      @Test
94      public void testParseLineStrictQuote() throws IOException {
95          StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
96  		sb.append("a,b,c").append("\n");   // standard case
97  		sb.append("a,\"b,b,b\",c").append("\n");  // quoted elements
98  		sb.append(",,").append("\n"); // empty elements
99  		sb.append("a,\"PO Box 123,\nKippax,ACT. 2615.\nAustralia\",d.\n");
100 		sb.append("\"Glen \"\"The Man\"\" Smith\",Athlete,Developer\n"); // Test quoted quote chars
101 		sb.append("\"\"\"\"\"\",\"test\"\n"); // """""","test"  representing:  "", test
102 		sb.append("\"a\nb\",b,\"\nd\",e\n");
103 		csvr = new CSVReader(new StringReader(sb.toString()), ',', '\"', true);
104         
105         // test normal case
106 		String[] nextLine = csvr.readNext();
107 		assertEquals("", nextLine[0]);
108 		assertEquals("", nextLine[1]);
109 		assertEquals("", nextLine[2]);
110 
111 		// test quoted commas
112 		nextLine = csvr.readNext();
113 		assertEquals("", nextLine[0]);
114 		assertEquals("b,b,b", nextLine[1]);
115 		assertEquals("", nextLine[2]);
116 
117 		// test empty elements
118 		nextLine = csvr.readNext();
119 		assertEquals(3, nextLine.length);
120 		
121 		// test multiline quoted
122 		nextLine = csvr.readNext();
123 		assertEquals(3, nextLine.length);
124 		
125 		// test quoted quote chars
126 		nextLine = csvr.readNext();
127 		assertEquals("Glen \"The Man\" Smith", nextLine[0]);
128 		
129 		nextLine = csvr.readNext();
130 		assertTrue(nextLine[0].equals("\"\"")); // check the tricky situation
131 		assertTrue(nextLine[1].equals("test")); // make sure we didn't ruin the next field..
132 		
133 		nextLine = csvr.readNext();
134 		assertEquals(4, nextLine.length);
135         assertEquals(nextLine[0], "a\nb");
136         assertEquals(nextLine[1], "");
137         assertEquals(nextLine[2], "\nd");
138         assertEquals(nextLine[3], "");
139 		
140 		//test end of stream
141 		assertNull(csvr.readNext());
142     }
143 
144 
145 	/**
146 	 * Test parsing to a list.
147 	 * 
148 	 * @throws IOException
149 	 *             if the reader fails.
150 	 */
151 	@Test
152 	public void testParseAll() throws IOException {
153 		assertEquals(7, csvr.readAll().size());
154 	}
155 	
156 	/**
157 	 * Tests constructors with optional delimiters and optional quote char.
158 	 * 
159 	 * @throws IOException if the reader fails.
160 	 */
161 	@Test
162 	public void testOptionalConstructors() throws IOException {
163 		
164 		StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
165 		sb.append("a\tb\tc").append("\n");   // tab separated case
166 		sb.append("a\t'b\tb\tb'\tc").append("\n");  // single quoted elements
167 		CSVReader c = new CSVReader(new StringReader(sb.toString()), '\t', '\'');
168 		
169 		String[] nextLine = c.readNext();
170 		assertEquals(3, nextLine.length);
171 
172 		nextLine = c.readNext();
173 		assertEquals(3, nextLine.length);
174 	}
175 
176     @Test
177     public void parseQuotedStringWithDefinedSeperator() throws IOException {
178         StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
179 		sb.append("a\tb\tc").append("\n");   // tab separated case
180 
181 		CSVReader c = new CSVReader(new StringReader(sb.toString()), '\t');
182 
183 		String[] nextLine = c.readNext();
184 		assertEquals(3, nextLine.length);
185 	
186     }
187 	
188 	/**
189 	 * Tests option to skip the first few lines of a file.
190 	 * 
191 	 * @throws IOException if bad things happen
192 	 */
193 	@Test
194 	public void testSkippingLines() throws IOException {
195 		
196 		StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
197 		sb.append("Skip this line\t with tab").append("\n");   // should skip this
198 		sb.append("And this line too").append("\n");   // and this
199 		sb.append("a\t'b\tb\tb'\tc").append("\n");  // single quoted elements
200 		CSVReader c = new CSVReader(new StringReader(sb.toString()), '\t', '\'', 2);
201 		
202 		String[] nextLine = c.readNext();
203 		assertEquals(3, nextLine.length);
204 		
205 		assertEquals("a", nextLine[0]);
206 	}
207 	
208 
209     /**
210 	 * Tests option to skip the first few lines of a file.
211 	 *
212 	 * @throws IOException if bad things happen
213 	 */
214 	@Test
215 	public void testSkippingLinesWithDifferentEscape() throws IOException {
216 
217 		StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
218 		sb.append("Skip this line?t with tab").append("\n");   // should skip this
219 		sb.append("And this line too").append("\n");   // and this
220 		sb.append("a\t'b\tb\tb'\t'c'").append("\n");  // single quoted elements
221 		CSVReader c = new CSVReader(new StringReader(sb.toString()), '\t', '\'', '?', 2);
222 
223 		String[] nextLine = c.readNext();
224 
225 		assertEquals(3, nextLine.length);
226 
227 		assertEquals("a", nextLine[0]);
228         assertEquals("c", nextLine[2]);
229 	}
230 	
231 	/**
232 	 * Test a normal non quoted line with three elements
233 	 * @throws IOException
234 	 */
235 	@Test
236 	public void testNormalParsedLine() throws IOException {
237 
238 		StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
239 
240 		sb.append("a,1234567,c").append("\n");// a,1234,c
241 
242 		CSVReader c = new CSVReader(new StringReader(sb.toString()));
243 
244 		String[] nextLine = c.readNext();
245 		assertEquals(3, nextLine.length);
246 
247 		assertEquals("a", nextLine[0]);
248 		assertEquals("1234567", nextLine[1]);
249 		assertEquals("c", nextLine[2]);
250 
251 	}
252 
253 	
254 
255 	
256 	/**
257 	 * Same as testADoubleQuoteAsDataElement but I changed the quotechar to a 
258 	 * single quote. 
259 	 * @throws IOException
260 	 */
261 	@Test
262 	public void testASingleQuoteAsDataElement() throws IOException {
263 
264 		StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
265 
266 		sb.append("a,'''',c").append("\n");// a,',c
267 
268 		CSVReader c = new CSVReader(new StringReader(sb.toString()), ',', '\'');
269 
270 		String[] nextLine = c.readNext();
271 		assertEquals(3, nextLine.length);
272 		
273 		assertEquals("a", nextLine[0]);
274 		assertEquals(1, nextLine[1].length());
275 		assertEquals("\'", nextLine[1]);
276 		assertEquals("c", nextLine[2]);
277 
278 	}
279 	
280 	/**
281 	 * Same as testADoubleQuoteAsDataElement but I changed the quotechar to a 
282 	 * single quote.  Also the middle field is empty. 
283 	 * @throws IOException
284 	 */
285 	@Test
286 	public void testASingleQuoteAsDataElementWithEmptyField() throws IOException {
287 
288 		StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
289 
290 		sb.append("a,'',c").append("\n");// a,,c
291 
292 		CSVReader c = new CSVReader(new StringReader(sb.toString()), ',', '\'');
293 
294 		String[] nextLine = c.readNext();
295 		assertEquals(3, nextLine.length);
296 		
297 		assertEquals("a", nextLine[0]);
298 		assertEquals(0, nextLine[1].length());
299 		assertEquals("", nextLine[1]);
300 		assertEquals("c", nextLine[2]);
301 
302 	}
303 	
304 
305 	
306 	@Test
307 	public void testEscapedQuote() throws IOException {
308 
309 		StringBuffer sb = new StringBuffer();
310 
311 		sb.append("a,\"123\\\"4567\",c").append("\n");// a,123"4",c
312 
313 		CSVReader c = new CSVReader(new StringReader(sb.toString()));
314 
315 		String[] nextLine = c.readNext();
316 		assertEquals(3, nextLine.length);
317 
318 		assertEquals("123\"4567", nextLine[1]);
319 
320 	}
321 
322 	@Test
323 	public void testEscapedEscape() throws IOException {
324 
325 		StringBuffer sb = new StringBuffer();
326 
327 		sb.append("a,\"123\\\\4567\",c").append("\n");// a,123"4",c
328 
329 		CSVReader c = new CSVReader(new StringReader(sb.toString()));
330 
331 		String[] nextLine = c.readNext();
332 		assertEquals(3, nextLine.length);
333 
334 		assertEquals("123\\4567", nextLine[1]);
335 
336 	}
337 
338 	
339 	/**
340 	 * Test a line where one of the elements is two single quotes and the 
341 	 * quote character is the default double quote.  The expected result is two 
342 	 * single quotes. 
343 	 * @throws IOException
344 	 */
345 	@Test
346 	public void testSingleQuoteWhenDoubleQuoteIsQuoteChar() throws IOException {
347 
348 		StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
349 
350 		sb.append("a,'',c").append("\n");// a,'',c
351 
352 		CSVReader c = new CSVReader(new StringReader(sb.toString()));
353 
354 		String[] nextLine = c.readNext();
355 		assertEquals(3, nextLine.length);
356 
357 		assertEquals("a", nextLine[0]);
358 		assertEquals(2, nextLine[1].length());
359 		assertEquals("''", nextLine[1]);
360 		assertEquals("c", nextLine[2]);
361 
362 	}
363 	
364 	/**
365 	 * Test a normal line with three elements and all elements are quoted
366 	 * @throws IOException
367 	 */
368 	@Test
369 	public void testQuotedParsedLine() throws IOException {
370 
371 		StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
372 
373 		sb.append("\"a\",\"1234567\",\"c\"").append("\n"); // "a","1234567","c"
374 
375 		CSVReader c = new CSVReader(new StringReader(sb.toString()));
376 
377 		String[] nextLine = c.readNext();
378 		assertEquals(3, nextLine.length);
379 
380 		assertEquals("a", nextLine[0]);
381 		assertEquals(1, nextLine[0].length());
382 		
383 		assertEquals("1234567", nextLine[1]);
384 		assertEquals("c", nextLine[2]);
385 
386 	}
387 
388 }