blob: 148cb055796432f36133c9cf8779564e6fbf25a6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.beanutils2;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.List;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Test accessing RowSets via DynaBeans.
*
*/
public class DynaRowSetTestCase extends TestCase {
/**
* The mock result set DynaClass to be tested.
*/
protected RowSetDynaClass dynaClass = null;
/**
* Names of the columns for this test. Must match the order they are
* defined in {@link TestResultSetMetaData}, and must be all lower case.
*/
protected String columns[] =
{ "bigdecimalproperty", "booleanproperty",
"byteproperty", "dateproperty",
"doubleproperty", "floatproperty",
"intproperty", "longproperty",
"nullproperty", "shortproperty",
"stringproperty", "timeproperty",
"timestampproperty" };
/**
* Construct a new instance of this test case.
*
* @param name Name of the test case
*/
public DynaRowSetTestCase(final String name) {
super(name);
}
/**
* Set up instance variables required by this test case.
*/
@Override
public void setUp() throws Exception {
dynaClass = new RowSetDynaClass(TestResultSet.createProxy());
}
/**
* Return the tests included in this test suite.
*/
public static Test suite() {
return new TestSuite(DynaRowSetTestCase.class);
}
/**
* Tear down instance variables required by this test case.
*/
@Override
public void tearDown() {
dynaClass = null;
}
public void testGetName() {
assertEquals("DynaClass name",
"org.apache.commons.beanutils2.RowSetDynaClass",
dynaClass.getName());
}
public void testGetDynaProperty() {
// Invalid argument test
try {
dynaClass.getDynaProperty(null);
fail("Did not throw IllegaArgumentException");
} catch (final IllegalArgumentException e) {
// Expected result
}
// Negative test
DynaProperty dynaProp = dynaClass.getDynaProperty("unknownProperty");
assertTrue("unknown property returns null",
dynaProp == null);
// Positive test
dynaProp = dynaClass.getDynaProperty("stringproperty");
assertNotNull("string property exists", dynaProp);
assertEquals("string property name", "stringproperty",
dynaProp.getName());
assertEquals("string property class", String.class,
dynaProp.getType());
}
public void testGetDynaProperties() {
final DynaProperty dynaProps[] = dynaClass.getDynaProperties();
assertNotNull("dynaProps exists", dynaProps);
assertEquals("dynaProps length", columns.length, dynaProps.length);
for (int i = 0; i < columns.length; i++) {
assertEquals("Property " + columns[i],
columns[i], dynaProps[i].getName());
}
}
public void testNewInstance() {
try {
dynaClass.newInstance();
fail("Did not throw UnsupportedOperationException()");
} catch (final UnsupportedOperationException e) {
// Expected result
} catch (final Exception e) {
fail("Threw exception " + e);
}
}
public void testListCount() {
final List<DynaBean> rows = dynaClass.getRows();
assertNotNull("list exists", rows);
assertEquals("list row count", 5, rows.size());
}
public void testListResults() {
// Grab the third row
final List<DynaBean> rows = dynaClass.getRows();
final DynaBean row = rows.get(2);
// Invalid argument test
try {
row.get("unknownProperty");
fail("Did not throw IllegalArgumentException");
} catch (final IllegalArgumentException e) {
// Expected result
}
// Verify property values
final Object bigDecimalProperty = row.get("bigdecimalproperty");
assertNotNull("bigDecimalProperty exists", bigDecimalProperty);
assertTrue("bigDecimalProperty type",
bigDecimalProperty instanceof BigDecimal);
assertEquals("bigDecimalProperty value",
123.45,
((BigDecimal) bigDecimalProperty).doubleValue(),
0.005);
final Object intProperty = row.get("intproperty");
assertNotNull("intProperty exists", intProperty);
assertTrue("intProperty type",
intProperty instanceof Integer);
assertEquals("intProperty value",
103,
((Integer) intProperty).intValue());
final Object nullProperty = row.get("nullproperty");
assertNull("nullProperty null", nullProperty);
final Object stringProperty = row.get("stringproperty");
assertNotNull("stringProperty exists", stringProperty);
assertTrue("stringProperty type",
stringProperty instanceof String);
assertEquals("stringProperty value",
"This is a string",
(String) stringProperty);
}
/**
* Test normal case column names (i.e. not converted to lower case)
*/
public void testListResultsNormalCase() {
RowSetDynaClass dynaClass = null;
try {
dynaClass = new RowSetDynaClass(TestResultSet.createProxy(), false);
} catch (final Exception e) {
fail("Error creating RowSetDynaClass: " + e);
}
// Grab the third row
final List<DynaBean> rows = dynaClass.getRows();
final DynaBean row = rows.get(2);
// Invalid argument test
try {
row.get("unknownProperty");
fail("Did not throw IllegalArgumentException");
} catch (final IllegalArgumentException e) {
// Expected result
}
// Verify property values
final Object bigDecimalProperty = row.get("bigDecimalProperty");
assertNotNull("bigDecimalProperty exists", bigDecimalProperty);
assertTrue("bigDecimalProperty type",
bigDecimalProperty instanceof BigDecimal);
assertEquals("bigDecimalProperty value",
123.45,
((BigDecimal) bigDecimalProperty).doubleValue(),
0.005);
final Object intProperty = row.get("intProperty");
assertNotNull("intProperty exists", intProperty);
assertTrue("intProperty type",
intProperty instanceof Integer);
assertEquals("intProperty value",
103,
((Integer) intProperty).intValue());
final Object nullProperty = row.get("nullProperty");
assertNull("nullProperty null", nullProperty);
final Object stringProperty = row.get("stringProperty");
assertNotNull("stringProperty exists", stringProperty);
assertTrue("stringProperty type",
stringProperty instanceof String);
assertEquals("stringProperty value",
"This is a string",
(String) stringProperty);
}
public void testLimitedRows() throws Exception {
// created one with low limit
final RowSetDynaClass limitedDynaClass = new RowSetDynaClass(TestResultSet.createProxy(), 3);
final List<DynaBean> rows = limitedDynaClass.getRows();
assertNotNull("list exists", rows);
assertEquals("limited row count", 3, rows.size());
}
/**
* Test issues associated with Oracle JDBC driver.
*
* See issue# https://issues.apache.org/jira/browse/BEANUTILS-142
*
* @throws Exception if an error occurs
*/
public void testInconsistentOracleDriver() throws Exception {
final ResultSetMetaData metaData = TestResultSetMetaData.createProxy(new TestResultSetMetaDataInconsistent());
final ResultSet resultSet = TestResultSet.createProxy(new TestResultSetInconsistent(metaData));
// Date Column returns "java.sql.Timestamp" for the column class name but ResultSet getObject
// returns a java.sql.Date value
final int dateColIdx = 4;
assertEquals("Date Meta Name", "dateProperty", metaData.getColumnName(dateColIdx));
assertEquals("Date Meta Class", "java.sql.Timestamp", metaData.getColumnClassName(dateColIdx));
assertEquals("Date Meta Type", java.sql.Types.DATE, metaData.getColumnType(dateColIdx));
assertEquals("Date ResultSet Value", java.sql.Date.class, resultSet.getObject("dateProperty").getClass());
// Timestamp column class returns a custom Timestamp impl for the column class name and ResultSet getObject
final int timestampColIdx = 13;
assertEquals("Timestamp Meta Name", "timestampProperty", metaData.getColumnName(timestampColIdx));
assertEquals("Timestamp Meta Class", CustomTimestamp.class.getName(), metaData.getColumnClassName(timestampColIdx));
assertEquals("Timestamp Meta Type", java.sql.Types.TIMESTAMP, metaData.getColumnType(timestampColIdx));
assertEquals("Timestamp ResultSet Value", CustomTimestamp.class, resultSet.getObject("timestampProperty").getClass());
final RowSetDynaClass inconsistentDynaClass = new RowSetDynaClass(resultSet);
final DynaBean firstRow = inconsistentDynaClass.getRows().get(0);
Class<?> expectedType = null;
DynaProperty property = null;
// Test Date
property = firstRow.getDynaClass().getDynaProperty("dateproperty");
expectedType = java.sql.Date.class;
assertEquals("Date Class", expectedType, property.getType());
assertEquals("Date Value", expectedType, firstRow.get(property.getName()).getClass());
// Test Timestamp
property = firstRow.getDynaClass().getDynaProperty("timestampproperty");
expectedType = java.sql.Timestamp.class;
assertEquals("Timestamp Class", expectedType, property.getType());
assertEquals("Timestamp Value", expectedType, firstRow.get(property.getName()).getClass());
}
/**
* A proxy ResultSet implementation that returns Timstamp for a date column.
*
* See issue# https://issues.apache.org/jira/browse/BEANUTILS-142
*/
private static class TestResultSetInconsistent extends TestResultSet {
public TestResultSetInconsistent(final ResultSetMetaData metaData) {
super(metaData);
}
/**
* Get an columns's value
* @param columnName Name of the column
* @return the column value
* @throws SQLException if an error occurs
*/
@Override
public Object getObject(final String columnName) throws SQLException {
if ("timestampProperty".equals(columnName)) {
return new CustomTimestamp();
}
return super.getObject(columnName);
}
}
/**
* A proxy ResultSetMetaData implementation that returns a class name that
* is inconsistent with the type returned by the ResultSet.getObject() method.
*
* See issue# https://issues.apache.org/jira/browse/BEANUTILS-142
*/
private static class TestResultSetMetaDataInconsistent extends TestResultSetMetaData {
/**
* This method substitues class names of "java.sql.Timestamp" with
* "java.sql.Date" to test inconsistent JDBC drivers.
*
* @param columnIndex The column index
* @return The column class name
* @throws SQLException if an error occurs
*/
@Override
public String getColumnClassName(final int columnIndex) throws SQLException {
final String columnName = getColumnName(columnIndex);
if (columnName.equals("dateProperty")) {
return java.sql.Timestamp.class.getName();
} else if (columnName.equals("timestampProperty")) {
return CustomTimestamp.class.getName();
} else {
return super.getColumnClassName(columnIndex);
}
}
}
private static class CustomTimestamp {
private final long timestamp = new java.util.Date().getTime();
@Override
public String toString() {
return "CustomTimestamp[" + timestamp + "]";
}
}
}