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.assertThrows;
23  
24  import java.io.IOException;
25  import java.io.StringReader;
26  
27  import org.apache.commons.csv.CSVFormat;
28  import org.apache.commons.csv.CSVParser;
29  import org.apache.commons.csv.DuplicateHeaderMode;
30  import org.junit.jupiter.api.Test;
31  
32  /**
33   * When {@link CSVFormat#withHeader(String...)} is not null; duplicate headers
34   * with empty strings should not be allowed.
35   *
36   * @see <a href="https://issues.apache.org/jira/browse/CSV-264">Jira Ticker</a>
37   */
38  class JiraCsv264Test {
39  
40      private static final String CSV_STRING = "\"\",\"B\",\"\"\n" +
41                                               "\"1\",\"2\",\"3\"\n" +
42                                               "\"4\",\"5\",\"6\"";
43  
44      /**
45       * A CSV file with a random gap in the middle.
46       */
47      private static final String CSV_STRING_GAP = "\"A\",\"B\",\"\",\"\",\"E\"\n" +
48                                                   "\"1\",\"2\",\"\",\"\",\"5\"\n" +
49                                                   "\"6\",\"7\",\"\",\"\",\"10\"";
50  
51      @Test
52      void testJiraCsv264() {
53          final CSVFormat csvFormat = CSVFormat.DEFAULT
54              .builder()
55              .setHeader()
56              .setDuplicateHeaderMode(DuplicateHeaderMode.DISALLOW)
57              .setAllowMissingColumnNames(true)
58              .get();
59          try (StringReader reader = new StringReader(CSV_STRING)) {
60              assertThrows(IllegalArgumentException.class, () -> csvFormat.parse(reader));
61          }
62      }
63  
64      @Test
65      void testJiraCsv264WithGapAllowEmpty() throws IOException {
66          final CSVFormat csvFormat = CSVFormat.DEFAULT
67              .builder()
68              .setHeader()
69              .setDuplicateHeaderMode(DuplicateHeaderMode.ALLOW_EMPTY)
70              .setAllowMissingColumnNames(true)
71              .get();
72          try (StringReader reader = new StringReader(CSV_STRING_GAP); CSVParser parser = csvFormat.parse(reader)) {
73              // empty
74          }
75      }
76  
77      @Test
78      void testJiraCsv264WithGapDisallow() {
79          final CSVFormat csvFormat = CSVFormat.DEFAULT
80              .builder()
81              .setHeader()
82              .setDuplicateHeaderMode(DuplicateHeaderMode.DISALLOW)
83              .setAllowMissingColumnNames(true)
84              .get();
85          try (StringReader reader = new StringReader(CSV_STRING_GAP)) {
86              assertThrows(IllegalArgumentException.class, () -> csvFormat.parse(reader));
87          }
88      }
89  }