1 package com.opencsv;
2
3 import com.opencsv.enums.CSVReaderNullFieldIndicator;
4 import com.opencsv.exceptions.CsvValidationException;
5 import com.opencsv.processor.RowProcessor;
6 import com.opencsv.validators.LineValidatorAggregator;
7 import com.opencsv.validators.RowValidatorAggregator;
8 import org.junit.jupiter.api.Assertions;
9 import org.junit.jupiter.api.BeforeEach;
10 import org.junit.jupiter.api.Test;
11
12 import java.io.IOException;
13 import java.io.StringReader;
14 import java.util.Locale;
15 import java.util.Map;
16
17 import static org.hamcrest.CoreMatchers.is;
18 import static org.hamcrest.MatcherAssert.assertThat;
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertNull;
21 import static org.mockito.ArgumentMatchers.anyString;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.when;
24
25
26
27
28 public class CsvReaderHeaderAwareTest {
29
30 private CSVReaderHeaderAware csvr;
31
32 @BeforeEach
33 public void setUpWithHeader() throws Exception {
34 StringReader reader = createReader();
35 csvr = new CSVReaderHeaderAware(reader);
36 }
37
38 @Test
39 public void shouldKeepBasicParsing() throws IOException, CsvValidationException {
40 String[] nextLine = csvr.readNext();
41 assertEquals("a", nextLine[0]);
42 assertEquals("b", nextLine[1]);
43 assertEquals("c", nextLine[2]);
44
45
46 nextLine = csvr.readNext();
47 assertEquals("a", nextLine[0]);
48 assertEquals("b,b,b", nextLine[1]);
49 assertEquals("c", nextLine[2]);
50
51
52 nextLine = csvr.readNext();
53 assertEquals(3, nextLine.length);
54
55
56 nextLine = csvr.readNext();
57 assertEquals(3, nextLine.length);
58
59
60 nextLine = csvr.readNext();
61 assertEquals("Glen \"The Man\" Smith", nextLine[0]);
62
63 nextLine = csvr.readNext();
64 assertEquals("\"\"", nextLine[0]);
65 assertEquals("test", nextLine[1]);
66
67 nextLine = csvr.readNext();
68 assertEquals(4, nextLine.length);
69
70 assertEquals("a", csvr.readNext()[0]);
71
72
73 assertNull(csvr.readNext());
74 }
75
76 @Test
77 public void testEmptyFieldAsNullWithMap() throws IOException, CsvValidationException {
78 CSVReaderHeaderAware csvr = (CSVReaderHeaderAware) new CSVReaderHeaderAwareBuilder(createReader())
79 .withFieldAsNull(CSVReaderNullFieldIndicator.EMPTY_SEPARATORS)
80 .build();
81
82
83 csvr.readNext();
84 csvr.readNext();
85
86
87 Map<String, String> nextLine = csvr.readMap();
88 assertEquals(3, nextLine.size());
89 assertNull(nextLine.get("second"));
90 }
91
92 @Test
93 public void shouldRetrieveColumnsByHeaderName() throws IOException, CsvValidationException {
94 assertEquals("a", csvr.readNext("first")[0]);
95 assertEquals("a", csvr.readNext("first")[0]);
96 assertEquals("", csvr.readNext("first")[0]);
97 assertEquals("PO Box 123,\nKippax,ACT. 2615.\nAustralia", csvr.readNext("second")[0]);
98 }
99
100 @Test
101 public void shouldRetrieveMultipleColumnsByHeaderName() throws IOException, CsvValidationException {
102 String[] nextLine = csvr.readNext("first", "third");
103 assertEquals("a", nextLine[0]);
104 assertEquals("c", nextLine[1]);
105
106 assertEquals("b,b,b", csvr.readNext("second")[0]);
107 }
108
109 @Test
110 public void shouldFailForInvalidColumn() {
111 Assertions.assertThrows(IllegalArgumentException.class, () -> csvr.readNext("fourth"));
112 }
113
114 @Test
115 public void shouldFailForInvalidColumnEvenAmongstValidOnes() {
116 Assertions.assertThrows(IllegalArgumentException.class, () -> csvr.readNext("first", "third", "fourth"));
117 }
118
119 @Test
120 public void shouldFailWhenNumberOfDataItemsIsLessThanHeader() throws IOException {
121 csvr.skip(7);
122 Assertions.assertThrows(IOException.class, () -> csvr.readNext("second"));
123 }
124
125 @Test
126 public void shouldFailWhenNumberOfDataItemsIsGreaterThanHeader() throws IOException {
127 csvr.skip(6);
128 Assertions.assertThrows(IOException.class, () -> csvr.readNext("second"));
129 }
130
131 @Test
132 public void shouldRetrieveMap() throws IOException, CsvValidationException {
133 Map<String, String> mappedLine = csvr.readMap();
134 assertEquals("a", mappedLine.get("first"));
135 assertEquals("b", mappedLine.get("second"));
136 assertEquals("c", mappedLine.get("third"));
137
138 csvr.skip(2);
139
140 mappedLine = csvr.readMap();
141 assertEquals("a", mappedLine.get("first"));
142 assertEquals("PO Box 123,\nKippax,ACT. 2615.\nAustralia", mappedLine.get("second"));
143 assertEquals("d.", mappedLine.get("third"));
144 }
145
146 @Test
147 public void readMapThrowsExceptionIfNumberOfDataItemsIsGreaterThanHeader() throws IOException, CsvValidationException {
148 Map<String, String> mappedLine = csvr.readMap();
149 assertEquals("a", mappedLine.get("first"));
150 assertEquals("b", mappedLine.get("second"));
151 assertEquals("c", mappedLine.get("third"));
152
153 csvr.skip(5);
154
155 Assertions.assertThrows(IOException.class, () -> csvr.readMap());
156 }
157
158 @Test
159 public void readMapThrowsExceptionIfNumberOfDataItemsIsLessThanHeader() throws IOException, CsvValidationException {
160 Map<String, String> mappedLine = csvr.readMap();
161 assertEquals("a", mappedLine.get("first"));
162 assertEquals("b", mappedLine.get("second"));
163 assertEquals("c", mappedLine.get("third"));
164
165 csvr.skip(6);
166
167 Assertions.assertThrows(IOException.class, () -> csvr.readMap());
168 }
169
170 @Test
171 public void shouldReturnNullWhenFileIsOver() throws IOException, CsvValidationException {
172 csvr.skip(8);
173 assertNull(csvr.readMap());
174 }
175
176 @Test
177 public void readNextWhenPastEOF() throws IOException, CsvValidationException {
178 csvr.skip(8);
179 assertNull(csvr.readNext("first"));
180 }
181
182 @Test
183 public void shouldInitialiseHeaderWithCompleteConstructor() throws IOException, CsvValidationException {
184 ICSVParser parser = mock(ICSVParser.class);
185 when(parser.parseLineMulti(anyString())).thenReturn(new String[]{"myHeader"});
186 try (CSVReaderHeaderAware reader = new CSVReaderHeaderAware(createReader(), 0, parser, false, false, 1, Locale.getDefault(),
187 new LineValidatorAggregator(), new RowValidatorAggregator(), new RowProcessor() {
188 @Override
189 public String processColumnItem(String column) {return column;}
190
191 @Override
192 public void processRow(String[] row) {}
193 })) {
194 assertThat(reader.readMap().keySet().iterator().next(), is("myHeader"));
195 }
196 }
197
198 private StringReader createReader() {
199 StringBuilder sb = new StringBuilder(ICSVParser.INITIAL_READ_SIZE);
200 sb.append("first,second,third\n");
201 sb.append("a,b,c").append("\n");
202 sb.append("a,\"b,b,b\",c").append("\n");
203 sb.append(",,").append("\n");
204 sb.append("a,\"PO Box 123,\nKippax,ACT. 2615.\nAustralia\",d.\n");
205 sb.append("\"Glen \"\"The Man\"\" Smith\",Athlete,Developer\n");
206 sb.append("\"\"\"\"\"\",\"test\"\n");
207 sb.append("\"a\nb\",b,\"\nd\",e\n");
208 sb.append("a");
209 return new StringReader(sb.toString());
210 }
211 }