001/* 002 * Copyright (C) 2011 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with the License. You may obtain a copy of the License at 006 * 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software distributed under the 010 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 011 * express or implied. See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014 015package com.google.common.collect.testing.google; 016 017import static com.google.common.collect.BoundType.CLOSED; 018import static com.google.common.collect.BoundType.OPEN; 019import static com.google.common.collect.testing.Helpers.copyToList; 020import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_ADD; 021import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE; 022import static com.google.common.collect.testing.features.CollectionSize.ONE; 023import static com.google.common.collect.testing.features.CollectionSize.SEVERAL; 024import static com.google.common.collect.testing.features.CollectionSize.ZERO; 025 026import com.google.common.annotations.GwtCompatible; 027import com.google.common.collect.BoundType; 028import com.google.common.collect.Iterators; 029import com.google.common.collect.Multiset; 030import com.google.common.collect.Multiset.Entry; 031import com.google.common.collect.Multisets; 032import com.google.common.collect.SortedMultiset; 033import com.google.common.collect.testing.features.CollectionFeature; 034import com.google.common.collect.testing.features.CollectionSize; 035import java.util.ArrayList; 036import java.util.Arrays; 037import java.util.Collections; 038import java.util.List; 039import java.util.NoSuchElementException; 040 041/** 042 * Tester for navigation of SortedMultisets. 043 * 044 * @author Louis Wasserman 045 */ 046@GwtCompatible 047public class MultisetNavigationTester<E> extends AbstractMultisetTester<E> { 048 private SortedMultiset<E> sortedMultiset; 049 private List<E> entries; 050 private Entry<E> a; 051 private Entry<E> b; 052 private Entry<E> c; 053 054 /** Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 */ 055 static <T> SortedMultiset<T> cast(Multiset<T> iterable) { 056 return (SortedMultiset<T>) iterable; 057 } 058 059 @Override 060 public void setUp() throws Exception { 061 super.setUp(); 062 sortedMultiset = cast(getMultiset()); 063 entries = 064 copyToList( 065 getSubjectGenerator() 066 .getSampleElements(getSubjectGenerator().getCollectionSize().getNumElements())); 067 Collections.sort(entries, sortedMultiset.comparator()); 068 069 // some tests assume SEVERAL == 3 070 if (entries.size() >= 1) { 071 a = Multisets.immutableEntry(entries.get(0), sortedMultiset.count(entries.get(0))); 072 if (entries.size() >= 3) { 073 b = Multisets.immutableEntry(entries.get(1), sortedMultiset.count(entries.get(1))); 074 c = Multisets.immutableEntry(entries.get(2), sortedMultiset.count(entries.get(2))); 075 } 076 } 077 } 078 079 /** Resets the contents of sortedMultiset to have entries a, c, for the navigation tests. */ 080 @SuppressWarnings("unchecked") 081 // Needed to stop Eclipse whining 082 private void resetWithHole() { 083 List<E> container = new ArrayList<E>(); 084 container.addAll(Collections.nCopies(a.getCount(), a.getElement())); 085 container.addAll(Collections.nCopies(c.getCount(), c.getElement())); 086 super.resetContainer(getSubjectGenerator().create(container.toArray())); 087 sortedMultiset = (SortedMultiset<E>) getMultiset(); 088 } 089 090 @CollectionSize.Require(ZERO) 091 public void testEmptyMultisetFirst() { 092 assertNull(sortedMultiset.firstEntry()); 093 try { 094 sortedMultiset.elementSet().first(); 095 fail(); 096 } catch (NoSuchElementException e) { 097 } 098 } 099 100 @CollectionFeature.Require(SUPPORTS_REMOVE) 101 @CollectionSize.Require(ZERO) 102 public void testEmptyMultisetPollFirst() { 103 assertNull(sortedMultiset.pollFirstEntry()); 104 } 105 106 @CollectionSize.Require(ZERO) 107 public void testEmptyMultisetNearby() { 108 for (BoundType type : BoundType.values()) { 109 assertNull(sortedMultiset.headMultiset(e0(), type).lastEntry()); 110 assertNull(sortedMultiset.tailMultiset(e0(), type).firstEntry()); 111 } 112 } 113 114 @CollectionSize.Require(ZERO) 115 public void testEmptyMultisetLast() { 116 assertNull(sortedMultiset.lastEntry()); 117 try { 118 assertNull(sortedMultiset.elementSet().last()); 119 fail(); 120 } catch (NoSuchElementException e) { 121 } 122 } 123 124 @CollectionFeature.Require(SUPPORTS_REMOVE) 125 @CollectionSize.Require(ZERO) 126 public void testEmptyMultisetPollLast() { 127 assertNull(sortedMultiset.pollLastEntry()); 128 } 129 130 @CollectionSize.Require(ONE) 131 public void testSingletonMultisetFirst() { 132 assertEquals(a, sortedMultiset.firstEntry()); 133 } 134 135 @CollectionFeature.Require(SUPPORTS_REMOVE) 136 @CollectionSize.Require(ONE) 137 public void testSingletonMultisetPollFirst() { 138 assertEquals(a, sortedMultiset.pollFirstEntry()); 139 assertTrue(sortedMultiset.isEmpty()); 140 } 141 142 @CollectionSize.Require(ONE) 143 public void testSingletonMultisetNearby() { 144 assertNull(sortedMultiset.headMultiset(e0(), OPEN).lastEntry()); 145 assertNull(sortedMultiset.tailMultiset(e0(), OPEN).lastEntry()); 146 147 assertEquals(a, sortedMultiset.headMultiset(e0(), CLOSED).lastEntry()); 148 assertEquals(a, sortedMultiset.tailMultiset(e0(), CLOSED).firstEntry()); 149 } 150 151 @CollectionSize.Require(ONE) 152 public void testSingletonMultisetLast() { 153 assertEquals(a, sortedMultiset.lastEntry()); 154 } 155 156 @CollectionFeature.Require(SUPPORTS_REMOVE) 157 @CollectionSize.Require(ONE) 158 public void testSingletonMultisetPollLast() { 159 assertEquals(a, sortedMultiset.pollLastEntry()); 160 assertTrue(sortedMultiset.isEmpty()); 161 } 162 163 @CollectionSize.Require(SEVERAL) 164 public void testFirst() { 165 assertEquals(a, sortedMultiset.firstEntry()); 166 } 167 168 @SuppressWarnings("unchecked") 169 @CollectionFeature.Require(SUPPORTS_REMOVE) 170 @CollectionSize.Require(SEVERAL) 171 public void testPollFirst() { 172 assertEquals(a, sortedMultiset.pollFirstEntry()); 173 assertEquals(Arrays.asList(b, c), copyToList(sortedMultiset.entrySet())); 174 } 175 176 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 177 public void testPollFirstUnsupported() { 178 try { 179 sortedMultiset.pollFirstEntry(); 180 fail(); 181 } catch (UnsupportedOperationException e) { 182 } 183 } 184 185 @CollectionSize.Require(SEVERAL) 186 public void testLower() { 187 resetWithHole(); 188 assertEquals(null, sortedMultiset.headMultiset(a.getElement(), OPEN).lastEntry()); 189 assertEquals(a, sortedMultiset.headMultiset(b.getElement(), OPEN).lastEntry()); 190 assertEquals(a, sortedMultiset.headMultiset(c.getElement(), OPEN).lastEntry()); 191 } 192 193 @CollectionSize.Require(SEVERAL) 194 public void testFloor() { 195 resetWithHole(); 196 assertEquals(a, sortedMultiset.headMultiset(a.getElement(), CLOSED).lastEntry()); 197 assertEquals(a, sortedMultiset.headMultiset(b.getElement(), CLOSED).lastEntry()); 198 assertEquals(c, sortedMultiset.headMultiset(c.getElement(), CLOSED).lastEntry()); 199 } 200 201 @CollectionSize.Require(SEVERAL) 202 public void testCeiling() { 203 resetWithHole(); 204 205 assertEquals(a, sortedMultiset.tailMultiset(a.getElement(), CLOSED).firstEntry()); 206 assertEquals(c, sortedMultiset.tailMultiset(b.getElement(), CLOSED).firstEntry()); 207 assertEquals(c, sortedMultiset.tailMultiset(c.getElement(), CLOSED).firstEntry()); 208 } 209 210 @CollectionSize.Require(SEVERAL) 211 public void testHigher() { 212 resetWithHole(); 213 assertEquals(c, sortedMultiset.tailMultiset(a.getElement(), OPEN).firstEntry()); 214 assertEquals(c, sortedMultiset.tailMultiset(b.getElement(), OPEN).firstEntry()); 215 assertEquals(null, sortedMultiset.tailMultiset(c.getElement(), OPEN).firstEntry()); 216 } 217 218 @CollectionSize.Require(SEVERAL) 219 public void testLast() { 220 assertEquals(c, sortedMultiset.lastEntry()); 221 } 222 223 @SuppressWarnings("unchecked") 224 @CollectionFeature.Require(SUPPORTS_REMOVE) 225 @CollectionSize.Require(SEVERAL) 226 public void testPollLast() { 227 assertEquals(c, sortedMultiset.pollLastEntry()); 228 assertEquals(Arrays.asList(a, b), copyToList(sortedMultiset.entrySet())); 229 } 230 231 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 232 @CollectionSize.Require(SEVERAL) 233 public void testPollLastUnsupported() { 234 try { 235 sortedMultiset.pollLastEntry(); 236 fail(); 237 } catch (UnsupportedOperationException e) { 238 } 239 } 240 241 @CollectionSize.Require(SEVERAL) 242 public void testDescendingNavigation() { 243 List<Entry<E>> ascending = new ArrayList<>(); 244 Iterators.addAll(ascending, sortedMultiset.entrySet().iterator()); 245 List<Entry<E>> descending = new ArrayList<>(); 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 258 try { 259 multiset.add(entry.getElement()); 260 fail("Expected IllegalArgumentException"); 261 } catch (IllegalArgumentException expected) { 262 } 263 264 try { 265 multiset.addAll(Collections.singletonList(entry.getElement())); 266 fail("Expected IllegalArgumentException"); 267 } catch (IllegalArgumentException expected) { 268 } 269 } 270 271 void expectRemoveZero(SortedMultiset<E> multiset, Entry<E> entry) { 272 assertEquals(0, multiset.remove(entry.getElement(), entry.getCount())); 273 assertFalse(multiset.remove(entry.getElement())); 274 assertFalse(multiset.elementSet().remove(entry.getElement())); 275 } 276 277 void expectSetCountFailure(SortedMultiset<E> multiset, Entry<E> entry) { 278 try { 279 multiset.setCount(entry.getElement(), multiset.count(entry.getElement())); 280 } catch (IllegalArgumentException acceptable) { 281 } 282 try { 283 multiset.setCount(entry.getElement(), multiset.count(entry.getElement()) + 1); 284 fail("Expected IllegalArgumentException"); 285 } catch (IllegalArgumentException expected) { 286 } 287 } 288 289 @CollectionSize.Require(ONE) 290 @CollectionFeature.Require(SUPPORTS_ADD) 291 public void testAddOutOfTailBoundsOne() { 292 expectAddFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 293 } 294 295 @CollectionSize.Require(SEVERAL) 296 @CollectionFeature.Require(SUPPORTS_ADD) 297 public void testAddOutOfTailBoundsSeveral() { 298 expectAddFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 299 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 300 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 301 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 302 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 303 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 304 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 305 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 306 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 307 } 308 309 @CollectionSize.Require(ONE) 310 @CollectionFeature.Require(SUPPORTS_ADD) 311 public void testAddOutOfHeadBoundsOne() { 312 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 313 } 314 315 @CollectionSize.Require(SEVERAL) 316 @CollectionFeature.Require(SUPPORTS_ADD) 317 public void testAddOutOfHeadBoundsSeveral() { 318 expectAddFailure(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 319 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 320 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 321 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 322 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 323 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 324 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 325 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 326 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 327 } 328 329 @CollectionSize.Require(ONE) 330 @CollectionFeature.Require(SUPPORTS_REMOVE) 331 public void testRemoveOutOfTailBoundsOne() { 332 expectRemoveZero(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 333 } 334 335 @CollectionSize.Require(SEVERAL) 336 @CollectionFeature.Require(SUPPORTS_REMOVE) 337 public void testRemoveOutOfTailBoundsSeveral() { 338 expectRemoveZero(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 339 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 340 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 341 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 342 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 343 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 344 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 345 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 346 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 347 } 348 349 @CollectionSize.Require(ONE) 350 @CollectionFeature.Require(SUPPORTS_REMOVE) 351 public void testRemoveOutOfHeadBoundsOne() { 352 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 353 } 354 355 @CollectionSize.Require(SEVERAL) 356 @CollectionFeature.Require(SUPPORTS_REMOVE) 357 public void testRemoveOutOfHeadBoundsSeveral() { 358 expectRemoveZero(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 359 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 360 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 361 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 362 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 363 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 364 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 365 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 366 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 367 } 368 369 @CollectionSize.Require(ONE) 370 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 371 public void testSetCountOutOfTailBoundsOne() { 372 expectSetCountFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 373 } 374 375 @CollectionSize.Require(SEVERAL) 376 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 377 public void testSetCountOutOfTailBoundsSeveral() { 378 expectSetCountFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 379 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 380 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 381 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 382 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 383 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 384 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 385 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 386 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 387 } 388 389 @CollectionSize.Require(ONE) 390 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 391 public void testSetCountOutOfHeadBoundsOne() { 392 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 393 } 394 395 @CollectionSize.Require(SEVERAL) 396 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 397 public void testSetCountOutOfHeadBoundsSeveral() { 398 expectSetCountFailure(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 399 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 400 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 401 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 402 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 403 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 404 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 405 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 406 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 407 } 408 409 @CollectionSize.Require(SEVERAL) 410 @CollectionFeature.Require(SUPPORTS_ADD) 411 public void testAddWithConflictingBounds() { 412 testEmptyRangeSubMultisetSupportingAdd( 413 sortedMultiset.subMultiset(a.getElement(), CLOSED, a.getElement(), OPEN)); 414 testEmptyRangeSubMultisetSupportingAdd( 415 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), OPEN)); 416 testEmptyRangeSubMultisetSupportingAdd( 417 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), CLOSED)); 418 testEmptyRangeSubMultisetSupportingAdd( 419 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), CLOSED)); 420 testEmptyRangeSubMultisetSupportingAdd( 421 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), OPEN)); 422 testEmptyRangeSubMultisetSupportingAdd( 423 sortedMultiset.subMultiset(b.getElement(), OPEN, a.getElement(), OPEN)); 424 } 425 426 @CollectionSize.Require(SEVERAL) 427 @CollectionFeature.Require(SUPPORTS_ADD) 428 public void testConflictingBounds() { 429 testEmptyRangeSubMultiset( 430 sortedMultiset.subMultiset(a.getElement(), CLOSED, a.getElement(), OPEN)); 431 testEmptyRangeSubMultiset( 432 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), OPEN)); 433 testEmptyRangeSubMultiset( 434 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), CLOSED)); 435 testEmptyRangeSubMultiset( 436 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), CLOSED)); 437 testEmptyRangeSubMultiset( 438 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), OPEN)); 439 testEmptyRangeSubMultiset( 440 sortedMultiset.subMultiset(b.getElement(), OPEN, a.getElement(), OPEN)); 441 } 442 443 public void testEmptyRangeSubMultiset(SortedMultiset<E> multiset) { 444 assertTrue(multiset.isEmpty()); 445 assertEquals(0, multiset.size()); 446 assertEquals(0, multiset.toArray().length); 447 assertTrue(multiset.entrySet().isEmpty()); 448 assertFalse(multiset.iterator().hasNext()); 449 assertEquals(0, multiset.entrySet().size()); 450 assertEquals(0, multiset.entrySet().toArray().length); 451 assertFalse(multiset.entrySet().iterator().hasNext()); 452 } 453 454 @SuppressWarnings("unchecked") 455 public void testEmptyRangeSubMultisetSupportingAdd(SortedMultiset<E> multiset) { 456 for (Entry<E> entry : Arrays.asList(a, b, c)) { 457 expectAddFailure(multiset, entry); 458 } 459 } 460 461 private static int totalSize(Iterable<? extends Entry<?>> entries) { 462 int sum = 0; 463 for (Entry<?> entry : entries) { 464 sum += entry.getCount(); 465 } 466 return sum; 467 } 468 469 private enum SubMultisetSpec { 470 TAIL_CLOSED { 471 @Override 472 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 473 return entries.subList(targetEntry, entries.size()); 474 } 475 476 @Override 477 <E> SortedMultiset<E> subMultiset( 478 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 479 return multiset.tailMultiset(entries.get(targetEntry).getElement(), CLOSED); 480 } 481 }, 482 TAIL_OPEN { 483 @Override 484 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 485 return entries.subList(targetEntry + 1, entries.size()); 486 } 487 488 @Override 489 <E> SortedMultiset<E> subMultiset( 490 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 491 return multiset.tailMultiset(entries.get(targetEntry).getElement(), OPEN); 492 } 493 }, 494 HEAD_CLOSED { 495 @Override 496 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 497 return entries.subList(0, targetEntry + 1); 498 } 499 500 @Override 501 <E> SortedMultiset<E> subMultiset( 502 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 503 return multiset.headMultiset(entries.get(targetEntry).getElement(), CLOSED); 504 } 505 }, 506 HEAD_OPEN { 507 @Override 508 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 509 return entries.subList(0, targetEntry); 510 } 511 512 @Override 513 <E> SortedMultiset<E> subMultiset( 514 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 515 return multiset.headMultiset(entries.get(targetEntry).getElement(), OPEN); 516 } 517 }; 518 519 abstract <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries); 520 521 abstract <E> SortedMultiset<E> subMultiset( 522 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry); 523 } 524 525 private void testSubMultisetEntrySet(SubMultisetSpec spec) { 526 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 527 for (int i = 0; i < entries.size(); i++) { 528 List<Entry<E>> expected = spec.expectedEntries(i, entries); 529 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 530 assertEquals(expected, copyToList(subMultiset.entrySet())); 531 } 532 } 533 534 private void testSubMultisetSize(SubMultisetSpec spec) { 535 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 536 for (int i = 0; i < entries.size(); i++) { 537 List<Entry<E>> expected = spec.expectedEntries(i, entries); 538 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 539 assertEquals(totalSize(expected), subMultiset.size()); 540 } 541 } 542 543 private void testSubMultisetDistinctElements(SubMultisetSpec spec) { 544 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 545 for (int i = 0; i < entries.size(); i++) { 546 List<Entry<E>> expected = spec.expectedEntries(i, entries); 547 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 548 assertEquals(expected.size(), subMultiset.entrySet().size()); 549 assertEquals(expected.size(), subMultiset.elementSet().size()); 550 } 551 } 552 553 public void testTailClosedEntrySet() { 554 testSubMultisetEntrySet(SubMultisetSpec.TAIL_CLOSED); 555 } 556 557 public void testTailClosedSize() { 558 testSubMultisetSize(SubMultisetSpec.TAIL_CLOSED); 559 } 560 561 public void testTailClosedDistinctElements() { 562 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_CLOSED); 563 } 564 565 public void testTailOpenEntrySet() { 566 testSubMultisetEntrySet(SubMultisetSpec.TAIL_OPEN); 567 } 568 569 public void testTailOpenSize() { 570 testSubMultisetSize(SubMultisetSpec.TAIL_OPEN); 571 } 572 573 public void testTailOpenDistinctElements() { 574 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_OPEN); 575 } 576 577 public void testHeadClosedEntrySet() { 578 testSubMultisetEntrySet(SubMultisetSpec.HEAD_CLOSED); 579 } 580 581 public void testHeadClosedSize() { 582 testSubMultisetSize(SubMultisetSpec.HEAD_CLOSED); 583 } 584 585 public void testHeadClosedDistinctElements() { 586 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_CLOSED); 587 } 588 589 public void testHeadOpenEntrySet() { 590 testSubMultisetEntrySet(SubMultisetSpec.HEAD_OPEN); 591 } 592 593 public void testHeadOpenSize() { 594 testSubMultisetSize(SubMultisetSpec.HEAD_OPEN); 595 } 596 597 public void testHeadOpenDistinctElements() { 598 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_OPEN); 599 } 600 601 @CollectionSize.Require(SEVERAL) 602 @CollectionFeature.Require(SUPPORTS_REMOVE) 603 public void testClearTailOpen() { 604 List<Entry<E>> expected = 605 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 606 sortedMultiset.tailMultiset(b.getElement(), OPEN).clear(); 607 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 608 } 609 610 @CollectionSize.Require(SEVERAL) 611 @CollectionFeature.Require(SUPPORTS_REMOVE) 612 public void testClearTailOpenEntrySet() { 613 List<Entry<E>> expected = 614 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 615 sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet().clear(); 616 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 617 } 618 619 @CollectionSize.Require(SEVERAL) 620 @CollectionFeature.Require(SUPPORTS_REMOVE) 621 public void testClearTailClosed() { 622 List<Entry<E>> expected = 623 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 624 sortedMultiset.tailMultiset(b.getElement(), CLOSED).clear(); 625 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 626 } 627 628 @CollectionSize.Require(SEVERAL) 629 @CollectionFeature.Require(SUPPORTS_REMOVE) 630 public void testClearTailClosedEntrySet() { 631 List<Entry<E>> expected = 632 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 633 sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet().clear(); 634 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 635 } 636 637 @CollectionSize.Require(SEVERAL) 638 @CollectionFeature.Require(SUPPORTS_REMOVE) 639 public void testClearHeadOpen() { 640 List<Entry<E>> expected = 641 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 642 sortedMultiset.headMultiset(b.getElement(), OPEN).clear(); 643 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 644 } 645 646 @CollectionSize.Require(SEVERAL) 647 @CollectionFeature.Require(SUPPORTS_REMOVE) 648 public void testClearHeadOpenEntrySet() { 649 List<Entry<E>> expected = 650 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 651 sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet().clear(); 652 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 653 } 654 655 @CollectionSize.Require(SEVERAL) 656 @CollectionFeature.Require(SUPPORTS_REMOVE) 657 public void testClearHeadClosed() { 658 List<Entry<E>> expected = 659 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 660 sortedMultiset.headMultiset(b.getElement(), CLOSED).clear(); 661 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 662 } 663 664 @CollectionSize.Require(SEVERAL) 665 @CollectionFeature.Require(SUPPORTS_REMOVE) 666 public void testClearHeadClosedEntrySet() { 667 List<Entry<E>> expected = 668 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 669 sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet().clear(); 670 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 671 } 672}