View Javadoc
1   /*
2    * Copyright 2007 Kasper B. Graversen
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.supercsv.io;
17  
18  import static org.junit.Assert.assertArrayEquals;
19  import static org.junit.Assert.assertEquals;
20  import static org.junit.Assert.assertNull;
21  import static org.supercsv.SuperCsvTestUtils.ADA;
22  import static org.supercsv.SuperCsvTestUtils.ADA_STRING;
23  import static org.supercsv.SuperCsvTestUtils.ALICE;
24  import static org.supercsv.SuperCsvTestUtils.ALICE_STRING;
25  import static org.supercsv.SuperCsvTestUtils.BILL;
26  import static org.supercsv.SuperCsvTestUtils.BILL_STRING;
27  import static org.supercsv.SuperCsvTestUtils.BOB;
28  import static org.supercsv.SuperCsvTestUtils.BOB_STRING;
29  import static org.supercsv.SuperCsvTestUtils.CSV_FILE;
30  import static org.supercsv.SuperCsvTestUtils.CUSTOMERS;
31  import static org.supercsv.SuperCsvTestUtils.GRACE;
32  import static org.supercsv.SuperCsvTestUtils.GRACE_STRING;
33  import static org.supercsv.SuperCsvTestUtils.HEADER;
34  import static org.supercsv.SuperCsvTestUtils.JOHN;
35  import static org.supercsv.SuperCsvTestUtils.JOHN_STRING;
36  import static org.supercsv.SuperCsvTestUtils.LARRY;
37  import static org.supercsv.SuperCsvTestUtils.LARRY_STRING;
38  import static org.supercsv.SuperCsvTestUtils.MIRANDA;
39  import static org.supercsv.SuperCsvTestUtils.MIRANDA_STRING;
40  import static org.supercsv.SuperCsvTestUtils.PARTIAL_HEADER;
41  import static org.supercsv.SuperCsvTestUtils.READ_PROCESSORS;
42  import static org.supercsv.SuperCsvTestUtils.SERGEI;
43  import static org.supercsv.SuperCsvTestUtils.SERGEI_STRING;
44  import static org.supercsv.SuperCsvTestUtils.STEVE;
45  import static org.supercsv.SuperCsvTestUtils.STEVE_STRING;
46  import static org.supercsv.SuperCsvTestUtils.STRING_CUSTOMERS;
47  
48  import java.io.IOException;
49  import java.io.Reader;
50  import java.io.StringReader;
51  
52  import org.junit.After;
53  import org.junit.Before;
54  import org.junit.Test;
55  import org.supercsv.cellprocessor.ift.CellProcessor;
56  import org.supercsv.exception.SuperCsvReflectionException;
57  import org.supercsv.mock.Customer;
58  import org.supercsv.mock.CustomerBean;
59  import org.supercsv.mock.CustomerStringBean;
60  import org.supercsv.mock.PersonBean;
61  import org.supercsv.prefs.CsvPreference;
62  
63  /**
64   * Tests the CsvBeanReader class.
65   * 
66   * @author James Bassett
67   */
68  public class CsvBeanReaderTest {
69  	
70  	private static final CsvPreference PREFS = CsvPreference.STANDARD_PREFERENCE;
71  	
72  	private Reader reader;
73  	
74  	private CsvBeanReader beanReader;
75  	
76  	private CsvBeanReader tokenizerBeanReader;
77  	
78  	/**
79  	 * Sets up the reader for the tests.
80  	 */
81  	@Before
82  	public void setUp() {
83  		reader = new StringReader(CSV_FILE);
84  		beanReader = new CsvBeanReader(reader, PREFS);
85  		
86  		final Tokenizer tokenizer = new Tokenizer(reader, PREFS);
87  		tokenizerBeanReader = new CsvBeanReader(tokenizer, PREFS);
88  	}
89  	
90  	/**
91  	 * Closes the readers after the test.
92  	 */
93  	@After
94  	public void tearDown() throws IOException {
95  		beanReader.close();
96  		tokenizerBeanReader.close();
97  	}
98  	
99  	/**
100 	 * Tests the read() method using processors.
101 	 */
102 	@Test
103 	public void testReadWithProcessors() throws IOException {
104 		
105 		final String[] header = beanReader.getHeader(true);
106 		assertArrayEquals(HEADER, header);
107 		
108 		assertEquals(JOHN, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
109 		assertEquals(BOB, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
110 		assertEquals(ALICE, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
111 		assertEquals(BILL, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
112 		assertEquals(MIRANDA, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
113 		assertEquals(STEVE, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
114 		assertEquals(ADA, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
115 		assertEquals(SERGEI, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
116 		assertEquals(LARRY, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
117 		assertEquals(GRACE, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
118 		assertNull(beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
119 	}
120 	
121 	/**
122 	 * Tests the read() method using processors, but only mapping a few columns.
123 	 */
124 	@Test
125 	public void testPartialReadWithProcessors() throws IOException {
126 		
127 		assertArrayEquals(HEADER, beanReader.getHeader(true));
128 		
129 		final String[] header = PARTIAL_HEADER;
130 		for( CustomerBean fullCustomer : CUSTOMERS ) {
131 			
132 			// create the expected customer (same as full but with only first/last name and email)
133 			CustomerBean expectedCustomer = new CustomerBean();
134 			expectedCustomer.setFirstName(fullCustomer.getFirstName());
135 			expectedCustomer.setLastName(fullCustomer.getLastName());
136 			expectedCustomer.setEmail(fullCustomer.getEmail());
137 			assertEquals(expectedCustomer, beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
138 		}
139 		
140 		assertNull(beanReader.read(CustomerBean.class, header, READ_PROCESSORS));
141 	}
142 	
143 	/**
144 	 * Tests the read() method with no processors.
145 	 */
146 	@Test
147 	public void testRead() throws IOException {
148 		
149 		final String[] header = beanReader.getHeader(true);
150 		assertArrayEquals(HEADER, header);
151 		
152 		assertEquals(JOHN_STRING, beanReader.read(CustomerStringBean.class, header));
153 		assertEquals(BOB_STRING, beanReader.read(CustomerStringBean.class, header));
154 		assertEquals(ALICE_STRING, beanReader.read(CustomerStringBean.class, header));
155 		assertEquals(BILL_STRING, beanReader.read(CustomerStringBean.class, header));
156 		assertEquals(MIRANDA_STRING, beanReader.read(CustomerStringBean.class, header));
157 		assertEquals(STEVE_STRING, beanReader.read(CustomerStringBean.class, header));
158 		assertEquals(ADA_STRING, beanReader.read(CustomerStringBean.class, header));
159 		assertEquals(SERGEI_STRING, beanReader.read(CustomerStringBean.class, header));
160 		assertEquals(LARRY_STRING, beanReader.read(CustomerStringBean.class, header));
161 		assertEquals(GRACE_STRING, beanReader.read(CustomerStringBean.class, header));
162 		assertNull(beanReader.read(CustomerStringBean.class, header));
163 	}
164 	
165 	/**
166 	 * Tests the read() method, but only mapping a few columns.
167 	 */
168 	@Test
169 	public void testPartialRead() throws IOException {
170 		
171 		assertArrayEquals(HEADER, beanReader.getHeader(true));
172 		
173 		final String[] header = PARTIAL_HEADER;
174 		for( CustomerStringBean fullCustomer : STRING_CUSTOMERS ) {
175 			
176 			// create the expected customer (same as full but with only first/last name and email)
177 			CustomerBean expectedCustomer = new CustomerBean();
178 			expectedCustomer.setFirstName(fullCustomer.getFirstName());
179 			expectedCustomer.setLastName(fullCustomer.getLastName());
180 			expectedCustomer.setEmail(fullCustomer.getEmail());
181 			assertEquals(expectedCustomer, beanReader.read(CustomerBean.class, header));
182 		}
183 		
184 		assertNull(beanReader.read(CustomerBean.class, header));
185 	}
186 	
187 	/**
188 	 * Tests the read() method with no processors, populating an existing bean.
189 	 */
190 	@Test
191 	public void testReadIntoExistingBean() throws IOException {
192 		
193 		final String[] header = beanReader.getHeader(true);
194 		assertArrayEquals(HEADER, header);
195 		
196 		assertEquals(JOHN_STRING, beanReader.read(new CustomerStringBean(), header));
197 		assertEquals(BOB_STRING, beanReader.read(new CustomerStringBean(), header));
198 		assertEquals(ALICE_STRING, beanReader.read(new CustomerStringBean(), header));
199 		assertEquals(BILL_STRING, beanReader.read(new CustomerStringBean(), header));
200 		assertEquals(MIRANDA_STRING, beanReader.read(new CustomerStringBean(), header));
201 		assertEquals(STEVE_STRING, beanReader.read(new CustomerStringBean(), header));
202 		assertEquals(ADA_STRING, beanReader.read(new CustomerStringBean(), header));
203 		assertEquals(SERGEI_STRING, beanReader.read(new CustomerStringBean(), header));
204 		assertEquals(LARRY_STRING, beanReader.read(new CustomerStringBean(), header));
205 		assertEquals(GRACE_STRING, beanReader.read(new CustomerStringBean(), header));
206 		assertNull(beanReader.read(new CustomerStringBean(), header));
207 	}
208 	
209 	/**
210 	 * Tests the read() method using processors, populating an existing bean.
211 	 */
212 	@Test
213 	public void testReadIntoExistingBeanWithProcessors() throws IOException {
214 		
215 		final String[] header = beanReader.getHeader(true);
216 		assertArrayEquals(HEADER, header);
217 		
218 		assertEquals(JOHN, beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
219 		assertEquals(BOB, beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
220 		assertEquals(ALICE, beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
221 		assertEquals(BILL, beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
222 		assertEquals(MIRANDA, beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
223 		assertEquals(STEVE, beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
224 		assertEquals(ADA, beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
225 		assertEquals(SERGEI, beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
226 		assertEquals(LARRY, beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
227 		assertEquals(GRACE, beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
228 		assertNull(beanReader.read(new CustomerBean(), header, READ_PROCESSORS));
229 	}
230 	
231 	/**
232 	 * Tests the read() method with no processors, using the tokenizer version of CsvBeanReader (just to make sure it
233 	 * behaves exactly the same as the reader version).
234 	 */
235 	@Test
236 	public void testReadUsingTokenizerReader() throws IOException {
237 		
238 		final String[] header = tokenizerBeanReader.getHeader(true);
239 		assertArrayEquals(HEADER, header);
240 		
241 		assertEquals(JOHN_STRING, tokenizerBeanReader.read(CustomerStringBean.class, header));
242 		assertEquals(BOB_STRING, tokenizerBeanReader.read(CustomerStringBean.class, header));
243 		assertEquals(ALICE_STRING, tokenizerBeanReader.read(CustomerStringBean.class, header));
244 		assertEquals(BILL_STRING, tokenizerBeanReader.read(CustomerStringBean.class, header));
245 		assertEquals(MIRANDA_STRING, tokenizerBeanReader.read(CustomerStringBean.class, header));
246 		assertEquals(STEVE_STRING, tokenizerBeanReader.read(CustomerStringBean.class, header));
247 		assertEquals(ADA_STRING, tokenizerBeanReader.read(CustomerStringBean.class, header));
248 		assertEquals(SERGEI_STRING, tokenizerBeanReader.read(CustomerStringBean.class, header));
249 		assertEquals(LARRY_STRING, tokenizerBeanReader.read(CustomerStringBean.class, header));
250 		assertEquals(GRACE_STRING, tokenizerBeanReader.read(CustomerStringBean.class, header));
251 		assertNull(tokenizerBeanReader.read(CustomerStringBean.class, header));
252 	}
253 	
254 	/**
255 	 * Tests the read() method with an interface and using processors.
256 	 */
257 	@Test
258 	public void testReadWithProcessorsUsingInterface() throws IOException {
259 		assertArrayEquals(HEADER, beanReader.getHeader(true));
260 		
261 		// only map the fields relevant to the interface
262 		final String[] header = new String[] { "customerNo", null, null, null, "mailingAddress", null, null, null,
263 			null, "loyaltyPoints" };
264 		
265 		int i = 0;
266 		Customer customer;
267 		while( (customer = beanReader.read(Customer.class, header, READ_PROCESSORS)) != null ) {
268 			assertEquals(CUSTOMERS.get(i).getCustomerNo(), customer.getCustomerNo());
269 			assertEquals(CUSTOMERS.get(i).getMailingAddress(), customer.getMailingAddress());
270 			assertEquals(CUSTOMERS.get(i).getLoyaltyPoints(), customer.getLoyaltyPoints());
271 			i++;
272 		}
273 		
274 		assertEquals(CUSTOMERS.size() + 1, beanReader.getRowNumber());
275 		
276 	}
277 	
278 	/**
279 	 * Tests the read() method with an class that has no default no-arg constructor.
280 	 */
281 	@Test(expected = SuperCsvReflectionException.class)
282 	public void testReadWithNonJavabean() throws IOException {
283 		beanReader.read(Integer.class, HEADER);
284 	}
285 	
286 	/**
287 	 * Tests the read() method, with a null bean class.
288 	 */
289 	@Test(expected = NullPointerException.class)
290 	public void testReadWithNullBeanClass() throws IOException {
291 		beanReader.read(null, HEADER);
292 	}
293 	
294 	/**
295 	 * Tests the read() method, with a null bean.
296 	 */
297 	@Test(expected = NullPointerException.class)
298 	public void testReadWithNullBean() throws IOException {
299 		beanReader.read((Object) null, HEADER);
300 	}
301 	
302 	/**
303 	 * Tests the read() method, with a null name mapping array.
304 	 */
305 	@Test(expected = NullPointerException.class)
306 	public void testReadWithNullNameMapping() throws IOException {
307 		beanReader.read(PersonBean.class, (String[]) null);
308 	}
309 	
310 	/**
311 	 * Tests the read() method, with a null name mapping array.
312 	 */
313 	@Test(expected = NullPointerException.class)
314 	public void testReadIntoBeanWithNullNameMapping() throws IOException {
315 		beanReader.read(new PersonBean(), (String[]) null);
316 	}
317 	
318 	/**
319 	 * Tests the read() method, with a name mapping array that's not the right size.
320 	 */
321 	@Test(expected = IllegalArgumentException.class)
322 	public void testReadWithInvalidSizeNameMapping() throws IOException {
323 		beanReader.getHeader(true);
324 		beanReader.read(PersonBean.class, new String[] { null, "firstName" });
325 	}
326 	
327 	/**
328 	 * Tests the read() method, with a name mapping array that's not the right size.
329 	 */
330 	@Test(expected = IllegalArgumentException.class)
331 	public void testReadIntoBeanWithInvalidSizeNameMapping() throws IOException {
332 		beanReader.getHeader(true);
333 		beanReader.read(new PersonBean(), new String[] { null, "firstName" });
334 	}
335 	
336 	/**
337 	 * Tests the read() method (with processors), with a null bean class.
338 	 */
339 	@Test(expected = NullPointerException.class)
340 	public void testReadProcessorsWithNullBeanClass() throws IOException {
341 		beanReader.read(null, HEADER, READ_PROCESSORS);
342 	}
343 	
344 	/**
345 	 * Tests the read() method (with processors), with a null bean.
346 	 */
347 	@Test(expected = NullPointerException.class)
348 	public void testReadUsingProcessorsWithNullBean() throws IOException {
349 		beanReader.read((Object) null, HEADER, READ_PROCESSORS);
350 	}
351 	
352 	/**
353 	 * Tests the read() method (with processors), with a null name mapping array.
354 	 */
355 	@Test(expected = NullPointerException.class)
356 	public void testReadProcessorsWithNullNameMapping() throws IOException {
357 		beanReader.read(PersonBean.class, (String[]) null, READ_PROCESSORS);
358 	}
359 	
360 	/**
361 	 * Tests the read() method (with processors), with a null name mapping array.
362 	 */
363 	@Test(expected = NullPointerException.class)
364 	public void testReadIntoBeanUsingProcessorsWithNullNameMapping() throws IOException {
365 		beanReader.read(new PersonBean(), (String[]) null, READ_PROCESSORS);
366 	}
367 	
368 	/**
369 	 * Tests the read() method (with processors), with a null cell processor array.
370 	 */
371 	@Test(expected = NullPointerException.class)
372 	public void testReadProcessorsWithNullProcessors() throws IOException {
373 		beanReader.read(PersonBean.class, HEADER, (CellProcessor[]) null);
374 	}
375 	
376 	/**
377 	 * Tests the read() method (with processors), with a null cell processor array.
378 	 */
379 	@Test(expected = NullPointerException.class)
380 	public void testReadIntoBeanUsingProcessorsWithNullProcessors() throws IOException {
381 		beanReader.read(new PersonBean(), HEADER, (CellProcessor[]) null);
382 	}
383 	
384 	/**
385 	 * Tests the Reader constructor with a null Reader.
386 	 */
387 	@SuppressWarnings("resource")
388 	@Test(expected = NullPointerException.class)
389 	public void testReaderConstructorWithNullReader() {
390 		new CsvBeanReader((Reader) null, PREFS);
391 	}
392 	
393 	/**
394 	 * Tests the Reader constructor with a null preference.
395 	 */
396 	@SuppressWarnings("resource")
397 	@Test(expected = NullPointerException.class)
398 	public void testReaderConstructorWithNullPreferences() {
399 		new CsvBeanReader(reader, null);
400 	}
401 	
402 	/**
403 	 * Tests the Tokenizer constructor with a null Reader.
404 	 */
405 	@SuppressWarnings("resource")
406 	@Test(expected = NullPointerException.class)
407 	public void testTokenizerConstructorWithNullReader() {
408 		new CsvBeanReader((Tokenizer) null, PREFS);
409 	}
410 	
411 	/**
412 	 * Tests the Tokenizer constructor with a null preference.
413 	 */
414 	@SuppressWarnings("resource")
415 	@Test(expected = NullPointerException.class)
416 	public void testTokenizerConstructorWithNullPreferences() {
417 		new CsvBeanReader(new Tokenizer(reader, PREFS), null);
418 	}
419 	
420 	/**
421 	 * Tests the read() method when invoking the bean's constructor throws IllegalAccessException.
422 	 */
423 	@Test(expected = SuperCsvReflectionException.class)
424 	public void testBeanInstantationThrowingIllegalAccessException() throws IOException {
425 		beanReader.read(IllegalAccessBean.class, HEADER);
426 	}
427 	
428 	/**
429 	 * Tests the read() method when invoking a setter throws an Exception.
430 	 */
431 	@SuppressWarnings("resource")
432 	@Test(expected = SuperCsvReflectionException.class)
433 	public void testSetterThrowingException() throws IOException {
434 		new CsvBeanReader(new StringReader("value"), PREFS).read(ExceptionBean.class, "illegalArgument");
435 	}
436 	
437 	/**
438 	 * Bean to test exceptions when invoking setters using CsvBeanReader.
439 	 */
440 	public static class ExceptionBean extends CustomerBean {
441 		
442 		public void setIllegalArgument(String s) {
443 			throw new IllegalArgumentException("i don't like it!");
444 		}
445 		
446 	}
447 	
448 	/**
449 	 * Bean to test exceptions when invoking the constructor using CsvBeanWriter.
450 	 */
451 	public static class IllegalAccessBean extends CustomerBean {
452 		
453 		public IllegalAccessBean() throws IllegalAccessException {
454 			throw new IllegalAccessException("naughty naughty!");
455 		}
456 		
457 	}
458 }