View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4.multimap;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertSame;
21  import static org.junit.jupiter.api.Assertions.assertThrows;
22  import static org.junit.jupiter.api.Assertions.assertTrue;
23  
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Collection;
27  import java.util.HashMap;
28  import java.util.Iterator;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.Map.Entry;
32  import java.util.Set;
33  
34  import org.apache.commons.collections4.MapIterator;
35  import org.apache.commons.collections4.MultiSet;
36  import org.apache.commons.collections4.MultiValuedMap;
37  import org.apache.commons.collections4.Unmodifiable;
38  import org.apache.commons.collections4.collection.AbstractCollectionTest;
39  import org.junit.jupiter.api.Test;
40  
41  /**
42   * Tests {@link UnmodifiableMultiValuedMap}.
43   */
44  public class UnmodifiableMultiValuedMapTest<K, V> extends AbstractMultiValuedMapTest<K, V> {
45  
46      /**
47       * Asserts the given map contains all added values after it was initialized
48       * with makeFullMap(). See COLLECTIONS-769.
49       *
50       * @param map the MultiValuedMap<K, V> to check
51       */
52      private void assertMapContainsAllValues(final MultiValuedMap<K, V> map) {
53          final int maxK = getSampleKeySize();
54          final int cpk = getSampleCountPerKey();
55          for (int k = 0; k < maxK; k++) {
56              final K key = makeKey(k);
57              final Collection<V> collection = map.get(key);
58              assertEquals(cpk, collection.size());
59              final String toString = collection.toString();
60              final List<V> expected = new ArrayList<>(cpk);
61              for (int j = 0; j < cpk; j++) {
62                  expected.add(makeValue(k, j));
63              }
64              assertEquals(expected.size(), collection.size());
65              assertEquals(expected, new ArrayList<>(collection));
66              assertEquals(expected.toString(), toString);
67          }
68      }
69  
70      @Override
71      protected int getIterationBehaviour() {
72          return AbstractCollectionTest.UNORDERED;
73      }
74  
75      @Override
76      public boolean isAddSupported() {
77          return false;
78      }
79  
80      @Override
81      public boolean isRemoveSupported() {
82          return false;
83      }
84  
85      @Override
86      protected MultiValuedMap<K, V> makeFullMap() {
87          final MultiValuedMap<K, V> map = new ArrayListValuedHashMap<>();
88          addSampleMappings(map);
89          return UnmodifiableMultiValuedMap.<K, V>unmodifiableMultiValuedMap(map);
90      }
91  
92      @Override
93      public MultiValuedMap<K, V> makeObject() {
94          return UnmodifiableMultiValuedMap.<K, V>unmodifiableMultiValuedMap(
95                  new ArrayListValuedHashMap<>());
96      }
97  
98      @Test
99      @SuppressWarnings("unchecked")
100     public void testAddException() {
101         final MultiValuedMap<K, V> map = makeObject();
102         assertThrows(UnsupportedOperationException.class, () -> map.put((K) "one", (V) "uno"));
103     }
104 
105     @Test
106     public void testClearException() {
107         final MultiValuedMap<K, V> map = makeFullMap();
108         assertThrows(UnsupportedOperationException.class, () -> map.clear(),
109                 "expected, not support clear() method UnmodifiableMultiValuedMap does not support change");
110         this.assertMapContainsAllValues(map);
111     }
112 
113     @Test
114     public void testDecorateFactory() {
115         final MultiValuedMap<K, V> map = makeFullMap();
116         assertSame(map, UnmodifiableMultiValuedMap.unmodifiableMultiValuedMap(map));
117     }
118 
119     @Test
120     public void testDecoratorFactoryNullMap() {
121         assertThrows(NullPointerException.class, () -> UnmodifiableMultiValuedMap.unmodifiableMultiValuedMap(null),
122                 "map must not be null");
123     }
124 
125     @Test
126     public void testPutAllException() {
127         final MultiValuedMap<K, V> map = makeObject();
128         final MultiValuedMap<K, V> original = new ArrayListValuedHashMap<>();
129         final Map<K, V> originalMap = new HashMap<>();
130         final Collection<V> coll = (Collection<V>) Arrays.asList("X", "Y", "Z");
131         original.put((K) "key", (V) "object1");
132         original.put((K) "key", (V) "object2");
133         originalMap.put((K) "keyX", (V) "object1");
134         originalMap.put((K) "keyY", (V) "object2");
135 
136         assertThrows(UnsupportedOperationException.class, () -> map.putAll(original),
137                 "expected, not support putAll() method UnmodifiableMultiValuedMap does not support change");
138         assertEquals("{}", map.toString());
139 
140         assertThrows(UnsupportedOperationException.class, () -> map.putAll(originalMap));
141         assertEquals("{}", map.toString());
142 
143         assertThrows(UnsupportedOperationException.class, () -> map.putAll((K) "A", coll));
144         assertEquals("{}", map.toString());
145     }
146 
147     @Test
148     public void testRemoveException() {
149         final MultiValuedMap<K, V> map = makeFullMap();
150         assertThrows(UnsupportedOperationException.class, () -> map.remove("one"),
151                 "not support remove() method UnmodifiableMultiValuedMap does not support change");
152         this.assertMapContainsAllValues(map);
153     }
154 
155     @Test
156     public void testRemoveMappingException() {
157         final MultiValuedMap<K, V> map = makeFullMap();
158         assertThrows(UnsupportedOperationException.class, () -> map.removeMapping("one", "uno"),
159                 "expected, not support removeMapping() method UnmodifiableMultiValuedMap does not support change");
160         this.assertMapContainsAllValues(map);
161     }
162 
163     @Test
164     public void testUnmodifiable() {
165         assertTrue(makeObject() instanceof Unmodifiable);
166         assertTrue(makeFullMap() instanceof Unmodifiable);
167     }
168 
169     @Test
170     @SuppressWarnings("unchecked")
171     public void testUnmodifiableAsMap() {
172         resetFull();
173         final Map<K, Collection<V>> mapCol = getMap().asMap();
174         assertThrows(UnsupportedOperationException.class, () -> mapCol.put((K) "four", (Collection<V>) Arrays.asList("four")));
175 
176         assertThrows(UnsupportedOperationException.class, () -> mapCol.remove("four"));
177 
178         assertThrows(UnsupportedOperationException.class, () -> mapCol.clear());
179 
180         assertThrows(UnsupportedOperationException.class, () -> mapCol.clear());
181     }
182 
183     @Test
184     @SuppressWarnings("unchecked")
185     public void testUnmodifiableEntries() {
186         resetFull();
187         final Collection<Entry<K, V>> entries = getMap().entries();
188         assertThrows(UnsupportedOperationException.class, () -> entries.clear());
189 
190         final Iterator<Entry<K, V>> it = entries.iterator();
191         final Entry<K, V> entry = it.next();
192         assertThrows(UnsupportedOperationException.class, () -> it.remove());
193 
194         assertThrows(UnsupportedOperationException.class, () -> entry.setValue((V) "three"));
195     }
196 
197     @Test
198     @SuppressWarnings("unchecked")
199     public void testUnmodifiableKeys() {
200         resetFull();
201         final MultiSet<K> keys = getMap().keys();
202         assertThrows(UnsupportedOperationException.class, () -> keys.add((K) "four"));
203 
204         assertThrows(UnsupportedOperationException.class, () -> keys.remove("four"));
205 
206         assertThrows(UnsupportedOperationException.class, () -> keys.clear());
207 
208         final Iterator<K> it = keys.iterator();
209         assertThrows(UnsupportedOperationException.class, () -> it.remove());
210     }
211 
212     @Test
213     @SuppressWarnings("unchecked")
214     public void testUnmodifiableKeySet() {
215         resetFull();
216         final Set<K> keySet = getMap().keySet();
217         assertThrows(UnsupportedOperationException.class, () -> keySet.add((K) "four"));
218 
219         assertThrows(UnsupportedOperationException.class, () -> keySet.remove("four"));
220 
221         assertThrows(UnsupportedOperationException.class, () -> keySet.clear());
222 
223         final Iterator<K> it = keySet.iterator();
224         assertThrows(UnsupportedOperationException.class, () -> it.remove());
225     }
226 
227     @Test
228     @SuppressWarnings("unchecked")
229     public void testUnmodifiableMapIterator() {
230         resetFull();
231         final MapIterator<K, V> mapIt = getMap().mapIterator();
232         assertThrows(UnsupportedOperationException.class, () -> mapIt.remove());
233 
234         assertThrows(UnsupportedOperationException.class, () -> mapIt.setValue((V) "three"));
235     }
236 
237     @Test
238     @SuppressWarnings("unchecked")
239     public void testUnmodifiableValues() {
240         resetFull();
241         final Collection<V> values = getMap().values();
242         assertThrows(UnsupportedOperationException.class, () -> values.add((V) "four"));
243 
244         assertThrows(UnsupportedOperationException.class, () -> values.remove("four"));
245 
246         assertThrows(UnsupportedOperationException.class, () -> values.clear());
247 
248         final Iterator<V> it = values.iterator();
249         assertThrows(UnsupportedOperationException.class, () -> it.remove());
250     }
251 
252 //    public void testCreate() throws Exception {
253 //        writeExternalFormToDisk((java.io.Serializable) makeObject(),
254 //                "src/test/resources/data/test/UnmodifiableMultiValuedMap.emptyCollection.version4.1.obj");
255 //        writeExternalFormToDisk((java.io.Serializable) makeFullMap(),
256 //                "src/test/resources/data/test/UnmodifiableMultiValuedMap.fullCollection.version4.1.obj");
257 //    }
258 
259 }