1 /* Copyright (c) 2000-2006 hamcrest.org 2 */ 3 package org.hamcrest.core; 4 5 import java.util.regex.Pattern; 6 7 import org.hamcrest.Description; 8 import org.hamcrest.Matcher; 9 import org.hamcrest.Factory; 10 import org.hamcrest.BaseMatcher; 11 12 /** 13 * Provides a custom description to another matcher. 14 */ 15 public class DescribedAs<T> extends BaseMatcher<T> { 16 private final String descriptionTemplate; 17 private final Matcher<T> matcher; 18 private final Object[] values; 19 20 private final static Pattern ARG_PATTERN = Pattern.compile("%([0-9]+)"); 21 DescribedAs(String descriptionTemplate, Matcher<T> matcher, Object[] values)22 public DescribedAs(String descriptionTemplate, Matcher<T> matcher, Object[] values) { 23 this.descriptionTemplate = descriptionTemplate; 24 this.matcher = matcher; 25 this.values = values.clone(); 26 } 27 matches(Object o)28 public boolean matches(Object o) { 29 return matcher.matches(o); 30 } 31 describeTo(Description description)32 public void describeTo(Description description) { 33 java.util.regex.Matcher arg = ARG_PATTERN.matcher(descriptionTemplate); 34 35 int textStart = 0; 36 while (arg.find()) { 37 description.appendText(descriptionTemplate.substring(textStart, arg.start())); 38 int argIndex = Integer.parseInt(arg.group(1)); 39 description.appendValue(values[argIndex]); 40 textStart = arg.end(); 41 } 42 43 if (textStart < descriptionTemplate.length()) { 44 description.appendText(descriptionTemplate.substring(textStart)); 45 } 46 } 47 48 /** 49 * Wraps an existing matcher and overrides the description when it fails. 50 */ 51 @Factory describedAs(String description, Matcher<T> matcher, Object... values)52 public static <T> Matcher<T> describedAs(String description, Matcher<T> matcher, Object... values) { 53 return new DescribedAs<T>(description, matcher, values); 54 } 55 } 56