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

uk.org.lidalia.test.Assert Maven / Gradle / Ivy

The newest version!
package uk.org.lidalia.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;

import uk.org.lidalia.lang.Modifier;

import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static uk.org.lidalia.lang.Exceptions.throwUnchecked;

/**
 * Utility Hamcrest matchers for unit test assertions.
 */
public final class Assert {

    /**
     * Asserts that a class is not instantiable - it exists only for its static members.
     * 

* More precisely, asserts that the class: *

    *
  • Has Object as its immediate superclass
  • *
  • Has only one constructor
  • *
  • That constructor is private
  • *
  • That constructor takes no arguments
  • *
  • That constructor will throw an {@link UnsupportedOperationException} with message "Not Instantiable" if it is * invoked via reflection.
  • *
*

* Usage: * {@code assertThat(Values.class, isNotInstantiable());} * * @return a matcher that asserts that a class is not instantiable */ public static Matcher> isNotInstantiable() { final Matcher isAThrowableWhoseMessageIs = is(aThrowableWhoseMessage(is("Not instantiable"))); final Matcher isAnUnsupportedOperationException = instanceOf(UnsupportedOperationException.class); final CombinableMatcher bothIsAnUnsupportedOperationException = CombinableMatcher.both( isAThrowableWhoseMessageIs); final CombinableMatcher bothIsAnUnsupportedOperationExceptionAndIsAThrowableWhoseMessageIs = bothIsAnUnsupportedOperationException .and(isAnUnsupportedOperationException); final Matcher aConstructorWhoseThrownExceptionBothIsAnUnsupportedOperationExceptionAndIsAThrowableWhoseMessageIs = aConstructorWhoseThrownException(bothIsAnUnsupportedOperationExceptionAndIsAThrowableWhoseMessageIs); final Matcher aMemberWithModifierPrivate = isAMemberWithModifier(Modifier.PRIVATE); final Matcher isACollectionWhoseSizeIs0 = is(Assert.>>aCollectionWhoseSize(is(0))); final Matcher isAConstructorWhoseParameterTypesAreACollectionWhoseSizeIs0 = is(aConstructorWhoseParameterTypes(isACollectionWhoseSizeIs0)); final CombinableMatcher> isAPrivateNoArgsConstructor = CombinableMatcher.both( isAConstructorWhoseParameterTypesAreACollectionWhoseSizeIs0) .and(aMemberWithModifierPrivate) .and(aConstructorWhoseThrownExceptionBothIsAnUnsupportedOperationExceptionAndIsAThrowableWhoseMessageIs); final Matcher> isEqualToObjectClass = is(equalTo(Object.class)); final FeatureMatcher, Class> isAClassThatExtendsObjectDirectly = aClassWhoseSuperClass(isEqualToObjectClass); final Matcher>> aSingleElementCollection = Assert.aCollectionWhoseSize(is(1)); final Matcher>> isASingleElementCollection = is(aSingleElementCollection); final Matcher>> aListWhoseFirstElementIsAPrivateNoArgsConstructor = Assert.aListWhoseElementAtIndex(0, isAPrivateNoArgsConstructor); final Matcher>> isAListWhoseFirstElementIsAPrivateNoArgsConstructor = is(aListWhoseFirstElementIsAPrivateNoArgsConstructor); final CombinableMatcher>> both = CombinableMatcher.both( isASingleElementCollection); final CombinableMatcher>> isASinglePrivateNoArgsConstructor = both .and(isAListWhoseFirstElementIsAPrivateNoArgsConstructor); final FeatureMatcher, List>> isAClassWithASinglePrivateNoArgsConstructor = aClassWhoseSetOfConstructors(isASinglePrivateNoArgsConstructor); final CombinableMatcher> both1 = CombinableMatcher.both(isAClassThatExtendsObjectDirectly); final CombinableMatcher> and = both1.and(isAClassWithASinglePrivateNoArgsConstructor); return (CombinableMatcher>) and; } /** * Facilitates making an assertion about the superclass of a {@link Class}. *

* Usage: * {@code assertThat(String.class, is(aClassWhoseSuperClass(is(Object.class))));} * * @param classMatcher the matcher that will be applied to the class's superclass * @return a matcher that will assert something about the superclass of a class */ public static FeatureMatcher, Class> aClassWhoseSuperClass( final Matcher> classMatcher) { return new FeatureMatcher, Class>( classMatcher, "a Class whose super class", "'s super class") { @Override @SuppressWarnings("unchecked") protected Class featureValueOf(final Class actual) { return actual.getSuperclass(); } }; } private static FeatureMatcher, List>> aClassWhoseSetOfConstructors( final Matcher>> matcher) { return new FeatureMatcher, List>>( matcher, "a Class whose set of constructors", "'s constructors") { @Override protected List> featureValueOf(final Class actual) { final List> constructors = asList(actual.getDeclaredConstructors()); Collections.sort(constructors, new Comparator>() { @Override public int compare(final Constructor one, final Constructor other) { return one.toString().compareTo(other.toString()); } }); return constructors; } }; } /** * Facilitates making an assertion about the size of a {@link Collection}. *

* Usage: * {@code assertThat(asList(1, 2, 3), is(aCollectionWhoseSize(is(3))));} * * @param sizeMatcher the matcher that will be applied to the collection's size * @param the type of the collection whose size will be matched * @return a matcher that will assert something about a collection's size */ public static > Matcher aCollectionWhoseSize(final Matcher sizeMatcher) { return new FeatureMatcher(sizeMatcher, "a Collection whose size", "'s size") { @Override protected Integer featureValueOf(final T actual) { return actual.size(); } }; } /** * Facilitates making an assertion about the element at a given index of a {@link List}. *

* Usage: * {@code assertThat(asList("a", "b", "c"), is(aListWhoseElementAtIndex(2, is("c"))));} * * @param index the index of the element in the list the matcher will be applied to * @param matcher the matcher that will be applied to the element * @param the type of the elements in the List * @return a matcher that will assert something about the element at the given index of a collection */ public static Matcher> aListWhoseElementAtIndex( final Integer index, final Matcher matcher) { return new FeatureMatcher, E>(matcher, "a List whose element at index " + index, "'s element at index " + index) { @Override protected E featureValueOf(final List actual) { if (actual.size() > index) { return actual.get(index); } else { throw new AssertionError(actual + " has no element at index " + index); } } }; } /** * Asserts that a given {@link Member} has a given {@link Modifier}. *

* Usage: * {@code assertThat(Object.class.getMethod("toString"), isAMemberWithModifier(Modifier.PUBLIC));} * * @param modifier the modifier the member is expected to have * @param the type of the Member * @return a matcher that will assert a member has a modifier */ public static Matcher isAMemberWithModifier(final Modifier modifier) { return new TypeSafeDiagnosingMatcher() { @Override protected boolean matchesSafely(final T item, final Description mismatchDescription) { final boolean matches = modifier.existsOn(item); if (!matches) { mismatchDescription.appendValue(item).appendText(" did not have modifier ").appendValue(modifier); } return matches; } @Override public void describeTo(final Description description) { description.appendText("is a member with modifier " + modifier); } }; } private static Matcher> aConstructorWhoseParameterTypes(final Matcher>> parameterMatcher) { return new FeatureMatcher, List>>( parameterMatcher, "a constructor whose parameter types", "'s parameter types") { @Override protected List> featureValueOf(final Constructor actual) { return asList(actual.getParameterTypes()); } }; } private static Matcher> aConstructorWhoseThrownException(final Matcher throwableMatcher) { return new FeatureMatcher, Throwable>( throwableMatcher, "a constructor whose thrown exception", "'s thrown exception") { @Override protected Throwable featureValueOf(final Constructor constructor) { try { constructor.setAccessible(true); constructor.newInstance(); return null; } catch (InvocationTargetException e) { return e.getCause(); } catch (Exception e) { return throwUnchecked(e, null); } finally { constructor.setAccessible(false); } } }; } private static Matcher aThrowableWhoseMessage(final Matcher messageMatcher) { return new FeatureMatcher(messageMatcher, "a throwable whose message", "'s message") { @Override protected String featureValueOf(final Throwable actual) { return actual.getMessage(); } }; } private Assert() { throw new UnsupportedOperationException("Not instantiable"); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy