View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.commons.csv.issues;
21  
22  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
23  import static org.junit.jupiter.api.Assertions.assertEquals;
24  import static org.junit.jupiter.api.Assertions.assertNull;
25  
26  import java.io.InputStreamReader;
27  import java.io.StringReader;
28  import java.io.StringWriter;
29  import java.util.ArrayList;
30  import java.util.Iterator;
31  import java.util.List;
32  import java.util.stream.Collectors;
33  
34  import org.apache.commons.csv.CSVFormat;
35  import org.apache.commons.csv.CSVParser;
36  import org.apache.commons.csv.CSVPrinter;
37  import org.apache.commons.csv.CSVRecord;
38  import org.junit.jupiter.api.Test;
39  
40  // psql (14.5 (Homebrew))
41  //
42  // create table COMMONS_CSV_PSQL_TEST (ID INTEGER, COL1 VARCHAR, COL2 VARCHAR, COL3 VARCHAR, COL4 VARCHAR);
43  // insert into COMMONS_CSV_PSQL_TEST select 1, 'abc', 'test line 1' || chr(10) || 'test line 2', null, '';
44  // insert into COMMONS_CSV_PSQL_TEST select 2, 'xyz', '\b:' || chr(8) || ' \t:' || chr(9) || ' \n:' || chr(10) || ' \r:' || chr(13), 'a', 'b';
45  // insert into COMMONS_CSV_PSQL_TEST values (3, 'a', 'b,c,d', '"quoted"', 'e');
46  // copy COMMONS_CSV_PSQL_TEST TO '/tmp/psql.csv' WITH (FORMAT CSV);
47  // copy COMMONS_CSV_PSQL_TEST TO '/tmp/psql.tsv';
48  //
49  // cat /tmp/psql.csv
50  // 1,abc,"test line 1
51  // test line 2",,""
52  // 2,xyz,"\b:^H \t:         \n:
53  //  \r:^M",a,b
54  // 3,a,"b,c,d","""quoted""",e
55  //
56  // cat /tmp/psql.tsv
57  // 1    abc    test line 1\ntest line 2                  \N
58  // 2    xyz    \\b:\b \\t:\t \\n:\n \\r:\r    a          b
59  // 3    a      b,c,d                         "quoted"    e
60  //
61  class JiraCsv290Test {
62  
63      private void testHelper(final String fileName, final CSVFormat format) throws Exception {
64          List<List<String>> content = new ArrayList<>();
65          try (CSVParser csvParser = CSVParser.parse(new InputStreamReader(this.getClass().getResourceAsStream("/org/apache/commons/csv/CSV-290/" + fileName)),
66                  format)) {
67              content = csvParser.stream().collect(Collectors.mapping(CSVRecord::toList, Collectors.toList()));
68          }
69  
70          assertEquals(3, content.size());
71  
72          assertEquals("1", content.get(0).get(0));
73          assertEquals("abc", content.get(0).get(1));
74          assertEquals("test line 1\ntest line 2", content.get(0).get(2)); // new line
75          assertNull(content.get(0).get(3)); // null
76          assertEquals("", content.get(0).get(4));
77  
78          assertEquals("2", content.get(1).get(0));
79          assertEquals("\\b:\b \\t:\t \\n:\n \\r:\r", content.get(1).get(2)); // \b, \t, \n, \r
80  
81          assertEquals("3", content.get(2).get(0));
82          assertEquals("b,c,d", content.get(2).get(2)); // value has comma
83          assertEquals("\"quoted\"", content.get(2).get(3)); // quoted
84      }
85  
86      @Test
87      void testPostgresqlCsv() throws Exception {
88          testHelper("psql.csv", CSVFormat.POSTGRESQL_CSV);
89      }
90  
91      @Test
92      void testPostgresqlText() throws Exception {
93          testHelper("psql.tsv", CSVFormat.POSTGRESQL_TEXT);
94      }
95  
96      @Test
97      void testWriteThenRead() throws Exception {
98          final StringWriter sw = new StringWriter();
99          final CSVFormat format = CSVFormat.POSTGRESQL_CSV.builder().setHeader().setSkipHeaderRecord(true).get();
100         try (CSVPrinter printer = new CSVPrinter(sw, format)) {
101             printer.printRecord("column1", "column2");
102             printer.printRecord("v11", "v12");
103             printer.printRecord("v21", "v22");
104             printer.close();
105             try (CSVParser parser = CSVParser.builder().setReader(new StringReader(sw.toString())).setFormat(format).get()) {
106                 assertArrayEquals(new Object[] { "column1", "column2" }, parser.getHeaderNames().toArray());
107                 final Iterator<CSVRecord> i = parser.iterator();
108                 assertArrayEquals(new String[] { "v11", "v12" }, i.next().toList().toArray());
109                 assertArrayEquals(new String[] { "v21", "v22" }, i.next().toList().toArray());
110             }
111         }
112     }
113 }