| package org.hamcrest.core; |
| |
| import org.hamcrest.BaseMatcher; |
| import org.hamcrest.Description; |
| import org.hamcrest.Matcher; |
| |
| import java.util.regex.Pattern; |
| |
| import static java.lang.Integer.parseInt; |
| |
| /** |
| * Provides a custom description to another matcher. |
| */ |
| public class DescribedAs<T> extends BaseMatcher<T> { |
| private final String descriptionTemplate; |
| private final Matcher<T> matcher; |
| private final Object[] values; |
| |
| private final static Pattern ARG_PATTERN = Pattern.compile("%([0-9]+)"); |
| |
| public DescribedAs(String descriptionTemplate, Matcher<T> matcher, Object[] values) { |
| this.descriptionTemplate = descriptionTemplate; |
| this.matcher = matcher; |
| this.values = values.clone(); |
| } |
| |
| @Override |
| public boolean matches(Object o) { |
| return matcher.matches(o); |
| } |
| |
| @Override |
| public void describeTo(Description description) { |
| java.util.regex.Matcher arg = ARG_PATTERN.matcher(descriptionTemplate); |
| |
| int textStart = 0; |
| while (arg.find()) { |
| description.appendText(descriptionTemplate.substring(textStart, arg.start())); |
| description.appendValue(values[parseInt(arg.group(1))]); |
| textStart = arg.end(); |
| } |
| |
| if (textStart < descriptionTemplate.length()) { |
| description.appendText(descriptionTemplate.substring(textStart)); |
| } |
| } |
| |
| @Override |
| public void describeMismatch(Object item, Description description) { |
| matcher.describeMismatch(item, description); |
| } |
| |
| /** |
| * Wraps an existing matcher, overriding its description with that specified. All other functions are |
| * delegated to the decorated matcher, including its mismatch description. |
| * For example: |
| * <pre>describedAs("a big decimal equal to %0", equalTo(myBigDecimal), myBigDecimal.toPlainString())</pre> |
| * |
| * @param description |
| * the new description for the wrapped matcher |
| * @param matcher |
| * the matcher to wrap |
| * @param values |
| * optional values to insert into the tokenised description |
| */ |
| public static <T> Matcher<T> describedAs(String description, Matcher<T> matcher, Object... values) { |
| return new DescribedAs<T>(description, matcher, values); |
| } |
| } |