1 package org.hamcrest.collection; 2 3 import org.hamcrest.Description; 4 import org.hamcrest.Matcher; 5 import org.hamcrest.TypeSafeMatcher; 6 7 import java.util.Map; 8 import java.util.Map.Entry; 9 10 import static org.hamcrest.core.IsAnything.anything; 11 import static org.hamcrest.core.IsEqual.equalTo; 12 13 public class IsMapContaining<K,V> extends TypeSafeMatcher<Map<? extends K, ? extends V>> { 14 private final Matcher<? super K> keyMatcher; 15 private final Matcher<? super V> valueMatcher; 16 IsMapContaining(Matcher<? super K> keyMatcher, Matcher<? super V> valueMatcher)17 public IsMapContaining(Matcher<? super K> keyMatcher, Matcher<? super V> valueMatcher) { 18 this.keyMatcher = keyMatcher; 19 this.valueMatcher = valueMatcher; 20 } 21 22 @Override matchesSafely(Map<? extends K, ? extends V> map)23 public boolean matchesSafely(Map<? extends K, ? extends V> map) { 24 for (Entry<? extends K, ? extends V> entry : map.entrySet()) { 25 if (keyMatcher.matches(entry.getKey()) && valueMatcher.matches(entry.getValue())) { 26 return true; 27 } 28 } 29 return false; 30 } 31 32 @Override describeMismatchSafely(Map<? extends K, ? extends V> map, Description mismatchDescription)33 public void describeMismatchSafely(Map<? extends K, ? extends V> map, Description mismatchDescription) { 34 mismatchDescription.appendText("map was ").appendValueList("[", ", ", "]", map.entrySet()); 35 } 36 37 @Override describeTo(Description description)38 public void describeTo(Description description) { 39 description.appendText("map containing [") 40 .appendDescriptionOf(keyMatcher) 41 .appendText("->") 42 .appendDescriptionOf(valueMatcher) 43 .appendText("]"); 44 } 45 46 /** 47 * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains 48 * at least one entry whose key satisfies the specified <code>keyMatcher</code> <b>and</b> whose 49 * value satisfies the specified <code>valueMatcher</code>. 50 * For example: 51 * <pre>assertThat(myMap, hasEntry(equalTo("bar"), equalTo("foo")))</pre> 52 * 53 * @param keyMatcher 54 * the key matcher that, in combination with the valueMatcher, must be satisfied by at least one entry 55 * @param valueMatcher 56 * the value matcher that, in combination with the keyMatcher, must be satisfied by at least one entry 57 */ hasEntry(Matcher<? super K> keyMatcher, Matcher<? super V> valueMatcher)58 public static <K,V> Matcher<Map<? extends K,? extends V>> hasEntry(Matcher<? super K> keyMatcher, Matcher<? super V> valueMatcher) { 59 return new IsMapContaining<K,V>(keyMatcher, valueMatcher); 60 } 61 62 /** 63 * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains 64 * at least one entry whose key equals the specified <code>key</code> <b>and</b> whose value equals the 65 * specified <code>value</code>. 66 * For example: 67 * <pre>assertThat(myMap, hasEntry("bar", "foo"))</pre> 68 * 69 * @param key 70 * the key that, in combination with the value, must be describe at least one entry 71 * @param value 72 * the value that, in combination with the key, must be describe at least one entry 73 */ hasEntry(K key, V value)74 public static <K,V> Matcher<Map<? extends K,? extends V>> hasEntry(K key, V value) { 75 return new IsMapContaining<K,V>(equalTo(key), equalTo(value)); 76 } 77 78 /** 79 * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains 80 * at least one key that satisfies the specified matcher. 81 * For example: 82 * <pre>assertThat(myMap, hasKey(equalTo("bar")))</pre> 83 * 84 * @param keyMatcher 85 * the matcher that must be satisfied by at least one key 86 */ hasKey(Matcher<? super K> keyMatcher)87 public static <K> Matcher<Map<? extends K, ?>> hasKey(Matcher<? super K> keyMatcher) { 88 return new IsMapContaining<K,Object>(keyMatcher, anything()); 89 } 90 91 /** 92 * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains 93 * at least one key that is equal to the specified key. 94 * For example: 95 * <pre>assertThat(myMap, hasKey("bar"))</pre> 96 * 97 * @param key 98 * the key that satisfying maps must contain 99 */ hasKey(K key)100 public static <K> Matcher<Map<? extends K, ?>> hasKey(K key) { 101 return new IsMapContaining<K,Object>(equalTo(key), anything()); 102 } 103 104 /** 105 * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains 106 * at least one value that satisfies the specified valueMatcher. 107 * For example: 108 * <pre>assertThat(myMap, hasValue(equalTo("foo")))</pre> 109 * 110 * @param valueMatcher 111 * the matcher that must be satisfied by at least one value 112 */ hasValue(Matcher<? super V> valueMatcher)113 public static <V> Matcher<Map<?, ? extends V>> hasValue(Matcher<? super V> valueMatcher) { 114 return new IsMapContaining<Object,V>(anything(), valueMatcher); 115 } 116 117 /** 118 * Creates a matcher for {@link java.util.Map}s matching when the examined {@link java.util.Map} contains 119 * at least one value that is equal to the specified value. 120 * For example: 121 * <pre>assertThat(myMap, hasValue("foo"))</pre> 122 * 123 * @param value 124 * the value that satisfying maps must contain 125 */ hasValue(V value)126 public static <V> Matcher<Map<?, ? extends V>> hasValue(V value) { 127 return new IsMapContaining<Object,V>(anything(), equalTo(value)); 128 } 129 } 130