1 /*
2  * Copyright (C) 2009 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 static com.google.common.collect.Maps.immutableEntry;
20 
21 import com.google.common.collect.testing.MapTestSuiteBuilder;
22 import com.google.common.collect.testing.SampleElements;
23 import com.google.common.collect.testing.TestMapGenerator;
24 import com.google.common.collect.testing.features.CollectionFeature;
25 import com.google.common.collect.testing.features.CollectionSize;
26 import com.google.common.collect.testing.features.MapFeature;
27 import com.google.common.testing.SerializableTester;
28 import java.io.Serializable;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33 import junit.framework.Test;
34 import junit.framework.TestCase;
35 import junit.framework.TestSuite;
36 
37 /**
38  * Unit test for {@link ImmutableClassToInstanceMap}.
39  *
40  * @author Kevin Bourrillion
41  */
42 public class ImmutableClassToInstanceMapTest extends TestCase {
suite()43   public static Test suite() {
44     TestSuite suite = new TestSuite();
45     suite.addTestSuite(ImmutableClassToInstanceMapTest.class);
46 
47     suite.addTest(
48         MapTestSuiteBuilder.using(
49                 new TestClassToInstanceMapGenerator() {
50                   // Other tests will verify what real, warning-free usage looks like
51                   // but here we have to do some serious fudging
52                   @Override
53                   @SuppressWarnings("unchecked")
54                   public Map<Class, Impl> create(Object... elements) {
55                     ImmutableClassToInstanceMap.Builder<Impl> builder =
56                         ImmutableClassToInstanceMap.builder();
57                     for (Object object : elements) {
58                       Entry<Class, Impl> entry = (Entry<Class, Impl>) object;
59                       builder.put(entry.getKey(), entry.getValue());
60                     }
61                     return (Map) builder.build();
62                   }
63                 })
64             .named("ImmutableClassToInstanceMap")
65             .withFeatures(
66                 MapFeature.REJECTS_DUPLICATES_AT_CREATION,
67                 MapFeature.RESTRICTS_KEYS,
68                 CollectionFeature.KNOWN_ORDER,
69                 CollectionSize.ANY,
70                 MapFeature.ALLOWS_ANY_NULL_QUERIES,
71                 CollectionFeature.SERIALIZABLE)
72             .createTestSuite());
73 
74     return suite;
75   }
76 
testSerialization_empty()77   public void testSerialization_empty() {
78     assertSame(
79         ImmutableClassToInstanceMap.of(),
80         SerializableTester.reserialize(ImmutableClassToInstanceMap.of()));
81   }
82 
testCopyOf_map_empty()83   public void testCopyOf_map_empty() {
84     Map<Class<?>, Object> in = Collections.emptyMap();
85     ClassToInstanceMap<Object> map = ImmutableClassToInstanceMap.copyOf(in);
86     assertTrue(map.isEmpty());
87     assertSame(map, ImmutableClassToInstanceMap.of());
88     assertSame(map, ImmutableClassToInstanceMap.copyOf(map));
89   }
90 
testOf_zero()91   public void testOf_zero() {
92     assertTrue(ImmutableClassToInstanceMap.of().isEmpty());
93   }
94 
testOf_one()95   public void testOf_one() {
96     ImmutableClassToInstanceMap<Number> map = ImmutableClassToInstanceMap.of(int.class, 1);
97     assertEquals(1, map.size());
98   }
99 
testCopyOf_map_valid()100   public void testCopyOf_map_valid() {
101     Map<Class<? extends Number>, Number> in = Maps.newHashMap();
102     in.put(Number.class, 0);
103     in.put(Double.class, Math.PI);
104     ClassToInstanceMap<Number> map = ImmutableClassToInstanceMap.copyOf(in);
105     assertEquals(2, map.size());
106 
107     Number zero = map.getInstance(Number.class);
108     assertEquals(0, zero);
109 
110     Double pi = map.getInstance(Double.class);
111     assertEquals(Math.PI, pi, 0.0);
112 
113     assertSame(map, ImmutableClassToInstanceMap.copyOf(map));
114   }
115 
testCopyOf_map_nulls()116   public void testCopyOf_map_nulls() {
117     Map<Class<? extends Number>, Number> nullKey = Collections.singletonMap(null, (Number) 1.0);
118     try {
119       ImmutableClassToInstanceMap.copyOf(nullKey);
120       fail();
121     } catch (NullPointerException expected) {
122     }
123 
124     Map<? extends Class<? extends Number>, Number> nullValue =
125         Collections.singletonMap(Number.class, null);
126     try {
127       ImmutableClassToInstanceMap.copyOf(nullValue);
128       fail();
129     } catch (NullPointerException expected) {
130     }
131   }
132 
testCopyOf_imap_empty()133   public void testCopyOf_imap_empty() {
134     Map<Class<?>, Object> in = Collections.emptyMap();
135     ClassToInstanceMap<Object> map = ImmutableClassToInstanceMap.copyOf(in);
136     assertTrue(map.isEmpty());
137   }
138 
testCopyOf_imap_valid()139   public void testCopyOf_imap_valid() {
140     ImmutableMap<Class<? extends Number>, ? extends Number> in =
141         ImmutableMap.of(Number.class, 0, Double.class, Math.PI);
142     ClassToInstanceMap<Number> map = ImmutableClassToInstanceMap.copyOf(in);
143     assertEquals(2, map.size());
144 
145     Number zero = map.getInstance(Number.class);
146     assertEquals(0, zero);
147 
148     Double pi = map.getInstance(Double.class);
149     assertEquals(Math.PI, pi, 0.0);
150   }
151 
testPrimitiveAndWrapper()152   public void testPrimitiveAndWrapper() {
153     ImmutableClassToInstanceMap<Number> ictim =
154         new ImmutableClassToInstanceMap.Builder<Number>()
155             .put(Integer.class, 0)
156             .put(int.class, 1)
157             .build();
158     assertEquals(2, ictim.size());
159 
160     assertEquals(0, (int) ictim.getInstance(Integer.class));
161     assertEquals(1, (int) ictim.getInstance(int.class));
162   }
163 
164   abstract static class TestClassToInstanceMapGenerator implements TestMapGenerator<Class, Impl> {
165 
166     @Override
createKeyArray(int length)167     public Class[] createKeyArray(int length) {
168       return new Class[length];
169     }
170 
171     @Override
createValueArray(int length)172     public Impl[] createValueArray(int length) {
173       return new Impl[length];
174     }
175 
176     @Override
samples()177     public SampleElements<Entry<Class, Impl>> samples() {
178       return new SampleElements<>(
179           immutableEntry((Class) One.class, new Impl(1)),
180           immutableEntry((Class) Two.class, new Impl(2)),
181           immutableEntry((Class) Three.class, new Impl(3)),
182           immutableEntry((Class) Four.class, new Impl(4)),
183           immutableEntry((Class) Five.class, new Impl(5)));
184     }
185 
186     @Override
187     @SuppressWarnings("unchecked")
createArray(int length)188     public Entry<Class, Impl>[] createArray(int length) {
189       return new Entry[length];
190     }
191 
192     @Override
order(List<Entry<Class, Impl>> insertionOrder)193     public Iterable<Entry<Class, Impl>> order(List<Entry<Class, Impl>> insertionOrder) {
194       return insertionOrder;
195     }
196   }
197 
198   private interface One {}
199 
200   private interface Two {}
201 
202   private interface Three {}
203 
204   private interface Four {}
205 
206   private interface Five {}
207 
208   static final class Impl implements One, Two, Three, Four, Five, Serializable {
209     final int value;
210 
Impl(int value)211     Impl(int value) {
212       this.value = value;
213     }
214 
215     @Override
equals(Object obj)216     public boolean equals(Object obj) {
217       return obj instanceof Impl && value == ((Impl) obj).value;
218     }
219 
220     @Override
hashCode()221     public int hashCode() {
222       return value;
223     }
224 
225     @Override
toString()226     public String toString() {
227       return Integer.toString(value);
228     }
229   }
230 }
231