View Javadoc
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   * @author Andre Rosot
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          // test quoted commas
46          nextLine = csvr.readNext();
47          assertEquals("a", nextLine[0]);
48          assertEquals("b,b,b", nextLine[1]);
49          assertEquals("c", nextLine[2]);
50  
51          // test empty elements
52          nextLine = csvr.readNext();
53          assertEquals(3, nextLine.length);
54  
55          // test multiline quoted
56          nextLine = csvr.readNext();
57          assertEquals(3, nextLine.length);
58  
59          // test quoted quote chars
60          nextLine = csvr.readNext();
61          assertEquals("Glen \"The Man\" Smith", nextLine[0]);
62  
63          nextLine = csvr.readNext();
64          assertEquals("\"\"", nextLine[0]); // check the tricky situation
65          assertEquals("test", nextLine[1]); // make sure we didn't ruin the next field..
66  
67          nextLine = csvr.readNext();
68          assertEquals(4, nextLine.length);
69  
70          assertEquals("a", csvr.readNext()[0]);
71  
72          //test end of stream
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          // The first two lines are irrelevant for this test.
83          csvr.readNext();
84          csvr.readNext();
85  
86          // test empty elements that are null
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");   // standard case
202         sb.append("a,\"b,b,b\",c").append("\n");  // quoted elements
203         sb.append(",,").append("\n"); // empty elements
204         sb.append("a,\"PO Box 123,\nKippax,ACT. 2615.\nAustralia\",d.\n");
205         sb.append("\"Glen \"\"The Man\"\" Smith\",Athlete,Developer\n"); // Test quoted quote chars
206         sb.append("\"\"\"\"\"\",\"test\"\n"); // """""","test"  representing:  "", test
207         sb.append("\"a\nb\",b,\"\nd\",e\n");
208         sb.append("a");
209         return new StringReader(sb.toString());
210     }
211 }