View Javadoc

1   package au.com.bytecode.opencsv;
2   /**
3    * Created by IntelliJ IDEA.
4    * User: Scott Conway
5    * Date: Oct 7, 2009
6    * Time: 9:56:48 PM
7    */
8   
9   import static org.junit.Assert.*;
10  import org.junit.Before;
11  import org.junit.Test;
12  
13  import java.io.IOException;
14  
15  public class CSVParserTest{
16  
17      CSVParser csvParser;
18  
19      @Before
20      public void setUp() {
21          csvParser = new CSVParser();
22      }
23  
24      @Test
25      public void testParseLine() throws Exception {
26          String nextItem[] = csvParser.parseLine("This, is, a, test.");
27          assertEquals(4, nextItem.length);
28          assertEquals("This", nextItem[0]);
29          assertEquals(" is", nextItem[1]);
30          assertEquals(" a", nextItem[2]);
31          assertEquals(" test.", nextItem[3]);
32      }
33  
34  
35      @Test
36      public void parseSimpleString() throws IOException {
37  
38          String[] nextLine = csvParser.parseLine("a,b,c");
39          assertEquals(3, nextLine.length);
40  		assertEquals("a", nextLine[0]);
41  		assertEquals("b", nextLine[1]);
42  		assertEquals("c", nextLine[2]);
43          assertFalse(csvParser.isPending());
44      }
45  
46      /**
47  	 * Tests quotes in the middle of an element.
48  	 *
49  	 * @throws IOException if bad things happen
50  	 */
51  	@Test
52  	public void testParsedLineWithInternalQuota() throws IOException {
53  
54  		String[] nextLine = csvParser.parseLine("a,123\"4\"567,c");
55  		assertEquals(3, nextLine.length);
56  
57  		assertEquals("123\"4\"567", nextLine[1]);
58  
59  	}
60  
61      @Test
62      public void parseQuotedStringWithCommas() throws IOException{
63          String[] nextLine = csvParser.parseLine("a,\"b,b,b\",c");
64  		assertEquals("a", nextLine[0]);
65  		assertEquals("b,b,b", nextLine[1]);
66  		assertEquals("c", nextLine[2]);
67          assertEquals(3, nextLine.length);
68      }
69  
70      @Test
71      public void parseQuotedStringWithDefinedSeperator() throws IOException{
72          csvParser = new CSVParser(':');
73  
74          String[] nextLine = csvParser.parseLine("a:\"b:b:b\":c");
75  		assertEquals("a", nextLine[0]);
76  		assertEquals("b:b:b", nextLine[1]);
77  		assertEquals("c", nextLine[2]);
78          assertEquals(3, nextLine.length);
79      }
80  
81      @Test
82      public void parseQuotedStringWithDefinedSeperatorAndQuote() throws IOException{
83          csvParser = new CSVParser(':', '\'');
84  
85          String[] nextLine = csvParser.parseLine("a:'b:b:b':c");
86  		assertEquals("a", nextLine[0]);
87  		assertEquals("b:b:b", nextLine[1]);
88  		assertEquals("c", nextLine[2]);
89          assertEquals(3, nextLine.length);
90      }
91  
92      @Test
93      public void parseEmptyElements() throws IOException {
94          String [] nextLine = csvParser.parseLine(",,");
95  		assertEquals(3, nextLine.length);
96          assertEquals("", nextLine[0]);
97          assertEquals("", nextLine[1]);
98          assertEquals("", nextLine[2]);
99      }
100 
101     @Test
102     public void parseMultiLinedQuoted() throws IOException {
103         String[] nextLine = csvParser.parseLine("a,\"PO Box 123,\nKippax,ACT. 2615.\nAustralia\",d.\n");
104 		assertEquals(3, nextLine.length);
105         assertEquals("a", nextLine[0]);
106         assertEquals("PO Box 123,\nKippax,ACT. 2615.\nAustralia", nextLine[1]);
107         assertEquals("d.\n", nextLine[2]);
108     }
109 
110 	@Test
111 	public void testADoubleQuoteAsDataElement() throws IOException {
112 
113 		String[] nextLine = csvParser.parseLine("a,\"\"\"\",c");// a,"""",c
114 
115 		assertEquals(3, nextLine.length);
116 
117 		assertEquals("a", nextLine[0]);
118 		assertEquals(1, nextLine[1].length());
119 		assertEquals("\"", nextLine[1]);
120 		assertEquals("c", nextLine[2]);
121 
122 	}
123 
124 	@Test
125 	public void testEscapedDoubleQuoteAsDataElement() throws IOException {
126 
127 		StringBuilder sb = new StringBuilder(CSVParser.INITIAL_READ_SIZE);
128 
129 		String[] nextLine = csvParser.parseLine("\"test\",\"this,test,is,good\",\"\\\"test\\\"\",\"\\\"quote\\\"\""); // "test","this,test,is,good","\"test\",\"quote\""
130 
131 		assertEquals(4, nextLine.length);
132 
133 		assertEquals("test", nextLine[0]);
134 		assertEquals("this,test,is,good", nextLine[1]);
135 		assertEquals("\"test\"", nextLine[2]);
136 		assertEquals("\"quote\"", nextLine[3]);
137 
138 	}
139     @Test
140     public void parseQuotedQuoteCharacters() throws IOException {
141         String[] nextLine = csvParser.parseLineMulti("\"Glen \"\"The Man\"\" Smith\",Athlete,Developer\n");
142         assertEquals(3, nextLine.length);
143 		assertEquals("Glen \"The Man\" Smith", nextLine[0]);
144         assertEquals("Athlete", nextLine[1]);
145         assertEquals("Developer\n", nextLine[2]);
146     }
147 
148     @Test
149     public void parseMultipleQuotes() throws IOException {
150         String[] nextLine = csvParser.parseLine("\"\"\"\"\"\",\"test\"\n"); // """""","test"  representing:  "", test
151 		assertEquals("\"\"",nextLine[0]); // check the tricky situation
152 		assertEquals("test\"\n", nextLine[1]); // make sure we didn't ruin the next field..
153         assertEquals(2, nextLine.length);
154     }
155 
156     @Test
157     public void parseTrickyString() throws IOException {
158         String[] nextLine = csvParser.parseLine("\"a\nb\",b,\"\nd\",e\n");
159 		assertEquals(4, nextLine.length);
160         assertEquals("a\nb", nextLine[0]);
161         assertEquals("b", nextLine[1]);
162         assertEquals("\nd", nextLine[2]);
163         assertEquals("e\n", nextLine[3]);
164     }
165 
166     private String setUpMultiLineInsideQuotes(){
167         StringBuffer sb = new StringBuffer(CSVParser.INITIAL_READ_SIZE);
168 
169         sb.append("Small test,\"This is a test across \ntwo lines.\"");
170 
171         return sb.toString();
172     }
173 
174     @Test
175     public void testAMultiLineInsideQuotes() throws IOException {
176 
177         String testString = setUpMultiLineInsideQuotes();
178 
179 		String[] nextLine = csvParser.parseLine(testString);
180         assertEquals(2, nextLine.length);
181 		assertEquals("Small test", nextLine[0]);
182         assertEquals("This is a test across \ntwo lines.", nextLine[1]);
183         assertFalse(csvParser.isPending());
184     }
185 
186     @Test
187     public void testStrictQuoteSimple() throws IOException {
188         csvParser = new CSVParser (',', '\"', '\\', true);
189         String testString = "\"a\",\"b\",\"c\"";
190 
191         String[] nextLine = csvParser.parseLine(testString);
192         assertEquals(3, nextLine.length);
193         assertEquals("a", nextLine[0]);
194         assertEquals("b", nextLine[1]);
195         assertEquals("c", nextLine[2]);
196     }
197 
198     @Test
199     public void testStrictQuoteWithSpacesAndTabs() throws IOException {
200         csvParser = new CSVParser (',', '\"', '\\', true);
201         String testString = " \t      \"a\",\"b\"      \t       ,   \"c\"   ";
202 
203         String[] nextLine = csvParser.parseLine(testString);
204         assertEquals(3, nextLine.length);
205         assertEquals("a", nextLine[0]);
206         assertEquals("b", nextLine[1]);
207         assertEquals("c", nextLine[2]);
208     }
209 
210     @Test
211     public void testStrictQuoteWithGarbage() throws IOException {
212         csvParser = new CSVParser (',', '\"', '\\', true);
213         String testString = "abc',!@#\",\\\"\"   xyz,";
214 
215         String[] nextLine = csvParser.parseLine(testString);
216         assertEquals(3, nextLine.length);
217         assertEquals("", nextLine[0]);
218         assertEquals(",\"", nextLine[1]);
219         assertEquals("", nextLine[2]);
220     }
221 
222     	/**
223 	 * Test issue 2263439 where an escaped quote was causing the parse to fail.
224 	 *
225 	 * Special thanks to Chris Morris for fixing this (id 1979054)
226 	 * @throws IOException
227 	 *
228 	 */
229 	@Test
230 	public void testIssue2263439() throws IOException {
231         csvParser = new CSVParser(',', '\'');
232             
233 		String[] nextLine = csvParser.parseLine("865,0,'AmeriKKKa\\'s_Most_Wanted','',294,0,0,0.734338696798625,'20081002052147',242429208,18448");
234 
235 		assertEquals(11, nextLine.length);
236 
237 		assertEquals("865", nextLine[0]);
238 		assertEquals("0", nextLine[1]);
239 		assertEquals("AmeriKKKa's_Most_Wanted", nextLine[2]);
240 		assertEquals("", nextLine[3]);
241 		assertEquals("18448", nextLine[10]);
242 
243 	}
244 
245 	/**
246 	 * Test issue 2859181 where an escaped character before a character
247 	 * that did not need escaping was causing the parse to fail.
248 	 *
249 	 * @throws IOException
250 	 *
251 	 */
252 	@Test
253 	public void testIssue2859181() throws IOException {
254         csvParser = new CSVParser(';');
255 		String[] nextLine = csvParser.parseLine("field1;\\=field2;\"\"\"field3\"\"\"");
256 
257 		assertEquals(3, nextLine.length);
258 
259 		assertEquals("field1", nextLine[0]);
260 		assertEquals("=field2", nextLine[1]);
261 		assertEquals("\"field3\"", nextLine[2]);
262 
263 	}
264 
265     	/**
266 	 * Test issue 2726363
267 	 *
268 	 * Data given:
269 	 *
270 	 *	"804503689","London",""London""shop","address","116.453182","39.918884"
271 	 *	"453074125","NewYork","brief","address"","121.514683","31.228511"
272 	 */
273 	@Test
274 	public void testIssue2726363() throws IOException {    
275 
276 		String[] nextLine = csvParser.parseLine("\"804503689\",\"London\",\"\"London\"shop\",\"address\",\"116.453182\",\"39.918884\"");
277 
278 		assertEquals(6, nextLine.length);
279 
280 
281 		assertEquals("804503689", nextLine[0]);
282 		assertEquals("London", nextLine[1]);
283 		assertEquals("\"London\"shop", nextLine[2]);
284 		assertEquals("address", nextLine[3]);
285 		assertEquals("116.453182", nextLine[4]);
286 		assertEquals("39.918884", nextLine[5]);
287 
288 	}
289 
290     @Test(expected=IOException.class)
291     public void anIOExceptionThrownifStringEndsInsideAQuotedString() throws IOException {
292         String[] nextLine = csvParser.parseLine("This,is a \"bad line to parse.");
293 
294 
295     }
296 
297     @Test
298     public void parseLineMultiAllowsQuotesAcrossMultipleLines() throws IOException {
299         String[] nextLine = csvParser.parseLineMulti("This,\"is a \"good\" line\\\\ to parse");
300 
301         assertEquals(1, nextLine.length);
302         assertEquals("This", nextLine[0]);
303         assertTrue(csvParser.isPending());
304 
305         nextLine = csvParser.parseLineMulti("because we are using parseLineMulti.\"");
306 
307         assertEquals(1, nextLine.length);
308         assertEquals("is a \"good\" line\\ to parse\nbecause we are using parseLineMulti.", nextLine[0]);
309         assertFalse(csvParser.isPending());
310     }
311 
312     @Test
313     public void pendingIsClearedAfterCallToParseLine() throws IOException {
314         String[] nextLine = csvParser.parseLineMulti("This,\"is a \"good\" line\\\\ to parse");
315 
316         assertEquals(1, nextLine.length);
317         assertEquals("This", nextLine[0]);
318         assertTrue(csvParser.isPending());
319 
320         nextLine = csvParser.parseLine("because we are using parseLineMulti.");
321 
322         assertEquals(1, nextLine.length);
323         assertEquals("because we are using parseLineMulti.", nextLine[0]);
324         assertFalse(csvParser.isPending());
325     }
326 
327     @Test
328     public void returnPendingIfNullIsPassedIntoParseLineMulti() throws IOException {
329         String[] nextLine = csvParser.parseLineMulti("This,\"is a \"goo\\d\" line\\\\ to parse\\");
330 
331         assertEquals(1, nextLine.length);
332         assertEquals("This", nextLine[0]);
333         assertTrue(csvParser.isPending());
334 
335         nextLine = csvParser.parseLineMulti(null);
336 
337         assertEquals(1, nextLine.length);
338         assertEquals("is a \"good\" line\\ to parse\n", nextLine[0]);
339         assertFalse(csvParser.isPending());
340     }
341 
342     @Test
343     public void returnNullWhenNullPassedIn() throws IOException {
344         String[] nextLine = csvParser.parseLine(null);
345         assertNull(nextLine);
346     }
347 
348         private static final String ESCAPE_TEST_STRING = "\\\\1\\2\\\"3\\"; // \\1\2\"\
349 
350     @Test
351     public void validateEscapeStringBeforeRealTest(){
352         assertNotNull(ESCAPE_TEST_STRING);
353         assertEquals(9, ESCAPE_TEST_STRING.length());
354     }
355 
356     @Test
357     public void whichCharactersAreEscapable(){
358         assertTrue(csvParser.isNextCharacterEscapable(ESCAPE_TEST_STRING, true, 0));
359         assertFalse(csvParser.isNextCharacterEscapable(ESCAPE_TEST_STRING, false, 0));
360         // Second character is not escapable because there is a non quote or non slash after it. 
361         assertFalse(csvParser.isNextCharacterEscapable(ESCAPE_TEST_STRING, true, 1));
362         assertFalse(csvParser.isNextCharacterEscapable(ESCAPE_TEST_STRING, false, 1));
363         // Fourth character is not escapable because there is a non quote or non slash after it.
364         assertFalse(csvParser.isNextCharacterEscapable(ESCAPE_TEST_STRING, true, 3));
365         assertFalse(csvParser.isNextCharacterEscapable(ESCAPE_TEST_STRING, false, 3));
366 
367         assertTrue(csvParser.isNextCharacterEscapable(ESCAPE_TEST_STRING, true, 5));
368         assertFalse(csvParser.isNextCharacterEscapable(ESCAPE_TEST_STRING, false, 5));
369 
370         int lastChar = ESCAPE_TEST_STRING.length() - 1;
371         assertFalse(csvParser.isNextCharacterEscapable(ESCAPE_TEST_STRING, true, lastChar));
372         assertFalse(csvParser.isNextCharacterEscapable(ESCAPE_TEST_STRING, false, lastChar));
373 
374     }
375 
376 }