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.util;
17  
18  import static org.junit.Assert.assertEquals;
19  import static org.junit.Assert.assertTrue;
20  import static org.supercsv.util.ReflectionUtils.findGetter;
21  import static org.supercsv.util.ReflectionUtils.findSetter;
22  
23  import java.lang.reflect.Constructor;
24  
25  import org.junit.After;
26  import org.junit.Before;
27  import org.junit.Test;
28  import org.supercsv.exception.SuperCsvReflectionException;
29  import org.supercsv.mock.ReflectionBean;
30  
31  /**
32   * Test the ReflectionUtils class.
33   * 
34   * @author James Bassett
35   */
36  public class ReflectionUtilsTest {
37  	
38  	private static final double DOUBLE_ASSERT_DELTA = 1e-15;
39  	
40  	private ReflectionBean bean;
41  	
42  	/**
43  	 * Sets up before the test.
44  	 */
45  	@Before
46  	public void setUp() {
47  		bean = new ReflectionBean();
48  	}
49  	
50  	/**
51  	 * Tidies up after the test.
52  	 */
53  	@After
54  	public void tearDown() {
55  		bean = null;
56  	}
57  	
58  	/**
59  	 * Tests the findGetter() method.
60  	 */
61  	@Test
62  	public void testFindGetter() throws Exception {
63  		final String name = "Bob";
64  		bean.setName(name);
65  		assertEquals(name, findGetter(bean, "name").invoke(bean));
66  	}
67  	
68  	/**
69  	 * Tests the findGetter() method with an 'get' style boolean getter.
70  	 */
71  	@Test
72  	public void testFindBooleanGetter() throws Exception {
73  		final Boolean boolValue = true;
74  		bean.setBooleanWrapper(boolValue);
75  		assertEquals(boolValue, findGetter(bean, "booleanWrapper").invoke(bean));
76  	}
77  	
78  	/**
79  	 * Tests the findGetter() method with an 'is' style boolean getter.
80  	 */
81  	@Test
82  	public void testFindAlternateBooleanGetter() throws Exception {
83  		final boolean boolValue = true;
84  		bean.setPrimitiveBoolean(boolValue);
85  		assertEquals(boolValue, findGetter(bean, "primitiveBoolean").invoke(bean));
86  	}
87  	
88  	/**
89  	 * Tests the findGetter() method with an 'is' style Boolean getter.
90  	 */
91  	@Test
92  	public void testFindAlternateBooleanWrapperGetter() throws Exception {
93  		final Boolean boolValue = Boolean.TRUE;
94  		bean.setBooleanWrapper2(boolValue);
95  		assertEquals(boolValue, findGetter(bean, "booleanWrapper2").invoke(bean));
96  	}
97  	
98  	/**
99  	 * Tests the findSetter() method.
100 	 */
101 	@Test
102 	public void testFindSetter() throws Exception {
103 		final String name = "Bob";
104 		findSetter(bean, "name", String.class).invoke(bean, name);
105 		assertEquals(name, bean.getName());
106 	}
107 	
108 	/**
109 	 * Tests the findSetter() method with a field type that is a subtype of the setter parameter type.
110 	 */
111 	@Test
112 	public void testFindSetterWithSubtype() throws Exception {
113 		findSetter(bean, "favouriteNumber", Integer.class).invoke(bean, Integer.valueOf(123));
114 		assertEquals(123, bean.getFavouriteNumber().intValue());
115 	}
116 	
117 	/**
118 	 * Tests the findSetter() method with a field type that's compatible with 2 setters (the exact match should always
119 	 * be used).
120 	 */
121 	@Test
122 	public void testFindSetterWithTwoOptions() throws Exception {
123 		findSetter(bean, "overloaded", Number.class).invoke(bean, Integer.valueOf(123));
124 		assertEquals(123, bean.getOverloaded().intValue());
125 	}
126 	
127 	/**
128 	 * Tests the findSetter() method with a field type that's compatible with 1 setter but has the same name as another
129 	 * method (which should be ignored).
130 	 */
131 	@Test
132 	public void testFindSetterWithMethodOfSameName() throws Exception {
133 		findSetter(bean, "primitiveBoolean", boolean.class).invoke(bean, true);
134 		assertTrue(bean.isPrimitiveBoolean());
135 	}
136 	
137 	/**
138 	 * Tests the findGetter() method with a field name that is all capitals.
139 	 */
140 	@Test
141 	public void testFindURLGetter() throws Exception {
142 		final String url = "www.google.com";
143 		bean.setURL(url);
144 		assertEquals(url, findGetter(bean, "URL").invoke(bean));
145 	}
146 	
147 	/**
148 	 * Tests the findSetter() method with a field name that is all capitals.
149 	 */
150 	@Test
151 	public void testFindURLSetter() throws Exception {
152 		final String url = "www.google.com";
153 		findSetter(bean, "URL", String.class).invoke(bean, url);
154 		assertEquals(url, bean.getURL());
155 	}
156 	
157 	/**
158 	 * Tests the findGetter() method with a getter that has a lowercase char after 'get'.
159 	 */
160 	@Test
161 	public void testFindiPhoneGetter() throws Exception {
162 		final String value = "Apple";
163 		bean.setiPad(value);
164 		assertEquals(value, findGetter(bean, "iPad").invoke(bean));
165 	}
166 	
167 	/**
168 	 * Tests the findSetter() method with a setter that has a lowercase char after 'set'.
169 	 */
170 	@Test
171 	public void testFindiPhoneSetter() throws Exception {
172 		final String value = "Apple";
173 		findSetter(bean, "iPad", String.class).invoke(bean, value);
174 		assertEquals(value, bean.getiPad());
175 	}
176 
177 	/**
178 	 * Tests the findGetter() method with a getter which checks "Turkey Test" support.
179 	 */
180 	@Test
181 	public void testFindIsTurkishGetter() throws Exception {
182 		final boolean value = true;
183 		bean.setIsTurkish(value);
184 		assertEquals(value, findGetter(bean, "isTurkish").invoke(bean));
185 	}
186 
187 	/**
188 	 * Tests the findSetter() method with a setter which checks "Turkey Test" support.
189 	 */
190 	@Test
191 	public void testFindIsTurkishSetter() throws Exception {
192 		final boolean value = true;
193 		findSetter(bean, "isTurkish", Boolean.class).invoke(bean, value);
194 		assertEquals(value, bean.getIsTurkish());
195 	}
196 	
197 	/**
198 	 * Tests the findSetter() method by passing primitives and wrapper classes to setters that expect wrapper classes
199 	 * and primitives respectively (this tests the autoboxing logic).
200 	 */
201 	@Test
202 	public void testAutoboxing() throws Exception {
203 		
204 		// first try setting wrapper values onto the primitive setters
205 		
206 		findSetter(bean, "primitiveBoolean", Boolean.class).invoke(bean, Boolean.TRUE);
207 		assertEquals(true, bean.isPrimitiveBoolean());
208 		
209 		findSetter(bean, "primitiveInt", Integer.class).invoke(bean, Integer.valueOf(1));
210 		assertEquals(1, bean.getPrimitiveInt());
211 		
212 		findSetter(bean, "primitiveShort", Short.class).invoke(bean, Short.valueOf("2"));
213 		assertEquals(Short.parseShort("2"), bean.getPrimitiveShort());
214 		
215 		findSetter(bean, "primitiveLong", Long.class).invoke(bean, Long.valueOf("3"));
216 		assertEquals(Long.parseLong("3"), bean.getPrimitiveLong());
217 		
218 		findSetter(bean, "primitiveDouble", Double.class).invoke(bean, Double.valueOf("4.0"));
219 		assertEquals(Double.parseDouble("4.0"), bean.getPrimitiveDouble(), DOUBLE_ASSERT_DELTA);
220 		
221 		findSetter(bean, "primitiveFloat", Float.class).invoke(bean, Float.valueOf("5.0"));
222 		assertEquals(Float.parseFloat("5.0"), bean.getPrimitiveFloat(), DOUBLE_ASSERT_DELTA);
223 		
224 		findSetter(bean, "primitiveChar", Character.class).invoke(bean, Character.valueOf('a'));
225 		assertEquals('a', bean.getPrimitiveChar());
226 		
227 		findSetter(bean, "primitiveByte", Byte.class).invoke(bean, Byte.valueOf("123"));
228 		assertEquals(Byte.parseByte("123"), bean.getPrimitiveByte());
229 		
230 		// now try setting primitive values onto the wrapper setters
231 		
232 		findSetter(bean, "booleanWrapper", boolean.class).invoke(bean, true);
233 		assertEquals(Boolean.TRUE, bean.getBooleanWrapper());
234 		
235 		findSetter(bean, "integerWrapper", int.class).invoke(bean, 1);
236 		assertEquals(Integer.valueOf(1), bean.getIntegerWrapper());
237 		
238 		findSetter(bean, "shortWrapper", short.class).invoke(bean, Short.parseShort("2"));
239 		assertEquals(Short.valueOf("2"), bean.getShortWrapper());
240 		
241 		findSetter(bean, "longWrapper", long.class).invoke(bean, Long.parseLong("3"));
242 		assertEquals(Long.valueOf("3"), bean.getLongWrapper());
243 		
244 		findSetter(bean, "doubleWrapper", double.class).invoke(bean, Double.parseDouble("4.0"));
245 		assertEquals(Double.valueOf("4.0"), bean.getDoubleWrapper());
246 		
247 		findSetter(bean, "floatWrapper", float.class).invoke(bean, Float.parseFloat("5.0"));
248 		assertEquals(Float.valueOf("5.0"), bean.getFloatWrapper());
249 		
250 		findSetter(bean, "charWrapper", char.class).invoke(bean, 'a');
251 		assertEquals(Character.valueOf('a'), bean.getCharWrapper());
252 		
253 		findSetter(bean, "byteWrapper", byte.class).invoke(bean, Byte.parseByte("123"));
254 		assertEquals(Byte.valueOf("123"), bean.getByteWrapper());
255 		
256 	}
257 	
258 	/**
259 	 * Tests the findGetter() method with a null object (should throw an exception).
260 	 */
261 	@Test(expected = NullPointerException.class)
262 	public void testFindGetterWithNullObject() {
263 		findGetter(null, "name");
264 	}
265 	
266 	/**
267 	 * Tests the findGetter() method with a null field name (should throw an exception).
268 	 */
269 	@Test(expected = NullPointerException.class)
270 	public void testFindGetterWithNullFieldName() {
271 		findGetter(bean, null);
272 	}
273 	
274 	/**
275 	 * Tests the findGetter() method with an invalid field name (should throw an exception).
276 	 */
277 	@Test(expected = SuperCsvReflectionException.class)
278 	public void testFindGetterWithInvalidFieldName() {
279 		findGetter(bean, "invalid");
280 	}
281 	
282 	/**
283 	 * Tests the findSetter() method with a null object (should throw an exception).
284 	 */
285 	@Test(expected = NullPointerException.class)
286 	public void testFindSetterWithNullObject() {
287 		findSetter(null, "name", String.class);
288 	}
289 	
290 	/**
291 	 * Tests the findSetter() method with a null field name (should throw an exception).
292 	 */
293 	@Test(expected = NullPointerException.class)
294 	public void testFindSetterWithNullFieldName() {
295 		findSetter(bean, null, String.class);
296 	}
297 	
298 	/**
299 	 * Tests the findSetter() method with a null field type (should throw an exception).
300 	 */
301 	@Test(expected = NullPointerException.class)
302 	public void testFindSetterWithNullFieldType() {
303 		findSetter(bean, "name", null);
304 	}
305 	
306 	/**
307 	 * Tests the findSetter() method with an invalid field name (should throw an exception).
308 	 */
309 	@Test(expected = SuperCsvReflectionException.class)
310 	public void testFindSetterWithInvalidFieldName() {
311 		findSetter(bean, "invalid", String.class);
312 	}
313 	
314 	/**
315 	 * Tests the findSetter() method with an invalid field name with a primitive parameter type (should throw an
316 	 * exception after trying both primitive and wrapper method signatures).
317 	 */
318 	@Test(expected = SuperCsvReflectionException.class)
319 	public void testFindSetterWithInvalidFieldNameAndPrimitiveType() {
320 		findSetter(bean, "invalid", int.class);
321 	}
322 	
323 	/**
324 	 * Tests the private constructor for test coverage (yes, this is stupid).
325 	 */
326 	@Test
327 	public void testPrivateConstructor() throws Exception {
328 		Constructor<?> c = ReflectionUtils.class.getDeclaredConstructors()[0];
329 		c.setAccessible(true);
330 		c.newInstance();
331 	}
332 	
333 }