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      public UnmodifiableMultiValuedMapTest() {
47          super(UnmodifiableMultiValuedMapTest.class.getSimpleName());
48      }
49  
50      /**
51       * Asserts the given map contains all added values after it was initialized
52       * with makeFullMap(). See COLLECTIONS-769.
53       *
54       * @param map the MultiValuedMap<K, V> to check
55       */
56      private void assertMapContainsAllValues(final MultiValuedMap<K, V> map) {
57          final int maxK = getSampleKeySize();
58          final int cpk = getSampleCountPerKey();
59          for (int k = 0; k < maxK; k++) {
60              final K key = makeKey(k);
61              final Collection<V> collection = map.get((K) key);
62              assertEquals(cpk, collection.size());
63              final String toString = collection.toString();
64              final List<V> expected = new ArrayList<>(cpk);
65              for (int j = 0; j < cpk; j++) {
66                  expected.add(makeValue(k, j));
67              }
68              assertEquals(expected.size(), collection.size());
69              assertEquals(expected, new ArrayList<>(collection));
70              assertEquals(expected.toString(), toString);
71          }
72      }
73  
74      @Override
75      protected int getIterationBehaviour() {
76          return AbstractCollectionTest.UNORDERED;
77      }
78  
79      @Override
80      public boolean isAddSupported() {
81          return false;
82      }
83  
84      @Override
85      public boolean isRemoveSupported() {
86          return false;
87      }
88  
89      @Override
90      protected MultiValuedMap<K, V> makeFullMap() {
91          final MultiValuedMap<K, V> map = new ArrayListValuedHashMap<>();
92          addSampleMappings(map);
93          return UnmodifiableMultiValuedMap.<K, V>unmodifiableMultiValuedMap(map);
94      }
95  
96      @Override
97      public MultiValuedMap<K, V> makeObject() {
98          return UnmodifiableMultiValuedMap.<K, V>unmodifiableMultiValuedMap(
99                  new ArrayListValuedHashMap<>());
100     }
101 
102     @Test
103     @SuppressWarnings("unchecked")
104     public void testAddException() {
105         final MultiValuedMap<K, V> map = makeObject();
106         assertThrows(UnsupportedOperationException.class, () -> map.put((K) "one", (V) "uno"));
107     }
108 
109     @Test
110     public void testClearException() {
111         final MultiValuedMap<K, V> map = makeFullMap();
112         assertThrows(UnsupportedOperationException.class, () -> map.clear(),
113                 "expected, not support clear() method UnmodifiableMultiValuedMap does not support change");
114         this.assertMapContainsAllValues(map);
115     }
116 
117     @Test
118     public void testDecorateFactory() {
119         final MultiValuedMap<K, V> map = makeFullMap();
120         assertSame(map, UnmodifiableMultiValuedMap.unmodifiableMultiValuedMap(map));
121     }
122 
123     @Test
124     public void testDecoratorFactoryNullMap() {
125         assertThrows(NullPointerException.class, () -> UnmodifiableMultiValuedMap.unmodifiableMultiValuedMap(null),
126                 "map must not be null");
127     }
128 
129     @Test
130     public void testPutAllException() {
131         final MultiValuedMap<K, V> map = makeObject();
132         final MultiValuedMap<K, V> original = new ArrayListValuedHashMap<>();
133         final Map<K, V> originalMap = new HashMap<>();
134         final Collection<V> coll = (Collection<V>) Arrays.asList("X", "Y", "Z");
135         original.put((K) "key", (V) "object1");
136         original.put((K) "key", (V) "object2");
137         originalMap.put((K) "keyX", (V) "object1");
138         originalMap.put((K) "keyY", (V) "object2");
139 
140         assertThrows(UnsupportedOperationException.class, () -> map.putAll(original),
141                 "expected, not support putAll() method UnmodifiableMultiValuedMap does not support change");
142         assertEquals("{}", map.toString());
143 
144         assertThrows(UnsupportedOperationException.class, () -> map.putAll(originalMap));
145         assertEquals("{}", map.toString());
146 
147         assertThrows(UnsupportedOperationException.class, () -> map.putAll((K) "A", coll));
148         assertEquals("{}", map.toString());
149     }
150 
151     @Test
152     public void testRemoveException() {
153         final MultiValuedMap<K, V> map = makeFullMap();
154         assertThrows(UnsupportedOperationException.class, () -> map.remove("one"),
155                 "not support remove() method UnmodifiableMultiValuedMap does not support change");
156         this.assertMapContainsAllValues(map);
157     }
158 
159     @Test
160     public void testRemoveMappingException() {
161         final MultiValuedMap<K, V> map = makeFullMap();
162         assertThrows(UnsupportedOperationException.class, () -> map.removeMapping("one", "uno"),
163                 "expected, not support removeMapping() method UnmodifiableMultiValuedMap does not support change");
164         this.assertMapContainsAllValues(map);
165     }
166 
167     @Test
168     public void testUnmodifiable() {
169         assertTrue(makeObject() instanceof Unmodifiable);
170         assertTrue(makeFullMap() instanceof Unmodifiable);
171     }
172 
173     @Test
174     @SuppressWarnings("unchecked")
175     public void testUnmodifiableAsMap() {
176         resetFull();
177         final Map<K, Collection<V>> mapCol = getMap().asMap();
178         assertThrows(UnsupportedOperationException.class, () -> mapCol.put((K) "four", (Collection<V>) Arrays.asList("four")));
179 
180         assertThrows(UnsupportedOperationException.class, () -> mapCol.remove("four"));
181 
182         assertThrows(UnsupportedOperationException.class, () -> mapCol.clear());
183 
184         assertThrows(UnsupportedOperationException.class, () -> mapCol.clear());
185     }
186 
187     @Test
188     @SuppressWarnings("unchecked")
189     public void testUnmodifiableEntries() {
190         resetFull();
191         final Collection<Entry<K, V>> entries = getMap().entries();
192         assertThrows(UnsupportedOperationException.class, () -> entries.clear());
193 
194         final Iterator<Entry<K, V>> it = entries.iterator();
195         final Entry<K, V> entry = it.next();
196         assertThrows(UnsupportedOperationException.class, () -> it.remove());
197 
198         assertThrows(UnsupportedOperationException.class, () -> entry.setValue((V) "three"));
199     }
200 
201     @Test
202     @SuppressWarnings("unchecked")
203     public void testUnmodifiableKeys() {
204         resetFull();
205         final MultiSet<K> keys = getMap().keys();
206         assertThrows(UnsupportedOperationException.class, () -> keys.add((K) "four"));
207 
208         assertThrows(UnsupportedOperationException.class, () -> keys.remove("four"));
209 
210         assertThrows(UnsupportedOperationException.class, () -> keys.clear());
211 
212         final Iterator<K> it = keys.iterator();
213         assertThrows(UnsupportedOperationException.class, () -> it.remove());
214     }
215 
216     @Test
217     @SuppressWarnings("unchecked")
218     public void testUnmodifiableKeySet() {
219         resetFull();
220         final Set<K> keySet = getMap().keySet();
221         assertThrows(UnsupportedOperationException.class, () -> keySet.add((K) "four"));
222 
223         assertThrows(UnsupportedOperationException.class, () -> keySet.remove("four"));
224 
225         assertThrows(UnsupportedOperationException.class, () -> keySet.clear());
226 
227         final Iterator<K> it = keySet.iterator();
228         assertThrows(UnsupportedOperationException.class, () -> it.remove());
229     }
230 
231     @Test
232     @SuppressWarnings("unchecked")
233     public void testUnmodifiableMapIterator() {
234         resetFull();
235         final MapIterator<K, V> mapIt = getMap().mapIterator();
236         assertThrows(UnsupportedOperationException.class, () -> mapIt.remove());
237 
238         assertThrows(UnsupportedOperationException.class, () -> mapIt.setValue((V) "three"));
239     }
240 
241     @Test
242     @SuppressWarnings("unchecked")
243     public void testUnmodifiableValues() {
244         resetFull();
245         final Collection<V> values = getMap().values();
246         assertThrows(UnsupportedOperationException.class, () -> values.add((V) "four"));
247 
248         assertThrows(UnsupportedOperationException.class, () -> values.remove("four"));
249 
250         assertThrows(UnsupportedOperationException.class, () -> values.clear());
251 
252         final Iterator<V> it = values.iterator();
253         assertThrows(UnsupportedOperationException.class, () -> it.remove());
254     }
255 
256 //    public void testCreate() throws Exception {
257 //        writeExternalFormToDisk((java.io.Serializable) makeObject(),
258 //                "src/test/resources/data/test/UnmodifiableMultiValuedMap.emptyCollection.version4.1.obj");
259 //        writeExternalFormToDisk((java.io.Serializable) makeFullMap(),
260 //                "src/test/resources/data/test/UnmodifiableMultiValuedMap.fullCollection.version4.1.obj");
261 //    }
262 
263 }