package fitnesse.slim.converters;
import java.lang.reflect.ParameterizedType;
import java.util.*;
import java.util.regex.Pattern;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import fitnesse.slim.Converter;
import fitnesse.slim.test.AnEnum;
import fitnesse.slim.test.AnotherEnum;
import static org.junit.Assert.*;
public class ConverterRegistryTest {
@Before
public void setUp() {
ConverterRegistry.resetToStandardConverters();
}
@AfterClass
public static void finalCleanUp() {
ConverterRegistry.resetToStandardConverters();
}
@Test
public void getConverters_should_return_several_default_converter() {
Map<Class<?>, Converter<?>> current = ConverterRegistry.getConverters();
assertTrue(current.size() > 0);
assertNotNull(current.get(Integer.class));
assertNotNull(current.get(Double.class));
assertNotNull(current.get(Date.class));
}
@Test
public void getConverterForClass_should_return_a_custom_converter_when_a_custom_converter_has_been_set() {
ConverterRegistry.addConverter(StringBuilder.class, new StringBuilderConverter());
Converter<StringBuilder> converter = ConverterRegistry.getConverterForClass(StringBuilder.class);
String current = converter.toString(new StringBuilder());
assertTrue(StringBuilderConverter.class.isInstance(converter));
assertEquals("customConverter", current);
}
@Test
public void getConverterForClass_should_return_a_property_editor_converter_when_editor_exists() throws Exception {
Class<AnotherEnum> value = AnotherEnum.class;
Converter<AnotherEnum> actual = ConverterRegistry.getConverterForClass(value);
assertTrue(PropertyEditorConverter.class.isInstance(actual));
assertConverts("enum property editor called with \"some value\"", actual, "some value");
}
private <T> void assertConverts(String expected, Converter<T> converter, String value) {
assertEquals(expected, converter.toString(converter.fromString(value)));
}
@Test
public void getConverterForClass_should_return_a_enum_converter_when_value_is_an_enum() {
Class<AnEnum> value = AnEnum.class;
Converter<AnEnum> actual = ConverterRegistry.getConverterForClass(value);
assertTrue(GenericEnumConverter.class.isInstance(actual));
}
@Test
public void getConverterForClass_should_return_an_array_converter_when_value_is_an_array_of_primitive() {
Class<int[]> value = int[].class;
Converter<int[]> current = ConverterRegistry.getConverterForClass(value);
int[] value2 = current.fromString("[1]");
assertTrue(current instanceof GenericArrayConverter);
assertEquals(1, value2[0]);
}
@Test
public void getConverterForClass_should_return_an_array_converter_when_value_is_an_array() {
Class<Integer[]> clazz = Integer[].class;
Converter<Integer[]> current = ConverterRegistry.getConverterForClass(clazz);
Integer[] value2 = current.fromString("[1]");
assertTrue(current instanceof GenericArrayConverter);
assertEquals(Integer.valueOf(1), value2[0]);
}
@Test
public void getConverterForClass_should_return_a_MapConverter_when_type_is_typed_map() throws SecurityException, NoSuchMethodException {
Class<?> typedClass = MyFixture.class.getMethod("getMap").getReturnType();
Converter<?> converter = ConverterRegistry.getConverterForClass(typedClass);
assertNotNull("no converter retunred", converter);
assertEquals(MapConverter.class, converter.getClass());
}
@Test
public void getConverterForClass_should_return_a_MapConverter_when_type_implements_map() throws SecurityException, NoSuchMethodException {
Class<?> typedClass = MyFixture.class.getMethod("getLinkedMap").getReturnType();
Converter<?> converter = ConverterRegistry.getConverterForClass(typedClass);
assertNotNull("no converter retunred", converter);
assertEquals(MapConverter.class, converter.getClass());
}
@Test
public void getConverterForClass_should_return_a_MapConverter_when_type_implements_map_indirectly() throws SecurityException, NoSuchMethodException {
Class<?> typedClass = MyFixture.class.getMethod("getTreeMap").getReturnType();
Converter<?> converter = ConverterRegistry.getConverterForClass(typedClass);
assertNotNull("no converter retunred", converter);
assertEquals(MapConverter.class, converter.getClass());
}
@Test
public void getConverterForClass_should_return_Converter_when_type_superclass_registered() throws SecurityException, NoSuchMethodException {
ConverterRegistry.addConverter(MyFixture.class, new MyFixtureConverter());
Converter<?> converter = ConverterRegistry.getConverterForClass(MySubFixture.class);
assertNotNull("no converter retunred", converter);
assertEquals(MyFixtureConverter.class, converter.getClass());
}
@Test
public void getConverterForClass_should_return_Object_Converter_as_last_resort() throws SecurityException, NoSuchMethodException {
Converter<Object> oldObjectConverter = ConverterRegistry.getConverterForClass(Object.class);
try {
ConverterRegistry.addConverter(Object.class, new MyObjectConverter());
Converter<?> converter = ConverterRegistry.getConverterForClass(ConverterRegistryTest.class);
assertNotNull("no converter retunred", converter);
assertEquals(MyObjectConverter.class, converter.getClass());
} finally {
// cleanup
ConverterRegistry.addConverter(Object.class, oldObjectConverter);
}
}
private static class MyFixture {
public Map<String, Object> getMap() {
return null;
}
public LinkedHashMap<String, Object> getLinkedMap() {
return null;
}
public TreeMap<String, Object> getTreeMap() {
return null;
}
}
private static class MyFixtureConverter implements Converter<MyFixture> {
@Override
public String toString(MyFixture o) {
return null;
}
@Override
public MyFixture fromString(String arg) {
return null;
}
}
private static class MyObjectConverter implements Converter<Object> {
@Override
public String toString(Object o) {
return null;
}
@Override
public Object fromString(String arg) {
return null;
}
}
private static class MySubFixture extends MyFixture {
}
@Test
@SuppressWarnings("rawtypes")
public void getConverterForClass_should_return_a_collection_of_string_when_value_is_a_list() {
Class<List> clazz = List.class;
Converter<List> converter = ConverterRegistry.getConverterForClass(clazz);
Object current = converter.fromString("[1]").get(0);
assertTrue(converter instanceof GenericCollectionConverter);
assertTrue(current instanceof String);
assertEquals("1", current);
}
@Test
@SuppressWarnings("rawtypes")
public void getConverterForClass_should_return_a_collection_of_typed_object_with_converter_when_value_is_a_typed_list() throws SecurityException, NoSuchMethodException {
Class<List> clazz = List.class;
ParameterizedType typedClass = (ParameterizedType) new ArrayList<Integer>() {} .getClass().getGenericSuperclass();
Converter<List> converter = ConverterRegistry.getConverterForClass(clazz, typedClass);
Object current = converter.fromString("[1]").get(0);
assertTrue(converter instanceof GenericCollectionConverter);
assertTrue(current instanceof Integer);
assertEquals(Integer.valueOf(1), current);
}
@Test
@SuppressWarnings("rawtypes")
public void getConverterForClass_should_return_a_collection_of_typed_object_without_converter_when_value_is_a_typed_list() throws SecurityException, NoSuchMethodException {
Class<List> clazz = List.class;
ParameterizedType typedClass = (ParameterizedType) new ArrayList<Object>() {} .getClass().getGenericSuperclass();
Converter<List> converter = ConverterRegistry.getConverterForClass(clazz, typedClass);
Object current = converter.fromString("[1]").get(0);
assertTrue(converter instanceof GenericCollectionConverter);
assertTrue(current instanceof String);
assertEquals("1", current);
List<Object> listToConvert = new ArrayList<>();
listToConvert.add(this);
listToConvert.add(new StringBuilderConverter());
listToConvert.add(null);
String converted = converter.toString(listToConvert);
Pattern p = Pattern.compile("\\[(.*?),\\s*(.*?),\\s*null\\]");
assertTrue(p.matcher(converted).matches());
}
/*
* PRIVATE
*/
private static class StringBuilderConverter implements Converter<StringBuilder> {
@Override
public String toString(StringBuilder o) {
return "customConverter";
}
@Override
public StringBuilder fromString(String arg) {
throw new IllegalStateException();
}
}
}