net.thucydides.core.matchers.BeanMatcherAsserts Maven / Gradle / Ivy
The newest version!
package net.thucydides.core.matchers;
import ch.lambdaj.Lambda;
import ch.lambdaj.function.convert.Converter;
import com.google.common.collect.ImmutableList;
import org.apache.commons.collections.ListUtils;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import static ch.lambdaj.Lambda.convert;
import static ch.lambdaj.Lambda.filter;
import static ch.lambdaj.Lambda.join;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
public class BeanMatcherAsserts {
private static final String NEW_LINE = System.getProperty("line.separator");
public static boolean matches(List elements, BeanMatcher... matchers) {
List filteredElements = filterElements(elements, matchers);
return apply(filteredElements, collectionMatchersIn(matchers));
}
private static boolean apply(final List elements, final List matchers) {
List collectionMatchers = addEmptyTestIfNoCountChecksArePresentTo(matchers);
for (BeanCollectionMatcher matcher : collectionMatchers) {
if (!matcher.matches(elements)) {
return false;
}
}
return true;
}
private static List addEmptyTestIfNoCountChecksArePresentTo(final List matchers) {
if (thereIsACardinalityConstraintSpecifiedInThe(matchers)) {
return matchers;
} else {
return mustContainAtLeastOneItemMatching(matchers);
}
}
private static List mustContainAtLeastOneItemMatching(List matchers) {
return ListUtils.union(matchers, Arrays.asList(BeanMatchers.the_count(is(not(0)))));
}
private static boolean thereIsACardinalityConstraintSpecifiedInThe(List matchers) {
for(BeanCollectionMatcher matcher : matchers) {
if (matcher instanceof BeanCountMatcher) {
return true;
}
}
return false;
}
private static List collectionMatchersIn(final BeanMatcher[] matchers) {
List compatibleMatchers = Lambda.filter(instanceOf(BeanCollectionMatcher.class), matchers);
return convert(compatibleMatchers, toBeanCollectionMatchers());
}
private static Converter toBeanCollectionMatchers() {
return new Converter() {
@Override
public BeanCollectionMatcher convert(BeanMatcher from) {
return (BeanCollectionMatcher) from;
}
};
}
public static List filterElements(final List elements, final BeanMatcher... matchers) {
List filteredItems = ImmutableList.copyOf(elements);
for(BeanFieldMatcher matcher : propertyMatchersIn(matchers)) {
filteredItems = filter(matcher.getMatcher(), filteredItems);
}
return filteredItems;
}
private static List propertyMatchersIn(BeanMatcher[] matchers) {
List compatibleMatchers = filter(instanceOf(BeanFieldMatcher.class), matchers);
return convert(compatibleMatchers, toBeanFieldMatchers());
}
private static Converter toBeanFieldMatchers() {
return new Converter() {
@Override
public BeanFieldMatcher convert(BeanMatcher from) {
return (BeanFieldMatcher) from;
}
};
}
public static void shouldMatch(List items, BeanMatcher... matchers) {
if (!matches(items, matchers)) {
throw new AssertionError("Failed to find matching elements for " + join(matchers)
+ NEW_LINE
+"Elements where " + join(items));
}
}
public static void shouldMatch(T bean, BeanMatcher... matchers) {
if (!matches(bean, matchers)) {
throw new AssertionError("Expected " + Arrays.toString(matchers) +
" but was " + descriptionOf(bean));
}
}
private static String descriptionOf(Object bean) {
if (isAMap(bean)) {
return mapDescription((Map) bean);
} else {
return beanDescription(bean);
}
}
private static String beanDescription(Object bean) {
List propertyTerms = new ArrayList();
try {
for(PropertyDescriptor descriptor : propertiesOf(bean)) {
Method getter = descriptor.getReadMethod();
if (getter != null) {
propertyTerms.add(propertyValueOf(descriptor.getDisplayName(), getter.invoke(bean).toString()));
}
}
return join(propertyTerms);
} catch (Throwable e) {
throw new IllegalArgumentException("Could not read bean properties", e);
}
}
private static String mapDescription(Map map) {
List propertyTerms = new ArrayList();
for (String key : map.keySet()) {
propertyTerms.add(propertyValueOf(key, map.get(key).toString()));
}
return join(propertyTerms);
}
private static boolean isAMap(Object bean) {
return Map.class.isAssignableFrom(bean.getClass());
}
public static boolean matches(T bean, BeanMatcher... matchers) {
return matches(Arrays.asList(bean), matchers);
}
private static String propertyValueOf(String propertyName, String value) {
return propertyName + " = '" + value + "'";
}
private static PropertyDescriptor[] propertiesOf(T bean) throws IntrospectionException {
return Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy