All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.thucydides.core.matchers.BeanMatcherAsserts Maven / Gradle / Ivy

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.*;
import static org.hamcrest.Matchers.*;

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));


        }
    }

    public static  void shouldNotMatch(List items, BeanMatcher... matchers) {
        if (matches(items, matchers)) {
            throw new AssertionError("Found unneeded matching elements for " + join(matchers)
                    + NEW_LINE
                    +"Elements where " + join(items));
        }
    }

    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 - 2024 Weber Informatics LLC | Privacy Policy