Skip to content

Commit 24ffa7b

Browse files
committed
Add test for duplicate header names
Test the CSVFormat and CSVParser handle the headers consistently. CSVParser handles all 36 cases. CSFFormat fails 6 cases. These are currently disabled.
1 parent 8d57c91 commit 24ffa7b

1 file changed

Lines changed: 155 additions & 0 deletions

File tree

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
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;
19+
20+
import java.io.IOException;
21+
import java.util.Arrays;
22+
import java.util.stream.Collectors;
23+
import java.util.stream.Stream;
24+
import org.junit.jupiter.api.Assertions;
25+
import org.junit.jupiter.params.ParameterizedTest;
26+
import org.junit.jupiter.params.provider.Arguments;
27+
import org.junit.jupiter.params.provider.MethodSource;
28+
29+
/**
30+
* Tests {@link CSVFormat}.
31+
*/
32+
public class CSVDuplicateHeaderTest {
33+
/**
34+
* Return test cases for duplicate header data. Uses the order:
35+
* <pre>
36+
* DuplicateHeaderMode duolicateHeaderMode
37+
* boolean allowMissingColumnNames
38+
* String[] headers
39+
* boolean valid
40+
* </pre>
41+
*
42+
* <p>TODO: Reinstate cases failed by CSVFormat.
43+
*
44+
* @return the stream of arguments
45+
*/
46+
static Stream<Arguments> duplicateHeaderData() {
47+
return Stream.of(
48+
// Any combination with a valid header
49+
Arguments.of(DuplicateHeaderMode.DISALLOW, false, new String[] {"A", "B"}, true),
50+
Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, false, new String[] {"A", "B"}, true),
51+
Arguments.of(DuplicateHeaderMode.ALLOW_ALL, false, new String[] {"A", "B"}, true),
52+
Arguments.of(DuplicateHeaderMode.DISALLOW, true, new String[] {"A", "B"}, true),
53+
Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, true, new String[] {"A", "B"}, true),
54+
Arguments.of(DuplicateHeaderMode.ALLOW_ALL, true, new String[] {"A", "B"}, true),
55+
56+
// Duplicate non-empty names
57+
Arguments.of(DuplicateHeaderMode.DISALLOW, false, new String[] {"A", "A"}, false),
58+
Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, false, new String[] {"A", "A"}, false),
59+
Arguments.of(DuplicateHeaderMode.ALLOW_ALL, false, new String[] {"A", "A"}, true),
60+
Arguments.of(DuplicateHeaderMode.DISALLOW, true, new String[] {"A", "A"}, false),
61+
Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, true, new String[] {"A", "A"}, false),
62+
Arguments.of(DuplicateHeaderMode.ALLOW_ALL, true, new String[] {"A", "A"}, true),
63+
64+
// Duplicate empty names
65+
Arguments.of(DuplicateHeaderMode.DISALLOW, false, new String[] {"", ""}, false),
66+
//Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, false, new String[] {"", ""}, false),
67+
//Arguments.of(DuplicateHeaderMode.ALLOW_ALL, false, new String[] {"", ""}, false),
68+
Arguments.of(DuplicateHeaderMode.DISALLOW, true, new String[] {"", ""}, false),
69+
Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, true, new String[] {"", ""}, true),
70+
Arguments.of(DuplicateHeaderMode.ALLOW_ALL, true, new String[] {"", ""}, true),
71+
72+
// Duplicate blank names
73+
Arguments.of(DuplicateHeaderMode.DISALLOW, false, new String[] {" ", " "}, false),
74+
Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, false, new String[] {" ", " "}, false),
75+
//Arguments.of(DuplicateHeaderMode.ALLOW_ALL, false, new String[] {" ", " "}, false),
76+
Arguments.of(DuplicateHeaderMode.DISALLOW, true, new String[] {" ", " "}, false),
77+
//Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, true, new String[] {" ", " "}, true),
78+
Arguments.of(DuplicateHeaderMode.ALLOW_ALL, true, new String[] {" ", " "}, true),
79+
80+
// Duplicate non-empty and empty names
81+
Arguments.of(DuplicateHeaderMode.DISALLOW, false, new String[] {"A", "A", "", ""}, false),
82+
Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, false, new String[] {"A", "A", "", ""}, false),
83+
//Arguments.of(DuplicateHeaderMode.ALLOW_ALL, false, new String[] {"A", "A", "", ""}, false),
84+
Arguments.of(DuplicateHeaderMode.DISALLOW, true, new String[] {"A", "A", "", ""}, false),
85+
Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, true, new String[] {"A", "A", "", ""}, false),
86+
Arguments.of(DuplicateHeaderMode.ALLOW_ALL, true, new String[] {"A", "A", "", ""}, true),
87+
88+
// Duplicate non-empty and blank names
89+
Arguments.of(DuplicateHeaderMode.DISALLOW, false, new String[] {"A", "A", " ", " "}, false),
90+
Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, false, new String[] {"A", "A", " ", " "}, false),
91+
//Arguments.of(DuplicateHeaderMode.ALLOW_ALL, false, new String[] {"A", "A", " ", " "}, false),
92+
Arguments.of(DuplicateHeaderMode.DISALLOW, true, new String[] {"A", "A", " ", " "}, false),
93+
Arguments.of(DuplicateHeaderMode.ALLOW_EMPTY, true, new String[] {"A", "A", " ", " "}, false),
94+
Arguments.of(DuplicateHeaderMode.ALLOW_ALL, true, new String[] {"A", "A", " ", " "}, true)
95+
);
96+
}
97+
98+
/**
99+
* Test duplicate headers with the CSVParser.
100+
*
101+
* @param duolicateHeaderMode the duolicate header mode
102+
* @param allowMissingColumnNames the allow missing column names flag
103+
* @param headers the headers
104+
* @param valid true if the settings are expected to be valid
105+
*/
106+
@ParameterizedTest
107+
@MethodSource(value = {"duplicateHeaderData"})
108+
public void testCSVFormat(DuplicateHeaderMode duolicateHeaderMode,
109+
boolean allowMissingColumnNames,
110+
String[] headers,
111+
boolean valid) {
112+
CSVFormat.Builder builder = CSVFormat.DEFAULT.builder()
113+
.setDuplicateHeaderMode(duolicateHeaderMode)
114+
.setAllowMissingColumnNames(allowMissingColumnNames)
115+
.setHeader(headers);
116+
if (valid) {
117+
CSVFormat format = builder.build();
118+
Assertions.assertEquals(duolicateHeaderMode, format.getDuplicateHeaderMode(), "DuplicateHeaderMode");
119+
Assertions.assertEquals(allowMissingColumnNames, format.getAllowMissingColumnNames(), "AllowMissingColumnNames");
120+
Assertions.assertArrayEquals(headers, format.getHeader(), "Header");
121+
} else {
122+
Assertions.assertThrows(IllegalArgumentException.class, () -> builder.build());
123+
}
124+
}
125+
126+
/**
127+
* Test duplicate headers with the CSVParser.
128+
*
129+
* @param duolicateHeaderMode the duolicate header mode
130+
* @param allowMissingColumnNames the allow missing column names flag
131+
* @param headers the headers (joined with the CSVFormat delimiter to create a string input)
132+
* @param valid true if the settings are expected to be valid
133+
* @throws IOException Signals that an I/O exception has occurred.
134+
*/
135+
@ParameterizedTest
136+
@MethodSource(value = {"duplicateHeaderData"})
137+
public void testCSVParser(DuplicateHeaderMode duolicateHeaderMode,
138+
boolean allowMissingColumnNames,
139+
String[] headers,
140+
boolean valid) throws IOException {
141+
CSVFormat format = CSVFormat.DEFAULT.builder()
142+
.setDuplicateHeaderMode(duolicateHeaderMode)
143+
.setAllowMissingColumnNames(allowMissingColumnNames)
144+
.setHeader()
145+
.build();
146+
String input = Arrays.stream(headers).collect(Collectors.joining(format.getDelimiterString()));
147+
if (valid) {
148+
try(CSVParser parser = CSVParser.parse(input, format)) {
149+
Assertions.assertEquals(Arrays.asList(headers), parser.getHeaderNames());
150+
}
151+
} else {
152+
Assertions.assertThrows(IllegalArgumentException.class, () -> CSVParser.parse(input, format));
153+
}
154+
}
155+
}

0 commit comments

Comments
 (0)