CVS: junit/src/org/junit/matchers IsCollectionContaining.java, NONE, 1.1 TypeSafeMatcher.java, NONE, 1.1 StringContains.java, NONE, 1.1 Each.java, NONE, 1.1 SubstringMatcher.java, NONE, 1.1

David Saff <[email protected]> Thu, 12 Jul 2007 10:08:26 -0700
Newsgroups gmane.comp.java.junit.devel
Message-ID <[email protected]>
Update of /cvsroot/junit/junit/src/org/junit/matchers
In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv26134/src/org/junit/matchers

Added Files:
	IsCollectionContaining.java TypeSafeMatcher.java 
	StringContains.java Each.java SubstringMatcher.java 
Log Message:
Re-organize theory packages

--- NEW FILE: IsCollectionContaining.java ---
package org.junit.matchers;

import static org.hamcrest.core.AllOf.allOf;
import static org.hamcrest.core.IsEqual.equalTo;

import java.util.ArrayList;
import java.util.Collection;

import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;

// Copied (hopefully temporarily) from hamcrest-library
public class IsCollectionContaining<T> extends TypeSafeMatcher<Iterable<T>> {
    private final Matcher<? extends T> elementMatcher;

    public IsCollectionContaining(Matcher<? extends T> elementMatcher) {
        this.elementMatcher = elementMatcher;
    }

    @Override
	public boolean matchesSafely(Iterable<T> collection) {
        for (T item : collection) {
            if (elementMatcher.matches(item)){
                return true;
            }
        }
        return false;
    }

    public void describeTo(Description description) {
        description
        	.appendText("a collection containing ")
        	.appendDescriptionOf(elementMatcher);
    }

    @Factory
    public static <T> Matcher<Iterable<T>> hasItem(Matcher<? extends T> elementMatcher) {
        return new IsCollectionContaining<T>(elementMatcher);
    }

    @Factory
    public static <T> Matcher<Iterable<T>> hasItem(T element) {
        return hasItem(equalTo(element));
    }

    @Factory
    public static <T> Matcher<Iterable<T>> hasItems(Matcher<? extends T>... elementMatchers) {
        Collection<Matcher<? extends Iterable<T>>> all
                = new ArrayList<Matcher<? extends Iterable<T>>>(elementMatchers.length);
        for (Matcher<? extends T> elementMatcher : elementMatchers) {
            all.add(hasItem(elementMatcher));
        }
        return allOf(all);
    }

    @Factory
    public static <T> Matcher<Iterable<T>> hasItems(T... elements) {
        Collection<Matcher<? extends Iterable<T>>> all
                = new ArrayList<Matcher<? extends Iterable<T>>>(elements.length);
        for (T element : elements) {
            all.add(hasItem(element));
        }
        return allOf(all);
    }

}

--- NEW FILE: TypeSafeMatcher.java ---
package org.junit.matchers;

import java.lang.reflect.Method;

import org.hamcrest.BaseMatcher;

/**
 * Convenient base class for Matchers that require a non-null value of a specific type.
 * This simply implements the null check, checks the type and then casts.
 *
 * @author Joe Walnes
 */
public abstract class TypeSafeMatcher<T> extends BaseMatcher<T> {

    private Class<?> expectedType;

    /**
     * Subclasses should implement this. The item will already have been checked for
     * the specific type and will never be null.
     */
    public abstract boolean matchesSafely(T item);

    protected TypeSafeMatcher() {
        expectedType = findExpectedType(getClass());
    }
    
    private static Class<?> findExpectedType(Class<?> fromClass) {
        for (Class<?> c = fromClass; c != Object.class; c = c.getSuperclass()) {
            for (Method method : c.getDeclaredMethods()) {
                if (isMatchesSafelyMethod(method)) {
                    return method.getParameterTypes()[0];
                }
            }
        }
        
        throw new Error("Cannot determine correct type for matchesSafely() method.");
    }
    
    private static boolean isMatchesSafelyMethod(Method method) {
        return method.getName().equals("matchesSafely") 
            && method.getParameterTypes().length == 1
            && !method.isSynthetic(); 
    }
    
    protected TypeSafeMatcher(Class<T> expectedType) {
    	this.expectedType = expectedType;
    }

    /**
     * Method made final to prevent accidental override.
     * If you need to override this, there's no point on extending TypeSafeMatcher.
     * Instead, extend the {@link BaseMatcher}.
     */
    @SuppressWarnings({"unchecked"})
    public final boolean matches(Object item) {
        return item != null
                && expectedType.isInstance(item)
                && matchesSafely((T) item);
    }
}

--- NEW FILE: StringContains.java ---
/*  Copyright (c) 2000-2006 hamcrest.org
 */
package org.junit.matchers;

import org.hamcrest.Factory;
import org.hamcrest.Matcher;

/**
 * Tests if the argument is a string that contains a substring.
 */
public class StringContains extends SubstringMatcher {
    public StringContains(String substring) {
        super(substring);
    }

    @Override
	protected boolean evalSubstringOf(String s) {
        return s.indexOf(substring) >= 0;
    }

    @Override
	protected String relationship() {
        return "containing";
    }

    @Factory
    public static Matcher<String> containsString(String substring) {
        return new StringContains(substring);
    }

}
--- NEW FILE: Each.java ---
package org.junit.matchers;

import static org.hamcrest.CoreMatchers.not;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import static org.junit.matchers.IsCollectionContaining.hasItem;

public class Each {
	public static <T> Matcher<Iterable<T>> each(final Matcher<T> individual) {
		final Matcher<Iterable<T>> allItemsAre = not(hasItem(not(individual)));
		
		return new BaseMatcher<Iterable<T>>() {
			public boolean matches(Object item) {
				return allItemsAre.matches(item);
			}
			
			public void describeTo(Description description) {
				description.appendText("each ");
				individual.describeTo(description);
			}
		};
	}
}

--- NEW FILE: SubstringMatcher.java ---
package org.junit.matchers;

import org.hamcrest.Description;

public abstract class SubstringMatcher extends TypeSafeMatcher<String> {

    // TODO: Replace String with CharSequence to allow for easy interopability between
    //       String, StringBuffer, StringBuilder, CharBuffer, etc (joe).

    protected final String substring;

    protected SubstringMatcher(final String substring) {
        this.substring = substring;
    }

    @Override
	public boolean matchesSafely(String item) {
        return evalSubstringOf(item);
    }

    public void describeTo(Description description) {
        description.appendText("a string ")
                .appendText(relationship())
                .appendText(" ")
                .appendValue(substring);
    }

    protected abstract boolean evalSubstringOf(String string);

    protected abstract String relationship();
}

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/