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; 040import org.junit.Ignore; 041 042/** 043 * Tester for navigation of SortedMultisets. 044 * 045 * @author Louis Wasserman 046 */ 047@GwtCompatible 048@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. 049@SuppressWarnings("JUnit4ClassUsedInJUnit3") 050public class MultisetNavigationTester<E> extends AbstractMultisetTester<E> { 051 private SortedMultiset<E> sortedMultiset; 052 private List<E> entries; 053 private Entry<E> a; 054 private Entry<E> b; 055 private Entry<E> c; 056 057 /** Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 */ 058 static <T> SortedMultiset<T> cast(Multiset<T> iterable) { 059 return (SortedMultiset<T>) iterable; 060 } 061 062 @Override 063 public void setUp() throws Exception { 064 super.setUp(); 065 sortedMultiset = cast(getMultiset()); 066 entries = 067 copyToList( 068 getSubjectGenerator() 069 .getSampleElements(getSubjectGenerator().getCollectionSize().getNumElements())); 070 Collections.sort(entries, sortedMultiset.comparator()); 071 072 // some tests assume SEVERAL == 3 073 if (entries.size() >= 1) { 074 a = Multisets.immutableEntry(entries.get(0), sortedMultiset.count(entries.get(0))); 075 if (entries.size() >= 3) { 076 b = Multisets.immutableEntry(entries.get(1), sortedMultiset.count(entries.get(1))); 077 c = Multisets.immutableEntry(entries.get(2), sortedMultiset.count(entries.get(2))); 078 } 079 } 080 } 081 082 /** Resets the contents of sortedMultiset to have entries a, c, for the navigation tests. */ 083 // Needed to stop Eclipse whining 084 private void resetWithHole() { 085 List<E> container = new ArrayList<>(); 086 container.addAll(Collections.nCopies(a.getCount(), a.getElement())); 087 container.addAll(Collections.nCopies(c.getCount(), c.getElement())); 088 super.resetContainer(getSubjectGenerator().create(container.toArray())); 089 sortedMultiset = (SortedMultiset<E>) getMultiset(); 090 } 091 092 @CollectionSize.Require(ZERO) 093 public void testEmptyMultisetFirst() { 094 assertNull(sortedMultiset.firstEntry()); 095 try { 096 sortedMultiset.elementSet().first(); 097 fail(); 098 } catch (NoSuchElementException e) { 099 } 100 } 101 102 @CollectionFeature.Require(SUPPORTS_REMOVE) 103 @CollectionSize.Require(ZERO) 104 public void testEmptyMultisetPollFirst() { 105 assertNull(sortedMultiset.pollFirstEntry()); 106 } 107 108 @CollectionSize.Require(ZERO) 109 public void testEmptyMultisetNearby() { 110 for (BoundType type : BoundType.values()) { 111 assertNull(sortedMultiset.headMultiset(e0(), type).lastEntry()); 112 assertNull(sortedMultiset.tailMultiset(e0(), type).firstEntry()); 113 } 114 } 115 116 @CollectionSize.Require(ZERO) 117 public void testEmptyMultisetLast() { 118 assertNull(sortedMultiset.lastEntry()); 119 try { 120 assertNull(sortedMultiset.elementSet().last()); 121 fail(); 122 } catch (NoSuchElementException e) { 123 } 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(e0(), OPEN).lastEntry()); 147 assertNull(sortedMultiset.tailMultiset(e0(), OPEN).lastEntry()); 148 149 assertEquals(a, sortedMultiset.headMultiset(e0(), CLOSED).lastEntry()); 150 assertEquals(a, sortedMultiset.tailMultiset(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 @CollectionFeature.Require(SUPPORTS_REMOVE) 171 @CollectionSize.Require(SEVERAL) 172 public void testPollFirst() { 173 assertEquals(a, sortedMultiset.pollFirstEntry()); 174 assertEquals(Arrays.asList(b, c), copyToList(sortedMultiset.entrySet())); 175 } 176 177 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 178 public void testPollFirstUnsupported() { 179 try { 180 sortedMultiset.pollFirstEntry(); 181 fail(); 182 } catch (UnsupportedOperationException e) { 183 } 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 @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 public void testEmptyRangeSubMultisetSupportingAdd(SortedMultiset<E> multiset) { 455 for (Entry<E> entry : Arrays.asList(a, b, c)) { 456 expectAddFailure(multiset, entry); 457 } 458 } 459 460 private static int totalSize(Iterable<? extends Entry<?>> entries) { 461 int sum = 0; 462 for (Entry<?> entry : entries) { 463 sum += entry.getCount(); 464 } 465 return sum; 466 } 467 468 private enum SubMultisetSpec { 469 TAIL_CLOSED { 470 @Override 471 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 472 return entries.subList(targetEntry, entries.size()); 473 } 474 475 @Override 476 <E> SortedMultiset<E> subMultiset( 477 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 478 return multiset.tailMultiset(entries.get(targetEntry).getElement(), CLOSED); 479 } 480 }, 481 TAIL_OPEN { 482 @Override 483 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 484 return entries.subList(targetEntry + 1, entries.size()); 485 } 486 487 @Override 488 <E> SortedMultiset<E> subMultiset( 489 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 490 return multiset.tailMultiset(entries.get(targetEntry).getElement(), OPEN); 491 } 492 }, 493 HEAD_CLOSED { 494 @Override 495 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 496 return entries.subList(0, targetEntry + 1); 497 } 498 499 @Override 500 <E> SortedMultiset<E> subMultiset( 501 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 502 return multiset.headMultiset(entries.get(targetEntry).getElement(), CLOSED); 503 } 504 }, 505 HEAD_OPEN { 506 @Override 507 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 508 return entries.subList(0, targetEntry); 509 } 510 511 @Override 512 <E> SortedMultiset<E> subMultiset( 513 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 514 return multiset.headMultiset(entries.get(targetEntry).getElement(), OPEN); 515 } 516 }; 517 518 abstract <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries); 519 520 abstract <E> SortedMultiset<E> subMultiset( 521 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry); 522 } 523 524 private void testSubMultisetEntrySet(SubMultisetSpec spec) { 525 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 526 for (int i = 0; i < entries.size(); i++) { 527 List<Entry<E>> expected = spec.expectedEntries(i, entries); 528 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 529 assertEquals(expected, copyToList(subMultiset.entrySet())); 530 } 531 } 532 533 private void testSubMultisetSize(SubMultisetSpec spec) { 534 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 535 for (int i = 0; i < entries.size(); i++) { 536 List<Entry<E>> expected = spec.expectedEntries(i, entries); 537 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 538 assertEquals(totalSize(expected), subMultiset.size()); 539 } 540 } 541 542 private void testSubMultisetDistinctElements(SubMultisetSpec spec) { 543 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 544 for (int i = 0; i < entries.size(); i++) { 545 List<Entry<E>> expected = spec.expectedEntries(i, entries); 546 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 547 assertEquals(expected.size(), subMultiset.entrySet().size()); 548 assertEquals(expected.size(), subMultiset.elementSet().size()); 549 } 550 } 551 552 public void testTailClosedEntrySet() { 553 testSubMultisetEntrySet(SubMultisetSpec.TAIL_CLOSED); 554 } 555 556 public void testTailClosedSize() { 557 testSubMultisetSize(SubMultisetSpec.TAIL_CLOSED); 558 } 559 560 public void testTailClosedDistinctElements() { 561 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_CLOSED); 562 } 563 564 public void testTailOpenEntrySet() { 565 testSubMultisetEntrySet(SubMultisetSpec.TAIL_OPEN); 566 } 567 568 public void testTailOpenSize() { 569 testSubMultisetSize(SubMultisetSpec.TAIL_OPEN); 570 } 571 572 public void testTailOpenDistinctElements() { 573 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_OPEN); 574 } 575 576 public void testHeadClosedEntrySet() { 577 testSubMultisetEntrySet(SubMultisetSpec.HEAD_CLOSED); 578 } 579 580 public void testHeadClosedSize() { 581 testSubMultisetSize(SubMultisetSpec.HEAD_CLOSED); 582 } 583 584 public void testHeadClosedDistinctElements() { 585 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_CLOSED); 586 } 587 588 public void testHeadOpenEntrySet() { 589 testSubMultisetEntrySet(SubMultisetSpec.HEAD_OPEN); 590 } 591 592 public void testHeadOpenSize() { 593 testSubMultisetSize(SubMultisetSpec.HEAD_OPEN); 594 } 595 596 public void testHeadOpenDistinctElements() { 597 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_OPEN); 598 } 599 600 @CollectionSize.Require(SEVERAL) 601 @CollectionFeature.Require(SUPPORTS_REMOVE) 602 public void testClearTailOpen() { 603 List<Entry<E>> expected = 604 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 605 sortedMultiset.tailMultiset(b.getElement(), OPEN).clear(); 606 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 607 } 608 609 @CollectionSize.Require(SEVERAL) 610 @CollectionFeature.Require(SUPPORTS_REMOVE) 611 public void testClearTailOpenEntrySet() { 612 List<Entry<E>> expected = 613 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 614 sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet().clear(); 615 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 616 } 617 618 @CollectionSize.Require(SEVERAL) 619 @CollectionFeature.Require(SUPPORTS_REMOVE) 620 public void testClearTailClosed() { 621 List<Entry<E>> expected = 622 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 623 sortedMultiset.tailMultiset(b.getElement(), CLOSED).clear(); 624 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 625 } 626 627 @CollectionSize.Require(SEVERAL) 628 @CollectionFeature.Require(SUPPORTS_REMOVE) 629 public void testClearTailClosedEntrySet() { 630 List<Entry<E>> expected = 631 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 632 sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet().clear(); 633 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 634 } 635 636 @CollectionSize.Require(SEVERAL) 637 @CollectionFeature.Require(SUPPORTS_REMOVE) 638 public void testClearHeadOpen() { 639 List<Entry<E>> expected = 640 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 641 sortedMultiset.headMultiset(b.getElement(), OPEN).clear(); 642 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 643 } 644 645 @CollectionSize.Require(SEVERAL) 646 @CollectionFeature.Require(SUPPORTS_REMOVE) 647 public void testClearHeadOpenEntrySet() { 648 List<Entry<E>> expected = 649 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 650 sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet().clear(); 651 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 652 } 653 654 @CollectionSize.Require(SEVERAL) 655 @CollectionFeature.Require(SUPPORTS_REMOVE) 656 public void testClearHeadClosed() { 657 List<Entry<E>> expected = 658 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 659 sortedMultiset.headMultiset(b.getElement(), CLOSED).clear(); 660 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 661 } 662 663 @CollectionSize.Require(SEVERAL) 664 @CollectionFeature.Require(SUPPORTS_REMOVE) 665 public void testClearHeadClosedEntrySet() { 666 List<Entry<E>> expected = 667 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 668 sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet().clear(); 669 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 670 } 671}