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; 025import static com.google.common.collect.testing.google.ReflectionFreeAssertThrows.assertThrows; 026import static java.util.Arrays.asList; 027import static java.util.Collections.nCopies; 028import static java.util.Collections.singletonList; 029import static java.util.Collections.sort; 030 031import com.google.common.annotations.GwtCompatible; 032import com.google.common.collect.BoundType; 033import com.google.common.collect.Iterators; 034import com.google.common.collect.Multiset; 035import com.google.common.collect.Multiset.Entry; 036import com.google.common.collect.Multisets; 037import com.google.common.collect.SortedMultiset; 038import com.google.common.collect.testing.features.CollectionFeature; 039import com.google.common.collect.testing.features.CollectionSize; 040import java.util.ArrayList; 041import java.util.Collections; 042import java.util.List; 043import java.util.NoSuchElementException; 044import org.junit.Ignore; 045 046/** 047 * Tester for navigation of SortedMultisets. 048 * 049 * @author Louis Wasserman 050 */ 051@GwtCompatible 052@Ignore("test runners must not instantiate and run this directly, only via suites we build") 053// @Ignore affects the Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. 054@SuppressWarnings("JUnit4ClassUsedInJUnit3") 055public class MultisetNavigationTester<E> extends AbstractMultisetTester<E> { 056 private SortedMultiset<E> sortedMultiset; 057 private List<E> entries; 058 private Entry<E> a; 059 private Entry<E> b; 060 private Entry<E> c; 061 062 /** Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557 */ 063 static <T> SortedMultiset<T> cast(Multiset<T> iterable) { 064 return (SortedMultiset<T>) iterable; 065 } 066 067 @Override 068 public void setUp() throws Exception { 069 super.setUp(); 070 sortedMultiset = cast(getMultiset()); 071 entries = 072 copyToList( 073 getSubjectGenerator() 074 .getSampleElements(getSubjectGenerator().getCollectionSize().getNumElements())); 075 sort(entries, sortedMultiset.comparator()); 076 077 // some tests assume SEVERAL == 3 078 if (entries.size() >= 1) { 079 a = Multisets.immutableEntry(entries.get(0), sortedMultiset.count(entries.get(0))); 080 if (entries.size() >= 3) { 081 b = Multisets.immutableEntry(entries.get(1), sortedMultiset.count(entries.get(1))); 082 c = Multisets.immutableEntry(entries.get(2), sortedMultiset.count(entries.get(2))); 083 } 084 } 085 } 086 087 /** Resets the contents of sortedMultiset to have entries a, c, for the navigation tests. */ 088 // Needed to stop Eclipse whining 089 private void resetWithHole() { 090 List<E> container = new ArrayList<>(); 091 container.addAll(nCopies(a.getCount(), a.getElement())); 092 container.addAll(nCopies(c.getCount(), c.getElement())); 093 super.resetContainer(getSubjectGenerator().create(container.toArray())); 094 sortedMultiset = (SortedMultiset<E>) getMultiset(); 095 } 096 097 @CollectionSize.Require(ZERO) 098 public void testEmptyMultisetFirst() { 099 assertNull(sortedMultiset.firstEntry()); 100 assertThrows(NoSuchElementException.class, () -> sortedMultiset.elementSet().first()); 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(e0(), type).lastEntry()); 113 assertNull(sortedMultiset.tailMultiset(e0(), type).firstEntry()); 114 } 115 } 116 117 @CollectionSize.Require(ZERO) 118 public void testEmptyMultisetLast() { 119 assertNull(sortedMultiset.lastEntry()); 120 assertThrows( 121 NoSuchElementException.class, () -> assertNull(sortedMultiset.elementSet().last())); 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 @CollectionFeature.Require(SUPPORTS_REMOVE) 169 @CollectionSize.Require(SEVERAL) 170 public void testPollFirst() { 171 assertEquals(a, sortedMultiset.pollFirstEntry()); 172 assertEquals(asList(b, c), copyToList(sortedMultiset.entrySet())); 173 } 174 175 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 176 public void testPollFirstUnsupported() { 177 assertThrows(UnsupportedOperationException.class, () -> sortedMultiset.pollFirstEntry()); 178 } 179 180 @CollectionSize.Require(SEVERAL) 181 public void testLower() { 182 resetWithHole(); 183 assertEquals(null, sortedMultiset.headMultiset(a.getElement(), OPEN).lastEntry()); 184 assertEquals(a, sortedMultiset.headMultiset(b.getElement(), OPEN).lastEntry()); 185 assertEquals(a, sortedMultiset.headMultiset(c.getElement(), OPEN).lastEntry()); 186 } 187 188 @CollectionSize.Require(SEVERAL) 189 public void testFloor() { 190 resetWithHole(); 191 assertEquals(a, sortedMultiset.headMultiset(a.getElement(), CLOSED).lastEntry()); 192 assertEquals(a, sortedMultiset.headMultiset(b.getElement(), CLOSED).lastEntry()); 193 assertEquals(c, sortedMultiset.headMultiset(c.getElement(), CLOSED).lastEntry()); 194 } 195 196 @CollectionSize.Require(SEVERAL) 197 public void testCeiling() { 198 resetWithHole(); 199 200 assertEquals(a, sortedMultiset.tailMultiset(a.getElement(), CLOSED).firstEntry()); 201 assertEquals(c, sortedMultiset.tailMultiset(b.getElement(), CLOSED).firstEntry()); 202 assertEquals(c, sortedMultiset.tailMultiset(c.getElement(), CLOSED).firstEntry()); 203 } 204 205 @CollectionSize.Require(SEVERAL) 206 public void testHigher() { 207 resetWithHole(); 208 assertEquals(c, sortedMultiset.tailMultiset(a.getElement(), OPEN).firstEntry()); 209 assertEquals(c, sortedMultiset.tailMultiset(b.getElement(), OPEN).firstEntry()); 210 assertEquals(null, sortedMultiset.tailMultiset(c.getElement(), OPEN).firstEntry()); 211 } 212 213 @CollectionSize.Require(SEVERAL) 214 public void testLast() { 215 assertEquals(c, sortedMultiset.lastEntry()); 216 } 217 218 @CollectionFeature.Require(SUPPORTS_REMOVE) 219 @CollectionSize.Require(SEVERAL) 220 public void testPollLast() { 221 assertEquals(c, sortedMultiset.pollLastEntry()); 222 assertEquals(asList(a, b), copyToList(sortedMultiset.entrySet())); 223 } 224 225 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 226 @CollectionSize.Require(SEVERAL) 227 public void testPollLastUnsupported() { 228 assertThrows(UnsupportedOperationException.class, () -> sortedMultiset.pollLastEntry()); 229 } 230 231 @CollectionSize.Require(SEVERAL) 232 public void testDescendingNavigation() { 233 List<Entry<E>> ascending = new ArrayList<>(); 234 Iterators.addAll(ascending, sortedMultiset.entrySet().iterator()); 235 List<Entry<E>> descending = new ArrayList<>(); 236 Iterators.addAll(descending, sortedMultiset.descendingMultiset().entrySet().iterator()); 237 Collections.reverse(descending); 238 assertEquals(ascending, descending); 239 } 240 241 void expectAddFailure(SortedMultiset<E> multiset, Entry<E> entry) { 242 try { 243 multiset.add(entry.getElement(), entry.getCount()); 244 fail("Expected IllegalArgumentException"); 245 } catch (IllegalArgumentException expected) { 246 } 247 248 try { 249 multiset.add(entry.getElement()); 250 fail("Expected IllegalArgumentException"); 251 } catch (IllegalArgumentException expected) { 252 } 253 254 try { 255 multiset.addAll(singletonList(entry.getElement())); 256 fail("Expected IllegalArgumentException"); 257 } catch (IllegalArgumentException expected) { 258 } 259 } 260 261 void expectRemoveZero(SortedMultiset<E> multiset, Entry<E> entry) { 262 assertEquals(0, multiset.remove(entry.getElement(), entry.getCount())); 263 assertFalse(multiset.remove(entry.getElement())); 264 assertFalse(multiset.elementSet().remove(entry.getElement())); 265 } 266 267 void expectSetCountFailure(SortedMultiset<E> multiset, Entry<E> entry) { 268 try { 269 multiset.setCount(entry.getElement(), multiset.count(entry.getElement())); 270 } catch (IllegalArgumentException acceptable) { 271 } 272 try { 273 multiset.setCount(entry.getElement(), multiset.count(entry.getElement()) + 1); 274 fail("Expected IllegalArgumentException"); 275 } catch (IllegalArgumentException expected) { 276 } 277 } 278 279 @CollectionSize.Require(ONE) 280 @CollectionFeature.Require(SUPPORTS_ADD) 281 public void testAddOutOfTailBoundsOne() { 282 expectAddFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 283 } 284 285 @CollectionSize.Require(SEVERAL) 286 @CollectionFeature.Require(SUPPORTS_ADD) 287 public void testAddOutOfTailBoundsSeveral() { 288 expectAddFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 289 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 290 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 291 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 292 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 293 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 294 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 295 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 296 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 297 } 298 299 @CollectionSize.Require(ONE) 300 @CollectionFeature.Require(SUPPORTS_ADD) 301 public void testAddOutOfHeadBoundsOne() { 302 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 303 } 304 305 @CollectionSize.Require(SEVERAL) 306 @CollectionFeature.Require(SUPPORTS_ADD) 307 public void testAddOutOfHeadBoundsSeveral() { 308 expectAddFailure(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 309 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 310 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 311 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 312 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 313 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 314 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 315 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 316 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 317 } 318 319 @CollectionSize.Require(ONE) 320 @CollectionFeature.Require(SUPPORTS_REMOVE) 321 public void testRemoveOutOfTailBoundsOne() { 322 expectRemoveZero(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 323 } 324 325 @CollectionSize.Require(SEVERAL) 326 @CollectionFeature.Require(SUPPORTS_REMOVE) 327 public void testRemoveOutOfTailBoundsSeveral() { 328 expectRemoveZero(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 329 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 330 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 331 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 332 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 333 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 334 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 335 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 336 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 337 } 338 339 @CollectionSize.Require(ONE) 340 @CollectionFeature.Require(SUPPORTS_REMOVE) 341 public void testRemoveOutOfHeadBoundsOne() { 342 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 343 } 344 345 @CollectionSize.Require(SEVERAL) 346 @CollectionFeature.Require(SUPPORTS_REMOVE) 347 public void testRemoveOutOfHeadBoundsSeveral() { 348 expectRemoveZero(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 349 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 350 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 351 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 352 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 353 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 354 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 355 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 356 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 357 } 358 359 @CollectionSize.Require(ONE) 360 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 361 public void testSetCountOutOfTailBoundsOne() { 362 expectSetCountFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 363 } 364 365 @CollectionSize.Require(SEVERAL) 366 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 367 public void testSetCountOutOfTailBoundsSeveral() { 368 expectSetCountFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 369 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 370 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 371 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 372 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 373 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 374 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 375 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 376 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 377 } 378 379 @CollectionSize.Require(ONE) 380 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 381 public void testSetCountOutOfHeadBoundsOne() { 382 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 383 } 384 385 @CollectionSize.Require(SEVERAL) 386 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 387 public void testSetCountOutOfHeadBoundsSeveral() { 388 expectSetCountFailure(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 389 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 390 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 391 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 392 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 393 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 394 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 395 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 396 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 397 } 398 399 @CollectionSize.Require(SEVERAL) 400 @CollectionFeature.Require(SUPPORTS_ADD) 401 public void testAddWithConflictingBounds() { 402 testEmptyRangeSubMultisetSupportingAdd( 403 sortedMultiset.subMultiset(a.getElement(), CLOSED, a.getElement(), OPEN)); 404 testEmptyRangeSubMultisetSupportingAdd( 405 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), OPEN)); 406 testEmptyRangeSubMultisetSupportingAdd( 407 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), CLOSED)); 408 testEmptyRangeSubMultisetSupportingAdd( 409 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), CLOSED)); 410 testEmptyRangeSubMultisetSupportingAdd( 411 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), OPEN)); 412 testEmptyRangeSubMultisetSupportingAdd( 413 sortedMultiset.subMultiset(b.getElement(), OPEN, a.getElement(), OPEN)); 414 } 415 416 @CollectionSize.Require(SEVERAL) 417 @CollectionFeature.Require(SUPPORTS_ADD) 418 public void testConflictingBounds() { 419 testEmptyRangeSubMultiset( 420 sortedMultiset.subMultiset(a.getElement(), CLOSED, a.getElement(), OPEN)); 421 testEmptyRangeSubMultiset( 422 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), OPEN)); 423 testEmptyRangeSubMultiset( 424 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), CLOSED)); 425 testEmptyRangeSubMultiset( 426 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), CLOSED)); 427 testEmptyRangeSubMultiset( 428 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), OPEN)); 429 testEmptyRangeSubMultiset( 430 sortedMultiset.subMultiset(b.getElement(), OPEN, a.getElement(), OPEN)); 431 } 432 433 public void testEmptyRangeSubMultiset(SortedMultiset<E> multiset) { 434 assertTrue(multiset.isEmpty()); 435 assertEquals(0, multiset.size()); 436 assertEquals(0, multiset.toArray().length); 437 assertTrue(multiset.entrySet().isEmpty()); 438 assertFalse(multiset.iterator().hasNext()); 439 assertEquals(0, multiset.entrySet().size()); 440 assertEquals(0, multiset.entrySet().toArray().length); 441 assertFalse(multiset.entrySet().iterator().hasNext()); 442 } 443 444 public void testEmptyRangeSubMultisetSupportingAdd(SortedMultiset<E> multiset) { 445 for (Entry<E> entry : asList(a, b, c)) { 446 expectAddFailure(multiset, entry); 447 } 448 } 449 450 private static int totalSize(Iterable<? extends Entry<?>> entries) { 451 int sum = 0; 452 for (Entry<?> entry : entries) { 453 sum += entry.getCount(); 454 } 455 return sum; 456 } 457 458 private enum SubMultisetSpec { 459 TAIL_CLOSED { 460 @Override 461 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 462 return entries.subList(targetEntry, entries.size()); 463 } 464 465 @Override 466 <E> SortedMultiset<E> subMultiset( 467 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 468 return multiset.tailMultiset(entries.get(targetEntry).getElement(), CLOSED); 469 } 470 }, 471 TAIL_OPEN { 472 @Override 473 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 474 return entries.subList(targetEntry + 1, entries.size()); 475 } 476 477 @Override 478 <E> SortedMultiset<E> subMultiset( 479 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 480 return multiset.tailMultiset(entries.get(targetEntry).getElement(), OPEN); 481 } 482 }, 483 HEAD_CLOSED { 484 @Override 485 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 486 return entries.subList(0, targetEntry + 1); 487 } 488 489 @Override 490 <E> SortedMultiset<E> subMultiset( 491 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 492 return multiset.headMultiset(entries.get(targetEntry).getElement(), CLOSED); 493 } 494 }, 495 HEAD_OPEN { 496 @Override 497 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 498 return entries.subList(0, targetEntry); 499 } 500 501 @Override 502 <E> SortedMultiset<E> subMultiset( 503 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 504 return multiset.headMultiset(entries.get(targetEntry).getElement(), OPEN); 505 } 506 }; 507 508 abstract <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries); 509 510 abstract <E> SortedMultiset<E> subMultiset( 511 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry); 512 } 513 514 private void testSubMultisetEntrySet(SubMultisetSpec spec) { 515 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 516 for (int i = 0; i < entries.size(); i++) { 517 List<Entry<E>> expected = spec.expectedEntries(i, entries); 518 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 519 assertEquals(expected, copyToList(subMultiset.entrySet())); 520 } 521 } 522 523 private void testSubMultisetSize(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(totalSize(expected), subMultiset.size()); 529 } 530 } 531 532 private void testSubMultisetDistinctElements(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(expected.size(), subMultiset.entrySet().size()); 538 assertEquals(expected.size(), subMultiset.elementSet().size()); 539 } 540 } 541 542 public void testTailClosedEntrySet() { 543 testSubMultisetEntrySet(SubMultisetSpec.TAIL_CLOSED); 544 } 545 546 public void testTailClosedSize() { 547 testSubMultisetSize(SubMultisetSpec.TAIL_CLOSED); 548 } 549 550 public void testTailClosedDistinctElements() { 551 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_CLOSED); 552 } 553 554 public void testTailOpenEntrySet() { 555 testSubMultisetEntrySet(SubMultisetSpec.TAIL_OPEN); 556 } 557 558 public void testTailOpenSize() { 559 testSubMultisetSize(SubMultisetSpec.TAIL_OPEN); 560 } 561 562 public void testTailOpenDistinctElements() { 563 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_OPEN); 564 } 565 566 public void testHeadClosedEntrySet() { 567 testSubMultisetEntrySet(SubMultisetSpec.HEAD_CLOSED); 568 } 569 570 public void testHeadClosedSize() { 571 testSubMultisetSize(SubMultisetSpec.HEAD_CLOSED); 572 } 573 574 public void testHeadClosedDistinctElements() { 575 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_CLOSED); 576 } 577 578 public void testHeadOpenEntrySet() { 579 testSubMultisetEntrySet(SubMultisetSpec.HEAD_OPEN); 580 } 581 582 public void testHeadOpenSize() { 583 testSubMultisetSize(SubMultisetSpec.HEAD_OPEN); 584 } 585 586 public void testHeadOpenDistinctElements() { 587 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_OPEN); 588 } 589 590 @CollectionSize.Require(SEVERAL) 591 @CollectionFeature.Require(SUPPORTS_REMOVE) 592 public void testClearTailOpen() { 593 List<Entry<E>> expected = 594 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 595 sortedMultiset.tailMultiset(b.getElement(), OPEN).clear(); 596 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 597 } 598 599 @CollectionSize.Require(SEVERAL) 600 @CollectionFeature.Require(SUPPORTS_REMOVE) 601 public void testClearTailOpenEntrySet() { 602 List<Entry<E>> expected = 603 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 604 sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet().clear(); 605 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 606 } 607 608 @CollectionSize.Require(SEVERAL) 609 @CollectionFeature.Require(SUPPORTS_REMOVE) 610 public void testClearTailClosed() { 611 List<Entry<E>> expected = 612 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 613 sortedMultiset.tailMultiset(b.getElement(), CLOSED).clear(); 614 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 615 } 616 617 @CollectionSize.Require(SEVERAL) 618 @CollectionFeature.Require(SUPPORTS_REMOVE) 619 public void testClearTailClosedEntrySet() { 620 List<Entry<E>> expected = 621 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 622 sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet().clear(); 623 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 624 } 625 626 @CollectionSize.Require(SEVERAL) 627 @CollectionFeature.Require(SUPPORTS_REMOVE) 628 public void testClearHeadOpen() { 629 List<Entry<E>> expected = 630 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 631 sortedMultiset.headMultiset(b.getElement(), OPEN).clear(); 632 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 633 } 634 635 @CollectionSize.Require(SEVERAL) 636 @CollectionFeature.Require(SUPPORTS_REMOVE) 637 public void testClearHeadOpenEntrySet() { 638 List<Entry<E>> expected = 639 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 640 sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet().clear(); 641 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 642 } 643 644 @CollectionSize.Require(SEVERAL) 645 @CollectionFeature.Require(SUPPORTS_REMOVE) 646 public void testClearHeadClosed() { 647 List<Entry<E>> expected = 648 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 649 sortedMultiset.headMultiset(b.getElement(), CLOSED).clear(); 650 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 651 } 652 653 @CollectionSize.Require(SEVERAL) 654 @CollectionFeature.Require(SUPPORTS_REMOVE) 655 public void testClearHeadClosedEntrySet() { 656 List<Entry<E>> expected = 657 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 658 sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet().clear(); 659 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 660 } 661}