Home | History | Annotate | Download | only in reflect
      1 /*
      2  * Copyright (C) 2012 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.reflect;
     18 
     19 import static com.google.common.truth.Truth.assertThat;
     20 
     21 import com.google.common.collect.ImmutableList;
     22 import com.google.common.collect.ImmutableMap;
     23 import com.google.common.collect.testing.MapTestSuiteBuilder;
     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.collect.testing.testers.MapPutTester;
     28 import com.google.common.reflect.ImmutableTypeToInstanceMapTest.TestTypeToInstanceMapGenerator;
     29 
     30 import junit.framework.Test;
     31 import junit.framework.TestCase;
     32 import junit.framework.TestSuite;
     33 
     34 import java.lang.reflect.Method;
     35 import java.util.Map;
     36 import java.util.Map.Entry;
     37 
     38 /**
     39  * Unit test of {@link MutableTypeToInstanceMap}.
     40  *
     41  * @author Ben Yu
     42  */
     43 public class MutableTypeToInstanceMapTest extends TestCase {
     44 
     45   public static Test suite() {
     46     TestSuite suite = new TestSuite();
     47     suite.addTestSuite(MutableTypeToInstanceMapTest.class);
     48 
     49     // Suppress this one because the tester framework doesn't understand that
     50     // *some* remappings will be allowed and others not.
     51     Method remapTest = null;
     52     try {
     53       remapTest = MapPutTester.class.getMethod(
     54           "testPut_replaceNullValueWithNonNullSupported");
     55     } catch (NoSuchMethodException e) {
     56       throw new AssertionError();
     57     }
     58 
     59     suite.addTest(MapTestSuiteBuilder
     60         .using(new TestTypeToInstanceMapGenerator() {
     61           // Other tests will verify what real, warning-free usage looks like
     62           // but here we have to do some serious fudging
     63           @Override
     64           @SuppressWarnings("unchecked")
     65           public Map<TypeToken, Object> create(Object... elements) {
     66             MutableTypeToInstanceMap<Object> map
     67                 = new MutableTypeToInstanceMap<Object>();
     68             for (Object object : elements) {
     69               Entry<TypeToken, Object> entry = (Entry<TypeToken, Object>) object;
     70               map.putInstance(entry.getKey(), entry.getValue());
     71             }
     72             return (Map) map;
     73           }
     74         })
     75         .named("MutableTypeToInstanceMap")
     76         .withFeatures(
     77             MapFeature.SUPPORTS_REMOVE,
     78             MapFeature.RESTRICTS_KEYS,
     79             MapFeature.ALLOWS_NULL_VALUES,
     80             CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
     81             CollectionSize.ANY,
     82             MapFeature.ALLOWS_ANY_NULL_QUERIES)
     83         .suppressing(remapTest)
     84         .createTestSuite());
     85 
     86     return suite;
     87   }
     88 
     89   private TypeToInstanceMap<Object> map;
     90 
     91   @Override protected void setUp() throws Exception {
     92     map = new MutableTypeToInstanceMap<Object>();
     93   }
     94 
     95   public void testPutThrows() {
     96     try {
     97       map.put(TypeToken.of(Integer.class), new Integer(5));
     98       fail();
     99     } catch (UnsupportedOperationException expected) {}
    100   }
    101 
    102   public void testPutAllThrows() {
    103     try {
    104       map.putAll(ImmutableMap.of(TypeToken.of(Integer.class), new Integer(5)));
    105       fail();
    106     } catch (UnsupportedOperationException expected) {}
    107   }
    108 
    109   public void testEntrySetMutationThrows() {
    110     map.putInstance(String.class, "test");
    111     assertEquals(TypeToken.of(String.class), map.entrySet().iterator().next().getKey());
    112     assertEquals("test", map.entrySet().iterator().next().getValue());
    113     try {
    114       map.entrySet().iterator().next().setValue(1);
    115       fail();
    116     } catch (UnsupportedOperationException expected) {}
    117   }
    118 
    119   public void testEntrySetToArrayMutationThrows() {
    120     map.putInstance(String.class, "test");
    121     @SuppressWarnings("unchecked") // Should get a CCE later if cast is wrong
    122     Entry<Object, Object> entry = (Entry<Object, Object>) map.entrySet().toArray()[0];
    123     assertEquals(TypeToken.of(String.class), entry.getKey());
    124     assertEquals("test", entry.getValue());
    125     try {
    126       entry.setValue(1);
    127       fail();
    128     } catch (UnsupportedOperationException expected) {}
    129   }
    130 
    131   public void testEntrySetToTypedArrayMutationThrows() {
    132     map.putInstance(String.class, "test");
    133     @SuppressWarnings("unchecked") // Should get a CCE later if cast is wrong
    134     Entry<Object, Object> entry = map.entrySet().toArray(new Entry[0])[0];
    135     assertEquals(TypeToken.of(String.class), entry.getKey());
    136     assertEquals("test", entry.getValue());
    137     try {
    138       entry.setValue(1);
    139       fail();
    140     } catch (UnsupportedOperationException expected) {}
    141   }
    142 
    143   public void testPutAndGetInstance() {
    144     assertNull(map.putInstance(Integer.class, new Integer(5)));
    145 
    146     Integer oldValue = map.putInstance(Integer.class, new Integer(7));
    147     assertEquals(5, (int) oldValue);
    148 
    149     Integer newValue = map.getInstance(Integer.class);
    150     assertEquals(7, (int) newValue);
    151     assertEquals(7, (int) map.getInstance(TypeToken.of(Integer.class)));
    152 
    153     // Won't compile: map.putInstance(Double.class, new Long(42));
    154   }
    155 
    156   public void testNull() {
    157     try {
    158       map.putInstance((TypeToken) null, new Integer(1));
    159       fail();
    160     } catch (NullPointerException expected) {
    161     }
    162     map.putInstance(Integer.class, null);
    163     assertNull(map.get(Integer.class));
    164     assertNull(map.getInstance(Integer.class));
    165 
    166     map.putInstance(Long.class, null);
    167     assertNull(map.get(Long.class));
    168     assertNull(map.getInstance(Long.class));
    169   }
    170 
    171   public void testPrimitiveAndWrapper() {
    172     assertNull(map.getInstance(int.class));
    173     assertNull(map.getInstance(Integer.class));
    174 
    175     assertNull(map.putInstance(int.class, 0));
    176     assertNull(map.putInstance(Integer.class, 1));
    177     assertEquals(2, map.size());
    178 
    179     assertEquals(0, (int) map.getInstance(int.class));
    180     assertEquals(1, (int) map.getInstance(Integer.class));
    181 
    182     assertEquals(0, (int) map.putInstance(int.class, null));
    183     assertEquals(1, (int) map.putInstance(Integer.class, null));
    184 
    185     assertNull(map.getInstance(int.class));
    186     assertNull(map.getInstance(Integer.class));
    187     assertEquals(2, map.size());
    188   }
    189 
    190   public void testParameterizedType() {
    191     TypeToken<ImmutableList<Integer>> type = new TypeToken<ImmutableList<Integer>>() {};
    192     map.putInstance(type, ImmutableList.of(1));
    193     assertEquals(1, map.size());
    194     assertEquals(ImmutableList.of(1), map.getInstance(type));
    195   }
    196 
    197   public void testGenericArrayType() {
    198     @SuppressWarnings("unchecked") // Trying to test generic array
    199     ImmutableList<Integer>[] array = new ImmutableList[] {ImmutableList.of(1)};
    200     TypeToken<ImmutableList<Integer>[]> type = new TypeToken<ImmutableList<Integer>[]>() {};
    201     map.putInstance(type, array);
    202     assertEquals(1, map.size());
    203     assertThat(map.getInstance(type)).asList().has().exactly(array[0]).inOrder();
    204   }
    205 
    206   public void testWildcardType() {
    207     TypeToken<ImmutableList<?>> type = new TypeToken<ImmutableList<?>>() {};
    208     map.putInstance(type, ImmutableList.of(1));
    209     assertEquals(1, map.size());
    210     assertEquals(ImmutableList.of(1), map.getInstance(type));
    211   }
    212 
    213   public void testGetInstance_withTypeVariable() {
    214     try {
    215       map.getInstance(this.<Number>anyIterableType());
    216       fail();
    217     } catch (IllegalArgumentException expected) {}
    218   }
    219 
    220   public void testPutInstance_withTypeVariable() {
    221     try {
    222       map.putInstance(this.<Integer>anyIterableType(), ImmutableList.of(1));
    223       fail();
    224     } catch (IllegalArgumentException expected) {}
    225   }
    226 
    227   private <T> TypeToken<Iterable<T>> anyIterableType() {
    228     return new TypeToken<Iterable<T>>() {};
    229   }
    230 }
    231