package br.com.caelum.vraptor.core; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertThat; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.List; import org.junit.Before; import org.junit.Test; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.FluentIterable; public class ReflectionProviderTest { public static class Dog { private String name; private boolean running; public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isRunning() { return running; } public void setRunning(boolean running) { this.running = running; } } public static class DomesticDog extends Dog { private String breed; public void setBreed(String breed) { this.breed = breed; } public String getBreed() { return breed; } } protected ReflectionProvider reflectionProvider; @Before public void setup() { reflectionProvider = new DefaultReflectionProvider(); } @Test public void shouldListAllMethodsMethodsFromClass() { List<Method> methods = reflectionProvider.getMethodsFor(Dog.class); List<String> names = FluentIterable.from(methods).filter(notFromObject()).transform(extractName()).toList(); assertThat(names, containsInAnyOrder("getName", "isRunning", "setName", "setRunning")); } @Test public void shouldListAllMethodsMethodsFromInheritedClassAndSuperclass() { List<Method> methods = reflectionProvider.getMethodsFor(DomesticDog.class); List<String> names = FluentIterable.from(methods).filter(notFromObject()).transform(extractName()).toList(); assertThat(names, containsInAnyOrder("getBreed", "getName", "isRunning", "setBreed", "setName", "setRunning")); } @Test public void shouldReturnMethodFromClass() { Method getName = reflectionProvider.getMethod(Dog.class, "getName"); assertThat(getName.getName(), equalTo("getName")); assertThat(getName.getReturnType().getName(), equalTo(String.class.getName())); assertThat(getName.getParameterTypes().length, equalTo(0)); Method setName = reflectionProvider.getMethod(Dog.class, "setName", String.class); assertThat(setName.getName(), equalTo("setName")); assertThat(setName.getReturnType().getName(), equalTo(void.class.getName())); assertThat(setName.getParameterTypes().length, equalTo(1)); } @Test public void shouldGetMethodFromInheritedClass() { Method getName = reflectionProvider.getMethod(DomesticDog.class, "getName"); assertThat(getName.getName(), equalTo("getName")); assertThat(getName.getReturnType().getName(), equalTo(String.class.getName())); assertThat(getName.getParameterTypes().length, equalTo(0)); Method setBreed = reflectionProvider.getMethod(DomesticDog.class, "setBreed", String.class); assertThat(setBreed.getName(), equalTo("setBreed")); assertThat(setBreed.getReturnType().getName(), equalTo(void.class.getName())); assertThat(setBreed.getParameterTypes().length, equalTo(1)); } @Test public void shouldReturnNullWhenMethodNotFound() { Method notFound = reflectionProvider.getMethod(Dog.class, "notFound"); assertThat(notFound, nullValue()); } @Test public void shouldInvokeMethodByInstanceFromClass() { Dog dog = new Dog(); Method setName = reflectionProvider.getMethod(Dog.class, "setName", String.class); reflectionProvider.invoke(dog, setName, "Otto"); assertThat(dog.getName(), equalTo("Otto")); } @Test public void shouldInvokeMethodByInstanceFromInheritedClass() { DomesticDog dog = new DomesticDog(); Method setName = reflectionProvider.getMethod(Dog.class, "setName", String.class); reflectionProvider.invoke(dog, setName, "Otto"); assertThat(dog.getName(), equalTo("Otto")); Method setBreed = reflectionProvider.getMethod(DomesticDog.class, "setBreed", String.class); reflectionProvider.invoke(dog, setBreed, "Schnauzer"); assertThat(dog.getBreed(), equalTo("Schnauzer")); } @Test public void shouldInvokeMethodByNameFromClass() { Dog dog = new Dog(); reflectionProvider.invoke(dog, "setName", "Otto"); assertThat(dog.getName(), equalTo("Otto")); } @Test public void shouldInvokeMethodByNameFromInheritedClass() { DomesticDog dog = new DomesticDog(); reflectionProvider.invoke(dog, "setName", "Otto"); assertThat(dog.getName(), equalTo("Otto")); reflectionProvider.invoke(dog, "setBreed", "Schnauzer"); assertThat(dog.getBreed(), equalTo("Schnauzer")); } @Test public void shouldInvokeGetterFromClass() { Dog dog = new Dog(); dog.setName("Otto"); dog.setRunning(true); String dogName = (String) reflectionProvider.invokeGetter(dog, "name"); assertThat(dogName, equalTo("Otto")); boolean isRunning = (boolean) reflectionProvider.invokeGetter(dog, "running"); assertThat(isRunning, equalTo(true)); } @Test public void shouldInvokeGetterFromInheritedClass() { DomesticDog dog = new DomesticDog(); dog.setName("Otto"); dog.setBreed("Schnauzer"); String dogName = (String) reflectionProvider.invokeGetter(dog, "name"); assertThat(dogName, equalTo("Otto")); String dogBreed = (String) reflectionProvider.invokeGetter(dog, "breed"); assertThat(dogBreed, equalTo("Schnauzer")); } @Test public void shouldGetFieldsFromClass() { List<Field> fields = reflectionProvider.getFieldsFor(Dog.class); List<String> names = FluentIterable.from(fields).filter(notFromObject()).transform(extractName()).toList(); assertThat(names, contains("name", "running")); } @Test public void shouldGetFieldsFromInheritedClass() { List<Field> fields = reflectionProvider.getFieldsFor(DomesticDog.class); List<String> names = FluentIterable.from(fields).filter(notFromObject()).transform(extractName()).toList(); assertThat(names, contains("breed", "name", "running")); } @Test public void shouldGetFieldByNameFromClass() { Field nameField = reflectionProvider.getField(Dog.class, "name"); assertThat(nameField.getName(), equalTo("name")); assertThat(nameField.getType().getName(), equalTo(String.class.getName())); Field runningField = reflectionProvider.getField(Dog.class, "running"); assertThat(runningField.getName(), equalTo("running")); assertThat(runningField.getType().getName(), equalTo(boolean.class.getName())); } @Test public void shouldGetFieldByNameFromInheritedClass() { Field nameField = reflectionProvider.getField(DomesticDog.class, "name"); assertThat(nameField.getName(), equalTo("name")); assertThat(nameField.getType().getName(), equalTo(String.class.getName())); Field breedField = reflectionProvider.getField(DomesticDog.class, "breed"); assertThat(breedField.getName(), equalTo("breed")); assertThat(breedField.getType().getName(), equalTo(String.class.getName())); } @Test public void shouldReturnNullWhenFieldNotFound() { Field notFound = reflectionProvider.getField(Dog.class, "notFound"); assertThat(notFound, nullValue()); } private Function<Member, String> extractName() { return new Function<Member, String>() { @Override public String apply(Member input) { return input.getName(); } }; } private Predicate<Member> notFromObject() { return new Predicate<Member>() { @Override public boolean apply(Member input) { return !input.getDeclaringClass().equals(Object.class); } }; } }