aboutsummaryrefslogtreecommitdiff
path: root/dexmaker-mockito-inline-extended/src/main/java/com/android/dx/mockito/inline/MarkerToHandlerMap.java
blob: 74a38b871a312f279cbdafc03e5046342979e07c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package com.android.dx.mockito.inline;

import org.mockito.invocation.MockHandler;
import org.mockito.mock.MockCreationSettings;

import java.util.AbstractMap;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * A map for mock marker object -> {@link InvocationHandlerAdapter} but
 * does not use the mock marker object as the key directly.
 * The problem of not doing so is that the object's real hashCode() and equals() =
 * methods will be invoked during
 * {@link InlineStaticMockMaker#createMock(MockCreationSettings, MockHandler)}. This poses a
 * potential test runtime error depending on the object's hashCode() implementation
 */
class MarkerToHandlerMap implements Map<Object, InvocationHandlerAdapter> {

    private final Map<MockMarkerKey, InvocationHandlerAdapter> markerToHandler = new HashMap<>();

    @Override
    public int size() {
        return markerToHandler.size();
    }

    @Override
    public boolean isEmpty() {
        return markerToHandler.isEmpty();
    }

    @Override
    public boolean containsKey(Object key) {
        return markerToHandler.containsKey(new MockMarkerKey(key));
    }

    @Override
    public boolean containsValue(Object value) {
        return markerToHandler.containsValue(value);
    }

    @Override
    public InvocationHandlerAdapter get(Object key) {
        return markerToHandler.get(new MockMarkerKey(key));
    }

    @Override
    public InvocationHandlerAdapter put(Object key, InvocationHandlerAdapter value) {
        return markerToHandler.put(new MockMarkerKey(key), value);
    }

    @Override
    public InvocationHandlerAdapter remove(Object key) {
        return markerToHandler.remove(new MockMarkerKey(key));
    }

    @Override
    public void putAll(Map<?, ? extends InvocationHandlerAdapter> m) {
        for (Entry<?, ? extends InvocationHandlerAdapter> entry : m.entrySet()) {
            put(new MockMarkerKey(entry.getKey()), entry.getValue());
        }
    }

    @Override
    public void clear() {
        markerToHandler.clear();
    }

    @Override
    public Set<Object> keySet() {
        Set<Object> set = new HashSet<>(entrySet().size());
        for (MockMarkerKey key : markerToHandler.keySet()) {
            set.add(key.mockMarker);
        }
        return set;
    }

    @Override
    public Collection<InvocationHandlerAdapter> values() {
        return markerToHandler.values();
    }

    @Override
    public Set<Entry<Object, InvocationHandlerAdapter>> entrySet() {
        Set<Entry<Object, InvocationHandlerAdapter>> set = new HashSet<>(entrySet().size());
        for (Entry<MockMarkerKey, InvocationHandlerAdapter> entry : markerToHandler.entrySet()) {
            set.add(new AbstractMap.SimpleImmutableEntry<>(entry.getKey().mockMarker, entry.getValue()));
        }
        return set;
    }

    private static class MockMarkerKey {

        private final Object mockMarker;

        public MockMarkerKey(Object mockMarker) {
            this.mockMarker = mockMarker;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            MockMarkerKey mockMarkerKey = (MockMarkerKey) o;

            return mockMarker == mockMarkerKey.mockMarker;
        }

        @Override
        public int hashCode() {
            return System.identityHashCode(mockMarker);
        }
    }
}