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