1 /* 2 * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4533691 7129185 27 * @summary Unit test for Collections.emptyNavigableMap 28 * @run testng EmptyNavigableMap 29 */ 30 31 package test.java.util.Collections; 32 33 import org.testng.Assert; 34 import org.testng.Assert.ThrowingRunnable; 35 import org.testng.annotations.DataProvider; 36 import org.testng.annotations.Test; 37 38 import java.math.BigInteger; 39 import java.util.Arrays; 40 import java.util.Collection; 41 import java.util.Collections; 42 import java.util.Comparator; 43 import java.util.Iterator; 44 import java.util.NavigableMap; 45 import java.util.SortedMap; 46 import java.util.TreeMap; 47 48 import static org.testng.Assert.assertFalse; 49 import static org.testng.Assert.assertTrue; 50 51 public class EmptyNavigableMap { 52 assertInstance(T actual, Class<? extends T> expected)53 public static <T> void assertInstance(T actual, Class<? extends T> expected) { 54 assertInstance(actual, expected, null); 55 } 56 assertInstance(T actual, Class<? extends T> expected, String message)57 public static <T> void assertInstance(T actual, Class<? extends T> expected, String message) { 58 assertTrue(expected.isInstance(actual), ((null != message) ? message : "") 59 + " " + (actual == null ? "<null>" : actual.getClass().getSimpleName()) + " != " + expected.getSimpleName() + ". "); 60 } 61 assertEmptyNavigableMap(Object obj)62 public static <T extends Throwable> void assertEmptyNavigableMap(Object obj) { 63 assertInstance(obj, NavigableMap.class); 64 assertTrue(((NavigableMap)obj).isEmpty() && (((NavigableMap)obj).size() == 0)); 65 } 66 assertEmptyNavigableMap(Object obj, String message)67 public static <T extends Throwable> void assertEmptyNavigableMap(Object obj, String message) { 68 assertInstance(obj, NavigableMap.class, message); 69 assertTrue(((NavigableMap)obj).isEmpty() && (((NavigableMap)obj).size() == 0), 70 ((null != message) ? message : "") + " Not empty. "); 71 } 72 assertThrows(Class<T> throwableClass, ThrowingRunnable runnable, String message)73 private <T extends Throwable> void assertThrows(Class<T> throwableClass, 74 ThrowingRunnable runnable, 75 String message) { 76 try { 77 Assert.assertThrows(throwableClass, runnable); 78 } catch (AssertionError e) { 79 throw new AssertionError(String.format("%s%n%s", 80 ((null != message) ? message : ""), e.getMessage()), e); 81 } 82 } 83 assertThrowsCCE(ThrowingRunnable r, String s)84 private void assertThrowsCCE(ThrowingRunnable r, String s) { 85 assertThrows(ClassCastException.class, r, s); 86 } 87 assertThrowsNPE(ThrowingRunnable r, String s)88 private void assertThrowsNPE(ThrowingRunnable r, String s) { 89 assertThrows(NullPointerException.class, r, s); 90 } 91 assertThrowsIAE(ThrowingRunnable r, String s)92 private void assertThrowsIAE(ThrowingRunnable r, String s) { 93 assertThrows(IllegalArgumentException.class, r, s); 94 } 95 isDescending(SortedMap<?,?> set)96 public static final boolean isDescending(SortedMap<?,?> set) { 97 if (null == set.comparator()) { 98 // natural order 99 return false; 100 } 101 102 if (Collections.reverseOrder() == set.comparator()) { 103 // reverse natural order. 104 return true; 105 } 106 107 if (set.comparator().equals(Collections.reverseOrder(Collections.reverseOrder(set.comparator())))) { 108 // it's a Collections.reverseOrder(Comparator). 109 return true; 110 } 111 112 throw new IllegalStateException("can't determine ordering for " + set); 113 } 114 115 /** 116 * Tests that the comparator is {@code null}. 117 */ 118 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testComparatorIsNull(String description, NavigableMap<?,?> navigableMap)119 public void testComparatorIsNull(String description, NavigableMap<?,?> navigableMap) { 120 Comparator comparator = navigableMap.comparator(); 121 122 assertTrue(comparator == null || comparator == Collections.reverseOrder(), description + ": Comparator (" + comparator + ") is not null."); 123 } 124 125 /** 126 * Tests that contains requires Comparable 127 */ 128 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testContainsRequiresComparable(String description, NavigableMap<?,?> navigableMap)129 public void testContainsRequiresComparable(String description, NavigableMap<?,?> navigableMap) { 130 assertThrowsCCE( 131 () -> navigableMap.containsKey(new Object()), 132 description + ": Comparable should be required"); 133 } 134 135 /** 136 * Tests that the contains method returns {@code false}. 137 */ 138 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testContains(String description, NavigableMap<?,?> navigableMap)139 public void testContains(String description, NavigableMap<?,?> navigableMap) { 140 assertFalse(navigableMap.containsKey(new Integer(1)), 141 description + ": Should not contain any elements."); 142 assertFalse(navigableMap.containsValue(new Integer(1)), 143 description + ": Should not contain any elements."); 144 } 145 146 /** 147 * Tests that the containsAll method returns {@code false}. 148 */ 149 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testContainsAll(String description, NavigableMap<?,?> navigableMap)150 public void testContainsAll(String description, NavigableMap<?,?> navigableMap) { 151 TreeMap treeMap = new TreeMap(); 152 treeMap.put("1", 1); 153 treeMap.put("2", 2); 154 treeMap.put("3", 3); 155 156 assertFalse(navigableMap.equals(treeMap), "Should not contain any elements."); 157 } 158 159 /** 160 * Tests that the iterator is empty. 161 */ 162 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testEmptyIterator(String description, NavigableMap<?,?> navigableMap)163 public void testEmptyIterator(String description, NavigableMap<?,?> navigableMap) { 164 assertFalse(navigableMap.keySet().iterator().hasNext(), "The iterator is not empty."); 165 assertFalse(navigableMap.values().iterator().hasNext(), "The iterator is not empty."); 166 assertFalse(navigableMap.entrySet().iterator().hasNext(), "The iterator is not empty."); 167 } 168 169 /** 170 * Tests that the set is empty. 171 */ 172 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testIsEmpty(String description, NavigableMap<?,?> navigableMap)173 public void testIsEmpty(String description, NavigableMap<?,?> navigableMap) { 174 assertTrue(navigableMap.isEmpty(), "The set is not empty."); 175 } 176 177 /** 178 * Tests the headMap() method. 179 */ 180 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testHeadMap(String description, NavigableMap navigableMap)181 public void testHeadMap(String description, NavigableMap navigableMap) { 182 assertThrowsNPE( 183 () -> { NavigableMap ss = navigableMap.headMap(null, false); }, 184 description + ": Must throw NullPointerException for null element"); 185 186 assertThrowsCCE( 187 () -> { NavigableMap ss = navigableMap.headMap(new Object(), true); }, 188 description + ": Must throw ClassCastException for non-Comparable element"); 189 190 NavigableMap ss = navigableMap.headMap("1", false); 191 192 assertEmptyNavigableMap(ss, description + ": Returned value is not empty navigable set."); 193 } 194 195 /** 196 * Tests that the size is 0. 197 */ 198 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testSizeIsZero(String description, NavigableMap<?,?> navigableMap)199 public void testSizeIsZero(String description, NavigableMap<?,?> navigableMap) { 200 assertTrue(0 == navigableMap.size(), "The size of the set is not 0."); 201 } 202 203 /** 204 * Tests the subMap() method. 205 */ 206 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testSubMap(String description, NavigableMap navigableMap)207 public void testSubMap(String description, NavigableMap navigableMap) { 208 assertThrowsNPE( 209 () -> { 210 SortedMap ss = navigableMap.subMap(null, BigInteger.TEN); 211 }, 212 description + ": Must throw NullPointerException for null element"); 213 214 assertThrowsNPE( 215 () -> { 216 SortedMap ss = navigableMap.subMap(BigInteger.ZERO, null); 217 }, 218 description + ": Must throw NullPointerException for null element"); 219 220 assertThrowsNPE( 221 () -> { 222 SortedMap ss = navigableMap.subMap(null, null); 223 }, 224 description + ": Must throw NullPointerException for null element"); 225 226 Object obj1 = new Object(); 227 Object obj2 = new Object(); 228 229 assertThrowsCCE( 230 () -> { 231 SortedMap ss = navigableMap.subMap(obj1, BigInteger.TEN); 232 }, 233 description + ": Must throw ClassCastException for parameter which is not Comparable."); 234 235 assertThrowsCCE( 236 () -> { 237 SortedMap ss = navigableMap.subMap(BigInteger.ZERO, obj2); 238 }, 239 description + ": Must throw ClassCastException for parameter which is not Comparable."); 240 241 assertThrowsCCE( 242 () -> { 243 SortedMap ss = navigableMap.subMap(obj1, obj2); 244 }, 245 description + ": Must throw ClassCastException for parameter which is not Comparable."); 246 247 // minimal range 248 navigableMap.subMap(BigInteger.ZERO, false, BigInteger.ZERO, false); 249 navigableMap.subMap(BigInteger.ZERO, false, BigInteger.ZERO, true); 250 navigableMap.subMap(BigInteger.ZERO, true, BigInteger.ZERO, false); 251 navigableMap.subMap(BigInteger.ZERO, true, BigInteger.ZERO, true); 252 253 Object first = isDescending(navigableMap) ? BigInteger.TEN : BigInteger.ZERO; 254 Object last = (BigInteger.ZERO == first) ? BigInteger.TEN : BigInteger.ZERO; 255 256 assertThrowsIAE( 257 () -> navigableMap.subMap(last, true, first, false), 258 description + ": Must throw IllegalArgumentException when fromElement is not less than toElement."); 259 260 navigableMap.subMap(first, true, last, false); 261 } 262 263 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testSubMapRanges(String description, NavigableMap navigableMap)264 public void testSubMapRanges(String description, NavigableMap navigableMap) { 265 Object first = isDescending(navigableMap) ? BigInteger.TEN : BigInteger.ZERO; 266 Object last = (BigInteger.ZERO == first) ? BigInteger.TEN : BigInteger.ZERO; 267 268 NavigableMap subMap = navigableMap.subMap(first, true, last, true); 269 270 // same subset 271 subMap.subMap(first, true, last, true); 272 273 // slightly smaller 274 NavigableMap ns = subMap.subMap(first, false, last, false); 275 // slight expansion 276 assertThrowsIAE( 277 () -> ns.subMap(first, true, last, true), 278 description + ": Expansion should not be allowed"); 279 280 // much smaller 281 subMap.subMap(first, false, BigInteger.ONE, false); 282 } 283 284 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testheadMapRanges(String description, NavigableMap navigableMap)285 public void testheadMapRanges(String description, NavigableMap navigableMap) { 286 NavigableMap subMap = navigableMap.headMap(BigInteger.ONE, true); 287 288 // same subset 289 subMap.headMap(BigInteger.ONE, true); 290 291 // slightly smaller 292 NavigableMap ns = subMap.headMap(BigInteger.ONE, false); 293 294 // slight expansion 295 assertThrowsIAE( 296 () -> ns.headMap(BigInteger.ONE, true), 297 description + ": Expansion should not be allowed"); 298 299 // much smaller 300 subMap.headMap(isDescending(subMap) ? BigInteger.TEN : BigInteger.ZERO, true); 301 } 302 303 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testTailMapRanges(String description, NavigableMap navigableMap)304 public void testTailMapRanges(String description, NavigableMap navigableMap) { 305 NavigableMap subMap = navigableMap.tailMap(BigInteger.ONE, true); 306 307 // same subset 308 subMap.tailMap(BigInteger.ONE, true); 309 310 // slightly smaller 311 NavigableMap ns = subMap.tailMap(BigInteger.ONE, false); 312 313 // slight expansion 314 assertThrowsIAE( 315 () -> ns.tailMap(BigInteger.ONE, true), 316 description + ": Expansion should not be allowed"); 317 318 // much smaller 319 subMap.tailMap(isDescending(subMap) ? BigInteger.ZERO : BigInteger.TEN, false); 320 } 321 322 /** 323 * Tests the tailMap() method. 324 */ 325 @Test(dataProvider = "NavigableMap<?,?>", dataProviderClass = EmptyNavigableMap.class) testTailMap(String description, NavigableMap navigableMap)326 public void testTailMap(String description, NavigableMap navigableMap) { 327 assertThrowsNPE( 328 () -> navigableMap.tailMap(null), 329 description + ": Must throw NullPointerException for null element"); 330 331 assertThrowsCCE( 332 () -> navigableMap.tailMap(new Object()), 333 description); 334 335 NavigableMap ss = navigableMap.tailMap("1", true); 336 337 assertEmptyNavigableMap(ss, description + ": Returned value is not empty navigable set."); 338 } 339 340 @DataProvider(name = "NavigableMap<?,?>", parallel = true) navigableMapsProvider()341 public static Iterator<Object[]> navigableMapsProvider() { 342 return makeNavigableMaps().iterator(); 343 } 344 makeNavigableMaps()345 public static Collection<Object[]> makeNavigableMaps() { 346 return Arrays.asList( 347 new Object[]{"UnmodifiableNavigableMap(TreeMap)", Collections.unmodifiableNavigableMap(new TreeMap())}, 348 new Object[]{"UnmodifiableNavigableMap(TreeMap.descendingMap()", Collections.unmodifiableNavigableMap(new TreeMap().descendingMap())}, 349 new Object[]{"UnmodifiableNavigableMap(TreeMap.descendingMap().descendingMap()", Collections.unmodifiableNavigableMap(new TreeMap().descendingMap().descendingMap())}, 350 new Object[]{"emptyNavigableMap()", Collections.emptyNavigableMap()}, 351 new Object[]{"emptyNavigableMap().descendingMap()", Collections.emptyNavigableMap().descendingMap()}, 352 new Object[]{"emptyNavigableMap().descendingMap().descendingMap()", Collections.emptyNavigableMap().descendingMap().descendingMap()} 353 ); 354 } 355 } 356