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