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. 049public class MultisetNavigationTester<E> extends AbstractMultisetTester<E> { 050 private SortedMultiset<E> sortedMultiset; 051 private List<E> entries; 052 private Entry<E> a; 053 private Entry<E> b; 054 private Entry<E> c; 055 056 /** Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 */ 057 static <T> SortedMultiset<T> cast(Multiset<T> iterable) { 058 return (SortedMultiset<T>) iterable; 059 } 060 061 @Override 062 public void setUp() throws Exception { 063 super.setUp(); 064 sortedMultiset = cast(getMultiset()); 065 entries = 066 copyToList( 067 getSubjectGenerator() 068 .getSampleElements(getSubjectGenerator().getCollectionSize().getNumElements())); 069 Collections.sort(entries, sortedMultiset.comparator()); 070 071 // some tests assume SEVERAL == 3 072 if (entries.size() >= 1) { 073 a = Multisets.immutableEntry(entries.get(0), sortedMultiset.count(entries.get(0))); 074 if (entries.size() >= 3) { 075 b = Multisets.immutableEntry(entries.get(1), sortedMultiset.count(entries.get(1))); 076 c = Multisets.immutableEntry(entries.get(2), sortedMultiset.count(entries.get(2))); 077 } 078 } 079 } 080 081 /** Resets the contents of sortedMultiset to have entries a, c, for the navigation tests. */ 082 // Needed to stop Eclipse whining 083 private void resetWithHole() { 084 List<E> container = new ArrayList<>(); 085 container.addAll(Collections.nCopies(a.getCount(), a.getElement())); 086 container.addAll(Collections.nCopies(c.getCount(), c.getElement())); 087 super.resetContainer(getSubjectGenerator().create(container.toArray())); 088 sortedMultiset = (SortedMultiset<E>) getMultiset(); 089 } 090 091 @CollectionSize.Require(ZERO) 092 public void testEmptyMultisetFirst() { 093 assertNull(sortedMultiset.firstEntry()); 094 try { 095 sortedMultiset.elementSet().first(); 096 fail(); 097 } catch (NoSuchElementException e) { 098 } 099 } 100 101 @CollectionFeature.Require(SUPPORTS_REMOVE) 102 @CollectionSize.Require(ZERO) 103 public void testEmptyMultisetPollFirst() { 104 assertNull(sortedMultiset.pollFirstEntry()); 105 } 106 107 @CollectionSize.Require(ZERO) 108 public void testEmptyMultisetNearby() { 109 for (BoundType type : BoundType.values()) { 110 assertNull(sortedMultiset.headMultiset(e0(), type).lastEntry()); 111 assertNull(sortedMultiset.tailMultiset(e0(), type).firstEntry()); 112 } 113 } 114 115 @CollectionSize.Require(ZERO) 116 public void testEmptyMultisetLast() { 117 assertNull(sortedMultiset.lastEntry()); 118 try { 119 assertNull(sortedMultiset.elementSet().last()); 120 fail(); 121 } catch (NoSuchElementException e) { 122 } 123 } 124 125 @CollectionFeature.Require(SUPPORTS_REMOVE) 126 @CollectionSize.Require(ZERO) 127 public void testEmptyMultisetPollLast() { 128 assertNull(sortedMultiset.pollLastEntry()); 129 } 130 131 @CollectionSize.Require(ONE) 132 public void testSingletonMultisetFirst() { 133 assertEquals(a, sortedMultiset.firstEntry()); 134 } 135 136 @CollectionFeature.Require(SUPPORTS_REMOVE) 137 @CollectionSize.Require(ONE) 138 public void testSingletonMultisetPollFirst() { 139 assertEquals(a, sortedMultiset.pollFirstEntry()); 140 assertTrue(sortedMultiset.isEmpty()); 141 } 142 143 @CollectionSize.Require(ONE) 144 public void testSingletonMultisetNearby() { 145 assertNull(sortedMultiset.headMultiset(e0(), OPEN).lastEntry()); 146 assertNull(sortedMultiset.tailMultiset(e0(), OPEN).lastEntry()); 147 148 assertEquals(a, sortedMultiset.headMultiset(e0(), CLOSED).lastEntry()); 149 assertEquals(a, sortedMultiset.tailMultiset(e0(), CLOSED).firstEntry()); 150 } 151 152 @CollectionSize.Require(ONE) 153 public void testSingletonMultisetLast() { 154 assertEquals(a, sortedMultiset.lastEntry()); 155 } 156 157 @CollectionFeature.Require(SUPPORTS_REMOVE) 158 @CollectionSize.Require(ONE) 159 public void testSingletonMultisetPollLast() { 160 assertEquals(a, sortedMultiset.pollLastEntry()); 161 assertTrue(sortedMultiset.isEmpty()); 162 } 163 164 @CollectionSize.Require(SEVERAL) 165 public void testFirst() { 166 assertEquals(a, sortedMultiset.firstEntry()); 167 } 168 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 @CollectionFeature.Require(SUPPORTS_REMOVE) 224 @CollectionSize.Require(SEVERAL) 225 public void testPollLast() { 226 assertEquals(c, sortedMultiset.pollLastEntry()); 227 assertEquals(Arrays.asList(a, b), copyToList(sortedMultiset.entrySet())); 228 } 229 230 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 231 @CollectionSize.Require(SEVERAL) 232 public void testPollLastUnsupported() { 233 try { 234 sortedMultiset.pollLastEntry(); 235 fail(); 236 } catch (UnsupportedOperationException e) { 237 } 238 } 239 240 @CollectionSize.Require(SEVERAL) 241 public void testDescendingNavigation() { 242 List<Entry<E>> ascending = new ArrayList<>(); 243 Iterators.addAll(ascending, sortedMultiset.entrySet().iterator()); 244 List<Entry<E>> descending = new ArrayList<>(); 245 Iterators.addAll(descending, sortedMultiset.descendingMultiset().entrySet().iterator()); 246 Collections.reverse(descending); 247 assertEquals(ascending, descending); 248 } 249 250 void expectAddFailure(SortedMultiset<E> multiset, Entry<E> entry) { 251 try { 252 multiset.add(entry.getElement(), entry.getCount()); 253 fail("Expected IllegalArgumentException"); 254 } catch (IllegalArgumentException expected) { 255 } 256 257 try { 258 multiset.add(entry.getElement()); 259 fail("Expected IllegalArgumentException"); 260 } catch (IllegalArgumentException expected) { 261 } 262 263 try { 264 multiset.addAll(Collections.singletonList(entry.getElement())); 265 fail("Expected IllegalArgumentException"); 266 } catch (IllegalArgumentException expected) { 267 } 268 } 269 270 void expectRemoveZero(SortedMultiset<E> multiset, Entry<E> entry) { 271 assertEquals(0, multiset.remove(entry.getElement(), entry.getCount())); 272 assertFalse(multiset.remove(entry.getElement())); 273 assertFalse(multiset.elementSet().remove(entry.getElement())); 274 } 275 276 void expectSetCountFailure(SortedMultiset<E> multiset, Entry<E> entry) { 277 try { 278 multiset.setCount(entry.getElement(), multiset.count(entry.getElement())); 279 } catch (IllegalArgumentException acceptable) { 280 } 281 try { 282 multiset.setCount(entry.getElement(), multiset.count(entry.getElement()) + 1); 283 fail("Expected IllegalArgumentException"); 284 } catch (IllegalArgumentException expected) { 285 } 286 } 287 288 @CollectionSize.Require(ONE) 289 @CollectionFeature.Require(SUPPORTS_ADD) 290 public void testAddOutOfTailBoundsOne() { 291 expectAddFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 292 } 293 294 @CollectionSize.Require(SEVERAL) 295 @CollectionFeature.Require(SUPPORTS_ADD) 296 public void testAddOutOfTailBoundsSeveral() { 297 expectAddFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 298 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 299 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 300 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 301 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 302 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 303 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 304 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 305 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 306 } 307 308 @CollectionSize.Require(ONE) 309 @CollectionFeature.Require(SUPPORTS_ADD) 310 public void testAddOutOfHeadBoundsOne() { 311 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 312 } 313 314 @CollectionSize.Require(SEVERAL) 315 @CollectionFeature.Require(SUPPORTS_ADD) 316 public void testAddOutOfHeadBoundsSeveral() { 317 expectAddFailure(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 318 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 319 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 320 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 321 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 322 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 323 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 324 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 325 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 326 } 327 328 @CollectionSize.Require(ONE) 329 @CollectionFeature.Require(SUPPORTS_REMOVE) 330 public void testRemoveOutOfTailBoundsOne() { 331 expectRemoveZero(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 332 } 333 334 @CollectionSize.Require(SEVERAL) 335 @CollectionFeature.Require(SUPPORTS_REMOVE) 336 public void testRemoveOutOfTailBoundsSeveral() { 337 expectRemoveZero(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 338 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 339 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 340 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 341 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 342 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 343 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 344 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 345 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 346 } 347 348 @CollectionSize.Require(ONE) 349 @CollectionFeature.Require(SUPPORTS_REMOVE) 350 public void testRemoveOutOfHeadBoundsOne() { 351 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 352 } 353 354 @CollectionSize.Require(SEVERAL) 355 @CollectionFeature.Require(SUPPORTS_REMOVE) 356 public void testRemoveOutOfHeadBoundsSeveral() { 357 expectRemoveZero(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 358 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 359 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 360 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 361 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 362 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 363 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 364 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 365 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 366 } 367 368 @CollectionSize.Require(ONE) 369 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 370 public void testSetCountOutOfTailBoundsOne() { 371 expectSetCountFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 372 } 373 374 @CollectionSize.Require(SEVERAL) 375 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 376 public void testSetCountOutOfTailBoundsSeveral() { 377 expectSetCountFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 378 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 379 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 380 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 381 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 382 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 383 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 384 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 385 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 386 } 387 388 @CollectionSize.Require(ONE) 389 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 390 public void testSetCountOutOfHeadBoundsOne() { 391 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 392 } 393 394 @CollectionSize.Require(SEVERAL) 395 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 396 public void testSetCountOutOfHeadBoundsSeveral() { 397 expectSetCountFailure(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 398 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 399 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 400 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 401 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 402 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 403 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 404 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 405 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 406 } 407 408 @CollectionSize.Require(SEVERAL) 409 @CollectionFeature.Require(SUPPORTS_ADD) 410 public void testAddWithConflictingBounds() { 411 testEmptyRangeSubMultisetSupportingAdd( 412 sortedMultiset.subMultiset(a.getElement(), CLOSED, a.getElement(), OPEN)); 413 testEmptyRangeSubMultisetSupportingAdd( 414 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), OPEN)); 415 testEmptyRangeSubMultisetSupportingAdd( 416 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), CLOSED)); 417 testEmptyRangeSubMultisetSupportingAdd( 418 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), CLOSED)); 419 testEmptyRangeSubMultisetSupportingAdd( 420 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), OPEN)); 421 testEmptyRangeSubMultisetSupportingAdd( 422 sortedMultiset.subMultiset(b.getElement(), OPEN, a.getElement(), OPEN)); 423 } 424 425 @CollectionSize.Require(SEVERAL) 426 @CollectionFeature.Require(SUPPORTS_ADD) 427 public void testConflictingBounds() { 428 testEmptyRangeSubMultiset( 429 sortedMultiset.subMultiset(a.getElement(), CLOSED, a.getElement(), OPEN)); 430 testEmptyRangeSubMultiset( 431 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), OPEN)); 432 testEmptyRangeSubMultiset( 433 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), CLOSED)); 434 testEmptyRangeSubMultiset( 435 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), CLOSED)); 436 testEmptyRangeSubMultiset( 437 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), OPEN)); 438 testEmptyRangeSubMultiset( 439 sortedMultiset.subMultiset(b.getElement(), OPEN, a.getElement(), OPEN)); 440 } 441 442 public void testEmptyRangeSubMultiset(SortedMultiset<E> multiset) { 443 assertTrue(multiset.isEmpty()); 444 assertEquals(0, multiset.size()); 445 assertEquals(0, multiset.toArray().length); 446 assertTrue(multiset.entrySet().isEmpty()); 447 assertFalse(multiset.iterator().hasNext()); 448 assertEquals(0, multiset.entrySet().size()); 449 assertEquals(0, multiset.entrySet().toArray().length); 450 assertFalse(multiset.entrySet().iterator().hasNext()); 451 } 452 453 public void testEmptyRangeSubMultisetSupportingAdd(SortedMultiset<E> multiset) { 454 for (Entry<E> entry : Arrays.asList(a, b, c)) { 455 expectAddFailure(multiset, entry); 456 } 457 } 458 459 private static int totalSize(Iterable<? extends Entry<?>> entries) { 460 int sum = 0; 461 for (Entry<?> entry : entries) { 462 sum += entry.getCount(); 463 } 464 return sum; 465 } 466 467 private enum SubMultisetSpec { 468 TAIL_CLOSED { 469 @Override 470 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 471 return entries.subList(targetEntry, entries.size()); 472 } 473 474 @Override 475 <E> SortedMultiset<E> subMultiset( 476 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 477 return multiset.tailMultiset(entries.get(targetEntry).getElement(), CLOSED); 478 } 479 }, 480 TAIL_OPEN { 481 @Override 482 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 483 return entries.subList(targetEntry + 1, entries.size()); 484 } 485 486 @Override 487 <E> SortedMultiset<E> subMultiset( 488 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 489 return multiset.tailMultiset(entries.get(targetEntry).getElement(), OPEN); 490 } 491 }, 492 HEAD_CLOSED { 493 @Override 494 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 495 return entries.subList(0, targetEntry + 1); 496 } 497 498 @Override 499 <E> SortedMultiset<E> subMultiset( 500 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 501 return multiset.headMultiset(entries.get(targetEntry).getElement(), CLOSED); 502 } 503 }, 504 HEAD_OPEN { 505 @Override 506 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 507 return entries.subList(0, targetEntry); 508 } 509 510 @Override 511 <E> SortedMultiset<E> subMultiset( 512 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 513 return multiset.headMultiset(entries.get(targetEntry).getElement(), OPEN); 514 } 515 }; 516 517 abstract <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries); 518 519 abstract <E> SortedMultiset<E> subMultiset( 520 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry); 521 } 522 523 private void testSubMultisetEntrySet(SubMultisetSpec spec) { 524 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 525 for (int i = 0; i < entries.size(); i++) { 526 List<Entry<E>> expected = spec.expectedEntries(i, entries); 527 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 528 assertEquals(expected, copyToList(subMultiset.entrySet())); 529 } 530 } 531 532 private void testSubMultisetSize(SubMultisetSpec spec) { 533 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 534 for (int i = 0; i < entries.size(); i++) { 535 List<Entry<E>> expected = spec.expectedEntries(i, entries); 536 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 537 assertEquals(totalSize(expected), subMultiset.size()); 538 } 539 } 540 541 private void testSubMultisetDistinctElements(SubMultisetSpec spec) { 542 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 543 for (int i = 0; i < entries.size(); i++) { 544 List<Entry<E>> expected = spec.expectedEntries(i, entries); 545 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 546 assertEquals(expected.size(), subMultiset.entrySet().size()); 547 assertEquals(expected.size(), subMultiset.elementSet().size()); 548 } 549 } 550 551 public void testTailClosedEntrySet() { 552 testSubMultisetEntrySet(SubMultisetSpec.TAIL_CLOSED); 553 } 554 555 public void testTailClosedSize() { 556 testSubMultisetSize(SubMultisetSpec.TAIL_CLOSED); 557 } 558 559 public void testTailClosedDistinctElements() { 560 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_CLOSED); 561 } 562 563 public void testTailOpenEntrySet() { 564 testSubMultisetEntrySet(SubMultisetSpec.TAIL_OPEN); 565 } 566 567 public void testTailOpenSize() { 568 testSubMultisetSize(SubMultisetSpec.TAIL_OPEN); 569 } 570 571 public void testTailOpenDistinctElements() { 572 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_OPEN); 573 } 574 575 public void testHeadClosedEntrySet() { 576 testSubMultisetEntrySet(SubMultisetSpec.HEAD_CLOSED); 577 } 578 579 public void testHeadClosedSize() { 580 testSubMultisetSize(SubMultisetSpec.HEAD_CLOSED); 581 } 582 583 public void testHeadClosedDistinctElements() { 584 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_CLOSED); 585 } 586 587 public void testHeadOpenEntrySet() { 588 testSubMultisetEntrySet(SubMultisetSpec.HEAD_OPEN); 589 } 590 591 public void testHeadOpenSize() { 592 testSubMultisetSize(SubMultisetSpec.HEAD_OPEN); 593 } 594 595 public void testHeadOpenDistinctElements() { 596 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_OPEN); 597 } 598 599 @CollectionSize.Require(SEVERAL) 600 @CollectionFeature.Require(SUPPORTS_REMOVE) 601 public void testClearTailOpen() { 602 List<Entry<E>> expected = 603 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 604 sortedMultiset.tailMultiset(b.getElement(), OPEN).clear(); 605 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 606 } 607 608 @CollectionSize.Require(SEVERAL) 609 @CollectionFeature.Require(SUPPORTS_REMOVE) 610 public void testClearTailOpenEntrySet() { 611 List<Entry<E>> expected = 612 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 613 sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet().clear(); 614 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 615 } 616 617 @CollectionSize.Require(SEVERAL) 618 @CollectionFeature.Require(SUPPORTS_REMOVE) 619 public void testClearTailClosed() { 620 List<Entry<E>> expected = 621 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 622 sortedMultiset.tailMultiset(b.getElement(), CLOSED).clear(); 623 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 624 } 625 626 @CollectionSize.Require(SEVERAL) 627 @CollectionFeature.Require(SUPPORTS_REMOVE) 628 public void testClearTailClosedEntrySet() { 629 List<Entry<E>> expected = 630 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 631 sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet().clear(); 632 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 633 } 634 635 @CollectionSize.Require(SEVERAL) 636 @CollectionFeature.Require(SUPPORTS_REMOVE) 637 public void testClearHeadOpen() { 638 List<Entry<E>> expected = 639 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 640 sortedMultiset.headMultiset(b.getElement(), OPEN).clear(); 641 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 642 } 643 644 @CollectionSize.Require(SEVERAL) 645 @CollectionFeature.Require(SUPPORTS_REMOVE) 646 public void testClearHeadOpenEntrySet() { 647 List<Entry<E>> expected = 648 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 649 sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet().clear(); 650 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 651 } 652 653 @CollectionSize.Require(SEVERAL) 654 @CollectionFeature.Require(SUPPORTS_REMOVE) 655 public void testClearHeadClosed() { 656 List<Entry<E>> expected = 657 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 658 sortedMultiset.headMultiset(b.getElement(), CLOSED).clear(); 659 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 660 } 661 662 @CollectionSize.Require(SEVERAL) 663 @CollectionFeature.Require(SUPPORTS_REMOVE) 664 public void testClearHeadClosedEntrySet() { 665 List<Entry<E>> expected = 666 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 667 sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet().clear(); 668 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 669 } 670}