View Javadoc
1   package com.opencsv;
2   /*
3    Copyright 2015 Bytecode Pty Ltd.
4   
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8   
9    http://www.apache.org/licenses/LICENSE-2.0
10  
11   Unless required by applicable law or agreed to in writing, software
12   distributed under the License is distributed on an "AS IS" BASIS,
13   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   See the License for the specific language governing permissions and
15   limitations under the License.
16   */
17  
18  import org.junit.jupiter.api.Assertions;
19  import org.junit.jupiter.api.Test;
20  import org.mockito.stubbing.Answer;
21  
22  import java.io.*;
23  import java.sql.ResultSet;
24  import java.sql.SQLException;
25  import java.util.*;
26  
27  import static org.junit.jupiter.api.Assertions.*;
28  import static org.mockito.Matchers.anyInt;
29  import static org.mockito.Matchers.anyString;
30  import static org.mockito.Mockito.*;
31  
32  public class CSVWriterTest {
33  
34     private static final String SIMPLE_STRING = "XXX";
35     private static final String[] SIMPLE_STRING_ARRAY = new String[]{SIMPLE_STRING};
36  
37     /**
38      * Test routine for converting output to a string.
39      *
40      * @param args the elements of a line of the cvs file
41      * @return a String version
42      */
43     private String invokeWriter(String ... args) {
44        StringWriter sw = new StringWriter();
45        ICSVWriter csvw = new CSVWriterBuilder(sw)
46                .withSeparator(',')
47                .withQuoteChar('\'')
48                .build();
49        csvw.writeNext(args);
50        return sw.toString();
51     }
52  
53     private String invokeNoEscapeWriter(String ... args) {
54        StringWriter sw = new StringWriter();
55        ICSVWriter csvw = new CSVWriterBuilder(sw)
56                .withSeparator(ICSVWriter.DEFAULT_SEPARATOR)
57                .withQuoteChar('\'')
58                .withEscapeChar(ICSVWriter.NO_ESCAPE_CHARACTER)
59                .build();
60        csvw.writeNext(args);
61        return sw.toString();
62     }
63  
64     @Test
65     public void correctlyParseNullString() {
66        StringWriter sw = new StringWriter();
67        ICSVWriter csvw = new CSVWriterBuilder(sw)
68                .withSeparator(',')
69                .withQuoteChar('\'')
70                .build();
71        csvw.writeNext(null);
72        assertEquals(0, sw.toString().length());
73     }
74  
75     @Test
76     public void correctlyParserNullObject() {
77        StringWriter sw = new StringWriter();
78        ICSVWriter csvw = new CSVWriterBuilder(sw)
79                .withSeparator(',')
80                .withQuoteChar('\'')
81                .build();
82        csvw.writeNext(null, false);
83        assertEquals(0, sw.toString().length());
84     }
85  
86     /**
87      * Tests parsing individual lines.
88      */
89     @Test
90     public void testParseLine() {
91  
92        // test normal case
93        String[] normal = {"a", "b", "c"};
94        String output = invokeWriter(normal);
95        assertEquals("'a','b','c'\n", output);
96  
97        // test quoted commas
98        String[] quoted = {"a", "b,b,b", "c"};
99        output = invokeWriter(quoted);
100       assertEquals("'a','b,b,b','c'\n", output);
101 
102       // test empty elements
103       String[] empty = {,};
104       output = invokeWriter(empty);
105       assertEquals("\n", output);
106 
107       // test multiline quoted
108       String[] multiline = {"This is a \n multiline entry", "so is \n this"};
109       output = invokeWriter(multiline);
110       assertEquals("'This is a \n multiline entry','so is \n this'\n", output);
111 
112 
113       // test quoted line
114       String[] quoteLine = {"This is a \" multiline entry", "so is \n this"};
115       output = invokeWriter(quoteLine);
116       assertEquals("'This is a \"\" multiline entry','so is \n this'\n", output);
117 
118    }
119 
120    @Test
121    public void testSpecialCharacters() {
122       // test quoted line
123       String output = invokeWriter("This is a \r multiline entry", "so is \n this");
124       assertEquals("'This is a \r multiline entry','so is \n this'\n", output);
125    }
126 
127    @Test
128    public void parseLineWithBothEscapeAndQuoteChar() {
129       // test quoted line
130       String output = invokeWriter("This is a 'multiline' entry", "so is \n this");
131       assertEquals("'This is a \"'multiline\"' entry','so is \n this'\n", output);
132    }
133 
134    /**
135     * Tests parsing individual lines.
136     */
137    @Test
138    public void testParseLineWithNoEscapeChar() {
139 
140       // test normal case
141       String[] normal = {"a", "b", "c"};
142       String output = invokeNoEscapeWriter(normal);
143       assertEquals("'a','b','c'\n", output);
144 
145       // test quoted commas
146       String[] quoted = {"a", "b,b,b", "c"};
147       output = invokeNoEscapeWriter(quoted);
148       assertEquals("'a','b,b,b','c'\n", output);
149 
150       // test empty elements
151       String[] empty = {,};
152       output = invokeNoEscapeWriter(empty);
153       assertEquals("\n", output);
154 
155       // test multiline quoted
156       String[] multiline = {"This is a \n multiline entry", "so is \n this"};
157       output = invokeNoEscapeWriter(multiline);
158       assertEquals("'This is a \n multiline entry','so is \n this'\n", output);
159    }
160 
161    @Test
162    public void parseLineWithNoEscapeCharAndQuotes() {
163       String output = invokeNoEscapeWriter("This is a \" 'multiline' entry", "so is \n this");
164       assertEquals("'This is a \" 'multiline' entry','so is \n this'\n", output);
165    }
166 
167 
168    /**
169     * Test writing to a list.
170     *
171     * @throws IOException if the reader fails.
172     */
173    @Test
174    public void testWriteAllAsList() throws IOException {
175 
176       List<String[]> allElements = new ArrayList<>();
177       String[] line1 = "Name#Phone#Email".split("#");
178       String[] line2 = "Glen#1234#glen@abcd.com".split("#");
179       String[] line3 = "John#5678#john@efgh.com".split("#");
180       allElements.add(line1);
181       allElements.add(line2);
182       allElements.add(line3);
183 
184       StringWriter sw = new StringWriter();
185       ICSVWriter csvw = new CSVWriter(sw);
186       csvw.writeAll(allElements);
187 
188       csvw.close();
189       assertFalse(csvw.checkError());
190       String result = sw.toString();
191       String[] lines = result.split("\n");
192 
193       assertEquals(3, lines.length);
194       assertEquals("\"Name\",\"Phone\",\"Email\"", lines[0]);
195       assertEquals("\"Glen\",\"1234\",\"glen@abcd.com\"", lines[1]);
196       assertEquals("\"John\",\"5678\",\"john@efgh.com\"", lines[2]);
197    }
198 
199    /**
200     * Test writing to an iterator.
201     *
202     * @throws IOException if the reader fails.
203     */
204    @Test
205    public void testWriteAllAsIterable() throws IOException {
206       final String[] line1 = "Name#Phone#Email".split("#");
207       final String[] line2 = "Glen#1234#glen@abcd.com".split("#");
208       final String[] line3 = "John#5678#john@efgh.com".split("#");
209 
210       @SuppressWarnings("unchecked")
211       Iterable<String[]> iterable = mock(Iterable.class);
212 
213       Answer<Iterator<String[]>> iteratorAnswer = invocationOnMock -> {
214          @SuppressWarnings("unchecked")
215          Iterator<String[]> iterator = mock(Iterator.class);
216          when(iterator.hasNext()).thenReturn(true).thenReturn(true).thenReturn(true)
217                  .thenReturn(false);
218          when(iterator.next()).thenReturn(line1).thenReturn(line2).thenReturn(line3)
219                  .thenThrow(NoSuchElementException.class);
220          return iterator;
221       };
222       when(iterable.iterator()).then(iteratorAnswer);
223 
224       StringWriter sw = new StringWriter();
225       ICSVWriter csvw = new CSVWriter(sw);
226       csvw.writeAll(iterable);
227 
228       csvw.close();
229       assertFalse(csvw.checkError());
230 
231       String result = sw.toString();
232       String[] lines = result.split("\n");
233 
234       assertEquals(3, lines.length);
235       assertEquals("\"Name\",\"Phone\",\"Email\"", lines[0]);
236       assertEquals("\"Glen\",\"1234\",\"glen@abcd.com\"", lines[1]);
237       assertEquals("\"John\",\"5678\",\"john@efgh.com\"", lines[2]);
238    }
239 
240    /**
241     * Test writing from a list.
242     */
243    @Test
244    public void testWriteAllObjects() throws IOException {
245 
246       List<String[]> allElements = new ArrayList<>(3);
247       String[] line1 = "Name#Phone#Email".split("#");
248       String[] line2 = "Glen#1234#glen@abcd.com".split("#");
249       String[] line3 = "John#5678#john@efgh.com".split("#");
250       allElements.add(line1);
251       allElements.add(line2);
252       allElements.add(line3);
253 
254       StringWriter sw = new StringWriter();
255       try (ICSVWriter csvw = new CSVWriter(sw)) {
256         csvw.writeAll(allElements, false);
257       }
258       String result = sw.toString();
259       String[] lines = result.split("\n");
260 
261       assertEquals(3, lines.length);
262 
263       String[] values = lines[1].split(",");
264       assertEquals("1234", values[1]);
265    }
266 
267    /**
268     * Tests the option of having omitting quotes in the output stream.
269     */
270    @Test
271    public void testNoQuoteChars() {
272 
273       String[] line = {"Foo", "Bar", "Baz"};
274       StringWriter sw = new StringWriter();
275       ICSVWriter csvw = new CSVWriterBuilder(sw)
276               .withSeparator(ICSVWriter.DEFAULT_SEPARATOR)
277               .withQuoteChar(ICSVWriter.NO_QUOTE_CHARACTER)
278               .build();
279       csvw.writeNext(line);
280       String result = sw.toString();
281 
282       assertEquals("Foo,Bar,Baz\n", result);
283    }
284 
285    /**
286     * Tests the option of having omitting quotes in the output stream.
287     */
288    @Test
289    public void testNoQuoteCharsAndNoEscapeChars() {
290 
291       String[] line = {"Foo", "Bar", "Baz"};
292       StringWriter sw = new StringWriter();
293       ICSVWriter csvw = new CSVWriterBuilder(sw)
294               .withSeparator(ICSVWriter.DEFAULT_SEPARATOR)
295               .withQuoteChar(ICSVWriter.NO_QUOTE_CHARACTER)
296               .withEscapeChar(ICSVWriter.NO_ESCAPE_CHARACTER)
297               .build();
298       csvw.writeNext(line);
299       String result = sw.toString();
300 
301       assertEquals("Foo,Bar,Baz\n", result);
302    }
303 
304    /**
305     * Tests the ability for the writer to apply quotes only where strings contain the separator, escape, quote or new line characters.
306     */
307    @Test
308    public void testIntelligentQuotes() throws IOException {
309       String[] line = {"1", "Foo", "With,Separator", "Line\nBreak", "Hello \"Foo Bar\" World", "Bar"};
310       StringWriter sw = new StringWriter();
311       try (ICSVWriter csvw = new CSVWriter(sw)) {
312         csvw.writeNext(line, false);
313       }
314       String result = sw.toString();
315 
316       assertEquals("1,Foo,\"With,Separator\",\"Line\nBreak\",\"Hello \"\"Foo Bar\"\" World\",Bar\n", result);
317    }
318 
319 
320    /**
321     * Test null values.
322     */
323    @Test
324    public void testNullValues() throws IOException {
325 
326       String[] line = {"Foo", null, "Bar", "baz"};
327       StringWriter sw = new StringWriter();
328       try (ICSVWriter csvw = new CSVWriter(sw)) {
329         csvw.writeNext(line);
330       }
331       String result = sw.toString();
332 
333       assertEquals("\"Foo\",,\"Bar\",\"baz\"\n", result);
334    }
335 
336    @Test
337    public void testStreamFlushing() throws IOException {
338 
339       String WRITE_FILE = "myfile.csv";
340       File tester = new File(WRITE_FILE);
341 
342       assertFalse(tester.exists());
343 
344       String[] nextLine = new String[]{"aaaa", "bbbb", "cccc", "dddd"};
345 
346       FileWriter fileWriter = new FileWriter(WRITE_FILE);
347 
348       ICSVWriter writer = new CSVWriter(fileWriter);
349 
350       writer.writeNext(nextLine);
351 
352       // If this line is not executed, it is not written in the file.
353       writer.close();
354 
355       assertTrue(tester.exists());
356       // cleanup
357       tester.delete();
358 
359    }
360 
361    @SuppressWarnings("resource")
362    @Test
363    public void flushWillThrowIOException() {
364       String[] line = {"Foo", "bar's"};
365       StringWriter sw = new StringWriter();
366       ICSVWriter csvw = new CSVWriterExceptionThrower(sw);
367       csvw.writeNext(line);
368       Assertions.assertThrows(IOException.class, csvw::flush);
369    }
370 
371    @SuppressWarnings("resource")
372    @Test
373    public void flushQuietlyWillNotThrowException() {
374       String[] line = {"Foo", "bar's"};
375       StringWriter sw = new StringWriter();
376       ICSVWriter csvw = new CSVWriterExceptionThrower(sw);
377       csvw.writeNext(line);
378       csvw.flushQuietly();
379    }
380 
381    @Test
382    public void testAlternateEscapeChar() {
383       String[] line = {"Foo", "bar's"};
384       StringWriter sw = new StringWriter();
385       ICSVWriter csvw = new CSVWriterBuilder(sw)
386               .withEscapeChar('\'').build();
387       csvw.writeNext(line);
388       assertEquals("\"Foo\",\"bar''s\"\n", sw.toString());
389    }
390 
391    @Test
392    public void embeddedQuoteInString() {
393       String[] line = {"Foo", "I choose a \\\"hero\\\" for this adventure"};
394       StringWriter sw = new StringWriter();
395       ICSVWriter csvw = new CSVWriterBuilder(sw)
396               .withEscapeChar(ICSVWriter.NO_ESCAPE_CHARACTER)
397               .build();
398       csvw.writeNext(line);
399       assertEquals("\"Foo\",\"I choose a \\\"hero\\\" for this adventure\"\n", sw.toString());
400    }
401 
402    @Test
403    public void testNoQuotingNoEscaping() {
404       String[] line = {"\"Foo\",\"Bar\""};
405       StringWriter sw = new StringWriter();
406       ICSVWriter csvw = new CSVWriterBuilder(sw)
407               .withQuoteChar(ICSVWriter.NO_QUOTE_CHARACTER)
408               .withEscapeChar(ICSVWriter.NO_ESCAPE_CHARACTER)
409               .build();
410       csvw.writeNext(line);
411       assertEquals("\"Foo\",\"Bar\"\n", sw.toString());
412    }
413 
414    @Test
415    public void testNestedQuotes() {
416       String[] data = new String[]{"\"\"", "test"};
417       String oracle = "\"\"\"\"\"\",\"test\"\n";
418 
419       ICSVWriter writer = null;
420       File tempFile = null;
421       FileWriter fwriter = null;
422 
423       try {
424          tempFile = File.createTempFile("csvWriterTest", ".csv");
425          tempFile.deleteOnExit();
426          fwriter = new FileWriter(tempFile);
427          writer = new CSVWriter(fwriter);
428       } catch (IOException e) {
429          fail();
430       }
431 
432       // write the test data:
433       writer.writeNext(data);
434 
435       try {
436          writer.close();
437       } catch (IOException e) {
438          fail();
439       }
440 
441       try {
442          // assert that the writer was also closed.
443          fwriter.flush();
444          fail();
445       } catch (IOException e) {
446          // we should go through here..
447       }
448 
449       // read the data and compare.
450       FileReader in = null;
451       try {
452          in = new FileReader(tempFile);
453       } catch (FileNotFoundException e) {
454          fail();
455       }
456 
457       StringBuilder fileContents = new StringBuilder(ICSVWriter.INITIAL_STRING_SIZE);
458       try {
459          int ch;
460          while ((ch = in.read()) != -1) {
461             fileContents.append((char) ch);
462          }
463          in.close();
464       } catch (IOException e) {
465          fail();
466       }
467 
468       assertEquals(oracle, fileContents.toString());
469    }
470 
471    @Test
472    public void testAlternateLineFeeds() {
473       String[] line = {"Foo", "Bar", "baz"};
474       StringWriter sw = new StringWriter();
475       ICSVWriter csvw = new CSVWriterBuilder(sw)
476               .withLineEnd("\r")
477               .build();
478       csvw.writeNext(line);
479       String result = sw.toString();
480 
481       assertTrue(result.endsWith("\r"));
482    }
483 
484    @Test
485    public void testResultSetWithHeaders() throws SQLException, IOException {
486       String[] header = {"Foo", "Bar", "baz"};
487       String[] value = {"v1", "v2", "v3"};
488 
489       StringWriter sw = new StringWriter();
490       try (ICSVWriter csvw = new CSVWriter(sw)) {
491         ResultSet rs = MockResultSetBuilder.buildResultSet(header, value, 1);
492 
493           int linesWritten = csvw.writeAll(rs, true); // don't need a result set since I am mocking the result.
494           assertFalse(csvw.checkError());
495           String result = sw.toString();
496 
497           assertNotNull(result);
498           assertEquals("\"Foo\",\"Bar\",\"baz\"\n\"v1\",\"v2\",\"v3\"\n", result);
499           assertEquals(2, linesWritten);
500       }
501    }
502 
503    @Test
504    public void testResultSetWithHeadersWithoutQuotes() throws SQLException, IOException {
505       String[] header = {"Foo", "Bar", "baz"};
506       String[] value = {"v1", "v2", "v3"};
507 
508       StringWriter sw = new StringWriter();
509       try (ICSVWriter csvw = new CSVWriter(sw)) {
510         ResultSet rs = MockResultSetBuilder.buildResultSet(header, value, 1);
511 
512           int linesWritten = csvw.writeAll(rs, true, false, false); // don't need a result set since I am mocking the result.
513           assertFalse(csvw.checkError());
514           String result = sw.toString();
515 
516           assertNotNull(result);
517           assertEquals("Foo,Bar,baz\nv1,v2,v3\n", result);
518           assertEquals(2, linesWritten);
519       }
520    }
521 
522    @Test
523    public void testMultiLineResultSetWithHeaders() throws SQLException, IOException {
524       String[] header = {"Foo", "Bar", "baz"};
525       String[] value = {"v1", "v2", "v3"};
526 
527       StringWriter sw = new StringWriter();
528       try (ICSVWriter csvw = new CSVWriter(sw)) {
529         csvw.setResultService(new ResultSetHelperService());
530 
531           ResultSet rs = MockResultSetBuilder.buildResultSet(header, value, 3);
532 
533           int linesWritten = csvw.writeAll(rs, true); // don't need a result set since I am mocking the result.
534           assertFalse(csvw.checkError());
535           String result = sw.toString();
536 
537           assertNotNull(result);
538           assertEquals("\"Foo\",\"Bar\",\"baz\"\n\"v1\",\"v2\",\"v3\"\n\"v1\",\"v2\",\"v3\"\n\"v1\",\"v2\",\"v3\"\n", result);
539           assertEquals(4, linesWritten);
540       }
541    }
542 
543    @Test
544    public void testResultSetWithoutHeaders() throws SQLException, IOException {
545       String[] header = {"Foo", "Bar", "baz"};
546       String[] value = {"v1", "v2", "v3"};
547 
548       StringWriter sw = new StringWriter();
549       try (ICSVWriter csvw = new CSVWriter(sw)) {
550         csvw.setResultService(new ResultSetHelperService());
551 
552           ResultSet rs = MockResultSetBuilder.buildResultSet(header, value, 1);
553 
554           int linesWritten = csvw.writeAll(rs, false); // don't need a result set since I am mocking the result.
555           assertFalse(csvw.checkError());
556           String result = sw.toString();
557 
558           assertNotNull(result);
559           assertEquals("\"v1\",\"v2\",\"v3\"\n", result);
560           assertEquals(1, linesWritten);
561       }
562    }
563 
564    @Test
565    public void testResultSetWithoutHeadersAndQuotes() throws SQLException, IOException {
566       String[] header = {"Foo", "Bar", "baz"};
567       String[] value = {"v1", "v2", "v3"};
568 
569       StringWriter sw = new StringWriter();
570       try (ICSVWriter csvw = new CSVWriter(sw)) {
571         csvw.setResultService(new ResultSetHelperService());
572 
573           ResultSet rs = MockResultSetBuilder.buildResultSet(header, value, 1);
574 
575           int linesWritten = csvw.writeAll(rs, false, false, false); // don't need a result set since I am mocking the result.
576           assertFalse(csvw.checkError());
577           String result = sw.toString();
578 
579           assertNotNull(result);
580           assertEquals("v1,v2,v3\n", result);
581           assertEquals(1, linesWritten);
582       }
583    }
584 
585    @Test
586    public void testMultiLineResultSetWithoutHeaders() throws SQLException, IOException {
587       String[] header = {"Foo", "Bar", "baz"};
588       String[] value = {"v1", "v2", "v3"};
589 
590       StringWriter sw = new StringWriter();
591       try (ICSVWriter csvw = new CSVWriter(sw)) {
592         csvw.setResultService(new ResultSetHelperService());
593 
594           ResultSet rs = MockResultSetBuilder.buildResultSet(header, value, 3);
595 
596           int linesWritten = csvw.writeAll(rs, false); // don't need a result set since I am mocking the result.
597 
598           assertFalse(csvw.checkError());
599           String result = sw.toString();
600 
601           assertNotNull(result);
602           assertEquals("\"v1\",\"v2\",\"v3\"\n\"v1\",\"v2\",\"v3\"\n\"v1\",\"v2\",\"v3\"\n", result);
603           assertEquals(3, linesWritten);
604       }
605    }
606 
607    @Test
608    public void testResultSetTrim() throws SQLException, IOException {
609       String[] header = {"Foo", "Bar", "baz"};
610       String[] value = {"v1         ", "v2 ", "v3"};
611 
612       StringWriter sw = new StringWriter();
613       try (ICSVWriter csvw = new CSVWriter(sw)) {
614         csvw.setResultService(new ResultSetHelperService());
615 
616           ResultSet rs = MockResultSetBuilder.buildResultSet(header, value, 1);
617 
618           int linesWritten = csvw.writeAll(rs, true, true); // don't need a result set since I am mocking the result.
619           assertFalse(csvw.checkError());
620           String result = sw.toString();
621 
622           assertNotNull(result);
623           assertEquals("\"Foo\",\"Bar\",\"baz\"\n\"v1\",\"v2\",\"v3\"\n", result);
624           assertEquals(2, linesWritten);
625       }
626    }
627 
628    @Test
629    public void needToSetBothQuoteAndEscapeCharIfYouWantThemToBeTheSame() throws SQLException, IOException {
630       String[] header = {"Foo", "Bar", "baz"};
631       String[] value = {"v1", "v2'v2a", "v3"};
632 
633       StringWriter sw = new StringWriter();
634       ICSVWriter csvw = new CSVWriterBuilder(sw)
635               .withQuoteChar('\'')
636               .withEscapeChar('\'')
637               .build();
638       csvw.setResultService(new ResultSetHelperService());
639 
640       ResultSet rs = MockResultSetBuilder.buildResultSet(header, value, 1);
641 
642       int linesWritten = csvw.writeAll(rs, true, true); // don't need a result set since I am mocking the result.
643       assertFalse(csvw.checkError());
644       String result = sw.toString();
645 
646       assertNotNull(result);
647       assertEquals("'Foo','Bar','baz'\n'v1','v2''v2a','v3'\n", result);
648       assertEquals(2, linesWritten);
649    }
650 
651    @Test
652    public void issue123SeparatorEscapedWhenQuoteIsNoQuoteChar() {
653       String[] header = {"Foo", "Bar", "baz"};
654       String[] value = {"v1", "v2" + ICSVWriter.DEFAULT_ESCAPE_CHARACTER + "v2a", "v3"};
655 
656       List<String[]> lines = new ArrayList<>();
657       lines.add(header);
658       lines.add(value);
659       StringWriter sw = new StringWriter();
660       ICSVWriter writer = new CSVWriterBuilder(sw)
661               .withQuoteChar(ICSVWriter.NO_QUOTE_CHARACTER)
662               .build();
663       writer.writeAll(lines);
664 
665       String result = sw.toString();
666       assertNotNull(result);
667       assertEquals("Foo,Bar,baz\nv1,v2" + ICSVWriter.DEFAULT_ESCAPE_CHARACTER + ICSVWriter.DEFAULT_ESCAPE_CHARACTER + "v2a,v3\n", result);
668    }
669 
670    @Test
671    public void issue123SeparatorEscapedWhenQuoteIsNoQuoteCharSpecifyingNoneDefaultEscapeChar() {
672       String[] header = {"Foo", "Bar", "baz"};
673       char escapeCharacter = '\\';
674       String[] value = {"v1", "v2" + escapeCharacter + "v2a" + ICSVWriter.DEFAULT_SEPARATOR + "v2b", "v3"};
675       List<String[]> lines = new ArrayList<>();
676       lines.add(header);
677       lines.add(value);
678       StringWriter sw = new StringWriter();
679       ICSVWriter writer = new CSVWriterBuilder(sw)
680               .withQuoteChar(ICSVWriter.NO_QUOTE_CHARACTER)
681               .withEscapeChar(escapeCharacter)
682               .build();
683       writer.writeAll(lines);
684 
685       String result = sw.toString();
686       assertNotNull(result);
687       assertEquals("Foo,Bar,baz\nv1,v2" + escapeCharacter + escapeCharacter + "v2a" + escapeCharacter + ICSVWriter.DEFAULT_SEPARATOR + "v2b,v3\n", result);
688    }
689 
690    @Test
691    public void issue136escapeNewLineCharactersWhenNoQuoteCharIsSet() {
692       String[] header = {"Foo", "Bar", "baz"};
693       char escapeCharacter = '\\';
694       String[] value = {"v1", "v2", "v3\n"};
695       List<String[]> lines = new ArrayList<>();
696       lines.add(header);
697       lines.add(value);
698       StringWriter sw = new StringWriter();
699       ICSVWriter writer = new CSVWriterBuilder(sw)
700               .withQuoteChar(ICSVWriter.NO_QUOTE_CHARACTER)
701               .withEscapeChar(escapeCharacter)
702               .build();
703       writer.writeAll(lines);
704 
705       String result = sw.toString();
706       assertNotNull(result);
707       assertEquals("Foo,Bar,baz\nv1,v2,v3" + escapeCharacter + "\n\n", result);
708    }
709    @Test
710    public void testIOException() throws IOException {
711       Writer writer = mock(Writer.class);
712       doThrow(IOException.class).when(writer).write(anyString());
713 
714       // Using writeNext()
715       ICSVWriter csvWriter = new CSVWriter(writer);
716       csvWriter.writeNext(SIMPLE_STRING_ARRAY);
717       csvWriter.close();
718       assertTrue(csvWriter.checkError());
719 
720       // Using writeAll(Iterable<String[]>, boolean)
721       csvWriter = new CSVWriter(writer);
722       csvWriter.writeAll(Collections.singletonList(SIMPLE_STRING_ARRAY), false);
723       csvWriter.close();
724       assertTrue(csvWriter.checkError());
725 
726       // Using writeAll(Iterable<String[]>)
727       csvWriter = new CSVWriter(writer);
728       csvWriter.writeAll(Collections.singletonList(SIMPLE_STRING_ARRAY));
729       csvWriter.close();
730       assertTrue(csvWriter.checkError());
731    }
732 
733    @Test
734    public void checkErrorReturnsTrueWhenPassedInPrintWriter() throws IOException {
735       Writer writer = mock(Writer.class);
736       doThrow(IOException.class).when(writer).write(anyString(), anyInt(), anyInt());
737 
738       PrintWriter printWriter = new PrintWriter(writer);
739 
740       ICSVWriter csvWriter = new CSVWriter(printWriter);
741 
742       csvWriter.writeNext(SIMPLE_STRING_ARRAY);
743 
744       csvWriter.close();
745 
746       assertTrue(csvWriter.checkError());
747    }
748 
749    @Test
750    public void getExceptionReturnsException() throws IOException {
751       Writer writer = mock(Writer.class);
752       AbstractCSVWriter csvWriter = spy(new CSVWriter(writer));
753 
754       String exceptionMessage = "Exception on writing csv";
755       IOException ioException = new IOException(exceptionMessage);
756       doThrow(ioException).when(csvWriter).writeNext(any(String[].class), anyBoolean(), any(StringBuilder.class));
757 
758       csvWriter.writeNext(SIMPLE_STRING_ARRAY);
759 
760       csvWriter.close();
761 
762       verify(csvWriter).writeNext(any(String[].class), anyBoolean(), any(StringBuilder.class));
763 
764       IOException storedException = csvWriter.getException();
765       assertEquals(ioException, storedException, "Expected Exception is not returned by getException");
766    }
767 
768    @Test
769    public void getExceptionReturnsExceptionUsingPrintWriter() throws IOException {
770       Writer writer = mock(Writer.class);
771       PrintWriter printWriter = new PrintWriter(writer);
772       AbstractCSVWriter csvWriter = spy(new CSVWriter(printWriter));
773 
774       String exceptionMessage = "Exception on writing csv";
775       IOException ioException = new IOException(exceptionMessage);
776       doThrow(ioException).when(csvWriter).writeNext(any(String[].class), anyBoolean(), any(StringBuilder.class));
777 
778       csvWriter.writeNext(SIMPLE_STRING_ARRAY);
779 
780       csvWriter.close();
781 
782       verify(csvWriter).writeNext(any(String[].class), anyBoolean(), any(StringBuilder.class));
783 
784       IOException storedException = csvWriter.getException();
785       assertEquals(ioException, storedException, "Expected Exception is not returned by getException");
786    }
787 
788    @Test
789    public void resetException() throws IOException {
790       Writer writer = mock(Writer.class);
791       doThrow(IOException.class).when(writer).write(anyString(), anyInt(), anyInt());
792       AbstractCSVWriter csvWriter = spy(new CSVWriter(writer));
793 
794       String exceptionMessage = "Exception on writing csv";
795       IOException ioException = new IOException(exceptionMessage);
796       doThrow(ioException).when(csvWriter).writeNext(any(String[].class), anyBoolean(), any(StringBuilder.class));
797 
798       csvWriter.writeNext(SIMPLE_STRING_ARRAY);
799 
800       IOException storedException = csvWriter.getException();
801       assertEquals(ioException, storedException, "Expected Exception is not returned by getException");
802 
803       csvWriter.resetError();
804 
805       assertNull(csvWriter.getException(), "Exception has not been removed");
806 
807       csvWriter.close();
808 
809       verify(csvWriter).writeNext(any(String[].class), anyBoolean(), any(StringBuilder.class));
810    }
811 
812    @Test
813    public void resetError() throws IOException {
814       Writer writer = mock(Writer.class);
815       doThrow(IOException.class).when(writer).write(anyString(), anyInt(), anyInt());
816       AbstractCSVWriter csvWriter = spy(new CSVWriter(writer));
817 
818       String exceptionMessage = "Exception on writing csv";
819       IOException ioException = new IOException(exceptionMessage);
820       doThrow(ioException).when(csvWriter).writeNext(any(String[].class), anyBoolean(), any(StringBuilder.class));
821 
822       csvWriter.writeNext(SIMPLE_STRING_ARRAY);
823 
824       assertTrue(csvWriter.checkError(), "Error has not occurred initially");
825 
826       csvWriter.resetError();
827 
828       assertFalse(csvWriter.checkError(), "Error has not been removed");
829 
830       csvWriter.close();
831 
832       verify(csvWriter).writeNext(any(String[].class), anyBoolean(), any(StringBuilder.class));
833    }
834 }