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