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.map;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNotNull;
22  import static org.junit.jupiter.api.Assertions.assertNull;
23  import static org.junit.jupiter.api.Assertions.assertSame;
24  import static org.junit.jupiter.api.Assertions.assertThrows;
25  
26  import java.util.Comparator;
27  import java.util.HashMap;
28  import java.util.Iterator;
29  import java.util.Map;
30  import java.util.SortedMap;
31  import java.util.TreeMap;
32  import java.util.concurrent.ConcurrentSkipListMap;
33  
34  import org.apache.commons.collections4.Predicate;
35  import org.apache.commons.collections4.functors.TruePredicate;
36  import org.junit.jupiter.api.Test;
37  
38  /**
39   * Extension of {@link PredicatedMapTest} for exercising the
40   * {@link PredicatedSortedMap} implementation.
41   *
42   * @param <K> the key type.
43   * @param <V> the value type.
44   */
45  public class PredicatedSortedMapTest<K, V> extends AbstractSortedMapTest<K, V> {
46  
47      private final class ReverseStringComparator implements Comparator<K> {
48          @Override
49          public int compare(final K arg0, final K arg1) {
50              return ((String) arg1).compareTo((String) arg0);
51          }
52      }
53  
54      protected static final Predicate<Object> truePredicate = TruePredicate.truePredicate();
55  
56      protected static final Predicate<Object> testPredicate = String.class::isInstance;
57  
58      protected final Comparator<K> reverseStringComparator = new ReverseStringComparator();
59  
60      protected SortedMap<K, V> decorateMap(final SortedMap<K, V> map, final Predicate<? super K> keyPredicate,
61          final Predicate<? super V> valuePredicate) {
62          return PredicatedSortedMap.predicatedSortedMap(map, keyPredicate, valuePredicate);
63      }
64  
65      @Override
66      public String getCompatibilityVersion() {
67          return "4";
68      }
69  
70      @Override
71      public boolean isAllowNullKey() {
72          return false;
73      }
74  
75      @Override
76      public boolean isSubMapViewsSerializable() {
77          // TreeMap sub map views have a bug in deserialization.
78          return false;
79      }
80  
81      @Override
82      public SortedMap<K, V> makeObject() {
83          return decorateMap(new TreeMap<>(), truePredicate, truePredicate);
84      }
85  
86      public SortedMap<K, V> makeTestMap() {
87          return decorateMap(new TreeMap<>(), testPredicate, testPredicate);
88      }
89  
90      public SortedMap<K, V> makeTestMapWithComparator() {
91          return decorateMap(new ConcurrentSkipListMap<>(reverseStringComparator), testPredicate, testPredicate);
92      }
93  
94      // from TestPredicatedMap
95      @Test
96      @SuppressWarnings("unchecked")
97      public void testEntrySet() {
98          SortedMap<K, V> map = makeTestMap();
99          assertNotNull(map.entrySet(), "returned entryset should not be null");
100         map = decorateMap(new TreeMap<>(), null, null);
101         map.put((K) "oneKey", (V) "oneValue");
102         assertEquals(1, map.entrySet().size(), "returned entryset should contain one entry");
103         map = decorateMap(map, null, null);
104     }
105 
106     @Test
107     @SuppressWarnings("unchecked")
108     public void testPut() {
109         final Map<K, V> map = makeTestMap();
110         assertThrows(IllegalArgumentException.class, () -> map.put((K) "Hi", (V) Integer.valueOf(3)),
111                 "Illegal value should raise IllegalArgument");
112 
113         assertThrows(IllegalArgumentException.class, () -> map.put((K) Integer.valueOf(3), (V) "Hi"),
114                 "Illegal key should raise IllegalArgument");
115 
116         assertFalse(map.containsKey(Integer.valueOf(3)));
117         assertFalse(map.containsValue(Integer.valueOf(3)));
118 
119         final Map<K, V> map2 = new HashMap<>();
120         map2.put((K) "A", (V) "a");
121         map2.put((K) "B", (V) "b");
122         map2.put((K) "C", (V) "c");
123         map2.put((K) "c", (V) Integer.valueOf(3));
124 
125         assertThrows(IllegalArgumentException.class, () -> map.putAll(map2),
126                 "Illegal value should raise IllegalArgument");
127 
128         map.put((K) "E", (V) "e");
129         Iterator<Map.Entry<K, V>> iterator = map.entrySet().iterator();
130         Map.Entry<K, V> entry = iterator.next();
131         final Map.Entry<K, V> finalEntry = entry;
132         assertThrows(IllegalArgumentException.class, () -> finalEntry.setValue((V) Integer.valueOf(3)),
133                 "Illegal value should raise IllegalArgument");
134 
135         map.put((K) "F", (V) "f");
136         iterator = map.entrySet().iterator();
137         entry = iterator.next();
138         entry.setValue((V) "x");
139 
140     }
141 
142     @Test
143     @SuppressWarnings("unchecked")
144     public void testReverseSortOrder() {
145         final SortedMap<K, V> map = makeTestMapWithComparator();
146         map.put((K) "A",  (V) "a");
147         map.put((K) "B", (V) "b");
148         assertThrows(IllegalArgumentException.class, () -> map.put(null, (V) "c"),
149                 "Null key should raise IllegalArgument");
150         map.put((K) "C", (V) "c");
151         assertThrows(IllegalArgumentException.class, () -> map.put((K) "D", null),
152                 "Null value should raise IllegalArgument");
153         assertEquals("A", map.lastKey(), "Last key should be A");
154         assertEquals("C", map.firstKey(), "First key should be C");
155         assertEquals("B", map.tailMap((K) "B").firstKey(),
156                 "First key in tail map should be B");
157         assertEquals("B", map.headMap((K) "A").lastKey(),
158                 "Last key in head map should be B");
159         assertEquals("B", map.subMap((K) "C", (K) "A").lastKey(),
160                 "Last key in submap should be B");
161 
162         final Comparator<? super K> c = map.comparator();
163         assertSame(c, reverseStringComparator, "reverse order, so comparator should be reverseStringComparator");
164     }
165 
166     @Test
167     @SuppressWarnings("unchecked")
168     public void testSortOrder() {
169         final SortedMap<K, V> map = makeTestMap();
170         map.put((K) "A", (V) "a");
171         map.put((K) "B", (V) "b");
172         assertThrows(IllegalArgumentException.class, () -> map.put(null, (V) "c"),
173                 "Null key should raise IllegalArgument");
174         map.put((K) "C", (V) "c");
175         assertThrows(IllegalArgumentException.class, () -> map.put((K) "D", null),
176                 "Null value should raise IllegalArgument");
177         assertEquals("A", map.firstKey(), "First key should be A");
178         assertEquals("C", map.lastKey(), "Last key should be C");
179         assertEquals("B", map.tailMap((K) "B").firstKey(),
180                 "First key in tail map should be B");
181         assertEquals("B", map.headMap((K) "C").lastKey(),
182                 "Last key in head map should be B");
183         assertEquals("B", map.subMap((K) "A", (K) "C").lastKey(),
184                 "Last key in submap should be B");
185 
186         final Comparator<? super K> c = map.comparator();
187         assertNull(c, "natural order, so comparator should be null");
188     }
189 
190 //    public void testCreate() throws Exception {
191 //        resetEmpty();
192 //        writeExternalFormToDisk(
193 //            (java.io.Serializable) map,
194 //            "src/test/resources/data/test/PredicatedSortedMap.emptyCollection.version4.obj");
195 //        resetFull();
196 //        writeExternalFormToDisk(
197 //            (java.io.Serializable) map,
198 //            "src/test/resources/data/test/PredicatedSortedMap.fullCollection.version4.obj");
199 //    }
200 
201 }