From c62fbea2ba09c81bc1219c0a4b2e0987e2323828 Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Thu, 11 Dec 2014 15:55:41 +0100 Subject: [PATCH] Demonstrate that the CollectionFactory API is not type-safe This commit introduces test methods in CollectionFactoryTests that demonstrate how the APIs for createCollection() and createMap() are not type-safe, specifically regarding the use of generics, raw types, and casting. --- .../core/CollectionFactoryTests.java | 62 +++++++++++++++++-- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java b/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java index fe8e8b55d3f..fb93162fa96 100644 --- a/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java +++ b/spring-core/src/test/java/org/springframework/core/CollectionFactoryTests.java @@ -63,7 +63,7 @@ public class CollectionFactoryTests { * actually contains elements of type {@code E}. */ @Test - public void createApproximateCollectionIsNotTypeSafe() { + public void createApproximateCollectionIsNotTypeSafeForEnumSet() { Collection ints = createApproximateCollection(EnumSet.of(Color.BLUE), 3); // Use a try-catch block to ensure that the exception is thrown as a result of the @@ -80,6 +80,24 @@ public class CollectionFactoryTests { } } + @Test + public void createCollectionIsNotTypeSafeForEnumSet() { + Collection ints = createCollection(EnumSet.class, Color.class, 3); + + // Use a try-catch block to ensure that the exception is thrown as a result of the + // next line and not as a result of the previous line. + try { + // Note that ints is of type Collection, but the collection returned + // by createCollection() is of type Collection. Thus, 42 cannot be cast + // to a Color. + ints.add(42); + fail("Should have thrown a ClassCastException"); + } + catch (ClassCastException e) { + /* expected */ + } + } + /** * The test demonstrates that the generics-based API for * {@link CollectionFactory#createApproximateMap(Object, int)} @@ -88,7 +106,7 @@ public class CollectionFactoryTests { * {@link #createApproximateCollectionIsNotTypeSafe()}. */ @Test - public void createApproximateMapIsNotTypeSafe() { + public void createApproximateMapIsNotTypeSafeForEnumMap() { EnumMap enumMap = new EnumMap<>(Color.class); enumMap.put(Color.RED, 1); enumMap.put(Color.BLUE, 2); @@ -97,8 +115,26 @@ public class CollectionFactoryTests { // Use a try-catch block to ensure that the exception is thrown as a result of the // next line and not as a result of the previous line. try { - // Note that the 'map' key is of type String, but the keys in the map returned - // by createApproximateMap() are of type Color. Thus "foo" cannot be cast to a + // Note that the 'map' key must be of type String, but the keys in the map + // returned by createApproximateMap() are of type Color. Thus "foo" cannot be + // cast to a Color. + map.put("foo", 1); + fail("Should have thrown a ClassCastException"); + } + catch (ClassCastException e) { + /* expected */ + } + } + + @Test + public void createMapIsNotTypeSafeForEnumMap() { + Map map = createMap(EnumMap.class, Color.class, 3); + + // Use a try-catch block to ensure that the exception is thrown as a result of the + // next line and not as a result of the previous line. + try { + // Note that the 'map' key must be of type String, but the keys in the map + // returned by createMap() are of type Color. Thus "foo" cannot be cast to a // Color. map.put("foo", 1); fail("Should have thrown a ClassCastException"); @@ -108,6 +144,24 @@ public class CollectionFactoryTests { } } + @Test + public void createMapIsNotTypeSafeForLinkedMultiValueMap() { + Map map = createMap(MultiValueMap.class, null, 3); + + // Use a try-catch block to ensure that the exception is thrown as a result of the + // next line and not as a result of the previous line. + try { + // Note: 'map' values must be of type Integer, but the values in the map + // returned by createMap() are of type java.util.List. Thus 1 cannot be + // cast to a List. + map.put("foo", 1); + fail("Should have thrown a ClassCastException"); + } + catch (ClassCastException e) { + /* expected */ + } + } + @Test public void createApproximateCollectionFromEmptyHashSet() { Collection set = createApproximateCollection(new HashSet(), 2);