AbstractNumberConverterTest.java
/*
* 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
*
* https://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.converters;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import org.apache.commons.beanutils2.ConversionException;
import org.junit.jupiter.api.Test;
/**
* Abstract base for <Number>Converter classes.
*
* @param <T> Number type.
*/
abstract class AbstractNumberConverterTest<T extends Number> {
/** Test Number values */
protected Number[] numbers = new Number[4];
protected abstract Class<T> getExpectedType();
protected abstract NumberConverter<T> makeConverter();
protected abstract NumberConverter<T> makeConverter(T defaultValue);
/**
* Convert Boolean --> Number (default conversion)
*/
@Test
void testBooleanToNumberDefault() {
final NumberConverter<T> converter = makeConverter();
// Other type --> String conversion
assertEquals(0, ((Number) converter.convert(getExpectedType(), Boolean.FALSE)).intValue(), "Boolean.FALSE to Number ");
assertEquals(1, ((Number) converter.convert(getExpectedType(), Boolean.TRUE)).intValue(), "Boolean.TRUE to Number ");
}
/**
* Convert Calendar --> Long
*/
@Test
void testCalendarToNumber() {
final NumberConverter<T> converter = makeConverter();
final Calendar calendarValue = Calendar.getInstance();
final long longValue = calendarValue.getTime().getTime();
// Calendar --> Long conversion
assertEquals(Long.valueOf(longValue), converter.convert(Long.class, calendarValue), "Calendar to Long");
// Calendar --> Integer
assertThrows(ConversionException.class, () -> converter.convert(Integer.class, calendarValue), "Calendar to Integer - expected a ConversionException");
}
/**
* Assumes ConversionException in response to covert(getExpectedType(),null).
*/
@Test
void testConvertNull() {
assertThrows(ConversionException.class, () -> makeConverter().convert(getExpectedType(), null), "Expected ConversionException");
}
/**
* Assumes convert(getExpectedType(),Number) returns some non-null instance of getExpectedType().
*/
@Test
void testConvertNumber() {
final String[] message = { "from Byte", "from Short", "from Integer", "from Long", "from Float", "from Double", "from BigDecimal", "from BigInteger",
"from Integer array", };
final Object[] number = { Byte.valueOf((byte) 7), Short.valueOf((short) 8), Integer.valueOf(9), Long.valueOf(10), Float.valueOf((float) 11.1),
Double.valueOf(12.2), new BigDecimal("17.2"), new BigInteger("33"),
new Integer[] { Integer.valueOf(3), Integer.valueOf(2), Integer.valueOf(1) } };
for (int i = 0; i < number.length; i++) {
final Object val = makeConverter().convert(getExpectedType(), number[i]);
assertNotNull(val, "Convert " + message[i] + " should not be null");
assertTrue(getExpectedType().isInstance(val), "Convert " + message[i] + " should return a " + getExpectedType().getName());
}
}
/**
* Convert Date --> Long
*/
@Test
void testDateToNumber() {
final NumberConverter<T> converter = makeConverter();
final Date dateValue = new Date();
final long longValue = dateValue.getTime();
// Date --> Long conversion
assertEquals(Long.valueOf(longValue), converter.convert(Long.class, dateValue), "Date to Long");
// Date --> Integer
assertThrows(ConversionException.class, () -> converter.convert(Integer.class, dateValue), "Date to Integer - expected a ConversionException");
}
/**
* Convert Number --> String (using default and specified Locales)
*/
@Test
void testInvalidDefault() {
final T defaultvalue = (T) numbers[0];
final NumberConverter<T> converter = makeConverter(defaultvalue);
// Default String --> Number conversion
assertEquals(defaultvalue, converter.convert(getExpectedType(), null), "Invalid null ");
assertEquals(defaultvalue, converter.convert(getExpectedType(), "XXXX"), "Default XXXX ");
}
/**
* Convert Number --> String (using default and specified Locales)
*/
@Test
void testInvalidException() {
final NumberConverter<T> converter = makeConverter();
assertThrows(ConversionException.class, () -> converter.convert(getExpectedType(), null), "Null test, expected ConversionException");
assertThrows(ConversionException.class, () -> converter.convert(getExpectedType(), "XXXX"), "Invalid test, expected ConversionException");
}
/**
* Test specifying an invalid type.
*/
@Test
void testInvalidType() {
final NumberConverter<T> converter = makeConverter();
assertThrows(ConversionException.class, () -> converter.convert(Object.class, numbers[0]), "Invalid type test, expected ConversionException");
}
/**
* Tests a conversion to an unsupported type if a default value is set.
*/
@Test
void testInvalidTypeWithDefault() {
final NumberConverter<T> converter = makeConverter((T) numbers[0]);
assertThrows(ConversionException.class, () -> converter.convert(Object.class, numbers[0]),
"Invalid type with default test, expected ConversionException");
}
/**
* Convert Number --> String (default conversion)
*/
@Test
void testNumberToStringDefault() {
final NumberConverter<T> converter = makeConverter();
// Default Number --> String conversion
assertEquals(numbers[0].toString(), converter.convert(String.class, numbers[0]), () -> "Default Convert " + numbers[0]);
assertEquals(numbers[1].toString(), converter.convert(String.class, numbers[1]), () -> "Default Convert " + numbers[1]);
}
/**
* Convert Number --> String (using default and specified Locales)
*/
@Test
void testNumberToStringLocale() {
// Re-set the default Locale to Locale.US
final Locale defaultLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
final NumberConverter<T> converter = makeConverter();
converter.setUseLocaleFormat(true);
// Default Locale
assertEquals("-12", converter.convert(String.class, numbers[0]), () -> "Default Locale " + numbers[0]);
assertEquals("13", converter.convert(String.class, numbers[1]), () -> "Default Locale " + numbers[1]);
// Locale.GERMAN
converter.setLocale(Locale.GERMAN);
assertEquals("-22", converter.convert(String.class, numbers[2]), () -> "Locale.GERMAN " + numbers[2]);
assertEquals("23", converter.convert(String.class, numbers[3]), () -> "Locale.GERMAN " + numbers[3]);
// Restore the default Locale
Locale.setDefault(defaultLocale);
}
/**
* Convert Number --> String (using a Pattern, with default and specified Locales)
*/
@Test
void testNumberToStringPattern() {
// Re-set the default Locale to Locale.US
final Locale defaultLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
final NumberConverter<T> converter = makeConverter();
converter.setPattern("[0,0.0];(0,0.0)");
// Default Locale
assertEquals("(12.0)", converter.convert(String.class, numbers[0]), () -> "Default Locale " + numbers[0]);
assertEquals("[13.0]", converter.convert(String.class, numbers[1]), () -> "Default Locale " + numbers[1]);
// Locale.GERMAN
converter.setLocale(Locale.GERMAN);
assertEquals("(22,0)", converter.convert(String.class, numbers[2]), () -> "Locale.GERMAN " + numbers[2]);
assertEquals("[23,0]", converter.convert(String.class, numbers[3]), () -> "Locale.GERMAN " + numbers[3]);
// Restore the default Locale
Locale.setDefault(defaultLocale);
}
/**
* Convert Other --> String (default conversion)
*/
@Test
void testOtherToStringDefault() {
final NumberConverter<T> converter = makeConverter();
// Other type --> String conversion
assertEquals("ABC", converter.convert(String.class, new StringBuilder("ABC")), "Default Convert ");
}
/**
* Convert Array --> Number
*/
@Test
void testStringArrayToInteger() {
final Integer defaultValue = Integer.valueOf(-1);
final NumberConverter<Integer> converter = new IntegerConverterTest().makeConverter(defaultValue);
// Default Locale
assertEquals(Integer.valueOf(5), converter.convert(Integer.class, new String[] { "5", "4", "3" }), "Valid First");
assertEquals(defaultValue, converter.convert(Integer.class, new String[] { "FOO", "1", "2" }), "Invalid First");
assertEquals(defaultValue, converter.convert(Integer.class, new String[] { null, "1", "2" }), "Null First");
assertEquals(Integer.valueOf(9), converter.convert(Integer.class, new long[] { 9, 2, 6 }), "Long Array");
}
/**
* Convert String --> Number (default conversion)
*/
@Test
void testStringToNumberDefault() {
final NumberConverter<T> converter = makeConverter();
converter.setUseLocaleFormat(false);
// Default String --> Number conversion
assertEquals(numbers[0], converter.convert(getExpectedType(), numbers[0].toString()), () -> "Default Convert " + numbers[0]);
// Invalid
assertThrows(ConversionException.class, () -> converter.convert(getExpectedType(), "12x"), "Expected invalid value to cause ConversionException");
}
/**
* Convert String --> Number if the target type is not defined. Then the default type should be used.
*/
@Test
void testStringToNumberDefaultType() {
final NumberConverter<T> converter = makeConverter();
converter.setUseLocaleFormat(false);
assertEquals(numbers[0], converter.convert(null, numbers[0].toString()), () -> "Default Convert " + numbers[0]);
}
/**
* Convert String --> Number (using default and specified Locales)
*/
@Test
void testStringToNumberLocale() {
// Re-set the default Locale to Locale.US
final Locale defaultLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
final NumberConverter<T> converter = makeConverter();
converter.setUseLocaleFormat(true);
// Default Locale
assertEquals(numbers[0], converter.convert(getExpectedType(), "-0,012"), () -> "Default Locale " + numbers[0]);
assertEquals(numbers[1], converter.convert(getExpectedType(), "0,013"), () -> "Default Locale " + numbers[1]);
// Invalid Value
assertThrows(ConversionException.class, () -> converter.convert(getExpectedType(), "0,02x"), "Expected invalid value to cause ConversionException");
// Locale.GERMAN
converter.setLocale(Locale.GERMAN);
assertEquals(numbers[2], converter.convert(getExpectedType(), "-0.022"), () -> "Locale.GERMAN " + numbers[2]);
assertEquals(numbers[3], converter.convert(getExpectedType(), "0.023"), () -> "Locale.GERMAN " + numbers[3]);
// Invalid Value
assertThrows(ConversionException.class, () -> converter.convert(getExpectedType(), "0.02x"), "Expected invalid value to cause ConversionException");
// Restore the default Locale
Locale.setDefault(defaultLocale);
}
/**
* Convert String --> Number (using a Pattern, with default and specified Locales)
*/
@Test
void testStringToNumberPattern() {
// Re-set the default Locale to Locale.US
final Locale defaultLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
final NumberConverter<T> converter = makeConverter();
converter.setPattern("[0,0];(0,0)");
// Default Locale
assertEquals(numbers[0], converter.convert(getExpectedType(), "(1,2)"), () -> "Default Locale " + numbers[0]);
assertEquals(numbers[1], converter.convert(getExpectedType(), "[1,3]"), () -> "Default Locale " + numbers[1]);
// Locale.GERMAN
converter.setLocale(Locale.GERMAN);
assertEquals(numbers[2], converter.convert(getExpectedType(), "(2.2)"), () -> "Locale.GERMAN " + numbers[2]);
assertEquals(numbers[3], converter.convert(getExpectedType(), "[2.3]"), () -> "Locale.GERMAN " + numbers[3]);
// Invalid Value
assertThrows(ConversionException.class, () -> converter.convert(getExpectedType(), "1,2"), "Expected invalid value to cause ConversionException");
// Invalid Type (will try via String)
final Object obj = new Object() {
@Override
public String toString() {
return "dsdgsdsdg";
}
};
assertThrows(ConversionException.class, () -> converter.convert(getExpectedType(), obj), "Expected invalid value to cause ConversionException");
// Restore the default Locale
Locale.setDefault(defaultLocale);
}
@Test
void testToString() {
assertNotNull(makeConverter().toString());
}
}