package org.jbehave.core.steps;
import java.beans.IntrospectionException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import org.jbehave.core.model.ExamplesTable;
import org.jbehave.core.steps.ParameterConverters.BooleanConverter;
import org.jbehave.core.steps.ParameterConverters.BooleanListConverter;
import org.jbehave.core.steps.ParameterConverters.DateConverter;
import org.jbehave.core.steps.ParameterConverters.EnumConverter;
import org.jbehave.core.steps.ParameterConverters.EnumListConverter;
import org.jbehave.core.steps.ParameterConverters.ExamplesTableConverter;
import org.jbehave.core.steps.ParameterConverters.ExamplesTableParametersConverter;
import org.jbehave.core.steps.ParameterConverters.MethodReturningConverter;
import org.jbehave.core.steps.ParameterConverters.NumberConverter;
import org.jbehave.core.steps.ParameterConverters.NumberListConverter;
import org.jbehave.core.steps.ParameterConverters.ParameterConverter;
import org.jbehave.core.steps.ParameterConverters.ParameterConvertionFailed;
import org.jbehave.core.steps.ParameterConverters.StringListConverter;
import org.jbehave.core.steps.SomeSteps.MyParameters;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
public class ParameterConvertersBehaviour {
private static String NAN = new DecimalFormatSymbols().getNaN();
private static String INFINITY = new DecimalFormatSymbols().getInfinity();
@SuppressWarnings("unchecked")
@Test
public void shouldDefineDefaultConverters() {
ParameterConverters converters = new ParameterConverters();
ParameterConverter[] defaultConverters = converters.defaultConverters(Locale.ENGLISH, ",");
assertThatDefaultConvertersInclude(defaultConverters, BooleanConverter.class, NumberConverter.class,
NumberListConverter.class, StringListConverter.class, DateConverter.class, EnumConverter.class,
EnumListConverter.class, ExamplesTableConverter.class, ExamplesTableParametersConverter.class);
}
private void assertThatDefaultConvertersInclude(ParameterConverter[] defaultConverters,
Class<? extends ParameterConverter>... converterTypes) {
for (Class<? extends ParameterConverter> type : converterTypes) {
boolean found = false;
for (ParameterConverter converter : defaultConverters) {
if (converter.getClass().isAssignableFrom(type)) {
found = true;
}
}
if (!found) {
throw new RuntimeException("Converter " + type + " should be in the list of default converters");
}
}
}
@Test
public void shouldConvertValuesToNumbersWithDefaultNumberFormat() {
NumberConverter converter = new NumberConverter();
assertThatAllNumberTypesAreAccepted(converter);
assertThatAllNumbersAreConverted(converter, ParameterConverters.DEFAULT_NUMBER_FORMAT_LOCAL);
}
@Test
public void shouldConvertValuesToNumbersWithEnglishNumberFormat() {
Locale locale = Locale.ENGLISH;
ParameterConverter converter = new NumberConverter(NumberFormat.getInstance(locale));
assertConverterForLocale(converter, locale);
}
private void assertConverterForLocale(ParameterConverter converter, Locale locale) {
assertThatAllNumberTypesAreAccepted(converter);
assertThatAllNumbersAreConverted(converter, locale);
assertThat((Integer) converter.convertValue("100,000", Integer.class), equalTo(100000));
assertThat((Long) converter.convertValue("100,000", Long.class), equalTo(100000L));
assertThat((Float) converter.convertValue("100,000.01", Float.class), equalTo(100000.01f));
assertThat((Double) converter.convertValue("100,000.01", Double.class), equalTo(100000.01d));
assertThat((Double) converter.convertValue("1,00,000.01", Double.class), equalTo(100000.01d)); //Hindi style
}
@Test
public void shouldConvertValuesToNumbersWithEnglishNumberFormatInMultipleThreads() {
final Locale locale = Locale.ENGLISH;
final int threads = 3;
final ParameterConverter converter = new NumberConverter(NumberFormat.getInstance(locale));
final BlockingQueue<String> queue = new ArrayBlockingQueue<String>(threads);
Thread t1 = new Thread(){
@Override
public void run(){
assertConverterForLocale(converter, locale);
queue.add(Thread.currentThread().getName());
}
};
Thread t2 = new Thread(){
@Override
public void run(){
assertConverterForLocale(converter, locale);
queue.add(Thread.currentThread().getName());
}
};
Thread t3 = new Thread(){
@Override
public void run(){
assertConverterForLocale(converter, locale);
queue.add(Thread.currentThread().getName());
}
};
t1.start();
t2.start();
t3.start();
for (int i = 0;i < threads;i++){
try {
System.out.println(queue.take() + " completed.");
} catch (InterruptedException e) {
fail(e.getMessage());
}
}
}
@Test
public void shouldConvertValuesToNumbersWithFrenchNumberFormat() {
Locale locale = Locale.FRENCH;
ParameterConverter converter = new NumberConverter(NumberFormat.getInstance(locale));
assertThatAllNumberTypesAreAccepted(converter);
assertThatAllNumbersAreConverted(converter, locale);
assertThat((Float) converter.convertValue("100000,01", Float.class), equalTo(100000.01f));
assertThat((Double) converter.convertValue("100000,01", Double.class), equalTo(100000.01d));
}
@Test
public void shouldConvertValuesToNumbersWithGermanNumberFormat() {
Locale locale = Locale.GERMAN;
ParameterConverter converter = new NumberConverter(NumberFormat.getInstance(locale));
assertThatAllNumberTypesAreAccepted(converter);
assertThatAllNumbersAreConverted(converter, locale);
assertThat((BigDecimal) converter.convertValue("1.000.000,01", BigDecimal.class), equalTo(new BigDecimal("1000000.01")));
}
private void assertThatAllNumberTypesAreAccepted(ParameterConverter converter) {
assertThat(converter.accept(Byte.class), equalTo(true));
assertThat(converter.accept(byte.class), equalTo(true));
assertThat(converter.accept(Short.class), equalTo(true));
assertThat(converter.accept(short.class), equalTo(true));
assertThat(converter.accept(Integer.class), equalTo(true));
assertThat(converter.accept(int.class), equalTo(true));
assertThat(converter.accept(Float.class), equalTo(true));
assertThat(converter.accept(float.class), equalTo(true));
assertThat(converter.accept(Long.class), equalTo(true));
assertThat(converter.accept(long.class), equalTo(true));
assertThat(converter.accept(Double.class), equalTo(true));
assertThat(converter.accept(double.class), equalTo(true));
assertThat(converter.accept(BigInteger.class), equalTo(true));
assertThat(converter.accept(BigDecimal.class), equalTo(true));
assertThat(converter.accept(AtomicInteger.class), equalTo(true));
assertThat(converter.accept(AtomicLong.class), equalTo(true));
assertThat(converter.accept(Number.class), equalTo(true));
assertThat(converter.accept(WrongType.class), equalTo(false));
}
private void assertThatAllNumbersAreConverted(ParameterConverter converter, Locale locale) {
DecimalFormatSymbols format = new DecimalFormatSymbols(locale);
char dot = format.getDecimalSeparator();
char minus = format.getMinusSign();
assertThat((Byte) converter.convertValue("127", Byte.class), equalTo(Byte.MAX_VALUE));
assertThat((Byte) converter.convertValue(minus + "128", byte.class), equalTo(Byte.MIN_VALUE));
assertThat((Short) converter.convertValue("32767", Short.class), equalTo(Short.MAX_VALUE));
assertThat((Short) converter.convertValue(minus + "32768", short.class), equalTo(Short.MIN_VALUE));
assertThat((Integer) converter.convertValue("3", Integer.class), equalTo(3));
assertThat((Integer) converter.convertValue("3", int.class), equalTo(3));
assertThat((Float) converter.convertValue("3" + dot + "0", Float.class), equalTo(3.0f));
assertThat((Float) converter.convertValue("3" + dot + "0", float.class), equalTo(3.0f));
assertThat((Long) converter.convertValue("3", Long.class), equalTo(3L));
assertThat((Long) converter.convertValue("3", long.class), equalTo(3L));
assertThat((Double) converter.convertValue("3" + dot + "0", Double.class), equalTo(3.0d));
assertThat((Double) converter.convertValue("3" + dot + "0", double.class), equalTo(3.0d));
assertThat((BigInteger) converter.convertValue("3", BigInteger.class), equalTo(new BigInteger("3")));
assertThat((BigDecimal) converter.convertValue("3" + dot + "0", BigDecimal.class), equalTo(new BigDecimal("3.0")));
assertThat((BigDecimal) converter.convertValue("3" + dot + "00", BigDecimal.class), equalTo(new BigDecimal("3.00"))); // currency
assertThat((BigDecimal) converter.convertValue("30000000", BigDecimal.class), equalTo(new BigDecimal(30000000))); // 7 or more digits
assertThat((BigDecimal) converter.convertValue("3" + dot + "000", BigDecimal.class), equalTo(new BigDecimal("3.000"))); // something else!
assertThat(((AtomicInteger)converter.convertValue("3", AtomicInteger.class)).get(), equalTo(3));
assertThat(((AtomicLong)converter.convertValue("3", AtomicLong.class)).get(), equalTo(3L));
assertThat((Number) converter.convertValue("3", Number.class), equalTo((Number)3L));
}
@Test
public void shouldFailToConvertInvalidNumbersWithNumberFormat() {
NumberConverter converter = new NumberConverter();
try {
converter.convertValue("abc", Long.class);
} catch (ParameterConvertionFailed e) {
assertThat(e.getCause(), is(instanceOf(ParseException.class)));
}
}
@Test
public void shouldFailToConvertInvalidNumbersWithNumberFormat2() {
NumberConverter converter = new NumberConverter();
try {
converter.convertValue("12.34.56", BigDecimal.class);
} catch (ParameterConvertionFailed e) {
assertThat(e.getCause(), is(instanceOf(NumberFormatException.class)));
}
}
@Test
public void shouldConvertNaNAndInfinityValuesToNumbers() {
ParameterConverter converter = new NumberConverter();
assertThat((Float) converter.convertValue(NAN, Float.class), equalTo(Float.NaN));
assertThat((Float) converter.convertValue(INFINITY, Float.class), equalTo(Float.POSITIVE_INFINITY));
assertThat((Float) converter.convertValue("-"+INFINITY, Float.class), equalTo(Float.NEGATIVE_INFINITY));
assertThat((Double) converter.convertValue(NAN, Double.class), equalTo(Double.NaN));
assertThat((Double) converter.convertValue(INFINITY, Double.class), equalTo(Double.POSITIVE_INFINITY));
assertThat((Double) converter.convertValue("-"+INFINITY, Double.class), equalTo(Double.NEGATIVE_INFINITY));
}
@SuppressWarnings("unchecked")
@Test
public void shouldConvertCommaSeparatedValuesToListOfNumbersWithDefaultFormat() throws ParseException, IntrospectionException {
ParameterConverter converter = new NumberListConverter();
Type listOfNumbers = SomeSteps.methodFor("aMethodWithListOfNumbers").getGenericParameterTypes()[0];
Type setOfNumbers = SomeSteps.methodFor("aMethodWithSetOfNumbers").getGenericParameterTypes()[0];
assertThat(converter.accept(listOfNumbers), is(true));
assertThat(converter.accept(setOfNumbers), is(false));
List<Number> list = (List<Number>) converter.convertValue("3, 0.5, 6.1f, 8.00", listOfNumbers);
NumberFormat numberFormat = NumberFormat.getInstance(ParameterConverters.DEFAULT_NUMBER_FORMAT_LOCAL);
assertThat(list.get(0), equalTo(numberFormat.parse("3")));
assertThat(list.get(1), equalTo(numberFormat.parse("0.5")));
assertThat(list.get(2), equalTo(numberFormat.parse("6.1f")));
assertThat(list.get(3), equalTo(numberFormat.parse("8.00")));
}
@SuppressWarnings("unchecked")
@Test
public void shouldConvertCommaSeparatedValuesToListOfNumbersWithCustomFormat() throws ParseException,
IntrospectionException {
NumberFormat numberFormat = new DecimalFormat("#,####");
ParameterConverter converter = new NumberListConverter(numberFormat, " ");
Type type = SomeSteps.methodFor("aMethodWithListOfNumbers").getGenericParameterTypes()[0];
List<Number> list = (List<Number>) converter.convertValue("3,000 0.5 6.1f 8.00", type);
assertThat(list.get(0), equalTo(numberFormat.parse("3,000")));
assertThat(list.get(1), equalTo(numberFormat.parse("0.5")));
assertThat(list.get(2), equalTo(numberFormat.parse("6.1f")));
assertThat(list.get(3), equalTo(numberFormat.parse("8.00")));
}
@SuppressWarnings("unchecked")
@Test
public void shouldConvertCommaSeparatedValuesOfSpecificNumberTypes() throws ParseException, IntrospectionException {
ParameterConverter converter = new NumberListConverter(NumberFormat.getInstance(Locale.ENGLISH), ",");
Type doublesType = SomeSteps.methodFor("aMethodWithListOfDoubles").getGenericParameterTypes()[0];
List<Double> doubles = (List<Double>) converter.convertValue("3, 0.5, 0.0, 8.00, "+NAN+","+INFINITY, doublesType);
assertThat(doubles.get(0), equalTo(3.0d));
assertThat(doubles.get(1), equalTo(0.5d));
assertThat(doubles.get(2), equalTo(0.0d));
assertThat(doubles.get(3), equalTo(8.00d));
assertThat(doubles.get(4), equalTo(Double.NaN));
assertThat(doubles.get(5), equalTo(Double.POSITIVE_INFINITY));
Type floatsType = SomeSteps.methodFor("aMethodWithListOfFloats").getGenericParameterTypes()[0];
List<Float> floats = (List<Float>) converter.convertValue("3, 0.5, 0.0, 8.00, "+NAN+", -"+INFINITY, floatsType);
assertThat(floats.get(0), equalTo(3.0f));
assertThat(floats.get(1), equalTo(0.5f));
assertThat(floats.get(2), equalTo(0.0f));
assertThat(floats.get(3), equalTo(8.00f));
assertThat(floats.get(4), equalTo(Float.NaN));
assertThat(floats.get(5), equalTo(Float.NEGATIVE_INFINITY));
Type longsType = SomeSteps.methodFor("aMethodWithListOfLongs").getGenericParameterTypes()[0];
List<Long> longs = (List<Long>) converter.convertValue("3, 0, 8", longsType);
assertThat(longs.get(0), equalTo(3L));
assertThat(longs.get(1), equalTo(0L));
assertThat(longs.get(2), equalTo(8L));
Type intsType = SomeSteps.methodFor("aMethodWithListOfIntegers").getGenericParameterTypes()[0];
List<Integer> ints = (List<Integer>) converter.convertValue("3, 0, 8", intsType);
assertThat(ints.get(0), equalTo(3));
assertThat(ints.get(1), equalTo(0));
assertThat(ints.get(2), equalTo(8));
}
@Test(expected = ParameterConvertionFailed.class)
public void shouldFailToConvertCommaSeparatedValuesOfInvalidNumbers() throws ParseException, IntrospectionException {
ParameterConverter converter = new NumberListConverter();
Type type = SomeSteps.methodFor("aMethodWithListOfNumbers").getGenericParameterTypes()[0];
converter.convertValue("3x, x.5", type);
}
@Test
public void shouldConvertCommaSeparatedValuesToListOfStrings() throws IntrospectionException {
ParameterConverter converter = new StringListConverter();
Type listOfStrings = SomeSteps.methodFor("aMethodWithListOfStrings").getGenericParameterTypes()[0];
Type listOfNumbers = SomeSteps.methodFor("aMethodWithListOfNumbers").getGenericParameterTypes()[0];
Type setOfNumbers = SomeSteps.methodFor("aMethodWithSetOfNumbers").getGenericParameterTypes()[0];
assertThat(converter.accept(listOfStrings), is(true));
assertThat(converter.accept(listOfNumbers), is(false));
assertThat(converter.accept(setOfNumbers), is(false));
ensureValueIsConvertedToList(converter, listOfStrings, "a, string ", Arrays.asList("a", "string"));
ensureValueIsConvertedToList(converter, listOfStrings, " ", Arrays.asList(new String[] {}));
}
@SuppressWarnings("unchecked")
private void ensureValueIsConvertedToList(ParameterConverter converter, Type type, String value,
List<String> expected) {
List<String> list = (List<String>) converter.convertValue(value, type);
assertThat(list.size(), equalTo(expected.size()));
}
@Test
public void shouldConvertDateWithDefaultFormat() throws ParseException, IntrospectionException {
ParameterConverter converter = new DateConverter();
assertThat(converter.accept(Date.class), equalTo(true));
assertThat(converter.accept(WrongType.class), is(false));
assertThat(converter.accept(mock(Type.class)), is(false));
Type type = SomeSteps.methodFor("aMethodWithDate").getGenericParameterTypes()[0];
String date = "01/01/2010";
assertThat((Date) converter.convertValue(date, type), equalTo(DateConverter.DEFAULT_FORMAT.parse(date)));
}
@Test
public void shouldConvertDateWithCustomFormat() throws ParseException, IntrospectionException {
DateFormat customFormat = new SimpleDateFormat("yyyy-MM-dd");
ParameterConverter converter = new DateConverter(customFormat);
assertThat(converter.accept(Date.class), equalTo(true));
assertThat(converter.accept(WrongType.class), is(false));
assertThat(converter.accept(mock(Type.class)), is(false));
Type type = SomeSteps.methodFor("aMethodWithDate").getGenericParameterTypes()[0];
String date = "2010-01-01";
assertThat((Date) converter.convertValue(date, type), equalTo(customFormat.parse(date)));
}
@Test(expected = ParameterConvertionFailed.class)
public void shouldFailToConvertDateWithInvalidFormat() throws ParseException, IntrospectionException {
Type type = SomeSteps.methodFor("aMethodWithDate").getGenericParameterTypes()[0];
ParameterConverter converter = new DateConverter();
String date = "dd+MM+yyyy";
converter.convertValue(date, type);
}
@Test
public void shouldConvertMultilineTable() throws ParseException, IntrospectionException {
ParameterConverter converter = new ExamplesTableConverter();
assertThat(converter.accept(ExamplesTable.class), is(true));
assertThat(converter.accept(WrongType.class), is(false));
assertThat(converter.accept(mock(Type.class)), is(false));
Type type = SomeSteps.methodFor("aMethodWithExamplesTable").getGenericParameterTypes()[0];
String value = "|col1|col2|\n|row11|row12|\n|row21|row22|\n";
ExamplesTable table = (ExamplesTable) converter.convertValue(value, type);
assertThat(table.getRowCount(), equalTo(2));
Map<String, String> row1 = table.getRow(0);
assertThat(row1.get("col1"), equalTo("row11"));
assertThat(row1.get("col2"), equalTo("row12"));
Map<String, String> row2 = table.getRow(1);
assertThat(row2.get("col1"), equalTo("row21"));
assertThat(row2.get("col2"), equalTo("row22"));
}
@Test
public void shouldConvertMultilineTableToParameters() throws ParseException, IntrospectionException {
ParameterConverter converter = new ExamplesTableParametersConverter();
Type type = SomeSteps.methodFor("aMethodWithExamplesTableParameters").getGenericParameterTypes()[0];
assertThat(converter.accept(type), is(true));
assertThat(converter.accept(WrongType.class), is(false));
assertThat(converter.accept(mock(Type.class)), is(false));
String value = "|col1|col2|\n|row11|row12|\n|row21|row22|\n";
@SuppressWarnings("unchecked")
List<MyParameters> parameters = (List<MyParameters>) converter.convertValue(value, type);
assertThat(parameters.size(), equalTo(2));
MyParameters row1 = parameters.get(0);
assertThat(row1.col1, equalTo("row11"));
assertThat(row1.col2, equalTo("row12"));
MyParameters row2 = parameters.get(1);
assertThat(row2.col1, equalTo("row21"));
assertThat(row2.col2, equalTo("row22"));
}
@Test
public void shouldConvertSinglelineTableToParameters() throws ParseException, IntrospectionException {
ParameterConverter converter = new ExamplesTableParametersConverter();
Type type = SomeSteps.methodFor("aMethodWithExamplesTableParameter").getGenericParameterTypes()[0];
assertThat(converter.accept(type), is(true));
assertThat(converter.accept(WrongType.class), is(false));
assertThat(converter.accept(mock(Type.class)), is(false));
String value = "|col1|col2|\n|row11|row12|\n";
MyParameters parameters = (MyParameters) converter.convertValue(value, type);
assertThat(parameters.col1, equalTo("row11"));
assertThat(parameters.col2, equalTo("row12"));
}
@Test
public void shouldConvertParameterFromMethodReturningValue() throws ParseException, IntrospectionException {
Method method = SomeSteps.methodFor("aMethodReturningExamplesTable");
ParameterConverter converter = new MethodReturningConverter(method, new SomeSteps());
assertThat(converter.accept(method.getReturnType()), is(true));
assertThat(converter.accept(WrongType.class), is(false));
assertThat(converter.accept(mock(Type.class)), is(false));
String value = "|col1|col2|\n|row11|row12|\n|row21|row22|\n";
ExamplesTable table = (ExamplesTable) converter.convertValue(value, ExamplesTable.class);
assertThat(table.getRowCount(), equalTo(2));
Map<String, String> row1 = table.getRow(0);
assertThat(row1.get("col1"), equalTo("row11"));
assertThat(row1.get("col2"), equalTo("row12"));
Map<String, String> row2 = table.getRow(1);
assertThat(row2.get("col1"), equalTo("row21"));
assertThat(row2.get("col2"), equalTo("row22"));
}
@Test(expected = ParameterConvertionFailed.class)
public void shouldFailToConvertParameterFromFailingMethodReturningValue() throws ParseException,
IntrospectionException {
Method method = SomeSteps.methodFor("aFailingMethodReturningExamplesTable");
ParameterConverter converter = new MethodReturningConverter(method, new SomeSteps());
String value = "|col1|col2|\n|row11|row12|\n|row21|row22|\n";
converter.convertValue(value, ExamplesTable.class);
}
@Test(expected = ParameterConvertionFailed.class)
public void shouldFailToConvertToUnknownType() throws ParseException, IntrospectionException {
new ParameterConverters().convert("abc", WrongType.class);
}
static class WrongType {
}
@Test
public void shouldConvertEnum() throws IntrospectionException {
ParameterConverter converter = new EnumConverter();
assertThat(converter.accept(SomeEnum.class), equalTo(true));
assertThat(converter.accept(WrongType.class), is(false));
assertThat(converter.accept(mock(Type.class)), is(false));
Type type = SomeSteps.methodFor("aMethodWithEnum").getGenericParameterTypes()[0];
assertThat((SomeEnum) converter.convertValue("ONE", type), equalTo(SomeEnum.ONE));
}
@Test(expected = ParameterConvertionFailed.class)
public void shouldFailToConvertEnumForValueNotDefined() throws IntrospectionException {
ParameterConverter converter = new EnumConverter();
Type type = SomeSteps.methodFor("aMethodWithEnum").getGenericParameterTypes()[0];
converter.convertValue("FOUR", type);
}
@SuppressWarnings("unchecked")
@Test
public void shouldConvertEnumList() throws IntrospectionException {
ParameterConverter converter = new EnumListConverter();
Type type = SomeSteps.methodFor("aMethodWithEnumList").getGenericParameterTypes()[0];
assertThat(converter.accept(type), equalTo(true));
List<SomeEnum> list = (List<SomeEnum>)converter.convertValue("ONE,TWO,THREE", type);
assertThat(list.get(0), equalTo(SomeEnum.ONE));
assertThat(list.get(1), equalTo(SomeEnum.TWO));
assertThat(list.get(2), equalTo(SomeEnum.THREE));
}
@Test
public void shouldConvertBoolean() throws IntrospectionException {
ParameterConverter converter = new BooleanConverter();
assertThat(converter.accept(Boolean.TYPE), equalTo(true));
assertThat(converter.accept(Boolean.class), equalTo(true));
assertThat(converter.accept(WrongType.class), is(false));
assertThat(converter.accept(mock(Type.class)), is(false));
Type type = SomeSteps.methodFor("aMethodWithBoolean").getGenericParameterTypes()[0];
assertThat((Boolean) converter.convertValue("true", type), is(true));
assertThat((Boolean) converter.convertValue("false", type), is(false));
assertThat((Boolean) converter.convertValue("whatever", type), is(false));
}
@Test
public void shouldConvertBooleanWithCustomValues() throws IntrospectionException {
ParameterConverter converter = new BooleanConverter("ON", "OFF");
assertThat(converter.accept(Boolean.TYPE), equalTo(true));
assertThat(converter.accept(Boolean.class), equalTo(true));
assertThat(converter.accept(WrongType.class), is(false));
assertThat(converter.accept(mock(Type.class)), is(false));
Type type = SomeSteps.methodFor("aMethodWithBoolean").getGenericParameterTypes()[0];
assertThat((Boolean) converter.convertValue("ON", type), is(true));
assertThat((Boolean) converter.convertValue("OFF", type), is(false));
assertThat((Boolean) converter.convertValue("whatever", type), is(false));
}
@SuppressWarnings("unchecked")
@Test
public void shouldConvertBooleanList() throws IntrospectionException {
ParameterConverter converter = new BooleanListConverter();
Type type = SomeSteps.methodFor("aMethodWithBooleanList").getGenericParameterTypes()[0];
assertThat(converter.accept(type), equalTo(true));
List<Boolean> list = (List<Boolean>) converter.convertValue("true,false,true", type);
assertThat(list.get(0), is(true));
assertThat(list.get(1), is(false));
assertThat(list.get(2), is(true));
}
@Test(expected = ParameterConvertionFailed.class)
public void shouldNotModifyListOfConvertersFromOriginalParameterConvertersWhenCreatingNewInstance() throws Exception {
ParameterConverters original = new ParameterConverters();
original.newInstanceAdding(new FooToBarParameterConverter());
ensureItStillDoesNotKnowHowToConvertFooToBar(original);
}
private void ensureItStillDoesNotKnowHowToConvertFooToBar(ParameterConverters original) {
original.convert("foo", Bar.class);
}
private class Bar {
}
private class FooToBarParameterConverter implements ParameterConverter {
public boolean accept(Type type) {
return type == Bar.class;
}
public Object convertValue(String value, Type type) {
return new Bar();
}
}
}