1 package org.hamcrest.text; 2 3 import org.hamcrest.Description; 4 import org.hamcrest.Matcher; 5 import org.hamcrest.TypeSafeMatcher; 6 7 import static java.lang.Character.isWhitespace; 8 9 /** 10 * Tests if a string is equal to another string, ignoring any changes in whitespace. 11 */ 12 public class IsEqualIgnoringWhiteSpace extends TypeSafeMatcher<String> { 13 14 // TODO: Replace String with CharSequence to allow for easy interoperability between 15 // String, StringBuffer, StringBuilder, CharBuffer, etc (joe). 16 17 private final String string; 18 19 public IsEqualIgnoringWhiteSpace(String string) { 20 if (string == null) { 21 throw new IllegalArgumentException("Non-null value required by IsEqualIgnoringCase()"); 22 } 23 this.string = string; 24 } 25 26 @Override 27 public boolean matchesSafely(String item) { 28 return stripSpace(string).equalsIgnoreCase(stripSpace(item)); 29 } 30 31 @Override 32 public void describeMismatchSafely(String item, Description mismatchDescription) { 33 mismatchDescription.appendText("was ").appendText(stripSpace(item)); 34 } 35 36 @Override 37 public void describeTo(Description description) { 38 description.appendText("equalToIgnoringWhiteSpace(") 39 .appendValue(string) 40 .appendText(")"); 41 } 42 43 public String stripSpace(String toBeStripped) { 44 final StringBuilder result = new StringBuilder(); 45 boolean lastWasSpace = true; 46 for (int i = 0; i < toBeStripped.length(); i++) { 47 char c = toBeStripped.charAt(i); 48 if (isWhitespace(c)) { 49 if (!lastWasSpace) { 50 result.append(' '); 51 } 52 lastWasSpace = true; 53 } else { 54 result.append(c); 55 lastWasSpace = false; 56 } 57 } 58 return result.toString().trim(); 59 } 60 61 /** 62 * Creates a matcher of {@link String} that matches when the examined string is equal to 63 * the specified expectedString, when whitespace differences are (mostly) ignored. To be 64 * exact, the following whitespace rules are applied: 65 * <ul> 66 * <li>all leading and trailing whitespace of both the expectedString and the examined string are ignored</li> 67 * <li>any remaining whitespace, appearing within either string, is collapsed to a single space before comparison</li> 68 * </ul> 69 * For example: 70 * <pre>assertThat(" my\tfoo bar ", equalToIgnoringWhiteSpace(" my foo bar"))</pre> 71 * 72 * @param expectedString 73 * the expected value of matched strings 74 */ 75 public static Matcher<String> equalToIgnoringWhiteSpace(String expectedString) { 76 return new IsEqualIgnoringWhiteSpace(expectedString); 77 } 78 79 } 80