1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.opencsv.bean;
17
18 import com.opencsv.CSVParser;
19 import com.opencsv.CSVParserBuilder;
20 import com.opencsv.CSVReader;
21 import com.opencsv.CSVReaderBuilder;
22 import com.opencsv.bean.mocks.*;
23 import com.opencsv.enums.CSVReaderNullFieldIndicator;
24 import com.opencsv.exceptions.CsvException;
25 import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
26 import org.junit.jupiter.api.Assertions;
27 import org.junit.jupiter.api.Test;
28
29 import java.io.*;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.NoSuchElementException;
33
34 import static org.junit.jupiter.api.Assertions.*;
35
36 public class CsvToBeanAsIteratorTest {
37
38 private static final String TEST_STRING = "name,orderNumber,num\n"
39 + "kyle,abc123456,123\n"
40 + "jimmy,def098765,456 ";
41
42 private CSVReader createReader() {
43 StringReader reader = new StringReader(TEST_STRING);
44 return new CSVReader(reader);
45 }
46
47
48
49 private static class FilterSmallNumbers implements CsvToBeanFilter {
50 @Override
51 public boolean allowLine(String[] line) {
52 return Integer.parseInt(line[2].trim()) > 200;
53 }
54 }
55
56 @Test
57 public void throwRuntimeExceptionWhenExceptionIsThrown() {
58 CsvToBean<Object> bean = new CsvToBean<>();
59 bean.setMappingStrategy(new ErrorHeaderMappingStrategy<>());
60 bean.setCsvReader(createReader());
61 Assertions.assertThrows(RuntimeException.class, () -> {
62 for (Object o : bean) {
63 }
64 });
65 }
66
67 @Test
68 public void throwRuntimeExceptionLineWhenExceptionIsThrown() {
69 CsvToBean<Object> bean = new CsvToBean<>();
70 bean.setMappingStrategy(new ErrorLineMappingStrategy<>());
71 bean.setCsvReader(createReader());
72 Assertions.assertThrows(RuntimeException.class, () -> {
73 for (Object o : bean) {
74 }
75 });
76 }
77
78 @Test
79 public void parseBeanWithNoAnnotations() {
80 HeaderColumnNameMappingStrategy<MockBean> strategy = new HeaderColumnNameMappingStrategy<>();
81 strategy.setType(MockBean.class);
82 CsvToBean<MockBean> bean = new CsvToBean<>();
83 bean.setMappingStrategy(strategy);
84 bean.setCsvReader(createReader());
85
86 Iterator<MockBean> it = bean.iterator();
87 assertTrue(it.hasNext());
88 assertEquals(new MockBean("kyle", null, "abc123456", 123, 0.0), it.next());
89 assertTrue(it.hasNext());
90 assertEquals(new MockBean("jimmy", null, "def098765", 456, 0.0), it.next());
91 assertFalse(it.hasNext());
92 try {
93 it.next();
94 fail("Iterator should have thrown an exception trying to access the element after the end of the list");
95 } catch (NoSuchElementException e) {
96 }
97 }
98
99 @Test
100 public void iteratorShouldNotSupportRemove() {
101 HeaderColumnNameMappingStrategy<MockBean> strategy = new HeaderColumnNameMappingStrategy<>();
102 strategy.setType(MockBean.class);
103 CsvToBean<MockBean> bean = new CsvToBean<>();
104 bean.setMappingStrategy(strategy);
105 bean.setCsvReader(createReader());
106
107 Iterator<MockBean> it = bean.iterator();
108 Assertions.assertThrows(UnsupportedOperationException.class, it::remove);
109 }
110
111 @Test
112 public void bug133ShouldNotThrowNullPointerExceptionWhenProcessingEmptyWithNoAnnotations() {
113 HeaderColumnNameMappingStrategy<Bug133Bean> strategy = new HeaderColumnNameMappingStrategy<>();
114 strategy.setType(Bug133Bean.class);
115
116 StringReader reader = new StringReader("one;two;three\n"
117 + "kyle;;123\n"
118 + "jimmy;;456 ");
119
120 CSVParserBuilder parserBuilder = new CSVParserBuilder();
121 CSVReaderBuilder readerBuilder = new CSVReaderBuilder(reader);
122
123 CSVParser parser = parserBuilder.withFieldAsNull(CSVReaderNullFieldIndicator.BOTH).withSeparator(';').build();
124 CSVReader csvReader = readerBuilder.withCSVParser(parser).build();
125
126 CsvToBean<Bug133Bean> bean = new CsvToBean<>();
127 bean.setMappingStrategy(strategy);
128 bean.setCsvReader(csvReader);
129
130 Iterator<Bug133Bean> it = bean.iterator();
131 assertTrue(it.hasNext());
132 assertNotNull(it.next());
133 assertTrue(it.hasNext());
134 assertNotNull(it.next());
135 assertFalse(it.hasNext());
136 }
137
138 @Test
139 public void throwIllegalStateWhenParseWithoutArgumentsIsCalled() {
140 CsvToBean csvtb = new CsvToBean();
141 Assertions.assertThrows(IllegalStateException.class, csvtb::iterator);
142 }
143
144 @Test
145 public void throwIllegalStateWhenOnlyReaderIsSpecifiedToParseWithoutArguments() {
146 CsvToBean csvtb = new CsvToBean();
147 csvtb.setCsvReader(new CSVReader(new StringReader(TEST_STRING)));
148 Assertions.assertThrows(IllegalStateException.class, csvtb::iterator);
149 }
150
151 @Test
152 public void throwIllegalStateWhenOnlyMapperIsSpecifiedToParseWithoutArguments() {
153 CsvToBean<AnnotatedMockBeanFull> csvtb = new CsvToBean<>();
154 HeaderColumnNameMappingStrategy<AnnotatedMockBeanFull> strat = new HeaderColumnNameMappingStrategy<>();
155 strat.setType(AnnotatedMockBeanFull.class);
156 csvtb.setMappingStrategy(strat);
157 Assertions.assertThrows(IllegalStateException.class, csvtb::iterator);
158 }
159
160 @Test
161 public void readWithIteratorAndFilter() {
162 HeaderColumnNameMappingStrategy<MockBean> strategy;
163 strategy = new HeaderColumnNameMappingStrategy<>();
164 strategy.setType(MockBean.class);
165 CsvToBean<MockBean> bean = new CsvToBeanBuilder<MockBean>(new StringReader(TEST_STRING))
166 .withMappingStrategy(strategy)
167 .withFilter(new FilterSmallNumbers())
168 .build();
169
170 Iterator<MockBean> iterator = bean.iterator();
171
172 assertTrue(iterator.hasNext());
173 MockBean mockBean = iterator.next();
174 assertEquals("jimmy", mockBean.getName());
175 assertEquals("def098765", mockBean.getOrderNumber());
176 assertEquals(456, mockBean.getNum());
177
178 assertFalse(iterator.hasNext());
179 }
180
181 @Test
182 public void readWithIteratorOfAnnotatedBean() {
183 HeaderColumnNameMappingStrategy<MinimalCsvBindByNameBeanForWriting> minimalStrategy = new HeaderColumnNameMappingStrategy<>();
184 minimalStrategy.setType(MinimalCsvBindByNameBeanForWriting.class);
185 StringReader reader = new StringReader("finda,findb,c\n1,2,3\n4,5,6");
186 Iterator<MinimalCsvBindByNameBeanForWriting> iterator = new CsvToBeanBuilder<MinimalCsvBindByNameBeanForWriting>(reader)
187 .withMappingStrategy(minimalStrategy)
188 .build()
189 .iterator();
190
191 assertTrue(iterator.hasNext());
192 MinimalCsvBindByNameBeanForWriting mockBean = iterator.next();
193 assertEquals(1, mockBean.getA());
194 assertEquals(2, mockBean.getB());
195 assertEquals(3, mockBean.getC());
196
197 assertTrue(iterator.hasNext());
198 mockBean = iterator.next();
199 assertEquals(4, mockBean.getA());
200 assertEquals(5, mockBean.getB());
201 assertEquals(6, mockBean.getC());
202
203 assertFalse(iterator.hasNext());
204 }
205
206 @Test
207 public void testRequiredHeaderMissing() {
208 HeaderColumnNameMappingStrategy<AnnotatedMockBeanForIterator> strat
209 = new HeaderColumnNameMappingStrategy<>();
210 strat.setType(AnnotatedMockBeanForIterator.class);
211 Reader fin = new StringReader("a\n1;2\n3,4");
212 Assertions.assertThrows(RuntimeException.class, () -> {
213 Iterator<AnnotatedMockBeanForIterator> iterator = new CsvToBeanBuilder<AnnotatedMockBeanForIterator>(fin)
214 .withMappingStrategy(strat)
215 .withSeparator(';')
216 .build()
217 .iterator();
218 });
219 }
220
221 @Test
222 public void testPrematureEOLUsingHeaderNameMappingWithoutExceptionCapturing() {
223 HeaderColumnNameMappingStrategy<AnnotatedMockBeanForIterator> strat
224 = new HeaderColumnNameMappingStrategy<>();
225 strat.setType(AnnotatedMockBeanForIterator.class);
226 Reader fin = new StringReader("a;b\n1;2\n3");
227 Iterator<AnnotatedMockBeanForIterator> iterator = new CsvToBeanBuilder<AnnotatedMockBeanForIterator>(fin)
228 .withMappingStrategy(strat)
229 .withSeparator(';')
230 .build()
231 .iterator();
232 try {
233 iterator.next();
234 fail("The first bean should not have been returned since the second bean is incomplete.");
235 } catch (RuntimeException e) {
236 assertNotNull(e.getCause());
237 assertTrue(e.getCause() instanceof CsvRequiredFieldEmptyException);
238 }
239 }
240
241 @Test
242 public void testPrematureEOLUsingHeaderNameMappingWithExceptionCapturing() {
243 HeaderColumnNameMappingStrategy<AnnotatedMockBeanForIterator> strat
244 = new HeaderColumnNameMappingStrategy<>();
245 strat.setType(AnnotatedMockBeanForIterator.class);
246 Reader fin = new StringReader("a;b\n1;2\n3");
247 CsvToBean<AnnotatedMockBeanForIterator> csvtb = new CsvToBeanBuilder<AnnotatedMockBeanForIterator>(fin)
248 .withMappingStrategy(strat)
249 .withSeparator(';')
250 .withThrowExceptions(false)
251 .build();
252 Iterator<AnnotatedMockBeanForIterator> iterator = csvtb.iterator();
253
254 iterator.next();
255 assertFalse(iterator.hasNext());
256 List<CsvException> savedExceptions = csvtb.getCapturedExceptions();
257 assertEquals(1, savedExceptions.size());
258 CsvException csve = savedExceptions.get(0);
259 assertTrue(csve instanceof CsvRequiredFieldEmptyException);
260 }
261
262 @Test
263 public void iteratorConvertsIOExceptionToRuntimeException() {
264 HeaderColumnNameMappingStrategy<MockBean> strategy = new HeaderColumnNameMappingStrategy<>();
265 strategy.setType(MockBean.class);
266 CsvToBean<MockBean> bean = new CsvToBean<>();
267 bean.setMappingStrategy(strategy);
268 bean.setCsvReader(new CSVReader(new ReaderThrowsIOException()));
269
270 try {
271 bean.iterator();
272 fail("Exception should have been thrown.");
273 } catch (RuntimeException re) {
274 assertNotNull(re.getCause());
275 assertTrue(re.getCause() instanceof IOException);
276 }
277 }
278
279 @Test
280 public void testMultipleExceptionsPerLine() throws FileNotFoundException {
281 ColumnPositionMappingStrategy<AnnotatedMockBeanFull> strat =
282 new ColumnPositionMappingStrategy<>();
283 strat.setType(AnnotatedMockBeanFull.class);
284 Reader fin = new FileReader("src/test/resources/testMultipleExceptionsPerLine.csv");
285 CsvToBean<AnnotatedMockBeanFull> ctb = new CsvToBeanBuilder<AnnotatedMockBeanFull>(fin)
286 .withMappingStrategy(strat)
287 .withSeparator(';')
288 .withThrowExceptions(false)
289 .build();
290 Iterator<AnnotatedMockBeanFull> it = ctb.iterator();
291 while(it.hasNext()) { it.next(); }
292 List<CsvException> exceptionList = ctb.getCapturedExceptions();
293 assertNotNull(exceptionList);
294 assertEquals(6, exceptionList.size());
295 assertEquals(1, exceptionList.get(0).getLineNumber());
296 assertEquals(1, exceptionList.get(1).getLineNumber());
297 assertEquals(1, exceptionList.get(2).getLineNumber());
298 assertEquals(2, exceptionList.get(3).getLineNumber());
299 assertEquals(2, exceptionList.get(4).getLineNumber());
300 assertEquals(2, exceptionList.get(5).getLineNumber());
301 }
302 }