1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.collect;
18 
19 import com.google.common.collect.ImmutableClassToInstanceMapTest.TestClassToInstanceMapGenerator;
20 import com.google.common.collect.testing.MapTestSuiteBuilder;
21 import com.google.common.collect.testing.features.CollectionFeature;
22 import com.google.common.collect.testing.features.CollectionSize;
23 import com.google.common.collect.testing.features.MapFeature;
24 import com.google.common.collect.testing.testers.MapPutTester;
25 
26 import junit.framework.Test;
27 import junit.framework.TestCase;
28 import junit.framework.TestSuite;
29 
30 import java.lang.reflect.Method;
31 import java.util.Map;
32 import java.util.Map.Entry;
33 
34 /**
35  * Unit test of {@link MutableClassToInstanceMap}.
36  *
37  * @author Kevin Bourrillion
38  */
39 public class MutableClassToInstanceMapTest extends TestCase {
40   public static Test suite() {
41     TestSuite suite = new TestSuite();
42     suite.addTestSuite(MutableClassToInstanceMapTest.class);
43 
44     // Suppress this one because the tester framework doesn't understand that
45     // *some* remappings will be allowed and others not.
46     Method remapTest = null;
47     try {
48       remapTest = MapPutTester.class.getMethod(
49           "testPut_replaceNullValueWithNonNullSupported");
50     } catch (NoSuchMethodException e) {
51       throw new AssertionError();
52     }
53 
54     suite.addTest(MapTestSuiteBuilder
55         .using(new TestClassToInstanceMapGenerator() {
56           // Other tests will verify what real, warning-free usage looks like
57           // but here we have to do some serious fudging
58           @Override
59           @SuppressWarnings("unchecked")
60           public Map<Class, Number> create(Object... elements) {
61             MutableClassToInstanceMap<Number> map
62                 = MutableClassToInstanceMap.create();
63             for (Object object : elements) {
64               Entry<Class, Number> entry = (Entry<Class, Number>) object;
65               map.putInstance(entry.getKey(), entry.getValue());
66             }
67             return (Map) map;
68           }
69         })
70         .named("MutableClassToInstanceMap")
71         .withFeatures(
72             MapFeature.GENERAL_PURPOSE,
73             MapFeature.RESTRICTS_KEYS,
74             MapFeature.ALLOWS_NULL_VALUES,
75             CollectionSize.ANY,
76             CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
77             MapFeature.ALLOWS_ANY_NULL_QUERIES)
78         .suppressing(remapTest)
79         .createTestSuite());
80 
81     return suite;
82   }
83 
84   private ClassToInstanceMap<Number> map;
85 
86   @Override protected void setUp() throws Exception {
87     map = MutableClassToInstanceMap.create();
88   }
89 
90   public void testConstraint() {
91 
92     /**
93      * We'll give ourselves a pass on testing all the possible ways of
94      * breaking the constraint, because we know that newClassMap() is
95      * implemented using ConstrainedMap which is itself well-tested.
96      * A purist would object to this, but what can I say, we're dirty
97      * cheaters.
98      */
99 
100     map.put(Integer.class, new Integer(5));
101     try {
102       map.put(Double.class, new Long(42));
103       fail();
104     } catch (ClassCastException expected) {
105     }
106     // Won't compile: map.put(String.class, "x");
107   }
108 
109   public void testPutAndGetInstance() {
110     assertNull(map.putInstance(Integer.class, new Integer(5)));
111 
112     Integer oldValue = map.putInstance(Integer.class, new Integer(7));
113     assertEquals(5, (int) oldValue);
114 
115     Integer newValue = map.getInstance(Integer.class);
116     assertEquals(7, (int) newValue);
117 
118     // Won't compile: map.putInstance(Double.class, new Long(42));
119   }
120 
121   public void testNull() {
122     try {
123       map.put(null, new Integer(1));
124       fail();
125     } catch (NullPointerException expected) {
126     }
127     map.putInstance(Integer.class, null);
128     assertNull(map.get(Integer.class));
129     assertNull(map.getInstance(Integer.class));
130 
131     map.put(Long.class, null);
132     assertNull(map.get(Long.class));
133     assertNull(map.getInstance(Long.class));
134   }
135 
136   public void testPrimitiveAndWrapper() {
137     assertNull(map.getInstance(int.class));
138     assertNull(map.getInstance(Integer.class));
139 
140     assertNull(map.putInstance(int.class, 0));
141     assertNull(map.putInstance(Integer.class, 1));
142     assertEquals(2, map.size());
143 
144     assertEquals(0, (int) map.getInstance(int.class));
145     assertEquals(1, (int) map.getInstance(Integer.class));
146 
147     assertEquals(0, (int) map.putInstance(int.class, null));
148     assertEquals(1, (int) map.putInstance(Integer.class, null));
149 
150     assertNull(map.getInstance(int.class));
151     assertNull(map.getInstance(Integer.class));
152     assertEquals(2, map.size());
153   }
154 }
155