Home | History | Annotate | Download | only in core
      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 
     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 
     28     public boolean matches(Object o) {
     29         return matcher.matches(o);
     30     }
     31 
     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
     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