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 { 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_NULL_QUERIES) 68 .createTestSuite()); 69 70 return suite; 71 } 72 73 public void testCopyOf_map_empty() { 74 Map<Class<?>, Object> in = Collections.emptyMap(); 75 ClassToInstanceMap<Object> map = ImmutableClassToInstanceMap.copyOf(in); 76 assertTrue(map.isEmpty()); 77 78 assertSame(map, ImmutableClassToInstanceMap.copyOf(map)); 79 } 80 81 public void testCopyOf_map_valid() { 82 Map<Class<? extends Number>, Number> in = Maps.newHashMap(); 83 in.put(Number.class, 0); 84 in.put(Double.class, Math.PI); 85 ClassToInstanceMap<Number> map = ImmutableClassToInstanceMap.copyOf(in); 86 assertEquals(2, map.size()); 87 88 Number zero = map.getInstance(Number.class); 89 assertEquals(0, zero); 90 91 Double pi = map.getInstance(Double.class); 92 assertEquals(Math.PI, pi, 0.0); 93 94 assertSame(map, ImmutableClassToInstanceMap.copyOf(map)); 95 } 96 97 public void testCopyOf_map_nulls() { 98 Map<Class<? extends Number>, Number> nullKey = Collections.singletonMap( 99 null, (Number) 1.0); 100 try { 101 ImmutableClassToInstanceMap.copyOf(nullKey); 102 fail(); 103 } catch (NullPointerException expected) { 104 } 105 106 Map<? extends Class<? extends Number>, Number> nullValue 107 = Collections.singletonMap(Number.class, null); 108 try { 109 ImmutableClassToInstanceMap.copyOf(nullValue); 110 fail(); 111 } catch (NullPointerException expected) { 112 } 113 } 114 115 public void testCopyOf_imap_empty() { 116 Map<Class<?>, Object> in = Collections.emptyMap(); 117 ClassToInstanceMap<Object> map = ImmutableClassToInstanceMap.copyOf(in); 118 assertTrue(map.isEmpty()); 119 } 120 121 public void testCopyOf_imap_valid() { 122 ImmutableMap<Class<? extends Number>, ? extends Number> in 123 = ImmutableMap.of(Number.class, 0, Double.class, Math.PI); 124 ClassToInstanceMap<Number> map = ImmutableClassToInstanceMap.copyOf(in); 125 assertEquals(2, map.size()); 126 127 Number zero = map.getInstance(Number.class); 128 assertEquals(0, zero); 129 130 Double pi = map.getInstance(Double.class); 131 assertEquals(Math.PI, pi, 0.0); 132 } 133 134 public void testPrimitiveAndWrapper() { 135 ImmutableClassToInstanceMap<Number> ictim 136 = new ImmutableClassToInstanceMap.Builder<Number>() 137 .put(Integer.class, 0) 138 .put(int.class, 1) 139 .build(); 140 assertEquals(2, ictim.size()); 141 142 assertEquals(0, (int) ictim.getInstance(Integer.class)); 143 assertEquals(1, (int) ictim.getInstance(int.class)); 144 } 145 146 abstract static class TestClassToInstanceMapGenerator 147 implements TestMapGenerator<Class, Number> { 148 149 @Override 150 public Class[] createKeyArray(int length) { 151 return new Class[length]; 152 } 153 154 @Override 155 public Number[] createValueArray(int length) { 156 return new Number[length]; 157 } 158 159 @Override 160 public SampleElements<Entry<Class, Number>> samples() { 161 Entry<Class, Number> entry1 = 162 Maps.immutableEntry((Class) Integer.class, (Number) 0); 163 Entry<Class, Number> entry2 = 164 Maps.immutableEntry((Class) Number.class, (Number) 1); 165 Entry<Class, Number> entry3 = 166 Maps.immutableEntry((Class) Double.class, (Number) 2.0); 167 Entry<Class, Number> entry4 = 168 Maps.immutableEntry((Class) Byte.class, (Number) (byte) 0x03); 169 Entry<Class, Number> entry5 = 170 Maps.immutableEntry((Class) Long.class, (Number) 0x0FF1C1AL); 171 return new SampleElements<Entry<Class, Number>>( 172 entry1, entry2, entry3, entry4, entry5 173 ); 174 } 175 176 @Override 177 @SuppressWarnings("unchecked") 178 public Entry<Class, Number>[] createArray(int length) { 179 return new Entry[length]; 180 } 181 182 @Override 183 public Iterable<Entry<Class, Number>> order( 184 List<Entry<Class, Number>> insertionOrder) { 185 return insertionOrder; 186 } 187 } 188 } 189