net.amygdalum.extensions.hamcrest.util.Matches Maven / Gradle / Ivy
package net.amygdalum.extensions.hamcrest.util;
import java.util.Arrays;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.SelfDescribing;
public class Matches implements SelfDescribing {
private Deque> matches;
private boolean mismatches;
public Matches() {
this.matches = new LinkedList<>();
this.mismatches = false;
}
public Matches mismatch(Matcher matcher, Object element) {
matches.add(new Mismatch<>(matcher, element));
mismatches = true;
return this;
}
public Matches mismatch(String description) {
matches.add(new MismatchDescription(description));
mismatches = true;
return this;
}
public Matches match() {
Matching peek = matches.peek();
if (peek instanceof Match>) {
((Match>) peek).inc();;
} else {
matches.add(new Match());
}
return this;
}
public boolean containsMismatches() {
return mismatches;
}
@Override
public void describeTo(Description description) {
description.appendText("<[");
Iterator> matchIterator = matches.iterator();
if (matchIterator.hasNext()) {
description.appendDescriptionOf(matchIterator.next());
}
while (matchIterator.hasNext()) {
description.appendText(", ");
description.appendDescriptionOf(matchIterator.next());
}
description.appendText("]>");
}
private static abstract class Matching implements SelfDescribing {
}
private static class Match extends Matching {
private int count;
public Match() {
this.count = 1;
}
public void inc() {
count++;
}
@Override
public void describeTo(Description description) {
char[] text = new char[count];
Arrays.fill(text, '.');
description.appendText(new String(text));
}
}
private static class MismatchDescription extends Matching {
private String description;
public MismatchDescription(String description) {
this.description = description;
}
@Override
public void describeTo(Description description) {
description.appendText(this.description);
}
}
private static class Mismatch extends Matching {
private Matcher matcher;
private Object element;
public Mismatch(Matcher matcher, Object element) {
this.matcher = matcher;
this.element = element;
}
@Override
public void describeTo(Description description) {
matcher.describeMismatch(element, description);
}
}
}