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 @SuppressWarnings("unchecked") 083 // Needed to stop Eclipse whining 084 private void resetWithHole() { 085 List<E> container = new ArrayList<E>(); 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 @SuppressWarnings("unchecked") 171 @CollectionFeature.Require(SUPPORTS_REMOVE) 172 @CollectionSize.Require(SEVERAL) 173 public void testPollFirst() { 174 assertEquals(a, sortedMultiset.pollFirstEntry()); 175 assertEquals(Arrays.asList(b, c), copyToList(sortedMultiset.entrySet())); 176 } 177 178 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 179 public void testPollFirstUnsupported() { 180 try { 181 sortedMultiset.pollFirstEntry(); 182 fail(); 183 } catch (UnsupportedOperationException e) { 184 } 185 } 186 187 @CollectionSize.Require(SEVERAL) 188 public void testLower() { 189 resetWithHole(); 190 assertEquals(null, sortedMultiset.headMultiset(a.getElement(), OPEN).lastEntry()); 191 assertEquals(a, sortedMultiset.headMultiset(b.getElement(), OPEN).lastEntry()); 192 assertEquals(a, sortedMultiset.headMultiset(c.getElement(), OPEN).lastEntry()); 193 } 194 195 @CollectionSize.Require(SEVERAL) 196 public void testFloor() { 197 resetWithHole(); 198 assertEquals(a, sortedMultiset.headMultiset(a.getElement(), CLOSED).lastEntry()); 199 assertEquals(a, sortedMultiset.headMultiset(b.getElement(), CLOSED).lastEntry()); 200 assertEquals(c, sortedMultiset.headMultiset(c.getElement(), CLOSED).lastEntry()); 201 } 202 203 @CollectionSize.Require(SEVERAL) 204 public void testCeiling() { 205 resetWithHole(); 206 207 assertEquals(a, sortedMultiset.tailMultiset(a.getElement(), CLOSED).firstEntry()); 208 assertEquals(c, sortedMultiset.tailMultiset(b.getElement(), CLOSED).firstEntry()); 209 assertEquals(c, sortedMultiset.tailMultiset(c.getElement(), CLOSED).firstEntry()); 210 } 211 212 @CollectionSize.Require(SEVERAL) 213 public void testHigher() { 214 resetWithHole(); 215 assertEquals(c, sortedMultiset.tailMultiset(a.getElement(), OPEN).firstEntry()); 216 assertEquals(c, sortedMultiset.tailMultiset(b.getElement(), OPEN).firstEntry()); 217 assertEquals(null, sortedMultiset.tailMultiset(c.getElement(), OPEN).firstEntry()); 218 } 219 220 @CollectionSize.Require(SEVERAL) 221 public void testLast() { 222 assertEquals(c, sortedMultiset.lastEntry()); 223 } 224 225 @SuppressWarnings("unchecked") 226 @CollectionFeature.Require(SUPPORTS_REMOVE) 227 @CollectionSize.Require(SEVERAL) 228 public void testPollLast() { 229 assertEquals(c, sortedMultiset.pollLastEntry()); 230 assertEquals(Arrays.asList(a, b), copyToList(sortedMultiset.entrySet())); 231 } 232 233 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 234 @CollectionSize.Require(SEVERAL) 235 public void testPollLastUnsupported() { 236 try { 237 sortedMultiset.pollLastEntry(); 238 fail(); 239 } catch (UnsupportedOperationException e) { 240 } 241 } 242 243 @CollectionSize.Require(SEVERAL) 244 public void testDescendingNavigation() { 245 List<Entry<E>> ascending = new ArrayList<>(); 246 Iterators.addAll(ascending, sortedMultiset.entrySet().iterator()); 247 List<Entry<E>> descending = new ArrayList<>(); 248 Iterators.addAll(descending, sortedMultiset.descendingMultiset().entrySet().iterator()); 249 Collections.reverse(descending); 250 assertEquals(ascending, descending); 251 } 252 253 void expectAddFailure(SortedMultiset<E> multiset, Entry<E> entry) { 254 try { 255 multiset.add(entry.getElement(), entry.getCount()); 256 fail("Expected IllegalArgumentException"); 257 } catch (IllegalArgumentException expected) { 258 } 259 260 try { 261 multiset.add(entry.getElement()); 262 fail("Expected IllegalArgumentException"); 263 } catch (IllegalArgumentException expected) { 264 } 265 266 try { 267 multiset.addAll(Collections.singletonList(entry.getElement())); 268 fail("Expected IllegalArgumentException"); 269 } catch (IllegalArgumentException expected) { 270 } 271 } 272 273 void expectRemoveZero(SortedMultiset<E> multiset, Entry<E> entry) { 274 assertEquals(0, multiset.remove(entry.getElement(), entry.getCount())); 275 assertFalse(multiset.remove(entry.getElement())); 276 assertFalse(multiset.elementSet().remove(entry.getElement())); 277 } 278 279 void expectSetCountFailure(SortedMultiset<E> multiset, Entry<E> entry) { 280 try { 281 multiset.setCount(entry.getElement(), multiset.count(entry.getElement())); 282 } catch (IllegalArgumentException acceptable) { 283 } 284 try { 285 multiset.setCount(entry.getElement(), multiset.count(entry.getElement()) + 1); 286 fail("Expected IllegalArgumentException"); 287 } catch (IllegalArgumentException expected) { 288 } 289 } 290 291 @CollectionSize.Require(ONE) 292 @CollectionFeature.Require(SUPPORTS_ADD) 293 public void testAddOutOfTailBoundsOne() { 294 expectAddFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 295 } 296 297 @CollectionSize.Require(SEVERAL) 298 @CollectionFeature.Require(SUPPORTS_ADD) 299 public void testAddOutOfTailBoundsSeveral() { 300 expectAddFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 301 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 302 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 303 expectAddFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 304 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 305 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 306 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 307 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 308 expectAddFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 309 } 310 311 @CollectionSize.Require(ONE) 312 @CollectionFeature.Require(SUPPORTS_ADD) 313 public void testAddOutOfHeadBoundsOne() { 314 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 315 } 316 317 @CollectionSize.Require(SEVERAL) 318 @CollectionFeature.Require(SUPPORTS_ADD) 319 public void testAddOutOfHeadBoundsSeveral() { 320 expectAddFailure(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 321 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 322 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 323 expectAddFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 324 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 325 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 326 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 327 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 328 expectAddFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 329 } 330 331 @CollectionSize.Require(ONE) 332 @CollectionFeature.Require(SUPPORTS_REMOVE) 333 public void testRemoveOutOfTailBoundsOne() { 334 expectRemoveZero(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 335 } 336 337 @CollectionSize.Require(SEVERAL) 338 @CollectionFeature.Require(SUPPORTS_REMOVE) 339 public void testRemoveOutOfTailBoundsSeveral() { 340 expectRemoveZero(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 341 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 342 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 343 expectRemoveZero(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 344 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 345 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 346 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 347 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 348 expectRemoveZero(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 349 } 350 351 @CollectionSize.Require(ONE) 352 @CollectionFeature.Require(SUPPORTS_REMOVE) 353 public void testRemoveOutOfHeadBoundsOne() { 354 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 355 } 356 357 @CollectionSize.Require(SEVERAL) 358 @CollectionFeature.Require(SUPPORTS_REMOVE) 359 public void testRemoveOutOfHeadBoundsSeveral() { 360 expectRemoveZero(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 361 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 362 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 363 expectRemoveZero(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 364 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 365 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 366 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 367 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 368 expectRemoveZero(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 369 } 370 371 @CollectionSize.Require(ONE) 372 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 373 public void testSetCountOutOfTailBoundsOne() { 374 expectSetCountFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 375 } 376 377 @CollectionSize.Require(SEVERAL) 378 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 379 public void testSetCountOutOfTailBoundsSeveral() { 380 expectSetCountFailure(sortedMultiset.tailMultiset(a.getElement(), OPEN), a); 381 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), CLOSED), a); 382 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), a); 383 expectSetCountFailure(sortedMultiset.tailMultiset(b.getElement(), OPEN), b); 384 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), a); 385 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), CLOSED), b); 386 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), a); 387 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), b); 388 expectSetCountFailure(sortedMultiset.tailMultiset(c.getElement(), OPEN), c); 389 } 390 391 @CollectionSize.Require(ONE) 392 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 393 public void testSetCountOutOfHeadBoundsOne() { 394 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 395 } 396 397 @CollectionSize.Require(SEVERAL) 398 @CollectionFeature.Require({SUPPORTS_ADD, SUPPORTS_REMOVE}) 399 public void testSetCountOutOfHeadBoundsSeveral() { 400 expectSetCountFailure(sortedMultiset.headMultiset(c.getElement(), OPEN), c); 401 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), CLOSED), c); 402 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), c); 403 expectSetCountFailure(sortedMultiset.headMultiset(b.getElement(), OPEN), b); 404 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), c); 405 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), CLOSED), b); 406 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), c); 407 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), b); 408 expectSetCountFailure(sortedMultiset.headMultiset(a.getElement(), OPEN), a); 409 } 410 411 @CollectionSize.Require(SEVERAL) 412 @CollectionFeature.Require(SUPPORTS_ADD) 413 public void testAddWithConflictingBounds() { 414 testEmptyRangeSubMultisetSupportingAdd( 415 sortedMultiset.subMultiset(a.getElement(), CLOSED, a.getElement(), OPEN)); 416 testEmptyRangeSubMultisetSupportingAdd( 417 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), OPEN)); 418 testEmptyRangeSubMultisetSupportingAdd( 419 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), CLOSED)); 420 testEmptyRangeSubMultisetSupportingAdd( 421 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), CLOSED)); 422 testEmptyRangeSubMultisetSupportingAdd( 423 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), OPEN)); 424 testEmptyRangeSubMultisetSupportingAdd( 425 sortedMultiset.subMultiset(b.getElement(), OPEN, a.getElement(), OPEN)); 426 } 427 428 @CollectionSize.Require(SEVERAL) 429 @CollectionFeature.Require(SUPPORTS_ADD) 430 public void testConflictingBounds() { 431 testEmptyRangeSubMultiset( 432 sortedMultiset.subMultiset(a.getElement(), CLOSED, a.getElement(), OPEN)); 433 testEmptyRangeSubMultiset( 434 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), OPEN)); 435 testEmptyRangeSubMultiset( 436 sortedMultiset.subMultiset(a.getElement(), OPEN, a.getElement(), CLOSED)); 437 testEmptyRangeSubMultiset( 438 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), CLOSED)); 439 testEmptyRangeSubMultiset( 440 sortedMultiset.subMultiset(b.getElement(), CLOSED, a.getElement(), OPEN)); 441 testEmptyRangeSubMultiset( 442 sortedMultiset.subMultiset(b.getElement(), OPEN, a.getElement(), OPEN)); 443 } 444 445 public void testEmptyRangeSubMultiset(SortedMultiset<E> multiset) { 446 assertTrue(multiset.isEmpty()); 447 assertEquals(0, multiset.size()); 448 assertEquals(0, multiset.toArray().length); 449 assertTrue(multiset.entrySet().isEmpty()); 450 assertFalse(multiset.iterator().hasNext()); 451 assertEquals(0, multiset.entrySet().size()); 452 assertEquals(0, multiset.entrySet().toArray().length); 453 assertFalse(multiset.entrySet().iterator().hasNext()); 454 } 455 456 @SuppressWarnings("unchecked") 457 public void testEmptyRangeSubMultisetSupportingAdd(SortedMultiset<E> multiset) { 458 for (Entry<E> entry : Arrays.asList(a, b, c)) { 459 expectAddFailure(multiset, entry); 460 } 461 } 462 463 private static int totalSize(Iterable<? extends Entry<?>> entries) { 464 int sum = 0; 465 for (Entry<?> entry : entries) { 466 sum += entry.getCount(); 467 } 468 return sum; 469 } 470 471 private enum SubMultisetSpec { 472 TAIL_CLOSED { 473 @Override 474 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 475 return entries.subList(targetEntry, entries.size()); 476 } 477 478 @Override 479 <E> SortedMultiset<E> subMultiset( 480 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 481 return multiset.tailMultiset(entries.get(targetEntry).getElement(), CLOSED); 482 } 483 }, 484 TAIL_OPEN { 485 @Override 486 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 487 return entries.subList(targetEntry + 1, entries.size()); 488 } 489 490 @Override 491 <E> SortedMultiset<E> subMultiset( 492 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 493 return multiset.tailMultiset(entries.get(targetEntry).getElement(), OPEN); 494 } 495 }, 496 HEAD_CLOSED { 497 @Override 498 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 499 return entries.subList(0, targetEntry + 1); 500 } 501 502 @Override 503 <E> SortedMultiset<E> subMultiset( 504 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 505 return multiset.headMultiset(entries.get(targetEntry).getElement(), CLOSED); 506 } 507 }, 508 HEAD_OPEN { 509 @Override 510 <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries) { 511 return entries.subList(0, targetEntry); 512 } 513 514 @Override 515 <E> SortedMultiset<E> subMultiset( 516 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry) { 517 return multiset.headMultiset(entries.get(targetEntry).getElement(), OPEN); 518 } 519 }; 520 521 abstract <E> List<Entry<E>> expectedEntries(int targetEntry, List<Entry<E>> entries); 522 523 abstract <E> SortedMultiset<E> subMultiset( 524 SortedMultiset<E> multiset, List<Entry<E>> entries, int targetEntry); 525 } 526 527 private void testSubMultisetEntrySet(SubMultisetSpec spec) { 528 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 529 for (int i = 0; i < entries.size(); i++) { 530 List<Entry<E>> expected = spec.expectedEntries(i, entries); 531 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 532 assertEquals(expected, copyToList(subMultiset.entrySet())); 533 } 534 } 535 536 private void testSubMultisetSize(SubMultisetSpec spec) { 537 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 538 for (int i = 0; i < entries.size(); i++) { 539 List<Entry<E>> expected = spec.expectedEntries(i, entries); 540 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 541 assertEquals(totalSize(expected), subMultiset.size()); 542 } 543 } 544 545 private void testSubMultisetDistinctElements(SubMultisetSpec spec) { 546 List<Entry<E>> entries = copyToList(sortedMultiset.entrySet()); 547 for (int i = 0; i < entries.size(); i++) { 548 List<Entry<E>> expected = spec.expectedEntries(i, entries); 549 SortedMultiset<E> subMultiset = spec.subMultiset(sortedMultiset, entries, i); 550 assertEquals(expected.size(), subMultiset.entrySet().size()); 551 assertEquals(expected.size(), subMultiset.elementSet().size()); 552 } 553 } 554 555 public void testTailClosedEntrySet() { 556 testSubMultisetEntrySet(SubMultisetSpec.TAIL_CLOSED); 557 } 558 559 public void testTailClosedSize() { 560 testSubMultisetSize(SubMultisetSpec.TAIL_CLOSED); 561 } 562 563 public void testTailClosedDistinctElements() { 564 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_CLOSED); 565 } 566 567 public void testTailOpenEntrySet() { 568 testSubMultisetEntrySet(SubMultisetSpec.TAIL_OPEN); 569 } 570 571 public void testTailOpenSize() { 572 testSubMultisetSize(SubMultisetSpec.TAIL_OPEN); 573 } 574 575 public void testTailOpenDistinctElements() { 576 testSubMultisetDistinctElements(SubMultisetSpec.TAIL_OPEN); 577 } 578 579 public void testHeadClosedEntrySet() { 580 testSubMultisetEntrySet(SubMultisetSpec.HEAD_CLOSED); 581 } 582 583 public void testHeadClosedSize() { 584 testSubMultisetSize(SubMultisetSpec.HEAD_CLOSED); 585 } 586 587 public void testHeadClosedDistinctElements() { 588 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_CLOSED); 589 } 590 591 public void testHeadOpenEntrySet() { 592 testSubMultisetEntrySet(SubMultisetSpec.HEAD_OPEN); 593 } 594 595 public void testHeadOpenSize() { 596 testSubMultisetSize(SubMultisetSpec.HEAD_OPEN); 597 } 598 599 public void testHeadOpenDistinctElements() { 600 testSubMultisetDistinctElements(SubMultisetSpec.HEAD_OPEN); 601 } 602 603 @CollectionSize.Require(SEVERAL) 604 @CollectionFeature.Require(SUPPORTS_REMOVE) 605 public void testClearTailOpen() { 606 List<Entry<E>> expected = 607 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 608 sortedMultiset.tailMultiset(b.getElement(), OPEN).clear(); 609 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 610 } 611 612 @CollectionSize.Require(SEVERAL) 613 @CollectionFeature.Require(SUPPORTS_REMOVE) 614 public void testClearTailOpenEntrySet() { 615 List<Entry<E>> expected = 616 copyToList(sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet()); 617 sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet().clear(); 618 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 619 } 620 621 @CollectionSize.Require(SEVERAL) 622 @CollectionFeature.Require(SUPPORTS_REMOVE) 623 public void testClearTailClosed() { 624 List<Entry<E>> expected = 625 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 626 sortedMultiset.tailMultiset(b.getElement(), CLOSED).clear(); 627 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 628 } 629 630 @CollectionSize.Require(SEVERAL) 631 @CollectionFeature.Require(SUPPORTS_REMOVE) 632 public void testClearTailClosedEntrySet() { 633 List<Entry<E>> expected = 634 copyToList(sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet()); 635 sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet().clear(); 636 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 637 } 638 639 @CollectionSize.Require(SEVERAL) 640 @CollectionFeature.Require(SUPPORTS_REMOVE) 641 public void testClearHeadOpen() { 642 List<Entry<E>> expected = 643 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 644 sortedMultiset.headMultiset(b.getElement(), OPEN).clear(); 645 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 646 } 647 648 @CollectionSize.Require(SEVERAL) 649 @CollectionFeature.Require(SUPPORTS_REMOVE) 650 public void testClearHeadOpenEntrySet() { 651 List<Entry<E>> expected = 652 copyToList(sortedMultiset.tailMultiset(b.getElement(), CLOSED).entrySet()); 653 sortedMultiset.headMultiset(b.getElement(), OPEN).entrySet().clear(); 654 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 655 } 656 657 @CollectionSize.Require(SEVERAL) 658 @CollectionFeature.Require(SUPPORTS_REMOVE) 659 public void testClearHeadClosed() { 660 List<Entry<E>> expected = 661 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 662 sortedMultiset.headMultiset(b.getElement(), CLOSED).clear(); 663 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 664 } 665 666 @CollectionSize.Require(SEVERAL) 667 @CollectionFeature.Require(SUPPORTS_REMOVE) 668 public void testClearHeadClosedEntrySet() { 669 List<Entry<E>> expected = 670 copyToList(sortedMultiset.tailMultiset(b.getElement(), OPEN).entrySet()); 671 sortedMultiset.headMultiset(b.getElement(), CLOSED).entrySet().clear(); 672 assertEquals(expected, copyToList(sortedMultiset.entrySet())); 673 } 674}