1package org.hamcrest.collection;
2
3import org.hamcrest.Description;
4import org.hamcrest.Factory;
5import org.hamcrest.Matcher;
6import org.hamcrest.TypeSafeMatcher;
7import org.hamcrest.core.IsAnything;
8
9import static org.hamcrest.core.IsEqual.equalTo;
10
11import java.util.Map;
12import java.util.Map.Entry;
13
14public class IsMapContaining<K,V> extends TypeSafeMatcher<Map<K, V>> {
15
16    private final Matcher<K> keyMatcher;
17    private final Matcher<V> valueMatcher;
18
19    public IsMapContaining(Matcher<K> keyMatcher, Matcher<V> valueMatcher) {
20        this.keyMatcher = keyMatcher;
21        this.valueMatcher = valueMatcher;
22    }
23
24    public boolean matchesSafely(Map<K, V> map) {
25        for (Entry<K, V> entry : map.entrySet()) {
26            if (keyMatcher.matches(entry.getKey()) && valueMatcher.matches(entry.getValue())) {
27                return true;
28            }
29        }
30        return false;
31    }
32
33    public void describeTo(Description description) {
34        description.appendText("map containing [")
35                   .appendDescriptionOf(keyMatcher)
36                   .appendText("->")
37			       .appendDescriptionOf(valueMatcher)
38			       .appendText("]");
39    }
40
41    @Factory
42    public static <K,V> Matcher<Map<K,V>> hasEntry(Matcher<K> keyMatcher, Matcher<V> valueMatcher) {
43        return new IsMapContaining<K,V>(keyMatcher, valueMatcher);
44    }
45
46    @Factory
47    public static <K,V> Matcher<Map<K,V>> hasEntry(K key, V value) {
48        return hasEntry(equalTo(key), equalTo(value));
49    }
50
51    @Factory
52    public static <K,V> Matcher<Map<K,V>> hasKey(Matcher<K> keyMatcher) {
53        return hasEntry(keyMatcher, IsAnything.<V>anything());
54    }
55
56    @Factory
57    public static <K,V> Matcher<Map<K,V>> hasKey(K key) {
58        return hasKey(equalTo(key));
59    }
60
61    @Factory
62    public static <K,V> Matcher<Map<K,V>> hasValue(Matcher<V> valueMatcher) {
63        return hasEntry(IsAnything.<K>anything(), valueMatcher);
64    }
65
66    @Factory
67    public static <K,V> Matcher<Map<K,V>> hasValue(V value) {
68        return hasValue(equalTo(value));
69    }
70}
71