001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.commons.beanutils;
019:
020: import java.math.BigDecimal;
021: import java.sql.Date;
022: import java.sql.ResultSet;
023: import java.sql.ResultSetMetaData;
024: import java.sql.SQLException;
025: import java.sql.Timestamp;
026: import java.sql.Types;
027: import java.util.List;
028:
029: import junit.framework.TestCase;
030: import junit.framework.Test;
031: import junit.framework.TestSuite;
032:
033: /**
034: * Test accessing RowSets via DynaBeans.
035: *
036: * @author Craig R. McClanahan
037: * @version $Revision: 556233 $ $Date: 2007-07-14 07:37:06 +0100 (Sat, 14 Jul 2007) $
038: */
039:
040: public class DynaRowSetTestCase extends TestCase {
041:
042: // ----------------------------------------------------- Instance Variables
043:
044: /**
045: * The mock result set DynaClass to be tested.
046: */
047: protected RowSetDynaClass dynaClass = null;
048:
049: /**
050: * Names of the columns for this test. Must match the order they are
051: * defined in {@link TestResultSetMetaData}, and must be all lower case.
052: */
053: protected String columns[] = { "bigdecimalproperty",
054: "booleanproperty", "byteproperty", "dateproperty",
055: "doubleproperty", "floatproperty", "intproperty",
056: "longproperty", "nullproperty", "shortproperty",
057: "stringproperty", "timeproperty", "timestampproperty" };
058:
059: // ----------------------------------------------------------- Constructors
060:
061: /**
062: * Construct a new instance of this test case.
063: *
064: * @param name Name of the test case
065: */
066: public DynaRowSetTestCase(String name) {
067:
068: super (name);
069:
070: }
071:
072: // --------------------------------------------------- Overall Test Methods
073:
074: /**
075: * Set up instance variables required by this test case.
076: */
077: public void setUp() throws Exception {
078:
079: dynaClass = new RowSetDynaClass(TestResultSet.createProxy());
080:
081: }
082:
083: /**
084: * Return the tests included in this test suite.
085: */
086: public static Test suite() {
087:
088: return (new TestSuite(DynaRowSetTestCase.class));
089:
090: }
091:
092: /**
093: * Tear down instance variables required by this test case.
094: */
095: public void tearDown() {
096:
097: dynaClass = null;
098:
099: }
100:
101: // ------------------------------------------------ Individual Test Methods
102:
103: public void testGetName() {
104:
105: assertEquals("DynaClass name",
106: "org.apache.commons.beanutils.RowSetDynaClass",
107: dynaClass.getName());
108:
109: }
110:
111: public void testGetDynaProperty() {
112:
113: // Invalid argument test
114: try {
115: dynaClass.getDynaProperty(null);
116: fail("Did not throw IllegaArgumentException");
117: } catch (IllegalArgumentException e) {
118: // Expected result
119: }
120:
121: // Negative test
122: DynaProperty dynaProp = dynaClass
123: .getDynaProperty("unknownProperty");
124: assertTrue("unknown property returns null", (dynaProp == null));
125:
126: // Positive test
127: dynaProp = dynaClass.getDynaProperty("stringproperty");
128: assertNotNull("string property exists", dynaProp);
129: assertEquals("string property name", "stringproperty", dynaProp
130: .getName());
131: assertEquals("string property class", String.class, dynaProp
132: .getType());
133:
134: }
135:
136: public void testGetDynaProperties() {
137:
138: DynaProperty dynaProps[] = dynaClass.getDynaProperties();
139: assertNotNull("dynaProps exists", dynaProps);
140: assertEquals("dynaProps length", columns.length,
141: dynaProps.length);
142: for (int i = 0; i < columns.length; i++) {
143: assertEquals("Property " + columns[i], columns[i],
144: dynaProps[i].getName());
145: }
146:
147: }
148:
149: public void testNewInstance() {
150:
151: try {
152: dynaClass.newInstance();
153: fail("Did not throw UnsupportedOperationException()");
154: } catch (UnsupportedOperationException e) {
155: // Expected result
156: } catch (Exception e) {
157: fail("Threw exception " + e);
158: }
159:
160: }
161:
162: public void testListCount() {
163:
164: List rows = dynaClass.getRows();
165: assertNotNull("list exists", rows);
166: assertEquals("list row count", 5, rows.size());
167:
168: }
169:
170: public void testListResults() {
171:
172: // Grab the third row
173: List rows = dynaClass.getRows();
174: DynaBean row = (DynaBean) rows.get(2);
175:
176: // Invalid argument test
177: try {
178: row.get("unknownProperty");
179: fail("Did not throw IllegalArgumentException");
180: } catch (IllegalArgumentException e) {
181: // Expected result
182: }
183:
184: // Verify property values
185:
186: Object bigDecimalProperty = row.get("bigdecimalproperty");
187: assertNotNull("bigDecimalProperty exists", bigDecimalProperty);
188: assertTrue("bigDecimalProperty type",
189: bigDecimalProperty instanceof BigDecimal);
190: assertEquals("bigDecimalProperty value", 123.45,
191: ((BigDecimal) bigDecimalProperty).doubleValue(), 0.005);
192:
193: Object intProperty = row.get("intproperty");
194: assertNotNull("intProperty exists", intProperty);
195: assertTrue("intProperty type", intProperty instanceof Integer);
196: assertEquals("intProperty value", 103, ((Integer) intProperty)
197: .intValue());
198:
199: Object nullProperty = row.get("nullproperty");
200: assertNull("nullProperty null", nullProperty);
201:
202: Object stringProperty = row.get("stringproperty");
203: assertNotNull("stringProperty exists", stringProperty);
204: assertTrue("stringProperty type",
205: stringProperty instanceof String);
206: assertEquals("stringProperty value", "This is a string",
207: (String) stringProperty);
208:
209: }
210:
211: /**
212: * Test normal case column names (i.e. not converted to lower case)
213: */
214: public void testListResultsNormalCase() {
215: RowSetDynaClass dynaClass = null;
216: try {
217: dynaClass = new RowSetDynaClass(
218: TestResultSet.createProxy(), false);
219: } catch (Exception e) {
220: fail("Error creating RowSetDynaClass: " + e);
221: }
222:
223: // Grab the third row
224: List rows = dynaClass.getRows();
225: DynaBean row = (DynaBean) rows.get(2);
226:
227: // Invalid argument test
228: try {
229: row.get("unknownProperty");
230: fail("Did not throw IllegalArgumentException");
231: } catch (IllegalArgumentException e) {
232: // Expected result
233: }
234:
235: // Verify property values
236:
237: Object bigDecimalProperty = row.get("bigDecimalProperty");
238: assertNotNull("bigDecimalProperty exists", bigDecimalProperty);
239: assertTrue("bigDecimalProperty type",
240: bigDecimalProperty instanceof BigDecimal);
241: assertEquals("bigDecimalProperty value", 123.45,
242: ((BigDecimal) bigDecimalProperty).doubleValue(), 0.005);
243:
244: Object intProperty = row.get("intProperty");
245: assertNotNull("intProperty exists", intProperty);
246: assertTrue("intProperty type", intProperty instanceof Integer);
247: assertEquals("intProperty value", 103, ((Integer) intProperty)
248: .intValue());
249:
250: Object nullProperty = row.get("nullProperty");
251: assertNull("nullProperty null", nullProperty);
252:
253: Object stringProperty = row.get("stringProperty");
254: assertNotNull("stringProperty exists", stringProperty);
255: assertTrue("stringProperty type",
256: stringProperty instanceof String);
257: assertEquals("stringProperty value", "This is a string",
258: (String) stringProperty);
259:
260: }
261:
262: public void testLimitedRows() throws Exception {
263:
264: // created one with low limit
265: RowSetDynaClass limitedDynaClass = new RowSetDynaClass(
266: TestResultSet.createProxy(), 3);
267: List rows = limitedDynaClass.getRows();
268: assertNotNull("list exists", rows);
269: assertEquals("limited row count", 3, rows.size());
270:
271: }
272:
273: /**
274: * Test issues associated with Oracle JDBC driver.
275: *
276: * See issue# https://issues.apache.org/jira/browse/BEANUTILS-142
277: *
278: * @throws Exception if an error occurs
279: */
280: public void testInconsistentOracleDriver() throws Exception {
281:
282: ResultSetMetaData metaData = TestResultSetMetaData
283: .createProxy(new TestResultSetMetaDataInconsistent());
284: ResultSet resultSet = TestResultSet
285: .createProxy(new TestResultSetInconsistent(metaData));
286:
287: // Date Column returns "java.sql.Timestamp" for the column class name but ResultSet getObject
288: // returns a java.sql.Date value
289: int dateColIdx = 4;
290: assertEquals("Date Meta Name", "dateProperty", metaData
291: .getColumnName(dateColIdx));
292: assertEquals("Date Meta Class", "java.sql.Timestamp", metaData
293: .getColumnClassName(dateColIdx));
294: assertEquals("Date Meta Type", java.sql.Types.DATE, metaData
295: .getColumnType(dateColIdx));
296: assertEquals("Date ResultSet Value", java.sql.Date.class,
297: resultSet.getObject("dateProperty").getClass());
298:
299: // Timestamp column class returns a custom Timestamp impl for the column class name and ResultSet getObject
300: int timestampColIdx = 13;
301: assertEquals("Timestamp Meta Name", "timestampProperty",
302: metaData.getColumnName(timestampColIdx));
303: assertEquals("Timestamp Meta Class", CustomTimestamp.class
304: .getName(), metaData
305: .getColumnClassName(timestampColIdx));
306: assertEquals("Timestamp Meta Type", java.sql.Types.TIMESTAMP,
307: metaData.getColumnType(timestampColIdx));
308: assertEquals("Timestamp ResultSet Value",
309: CustomTimestamp.class, resultSet.getObject(
310: "timestampProperty").getClass());
311:
312: RowSetDynaClass inconsistentDynaClass = new RowSetDynaClass(
313: resultSet);
314: DynaBean firstRow = (DynaBean) inconsistentDynaClass.getRows()
315: .get(0);
316: Class expectedType = null;
317: DynaProperty property = null;
318:
319: // Test Date
320: property = firstRow.getDynaClass().getDynaProperty(
321: "dateproperty");
322: expectedType = java.sql.Date.class;
323: assertEquals("Date Class", expectedType, property.getType());
324: assertEquals("Date Value", expectedType, firstRow.get(
325: property.getName()).getClass());
326:
327: // Test Timestamp
328: property = firstRow.getDynaClass().getDynaProperty(
329: "timestampproperty");
330: expectedType = java.sql.Timestamp.class;
331: assertEquals("Timestamp Class", expectedType, property
332: .getType());
333: assertEquals("Timestamp Value", expectedType, firstRow.get(
334: property.getName()).getClass());
335: }
336:
337: /**
338: * A proxy ResultSet implementation that returns Timstamp for a date column.
339: *
340: * See issue# https://issues.apache.org/jira/browse/BEANUTILS-142
341: */
342: private static class TestResultSetInconsistent extends
343: TestResultSet {
344:
345: public TestResultSetInconsistent(ResultSetMetaData metaData) {
346: super (metaData);
347: }
348:
349: /**
350: * Get an columns's value
351: * @param columnName Name of the column
352: * @return the column value
353: * @throws SQLException if an error occurs
354: */
355: public Object getObject(String columnName) throws SQLException {
356: if ("timestampProperty".equals(columnName)) {
357: return new CustomTimestamp();
358: } else {
359: return super .getObject(columnName);
360: }
361: }
362:
363: }
364:
365: /**
366: * A proxy ResultSetMetaData implementation that returns a class name that
367: * is inconsistent with the type returned by the ResultSet.getObject() method.
368: *
369: * See issue# https://issues.apache.org/jira/browse/BEANUTILS-142
370: */
371: private static class TestResultSetMetaDataInconsistent extends
372: TestResultSetMetaData {
373:
374: /**
375: * This method substitues class names of "java.sql.Timestamp" with
376: * "java.sql.Date" to test inconsistent JDBC drivers.
377: *
378: * @param columnIndex The column index
379: * @return The column class name
380: * @throws SQLException if an error occurs
381: */
382: public String getColumnClassName(int columnIndex)
383: throws SQLException {
384: String columnName = getColumnName(columnIndex);
385: if (columnName.equals("dateProperty")) {
386: return java.sql.Timestamp.class.getName();
387: } else if (columnName.equals("timestampProperty")) {
388: return CustomTimestamp.class.getName();
389: } else {
390: return super .getColumnClassName(columnIndex);
391: }
392: }
393: }
394:
395: private static class CustomTimestamp {
396: private long timestamp = new java.util.Date().getTime();
397:
398: public String toString() {
399: return "CustomTimestamp[" + timestamp + "]";
400: }
401: }
402: }
|