1 /* 2 * Copyright (C) 2011 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 11 * express or implied. See the License for the specific language governing permissions and 12 * limitations under the License. 13 */ 14 15 package com.google.common.collect.testing.google; 16 17 import static com.google.common.collect.BoundType.CLOSED; 18 import static com.google.common.collect.BoundType.OPEN; 19 import static com.google.common.collect.testing.Helpers.copyToList; 20 import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD; 21 import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE; 22 import static com.google.common.collect.testing.features.CollectionSize.ONE; 23 import static com.google.common.collect.testing.features.CollectionSize.SEVERAL; 24 import static com.google.common.collect.testing.features.CollectionSize.ZERO; 25 26 import com.google.common.annotations.GwtCompatible; 27 import com.google.common.collect.BoundType; 28 import com.google.common.collect.Iterators; 29 import com.google.common.collect.Multiset; 30 import com.google.common.collect.Multiset.Entry; 31 import com.google.common.collect.Multisets; 32 import com.google.common.collect.SortedMultiset; 33 import com.google.common.collect.testing.features.CollectionFeature; 34 import com.google.common.collect.testing.features.CollectionSize; 35 36 import java.util.ArrayList; 37 import java.util.Arrays; 38 import java.util.Collections; 39 import java.util.List; 40 import java.util.NoSuchElementException; 41 42 /** 43 * Tester for navigation of SortedMultisets. 44 * 45 * @author Louis Wasserman 46 */ 47 @GwtCompatible 48 public class MultisetNavigationTester<E> extends AbstractMultisetTester<E> { 49 private SortedMultiset<E> sortedMultiset; 50 private List<E> entries; 51 private Entry<E> a; 52 private Entry<E> b; 53 private Entry<E> c; 54 55 /** 56 * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 57 */ 58 static <T> SortedMultiset<T> cast(Multiset<T> iterable) { 59 return (SortedMultiset<T>) iterable; 60 } 61 62 @Override 63 public void setUp() throws Exception { 64 super.setUp(); 65 sortedMultiset = cast(getMultiset()); 66 entries = 67 copyToList(getSubjectGenerator().getSampleElements( 68 getSubjectGenerator().getCollectionSize().getNumElements())); 69 Collections.sort(entries, sortedMultiset.comparator()); 70 71 // some tests assume SEVERAL == 3 72 if (entries.size() >= 1) { 73 a = Multisets.immutableEntry(entries.get(0), sortedMultiset.count(entries.get(0))); 74 if (entries.size() >= 3) { 75 b = Multisets.immutableEntry(entries.get(1), sortedMultiset.count(entries.get(1))); 76 c = Multisets.immutableEntry(entries.get(2), sortedMultiset.count(entries.get(2))); 77 } 78 } 79 } 80 81 /** 82 * Resets the contents of sortedMultiset to have entries a, c, for the navigation tests. 83 */ 84 @SuppressWarnings("unchecked") 85 // Needed to stop Eclipse whining 86 private void resetWithHole() { 87 List<E> container = new ArrayList<E>(); 88 container.addAll(Collections.nCopies(a.getCount(), a.getElement())); 89 container.addAll(Collections.nCopies(c.getCount(), c.getElement())); 90 super.resetContainer(getSubjectGenerator().create(container.toArray())); 91 sortedMultiset = (SortedMultiset<E>) getMultiset(); 92 } 93 94 @CollectionSize.Require(ZERO) 95 public void testEmptyMultisetFirst() { 96 assertNull(sortedMultiset.firstEntry()); 97 try { 98 sortedMultiset.elementSet().first(); 99 fail(); 100 } catch (NoSuchElementException e) {} 101 } 102 103 @CollectionFeature.Require(SUPPORTS_REMOVE) 104 @CollectionSize.Require(ZERO) 105 public void testEmptyMultisetPollFirst() { 106 assertNull(sortedMultiset.pollFirstEntry()); 107 } 108 109 @CollectionSize.Require(ZERO) 110 public void testEmptyMultisetNearby() { 111 for (BoundType type : BoundType.values()) { 112 assertNull(sortedMultiset.headMultiset(samples.e0, type).lastEntry()); 113 assertNull(sortedMultiset.tailMultiset(samples.e0, type).firstEntry()); 114 } 115 } 116 117 @CollectionSize.Require(ZERO) 118 public void testEmptyMultisetLast() { 119 assertNull(sortedMultiset.lastEntry()); 120 try { 121 assertNull(sortedMultiset.elementSet().last()); 122 fail(); 123 } catch (NoSuchElementException e) {} 124 } 125 126 @CollectionFeature.Require(SUPPORTS_REMOVE) 127 @CollectionSize.Require(ZERO) 128 public void testEmptyMultisetPollLast() { 129 assertNull(sortedMultiset.pollLastEntry()); 130 } 131 132 @CollectionSize.Require(ONE) 133 public void testSingletonMultisetFirst() { 134 assertEquals(a, sortedMultiset.firstEntry()); 135 } 136 137 @CollectionFeature.Require(SUPPORTS_REMOVE) 138 @CollectionSize.Require(ONE) 139 public void testSingletonMultisetPollFirst() { 140 assertEquals(a, sortedMultiset.pollFirstEntry()); 141 assertTrue(sortedMultiset.isEmpty()); 142 } 143 144 @CollectionSize.Require(ONE) 145 public void testSingletonMultisetNearby() { 146 assertNull(sortedMultiset.headMultiset(samples.e0, OPEN).lastEntry()); 147 assertNull(sortedMultiset.tailMultiset(samples.e0, OPEN).lastEntry()); 148 149 assertEquals(a, sortedMultiset.headMultiset(samples.e0, CLOSED).lastEntry()); 150 assertEquals(a, sortedMultiset.tailMultiset(samples.e0, CLOSED).firstEntry()); 151 } 152 153 @CollectionSize.Require(ONE) 154 public void testSingletonMultisetLast() { 155 assertEquals(a, sortedMultiset.lastEntry()); 156 } 157 158 @CollectionFeature.Require(SUPPORTS_REMOVE) 159 @CollectionSize.Require(ONE) 160 public void testSingletonMultisetPollLast() { 161 assertEquals(a, sortedMultiset.pollLastEntry()); 162 assertTrue(sortedMultiset.isEmpty()); 163 } 164 165 @CollectionSize.Require(SEVERAL) 166 public void testFirst() { 167 assertEquals(a, sortedMultiset.firstEntry()); 168 } 169 170 @SuppressWarnings("unchecked") 171 @CollectionFeature.Require(SUPPORTS_REMOVE) 172 @CollectionSize.Require(SEVERAL) 173 public void testPollFirst() { 174 assertEquals(a, sortedMultiset.pollFirstEntry()); 175 assertEquals(Arrays.asList(b, c), copyToList(sortedMultiset.entrySet())); 176 } 177 178 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 179 public void testPollFirstUnsupported() { 180 try { 181 sortedMultiset.pollFirstEntry(); 182 fail(); 183 } catch (UnsupportedOperationException e) {} 184 } 185 186 @CollectionSize.Require(SEVERAL) 187 public void testLower() { 188 resetWithHole(); 189 assertEquals(null, sortedMultiset.headMultiset(a.getElement(), OPEN).lastEntry()); 190 assertEquals(a, sortedMultiset.headMultiset(b.getElement(), OPEN).lastEntry()); 191 assertEquals(a, sortedMultiset.headMultiset(c.getElement(), OPEN).lastEntry()); 192 } 193 194 @CollectionSize.Require(SEVERAL) 195 public void testFloor() { 196 resetWithHole(); 197 assertEquals(a, sortedMultiset.headMultiset(a.getElement(), CLOSED).lastEntry()); 198 assertEquals(a, sortedMultiset.headMultiset(b.getElement(), CLOSED).lastEntry()); 199 assertEquals(c, sortedMultiset.headMultiset(c.getElement(), CLOSED).lastEntry()); 200 } 201 202 @CollectionSize.Require(SEVERAL) 203 public void testCeiling() { 204 resetWithHole(); 205 206 assertEquals(a, sortedMultiset.tailMultiset(a.getElement(), CLOSED).firstEntry()); 207 assertEquals(c, sortedMultiset.tailMultiset(b.getElement(), CLOSED).firstEntry()); 208 assertEquals(c, sortedMultiset.tailMultiset(c.getElement(), CLOSED).firstEntry()); 209 } 210 211 @CollectionSize.Require(SEVERAL) 212 public void testHigher() { 213 resetWithHole(); 214 assertEquals(c, sortedMultiset.tailMultiset(a.getElement(), OPEN).firstEntry()); 215 assertEquals(c, sortedMultiset.tailMultiset(b.getElement(), OPEN).firstEntry()); 216 assertEquals(null, sortedMultiset.tailMultiset(c.getElement(), OPEN).firstEntry()); 217 } 218 219 @CollectionSize.Require(SEVERAL) 220 public void testLast() { 221 assertEquals(c, sortedMultiset.lastEntry()); 222 } 223 224 @SuppressWarnings("unchecked") 225 @CollectionFeature.Require(SUPPORTS_REMOVE) 226 @CollectionSize.Require(SEVERAL) 227 public void testPollLast() { 228 assertEquals(c, sortedMultiset.pollLastEntry()); 229 assertEquals(Arrays.asList(a, b), copyToList(sortedMultiset.entrySet())); 230 } 231 232 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 233 @CollectionSize.Require(SEVERAL) 234 public void testPollLastUnsupported() { 235 try { 236 sortedMultiset.pollLastEntry(); 237 fail(); 238 } catch (UnsupportedOperationException e) {} 239 } 240 241 @CollectionSize.Require(SEVERAL) 242 public void testDescendingNavigation() { 243 List<Entry<E>> ascending = new ArrayList<Entry<E>>(); 244 Iterators.addAll(ascending, sortedMultiset.entrySet().iterator()); 245 List<Entry<E>> descending = new ArrayList<Entry<E>>(); 246 Iterators.addAll(descending, sortedMultiset.descendingMultiset().entrySet().iterator()); 247 Collections.reverse(descending); 248 assertEquals(ascending, descending); 249 } 250 251 void expectAddFailure(SortedMultiset<E> multiset, Entry<E> entry) { 252 try { 253 multiset.add(entry.getElement(), entry.getCount()); 254 fail("Expected IllegalArgumentException"); 255 } catch (IllegalArgumentException expected) {} 256 257 try { 258 multiset.add(entry.getElement()); 259 fail("Expected IllegalArgumentException"); 260 } catch (IllegalArgumentException expected) {} 261 262 try { 263 multiset.addAll(Collections.singletonList(entry.getElement())); 264 fail("Expected IllegalArgumentException"); 265 } catch (IllegalArgumentException expected) {} 266 } 267 268 void expectRemoveZero(SortedMultiset<E> multiset, Entry<E> entry) { 269 assertEquals(0, multiset.remove(entry.getElement(), entry.getCount())); 270 assertFalse(multiset.remove(entry.getElement())); 271 assertFalse(multiset.elementSet().remove(entry.getElement())); 272 } 273 274 void expectSetCountFailure(SortedMultiset<E> multiset, Entry<E> entry) { 275 try { 276 multiset.setCount(entry.getElement(), multiset.count(entry.getElement())); 277 } catch (IllegalArgumentException acceptable) {} 278 try { 279 multiset.setCount(entry.getElement(), multiset.count(entry.getElement()) + 1); 280 fail("Expected IllegalArgumentException"); 281 } catch (IllegalArgumentException expected) {} 282 } 283 284 @CollectionSize.Require(ONE) 285 @CollectionFeature.Require(SUPPORTS_ADD) 286 public void testAddOutOfTailBoundsOne() { 287 expectAddFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 288 } 289 290 @CollectionSize.Require(SEVERAL) 291 @CollectionFeature.Require(SUPPORTS_ADD) 292 public void testAddOutOfTailBoundsSeveral() { 293 expectAddFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 294 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 295 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 296 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 297 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 298 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 299 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 300 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 301 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 302 } 303 304 @CollectionSize.Require(ONE) 305 @CollectionFeature.Require(SUPPORTS_ADD) 306 public void testAddOutOfHeadBoundsOne() { 307 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 308 } 309 310 @CollectionSize.Require(SEVERAL) 311 @CollectionFeature.Require(SUPPORTS_ADD) 312 public void testAddOutOfHeadBoundsSeveral() { 313 expectAddFailure(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 314 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 315 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 316 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 317 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 318 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 319 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 320 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 321 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 322 } 323 324 @CollectionSize.Require(ONE) 325 @CollectionFeature.Require(SUPPORTS_REMOVE) 326 public void testRemoveOutOfTailBoundsOne() { 327 expectRemoveZero(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 328 } 329 330 @CollectionSize.Require(SEVERAL) 331 @CollectionFeature.Require(SUPPORTS_REMOVE) 332 public void testRemoveOutOfTailBoundsSeveral() { 333 expectRemoveZero(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 334 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 335 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 336 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 337 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 338 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 339 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 340 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 341 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 342 } 343 344 @CollectionSize.Require(ONE) 345 @CollectionFeature.Require(SUPPORTS_REMOVE) 346 public void testRemoveOutOfHeadBoundsOne() { 347 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 348 } 349 350 @CollectionSize.Require(SEVERAL) 351 @CollectionFeature.Require(SUPPORTS_REMOVE) 352 public void testRemoveOutOfHeadBoundsSeveral() { 353 expectRemoveZero(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 354 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 355 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 356 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 357 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 358 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 359 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 360 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 361 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 362 } 363 364 @CollectionSize.Require(ONE) 365 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 366 public void testSetCountOutOfTailBoundsOne() { 367 expectSetCountFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 368 } 369 370 @CollectionSize.Require(SEVERAL) 371 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 372 public void testSetCountOutOfTailBoundsSeveral() { 373 expectSetCountFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 374 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 375 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 376 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 377 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 378 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 379 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 380 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 381 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 382 } 383 384 @CollectionSize.Require(ONE) 385 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 386 public void testSetCountOutOfHeadBoundsOne() { 387 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 388 } 389 390 @CollectionSize.Require(SEVERAL) 391 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 392 public void testSetCountOutOfHeadBoundsSeveral() { 393 expectSetCountFailure(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 394 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 395 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 396 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 397 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 398 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 399 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 400 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 401 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 402 } 403 404 @CollectionSize.Require(SEVERAL) 405 @CollectionFeature.Require(SUPPORTS_ADD) 406 public void testAddWithConflictingBounds() { 407 testEmptyRangeSubMultisetSupportingAdd(sortedMultiset.subMultiset(a.getElement(), CLOSED, 408 a.getElement(), OPEN)); 409 testEmptyRangeSubMultisetSupportingAdd(sortedMultiset.subMultiset(a.getElement(), OPEN, 410 a.getElement(), OPEN)); 411 testEmptyRangeSubMultisetSupportingAdd(sortedMultiset.subMultiset(a.getElement(), OPEN, 412 a.getElement(), CLOSED)); 413 testEmptyRangeSubMultisetSupportingAdd(sortedMultiset.subMultiset(b.getElement(), CLOSED, 414 a.getElement(), CLOSED)); 415 testEmptyRangeSubMultisetSupportingAdd(sortedMultiset.subMultiset(b.getElement(), CLOSED, 416 a.getElement(), OPEN)); 417 testEmptyRangeSubMultisetSupportingAdd(sortedMultiset.subMultiset(b.getElement(), OPEN, 418 a.getElement(), OPEN)); 419 } 420 421 @CollectionSize.Require(SEVERAL) 422 @CollectionFeature.Require(SUPPORTS_ADD) 423 public void testConflictingBounds() { 424 testEmptyRangeSubMultiset(sortedMultiset.subMultiset(a.getElement(), CLOSED, a.getElement(), 425 OPEN)); 426 testEmptyRangeSubMultiset(sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), 427 OPEN)); 428 testEmptyRangeSubMultiset(sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), 429 CLOSED)); 430 testEmptyRangeSubMultiset(sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), 431 CLOSED)); 432 testEmptyRangeSubMultiset(sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), 433 OPEN)); 434 testEmptyRangeSubMultiset(sortedMultiset.subMultiset(b.getElement(), OPEN, a.getElement(), 435 OPEN)); 436 } 437 438 public void testEmptyRangeSubMultiset(SortedMultiset<E> multiset) { 439 assertTrue(multiset.isEmpty()); 440 assertEquals(0, multiset.size()); 441 assertEquals(0, multiset.toArray().length); 442 assertTrue(multiset.entrySet().isEmpty()); 443 assertFalse(multiset.iterator().hasNext()); 444 assertEquals(0, multiset.entrySet().size()); 445 assertEquals(0, multiset.entrySet().toArray().length); 446 assertFalse(multiset.entrySet().iterator().hasNext()); 447 } 448 449 @SuppressWarnings("unchecked") 450 public void testEmptyRangeSubMultisetSupportingAdd(SortedMultiset<E> multiset) { 451 for (Entry<E> entry : Arrays.asList(a, b, c)) { 452 expectAddFailure(multiset, entry); 453 } 454 } 455 456 private int totalSize(Iterable<? extends Entry<?>> entries) { 457 int sum = 0; 458 for (Entry<?> entry : entries) { 459 sum += entry.getCount(); 460 } 461 return sum; 462 } 463 464 private enum SubMultisetSpec { 465 TAIL_CLOSED { 466 @Override 467 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 468 return entries.subList(targetEntry, entries.size()); 469 } 470 471 @Override 472 <E> SortedMultiset<E> subMultiset(SortedMultiset<E> multiset, List<Entry<E>> entries, 473 int targetEntry) { 474 return multiset.tailMultiset(entries.get(targetEntry).getElement(), CLOSED); 475 } 476 }, 477 TAIL_OPEN { 478 @Override 479 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 480 return entries.subList(targetEntry + 1, entries.size()); 481 } 482 483 @Override 484 <E> SortedMultiset<E> subMultiset(SortedMultiset<E> multiset, List<Entry<E>> entries, 485 int targetEntry) { 486 return multiset.tailMultiset(entries.get(targetEntry).getElement(), OPEN); 487 } 488 }, 489 HEAD_CLOSED { 490 @Override 491 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 492 return entries.subList(0, targetEntry + 1); 493 } 494 495 @Override 496 <E> SortedMultiset<E> subMultiset(SortedMultiset<E> multiset, List<Entry<E>> entries, 497 int targetEntry) { 498 return multiset.headMultiset(entries.get(targetEntry).getElement(), CLOSED); 499 } 500 }, 501 HEAD_OPEN { 502 @Override 503 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 504 return entries.subList(0, targetEntry); 505 } 506 507 @Override 508 <E> SortedMultiset<E> subMultiset(SortedMultiset<E> multiset, List<Entry<E>> entries, 509 int targetEntry) { 510 return multiset.headMultiset(entries.get(targetEntry).getElement(), OPEN); 511 } 512 }; 513 abstract <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries); 514 515 abstract <E> SortedMultiset<E> subMultiset(SortedMultiset<E> multiset, List<Entry<E>> entries, 516 int targetEntry); 517 } 518 519 private void testSubMultisetEntrySet(SubMultisetSpec spec) { 520 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 521 for (int i = 0; i < entries.size(); i++) { 522 List<Entry<E>> expected = spec.expectedEntries(i, entries); 523 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 524 assertEquals(expected, copyToList(subMultiset.entrySet())); 525 } 526 } 527 528 private void testSubMultisetSize(SubMultisetSpec spec) { 529 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 530 for (int i = 0; i < entries.size(); i++) { 531 List<Entry<E>> expected = spec.expectedEntries(i, entries); 532 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 533 assertEquals(totalSize(expected), subMultiset.size()); 534 } 535 } 536 537 private void testSubMultisetDistinctElements(SubMultisetSpec spec) { 538 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 539 for (int i = 0; i < entries.size(); i++) { 540 List<Entry<E>> expected = spec.expectedEntries(i, entries); 541 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 542 assertEquals(expected.size(), subMultiset.entrySet().size()); 543 assertEquals(expected.size(), subMultiset.elementSet().size()); 544 } 545 } 546 547 public void testTailClosedEntrySet() { 548 testSubMultisetEntrySet(SubMultisetSpec.TAIL_CLOSED); 549 } 550 551 public void testTailClosedSize() { 552 testSubMultisetSize(SubMultisetSpec.TAIL_CLOSED); 553 } 554 555 public void testTailClosedDistinctElements() { 556 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_CLOSED); 557 } 558 559 public void testTailOpenEntrySet() { 560 testSubMultisetEntrySet(SubMultisetSpec.TAIL_OPEN); 561 } 562 563 public void testTailOpenSize() { 564 testSubMultisetSize(SubMultisetSpec.TAIL_OPEN); 565 } 566 567 public void testTailOpenDistinctElements() { 568 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_OPEN); 569 } 570 571 public void testHeadClosedEntrySet() { 572 testSubMultisetEntrySet(SubMultisetSpec.HEAD_CLOSED); 573 } 574 575 public void testHeadClosedSize() { 576 testSubMultisetSize(SubMultisetSpec.HEAD_CLOSED); 577 } 578 579 public void testHeadClosedDistinctElements() { 580 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_CLOSED); 581 } 582 583 public void testHeadOpenEntrySet() { 584 testSubMultisetEntrySet(SubMultisetSpec.HEAD_OPEN); 585 } 586 587 public void testHeadOpenSize() { 588 testSubMultisetSize(SubMultisetSpec.HEAD_OPEN); 589 } 590 591 public void testHeadOpenDistinctElements() { 592 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_OPEN); 593 } 594 595 @CollectionSize.Require(SEVERAL) 596 @CollectionFeature.Require(SUPPORTS_REMOVE) 597 public void testClearTailOpen() { 598 List<Entry<E>> expected = 599 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 600 sortedMultiset.tailMultiset(b.getElement(), OPEN).clear(); 601 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 602 } 603 604 @CollectionSize.Require(SEVERAL) 605 @CollectionFeature.Require(SUPPORTS_REMOVE) 606 public void testClearTailOpenEntrySet() { 607 List<Entry<E>> expected = 608 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 609 sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet().clear(); 610 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 611 } 612 613 @CollectionSize.Require(SEVERAL) 614 @CollectionFeature.Require(SUPPORTS_REMOVE) 615 public void testClearTailClosed() { 616 List<Entry<E>> expected = 617 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 618 sortedMultiset.tailMultiset(b.getElement(), CLOSED).clear(); 619 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 620 } 621 622 @CollectionSize.Require(SEVERAL) 623 @CollectionFeature.Require(SUPPORTS_REMOVE) 624 public void testClearTailClosedEntrySet() { 625 List<Entry<E>> expected = 626 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 627 sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet().clear(); 628 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 629 } 630 631 @CollectionSize.Require(SEVERAL) 632 @CollectionFeature.Require(SUPPORTS_REMOVE) 633 public void testClearHeadOpen() { 634 List<Entry<E>> expected = 635 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 636 sortedMultiset.headMultiset(b.getElement(), OPEN).clear(); 637 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 638 } 639 640 @CollectionSize.Require(SEVERAL) 641 @CollectionFeature.Require(SUPPORTS_REMOVE) 642 public void testClearHeadOpenEntrySet() { 643 List<Entry<E>> expected = 644 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 645 sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet().clear(); 646 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 647 } 648 649 @CollectionSize.Require(SEVERAL) 650 @CollectionFeature.Require(SUPPORTS_REMOVE) 651 public void testClearHeadClosed() { 652 List<Entry<E>> expected = 653 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 654 sortedMultiset.headMultiset(b.getElement(), CLOSED).clear(); 655 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 656 } 657 658 @CollectionSize.Require(SEVERAL) 659 @CollectionFeature.Require(SUPPORTS_REMOVE) 660 public void testClearHeadClosedEntrySet() { 661 List<Entry<E>> expected = 662 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 663 sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet().clear(); 664 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 665 } 666 } 667