Coverage Summary for Class: MultimapTestSuiteBuilder (com.google.common.collect.testing.google)
| Class | Method, % | Line, % |
|---|---|---|
| MultimapTestSuiteBuilder | 0% (0/18) | 0% (0/119) |
| MultimapTestSuiteBuilder$AsMapGenerator | 0% (0/9) | 0% (0/43) |
| MultimapTestSuiteBuilder$EntriesGenerator | 0% (0/6) | 0% (0/7) |
| MultimapTestSuiteBuilder$KeysGenerator | 0% (0/7) | 0% (0/29) |
| MultimapTestSuiteBuilder$MultimapAsMapGetGenerator | 0% (0/2) | 0% (0/9) |
| MultimapTestSuiteBuilder$MultimapGetGenerator | 0% (0/5) | 0% (0/28) |
| MultimapTestSuiteBuilder$ReserializedMultimapGenerator | 0% (0/10) | 0% (0/17) |
| MultimapTestSuiteBuilder$ValuesGenerator | 0% (0/5) | 0% (0/28) |
| Total | 0% (0/62) | 0% (0/280) |
1 /* 2 * Copyright (C) 2012 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect.testing.google; 18 19 import static com.google.common.base.Preconditions.checkArgument; 20 import static com.google.common.collect.testing.Helpers.mapEntry; 21 22 import com.google.common.annotations.GwtIncompatible; 23 import com.google.common.collect.ImmutableList; 24 import com.google.common.collect.ImmutableMultimap; 25 import com.google.common.collect.Multimap; 26 import com.google.common.collect.Multiset; 27 import com.google.common.collect.testing.AbstractTester; 28 import com.google.common.collect.testing.CollectionTestSuiteBuilder; 29 import com.google.common.collect.testing.DerivedGenerator; 30 import com.google.common.collect.testing.FeatureSpecificTestSuiteBuilder; 31 import com.google.common.collect.testing.Helpers; 32 import com.google.common.collect.testing.MapTestSuiteBuilder; 33 import com.google.common.collect.testing.OneSizeTestContainerGenerator; 34 import com.google.common.collect.testing.PerCollectionSizeTestSuiteBuilder; 35 import com.google.common.collect.testing.SampleElements; 36 import com.google.common.collect.testing.TestCollectionGenerator; 37 import com.google.common.collect.testing.TestMapGenerator; 38 import com.google.common.collect.testing.TestSubjectGenerator; 39 import com.google.common.collect.testing.features.CollectionFeature; 40 import com.google.common.collect.testing.features.CollectionSize; 41 import com.google.common.collect.testing.features.Feature; 42 import com.google.common.collect.testing.features.ListFeature; 43 import com.google.common.collect.testing.features.MapFeature; 44 import com.google.common.testing.SerializableTester; 45 import java.util.ArrayList; 46 import java.util.Collection; 47 import java.util.Collections; 48 import java.util.EnumSet; 49 import java.util.HashMap; 50 import java.util.HashSet; 51 import java.util.Iterator; 52 import java.util.LinkedHashMap; 53 import java.util.List; 54 import java.util.Map; 55 import java.util.Map.Entry; 56 import java.util.Set; 57 import junit.framework.TestSuite; 58 59 /** 60 * Creates, based on your criteria, a JUnit test suite that exhaustively tests a {@code Multimap} 61 * implementation. 62 * 63 * @author Louis Wasserman 64 */ 65 @GwtIncompatible 66 public class MultimapTestSuiteBuilder<K, V, M extends Multimap<K, V>> 67 extends PerCollectionSizeTestSuiteBuilder< 68 MultimapTestSuiteBuilder<K, V, M>, TestMultimapGenerator<K, V, M>, M, Entry<K, V>> { 69 70 public static <K, V, M extends Multimap<K, V>> MultimapTestSuiteBuilder<K, V, M> using( 71 TestMultimapGenerator<K, V, M> generator) { 72 return new MultimapTestSuiteBuilder<K, V, M>().usingGenerator(generator); 73 } 74 75 // Class parameters must be raw. 76 @Override 77 protected List<Class<? extends AbstractTester>> getTesters() { 78 return ImmutableList.<Class<? extends AbstractTester>>of( 79 MultimapAsMapGetTester.class, 80 MultimapAsMapTester.class, 81 MultimapSizeTester.class, 82 MultimapClearTester.class, 83 MultimapContainsKeyTester.class, 84 MultimapContainsValueTester.class, 85 MultimapContainsEntryTester.class, 86 MultimapEntriesTester.class, 87 MultimapEqualsTester.class, 88 MultimapForEachTester.class, 89 MultimapGetTester.class, 90 MultimapKeySetTester.class, 91 MultimapKeysTester.class, 92 MultimapPutTester.class, 93 MultimapPutAllMultimapTester.class, 94 MultimapPutIterableTester.class, 95 MultimapReplaceValuesTester.class, 96 MultimapRemoveEntryTester.class, 97 MultimapRemoveAllTester.class, 98 MultimapToStringTester.class, 99 MultimapValuesTester.class); 100 } 101 102 @Override 103 protected List<TestSuite> createDerivedSuites( 104 FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<M, Entry<K, V>>> 105 parentBuilder) { 106 // TODO: Once invariant support is added, supply invariants to each of the 107 // derived suites, to check that mutations to the derived collections are 108 // reflected in the underlying map. 109 110 List<TestSuite> derivedSuites = super.createDerivedSuites(parentBuilder); 111 112 if (parentBuilder.getFeatures().contains(CollectionFeature.SERIALIZABLE)) { 113 derivedSuites.add( 114 MultimapTestSuiteBuilder.using( 115 new ReserializedMultimapGenerator<K, V, M>(parentBuilder.getSubjectGenerator())) 116 .withFeatures(computeReserializedMultimapFeatures(parentBuilder.getFeatures())) 117 .named(parentBuilder.getName() + " reserialized") 118 .suppressing(parentBuilder.getSuppressedTests()) 119 .createTestSuite()); 120 } 121 122 derivedSuites.add( 123 MapTestSuiteBuilder.using(new AsMapGenerator<K, V, M>(parentBuilder.getSubjectGenerator())) 124 .withFeatures(computeAsMapFeatures(parentBuilder.getFeatures())) 125 .named(parentBuilder.getName() + ".asMap") 126 .suppressing(parentBuilder.getSuppressedTests()) 127 .createTestSuite()); 128 129 derivedSuites.add(computeEntriesTestSuite(parentBuilder)); 130 derivedSuites.add(computeMultimapGetTestSuite(parentBuilder)); 131 derivedSuites.add(computeMultimapAsMapGetTestSuite(parentBuilder)); 132 derivedSuites.add(computeKeysTestSuite(parentBuilder)); 133 derivedSuites.add(computeValuesTestSuite(parentBuilder)); 134 135 return derivedSuites; 136 } 137 138 TestSuite computeValuesTestSuite( 139 FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<M, Entry<K, V>>> 140 parentBuilder) { 141 return CollectionTestSuiteBuilder.using( 142 new ValuesGenerator<K, V, M>(parentBuilder.getSubjectGenerator())) 143 .withFeatures(computeValuesFeatures(parentBuilder.getFeatures())) 144 .named(parentBuilder.getName() + ".values") 145 .suppressing(parentBuilder.getSuppressedTests()) 146 .createTestSuite(); 147 } 148 149 TestSuite computeEntriesTestSuite( 150 FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<M, Entry<K, V>>> 151 parentBuilder) { 152 return CollectionTestSuiteBuilder.using( 153 new EntriesGenerator<K, V, M>(parentBuilder.getSubjectGenerator())) 154 .withFeatures(computeEntriesFeatures(parentBuilder.getFeatures())) 155 .named(parentBuilder.getName() + ".entries") 156 .suppressing(parentBuilder.getSuppressedTests()) 157 .createTestSuite(); 158 } 159 160 TestSuite computeMultimapGetTestSuite( 161 FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<M, Entry<K, V>>> 162 parentBuilder) { 163 return CollectionTestSuiteBuilder.using( 164 new MultimapGetGenerator<K, V, M>(parentBuilder.getSubjectGenerator())) 165 .withFeatures(computeMultimapGetFeatures(parentBuilder.getFeatures())) 166 .named(parentBuilder.getName() + ".get[key]") 167 .suppressing(parentBuilder.getSuppressedTests()) 168 .createTestSuite(); 169 } 170 171 TestSuite computeMultimapAsMapGetTestSuite( 172 FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<M, Entry<K, V>>> 173 parentBuilder) { 174 Set<Feature<?>> features = computeMultimapAsMapGetFeatures(parentBuilder.getFeatures()); 175 if (Collections.disjoint(features, EnumSet.allOf(CollectionSize.class))) { 176 return new TestSuite(); 177 } else { 178 return CollectionTestSuiteBuilder.using( 179 new MultimapAsMapGetGenerator<K, V, M>(parentBuilder.getSubjectGenerator())) 180 .withFeatures(features) 181 .named(parentBuilder.getName() + ".asMap[].get[key]") 182 .suppressing(parentBuilder.getSuppressedTests()) 183 .createTestSuite(); 184 } 185 } 186 187 TestSuite computeKeysTestSuite( 188 FeatureSpecificTestSuiteBuilder<?, ? extends OneSizeTestContainerGenerator<M, Entry<K, V>>> 189 parentBuilder) { 190 return MultisetTestSuiteBuilder.using( 191 new KeysGenerator<K, V, M>(parentBuilder.getSubjectGenerator())) 192 .withFeatures(computeKeysFeatures(parentBuilder.getFeatures())) 193 .named(parentBuilder.getName() + ".keys") 194 .suppressing(parentBuilder.getSuppressedTests()) 195 .createTestSuite(); 196 } 197 198 static Set<Feature<?>> computeDerivedCollectionFeatures(Set<Feature<?>> multimapFeatures) { 199 Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures); 200 if (!derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) { 201 derivedFeatures.remove(CollectionFeature.SERIALIZABLE); 202 } 203 if (derivedFeatures.remove(MapFeature.SUPPORTS_REMOVE)) { 204 derivedFeatures.add(CollectionFeature.SUPPORTS_REMOVE); 205 } 206 return derivedFeatures; 207 } 208 209 static Set<Feature<?>> computeEntriesFeatures(Set<Feature<?>> multimapFeatures) { 210 Set<Feature<?>> result = computeDerivedCollectionFeatures(multimapFeatures); 211 if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_ENTRY_QUERIES)) { 212 result.add(CollectionFeature.ALLOWS_NULL_QUERIES); 213 } 214 return result; 215 } 216 217 static Set<Feature<?>> computeValuesFeatures(Set<Feature<?>> multimapFeatures) { 218 Set<Feature<?>> result = computeDerivedCollectionFeatures(multimapFeatures); 219 if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_VALUES)) { 220 result.add(CollectionFeature.ALLOWS_NULL_VALUES); 221 } 222 if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_VALUE_QUERIES)) { 223 result.add(CollectionFeature.ALLOWS_NULL_QUERIES); 224 } 225 return result; 226 } 227 228 static Set<Feature<?>> computeKeysFeatures(Set<Feature<?>> multimapFeatures) { 229 Set<Feature<?>> result = computeDerivedCollectionFeatures(multimapFeatures); 230 if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_KEYS)) { 231 result.add(CollectionFeature.ALLOWS_NULL_VALUES); 232 } 233 if (multimapFeatures.contains(MapFeature.ALLOWS_NULL_KEY_QUERIES)) { 234 result.add(CollectionFeature.ALLOWS_NULL_QUERIES); 235 } 236 return result; 237 } 238 239 private static Set<Feature<?>> computeReserializedMultimapFeatures( 240 Set<Feature<?>> multimapFeatures) { 241 Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures); 242 derivedFeatures.remove(CollectionFeature.SERIALIZABLE); 243 derivedFeatures.remove(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS); 244 return derivedFeatures; 245 } 246 247 private static Set<Feature<?>> computeAsMapFeatures(Set<Feature<?>> multimapFeatures) { 248 Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures); 249 derivedFeatures.remove(MapFeature.GENERAL_PURPOSE); 250 derivedFeatures.remove(MapFeature.SUPPORTS_PUT); 251 derivedFeatures.remove(MapFeature.ALLOWS_NULL_VALUES); 252 derivedFeatures.add(MapFeature.ALLOWS_NULL_VALUE_QUERIES); 253 derivedFeatures.add(MapFeature.REJECTS_DUPLICATES_AT_CREATION); 254 if (!derivedFeatures.contains(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) { 255 derivedFeatures.remove(CollectionFeature.SERIALIZABLE); 256 } 257 return derivedFeatures; 258 } 259 260 private static final ImmutableMultimap<Feature<?>, Feature<?>> GET_FEATURE_MAP = 261 ImmutableMultimap.<Feature<?>, Feature<?>>builder() 262 .put( 263 MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, 264 CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION) 265 .put(MapFeature.GENERAL_PURPOSE, ListFeature.SUPPORTS_ADD_WITH_INDEX) 266 .put(MapFeature.GENERAL_PURPOSE, ListFeature.SUPPORTS_REMOVE_WITH_INDEX) 267 .put(MapFeature.GENERAL_PURPOSE, ListFeature.SUPPORTS_SET) 268 .put(MapFeature.ALLOWS_NULL_VALUE_QUERIES, CollectionFeature.ALLOWS_NULL_QUERIES) 269 .put(MapFeature.ALLOWS_NULL_VALUES, CollectionFeature.ALLOWS_NULL_VALUES) 270 .put(MapFeature.SUPPORTS_REMOVE, CollectionFeature.SUPPORTS_REMOVE) 271 .put(MapFeature.SUPPORTS_PUT, CollectionFeature.SUPPORTS_ADD) 272 .build(); 273 274 Set<Feature<?>> computeMultimapGetFeatures(Set<Feature<?>> multimapFeatures) { 275 Set<Feature<?>> derivedFeatures = Helpers.copyToSet(multimapFeatures); 276 for (Entry<Feature<?>, Feature<?>> entry : GET_FEATURE_MAP.entries()) { 277 if (derivedFeatures.contains(entry.getKey())) { 278 derivedFeatures.add(entry.getValue()); 279 } 280 } 281 if (derivedFeatures.remove(MultimapFeature.VALUE_COLLECTIONS_SUPPORT_ITERATOR_REMOVE)) { 282 derivedFeatures.add(CollectionFeature.SUPPORTS_ITERATOR_REMOVE); 283 } 284 if (!derivedFeatures.contains(CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS)) { 285 derivedFeatures.remove(CollectionFeature.SERIALIZABLE); 286 } 287 derivedFeatures.removeAll(GET_FEATURE_MAP.keySet()); 288 return derivedFeatures; 289 } 290 291 Set<Feature<?>> computeMultimapAsMapGetFeatures(Set<Feature<?>> multimapFeatures) { 292 Set<Feature<?>> derivedFeatures = 293 Helpers.copyToSet(computeMultimapGetFeatures(multimapFeatures)); 294 if (derivedFeatures.remove(CollectionSize.ANY)) { 295 derivedFeatures.addAll(CollectionSize.ANY.getImpliedFeatures()); 296 } 297 derivedFeatures.remove(CollectionSize.ZERO); 298 return derivedFeatures; 299 } 300 301 private static class AsMapGenerator<K, V, M extends Multimap<K, V>> 302 implements TestMapGenerator<K, Collection<V>>, DerivedGenerator { 303 private final OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator; 304 305 public AsMapGenerator(OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) { 306 this.multimapGenerator = multimapGenerator; 307 } 308 309 @Override 310 public TestSubjectGenerator<?> getInnerGenerator() { 311 return multimapGenerator; 312 } 313 314 private Collection<V> createCollection(V v) { 315 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 316 .createCollection(Collections.singleton(v)); 317 } 318 319 @Override 320 public SampleElements<Entry<K, Collection<V>>> samples() { 321 SampleElements<K> sampleKeys = 322 ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys(); 323 SampleElements<V> sampleValues = 324 ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleValues(); 325 return new SampleElements<>( 326 mapEntry(sampleKeys.e0(), createCollection(sampleValues.e0())), 327 mapEntry(sampleKeys.e1(), createCollection(sampleValues.e1())), 328 mapEntry(sampleKeys.e2(), createCollection(sampleValues.e2())), 329 mapEntry(sampleKeys.e3(), createCollection(sampleValues.e3())), 330 mapEntry(sampleKeys.e4(), createCollection(sampleValues.e4()))); 331 } 332 333 @Override 334 public Map<K, Collection<V>> create(Object... elements) { 335 Set<K> keySet = new HashSet<>(); 336 List<Entry<K, V>> builder = new ArrayList<>(); 337 for (Object o : elements) { 338 Entry<K, Collection<V>> entry = (Entry<K, Collection<V>>) o; 339 keySet.add(entry.getKey()); 340 for (V v : entry.getValue()) { 341 builder.add(mapEntry(entry.getKey(), v)); 342 } 343 } 344 checkArgument(keySet.size() == elements.length, "Duplicate keys"); 345 return multimapGenerator.create(builder.toArray()).asMap(); 346 } 347 348 @SuppressWarnings("unchecked") 349 @Override 350 public Entry<K, Collection<V>>[] createArray(int length) { 351 return new Entry[length]; 352 } 353 354 @Override 355 public Iterable<Entry<K, Collection<V>>> order(List<Entry<K, Collection<V>>> insertionOrder) { 356 Map<K, Collection<V>> map = new HashMap<>(); 357 List<Entry<K, V>> builder = new ArrayList<>(); 358 for (Entry<K, Collection<V>> entry : insertionOrder) { 359 for (V v : entry.getValue()) { 360 builder.add(mapEntry(entry.getKey(), v)); 361 } 362 map.put(entry.getKey(), entry.getValue()); 363 } 364 Iterable<Entry<K, V>> ordered = multimapGenerator.order(builder); 365 LinkedHashMap<K, Collection<V>> orderedMap = new LinkedHashMap<>(); 366 for (Entry<K, V> entry : ordered) { 367 orderedMap.put(entry.getKey(), map.get(entry.getKey())); 368 } 369 return orderedMap.entrySet(); 370 } 371 372 @Override 373 public K[] createKeyArray(int length) { 374 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 375 .createKeyArray(length); 376 } 377 378 @SuppressWarnings("unchecked") 379 @Override 380 public Collection<V>[] createValueArray(int length) { 381 return new Collection[length]; 382 } 383 } 384 385 static class EntriesGenerator<K, V, M extends Multimap<K, V>> 386 implements TestCollectionGenerator<Entry<K, V>>, DerivedGenerator { 387 private final OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator; 388 389 public EntriesGenerator(OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) { 390 this.multimapGenerator = multimapGenerator; 391 } 392 393 @Override 394 public TestSubjectGenerator<?> getInnerGenerator() { 395 return multimapGenerator; 396 } 397 398 @Override 399 public SampleElements<Entry<K, V>> samples() { 400 return multimapGenerator.samples(); 401 } 402 403 @Override 404 public Collection<Entry<K, V>> create(Object... elements) { 405 return multimapGenerator.create(elements).entries(); 406 } 407 408 @SuppressWarnings("unchecked") 409 @Override 410 public Entry<K, V>[] createArray(int length) { 411 return new Entry[length]; 412 } 413 414 @Override 415 public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) { 416 return multimapGenerator.order(insertionOrder); 417 } 418 } 419 420 static class ValuesGenerator<K, V, M extends Multimap<K, V>> 421 implements TestCollectionGenerator<V> { 422 private final OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator; 423 424 public ValuesGenerator(OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) { 425 this.multimapGenerator = multimapGenerator; 426 } 427 428 @Override 429 public SampleElements<V> samples() { 430 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 431 .sampleValues(); 432 } 433 434 @Override 435 public Collection<V> create(Object... elements) { 436 K k = 437 ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 438 .sampleKeys() 439 .e0(); 440 Entry<K, V>[] entries = new Entry[elements.length]; 441 for (int i = 0; i < elements.length; i++) { 442 entries[i] = mapEntry(k, (V) elements[i]); 443 } 444 return multimapGenerator.create((Object[]) entries).values(); 445 } 446 447 @SuppressWarnings("unchecked") 448 @Override 449 public V[] createArray(int length) { 450 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 451 .createValueArray(length); 452 } 453 454 @Override 455 public Iterable<V> order(List<V> insertionOrder) { 456 K k = 457 ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 458 .sampleKeys() 459 .e0(); 460 List<Entry<K, V>> entries = new ArrayList<>(); 461 for (V v : insertionOrder) { 462 entries.add(mapEntry(k, v)); 463 } 464 Iterable<Entry<K, V>> ordered = multimapGenerator.order(entries); 465 List<V> orderedValues = new ArrayList<>(); 466 for (Entry<K, V> entry : ordered) { 467 orderedValues.add(entry.getValue()); 468 } 469 return orderedValues; 470 } 471 } 472 473 static class KeysGenerator<K, V, M extends Multimap<K, V>> 474 implements TestMultisetGenerator<K>, DerivedGenerator { 475 private final OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator; 476 477 public KeysGenerator(OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) { 478 this.multimapGenerator = multimapGenerator; 479 } 480 481 @Override 482 public TestSubjectGenerator<?> getInnerGenerator() { 483 return multimapGenerator; 484 } 485 486 @Override 487 public SampleElements<K> samples() { 488 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys(); 489 } 490 491 @Override 492 public Multiset<K> create(Object... elements) { 493 /* 494 * This is nasty and complicated, but it's the only way to make sure keys get mapped to enough 495 * distinct values. 496 */ 497 Entry[] entries = new Entry[elements.length]; 498 Map<K, Iterator<V>> valueIterators = new HashMap<>(); 499 for (int i = 0; i < elements.length; i++) { 500 @SuppressWarnings("unchecked") 501 K key = (K) elements[i]; 502 503 Iterator<V> valueItr = valueIterators.get(key); 504 if (valueItr == null) { 505 valueIterators.put(key, valueItr = sampleValuesIterator()); 506 } 507 entries[i] = mapEntry((K) elements[i], valueItr.next()); 508 } 509 return multimapGenerator.create((Object[]) entries).keys(); 510 } 511 512 private Iterator<V> sampleValuesIterator() { 513 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 514 .sampleValues() 515 .iterator(); 516 } 517 518 @SuppressWarnings("unchecked") 519 @Override 520 public K[] createArray(int length) { 521 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 522 .createKeyArray(length); 523 } 524 525 @Override 526 public Iterable<K> order(List<K> insertionOrder) { 527 Iterator<V> valueIter = sampleValuesIterator(); 528 List<Entry<K, V>> entries = new ArrayList<>(); 529 for (K k : insertionOrder) { 530 entries.add(mapEntry(k, valueIter.next())); 531 } 532 Iterable<Entry<K, V>> ordered = multimapGenerator.order(entries); 533 List<K> orderedValues = new ArrayList<>(); 534 for (Entry<K, V> entry : ordered) { 535 orderedValues.add(entry.getKey()); 536 } 537 return orderedValues; 538 } 539 } 540 541 static class MultimapGetGenerator<K, V, M extends Multimap<K, V>> 542 implements TestCollectionGenerator<V> { 543 final OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator; 544 545 public MultimapGetGenerator(OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) { 546 this.multimapGenerator = multimapGenerator; 547 } 548 549 @Override 550 public SampleElements<V> samples() { 551 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 552 .sampleValues(); 553 } 554 555 @Override 556 public V[] createArray(int length) { 557 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 558 .createValueArray(length); 559 } 560 561 @Override 562 public Iterable<V> order(List<V> insertionOrder) { 563 K k = 564 ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 565 .sampleKeys() 566 .e0(); 567 List<Entry<K, V>> entries = new ArrayList<>(); 568 for (V v : insertionOrder) { 569 entries.add(mapEntry(k, v)); 570 } 571 Iterable<Entry<K, V>> orderedEntries = multimapGenerator.order(entries); 572 List<V> values = new ArrayList<>(); 573 for (Entry<K, V> entry : orderedEntries) { 574 values.add(entry.getValue()); 575 } 576 return values; 577 } 578 579 @Override 580 public Collection<V> create(Object... elements) { 581 Entry<K, V>[] array = multimapGenerator.createArray(elements.length); 582 K k = 583 ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 584 .sampleKeys() 585 .e0(); 586 for (int i = 0; i < elements.length; i++) { 587 array[i] = mapEntry(k, (V) elements[i]); 588 } 589 return multimapGenerator.create((Object[]) array).get(k); 590 } 591 } 592 593 static class MultimapAsMapGetGenerator<K, V, M extends Multimap<K, V>> 594 extends MultimapGetGenerator<K, V, M> { 595 596 public MultimapAsMapGetGenerator( 597 OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) { 598 super(multimapGenerator); 599 } 600 601 @Override 602 public Collection<V> create(Object... elements) { 603 Entry<K, V>[] array = multimapGenerator.createArray(elements.length); 604 K k = 605 ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 606 .sampleKeys() 607 .e0(); 608 for (int i = 0; i < elements.length; i++) { 609 array[i] = mapEntry(k, (V) elements[i]); 610 } 611 return multimapGenerator.create((Object[]) array).asMap().get(k); 612 } 613 } 614 615 private static class ReserializedMultimapGenerator<K, V, M extends Multimap<K, V>> 616 implements TestMultimapGenerator<K, V, M> { 617 private final OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator; 618 619 public ReserializedMultimapGenerator( 620 OneSizeTestContainerGenerator<M, Entry<K, V>> multimapGenerator) { 621 this.multimapGenerator = multimapGenerator; 622 } 623 624 @Override 625 public SampleElements<Entry<K, V>> samples() { 626 return multimapGenerator.samples(); 627 } 628 629 @Override 630 public Entry<K, V>[] createArray(int length) { 631 return multimapGenerator.createArray(length); 632 } 633 634 @Override 635 public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) { 636 return multimapGenerator.order(insertionOrder); 637 } 638 639 @Override 640 public M create(Object... elements) { 641 return SerializableTester.reserialize( 642 ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 643 .create(elements)); 644 } 645 646 @Override 647 public K[] createKeyArray(int length) { 648 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 649 .createKeyArray(length); 650 } 651 652 @Override 653 public V[] createValueArray(int length) { 654 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 655 .createValueArray(length); 656 } 657 658 @Override 659 public SampleElements<K> sampleKeys() { 660 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()).sampleKeys(); 661 } 662 663 @Override 664 public SampleElements<V> sampleValues() { 665 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 666 .sampleValues(); 667 } 668 669 @Override 670 public Collection<V> createCollection(Iterable<? extends V> values) { 671 return ((TestMultimapGenerator<K, V, M>) multimapGenerator.getInnerGenerator()) 672 .createCollection(values); 673 } 674 } 675 }