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