package org.simpleflatmapper.reflect.test.meta;
import org.junit.Test;
import org.simpleflatmapper.reflect.ConstructorNotFoundException;
import org.simpleflatmapper.reflect.InstantiatorDefinition;
import org.simpleflatmapper.reflect.ReflectionService;
import org.simpleflatmapper.reflect.meta.*;
import org.simpleflatmapper.test.beans.Foo;
import org.simpleflatmapper.test.junit.LibrarySetsClassLoader;
import org.simpleflatmapper.util.Consumer;
import org.simpleflatmapper.util.Predicate;
import org.simpleflatmapper.util.TypeReference;
import org.simpleflatmapper.tuple.Tuple2;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.*;
public class TupleClassMetaTest {
private Predicate<PropertyMeta<?, ?>> isValidPropertyMeta = new Predicate<PropertyMeta<?, ?>>() {
@Override
public boolean test(PropertyMeta<?, ?> propertyMeta) {
return true;
}
};
@Test
public void failOnNoConstructorMatchingType() {
Type type = new TypeReference<MyTuple<String, String>>() {}.getType();
try {
new TupleClassMeta<MyTuple<String, String>>(type, ReflectionService.newInstance());
fail();
} catch (ConstructorNotFoundException e) {
// expect
}
}
@SuppressWarnings("unused")
static class MyTuple<T1, T2> {
}
@Test
public void testFindPropertyNoAsm() {
Type type = new TypeReference<Tuple2<String, String>>() {}.getType();
ClassMeta<Tuple2<String, String>> classMeta = ReflectionService.disableAsm().getClassMeta(type);
InstantiatorDefinition instantiatorDefinition = classMeta.getInstantiatorDefinitions().get(0);
assertEquals("element0", instantiatorDefinition.getParameters()[0].getName());
assertEquals("element1", instantiatorDefinition.getParameters()[1].getName());
assertEquals(2, instantiatorDefinition.getParameters().length);
}
ClassMeta<Tuple2<Foo, Foo>> classMeta = ReflectionService.newInstance().getClassMeta(new TypeReference<Tuple2<Foo, Foo>>() {}.getType());
@Test
public void testIndexStartingAtZero() {
final PropertyFinder<Tuple2<Foo, Foo>> propertyFinder = classMeta.newPropertyFinder(isValidPropertyMeta);
final PropertyMeta<Tuple2<Foo, Foo>, ?> t0_foo = propertyFinder.findProperty(newMatcher("t0_foo"));
final PropertyMeta<Tuple2<Foo, Foo>, ?> t0_bar = propertyFinder.findProperty(newMatcher("t0_bar"));
final PropertyMeta<Tuple2<Foo, Foo>, ?> t1_foo = propertyFinder.findProperty(newMatcher("t1_foo"));
final PropertyMeta<Tuple2<Foo, Foo>, ?> t1_bar = propertyFinder.findProperty(newMatcher("t1_bar"));
validate(t0_foo, t0_bar, t1_foo, t1_bar);
}
private void validate(PropertyMeta<Tuple2<Foo, Foo>, ?> t0_foo,
PropertyMeta<Tuple2<Foo, Foo>, ?> t0_bar,
PropertyMeta<Tuple2<Foo, Foo>, ?> t1_foo,
PropertyMeta<Tuple2<Foo, Foo>, ?> t1_bar) {
assertNotNull(t0_foo);
assertIs("element0", "foo", t0_foo);
assertNotNull(t0_bar);
assertIs("element0", "bar", t0_bar);
assertNotNull(t1_foo);
assertIs("element1", "foo", t1_foo);
assertNotNull(t1_foo);
assertIs("element1", "bar", t1_bar);
}
@SuppressWarnings("unchecked")
private void assertIs(String elementName, String prop, PropertyMeta<Tuple2<Foo, Foo>, ?> propertyMeta) {
assertTrue(propertyMeta.isSubProperty());
SubPropertyMeta<Tuple2<Foo, Foo>, Foo, String> subPropertyMeta = (SubPropertyMeta<Tuple2<Foo, Foo>, Foo, String>) propertyMeta;
assertEquals(elementName, subPropertyMeta.getOwnerProperty().getName());
assertEquals(prop, subPropertyMeta.getSubProperty().getName());
}
private PropertyNameMatcher newMatcher(String name) {
return new DefaultPropertyNameMatcher(name, 0, false, false);
}
@Test
public void testIndexStartingFlexiblePrefix() {
final PropertyFinder<Tuple2<Foo, Foo>> propertyFinder = classMeta.newPropertyFinder(isValidPropertyMeta);
final PropertyMeta<Tuple2<Foo, Foo>, ?> t0_foo = propertyFinder.findProperty(newMatcher("ta_foo"));
final PropertyMeta<Tuple2<Foo, Foo>, ?> t0_bar = propertyFinder.findProperty(newMatcher("ta_bar"));
final PropertyMeta<Tuple2<Foo, Foo>, ?> t1_foo = propertyFinder.findProperty(newMatcher("tb_foo"));
final PropertyMeta<Tuple2<Foo, Foo>, ?> t1_bar = propertyFinder.findProperty(newMatcher("tb_bar"));
validate(t0_foo, t0_bar, t1_foo, t1_bar);
}
@Test
public void testForEach() {
final List<String> names = new ArrayList<String>();
ClassMeta<Object> classMeta = ReflectionService.newInstance().getClassMeta(new TypeReference<Tuple2<Foo, Foo>>() {
}.getType());
classMeta.forEachProperties(new Consumer<PropertyMeta<?, ?>>() {
@Override
public void accept(PropertyMeta<?, ?> dbObjectPropertyMeta) {
names.add(dbObjectPropertyMeta.getName());
}
});
assertEquals(Arrays.asList("element0", "element1"), names);
}
@Test
public void testRespecify() throws ClassNotFoundException, MalformedURLException {
ClassLoader cl = new URLClassLoader(new URL[] {LibrarySetsClassLoader.findUrl(Tuple2.class, getClass().getClassLoader())}, null) {
@Override
public InputStream getResourceAsStream(String name) {
return null;
}
};
ReflectionService reflectionService = new ReflectionService(null) {
};
Class<?> tuple2Class = cl.loadClass(Tuple2.class.getName());
TupleClassMeta classMeta = new TupleClassMeta(tuple2Class, reflectionService);
List<InstantiatorDefinition> instantiatorDefinitions = classMeta.getInstantiatorDefinitions();
assertEquals(1, instantiatorDefinitions.size());
assertEquals("element0", instantiatorDefinitions.get(0).getParameters()[0].getName());
}
}