package dbfit.test.matchers;
import fit.Parse;
import org.hamcrest.TypeSafeMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import static org.hamcrest.Matchers.anything;
import java.io.StringWriter;
import java.io.PrintWriter;
public class TraversingParseMatcher extends TypeSafeMatcher<Parse> {
protected Matcher elementMatcher;
protected int expectedCount = 1;
protected int actualCount = 0;
// Override this to traverse sub-elements
protected void visitElements(Parse parse) {
matchElement(parse);
}
public TraversingParseMatcher() {
this(anything());
}
public TraversingParseMatcher(Matcher elementMatcher) {
this.elementMatcher = elementMatcher;
}
public TraversingParseMatcher which(Matcher elementMatcher) {
this.elementMatcher = elementMatcher;
return this;
}
public TraversingParseMatcher withExpectedCount(int expectedCount) {
this.expectedCount = expectedCount;
return this;
}
protected void matchElement(Parse element) {
if (elementMatcher.matches(element)) {
++actualCount;
}
}
private final void matchElements(Parse parse) {
actualCount = 0;
visitElements(parse);
}
@Override
public boolean matchesSafely(Parse parse) {
matchElements(parse);
return (actualCount == expectedCount);
}
@Override
public void describeTo(final Description description) {
description
.appendText("should contain ")
.appendText(expectedCount + " " + getElementsKind() + "s")
.appendText(" where:\n")
.appendDescriptionOf(elementMatcher);
}
@Override
public void describeMismatchSafely(Parse item, Description mismatchDescription) {
StringWriter sw = new StringWriter();
item.print(new PrintWriter(sw));
mismatchDescription
.appendText("was actualCount=" + actualCount + ":\n---\n")
.appendText(sw.toString()).appendText("\n---\n");
}
protected String getElementsKind() {
return "element";
}
}