View Javadoc
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.Maps;
23  import com.google.common.collect.testing.MapTestSuiteBuilder;
24  import com.google.common.collect.testing.SampleElements;
25  import com.google.common.collect.testing.TestMapGenerator;
26  import com.google.common.collect.testing.features.CollectionFeature;
27  import com.google.common.collect.testing.features.CollectionSize;
28  import com.google.common.collect.testing.features.MapFeature;
29  
30  import junit.framework.Test;
31  import junit.framework.TestCase;
32  import junit.framework.TestSuite;
33  
34  import java.util.List;
35  import java.util.Map;
36  import java.util.Map.Entry;
37  
38  /**
39   * Unit test for {@link ImmutableTypeToInstanceMap}.
40   *
41   * @author Ben Yu
42   */
43  public class ImmutableTypeToInstanceMapTest extends TestCase {
44  
45    public static Test suite() {
46      TestSuite suite = new TestSuite();
47      suite.addTestSuite(ImmutableTypeToInstanceMapTest.class);
48  
49      suite.addTest(MapTestSuiteBuilder
50          .using(new TestTypeToInstanceMapGenerator() {
51            // Other tests will verify what real, warning-free usage looks like
52            // but here we have to do some serious fudging
53            @Override
54            @SuppressWarnings("unchecked")
55            public Map<TypeToken, Object> create(Object... elements) {
56              ImmutableTypeToInstanceMap.Builder<Object> builder
57                  = ImmutableTypeToInstanceMap.builder();
58              for (Object object : elements) {
59                Entry<TypeToken, Object> entry = (Entry<TypeToken, Object>) object;
60                builder.put(entry.getKey(), entry.getValue());
61              }
62              return (Map) builder.build();
63            }
64          })
65          .named("ImmutableTypeToInstanceMap")
66          .withFeatures(
67              MapFeature.REJECTS_DUPLICATES_AT_CREATION,
68              MapFeature.RESTRICTS_KEYS,
69              CollectionFeature.KNOWN_ORDER,
70              CollectionSize.ANY,
71              MapFeature.ALLOWS_ANY_NULL_QUERIES)
72          .createTestSuite());
73  
74      return suite;
75    }
76  
77    public void testEmpty() {
78      assertEquals(0, ImmutableTypeToInstanceMap.of().size());
79    }
80  
81    public void testPrimitiveAndWrapper() {
82      ImmutableTypeToInstanceMap<Number> map = ImmutableTypeToInstanceMap.<Number>builder()
83          .put(Integer.class, 0)
84          .put(int.class, 1)
85          .build();
86      assertEquals(2, map.size());
87  
88      assertEquals(0, (int) map.getInstance(Integer.class));
89      assertEquals(0, (int) map.getInstance(TypeToken.of(Integer.class)));
90      assertEquals(1, (int) map.getInstance(int.class));
91      assertEquals(1, (int) map.getInstance(TypeToken.of(int.class)));
92    }
93  
94    public void testParameterizedType() {
95      TypeToken<ImmutableList<Integer>> type = new TypeToken<ImmutableList<Integer>>() {};
96      ImmutableTypeToInstanceMap<Iterable<?>> map = ImmutableTypeToInstanceMap.<Iterable<?>>builder()
97          .put(type, ImmutableList.of(1))
98          .build();
99      assertEquals(1, map.size());
100     assertEquals(ImmutableList.of(1), map.getInstance(type));
101   }
102 
103   public void testGeneriArrayType() {
104     @SuppressWarnings("unchecked") // Trying to test generic array
105     ImmutableList<Integer>[] array = new ImmutableList[] {ImmutableList.of(1)};
106     TypeToken<ImmutableList<Integer>[]> type = new TypeToken<ImmutableList<Integer>[]>() {};
107     ImmutableTypeToInstanceMap<Iterable<?>[]> map =
108         ImmutableTypeToInstanceMap.<Iterable<?>[]>builder()
109             .put(type, array)
110             .build();
111     assertEquals(1, map.size());
112     assertThat(map.getInstance(type)).asList().has().exactly(array[0]).inOrder();
113   }
114 
115   public void testWildcardType() {
116     TypeToken<ImmutableList<?>> type = new TypeToken<ImmutableList<?>>() {};
117     ImmutableTypeToInstanceMap<Iterable<?>> map = ImmutableTypeToInstanceMap.<Iterable<?>>builder()
118             .put(type, ImmutableList.of(1))
119             .build();
120     assertEquals(1, map.size());
121     assertEquals(ImmutableList.of(1), map.getInstance(type));
122   }
123 
124   public void testGetInstance_containsTypeVariable() {
125     ImmutableTypeToInstanceMap<Iterable<Number>> map = ImmutableTypeToInstanceMap.of();
126     try {
127       map.getInstance(this.<Number>anyIterableType());
128       fail();
129     } catch (IllegalArgumentException expected) {}
130   }
131 
132   public void testPut_containsTypeVariable() {
133     ImmutableTypeToInstanceMap.Builder<Iterable<Integer>> builder =
134         ImmutableTypeToInstanceMap.builder();
135     try {
136       builder.put(this.<Integer>anyIterableType(), ImmutableList.of(1));
137       fail();
138     } catch (IllegalArgumentException expected) {}
139   }
140 
141   private <T> TypeToken<Iterable<T>> anyIterableType() {
142     return new TypeToken<Iterable<T>>() {};
143   }
144 
145   abstract static class TestTypeToInstanceMapGenerator
146       implements TestMapGenerator<TypeToken, Object> {
147 
148     @Override public TypeToken[] createKeyArray(int length) {
149       return new TypeToken[length];
150     }
151 
152     @Override public Object[] createValueArray(int length) {
153       return new Object[length];
154     }
155 
156     @Override
157     public SampleElements<Entry<TypeToken, Object>> samples() {
158       Entry<TypeToken, Object> entry1 =
159           Maps.immutableEntry((TypeToken) TypeToken.of(Integer.class), (Object) 0);
160       Entry<TypeToken, Object> entry2 =
161           Maps.immutableEntry((TypeToken) TypeToken.of(Number.class), (Object) 1);
162       Entry<TypeToken, Object> entry3 =
163           Maps.immutableEntry((TypeToken) new TypeToken<ImmutableList<Integer>>() {},
164               (Object) ImmutableList.of(2));
165       Entry<TypeToken, Object> entry4 =
166           Maps.immutableEntry((TypeToken) new TypeToken<int[]>() {}, (Object) new int[] {3});
167       Entry<TypeToken, Object> entry5 =
168           Maps.immutableEntry((TypeToken) new TypeToken<Iterable<?>>() {},
169               (Object) ImmutableList.of("4"));
170       return new SampleElements<Entry<TypeToken, Object>>(
171           entry1, entry2, entry3, entry4, entry5
172       );
173     }
174 
175     @Override
176     @SuppressWarnings("unchecked")
177     public Entry<TypeToken, Object>[] createArray(int length) {
178       return new Entry[length];
179     }
180 
181     @Override
182     public Iterable<Entry<TypeToken, Object>> order(List<Entry<TypeToken, Object>> insertionOrder) {
183       return insertionOrder;
184     }
185   }
186 }