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

net.amygdalum.testrecorder.runtime.ContainsMatcher Maven / Gradle / Ivy

The newest version!
package net.amygdalum.testrecorder.runtime;

import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsNull.nullValue;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.core.IsNull;

public class ContainsMatcher extends AbstractIterableMatcher> {

	private Class type;
	private List> elements;

	public ContainsMatcher(Class type) {
		this.type = type;
		this.elements = new ArrayList<>();
	}

	public ContainsMatcher and(T element) {
		return and(match(element));
	}

	public ContainsMatcher and(Matcher element) {
		elements.add(element);
		return this;
	}

	private Matcher match(T element) {
		if (element == null) {
			return nullValue(type);
		} else {
			return equalTo(element);
		}
	}

	@Override
	public void describeTo(Description description) {
		description.appendText("containing ").appendValueList("[", ", ", "]", elements);
	}

	@Override
	protected void describeMismatchSafely(Collection item, Description mismatchDescription) {
		List> unmatched = new LinkedList<>(elements);
		Matches matches = new Matches<>();
		List notExpected = new ArrayList<>();

		for (T element : item) {

			boolean success = tryMatch(unmatched, element);
			if (success) {
				matches.match();
			} else {
				notExpected.add(element);
			}
		}

		if (!notExpected.isEmpty()) {
			matches.mismatch("found " + notExpected.size() + " elements surplus " + toFoundSet(notExpected));
		}
		if (!unmatched.isEmpty()) {
			matches.mismatch("missing " + unmatched.size() + " elements " + toExpectedSet(unmatched));
		}
		mismatchDescription.appendText("mismatching elements ").appendDescriptionOf(matches);
	}

	@Override
	protected Matcher bestMatcher() {
		for (Matcher matcher : elements) {
			if (matcher.getClass() != IsNull.class) {
				return matcher;
			}
		}
		return equalTo(null);
	}

	@Override
	protected boolean matchesSafely(Collection item) {
		List> unmatched = new LinkedList<>(elements);

		for (T element : item) {
			boolean success = tryMatch(unmatched, element);
			if (!success) {
				return false;
			}
		}

		return unmatched.isEmpty();
	}

	private boolean tryMatch(List> unmatched, T element) {
		Iterator> matchers = unmatched.iterator();
		while (matchers.hasNext()) {
			Matcher matcher = matchers.next();
			if (matcher.matches(element)) {
				matchers.remove();
				return true;
			}
		}
		return false;
	}

	public static  ContainsMatcher empty(Class type) {
		return new ContainsMatcher<>(type);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static ContainsMatcher empty() {
		return new ContainsMatcher(Object.class);
	}

	@SuppressWarnings("unchecked")
	@SafeVarargs
	public static  ContainsMatcher contains(Class key, Object... elements) {
		ContainsMatcher set = new ContainsMatcher<>(key);
		for (Object element : elements) {
			if (element instanceof Matcher) {
				set.and((Matcher) element);
			} else {
				set.and(key.cast(element));
			}
		}
		return set;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@SafeVarargs
	public static ContainsMatcher contains(Object... elements) {
		ContainsMatcher set = new ContainsMatcher(Object.class);
		for (Object element : elements) {
			if (element instanceof Matcher) {
				set.and((Matcher) element);
			} else {
				set.and(element);
			}
		}
		return set;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy