aboutsummaryrefslogtreecommitdiffstats
path: root/guava-tests/test/com/google
diff options
context:
space:
mode:
authorPaul Duffin <paulduffin@google.com>2015-01-06 16:17:43 +0000
committerPaul Duffin <paulduffin@google.com>2015-01-08 14:36:14 +0000
commit3c77433663281544363151bf284b0240dfd22a42 (patch)
tree80bc061726b4720c9bf713a2a494920b393c2a7e /guava-tests/test/com/google
parent5e6db342fc75b1945298142530f2d1d1861bce73 (diff)
downloadandroid_external_guava-3c77433663281544363151bf284b0240dfd22a42.tar.gz
android_external_guava-3c77433663281544363151bf284b0240dfd22a42.tar.bz2
android_external_guava-3c77433663281544363151bf284b0240dfd22a42.zip
Upgraded Guava to unmodified v14.0.1
This simply copies the Guava source for v14.0.1 straight from its github repository into this one. Additional commits will be made which will allow this to compile on Android. Change-Id: If0a8231e1d9530b7bdd94474403f7055e013979f
Diffstat (limited to 'guava-tests/test/com/google')
-rw-r--r--guava-tests/test/com/google/common/base/BenchmarkHelpers.java84
-rw-r--r--guava-tests/test/com/google/common/base/CaseFormatTest.java20
-rw-r--r--guava-tests/test/com/google/common/base/CharMatcherTest.java222
-rw-r--r--guava-tests/test/com/google/common/base/CharsetsTest.java10
-rw-r--r--guava-tests/test/com/google/common/base/EnumsTest.java51
-rw-r--r--guava-tests/test/com/google/common/base/EquivalenceTest.java70
-rw-r--r--guava-tests/test/com/google/common/base/EquivalencesTest.java63
-rw-r--r--guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java245
-rw-r--r--guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java33
-rw-r--r--guava-tests/test/com/google/common/base/FunctionsTest.java25
-rw-r--r--guava-tests/test/com/google/common/base/JoinerTest.java31
-rw-r--r--guava-tests/test/com/google/common/base/ObjectsTest.java2
-rw-r--r--guava-tests/test/com/google/common/base/OptionalTest.java116
-rw-r--r--guava-tests/test/com/google/common/base/PackageSanityTests.java30
-rw-r--r--guava-tests/test/com/google/common/base/PreconditionsTest.java2
-rw-r--r--guava-tests/test/com/google/common/base/PredicatesTest.java25
-rw-r--r--guava-tests/test/com/google/common/base/SplitterTest.java235
-rw-r--r--guava-tests/test/com/google/common/base/StopwatchTest.java65
-rw-r--r--guava-tests/test/com/google/common/base/StringsTest.java2
-rw-r--r--guava-tests/test/com/google/common/base/SuppliersTest.java37
-rw-r--r--guava-tests/test/com/google/common/base/ThrowablesTest.java12
-rw-r--r--guava-tests/test/com/google/common/base/ToStringHelperTest.java107
-rw-r--r--guava-tests/test/com/google/common/cache/AbstractCacheTest.java14
-rw-r--r--guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java503
-rw-r--r--guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java539
-rw-r--r--guava-tests/test/com/google/common/cache/CacheBuilderTest.java18
-rw-r--r--guava-tests/test/com/google/common/cache/CacheEvictionTest.java36
-rw-r--r--guava-tests/test/com/google/common/cache/CacheExpirationTest.java54
-rw-r--r--guava-tests/test/com/google/common/cache/CacheLoadingTest.java124
-rw-r--r--guava-tests/test/com/google/common/cache/CacheManualTest.java4
-rw-r--r--guava-tests/test/com/google/common/cache/CacheReferencesTest.java6
-rw-r--r--guava-tests/test/com/google/common/cache/CacheTesting.java11
-rw-r--r--guava-tests/test/com/google/common/cache/EmptyCachesTest.java4
-rw-r--r--guava-tests/test/com/google/common/cache/LocalCacheTest.java112
-rw-r--r--guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java63
-rw-r--r--guava-tests/test/com/google/common/cache/PackageSanityTests.java36
-rw-r--r--guava-tests/test/com/google/common/cache/PopulatedCachesTest.java35
-rw-r--r--guava-tests/test/com/google/common/cache/RemovalNotificationTest.java41
-rw-r--r--guava-tests/test/com/google/common/cache/TestingCacheLoaders.java9
-rw-r--r--guava-tests/test/com/google/common/cache/TestingRemovalListeners.java6
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractBiMapTest.java550
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractBstBalancePolicyTest.java115
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractCollectionTest.java6
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java27
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractImmutableTableTest.java29
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java68
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractMultimapTest.java98
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractMultisetTest.java9
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractRangeSetTest.java71
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractSequentialIteratorTest.java (renamed from guava-tests/test/com/google/common/collect/AbstractLinkedIteratorTest.java)22
-rw-r--r--guava-tests/test/com/google/common/collect/AbstractTableReadTest.java6
-rw-r--r--guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java52
-rw-r--r--guava-tests/test/com/google/common/collect/ArrayTableTest.java29
-rw-r--r--guava-tests/test/com/google/common/collect/BenchmarkHelpers.java297
-rw-r--r--guava-tests/test/com/google/common/collect/BiMapCollectionTest.java74
-rw-r--r--guava-tests/test/com/google/common/collect/BiMapMapInterfaceTest.java126
-rw-r--r--guava-tests/test/com/google/common/collect/BstCountBasedBalancePoliciesTest.java63
-rw-r--r--guava-tests/test/com/google/common/collect/BstInOrderPathTest.java199
-rw-r--r--guava-tests/test/com/google/common/collect/BstMutationResultTest.java33
-rw-r--r--guava-tests/test/com/google/common/collect/BstNodeTest.java125
-rw-r--r--guava-tests/test/com/google/common/collect/BstOperationsTest.java544
-rw-r--r--guava-tests/test/com/google/common/collect/BstPathTest.java55
-rw-r--r--guava-tests/test/com/google/common/collect/BstRangeOpsTest.java397
-rw-r--r--guava-tests/test/com/google/common/collect/BstTesting.java188
-rw-r--r--guava-tests/test/com/google/common/collect/CollectionBenchmarkSampleData.java155
-rw-r--r--guava-tests/test/com/google/common/collect/Collections2Test.java413
-rw-r--r--guava-tests/test/com/google/common/collect/ComparisonChainTest.java24
-rw-r--r--guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java45
-rw-r--r--guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java111
-rw-r--r--guava-tests/test/com/google/common/collect/ConstraintsTest.java65
-rw-r--r--guava-tests/test/com/google/common/collect/ContiguousSetNonGwtTest.java110
-rw-r--r--guava-tests/test/com/google/common/collect/ContiguousSetTest.java303
-rw-r--r--guava-tests/test/com/google/common/collect/CountTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/DiscreteDomainTest.java (renamed from guava-tests/test/com/google/common/collect/DiscreteDomainsTest.java)9
-rw-r--r--guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java33
-rw-r--r--guava-tests/test/com/google/common/collect/EnumBiMapTest.java166
-rw-r--r--guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java115
-rw-r--r--guava-tests/test/com/google/common/collect/EnumMultisetTest.java70
-rw-r--r--guava-tests/test/com/google/common/collect/FauxveridesTest.java12
-rw-r--r--guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java446
-rw-r--r--guava-tests/test/com/google/common/collect/FluentIterableTest.java728
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingBlockingDequeTest.java120
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingDequeTest.java225
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingListTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingMapTest.java40
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java4
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingNavigableMapTest.java380
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingNavigableSetTest.java255
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingQueueTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingSetTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java46
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/ForwardingTestCase.java2
-rw-r--r--guava-tests/test/com/google/common/collect/GeneralRangeTest.java38
-rw-r--r--guava-tests/test/com/google/common/collect/HashBasedTableTest.java22
-rw-r--r--guava-tests/test/com/google/common/collect/HashBiMapTest.java86
-rw-r--r--guava-tests/test/com/google/common/collect/HashMultimapTest.java44
-rw-r--r--guava-tests/test/com/google/common/collect/HashMultisetTest.java48
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java102
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableCollectionTest.java40
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java80
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java82
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableListTest.java76
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableMapTest.java133
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java13
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java82
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableRangeMapTest.java228
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java508
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSetCollectionTest.java253
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java99
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSetTest.java103
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java166
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java179
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java258
-rw-r--r--guava-tests/test/com/google/common/collect/ImmutableTableTest.java61
-rw-r--r--guava-tests/test/com/google/common/collect/InternersTest.java18
-rw-r--r--guava-tests/test/com/google/common/collect/IterablesTest.java83
-rw-r--r--guava-tests/test/com/google/common/collect/IteratorsTest.java96
-rw-r--r--guava-tests/test/com/google/common/collect/LenientSerializableTester.java9
-rw-r--r--guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java107
-rw-r--r--guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java57
-rw-r--r--guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java56
-rw-r--r--guava-tests/test/com/google/common/collect/ListsTest.java174
-rw-r--r--guava-tests/test/com/google/common/collect/MapConstraintsTest.java16
-rw-r--r--guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java43
-rw-r--r--guava-tests/test/com/google/common/collect/MapsCollectionTest.java639
-rw-r--r--guava-tests/test/com/google/common/collect/MapsSortedTransformValuesTest.java6
-rw-r--r--guava-tests/test/com/google/common/collect/MapsTest.java1378
-rw-r--r--guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java10
-rw-r--r--guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java51
-rw-r--r--guava-tests/test/com/google/common/collect/MultimapCollectionTest.java978
-rw-r--r--guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java661
-rw-r--r--guava-tests/test/com/google/common/collect/MultimapsTest.java151
-rw-r--r--guava-tests/test/com/google/common/collect/MultisetsCollectionTest.java (renamed from guava-tests/test/com/google/common/collect/MultisetCollectionTest.java)234
-rw-r--r--guava-tests/test/com/google/common/collect/MultisetsTest.java208
-rw-r--r--guava-tests/test/com/google/common/collect/NewCustomTableTest.java6
-rw-r--r--guava-tests/test/com/google/common/collect/ObjectArraysTest.java80
-rw-r--r--guava-tests/test/com/google/common/collect/OrderingTest.java291
-rw-r--r--guava-tests/test/com/google/common/collect/PackageSanityTests.java32
-rw-r--r--guava-tests/test/com/google/common/collect/QueuesTest.java11
-rw-r--r--guava-tests/test/com/google/common/collect/RangeNonGwtTest.java10
-rw-r--r--guava-tests/test/com/google/common/collect/RangeTest.java372
-rw-r--r--guava-tests/test/com/google/common/collect/RangesTest.java1
-rw-r--r--guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java17
-rw-r--r--guava-tests/test/com/google/common/collect/SetOperationsTest.java4
-rw-r--r--guava-tests/test/com/google/common/collect/SetsTest.java324
-rw-r--r--guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java13
-rw-r--r--guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java34
-rw-r--r--guava-tests/test/com/google/common/collect/SortedIterablesTest.java36
-rw-r--r--guava-tests/test/com/google/common/collect/SortedListsTest.java12
-rw-r--r--guava-tests/test/com/google/common/collect/SortedMapsTest.java222
-rw-r--r--guava-tests/test/com/google/common/collect/SpecialRandom.java55
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java78
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java14
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedNavigableMapTest.java392
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedNavigableSetTest.java268
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java177
-rw-r--r--guava-tests/test/com/google/common/collect/SynchronizedSetTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/TableCollectionTest.java15
-rw-r--r--guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java2
-rw-r--r--guava-tests/test/com/google/common/collect/TransformedImmutableListTest.java51
-rw-r--r--guava-tests/test/com/google/common/collect/TransformedSetTest.java126
-rw-r--r--guava-tests/test/com/google/common/collect/TreeBasedTableTest.java155
-rw-r--r--guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java35
-rw-r--r--guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java553
-rw-r--r--guava-tests/test/com/google/common/collect/TreeMultisetTest.java143
-rw-r--r--guava-tests/test/com/google/common/collect/TreeRangeMapTest.java480
-rw-r--r--guava-tests/test/com/google/common/collect/TreeRangeSetTest.java570
-rw-r--r--guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java4
-rw-r--r--guava-tests/test/com/google/common/eventbus/EventBusTest.java58
-rw-r--r--guava-tests/test/com/google/common/eventbus/EventHandlerTest.java41
-rw-r--r--guava-tests/test/com/google/common/eventbus/PackageSanityTests.java51
-rw-r--r--guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java4
-rw-r--r--guava-tests/test/com/google/common/eventbus/StringCatcher.java10
-rw-r--r--guava-tests/test/com/google/common/eventbus/outside/AnnotatedHandlerFinderTests.java451
-rw-r--r--guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java57
-rw-r--r--guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java140
-rw-r--r--guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java69
-rw-r--r--guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java115
-rw-r--r--guava-tests/test/com/google/common/hash/BloomFilterTest.java241
-rw-r--r--guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java87
-rw-r--r--guava-tests/test/com/google/common/hash/FunnelsTest.java92
-rw-r--r--guava-tests/test/com/google/common/hash/HashCodesTest.java126
-rw-r--r--guava-tests/test/com/google/common/hash/HashFunctionsTest.java74
-rw-r--r--guava-tests/test/com/google/common/hash/HashTestUtils.java506
-rw-r--r--guava-tests/test/com/google/common/hash/HashingTest.java215
-rw-r--r--guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java73
-rw-r--r--guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java71
-rw-r--r--guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java39
-rw-r--r--guava-tests/test/com/google/common/hash/PackageSanityTests.java35
-rw-r--r--guava-tests/test/com/google/common/io/BaseEncodingTest.java431
-rw-r--r--guava-tests/test/com/google/common/io/ByteSinkTest.java117
-rw-r--r--guava-tests/test/com/google/common/io/ByteSinkTester.java125
-rw-r--r--guava-tests/test/com/google/common/io/ByteSourceTest.java215
-rw-r--r--guava-tests/test/com/google/common/io/ByteSourceTester.java187
-rw-r--r--guava-tests/test/com/google/common/io/ByteStreamsTest.java382
-rw-r--r--guava-tests/test/com/google/common/io/CharSinkTest.java128
-rw-r--r--guava-tests/test/com/google/common/io/CharSinkTester.java135
-rw-r--r--guava-tests/test/com/google/common/io/CharSourceTest.java145
-rw-r--r--guava-tests/test/com/google/common/io/CharSourceTester.java147
-rw-r--r--guava-tests/test/com/google/common/io/CharStreamsTest.java144
-rw-r--r--guava-tests/test/com/google/common/io/CloseablesTest.java72
-rw-r--r--guava-tests/test/com/google/common/io/CloserTest.java461
-rw-r--r--guava-tests/test/com/google/common/io/FlushablesTest.java112
-rw-r--r--guava-tests/test/com/google/common/io/PackageSanityTests.java36
-rw-r--r--guava-tests/test/com/google/common/io/RandomAmountInputStream.java6
-rw-r--r--guava-tests/test/com/google/common/io/ResourcesTest.java48
-rw-r--r--guava-tests/test/com/google/common/io/SourceSinkFactories.java378
-rw-r--r--guava-tests/test/com/google/common/io/SourceSinkFactory.java101
-rw-r--r--guava-tests/test/com/google/common/io/SourceSinkTester.java125
-rw-r--r--guava-tests/test/com/google/common/io/TestByteSink.java75
-rw-r--r--guava-tests/test/com/google/common/io/TestByteSource.java74
-rw-r--r--guava-tests/test/com/google/common/io/TestCharSink.java76
-rw-r--r--guava-tests/test/com/google/common/io/TestCharSource.java52
-rw-r--r--guava-tests/test/com/google/common/io/TestInputStream.java91
-rw-r--r--guava-tests/test/com/google/common/io/TestOption.java30
-rw-r--r--guava-tests/test/com/google/common/io/TestOutputStream.java83
-rw-r--r--guava-tests/test/com/google/common/io/TestReader.java46
-rw-r--r--guava-tests/test/com/google/common/io/TestStreamSupplier.java37
-rw-r--r--guava-tests/test/com/google/common/io/TestWriter.java63
-rw-r--r--guava-tests/test/com/google/common/math/BigIntegerMathTest.java96
-rw-r--r--guava-tests/test/com/google/common/math/DoubleMathTest.java145
-rw-r--r--guava-tests/test/com/google/common/math/DoubleUtilsTest.java66
-rw-r--r--guava-tests/test/com/google/common/math/IntMathTest.java145
-rw-r--r--guava-tests/test/com/google/common/math/LongMathTest.java178
-rw-r--r--guava-tests/test/com/google/common/math/MathBenchmarking.java79
-rw-r--r--guava-tests/test/com/google/common/math/MathPreconditionsTest.java268
-rw-r--r--guava-tests/test/com/google/common/math/MathTesting.java32
-rw-r--r--guava-tests/test/com/google/common/math/PackageSanityTests.java27
-rw-r--r--guava-tests/test/com/google/common/math/TestPlatform.java (renamed from guava-tests/test/com/google/common/collect/InverseBiMapTest.java)17
-rw-r--r--guava-tests/test/com/google/common/net/HostAndPortTest.java232
-rw-r--r--guava-tests/test/com/google/common/net/HostSpecifierTest.java2
-rw-r--r--guava-tests/test/com/google/common/net/HttpHeadersTest.java5
-rw-r--r--guava-tests/test/com/google/common/net/InetAddressesTest.java44
-rw-r--r--guava-tests/test/com/google/common/net/InternetDomainNameTest.java15
-rw-r--r--guava-tests/test/com/google/common/net/MediaTypeTest.java432
-rw-r--r--guava-tests/test/com/google/common/net/PackageSanityTests.java31
-rw-r--r--guava-tests/test/com/google/common/net/TestPlatform.java26
-rw-r--r--guava-tests/test/com/google/common/primitives/BooleansTest.java94
-rw-r--r--guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/BytesTest.java24
-rw-r--r--guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/CharsTest.java6
-rw-r--r--guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/DoublesTest.java136
-rw-r--r--guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/FloatsTest.java124
-rw-r--r--guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/IntsTest.java26
-rw-r--r--guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/LongsTest.java101
-rw-r--r--guava-tests/test/com/google/common/primitives/PackageSanityTests.java31
-rw-r--r--guava-tests/test/com/google/common/primitives/PrimitivesTest.java2
-rw-r--r--guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java4
-rw-r--r--guava-tests/test/com/google/common/primitives/ShortsTest.java26
-rw-r--r--guava-tests/test/com/google/common/primitives/SignedBytesTest.java8
-rw-r--r--guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java98
-rw-r--r--guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java144
-rw-r--r--guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java134
-rw-r--r--guava-tests/test/com/google/common/primitives/UnsignedLongTest.java127
-rw-r--r--guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java198
-rw-r--r--guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java139
-rw-r--r--guava-tests/test/com/google/common/reflect/ClassPathTest.java374
-rw-r--r--guava-tests/test/com/google/common/reflect/ElementTest.java244
-rw-r--r--guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java186
-rw-r--r--guava-tests/test/com/google/common/reflect/InvokableTest.java536
-rw-r--r--guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java194
-rw-r--r--guava-tests/test/com/google/common/reflect/PackageSanityTests.java25
-rw-r--r--guava-tests/test/com/google/common/reflect/ParameterTest.java56
-rw-r--r--guava-tests/test/com/google/common/reflect/ReflectionTest.java92
-rw-r--r--guava-tests/test/com/google/common/reflect/TypeParameterTest.java61
-rw-r--r--guava-tests/test/com/google/common/reflect/TypeResolverTest.java216
-rw-r--r--guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java547
-rw-r--r--guava-tests/test/com/google/common/reflect/TypeTokenTest.java1517
-rw-r--r--guava-tests/test/com/google/common/reflect/TypesTest.java424
-rw-r--r--guava-tests/test/com/google/common/reflect/subpackage/ClassInSubPackage.java19
-rw-r--r--guava-tests/test/com/google/common/reflect/test.txt1
-rw-r--r--guava-tests/test/com/google/common/testing/EqualsTesterTest.java438
-rw-r--r--guava-tests/test/com/google/common/testing/EquivalenceTesterTest.java246
-rw-r--r--guava-tests/test/com/google/common/testing/FakeTickerTest.java74
-rw-r--r--guava-tests/test/com/google/common/testing/GcFinalizationTest.java178
-rw-r--r--guava-tests/test/com/google/common/testing/NullPointerTesterTest.java601
-rw-r--r--guava-tests/test/com/google/common/testing/SerializableTesterTest.java133
-rw-r--r--guava-tests/test/com/google/common/testing/TearDownStackTest.java174
-rw-r--r--guava-tests/test/com/google/common/testing/TestLogHandlerTest.java97
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java85
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java32
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java218
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java95
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java550
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java1
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java25
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java2
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java581
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java64
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingBlockingQueueTest.java28
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingCheckedFutureTest.java90
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingExecutorServiceTest.java28
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingFutureTest.java28
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingListenableFutureTest.java44
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingListeningExecutorServiceTest.java28
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java74
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTesterTest.java53
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ForwardingServiceTest.java28
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/FuturesTest.java693
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/InterruptionUtil.java2
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java20
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java11
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java9
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java240
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java27
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java363
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java2
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/StripedTest.java165
-rw-r--r--guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java23
316 files changed, 31432 insertions, 11008 deletions
diff --git a/guava-tests/test/com/google/common/base/BenchmarkHelpers.java b/guava-tests/test/com/google/common/base/BenchmarkHelpers.java
new file mode 100644
index 0000000..791c115
--- /dev/null
+++ b/guava-tests/test/com/google/common/base/BenchmarkHelpers.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.base;
+
+/**
+ * Common benchmarking utilities.
+ *
+ * @author Christopher Swenson
+ * @author Louis Wasserman
+ */
+class BenchmarkHelpers {
+ private static final String WHITESPACE_CHARACTERS =
+ "\u00a0\u180e\u202f\t\n\013\f\r \u0085"
+ + "\u1680\u2028\u2029\u205f\u3000\u2000\u2001\u2002\u2003\u2004\u2005"
+ + "\u2006\u2007\u2008\u2009\u200a";
+ private static final String ASCII_CHARACTERS;
+ static {
+ int spaceInAscii = 32;
+ int sevenBitAsciiMax = 128;
+ StringBuilder sb = new StringBuilder(sevenBitAsciiMax - spaceInAscii);
+ for (int ch = spaceInAscii; ch < sevenBitAsciiMax; ch++) {
+ sb.append((char) ch);
+ }
+ ASCII_CHARACTERS = sb.toString();
+ }
+
+ private static final String ALL_DIGITS;
+ static {
+ StringBuilder sb = new StringBuilder();
+ String zeros =
+ "0\u0660\u06f0\u07c0\u0966\u09e6\u0a66\u0ae6\u0b66\u0be6\u0c66"
+ + "\u0ce6\u0d66\u0e50\u0ed0\u0f20\u1040\u1090\u17e0\u1810\u1946"
+ + "\u19d0\u1b50\u1bb0\u1c40\u1c50\ua620\ua8d0\ua900\uaa50\uff10";
+ for (char base : zeros.toCharArray()) {
+ for (int offset = 0; offset < 10; offset++) {
+ sb.append((char) (base + offset));
+ }
+ }
+ ALL_DIGITS = sb.toString();
+ }
+
+ /**
+ * Sample CharMatcher instances for benchmarking.
+ */
+ public enum SampleMatcherConfig {
+ WHITESPACE(CharMatcher.WHITESPACE, WHITESPACE_CHARACTERS),
+ HASH(CharMatcher.is('#'), "#"),
+ ASCII(CharMatcher.ASCII, ASCII_CHARACTERS),
+ WESTERN_DIGIT("0123456789"),
+ ALL_DIGIT(CharMatcher.DIGIT, ALL_DIGITS),
+ OPS_5("+-*/%"),
+ HEX_16(CharMatcher.inRange('0', '9').or(CharMatcher.inRange('A', 'F')), "0123456789ABCDEF"),
+ HEX_22(CharMatcher.inRange('0', '9')
+ .or(CharMatcher.inRange('A', 'F')).or(CharMatcher.inRange('a', 'f')),
+ "0123456789ABCDEFabcdef"),
+ GERMAN_59(CharMatcher.inRange('a', 'z')
+ .or(CharMatcher.inRange('A', 'Z')).or(CharMatcher.anyOf("äöüßÄÖÜ")),
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZäöüßÄÖÜ");
+
+ public final CharMatcher matcher;
+ public final String matchingChars;
+
+ SampleMatcherConfig(String matchingChars) {
+ this(CharMatcher.anyOf(matchingChars), matchingChars);
+ }
+
+ SampleMatcherConfig(CharMatcher matcher, String matchingChars) {
+ this.matcher = matcher;
+ this.matchingChars = matchingChars;
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/base/CaseFormatTest.java b/guava-tests/test/com/google/common/base/CaseFormatTest.java
index daabfa3..d42bfc4 100644
--- a/guava-tests/test/com/google/common/base/CaseFormatTest.java
+++ b/guava-tests/test/com/google/common/base/CaseFormatTest.java
@@ -23,6 +23,8 @@ import static com.google.common.base.CaseFormat.UPPER_CAMEL;
import static com.google.common.base.CaseFormat.UPPER_UNDERSCORE;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -31,7 +33,7 @@ import junit.framework.TestCase;
*
* @author Mike Bostock
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class CaseFormatTest extends TestCase {
public void testIdentity() {
@@ -44,15 +46,13 @@ public class CaseFormatTest extends TestCase {
}
}
- public void testNullPointer() {
- try {
- LOWER_CAMEL.to(null, "");
- fail();
- } catch (NullPointerException expected) {}
- try {
- LOWER_CAMEL.to(LOWER_HYPHEN, null);
- fail();
- } catch (NullPointerException expected) {}
+ @GwtIncompatible("NullPointerTester")
+ public void testNullArguments() {
+ NullPointerTester tester = new NullPointerTester();
+ tester.testAllPublicStaticMethods(CaseFormat.class);
+ for (CaseFormat format : CaseFormat.values()) {
+ tester.testAllPublicInstanceMethods(format);
+ }
}
public void testLowerHyphenToLowerHyphen() {
diff --git a/guava-tests/test/com/google/common/base/CharMatcherTest.java b/guava-tests/test/com/google/common/base/CharMatcherTest.java
index 5fe5662..9bdd200 100644
--- a/guava-tests/test/com/google/common/base/CharMatcherTest.java
+++ b/guava-tests/test/com/google/common/base/CharMatcherTest.java
@@ -25,11 +25,18 @@ import static com.google.common.base.CharMatcher.noneOf;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.Sets;
import com.google.common.testing.NullPointerTester;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+
/**
* Unit test for {@link CharMatcher}.
*
@@ -68,7 +75,7 @@ public class CharMatcherTest extends TestCase {
assertSame(WHATEVER, CharMatcher.NONE.or(WHATEVER));
}
- // The rest of the behavior of ANY and NONE will be covered in the tests for
+ // The rest of the behavior of ANY and DEFAULT will be covered in the tests for
// the text processing methods below.
// The next tests require ICU4J and have, at least for now, been sliced out
@@ -82,8 +89,6 @@ public class CharMatcherTest extends TestCase {
}
}
- // There's no way to test LEGACY_WHITESPACE, really; it just is what it is.
-
// Omitting tests for the rest of the JAVA_* constants as these are defined
// as extremely straightforward pass-throughs to the JDK methods.
@@ -94,6 +99,34 @@ public class CharMatcherTest extends TestCase {
// method, but by overall "scenario". Also, the variety of actual tests we
// do borders on absurd overkill. Better safe than sorry, though?
+ @GwtIncompatible("java.util.BitSet")
+ public void testSetBits() {
+ doTestSetBits(CharMatcher.ANY);
+ doTestSetBits(CharMatcher.NONE);
+ doTestSetBits(is('a'));
+ doTestSetBits(isNot('a'));
+ doTestSetBits(anyOf(""));
+ doTestSetBits(anyOf("x"));
+ doTestSetBits(anyOf("xy"));
+ doTestSetBits(anyOf("CharMatcher"));
+ doTestSetBits(noneOf("CharMatcher"));
+ doTestSetBits(inRange('n', 'q'));
+ doTestSetBits(forPredicate(Predicates.equalTo('c')));
+ doTestSetBits(CharMatcher.ASCII);
+ doTestSetBits(CharMatcher.DIGIT);
+ doTestSetBits(CharMatcher.INVISIBLE);
+ doTestSetBits(inRange('A', 'Z').and(inRange('F', 'K').negate()));
+ }
+
+ @GwtIncompatible("java.util.BitSet")
+ private void doTestSetBits(CharMatcher matcher) {
+ BitSet bitset = new BitSet();
+ matcher.setBits(bitset);
+ for (int i = Character.MIN_VALUE; i <= Character.MAX_VALUE; i++) {
+ assertEquals(matcher.matches((char) i), bitset.get(i));
+ }
+ }
+
public void testEmpty() throws Exception {
doTestEmpty(CharMatcher.ANY);
doTestEmpty(CharMatcher.NONE);
@@ -339,14 +372,11 @@ public class CharMatcherTest extends TestCase {
assertFalse(matcher.matchesAllOf(s));
assertTrue(matcher.matchesNoneOf(s));
- // Note: only 'assertEquals' is promised by the API. Although they could
- // have been assertSame() on the server side, they have to be assertEquals
- // in GWT, because of GWT issue 4491.
- assertEquals(s, matcher.removeFrom(s));
- assertEquals(s, matcher.replaceFrom(s, 'z'));
- assertEquals(s, matcher.replaceFrom(s, "ZZ"));
- assertEquals(s, matcher.trimFrom(s));
- assertEquals(0, matcher.countIn(s));
+ assertSame(s, matcher.removeFrom(s));
+ assertSame(s, matcher.replaceFrom(s, 'z'));
+ assertSame(s, matcher.replaceFrom(s, "ZZ"));
+ assertSame(s, matcher.trimFrom(s));
+ assertSame(0, matcher.countIn(s));
}
private void reallyTestMatchThenNoMatch(CharMatcher matcher, String s) {
@@ -381,10 +411,23 @@ public class CharMatcherTest extends TestCase {
assertEquals(1, matcher.countIn(s));
}
+ /**
+ * Checks that expected is equals to out, and further, if in is
+ * equals to expected, then out is successfully optimized to be
+ * identical to in, i.e. that "in" is simply returned.
+ */
+ private void assertEqualsSame(String expected, String in, String out) {
+ if (expected.equals(in)) {
+ assertSame(in, out);
+ } else {
+ assertEquals(expected, out);
+ }
+ }
+
// Test collapse() a little differently than the rest, as we really want to
// cover lots of different configurations of input text
public void testCollapse() {
- // collapsing groups of - into _
+ // collapsing groups of '-' into '_' or '-'
doTestCollapse("-", "_");
doTestCollapse("x-", "x_");
doTestCollapse("-x", "_x");
@@ -411,30 +454,29 @@ public class CharMatcherTest extends TestCase {
private void doTestCollapse(String in, String out) {
// Try a few different matchers which all match '-' and not 'x'
- assertEquals(out, is('-').collapseFrom(in, '_'));
- assertEquals(out, is('-').or(is('#')).collapseFrom(in, '_'));
- assertEquals(out, isNot('x').collapseFrom(in, '_'));
- assertEquals(out, is('x').negate().collapseFrom(in, '_'));
- assertEquals(out, anyOf("-").collapseFrom(in, '_'));
- assertEquals(out, anyOf("-#").collapseFrom(in, '_'));
- assertEquals(out, anyOf("-#123").collapseFrom(in, '_'));
+ // Try replacement chars that both do and do not change the value.
+ for (char replacement : new char[] { '_', '-' }) {
+ String expected = out.replace('_', replacement);
+ assertEqualsSame(expected, in, is('-').collapseFrom(in, replacement));
+ assertEqualsSame(expected, in, is('-').collapseFrom(in, replacement));
+ assertEqualsSame(expected, in, is('-').or(is('#')).collapseFrom(in, replacement));
+ assertEqualsSame(expected, in, isNot('x').collapseFrom(in, replacement));
+ assertEqualsSame(expected, in, is('x').negate().collapseFrom(in, replacement));
+ assertEqualsSame(expected, in, anyOf("-").collapseFrom(in, replacement));
+ assertEqualsSame(expected, in, anyOf("-#").collapseFrom(in, replacement));
+ assertEqualsSame(expected, in, anyOf("-#123").collapseFrom(in, replacement));
+ }
}
private void doTestCollapseWithNoChange(String inout) {
- /*
- * Note: assertSame(), not promised by the spec, happens to work with the
- * current implementation because String.toString() promises to return
- * |this|. However, GWT bug 4491 keeps it from working there, so we stick
- * with assertEquals().
- */
- assertEquals(inout, is('-').collapseFrom(inout, '_'));
- assertEquals(inout, is('-').or(is('#')).collapseFrom(inout, '_'));
- assertEquals(inout, isNot('x').collapseFrom(inout, '_'));
- assertEquals(inout, is('x').negate().collapseFrom(inout, '_'));
- assertEquals(inout, anyOf("-").collapseFrom(inout, '_'));
- assertEquals(inout, anyOf("-#").collapseFrom(inout, '_'));
- assertEquals(inout, anyOf("-#123").collapseFrom(inout, '_'));
- assertEquals(inout, CharMatcher.NONE.collapseFrom(inout, '_'));
+ assertSame(inout, is('-').collapseFrom(inout, '_'));
+ assertSame(inout, is('-').or(is('#')).collapseFrom(inout, '_'));
+ assertSame(inout, isNot('x').collapseFrom(inout, '_'));
+ assertSame(inout, is('x').negate().collapseFrom(inout, '_'));
+ assertSame(inout, anyOf("-").collapseFrom(inout, '_'));
+ assertSame(inout, anyOf("-#").collapseFrom(inout, '_'));
+ assertSame(inout, anyOf("-#123").collapseFrom(inout, '_'));
+ assertSame(inout, CharMatcher.NONE.collapseFrom(inout, '_'));
}
public void testCollapse_any() {
@@ -548,7 +590,9 @@ public class CharMatcherTest extends TestCase {
}
public void testTrimAndCollapse() {
- // collapsing groups of - into _
+ // collapsing groups of '-' into '_' or '-'
+ doTestTrimAndCollapse("", "");
+ doTestTrimAndCollapse("x", "x");
doTestTrimAndCollapse("-", "");
doTestTrimAndCollapse("x-", "x");
doTestTrimAndCollapse("-x", "x");
@@ -571,13 +615,16 @@ public class CharMatcherTest extends TestCase {
private void doTestTrimAndCollapse(String in, String out) {
// Try a few different matchers which all match '-' and not 'x'
- assertEquals(out, is('-').trimAndCollapseFrom(in, '_'));
- assertEquals(out, is('-').or(is('#')).trimAndCollapseFrom(in, '_'));
- assertEquals(out, isNot('x').trimAndCollapseFrom(in, '_'));
- assertEquals(out, is('x').negate().trimAndCollapseFrom(in, '_'));
- assertEquals(out, anyOf("-").trimAndCollapseFrom(in, '_'));
- assertEquals(out, anyOf("-#").trimAndCollapseFrom(in, '_'));
- assertEquals(out, anyOf("-#123").trimAndCollapseFrom(in, '_'));
+ for (char replacement : new char[] { '_', '-' }) {
+ String expected = out.replace('_', replacement);
+ assertEqualsSame(expected, in, is('-').trimAndCollapseFrom(in, replacement));
+ assertEqualsSame(expected, in, is('-').or(is('#')).trimAndCollapseFrom(in, replacement));
+ assertEqualsSame(expected, in, isNot('x').trimAndCollapseFrom(in, replacement));
+ assertEqualsSame(expected, in, is('x').negate().trimAndCollapseFrom(in, replacement));
+ assertEqualsSame(expected, in, anyOf("-").trimAndCollapseFrom(in, replacement));
+ assertEqualsSame(expected, in, anyOf("-#").trimAndCollapseFrom(in, replacement));
+ assertEqualsSame(expected, in, anyOf("-#123").trimAndCollapseFrom(in, replacement));
+ }
}
public void testReplaceFrom() {
@@ -594,14 +641,107 @@ public class CharMatcherTest extends TestCase {
// build a precomputed version.
CharMatcher m1 = is('x');
assertSame(m1, m1.precomputed());
+ assertSame(m1.toString(), m1.precomputed().toString());
CharMatcher m2 = anyOf("Az");
assertSame(m2, m2.precomputed());
+ assertSame(m2.toString(), m2.precomputed().toString());
CharMatcher m3 = inRange('A', 'Z');
assertSame(m3, m3.precomputed());
+ assertSame(m3.toString(), m3.precomputed().toString());
assertSame(CharMatcher.NONE, CharMatcher.NONE.precomputed());
assertSame(CharMatcher.ANY, CharMatcher.ANY.precomputed());
}
+
+ @GwtIncompatible("java.util.BitSet")
+ private static BitSet bitSet(String chars) {
+ return bitSet(chars.toCharArray());
+ }
+
+ @GwtIncompatible("java.util.BitSet")
+ private static BitSet bitSet(char[] chars) {
+ BitSet tmp = new BitSet();
+ for (int i = 0; i < chars.length; i++) {
+ tmp.set(chars[i]);
+ }
+ return tmp;
+ }
+
+ @GwtIncompatible("java.util.Random, java.util.BitSet")
+ public void testSmallCharMatcher() {
+ CharMatcher len1 = SmallCharMatcher.from(bitSet("#"), "#");
+ CharMatcher len2 = SmallCharMatcher.from(bitSet("ab"), "ab");
+ CharMatcher len3 = SmallCharMatcher.from(bitSet("abc"), "abc");
+ CharMatcher len4 = SmallCharMatcher.from(bitSet("abcd"), "abcd");
+ assertTrue(len1.matches('#'));
+ assertFalse(len1.matches('!'));
+ assertTrue(len2.matches('a'));
+ assertTrue(len2.matches('b'));
+ for (char c = 'c'; c < 'z'; c++) {
+ assertFalse(len2.matches(c));
+ }
+ assertTrue(len3.matches('a'));
+ assertTrue(len3.matches('b'));
+ assertTrue(len3.matches('c'));
+ for (char c = 'd'; c < 'z'; c++) {
+ assertFalse(len3.matches(c));
+ }
+ assertTrue(len4.matches('a'));
+ assertTrue(len4.matches('b'));
+ assertTrue(len4.matches('c'));
+ assertTrue(len4.matches('d'));
+ for (char c = 'e'; c < 'z'; c++) {
+ assertFalse(len4.matches(c));
+ }
+
+ Random rand = new Random(1234);
+ for (int testCase = 0; testCase < 100; testCase++) {
+ char[] chars = randomChars(rand, rand.nextInt(63) + 1);
+ CharMatcher m = SmallCharMatcher.from(bitSet(chars), new String(chars));
+ checkExactMatches(m, chars);
+ }
+ }
+
+ static void checkExactMatches(CharMatcher m, char[] chars) {
+ Set<Character> positive = Sets.newHashSetWithExpectedSize(chars.length);
+ for (int i = 0; i < chars.length; i++) {
+ positive.add(chars[i]);
+ }
+ for (int c = 0; c <= Character.MAX_VALUE; c++) {
+ assertFalse(positive.contains(new Character((char) c)) ^ m.matches((char) c));
+ }
+ }
+
+ static char[] randomChars(Random rand, int size) {
+ Set<Character> chars = new HashSet<Character>(size);
+ for (int i = 0; i < size; i++) {
+ char c;
+ while (true) {
+ c = (char) rand.nextInt(Character.MAX_VALUE - Character.MIN_VALUE + 1);
+ if (!chars.contains(c)) {
+ break;
+ }
+ }
+ chars.add(c);
+ }
+ char[] retValue = new char[chars.size()];
+ int i = 0;
+ for (char c : chars) {
+ retValue[i++] = c;
+ }
+ Arrays.sort(retValue);
+ return retValue;
+ }
+
+ public void testToString() {
+ assertEquals("CharMatcher.NONE", CharMatcher.anyOf("").toString());
+ assertEquals("CharMatcher.is('\\u0031')", CharMatcher.anyOf("1").toString());
+ assertEquals("CharMatcher.anyOf(\"\\u0031\\u0032\")", CharMatcher.anyOf("12").toString());
+ assertEquals("CharMatcher.anyOf(\"\\u0031\\u0032\\u0033\")",
+ CharMatcher.anyOf("321").toString());
+ assertEquals("CharMatcher.inRange('\\u0031', '\\u0033')",
+ CharMatcher.inRange('1', '3').toString());
+ }
}
diff --git a/guava-tests/test/com/google/common/base/CharsetsTest.java b/guava-tests/test/com/google/common/base/CharsetsTest.java
index 67f2b07..e58bba6 100644
--- a/guava-tests/test/com/google/common/base/CharsetsTest.java
+++ b/guava-tests/test/com/google/common/base/CharsetsTest.java
@@ -16,6 +16,9 @@
package com.google.common.base;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+
import junit.framework.TestCase;
import java.nio.charset.Charset;
@@ -25,11 +28,15 @@ import java.nio.charset.Charset;
*
* @author Mike Bostock
*/
+@GwtCompatible(emulated = true)
public class CharsetsTest extends TestCase {
+
+ @GwtIncompatible("Non-UTF-8 Charset")
public void testUsAscii() {
assertEquals(Charset.forName("US-ASCII"), Charsets.US_ASCII);
}
+ @GwtIncompatible("Non-UTF-8 Charset")
public void testIso88591() {
assertEquals(Charset.forName("ISO-8859-1"), Charsets.ISO_8859_1);
}
@@ -38,14 +45,17 @@ public class CharsetsTest extends TestCase {
assertEquals(Charset.forName("UTF-8"), Charsets.UTF_8);
}
+ @GwtIncompatible("Non-UTF-8 Charset")
public void testUtf16be() {
assertEquals(Charset.forName("UTF-16BE"), Charsets.UTF_16BE);
}
+ @GwtIncompatible("Non-UTF-8 Charset")
public void testUtf16le() {
assertEquals(Charset.forName("UTF-16LE"), Charsets.UTF_16LE);
}
+ @GwtIncompatible("Non-UTF-8 Charset")
public void testUtf16() {
assertEquals(Charset.forName("UTF-16"), Charsets.UTF_16);
}
diff --git a/guava-tests/test/com/google/common/base/EnumsTest.java b/guava-tests/test/com/google/common/base/EnumsTest.java
index 142833b..473df7d 100644
--- a/guava-tests/test/com/google/common/base/EnumsTest.java
+++ b/guava-tests/test/com/google/common/base/EnumsTest.java
@@ -24,6 +24,10 @@ import com.google.common.testing.SerializableTester;
import junit.framework.TestCase;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Field;
+
/**
* Tests for {@link Enums}.
*
@@ -54,7 +58,7 @@ public class EnumsTest extends TestCase {
assertNull(function.apply("poodlE"));
}
- public void testValueOfFunction_nullWhenNotMatchingConstant() {
+ public void testValueOfFunction_nullWhenNoMatchingConstant() {
Function<String, TestEnum> function = Enums.valueOfFunction(TestEnum.class);
assertNull(function.apply("WOMBAT"));
}
@@ -73,9 +77,52 @@ public class EnumsTest extends TestCase {
SerializableTester.reserializeAndAssert(function);
}
+ public void testGetIfPresent() {
+ assertEquals(Optional.of(TestEnum.CHEETO), Enums.getIfPresent(TestEnum.class, "CHEETO"));
+ assertEquals(Optional.of(TestEnum.HONDA), Enums.getIfPresent(TestEnum.class, "HONDA"));
+ assertEquals(Optional.of(TestEnum.POODLE), Enums.getIfPresent(TestEnum.class, "POODLE"));
+
+ assertTrue(Enums.getIfPresent(TestEnum.class, "CHEETO").isPresent());
+ assertTrue(Enums.getIfPresent(TestEnum.class, "HONDA").isPresent());
+ assertTrue(Enums.getIfPresent(TestEnum.class, "POODLE").isPresent());
+
+ assertEquals(TestEnum.CHEETO, Enums.getIfPresent(TestEnum.class, "CHEETO").get());
+ assertEquals(TestEnum.HONDA, Enums.getIfPresent(TestEnum.class, "HONDA").get());
+ assertEquals(TestEnum.POODLE, Enums.getIfPresent(TestEnum.class, "POODLE").get());
+ }
+
+ public void testGetIfPresent_caseSensitive() {
+ assertFalse(Enums.getIfPresent(TestEnum.class, "cHEETO").isPresent());
+ assertFalse(Enums.getIfPresent(TestEnum.class, "Honda").isPresent());
+ assertFalse(Enums.getIfPresent(TestEnum.class, "poodlE").isPresent());
+ }
+
+ public void testGetIfPresent_whenNoMatchingConstant() {
+ assertEquals(Optional.absent(), Enums.getIfPresent(TestEnum.class, "WOMBAT"));
+ }
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Enums.class);
}
+
+ @Retention(RetentionPolicy.RUNTIME)
+ private @interface ExampleAnnotation {}
+
+ private enum AnEnum {
+ @ExampleAnnotation FOO,
+ BAR
+ }
+
+ @GwtIncompatible("reflection")
+ public void testGetField() {
+ Field foo = Enums.getField(AnEnum.FOO);
+ assertEquals("FOO", foo.getName());
+ assertTrue(foo.isAnnotationPresent(ExampleAnnotation.class));
+
+ Field bar = Enums.getField(AnEnum.BAR);
+ assertEquals("BAR", bar.getName());
+ assertFalse(bar.isAnnotationPresent(ExampleAnnotation.class));
+ }
}
diff --git a/guava-tests/test/com/google/common/base/EquivalenceTest.java b/guava-tests/test/com/google/common/base/EquivalenceTest.java
index 877aa67..cced838 100644
--- a/guava-tests/test/com/google/common/base/EquivalenceTest.java
+++ b/guava-tests/test/com/google/common/base/EquivalenceTest.java
@@ -18,9 +18,11 @@ package com.google.common.base;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Equivalence.Wrapper;
import com.google.common.collect.ImmutableList;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.EquivalenceTester;
+import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
import junit.framework.TestCase;
@@ -35,7 +37,7 @@ public class EquivalenceTest extends TestCase {
@SuppressWarnings("unchecked") // Iterable<String>...
public void testPairwiseEquivalent() {
- EquivalenceTester.of(Equivalences.equals().<String>pairwise())
+ EquivalenceTester.of(Equivalence.equals().<String>pairwise())
.addEquivalenceGroup(ImmutableList.<String>of())
.addEquivalenceGroup(ImmutableList.of("a"))
.addEquivalenceGroup(ImmutableList.of("b"))
@@ -45,8 +47,8 @@ public class EquivalenceTest extends TestCase {
public void testPairwiseEquivalent_equals() {
new EqualsTester()
- .addEqualityGroup(Equivalences.equals().pairwise(), Equivalences.equals().pairwise())
- .addEqualityGroup(Equivalences.identity().pairwise())
+ .addEqualityGroup(Equivalence.equals().pairwise(), Equivalence.equals().pairwise())
+ .addEqualityGroup(Equivalence.identity().pairwise())
.testEquals();
}
@@ -58,7 +60,7 @@ public class EquivalenceTest extends TestCase {
}
}
- private static final Equivalence<String> LENGTH_EQUIVALENCE = Equivalences.equals()
+ private static final Equivalence<String> LENGTH_EQUIVALENCE = Equivalence.equals()
.onResultOf(LengthFunction.INSTANCE);
public void testWrap() {
@@ -73,14 +75,22 @@ public class EquivalenceTest extends TestCase {
.addEqualityGroup(
LENGTH_EQUIVALENCE.wrap(null),
LENGTH_EQUIVALENCE.wrap(null))
- .addEqualityGroup(Equivalences.equals().wrap("hello"))
- .addEqualityGroup(Equivalences.equals().wrap(null))
+ .addEqualityGroup(Equivalence.equals().wrap("hello"))
+ .addEqualityGroup(Equivalence.equals().wrap(null))
.testEquals();
}
+ public void testWrap_get() {
+ String test = "test";
+ Wrapper<String> wrapper = LENGTH_EQUIVALENCE.wrap(test);
+ assertSame(test, wrapper.get());
+ }
+
@GwtIncompatible("SerializableTester")
- public void testWrapSerialization() {
+ public void testSerialization() {
SerializableTester.reserializeAndAssert(LENGTH_EQUIVALENCE.wrap("hello"));
+ SerializableTester.reserializeAndAssert(Equivalence.equals());
+ SerializableTester.reserializeAndAssert(Equivalence.identity());
}
private static class IntValue {
@@ -96,7 +106,7 @@ public class EquivalenceTest extends TestCase {
}
public void testOnResultOf() {
- EquivalenceTester.of(Equivalences.equals().onResultOf(Functions.toStringFunction()))
+ EquivalenceTester.of(Equivalence.equals().onResultOf(Functions.toStringFunction()))
.addEquivalenceGroup(new IntValue(1), new IntValue(1))
.addEquivalenceGroup(new IntValue(2))
.test();
@@ -105,27 +115,55 @@ public class EquivalenceTest extends TestCase {
public void testOnResultOf_equals() {
new EqualsTester()
.addEqualityGroup(
- Equivalences.identity().onResultOf(Functions.toStringFunction()),
- Equivalences.identity().onResultOf(Functions.toStringFunction()))
- .addEqualityGroup(Equivalences.equals().onResultOf(Functions.toStringFunction()))
- .addEqualityGroup(Equivalences.identity().onResultOf(Functions.identity()))
+ Equivalence.identity().onResultOf(Functions.toStringFunction()),
+ Equivalence.identity().onResultOf(Functions.toStringFunction()))
+ .addEqualityGroup(Equivalence.equals().onResultOf(Functions.toStringFunction()))
+ .addEqualityGroup(Equivalence.identity().onResultOf(Functions.identity()))
.testEquals();
}
public void testEquivalentTo() {
- Predicate<Object> equalTo1 = Equivalences.equals().equivalentTo("1");
+ Predicate<Object> equalTo1 = Equivalence.equals().equivalentTo("1");
assertTrue(equalTo1.apply("1"));
assertFalse(equalTo1.apply("2"));
assertFalse(equalTo1.apply(null));
- Predicate<Object> isNull = Equivalences.equals().equivalentTo(null);
+ Predicate<Object> isNull = Equivalence.equals().equivalentTo(null);
assertFalse(isNull.apply("1"));
assertFalse(isNull.apply("2"));
assertTrue(isNull.apply(null));
new EqualsTester()
- .addEqualityGroup(equalTo1, Equivalences.equals().equivalentTo("1"))
+ .addEqualityGroup(equalTo1, Equivalence.equals().equivalentTo("1"))
.addEqualityGroup(isNull)
- .addEqualityGroup(Equivalences.identity().equivalentTo("1"))
+ .addEqualityGroup(Equivalence.identity().equivalentTo("1"))
.testEquals();
}
+ public void testEqualsEquivalent() {
+ EquivalenceTester.of(Equivalence.equals())
+ .addEquivalenceGroup(new Integer(42), 42)
+ .addEquivalenceGroup("a")
+ .test();
+ }
+
+ public void testIdentityEquivalent() {
+ EquivalenceTester.of(Equivalence.identity())
+ .addEquivalenceGroup(new Integer(42))
+ .addEquivalenceGroup(new Integer(42))
+ .addEquivalenceGroup("a")
+ .test();
+ }
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(Equivalence.equals(), Equivalence.equals())
+ .addEqualityGroup(Equivalence.identity(), Equivalence.identity())
+ .testEquals();
+ }
+
+ @GwtIncompatible("NullPointerTester")
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(Equivalence.class);
+ new NullPointerTester().testAllPublicInstanceMethods(Equivalence.equals());
+ new NullPointerTester().testAllPublicInstanceMethods(Equivalence.identity());
+ }
}
diff --git a/guava-tests/test/com/google/common/base/EquivalencesTest.java b/guava-tests/test/com/google/common/base/EquivalencesTest.java
deleted file mode 100644
index 41d9fd0..0000000
--- a/guava-tests/test/com/google/common/base/EquivalencesTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * diOBJECTibuted under the License is diOBJECTibuted on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.base;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.testing.EqualsTester;
-import com.google.common.testing.EquivalenceTester;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.TestCase;
-
-/**
- * Unit test for {@link Equivalences}.
- *
- * @author Kurt Alfred Kluever
- * @author Jige Yu
- */
-@GwtCompatible(emulated = true)
-public class EquivalencesTest extends TestCase {
-
- public void testEqualsEquivalent() {
- EquivalenceTester.of(Equivalences.equals())
- .addEquivalenceGroup(new Integer(42), 42)
- .addEquivalenceGroup("a")
- .test();
- }
-
- public void testIdentityEquivalent() {
- EquivalenceTester.of(Equivalences.identity())
- .addEquivalenceGroup(new Integer(42))
- .addEquivalenceGroup(new Integer(42))
- .addEquivalenceGroup("a")
- .test();
- }
-
- public void testEquality() {
- new EqualsTester()
- .addEqualityGroup(Equivalences.equals(), Equivalences.equals())
- .addEqualityGroup(Equivalences.identity(), Equivalences.identity())
- .testEquals();
- }
-
- @GwtIncompatible("SerializableTester")
- public void testSerialization() {
- SerializableTester.reserializeAndAssert(Equivalences.equals());
- SerializableTester.reserializeAndAssert(Equivalences.identity());
- }
-}
diff --git a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java
new file mode 100644
index 0000000..7582300
--- /dev/null
+++ b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueClassLoaderUnloadingTest.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2005 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.testing.GcFinalization;
+import java.io.Closeable;
+
+import junit.framework.TestCase;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.Permission;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Tests that the {@code ClassLoader} of {@link FinalizableReferenceQueue} can be unloaded. These
+ * tests are separate from {@link FinalizableReferenceQueueTest} so that they can be excluded from
+ * coverage runs, as the coverage system interferes with them.
+ *
+ * @author Eamonn McManus
+ */
+public class FinalizableReferenceQueueClassLoaderUnloadingTest extends TestCase {
+
+ /*
+ * The following tests check that the use of FinalizableReferenceQueue does not prevent the
+ * ClassLoader that loaded that class from later being garbage-collected. If anything continues
+ * to reference the FinalizableReferenceQueue class then its ClassLoader cannot be
+ * garbage-collected, even if there are no more instances of FinalizableReferenceQueue itself.
+ * The code in FinalizableReferenceQueue goes to considerable trouble to ensure that there are
+ * no such references and the tests here check that that trouble has not been in vain.
+ *
+ * When we reference FinalizableReferenceQueue in this test, we are referencing a class that is
+ * loaded by this test and that will obviously remain loaded for as long as the test is running.
+ * So in order to check ClassLoader garbage collection we need to create a new ClassLoader and
+ * make it load its own version of FinalizableReferenceQueue. Then we need to interact with that
+ * parallel version through reflection in order to exercise the parallel
+ * FinalizableReferenceQueue, and then check that the parallel ClassLoader can be
+ * garbage-collected after that.
+ */
+
+ public static class MyFinalizableWeakReference extends FinalizableWeakReference<Object> {
+ public MyFinalizableWeakReference(Object x, FinalizableReferenceQueue queue) {
+ super(x, queue);
+ }
+
+ public void finalizeReferent() {
+ }
+ }
+
+ private static class PermissivePolicy extends Policy {
+ @Override
+ public boolean implies(ProtectionDomain pd, Permission perm) {
+ return true;
+ }
+ }
+
+ private WeakReference<ClassLoader> useFrqInSeparateLoader() throws Exception {
+ final URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader();
+ final URL[] urls = myLoader.getURLs();
+ URLClassLoader sepLoader = new URLClassLoader(urls, myLoader.getParent());
+ // sepLoader is the loader that we will use to load the parallel FinalizableReferenceQueue (FRQ)
+ // and friends, and that we will eventually expect to see garbage-collected. The assumption
+ // is that the ClassLoader of this test is a URLClassLoader, and that it loads FRQ itself
+ // rather than delegating to a parent ClassLoader. If this assumption is violated the test will
+ // fail and will need to be rewritten.
+
+ Class<?> frqC = FinalizableReferenceQueue.class;
+ Class<?> sepFrqC = sepLoader.loadClass(frqC.getName());
+ assertNotSame(frqC, sepFrqC);
+ // Check the assumptions above.
+
+ // FRQ tries to load the Finalizer class (for the reference-collecting thread) in a few ways.
+ // If the class is accessible to the system ClassLoader (ClassLoader.getSystemClassLoader())
+ // then FRQ does not bother to load Finalizer.class through a separate ClassLoader. That happens
+ // in our test environment, which foils the purpose of this test, so we disable the logic for
+ // our test by setting a static field. We are changing the field in the parallel version of FRQ
+ // and each test creates its own one of those, so there is no test interference here.
+ Class<?> sepFrqSystemLoaderC =
+ sepLoader.loadClass(FinalizableReferenceQueue.SystemLoader.class.getName());
+ Field disabled = sepFrqSystemLoaderC.getDeclaredField("disabled");
+ disabled.setAccessible(true);
+ disabled.set(null, true);
+
+ // Now make a parallel FRQ and an associated FinalizableWeakReference to an object, in order to
+ // exercise some classes from the parallel ClassLoader.
+ AtomicReference<Object> sepFrqA = new AtomicReference<Object>(sepFrqC.newInstance());
+ @SuppressWarnings("unchecked")
+ Class<? extends WeakReference<?>> sepFwrC = (Class<? extends WeakReference<?>>)
+ sepLoader.loadClass(MyFinalizableWeakReference.class.getName());
+ Constructor<? extends WeakReference<?>> sepFwrCons =
+ sepFwrC.getConstructor(Object.class, sepFrqC);
+ // The object that we will wrap in FinalizableWeakReference is a Stopwatch.
+ Class<?> sepStopwatchC = sepLoader.loadClass(Stopwatch.class.getName());
+ assertSame(sepLoader, sepStopwatchC.getClassLoader());
+ AtomicReference<Object> sepStopwatchA =
+ new AtomicReference<Object>(sepStopwatchC.newInstance());
+ AtomicReference<WeakReference<?>> sepStopwatchRef =
+ new AtomicReference<WeakReference<?>>(
+ sepFwrCons.newInstance(sepStopwatchA.get(), sepFrqA.get()));
+ assertNotNull(sepStopwatchA.get());
+ // Clear all references to the Stopwatch and wait for it to be gc'd.
+ sepStopwatchA.set(null);
+ GcFinalization.awaitClear(sepStopwatchRef.get());
+ // Return a weak reference to the parallel ClassLoader. This is the reference that should
+ // eventually become clear if there are no other references to the ClassLoader.
+ return new WeakReference<ClassLoader>(sepLoader);
+ }
+
+ private void doTestUnloadable() throws Exception {
+ WeakReference<ClassLoader> loaderRef = useFrqInSeparateLoader();
+ GcFinalization.awaitClear(loaderRef);
+ }
+
+ public void testUnloadableWithoutSecurityManager() throws Exception {
+ // Test that the use of a FinalizableReferenceQueue does not subsequently prevent the
+ // loader of that class from being garbage-collected.
+ SecurityManager oldSecurityManager = System.getSecurityManager();
+ try {
+ System.setSecurityManager(null);
+ doTestUnloadable();
+ } finally {
+ System.setSecurityManager(oldSecurityManager);
+ }
+ }
+
+ public void testUnloadableWithSecurityManager() throws Exception {
+ // Test that the use of a FinalizableReferenceQueue does not subsequently prevent the
+ // loader of that class from being garbage-collected even if there is a SecurityManager.
+ // The SecurityManager environment makes such leaks more likely because when you create
+ // a URLClassLoader with a SecurityManager, the creating code's AccessControlContext is
+ // captured, and that references the creating code's ClassLoader.
+ Policy oldPolicy = Policy.getPolicy();
+ SecurityManager oldSecurityManager = System.getSecurityManager();
+ try {
+ Policy.setPolicy(new PermissivePolicy());
+ System.setSecurityManager(new SecurityManager());
+ doTestUnloadable();
+ } finally {
+ System.setSecurityManager(oldSecurityManager);
+ Policy.setPolicy(oldPolicy);
+ }
+ }
+
+ public static class FrqUser implements Callable<WeakReference<Object>> {
+ public static FinalizableReferenceQueue frq = new FinalizableReferenceQueue();
+ public static final Semaphore finalized = new Semaphore(0);
+
+ @Override
+ public WeakReference<Object> call() {
+ WeakReference<Object> wr = new FinalizableWeakReference<Object>(new Integer(23), frq) {
+ @Override
+ public void finalizeReferent() {
+ finalized.release();
+ }
+ };
+ return wr;
+ }
+ }
+
+ public void testUnloadableInStaticFieldIfClosed() throws Exception {
+ Policy oldPolicy = Policy.getPolicy();
+ SecurityManager oldSecurityManager = System.getSecurityManager();
+ try {
+ Policy.setPolicy(new PermissivePolicy());
+ System.setSecurityManager(new SecurityManager());
+ WeakReference<ClassLoader> loaderRef = doTestUnloadableInStaticFieldIfClosed();
+ GcFinalization.awaitClear(loaderRef);
+ } finally {
+ System.setSecurityManager(oldSecurityManager);
+ Policy.setPolicy(oldPolicy);
+ }
+ }
+
+ // If you have a FinalizableReferenceQueue that is a static field of one of the classes of your
+ // app (like the FrqUser class above), then the app's ClassLoader will never be gc'd. The reason
+ // is that we attempt to run a thread in a separate ClassLoader that will detect when the FRQ
+ // is no longer referenced, meaning that the app's ClassLoader has been gc'd, and when that
+ // happens. But the thread's supposedly separate ClassLoader actually has a reference to the app's
+ // ClasLoader via its AccessControlContext. It does not seem to be possible to make a
+ // URLClassLoader without capturing this reference, and it probably would not be desirable for
+ // security reasons anyway. Therefore, the FRQ.close() method provides a way to stop the thread
+ // explicitly. This test checks that calling that method does allow an app's ClassLoader to be
+ // gc'd even if there is a still a FinalizableReferenceQueue in a static field. (Setting the field
+ // to null would also work, but only if there are no references to the FRQ anywhere else.)
+ private WeakReference<ClassLoader> doTestUnloadableInStaticFieldIfClosed() throws Exception {
+ final URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader();
+ final URL[] urls = myLoader.getURLs();
+ URLClassLoader sepLoader = new URLClassLoader(urls, myLoader.getParent());
+
+ Class<?> frqC = FinalizableReferenceQueue.class;
+ Class<?> sepFrqC = sepLoader.loadClass(frqC.getName());
+ assertNotSame(frqC, sepFrqC);
+
+ Class<?> sepFrqSystemLoaderC =
+ sepLoader.loadClass(FinalizableReferenceQueue.SystemLoader.class.getName());
+ Field disabled = sepFrqSystemLoaderC.getDeclaredField("disabled");
+ disabled.setAccessible(true);
+ disabled.set(null, true);
+
+ Class<?> frqUserC = FrqUser.class;
+ Class<?> sepFrqUserC = sepLoader.loadClass(frqUserC.getName());
+ assertNotSame(frqUserC, sepFrqUserC);
+ assertSame(sepLoader, sepFrqUserC.getClassLoader());
+
+ @SuppressWarnings("unchecked")
+ Callable<WeakReference<Object>> sepFrqUser =
+ (Callable<WeakReference<Object>>) sepFrqUserC.newInstance();
+ WeakReference<Object> finalizableWeakReference = sepFrqUser.call();
+
+ GcFinalization.awaitClear(finalizableWeakReference);
+
+ Field sepFrqUserFinalizedF = sepFrqUserC.getField("finalized");
+ Semaphore finalizeCount = (Semaphore) sepFrqUserFinalizedF.get(null);
+ boolean finalized = finalizeCount.tryAcquire(5, TimeUnit.SECONDS);
+ assertTrue(finalized);
+
+ Field sepFrqUserFrqF = sepFrqUserC.getField("frq");
+ Closeable frq = (Closeable) sepFrqUserFrqF.get(null);
+ frq.close();
+
+ return new WeakReference<ClassLoader>(sepLoader);
+ }
+}
diff --git a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java
index c6f7248..883aa7f 100644
--- a/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java
+++ b/guava-tests/test/com/google/common/base/FinalizableReferenceQueueTest.java
@@ -17,6 +17,7 @@
package com.google.common.base;
import com.google.common.base.internal.Finalizer;
+import com.google.common.testing.GcFinalization;
import junit.framework.TestCase;
@@ -40,19 +41,14 @@ public class FinalizableReferenceQueueTest extends TestCase {
}
public void testFinalizeReferentCalled() {
- MockReference reference = new MockReference(
+ final MockReference reference = new MockReference(
frq = new FinalizableReferenceQueue());
- // wait up to 5s
- for (int i = 0; i < 500; i++) {
- if (reference.finalizeReferentCalled) {
- return;
- }
- try {
- System.gc();
- Thread.sleep(10);
- } catch (InterruptedException e) { /* ignore */ }
- }
- fail();
+
+ GcFinalization.awaitDone(new GcFinalization.FinalizationPredicate() {
+ public boolean isDone() {
+ return reference.finalizeReferentCalled;
+ }
+ });
}
static class MockReference extends FinalizableWeakReference<Object> {
@@ -78,18 +74,7 @@ public class FinalizableReferenceQueueTest extends TestCase {
public void testThatFinalizerStops() {
weaklyReferenceQueue();
-
- // wait up to 5s
- for (int i = 0; i < 500; i++) {
- if (queueReference.get() == null) {
- return;
- }
- try {
- System.gc();
- Thread.sleep(10);
- } catch (InterruptedException e) { /* ignore */ }
- }
- fail();
+ GcFinalization.awaitClear(queueReference);
}
/**
diff --git a/guava-tests/test/com/google/common/base/FunctionsTest.java b/guava-tests/test/com/google/common/base/FunctionsTest.java
index e74f622..cc7b4f2 100644
--- a/guava-tests/test/com/google/common/base/FunctionsTest.java
+++ b/guava-tests/test/com/google/common/base/FunctionsTest.java
@@ -20,6 +20,7 @@ import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
+import com.google.common.testing.ClassSanityTester;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -78,7 +79,7 @@ public class FunctionsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Functions.class);
}
@@ -385,14 +386,14 @@ public class FunctionsTest extends TestCase {
implements Supplier<Integer>, Serializable {
private static final long serialVersionUID = 0;
-
+
private int value;
@Override
public Integer get() {
return ++value;
}
-
+
@Override
public boolean equals(Object obj) {
if (obj instanceof CountingSupplier) {
@@ -400,7 +401,7 @@ public class FunctionsTest extends TestCase {
}
return false;
}
-
+
@Override
public int hashCode() {
return value;
@@ -413,7 +414,7 @@ public class FunctionsTest extends TestCase {
assertEquals(1, (int) function.apply(null));
assertEquals(2, (int) function.apply("foo"));
-
+
new EqualsTester()
.addEqualityGroup(function, Functions.forSupplier(supplier))
.addEqualityGroup(Functions.forSupplier(new CountingSupplier()))
@@ -427,8 +428,18 @@ public class FunctionsTest extends TestCase {
checkCanReserialize(Functions.forSupplier(new CountingSupplier()));
}
+ @GwtIncompatible("reflection")
+ public void testNulls() throws Exception {
+ new ClassSanityTester().forAllPublicStaticMethods(Functions.class).testNulls();
+ }
+
+ @GwtIncompatible("reflection")
+ public void testEqualsAndSerializable() throws Exception {
+ new ClassSanityTester().forAllPublicStaticMethods(Functions.class).testEqualsAndSerializable();
+ }
+
@GwtIncompatible("SerializableTester")
- private <Y> void checkCanReserialize(Function<? super Integer, Y> f) {
+ private static <Y> void checkCanReserialize(Function<? super Integer, Y> f) {
Function<? super Integer, Y> g = SerializableTester.reserializeAndAssert(f);
for (int i = 1; i < 5; i++) {
// convoluted way to check that the same result happens from each
@@ -448,7 +459,7 @@ public class FunctionsTest extends TestCase {
}
@GwtIncompatible("SerializableTester")
- private <Y> void checkCanReserializeSingleton(Function<? super String, Y> f) {
+ private static <Y> void checkCanReserializeSingleton(Function<? super String, Y> f) {
Function<? super String, Y> g = SerializableTester.reserializeAndAssert(f);
assertSame(f, g);
for (Integer i = 1; i < 5; i++) {
diff --git a/guava-tests/test/com/google/common/base/JoinerTest.java b/guava-tests/test/com/google/common/base/JoinerTest.java
index 1b6bbc5..d7f5855 100644
--- a/guava-tests/test/com/google/common/base/JoinerTest.java
+++ b/guava-tests/test/com/google/common/base/JoinerTest.java
@@ -220,7 +220,7 @@ public class JoinerTest extends TestCase {
Joiner zeroForNull = J.useForNull("0");
checkIterableIterator(zeroForNull, "1-2-3-4");
}
-
+
private static void checkIterableIterator(Joiner joiner, String expected) {
assertEquals(expected, joiner.join(new IterableIterator()));
@@ -254,7 +254,7 @@ public class JoinerTest extends TestCase {
public void test_useForNull_skipNulls() {
Joiner j = Joiner.on("x").useForNull("y");
try {
- j.skipNulls();
+ j = j.skipNulls();
fail();
} catch (UnsupportedOperationException expected) {
}
@@ -263,7 +263,7 @@ public class JoinerTest extends TestCase {
public void test_skipNulls_useForNull() {
Joiner j = Joiner.on("x").skipNulls();
try {
- j.useForNull("y");
+ j = j.useForNull("y");
fail();
} catch (UnsupportedOperationException expected) {
}
@@ -272,7 +272,7 @@ public class JoinerTest extends TestCase {
public void test_useForNull_twice() {
Joiner j = Joiner.on("x").useForNull("y");
try {
- j.useForNull("y");
+ j = j.useForNull("y");
fail();
} catch (UnsupportedOperationException expected) {
}
@@ -338,6 +338,7 @@ public class JoinerTest extends TestCase {
assertEquals("1:2;1:3;3:4;5:6;5:10", sb2.toString());
}
+ @SuppressWarnings("ReturnValueIgnored")
public void test_skipNulls_onMap() {
Joiner j = Joiner.on(",").skipNulls();
try {
@@ -396,17 +397,17 @@ public class JoinerTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(StringBuilder.class, new StringBuilder());
- // This is necessary because of the generics hackery we have to temporarily support parameters
- // which implement both Iterator and Iterable.
- tester.setDefault(Object.class, Iterators.emptyIterator());
+ public void testNullPointers() {
+ NullPointerTester tester = new NullPointerTester()
+ // This is necessary because of the generics hackery we have to temporarily support
+ // parameters which implement both Iterator and Iterable.;
+ .setDefault(Object.class, Iterators.emptyIterator());
tester.testAllPublicStaticMethods(Joiner.class);
- tester.testAllPublicInstanceMethods(Joiner.on(","));
- tester.testAllPublicInstanceMethods(Joiner.on(",").skipNulls());
- tester.testAllPublicInstanceMethods(Joiner.on(",").useForNull("x"));
- tester.testAllPublicInstanceMethods(
- Joiner.on(",").withKeyValueSeparator("="));
+ tester.testInstanceMethods(Joiner.on(","), NullPointerTester.Visibility.PACKAGE);
+ tester.testInstanceMethods(Joiner.on(",").skipNulls(), NullPointerTester.Visibility.PACKAGE);
+ tester.testInstanceMethods(
+ Joiner.on(",").useForNull("x"), NullPointerTester.Visibility.PACKAGE);
+ tester.testInstanceMethods(
+ Joiner.on(",").withKeyValueSeparator("="), NullPointerTester.Visibility.PACKAGE);
}
}
diff --git a/guava-tests/test/com/google/common/base/ObjectsTest.java b/guava-tests/test/com/google/common/base/ObjectsTest.java
index 7b1f47b..f5d0899 100644
--- a/guava-tests/test/com/google/common/base/ObjectsTest.java
+++ b/guava-tests/test/com/google/common/base/ObjectsTest.java
@@ -78,7 +78,7 @@ public class ObjectsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Objects.class);
}
diff --git a/guava-tests/test/com/google/common/base/OptionalTest.java b/guava-tests/test/com/google/common/base/OptionalTest.java
index 5a0b765..602b7c7 100644
--- a/guava-tests/test/com/google/common/base/OptionalTest.java
+++ b/guava-tests/test/com/google/common/base/OptionalTest.java
@@ -16,10 +16,11 @@
package com.google.common.base;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -93,15 +94,15 @@ public final class OptionalTest extends TestCase {
assertEquals("default", Optional.absent().or("default"));
}
- public void testOr_Supplier_present() {
+ public void testOr_supplier_present() {
assertEquals("a", Optional.of("a").or(Suppliers.ofInstance("fallback")));
}
- public void testOr_Supplier_absent() {
+ public void testOr_supplier_absent() {
assertEquals("fallback", Optional.absent().or(Suppliers.ofInstance("fallback")));
}
- public void testOr_NullSupplier_absent() {
+ public void testOr_nullSupplier_absent() {
Supplier<Object> nullSupplier = Suppliers.ofInstance(null);
Optional<Object> absentOptional = Optional.absent();
try {
@@ -111,6 +112,11 @@ public final class OptionalTest extends TestCase {
}
}
+ public void testOr_nullSupplier_present() {
+ Supplier<String> nullSupplier = Suppliers.ofInstance(null);
+ assertEquals("a", Optional.of("a").or(nullSupplier));
+ }
+
public void testOr_Optional_present() {
assertEquals(Optional.of("a"), Optional.of("a").or(Optional.of("fallback")));
}
@@ -126,16 +132,16 @@ public final class OptionalTest extends TestCase {
public void testOrNull_absent() {
assertNull(Optional.absent().orNull());
}
-
+
public void testAsSet_present() {
Set<String> expected = Collections.singleton("a");
assertEquals(expected, Optional.of("a").asSet());
}
-
+
public void testAsSet_absent() {
assertTrue("Returned set should be empty", Optional.absent().asSet().isEmpty());
}
-
+
public void testAsSet_presentIsImmutable() {
Set<String> presentAsSet = Optional.of("a").asSet();
try {
@@ -154,6 +160,42 @@ public final class OptionalTest extends TestCase {
}
}
+ public void testTransform_absent() {
+ assertEquals(Optional.absent(), Optional.absent().transform(Functions.identity()));
+ assertEquals(Optional.absent(), Optional.absent().transform(Functions.toStringFunction()));
+ }
+
+ public void testTransform_presentIdentity() {
+ assertEquals(Optional.of("a"), Optional.of("a").transform(Functions.identity()));
+ }
+
+ public void testTransform_presentToString() {
+ assertEquals(Optional.of("42"), Optional.of(42).transform(Functions.toStringFunction()));
+ }
+
+ public void testTransform_present_functionReturnsNull() {
+ try {
+ Optional.of("a").transform(
+ new Function<String, String>() {
+ @Override public String apply(String input) {
+ return null;
+ }
+ });
+ fail("Should throw if Function returns null.");
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testTransform_abssent_functionReturnsNull() {
+ assertEquals(Optional.absent(),
+ Optional.absent().transform(
+ new Function<Object, Object>() {
+ @Override public Object apply(Object input) {
+ return null;
+ }
+ }));
+ }
+
// TODO(kevinb): use EqualsTester
public void testEqualsAndHashCode_absent() {
@@ -179,27 +221,71 @@ public final class OptionalTest extends TestCase {
public void testPresentInstances_allPresent() {
List<Optional<String>> optionals =
ImmutableList.of(Optional.of("a"), Optional.of("b"), Optional.of("c"));
- ASSERT.that(Optional.presentInstances(optionals)).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(Optional.presentInstances(optionals)).iteratesOverSequence("a", "b", "c");
}
-
+
public void testPresentInstances_allAbsent() {
List<Optional<Object>> optionals =
ImmutableList.of(Optional.absent(), Optional.absent());
ASSERT.that(Optional.presentInstances(optionals)).isEmpty();
}
-
+
public void testPresentInstances_somePresent() {
List<Optional<String>> optionals =
ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c"));
- ASSERT.that(Optional.presentInstances(optionals)).hasContentsInOrder("a", "c");
+ ASSERT.that(Optional.presentInstances(optionals)).iteratesOverSequence("a", "c");
}
-
+
public void testPresentInstances_callingIteratorTwice() {
List<Optional<String>> optionals =
ImmutableList.of(Optional.of("a"), Optional.<String>absent(), Optional.of("c"));
Iterable<String> onlyPresent = Optional.presentInstances(optionals);
- ASSERT.that(onlyPresent).hasContentsInOrder("a", "c");
- ASSERT.that(onlyPresent).hasContentsInOrder("a", "c");
+ ASSERT.that(onlyPresent).iteratesOverSequence("a", "c");
+ ASSERT.that(onlyPresent).iteratesOverSequence("a", "c");
+ }
+
+ public void testPresentInstances_wildcards() {
+ List<Optional<? extends Number>> optionals =
+ ImmutableList.<Optional<? extends Number>>of(Optional.<Double>absent(), Optional.of(2));
+ Iterable<Number> onlyPresent = Optional.presentInstances(optionals);
+ ASSERT.that(onlyPresent).iteratesOverSequence(2);
+ }
+
+ private static Optional<Integer> getSomeOptionalInt() {
+ return Optional.of(1);
+ }
+
+ private static FluentIterable<? extends Number> getSomeNumbers() {
+ return FluentIterable.from(ImmutableList.<Number>of());
+ }
+
+ /*
+ * The following tests demonstrate the shortcomings of or() and test that the casting workaround
+ * mentioned in the method Javadoc does in fact compile.
+ */
+
+ public void testSampleCodeError1() {
+ Optional<Integer> optionalInt = getSomeOptionalInt();
+ // Number value = optionalInt.or(0.5); // error
+ }
+
+ public void testSampleCodeError2() {
+ FluentIterable<? extends Number> numbers = getSomeNumbers();
+ Optional<? extends Number> first = numbers.first();
+ // Number value = first.or(0.5); // error
+ }
+
+ @SuppressWarnings("unchecked") // safe covariant cast
+ public void testSampleCodeFine1() {
+ Optional<Number> optionalInt = (Optional) getSomeOptionalInt();
+ Number value = optionalInt.or(0.5); // fine
+ }
+
+ @SuppressWarnings("unchecked") // safe covariant cast
+ public void testSampleCodeFine2() {
+ FluentIterable<? extends Number> numbers = getSomeNumbers();
+ Optional<Number> first = (Optional) numbers.first();
+ Number value = first.or(0.5); // fine
}
@GwtIncompatible("SerializableTester")
@@ -209,7 +295,7 @@ public final class OptionalTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester npTester = new NullPointerTester();
npTester.testAllPublicConstructors(Optional.class);
npTester.testAllPublicStaticMethods(Optional.class);
diff --git a/guava-tests/test/com/google/common/base/PackageSanityTests.java b/guava-tests/test/com/google/common/base/PackageSanityTests.java
new file mode 100644
index 0000000..6a356ec
--- /dev/null
+++ b/guava-tests/test/com/google/common/base/PackageSanityTests.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.base;
+
+import com.google.common.testing.AbstractPackageSanityTests;
+
+/**
+ * Basic sanity tests for classes in {@code common.base}.
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {
+ public PackageSanityTests() {
+ // package private classes like FunctionalEquivalence are tested through the public API.
+ publicApiOnly();
+ }
+}
diff --git a/guava-tests/test/com/google/common/base/PreconditionsTest.java b/guava-tests/test/com/google/common/base/PreconditionsTest.java
index 8f19d40..c3f8c98 100644
--- a/guava-tests/test/com/google/common/base/PreconditionsTest.java
+++ b/guava-tests/test/com/google/common/base/PreconditionsTest.java
@@ -340,7 +340,7 @@ public class PreconditionsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Preconditions.class);
}
diff --git a/guava-tests/test/com/google/common/base/PredicatesTest.java b/guava-tests/test/com/google/common/base/PredicatesTest.java
index c256c71..8aeebdc 100644
--- a/guava-tests/test/com/google/common/base/PredicatesTest.java
+++ b/guava-tests/test/com/google/common/base/PredicatesTest.java
@@ -21,6 +21,7 @@ import static com.google.common.base.CharMatcher.WHITESPACE;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableSet;
+import com.google.common.testing.ClassSanityTester;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -596,15 +597,15 @@ public class PredicatesTest extends TestCase {
public void testIsInstanceOf_serialization() {
checkSerialization(Predicates.instanceOf(Integer.class));
}
-
+
@GwtIncompatible("Predicates.assignableFrom")
public void testIsAssignableFrom_apply() {
Predicate<Class<?>> isInteger = Predicates.assignableFrom(Integer.class);
assertTrue(isInteger.apply(Integer.class));
assertFalse(isInteger.apply(Float.class));
-
- try {
+
+ try {
isInteger.apply(null);
fail();
} catch(NullPointerException expected) {}
@@ -640,7 +641,7 @@ public class PredicatesTest extends TestCase {
@GwtIncompatible("Predicates.assignableFrom, SerializableTester")
public void testIsAssignableFrom_serialization() {
- Predicate<Class<?>> predicate =
+ Predicate<Class<?>> predicate =
Predicates.assignableFrom(Integer.class);
Predicate<Class<?>> reserialized =
SerializableTester.reserializeAndAssert(predicate);
@@ -763,7 +764,7 @@ public class PredicatesTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Predicates.class);
}
@@ -908,12 +909,22 @@ public class PredicatesTest extends TestCase {
assertEqualHashCode(
Predicates.or(p1, p2),
Predicates.or(p1, p2));
-
+
// While not a contractual requirement, we'd like the hash codes for ands
- // & ors of the same predicates to not collide.
+ // & ors of the same predicates to not collide.
assertTrue(Predicates.and(p1, p2).hashCode() != Predicates.or(p1, p2).hashCode());
}
+ @GwtIncompatible("reflection")
+ public void testNulls() throws Exception {
+ new ClassSanityTester().forAllPublicStaticMethods(Predicates.class).testNulls();
+ }
+
+ @GwtIncompatible("reflection")
+ public void testEqualsAndSerializable() throws Exception {
+ new ClassSanityTester().forAllPublicStaticMethods(Predicates.class).testEqualsAndSerializable();
+ }
+
private static void assertEvalsToTrue(Predicate<? super Integer> predicate) {
assertTrue(predicate.apply(0));
assertTrue(predicate.apply(1));
diff --git a/guava-tests/test/com/google/common/base/SplitterTest.java b/guava-tests/test/com/google/common/base/SplitterTest.java
index 25e963f..57e44b0 100644
--- a/guava-tests/test/com/google/common/base/SplitterTest.java
+++ b/guava-tests/test/com/google/common/base/SplitterTest.java
@@ -16,7 +16,7 @@
package com.google.common.base;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -51,43 +51,49 @@ public class SplitterTest extends TestCase {
public void testCharacterSimpleSplit() {
String simple = "a,b,c";
Iterable<String> letters = COMMA_SPLITTER.split(simple);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
+ }
+
+ public void testToString() {
+ assertEquals("[]", Splitter.on(',').split("").toString());
+ assertEquals("[a, b, c]", Splitter.on(',').split("a,b,c").toString());
+ assertEquals("[yam, bam, jam, ham]", Splitter.on(", ").split("yam, bam, jam, ham").toString());
}
public void testCharacterSimpleSplitWithNoDelimiter() {
String simple = "a,b,c";
Iterable<String> letters = Splitter.on('.').split(simple);
- ASSERT.that(letters).hasContentsInOrder("a,b,c");
+ ASSERT.that(letters).iteratesOverSequence("a,b,c");
}
public void testCharacterSplitWithDoubleDelimiter() {
String doubled = "a,,b,c";
Iterable<String> letters = COMMA_SPLITTER.split(doubled);
- ASSERT.that(letters).hasContentsInOrder("a", "", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "", "b", "c");
}
public void testCharacterSplitWithDoubleDelimiterAndSpace() {
String doubled = "a,, b,c";
Iterable<String> letters = COMMA_SPLITTER.split(doubled);
- ASSERT.that(letters).hasContentsInOrder("a", "", " b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "", " b", "c");
}
public void testCharacterSplitWithTrailingDelimiter() {
String trailing = "a,b,c,";
Iterable<String> letters = COMMA_SPLITTER.split(trailing);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "");
}
public void testCharacterSplitWithLeadingDelimiter() {
String leading = ",a,b,c";
Iterable<String> letters = COMMA_SPLITTER.split(leading);
- ASSERT.that(letters).hasContentsInOrder("", "a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c");
}
public void testCharacterSplitWithMulitpleLetters() {
Iterable<String> testCharacteringMotto = Splitter.on('-').split(
"Testing-rocks-Debugging-sucks");
- ASSERT.that(testCharacteringMotto).hasContentsInOrder(
+ ASSERT.that(testCharacteringMotto).iteratesOverSequence(
"Testing", "rocks", "Debugging", "sucks");
}
@@ -95,7 +101,7 @@ public class SplitterTest extends TestCase {
Iterable<String> testCharacteringMotto = Splitter
.on(CharMatcher.WHITESPACE)
.split("Testing\nrocks\tDebugging sucks");
- ASSERT.that(testCharacteringMotto).hasContentsInOrder(
+ ASSERT.that(testCharacteringMotto).iteratesOverSequence(
"Testing", "rocks", "Debugging", "sucks");
}
@@ -103,26 +109,26 @@ public class SplitterTest extends TestCase {
String doubled = "a..b.c";
Iterable<String> letters = Splitter.on('.')
.omitEmptyStrings().split(doubled);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
}
public void testCharacterSplitEmptyToken() {
String emptyToken = "a. .c";
Iterable<String> letters = Splitter.on('.').trimResults()
.split(emptyToken);
- ASSERT.that(letters).hasContentsInOrder("a", "", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "", "c");
}
public void testCharacterSplitEmptyTokenOmitEmptyStrings() {
String emptyToken = "a. .c";
Iterable<String> letters = Splitter.on('.')
.omitEmptyStrings().trimResults().split(emptyToken);
- ASSERT.that(letters).hasContentsInOrder("a", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "c");
}
public void testCharacterSplitOnEmptyString() {
Iterable<String> nothing = Splitter.on('.').split("");
- ASSERT.that(nothing).hasContentsInOrder("");
+ ASSERT.that(nothing).iteratesOverSequence("");
}
public void testCharacterSplitOnEmptyStringOmitEmptyStrings() {
@@ -131,7 +137,7 @@ public class SplitterTest extends TestCase {
public void testCharacterSplitOnOnlyDelimiter() {
Iterable<String> blankblank = Splitter.on('.').split(".");
- ASSERT.that(blankblank).hasContentsInOrder("", "");
+ ASSERT.that(blankblank).iteratesOverSequence("", "");
}
public void testCharacterSplitOnOnlyDelimitersOmitEmptyStrings() {
@@ -145,97 +151,97 @@ public class SplitterTest extends TestCase {
Iterable<String> family = COMMA_SPLITTER
.trimResults(CharMatcher.anyOf("afro").or(CharMatcher.WHITESPACE))
.split(jacksons);
- ASSERT.that(family).hasContentsInOrder(
+ ASSERT.that(family).iteratesOverSequence(
"(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)");
}
public void testStringSimpleSplit() {
String simple = "a,b,c";
- Iterable<String> letters = Splitter.on(",").split(simple);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
+ Iterable<String> letters = Splitter.on(',').split(simple);
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
}
public void testStringSimpleSplitWithNoDelimiter() {
String simple = "a,b,c";
- Iterable<String> letters = Splitter.on(".").split(simple);
- ASSERT.that(letters).hasContentsInOrder("a,b,c");
+ Iterable<String> letters = Splitter.on('.').split(simple);
+ ASSERT.that(letters).iteratesOverSequence("a,b,c");
}
public void testStringSplitWithDoubleDelimiter() {
String doubled = "a,,b,c";
- Iterable<String> letters = Splitter.on(",").split(doubled);
- ASSERT.that(letters).hasContentsInOrder("a", "", "b", "c");
+ Iterable<String> letters = Splitter.on(',').split(doubled);
+ ASSERT.that(letters).iteratesOverSequence("a", "", "b", "c");
}
public void testStringSplitWithDoubleDelimiterAndSpace() {
String doubled = "a,, b,c";
- Iterable<String> letters = Splitter.on(",").split(doubled);
- ASSERT.that(letters).hasContentsInOrder("a", "", " b", "c");
+ Iterable<String> letters = Splitter.on(',').split(doubled);
+ ASSERT.that(letters).iteratesOverSequence("a", "", " b", "c");
}
public void testStringSplitWithTrailingDelimiter() {
String trailing = "a,b,c,";
- Iterable<String> letters = Splitter.on(",").split(trailing);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "");
+ Iterable<String> letters = Splitter.on(',').split(trailing);
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "");
}
public void testStringSplitWithLeadingDelimiter() {
String leading = ",a,b,c";
- Iterable<String> letters = Splitter.on(",").split(leading);
- ASSERT.that(letters).hasContentsInOrder("", "a", "b", "c");
+ Iterable<String> letters = Splitter.on(',').split(leading);
+ ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c");
}
public void testStringSplitWithMultipleLetters() {
- Iterable<String> testStringingMotto = Splitter.on("-").split(
+ Iterable<String> testStringingMotto = Splitter.on('-').split(
"Testing-rocks-Debugging-sucks");
- ASSERT.that(testStringingMotto).hasContentsInOrder(
+ ASSERT.that(testStringingMotto).iteratesOverSequence(
"Testing", "rocks", "Debugging", "sucks");
}
public void testStringSplitWithDoubleDelimiterOmitEmptyStrings() {
String doubled = "a..b.c";
- Iterable<String> letters = Splitter.on(".")
+ Iterable<String> letters = Splitter.on('.')
.omitEmptyStrings().split(doubled);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
}
public void testStringSplitEmptyToken() {
String emptyToken = "a. .c";
- Iterable<String> letters = Splitter.on(".").trimResults()
+ Iterable<String> letters = Splitter.on('.').trimResults()
.split(emptyToken);
- ASSERT.that(letters).hasContentsInOrder("a", "", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "", "c");
}
public void testStringSplitEmptyTokenOmitEmptyStrings() {
String emptyToken = "a. .c";
- Iterable<String> letters = Splitter.on(".")
+ Iterable<String> letters = Splitter.on('.')
.omitEmptyStrings().trimResults().split(emptyToken);
- ASSERT.that(letters).hasContentsInOrder("a", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "c");
}
public void testStringSplitWithLongDelimiter() {
String longDelimiter = "a, b, c";
Iterable<String> letters = Splitter.on(", ").split(longDelimiter);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
}
public void testStringSplitWithLongLeadingDelimiter() {
String longDelimiter = ", a, b, c";
Iterable<String> letters = Splitter.on(", ").split(longDelimiter);
- ASSERT.that(letters).hasContentsInOrder("", "a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c");
}
public void testStringSplitWithLongTrailingDelimiter() {
String longDelimiter = "a, b, c, ";
Iterable<String> letters = Splitter.on(", ").split(longDelimiter);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "");
}
public void testStringSplitWithDelimiterSubstringInValue() {
String fourCommasAndFourSpaces = ",,,, ";
Iterable<String> threeCommasThenThreeSpaces = Splitter.on(", ").split(
fourCommasAndFourSpaces);
- ASSERT.that(threeCommasThenThreeSpaces).hasContentsInOrder(",,,", " ");
+ ASSERT.that(threeCommasThenThreeSpaces).iteratesOverSequence(",,,", " ");
}
public void testStringSplitWithEmptyString() {
@@ -247,31 +253,31 @@ public class SplitterTest extends TestCase {
}
public void testStringSplitOnEmptyString() {
- Iterable<String> notMuch = Splitter.on(".").split("");
- ASSERT.that(notMuch).hasContentsInOrder("");
+ Iterable<String> notMuch = Splitter.on('.').split("");
+ ASSERT.that(notMuch).iteratesOverSequence("");
}
public void testStringSplitOnEmptyStringOmitEmptyString() {
- ASSERT.that(Splitter.on(".").omitEmptyStrings().split("")).isEmpty();
+ ASSERT.that(Splitter.on('.').omitEmptyStrings().split("")).isEmpty();
}
public void testStringSplitOnOnlyDelimiter() {
- Iterable<String> blankblank = Splitter.on(".").split(".");
- ASSERT.that(blankblank).hasContentsInOrder("", "");
+ Iterable<String> blankblank = Splitter.on('.').split(".");
+ ASSERT.that(blankblank).iteratesOverSequence("", "");
}
public void testStringSplitOnOnlyDelimitersOmitEmptyStrings() {
- Iterable<String> empty = Splitter.on(".").omitEmptyStrings().split("...");
+ Iterable<String> empty = Splitter.on('.').omitEmptyStrings().split("...");
ASSERT.that(empty).isEmpty();
}
public void testStringSplitWithTrim() {
String jacksons = "arfo(Marlon)aorf, (Michael)orfa, afro(Jackie)orfa, "
+ "ofar(Jemaine), aff(Tito)";
- Iterable<String> family = Splitter.on(",")
+ Iterable<String> family = Splitter.on(',')
.trimResults(CharMatcher.anyOf("afro").or(CharMatcher.WHITESPACE))
.split(jacksons);
- ASSERT.that(family).hasContentsInOrder(
+ ASSERT.that(family).iteratesOverSequence(
"(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)");
}
@@ -279,42 +285,42 @@ public class SplitterTest extends TestCase {
public void testPatternSimpleSplit() {
String simple = "a,b,c";
Iterable<String> letters = Splitter.onPattern(",").split(simple);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
}
@GwtIncompatible("Splitter.onPattern")
public void testPatternSimpleSplitWithNoDelimiter() {
String simple = "a,b,c";
Iterable<String> letters = Splitter.onPattern("foo").split(simple);
- ASSERT.that(letters).hasContentsInOrder("a,b,c");
+ ASSERT.that(letters).iteratesOverSequence("a,b,c");
}
@GwtIncompatible("Splitter.onPattern")
public void testPatternSplitWithDoubleDelimiter() {
String doubled = "a,,b,c";
Iterable<String> letters = Splitter.onPattern(",").split(doubled);
- ASSERT.that(letters).hasContentsInOrder("a", "", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "", "b", "c");
}
@GwtIncompatible("Splitter.onPattern")
public void testPatternSplitWithDoubleDelimiterAndSpace() {
String doubled = "a,, b,c";
Iterable<String> letters = Splitter.onPattern(",").split(doubled);
- ASSERT.that(letters).hasContentsInOrder("a", "", " b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "", " b", "c");
}
@GwtIncompatible("Splitter.onPattern")
public void testPatternSplitWithTrailingDelimiter() {
String trailing = "a,b,c,";
Iterable<String> letters = Splitter.onPattern(",").split(trailing);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "");
}
@GwtIncompatible("Splitter.onPattern")
public void testPatternSplitWithLeadingDelimiter() {
String leading = ",a,b,c";
Iterable<String> letters = Splitter.onPattern(",").split(leading);
- ASSERT.that(letters).hasContentsInOrder("", "a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c");
}
// TODO(kevinb): the name of this method suggests it might not actually be testing what it
@@ -323,7 +329,7 @@ public class SplitterTest extends TestCase {
public void testPatternSplitWithMultipleLetters() {
Iterable<String> testPatterningMotto = Splitter.onPattern("-").split(
"Testing-rocks-Debugging-sucks");
- ASSERT.that(testPatterningMotto).hasContentsInOrder("Testing", "rocks", "Debugging", "sucks");
+ ASSERT.that(testPatterningMotto).iteratesOverSequence("Testing", "rocks", "Debugging", "sucks");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -336,14 +342,30 @@ public class SplitterTest extends TestCase {
String doubled = "a..b.c";
Iterable<String> letters = Splitter.on(literalDotPattern())
.omitEmptyStrings().split(doubled);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
+ }
+
+ @GwtIncompatible("java.util.regex.Pattern")
+ public void testPatternSplitLookBehind() {
+ String toSplit = ":foo::barbaz:";
+ String regexPattern = "(?<=:)";
+ Iterable<String> split = Splitter.onPattern(regexPattern).split(toSplit);
+ ASSERT.that(split).iteratesOverSequence(":", "foo:", ":", "barbaz:");
+ // splits into chunks ending in :
+ }
+
+ @GwtIncompatible("java.util.regex.Pattern")
+ public void testPatternSplitWordBoundary() {
+ String string = "foo<bar>bletch";
+ Iterable<String> words = Splitter.on(Pattern.compile("\\b")).split(string);
+ ASSERT.that(words).iteratesOverSequence("foo", "<", "bar", ">", "bletch");
}
@GwtIncompatible("java.util.regex.Pattern")
public void testPatternSplitEmptyToken() {
String emptyToken = "a. .c";
Iterable<String> letters = Splitter.on(literalDotPattern()).trimResults().split(emptyToken);
- ASSERT.that(letters).hasContentsInOrder("a", "", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "", "c");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -351,14 +373,14 @@ public class SplitterTest extends TestCase {
String emptyToken = "a. .c";
Iterable<String> letters = Splitter.on(literalDotPattern())
.omitEmptyStrings().trimResults().split(emptyToken);
- ASSERT.that(letters).hasContentsInOrder("a", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "c");
}
@GwtIncompatible("java.util.regex.Pattern")
public void testPatternSplitOnOnlyDelimiter() {
Iterable<String> blankblank = Splitter.on(literalDotPattern()).split(".");
- ASSERT.that(blankblank).hasContentsInOrder("", "");
+ ASSERT.that(blankblank).iteratesOverSequence("", "");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -373,7 +395,7 @@ public class SplitterTest extends TestCase {
String longDelimiter = "a, b, c";
Iterable<String> letters = Splitter.on(Pattern.compile(",\\s*"))
.split(longDelimiter);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -381,7 +403,7 @@ public class SplitterTest extends TestCase {
String longDelimiter = ", a, b, c";
Iterable<String> letters = Splitter.on(Pattern.compile(", "))
.split(longDelimiter);
- ASSERT.that(letters).hasContentsInOrder("", "a", "b", "c");
+ ASSERT.that(letters).iteratesOverSequence("", "a", "b", "c");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -389,7 +411,7 @@ public class SplitterTest extends TestCase {
String longDelimiter = "a, b, c/ ";
Iterable<String> letters = Splitter.on(Pattern.compile("[,/]\\s"))
.split(longDelimiter);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "");
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -408,7 +430,7 @@ public class SplitterTest extends TestCase {
Iterable<String> family = Splitter.on(Pattern.compile(","))
.trimResults(CharMatcher.anyOf("afro").or(CharMatcher.WHITESPACE))
.split(jacksons);
- ASSERT.that(family).hasContentsInOrder(
+ ASSERT.that(family).iteratesOverSequence(
"(Marlon)", "(Michael)", "(Jackie)", "(Jemaine)", "(Tito)");
}
@@ -417,7 +439,7 @@ public class SplitterTest extends TestCase {
}
public void testSplitterIterableIsUnmodifiable_string() {
- assertIteratorIsUnmodifiable(Splitter.on(",").split("a,b").iterator());
+ assertIteratorIsUnmodifiable(Splitter.on(',').split("a,b").iterator());
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -440,7 +462,7 @@ public class SplitterTest extends TestCase {
}
public void testSplitterIterableIsLazy_string() {
- assertSplitterIterableIsLazy(Splitter.on(","));
+ assertSplitterIterableIsLazy(Splitter.on(','));
}
@GwtIncompatible("java.util.regex.Pattern")
@@ -466,47 +488,47 @@ public class SplitterTest extends TestCase {
assertFalse(iterator.hasNext());
}
- public void testAtEachSimpleSplit() {
+ public void testFixedLengthSimpleSplit() {
String simple = "abcde";
Iterable<String> letters = Splitter.fixedLength(2).split(simple);
- ASSERT.that(letters).hasContentsInOrder("ab", "cd", "e");
+ ASSERT.that(letters).iteratesOverSequence("ab", "cd", "e");
}
- public void testAtEachSplitEqualChunkLength() {
+ public void testFixedLengthSplitEqualChunkLength() {
String simple = "abcdef";
Iterable<String> letters = Splitter.fixedLength(2).split(simple);
- ASSERT.that(letters).hasContentsInOrder("ab", "cd", "ef");
+ ASSERT.that(letters).iteratesOverSequence("ab", "cd", "ef");
}
- public void testAtEachSplitOnlyOneChunk() {
+ public void testFixedLengthSplitOnlyOneChunk() {
String simple = "abc";
Iterable<String> letters = Splitter.fixedLength(3).split(simple);
- ASSERT.that(letters).hasContentsInOrder("abc");
+ ASSERT.that(letters).iteratesOverSequence("abc");
}
- public void testAtEachSplitSmallerString() {
+ public void testFixedLengthSplitSmallerString() {
String simple = "ab";
Iterable<String> letters = Splitter.fixedLength(3).split(simple);
- ASSERT.that(letters).hasContentsInOrder("ab");
+ ASSERT.that(letters).iteratesOverSequence("ab");
}
- public void testAtEachSplitEmptyString() {
+ public void testFixedLengthSplitEmptyString() {
String simple = "";
Iterable<String> letters = Splitter.fixedLength(3).split(simple);
- ASSERT.that(letters).hasContentsInOrder("");
+ ASSERT.that(letters).iteratesOverSequence("");
}
- public void testAtEachSplitEmptyStringWithOmitEmptyStrings() {
+ public void testFixedLengthSplitEmptyStringWithOmitEmptyStrings() {
ASSERT.that(Splitter.fixedLength(3).omitEmptyStrings().split("")).isEmpty();
}
- public void testAtEachSplitIntoChars() {
+ public void testFixedLengthSplitIntoChars() {
String simple = "abcd";
Iterable<String> letters = Splitter.fixedLength(1).split(simple);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "d");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "d");
}
- public void testAtEachSplitZeroChunkLen() {
+ public void testFixedLengthSplitZeroChunkLen() {
try {
Splitter.fixedLength(0);
fail();
@@ -514,7 +536,7 @@ public class SplitterTest extends TestCase {
}
}
- public void testAtEachSplitNegativeChunkLen() {
+ public void testFixedLengthSplitNegativeChunkLen() {
try {
Splitter.fixedLength(-1);
fail();
@@ -525,73 +547,73 @@ public class SplitterTest extends TestCase {
public void testLimitLarge() {
String simple = "abcd";
Iterable<String> letters = Splitter.fixedLength(1).limit(100).split(simple);
- ASSERT.that(letters).hasContentsInOrder("a", "b", "c", "d");
+ ASSERT.that(letters).iteratesOverSequence("a", "b", "c", "d");
}
public void testLimitOne() {
String simple = "abcd";
Iterable<String> letters = Splitter.fixedLength(1).limit(1).split(simple);
- ASSERT.that(letters).hasContentsInOrder("abcd");
+ ASSERT.that(letters).iteratesOverSequence("abcd");
}
public void testLimitFixedLength() {
String simple = "abcd";
Iterable<String> letters = Splitter.fixedLength(1).limit(2).split(simple);
- ASSERT.that(letters).hasContentsInOrder("a", "bcd");
+ ASSERT.that(letters).iteratesOverSequence("a", "bcd");
}
public void testLimitSeparator() {
String simple = "a,b,c,d";
Iterable<String> items = COMMA_SPLITTER.limit(2).split(simple);
- ASSERT.that(items).hasContentsInOrder("a", "b,c,d");
+ ASSERT.that(items).iteratesOverSequence("a", "b,c,d");
}
public void testLimitExtraSeparators() {
String text = "a,,,b,,c,d";
Iterable<String> items = COMMA_SPLITTER.limit(2).split(text);
- ASSERT.that(items).hasContentsInOrder("a", ",,b,,c,d");
+ ASSERT.that(items).iteratesOverSequence("a", ",,b,,c,d");
}
public void testLimitExtraSeparatorsOmitEmpty() {
String text = "a,,,b,,c,d";
Iterable<String> items = COMMA_SPLITTER.limit(2).omitEmptyStrings().split(text);
- ASSERT.that(items).hasContentsInOrder("a", "b,,c,d");
+ ASSERT.that(items).iteratesOverSequence("a", "b,,c,d");
}
public void testLimitExtraSeparatorsOmitEmpty3() {
String text = "a,,,b,,c,d";
Iterable<String> items = COMMA_SPLITTER.limit(3).omitEmptyStrings().split(text);
- ASSERT.that(items).hasContentsInOrder("a", "b", "c,d");
+ ASSERT.that(items).iteratesOverSequence("a", "b", "c,d");
}
public void testLimitExtraSeparatorsTrim() {
String text = ",,a,, , b ,, c,d ";
Iterable<String> items = COMMA_SPLITTER.limit(2).omitEmptyStrings().trimResults().split(text);
- ASSERT.that(items).hasContentsInOrder("a", "b ,, c,d");
+ ASSERT.that(items).iteratesOverSequence("a", "b ,, c,d");
}
public void testLimitExtraSeparatorsTrim3() {
String text = ",,a,, , b ,, c,d ";
Iterable<String> items = COMMA_SPLITTER.limit(3).omitEmptyStrings().trimResults().split(text);
- ASSERT.that(items).hasContentsInOrder("a", "b", "c,d");
+ ASSERT.that(items).iteratesOverSequence("a", "b", "c,d");
}
public void testLimitExtraSeparatorsTrim1() {
String text = ",,a,, , b ,, c,d ";
Iterable<String> items = COMMA_SPLITTER.limit(1).omitEmptyStrings().trimResults().split(text);
- ASSERT.that(items).hasContentsInOrder("a,, , b ,, c,d");
+ ASSERT.that(items).iteratesOverSequence("a,, , b ,, c,d");
}
public void testLimitExtraSeparatorsTrim1NoOmit() {
String text = ",,a,, , b ,, c,d ";
Iterable<String> items = COMMA_SPLITTER.limit(1).trimResults().split(text);
- ASSERT.that(items).hasContentsInOrder(",,a,, , b ,, c,d");
+ ASSERT.that(items).iteratesOverSequence(",,a,, , b ,, c,d");
}
public void testLimitExtraSeparatorsTrim1Empty() {
String text = "";
Iterable<String> items = COMMA_SPLITTER.limit(1).split(text);
- ASSERT.that(items).hasContentsInOrder("");
+ ASSERT.that(items).iteratesOverSequence("");
}
public void testLimitExtraSeparatorsTrim1EmptyOmit() {
@@ -600,6 +622,7 @@ public class SplitterTest extends TestCase {
ASSERT.that(items).isEmpty();
}
+ @SuppressWarnings("ReturnValueIgnored")
public void testInvalidZeroLimit() {
try {
COMMA_SPLITTER.limit(0);
@@ -609,11 +632,11 @@ public class SplitterTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Splitter.class);
- tester.testAllPublicInstanceMethods(Splitter.on(","));
- tester.testAllPublicInstanceMethods(Splitter.on(",").trimResults());
+ tester.testAllPublicInstanceMethods(Splitter.on(','));
+ tester.testAllPublicInstanceMethods(Splitter.on(',').trimResults());
}
private static <E> List<E> asList(Collection<E> collection){
@@ -662,6 +685,19 @@ public class SplitterTest extends TestCase {
ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet()));
}
+ public void testMapSplitter_CharacterSeparator() {
+ // try different delimiters.
+ Map<String, String> m = Splitter
+ .on(",")
+ .withKeyValueSeparator(':')
+ .split("boy:tom,girl:tina,cat:kitty,dog:tommy");
+ ImmutableMap<String, String> expected =
+ ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy");
+
+ ASSERT.that(m).isEqualTo(expected);
+ ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet()));
+ }
+
public void testMapSplitter_multiCharacterSeparator() {
// try different delimiters.
Map<String, String> m = Splitter
@@ -675,6 +711,7 @@ public class SplitterTest extends TestCase {
ASSERT.that(asList(m.entrySet())).is(asList(expected.entrySet()));
}
+ @SuppressWarnings("ReturnValueIgnored")
public void testMapSplitter_emptySeparator() {
try {
COMMA_SPLITTER.withKeyValueSeparator("");
@@ -692,27 +729,27 @@ public class SplitterTest extends TestCase {
}
public void testMapSplitter_orderedResults() {
- Map<String, String> m = Splitter.on(",")
+ Map<String, String> m = Splitter.on(',')
.withKeyValueSeparator(":")
.split("boy:tom,girl:tina,cat:kitty,dog:tommy");
- ASSERT.that(m.keySet()).hasContentsInOrder("boy", "girl", "cat", "dog");
+ ASSERT.that(m.keySet()).iteratesOverSequence("boy", "girl", "cat", "dog");
ASSERT.that(m).isEqualTo(
ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"));
// try in a different order
- m = Splitter.on(",")
+ m = Splitter.on(',')
.withKeyValueSeparator(":")
.split("girl:tina,boy:tom,dog:tommy,cat:kitty");
- ASSERT.that(m.keySet()).hasContentsInOrder("girl", "boy", "dog", "cat");
+ ASSERT.that(m.keySet()).iteratesOverSequence("girl", "boy", "dog", "cat");
ASSERT.that(m).isEqualTo(
ImmutableMap.of("boy", "tom", "girl", "tina", "cat", "kitty", "dog", "tommy"));
}
public void testMapSplitter_duplicateKeys() {
try {
- Splitter.on(",").withKeyValueSeparator(":").split("a:1,b:2,a:3");
+ Splitter.on(',').withKeyValueSeparator(":").split("a:1,b:2,a:3");
fail();
} catch (IllegalArgumentException expected) {
}
diff --git a/guava-tests/test/com/google/common/base/StopwatchTest.java b/guava-tests/test/com/google/common/base/StopwatchTest.java
index 33e8fb0..da4f15b 100644
--- a/guava-tests/test/com/google/common/base/StopwatchTest.java
+++ b/guava-tests/test/com/google/common/base/StopwatchTest.java
@@ -39,7 +39,7 @@ public class StopwatchTest extends TestCase {
public void testInitialState() {
assertFalse(stopwatch.isRunning());
- assertEquals(0, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(0, stopwatch.elapsed(NANOSECONDS));
}
public void testStart() {
@@ -88,43 +88,43 @@ public class StopwatchTest extends TestCase {
stopwatch.reset();
assertFalse(stopwatch.isRunning());
ticker.advance(2);
- assertEquals(0, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(0, stopwatch.elapsed(NANOSECONDS));
stopwatch.start();
ticker.advance(3);
- assertEquals(3, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(3, stopwatch.elapsed(NANOSECONDS));
}
public void testReset_whileRunning() {
ticker.advance(1);
stopwatch.start();
- assertEquals(0, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(0, stopwatch.elapsed(NANOSECONDS));
ticker.advance(2);
- assertEquals(2, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(2, stopwatch.elapsed(NANOSECONDS));
stopwatch.reset();
assertFalse(stopwatch.isRunning());
ticker.advance(3);
- assertEquals(0, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(0, stopwatch.elapsed(NANOSECONDS));
}
- public void testElapsedTime_whileRunning() {
+ public void testElapsed_whileRunning() {
ticker.advance(78);
stopwatch.start();
- assertEquals(0, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(0, stopwatch.elapsed(NANOSECONDS));
ticker.advance(345);
- assertEquals(345, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(345, stopwatch.elapsed(NANOSECONDS));
}
- public void testElapsedTime_notRunning() {
+ public void testElapsed_notRunning() {
ticker.advance(1);
stopwatch.start();
ticker.advance(4);
stopwatch.stop();
ticker.advance(9);
- assertEquals(4, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(4, stopwatch.elapsed(NANOSECONDS));
}
- public void testElapsedTime_multipleSegments() {
+ public void testElapsed_multipleSegments() {
stopwatch.start();
ticker.advance(9);
stopwatch.stop();
@@ -132,46 +132,46 @@ public class StopwatchTest extends TestCase {
ticker.advance(16);
stopwatch.start();
- assertEquals(9, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(9, stopwatch.elapsed(NANOSECONDS));
ticker.advance(25);
- assertEquals(34, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(34, stopwatch.elapsed(NANOSECONDS));
stopwatch.stop();
ticker.advance(36);
- assertEquals(34, stopwatch.elapsedTime(NANOSECONDS));
+ assertEquals(34, stopwatch.elapsed(NANOSECONDS));
}
- public void testElapsedTime_micros() {
+ public void testElapsed_micros() {
stopwatch.start();
ticker.advance(999);
- assertEquals(0, stopwatch.elapsedTime(MICROSECONDS));
+ assertEquals(0, stopwatch.elapsed(MICROSECONDS));
ticker.advance(1);
- assertEquals(1, stopwatch.elapsedTime(MICROSECONDS));
+ assertEquals(1, stopwatch.elapsed(MICROSECONDS));
}
- public void testElapsedTime_millis() {
+ public void testElapsed_millis() {
stopwatch.start();
ticker.advance(999999);
- assertEquals(0, stopwatch.elapsedTime(MILLISECONDS));
+ assertEquals(0, stopwatch.elapsed(MILLISECONDS));
ticker.advance(1);
- assertEquals(1, stopwatch.elapsedTime(MILLISECONDS));
+ assertEquals(1, stopwatch.elapsed(MILLISECONDS));
}
public void testElapsedMillis() {
stopwatch.start();
ticker.advance(999999);
- assertEquals(0, stopwatch.elapsedMillis());
+ assertEquals(0, stopwatch.elapsed(MILLISECONDS));
ticker.advance(1);
- assertEquals(1, stopwatch.elapsedMillis());
+ assertEquals(1, stopwatch.elapsed(MILLISECONDS));
}
public void testElapsedMillis_whileRunning() {
ticker.advance(78000000);
stopwatch.start();
- assertEquals(0, stopwatch.elapsedMillis());
+ assertEquals(0, stopwatch.elapsed(MILLISECONDS));
ticker.advance(345000000);
- assertEquals(345, stopwatch.elapsedMillis());
+ assertEquals(345, stopwatch.elapsed(MILLISECONDS));
}
public void testElapsedMillis_notRunning() {
@@ -180,7 +180,7 @@ public class StopwatchTest extends TestCase {
ticker.advance(4000000);
stopwatch.stop();
ticker.advance(9000000);
- assertEquals(4, stopwatch.elapsedMillis());
+ assertEquals(4, stopwatch.elapsed(MILLISECONDS));
}
public void testElapsedMillis_multipleSegments() {
@@ -191,13 +191,13 @@ public class StopwatchTest extends TestCase {
ticker.advance(16000000);
stopwatch.start();
- assertEquals(9, stopwatch.elapsedMillis());
+ assertEquals(9, stopwatch.elapsed(MILLISECONDS));
ticker.advance(25000000);
- assertEquals(34, stopwatch.elapsedMillis());
+ assertEquals(34, stopwatch.elapsed(MILLISECONDS));
stopwatch.stop();
ticker.advance(36000000);
- assertEquals(34, stopwatch.elapsedMillis());
+ assertEquals(34, stopwatch.elapsed(MILLISECONDS));
}
@GwtIncompatible("String.format()")
@@ -224,11 +224,4 @@ public class StopwatchTest extends TestCase {
assertEquals("5.000 s", stopwatch.toString());
}
- @GwtIncompatible("GWT is at millisecond granularity")
- public void testDefault() {
- // By default System.nanoTime() is used as the time source
- long value = new Stopwatch().start().elapsedTime(NANOSECONDS);
- assertTrue(value > 0);
- // There isn't much else we can test about this
- }
}
diff --git a/guava-tests/test/com/google/common/base/StringsTest.java b/guava-tests/test/com/google/common/base/StringsTest.java
index f97c288..fb6ff1c 100644
--- a/guava-tests/test/com/google/common/base/StringsTest.java
+++ b/guava-tests/test/com/google/common/base/StringsTest.java
@@ -221,7 +221,7 @@ public class StringsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Strings.class);
}
diff --git a/guava-tests/test/com/google/common/base/SuppliersTest.java b/guava-tests/test/com/google/common/base/SuppliersTest.java
index 7b4b8b9..6e6ea9c 100644
--- a/guava-tests/test/com/google/common/base/SuppliersTest.java
+++ b/guava-tests/test/com/google/common/base/SuppliersTest.java
@@ -21,7 +21,8 @@ import static com.google.common.testing.SerializableTester.reserialize;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.Lists;
-import com.google.common.testing.NullPointerTester;
+import com.google.common.testing.ClassSanityTester;
+import com.google.common.testing.EqualsTester;
import junit.framework.TestCase;
@@ -391,9 +392,35 @@ public class SuppliersTest extends TestCase {
Suppliers.synchronizedSupplier(Suppliers.ofInstance(5))).get());
}
- @GwtIncompatible("NullPointerTest")
- public void testNullPointers() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.testAllPublicStaticMethods(Suppliers.class);
+ @GwtIncompatible("reflection")
+ public void testSuppliersNullChecks() throws Exception {
+ new ClassSanityTester().forAllPublicStaticMethods(Suppliers.class)
+ .testNulls();
+ }
+
+ @GwtIncompatible("reflection")
+ public void testSuppliersSerializable() throws Exception {
+ new ClassSanityTester().forAllPublicStaticMethods(Suppliers.class)
+ .testSerializable();
+ }
+
+ public void testOfInstance_equals() {
+ new EqualsTester()
+ .addEqualityGroup(
+ Suppliers.ofInstance("foo"), Suppliers.ofInstance("foo"))
+ .addEqualityGroup(Suppliers.ofInstance("bar"))
+ .testEquals();
+ }
+
+ public void testCompose_equals() {
+ new EqualsTester()
+ .addEqualityGroup(
+ Suppliers.compose(Functions.constant(1), Suppliers.ofInstance("foo")),
+ Suppliers.compose(Functions.constant(1), Suppliers.ofInstance("foo")))
+ .addEqualityGroup(
+ Suppliers.compose(Functions.constant(2), Suppliers.ofInstance("foo")))
+ .addEqualityGroup(
+ Suppliers.compose(Functions.constant(1), Suppliers.ofInstance("bar")))
+ .testEquals();
}
}
diff --git a/guava-tests/test/com/google/common/base/ThrowablesTest.java b/guava-tests/test/com/google/common/base/ThrowablesTest.java
index 1abd1ff..53a6f2c 100644
--- a/guava-tests/test/com/google/common/base/ThrowablesTest.java
+++ b/guava-tests/test/com/google/common/base/ThrowablesTest.java
@@ -31,9 +31,9 @@ import java.util.List;
/**
* Unit test for {@link Throwables}.
*
- * @author Kevin Bourrillion
+ * @author Kevin Bourrillion
*/
-@SuppressWarnings("serial") // this warning is silly for exceptions in tests
+@SuppressWarnings("serial") // this warning is silly for exceptions in tests
public class ThrowablesTest extends TestCase {
public void testPropagateIfPossible_NoneDeclared_NoneThrown() {
Sample sample = new Sample() {
@@ -442,7 +442,6 @@ public class ThrowablesTest extends TestCase {
assertSame(cause, Throwables.getRootCause(exception));
}
- private static class SomeThrowable extends Throwable {}
private static class SomeError extends Error {}
private static class SomeCheckedException extends Exception {}
private static class SomeOtherCheckedException extends Exception {}
@@ -524,10 +523,7 @@ public class ThrowablesTest extends TestCase {
}
}
- public void testNullPointers() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Throwable.class, new SomeCheckedException());
- tester.setDefault(Class.class, SomeCheckedException.class);
- tester.testAllPublicStaticMethods(Throwables.class);
+ public void testNullPointers() {
+ new NullPointerTester().testAllPublicStaticMethods(Throwables.class);
}
}
diff --git a/guava-tests/test/com/google/common/base/ToStringHelperTest.java b/guava-tests/test/com/google/common/base/ToStringHelperTest.java
index 32ba19f..7817c4d 100644
--- a/guava-tests/test/com/google/common/base/ToStringHelperTest.java
+++ b/guava-tests/test/com/google/common/base/ToStringHelperTest.java
@@ -324,6 +324,113 @@ public class ToStringHelperTest extends TestCase {
assertTrue(result, result.matches(expected));
}
+ @GwtIncompatible("Class names are obfuscated in GWT")
+ public void testToStringOmitNullValues_oneField() {
+ String toTest = Objects.toStringHelper(new TestClass())
+ .omitNullValues()
+ .add("field1", null)
+ .toString();
+ assertEquals("TestClass{}", toTest);
+ }
+
+ @GwtIncompatible("Class names are obfuscated in GWT")
+ public void testToStringOmitNullValues_manyFieldsFirstNull() {
+ String toTest = Objects.toStringHelper(new TestClass())
+ .omitNullValues()
+ .add("field1", null)
+ .add("field2", "Googley")
+ .add("field3", "World")
+ .toString();
+ assertEquals("TestClass{field2=Googley, field3=World}", toTest);
+ }
+
+ @GwtIncompatible("Class names are obfuscated in GWT")
+ public void testToStringOmitNullValues_manyFieldsOmitAfterNull() {
+ String toTest = Objects.toStringHelper(new TestClass())
+ .add("field1", null)
+ .add("field2", "Googley")
+ .add("field3", "World")
+ .omitNullValues()
+ .toString();
+ assertEquals("TestClass{field2=Googley, field3=World}", toTest);
+ }
+
+ @GwtIncompatible("Class names are obfuscated in GWT")
+ public void testToStringOmitNullValues_manyFieldsLastNull() {
+ String toTest = Objects.toStringHelper(new TestClass())
+ .omitNullValues()
+ .add("field1", "Hello")
+ .add("field2", "Googley")
+ .add("field3", null)
+ .toString();
+ assertEquals("TestClass{field1=Hello, field2=Googley}", toTest);
+ }
+
+ @GwtIncompatible("Class names are obfuscated in GWT")
+ public void testToStringOmitNullValues_oneValue() {
+ String toTest = Objects.toStringHelper(new TestClass())
+ .omitNullValues()
+ .addValue(null)
+ .toString();
+ assertEquals("TestClass{}", toTest);
+ }
+
+ @GwtIncompatible("Class names are obfuscated in GWT")
+ public void testToStringOmitNullValues_manyValuesFirstNull() {
+ String toTest = Objects.toStringHelper(new TestClass())
+ .omitNullValues()
+ .addValue(null)
+ .addValue("Googley")
+ .addValue("World")
+ .toString();
+ assertEquals("TestClass{Googley, World}", toTest);
+ }
+
+ @GwtIncompatible("Class names are obfuscated in GWT")
+ public void testToStringOmitNullValues_manyValuesLastNull() {
+ String toTest = Objects.toStringHelper(new TestClass())
+ .omitNullValues()
+ .addValue("Hello")
+ .addValue("Googley")
+ .addValue(null)
+ .toString();
+ assertEquals("TestClass{Hello, Googley}", toTest);
+ }
+
+ @GwtIncompatible("Class names are obfuscated in GWT")
+ public void testToStringOmitNullValues_differentOrder() {
+ String expected = "TestClass{field1=Hello, field2=Googley, field3=World}";
+ String toTest1 = Objects.toStringHelper(new TestClass())
+ .omitNullValues()
+ .add("field1", "Hello")
+ .add("field2", "Googley")
+ .add("field3", "World")
+ .toString();
+ String toTest2 = Objects.toStringHelper(new TestClass())
+ .add("field1", "Hello")
+ .add("field2", "Googley")
+ .omitNullValues()
+ .add("field3", "World")
+ .toString();
+ assertEquals(expected, toTest1);
+ assertEquals(expected, toTest2);
+ }
+
+ @GwtIncompatible("Class names are obfuscated in GWT")
+ public void testToStringOmitNullValues_canBeCalledManyTimes() {
+ String toTest = Objects.toStringHelper(new TestClass())
+ .omitNullValues()
+ .omitNullValues()
+ .add("field1", "Hello")
+ .omitNullValues()
+ .add("field2", "Googley")
+ .omitNullValues()
+ .add("field3", "World")
+ .toString();
+ assertEquals("TestClass{field1=Hello, field2=Googley, field3=World}",
+ toTest);
+ }
+
/**
* Test class for testing formatting of inner classes.
*/
diff --git a/guava-tests/test/com/google/common/cache/AbstractCacheTest.java b/guava-tests/test/com/google/common/cache/AbstractCacheTest.java
index 46e2a9e..0cb6d1c 100644
--- a/guava-tests/test/com/google/common/cache/AbstractCacheTest.java
+++ b/guava-tests/test/com/google/common/cache/AbstractCacheTest.java
@@ -24,7 +24,6 @@ import com.google.common.collect.Lists;
import junit.framework.TestCase;
import java.util.List;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicReference;
/**
@@ -41,12 +40,6 @@ public class AbstractCacheTest extends TestCase {
public Object getIfPresent(Object key) {
return valueRef.get();
}
-
- @Override
- public Object get(Object key) throws ExecutionException {
- throw new UnsupportedOperationException();
- }
-
};
assertNull(cache.getIfPresent(new Object()));
@@ -60,12 +53,7 @@ public class AbstractCacheTest extends TestCase {
final List<Object> invalidated = Lists.newArrayList();
Cache<Integer, Integer> cache = new AbstractCache<Integer, Integer>() {
@Override
- public Integer getIfPresent(Integer key) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Integer get(Integer key) throws ExecutionException {
+ public Integer getIfPresent(Object key) {
throw new UnsupportedOperationException();
}
diff --git a/guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java b/guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java
new file mode 100644
index 0000000..b93db3f
--- /dev/null
+++ b/guava-tests/test/com/google/common/cache/CacheBuilderGwtTest.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.cache;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.google.common.testing.FakeTicker;
+
+import junit.framework.TestCase;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test suite for {@link CacheBuilder}.
+ * TODO(cpovirk): merge into CacheBuilderTest?
+ *
+ * @author Jon Donovan
+ */
+@GwtCompatible
+public class CacheBuilderGwtTest extends TestCase {
+
+ private FakeTicker fakeTicker;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ fakeTicker = new FakeTicker();
+ }
+
+ public void testLoader() throws ExecutionException {
+
+ final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .build();
+
+ Callable<Integer> loader = new Callable<Integer>() {
+ private int i = 0;
+
+ @Override
+ public Integer call() throws Exception {
+ return ++i;
+ }
+ };
+
+ cache.put(0, 10);
+
+ assertEquals(Integer.valueOf(10), cache.get(0, loader));
+ assertEquals(Integer.valueOf(1), cache.get(20, loader));
+ assertEquals(Integer.valueOf(2), cache.get(34, loader));
+
+ cache.invalidate(0);
+ assertEquals(Integer.valueOf(3), cache.get(0, loader));
+
+ cache.put(0, 10);
+ cache.invalidateAll();
+ assertEquals(Integer.valueOf(4), cache.get(0, loader));
+ }
+
+ public void testSizeConstraint() {
+ final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .maximumSize(4)
+ .build();
+
+ cache.put(1, 10);
+ cache.put(2, 20);
+ cache.put(3, 30);
+ cache.put(4, 40);
+ cache.put(5, 50);
+
+ assertEquals(null, cache.getIfPresent(10));
+ // Order required to remove dependence on acces order / write order constraint.
+ assertEquals(Integer.valueOf(20), cache.getIfPresent(2));
+ assertEquals(Integer.valueOf(30), cache.getIfPresent(3));
+ assertEquals(Integer.valueOf(40), cache.getIfPresent(4));
+ assertEquals(Integer.valueOf(50), cache.getIfPresent(5));
+
+ cache.put(1, 10);
+ assertEquals(Integer.valueOf(10), cache.getIfPresent(1));
+ assertEquals(Integer.valueOf(30), cache.getIfPresent(3));
+ assertEquals(Integer.valueOf(40), cache.getIfPresent(4));
+ assertEquals(Integer.valueOf(50), cache.getIfPresent(5));
+ assertEquals(null, cache.getIfPresent(2));
+ }
+
+ public void testLoadingCache() throws ExecutionException {
+ CacheLoader<Integer, Integer> loader = new CacheLoader<Integer, Integer>() {
+ int i = 0;
+ @Override
+ public Integer load(Integer key) throws Exception {
+ return i++;
+ }
+
+ };
+
+ LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .build(loader);
+
+ cache.put(10, 20);
+
+ Map<Integer, Integer> map = cache.getAll(ImmutableList.of(10, 20, 30, 54, 443, 1));
+
+ assertEquals(Integer.valueOf(20), map.get(10));
+ assertEquals(Integer.valueOf(0), map.get(20));
+ assertEquals(Integer.valueOf(1), map.get(30));
+ assertEquals(Integer.valueOf(2), map.get(54));
+ assertEquals(Integer.valueOf(3), map.get(443));
+ assertEquals(Integer.valueOf(4), map.get(1));
+ assertEquals(Integer.valueOf(5), cache.get(6));
+ assertEquals(Integer.valueOf(6), cache.apply(7));
+ }
+
+ public void testExpireAfterAccess() {
+ final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterAccess(1000, TimeUnit.MILLISECONDS)
+ .ticker(fakeTicker)
+ .build();
+
+ cache.put(0, 10);
+ cache.put(2, 30);
+
+ fakeTicker.advance(999, TimeUnit.MILLISECONDS);
+ assertEquals(Integer.valueOf(30), cache.getIfPresent(2));
+ fakeTicker.advance(1, TimeUnit.MILLISECONDS);
+ assertEquals(Integer.valueOf(30), cache.getIfPresent(2));
+ fakeTicker.advance(1000, TimeUnit.MILLISECONDS);
+ assertEquals(null, cache.getIfPresent(0));
+ }
+
+ public void testExpireAfterWrite() {
+ final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
+ .ticker(fakeTicker)
+ .build();
+
+ cache.put(10, 100);
+ cache.put(20, 200);
+ cache.put(4, 2);
+
+ fakeTicker.advance(999, TimeUnit.MILLISECONDS);
+ assertEquals(Integer.valueOf(100), cache.getIfPresent(10));
+ assertEquals(Integer.valueOf(200), cache.getIfPresent(20));
+ assertEquals(Integer.valueOf(2), cache.getIfPresent(4));
+
+ fakeTicker.advance(2, TimeUnit.MILLISECONDS);
+ assertEquals(null, cache.getIfPresent(10));
+ assertEquals(null, cache.getIfPresent(20));
+ assertEquals(null, cache.getIfPresent(4));
+
+ cache.put(10, 20);
+ assertEquals(Integer.valueOf(20), cache.getIfPresent(10));
+
+ fakeTicker.advance(1000, TimeUnit.MILLISECONDS);
+ assertEquals(null, cache.getIfPresent(10));
+ }
+
+ public void testExpireAfterWriteAndAccess() {
+ final Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
+ .expireAfterAccess(500, TimeUnit.MILLISECONDS)
+ .ticker(fakeTicker)
+ .build();
+
+ cache.put(10, 100);
+ cache.put(20, 200);
+ cache.put(4, 2);
+
+ fakeTicker.advance(499, TimeUnit.MILLISECONDS);
+ assertEquals(Integer.valueOf(100), cache.getIfPresent(10));
+ assertEquals(Integer.valueOf(200), cache.getIfPresent(20));
+
+ fakeTicker.advance(2, TimeUnit.MILLISECONDS);
+ assertEquals(Integer.valueOf(100), cache.getIfPresent(10));
+ assertEquals(Integer.valueOf(200), cache.getIfPresent(20));
+ assertEquals(null, cache.getIfPresent(4));
+
+ fakeTicker.advance(499, TimeUnit.MILLISECONDS);
+ assertEquals(null, cache.getIfPresent(10));
+ assertEquals(null, cache.getIfPresent(20));
+
+ cache.put(10, 20);
+ assertEquals(Integer.valueOf(20), cache.getIfPresent(10));
+
+ fakeTicker.advance(500, TimeUnit.MILLISECONDS);
+ assertEquals(null, cache.getIfPresent(10));
+ }
+
+ public void testMapMethods() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .build();
+
+ ConcurrentMap<Integer, Integer> asMap = cache.asMap();
+
+ cache.put(10, 100);
+ cache.put(2, 52);
+
+ asMap.replace(2, 79);
+ asMap.replace(3, 60);
+
+ assertEquals(null, cache.getIfPresent(3));
+ assertEquals(null, asMap.get(3));
+
+ assertEquals(Integer.valueOf(79), cache.getIfPresent(2));
+ assertEquals(Integer.valueOf(79), asMap.get(2));
+
+ asMap.replace(10, 100, 50);
+ asMap.replace(2, 52, 99);
+
+ assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
+ assertEquals(Integer.valueOf(50), asMap.get(10));
+ assertEquals(Integer.valueOf(79), cache.getIfPresent(2));
+ assertEquals(Integer.valueOf(79), asMap.get(2));
+
+ asMap.remove(10, 100);
+ asMap.remove(2, 79);
+
+ assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
+ assertEquals(Integer.valueOf(50), asMap.get(10));
+ assertEquals(null, cache.getIfPresent(2));
+ assertEquals(null, asMap.get(2));
+
+ asMap.putIfAbsent(2, 20);
+ asMap.putIfAbsent(10, 20);
+
+ assertEquals(Integer.valueOf(20), cache.getIfPresent(2));
+ assertEquals(Integer.valueOf(20), asMap.get(2));
+ assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
+ assertEquals(Integer.valueOf(50), asMap.get(10));
+ }
+
+ public void testRemovalListener() {
+ final int[] stats = new int[4];
+
+ RemovalListener<Integer, Integer> countingListener = new RemovalListener<Integer, Integer>() {
+ @Override
+ public void onRemoval(RemovalNotification<Integer, Integer> notification) {
+ switch (notification.getCause()) {
+ case EXPIRED:
+ stats[0]++;
+ break;
+ case EXPLICIT:
+ stats[1]++;
+ break;
+ case REPLACED:
+ stats[2]++;
+ break;
+ case SIZE:
+ stats[3]++;
+ break;
+ default:
+ throw new IllegalStateException("No collected exceptions in GWT CacheBuilder.");
+ }
+ }
+ };
+
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
+ .removalListener(countingListener)
+ .ticker(fakeTicker)
+ .maximumSize(2)
+ .build();
+
+ // Add more than two elements to increment size removals.
+ cache.put(3, 20);
+ cache.put(6, 2);
+ cache.put(98, 45);
+ cache.put(56, 76);
+ cache.put(23, 84);
+
+ // Replace the two present elements.
+ cache.put(23, 20);
+ cache.put(56, 49);
+ cache.put(23, 2);
+ cache.put(56, 4);
+
+ // Expire the two present elements.
+ fakeTicker.advance(1001, TimeUnit.MILLISECONDS);
+
+ cache.getIfPresent(23);
+ cache.getIfPresent(56);
+
+ // Add two elements and invalidate them.
+ cache.put(1, 4);
+ cache.put(2, 8);
+
+ cache.invalidateAll();
+
+ assertEquals(2, stats[0]);
+ assertEquals(2, stats[1]);
+ assertEquals(4, stats[2]);
+ assertEquals(3, stats[3]);
+ }
+
+ public void testPutAll() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .build();
+
+ cache.putAll(ImmutableMap.of(10, 20, 30, 50, 60, 90));
+
+ assertEquals(Integer.valueOf(20), cache.getIfPresent(10));
+ assertEquals(Integer.valueOf(50), cache.getIfPresent(30));
+ assertEquals(Integer.valueOf(90), cache.getIfPresent(60));
+
+ cache.asMap().putAll(ImmutableMap.of(10, 50, 30, 20, 60, 70, 5, 5));
+
+ assertEquals(Integer.valueOf(50), cache.getIfPresent(10));
+ assertEquals(Integer.valueOf(20), cache.getIfPresent(30));
+ assertEquals(Integer.valueOf(70), cache.getIfPresent(60));
+ assertEquals(Integer.valueOf(5), cache.getIfPresent(5));
+ }
+
+ public void testInvalidate() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .build();
+
+ cache.put(654, 2675);
+ cache.put(2456, 56);
+ cache.put(2, 15);
+
+ cache.invalidate(654);
+
+ assertFalse(cache.asMap().containsKey(654));
+ assertTrue(cache.asMap().containsKey(2456));
+ assertTrue(cache.asMap().containsKey(2));
+ }
+
+ public void testInvalidateAll() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .build();
+
+ cache.put(654, 2675);
+ cache.put(2456, 56);
+ cache.put(2, 15);
+
+ cache.invalidateAll();
+ assertFalse(cache.asMap().containsKey(654));
+ assertFalse(cache.asMap().containsKey(2456));
+ assertFalse(cache.asMap().containsKey(2));
+
+ cache.put(654, 2675);
+ cache.put(2456, 56);
+ cache.put(2, 15);
+ cache.put(1, 3);
+
+ cache.invalidateAll(ImmutableSet.of(1, 2));
+
+ assertFalse(cache.asMap().containsKey(1));
+ assertFalse(cache.asMap().containsKey(2));
+ assertTrue(cache.asMap().containsKey(654));
+ assertTrue(cache.asMap().containsKey(2456));
+ }
+
+ public void testAsMap_containsValue() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterWrite(20000, TimeUnit.MILLISECONDS)
+ .ticker(fakeTicker)
+ .build();
+
+ cache.put(654, 2675);
+ fakeTicker.advance(10000, TimeUnit.MILLISECONDS);
+ cache.put(2456, 56);
+ cache.put(2, 15);
+
+ fakeTicker.advance(10001, TimeUnit.MILLISECONDS);
+
+ assertTrue(cache.asMap().containsValue(15));
+ assertTrue(cache.asMap().containsValue(56));
+ assertFalse(cache.asMap().containsValue(2675));
+ }
+
+ public void testAsMap_containsKey() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterWrite(20000, TimeUnit.MILLISECONDS)
+ .ticker(fakeTicker)
+ .build();
+
+ cache.put(654, 2675);
+ fakeTicker.advance(10000, TimeUnit.MILLISECONDS);
+ cache.put(2456, 56);
+ cache.put(2, 15);
+
+ fakeTicker.advance(10001, TimeUnit.MILLISECONDS);
+
+ assertTrue(cache.asMap().containsKey(2));
+ assertTrue(cache.asMap().containsKey(2456));
+ assertFalse(cache.asMap().containsKey(654));
+ }
+
+ public void testAsMapValues_contains() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
+ .ticker(fakeTicker)
+ .build();
+
+ cache.put(10, 20);
+ fakeTicker.advance(500, TimeUnit.MILLISECONDS);
+ cache.put(20, 22);
+ cache.put(5, 10);
+
+ fakeTicker.advance(501, TimeUnit.MILLISECONDS);
+
+ assertTrue(cache.asMap().values().contains(22));
+ assertTrue(cache.asMap().values().contains(10));
+ assertFalse(cache.asMap().values().contains(20));
+ }
+
+ public void testAsMapKeySet() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
+ .ticker(fakeTicker)
+ .build();
+
+ cache.put(10, 20);
+ fakeTicker.advance(500, TimeUnit.MILLISECONDS);
+ cache.put(20, 22);
+ cache.put(5, 10);
+
+ fakeTicker.advance(501, TimeUnit.MILLISECONDS);
+
+ Set<Integer> foundKeys = Sets.newHashSet();
+ for (Integer current : cache.asMap().keySet()) {
+ foundKeys.add(current);
+ }
+
+ assertEquals(ImmutableSet.of(20, 5), foundKeys);
+ }
+
+
+ public void testAsMapKeySet_contains() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
+ .ticker(fakeTicker)
+ .build();
+
+ cache.put(10, 20);
+ fakeTicker.advance(500, TimeUnit.MILLISECONDS);
+ cache.put(20, 22);
+ cache.put(5, 10);
+
+ fakeTicker.advance(501, TimeUnit.MILLISECONDS);
+
+ assertTrue(cache.asMap().keySet().contains(20));
+ assertTrue(cache.asMap().keySet().contains(5));
+ assertFalse(cache.asMap().keySet().contains(10));
+ }
+
+ public void testAsMapEntrySet() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
+ .ticker(fakeTicker)
+ .build();
+
+ cache.put(10, 20);
+ fakeTicker.advance(500, TimeUnit.MILLISECONDS);
+ cache.put(20, 22);
+ cache.put(5, 10);
+
+ fakeTicker.advance(501, TimeUnit.MILLISECONDS);
+
+ int sum = 0;
+ for (Entry<Integer, Integer> current : cache.asMap().entrySet()) {
+ sum += current.getKey() + current.getValue();
+ }
+ assertEquals(57, sum);
+ }
+
+ public void testAsMapValues_iteratorRemove() {
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .expireAfterWrite(1000, TimeUnit.MILLISECONDS)
+ .ticker(fakeTicker)
+ .build();
+
+ cache.put(10, 20);
+ Iterator<Integer> iterator = cache.asMap().values().iterator();
+ iterator.next();
+ iterator.remove();
+
+ assertEquals(0, cache.size());
+ }
+}
diff --git a/guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java b/guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java
new file mode 100644
index 0000000..4149a9f
--- /dev/null
+++ b/guava-tests/test/com/google/common/cache/CacheBuilderSpecTest.java
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.cache;
+
+import static com.google.common.cache.CacheBuilderSpec.parse;
+import static com.google.common.cache.TestingWeighers.constantWeigher;
+
+import com.google.common.base.Suppliers;
+import com.google.common.cache.LocalCache.Strength;
+import com.google.common.testing.EqualsTester;
+
+import junit.framework.TestCase;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests CacheBuilderSpec.
+ * TODO(user): tests of a few invalid input conditions, boundary conditions.
+ *
+ * @author Adam Winer
+ */
+public class CacheBuilderSpecTest extends TestCase {
+ public void testParse_empty() {
+ CacheBuilderSpec spec = parse("");
+ assertNull(spec.initialCapacity);
+ assertNull(spec.maximumSize);
+ assertNull(spec.maximumWeight);
+ assertNull(spec.concurrencyLevel);
+ assertNull(spec.keyStrength);
+ assertNull(spec.valueStrength);
+ assertNull(spec.writeExpirationTimeUnit);
+ assertNull(spec.accessExpirationTimeUnit);
+ assertCacheBuilderEquivalence(CacheBuilder.newBuilder(), CacheBuilder.from(spec));
+ }
+
+ public void testParse_initialCapacity() {
+ CacheBuilderSpec spec = parse("initialCapacity=10");
+ assertEquals(10, spec.initialCapacity.intValue());
+ assertNull(spec.maximumSize);
+ assertNull(spec.maximumWeight);
+ assertNull(spec.concurrencyLevel);
+ assertNull(spec.keyStrength);
+ assertNull(spec.valueStrength);
+ assertNull(spec.writeExpirationTimeUnit);
+ assertNull(spec.accessExpirationTimeUnit);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().initialCapacity(10), CacheBuilder.from(spec));
+ }
+
+ public void testParse_initialCapacityRepeated() {
+ try {
+ parse("initialCapacity=10, initialCapacity=20");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_maximumSize() {
+ CacheBuilderSpec spec = parse("maximumSize=9000");
+ assertNull(spec.initialCapacity);
+ assertEquals(9000, spec.maximumSize.longValue());
+ assertNull(spec.concurrencyLevel);
+ assertNull(spec.keyStrength);
+ assertNull(spec.valueStrength);
+ assertNull(spec.writeExpirationTimeUnit);
+ assertNull(spec.accessExpirationTimeUnit);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().maximumSize(9000), CacheBuilder.from(spec));
+ }
+
+ public void testParse_maximumSizeRepeated() {
+ try {
+ parse("maximumSize=10, maximumSize=20");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_maximumWeight() {
+ CacheBuilderSpec spec = parse("maximumWeight=9000");
+ assertNull(spec.initialCapacity);
+ assertEquals(9000, spec.maximumWeight.longValue());
+ assertNull(spec.concurrencyLevel);
+ assertNull(spec.keyStrength);
+ assertNull(spec.valueStrength);
+ assertNull(spec.writeExpirationTimeUnit);
+ assertNull(spec.accessExpirationTimeUnit);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().maximumWeight(9000), CacheBuilder.from(spec));
+ }
+
+ public void testParse_maximumWeightRepeated() {
+ try {
+ parse("maximumWeight=10, maximumWeight=20");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_maximumSizeAndMaximumWeight() {
+ try {
+ parse("maximumSize=10, maximumWeight=20");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_concurrencyLevel() {
+ CacheBuilderSpec spec = parse("concurrencyLevel=32");
+ assertNull(spec.initialCapacity);
+ assertNull(spec.maximumSize);
+ assertNull(spec.maximumWeight);
+ assertEquals(32, spec.concurrencyLevel.intValue());
+ assertNull(spec.keyStrength);
+ assertNull(spec.valueStrength);
+ assertNull(spec.writeExpirationTimeUnit);
+ assertNull(spec.accessExpirationTimeUnit);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().concurrencyLevel(32), CacheBuilder.from(spec));
+ }
+
+ public void testParse_concurrencyLevelRepeated() {
+ try {
+ parse("concurrencyLevel=10, concurrencyLevel=20");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_weakKeys() {
+ CacheBuilderSpec spec = parse("weakKeys");
+ assertNull(spec.initialCapacity);
+ assertNull(spec.maximumSize);
+ assertNull(spec.maximumWeight);
+ assertNull(spec.concurrencyLevel);
+ assertEquals(Strength.WEAK, spec.keyStrength);
+ assertNull(spec.valueStrength);
+ assertNull(spec.writeExpirationTimeUnit);
+ assertNull(spec.accessExpirationTimeUnit);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().weakKeys(), CacheBuilder.from(spec));
+ }
+
+ public void testParse_weakKeysCannotHaveValue() {
+ try {
+ parse("weakKeys=true");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_repeatedKeyStrength() {
+ try {
+ parse("weakKeys, weakKeys");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_softValues() {
+ CacheBuilderSpec spec = parse("softValues");
+ assertNull(spec.initialCapacity);
+ assertNull(spec.maximumSize);
+ assertNull(spec.maximumWeight);
+ assertNull(spec.concurrencyLevel);
+ assertNull(spec.keyStrength);
+ assertEquals(Strength.SOFT, spec.valueStrength);
+ assertNull(spec.writeExpirationTimeUnit);
+ assertNull(spec.accessExpirationTimeUnit);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().softValues(), CacheBuilder.from(spec));
+ }
+
+ public void testParse_softValuesCannotHaveValue() {
+ try {
+ parse("softValues=true");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_weakValues() {
+ CacheBuilderSpec spec = parse("weakValues");
+ assertNull(spec.initialCapacity);
+ assertNull(spec.maximumSize);
+ assertNull(spec.maximumWeight);
+ assertNull(spec.concurrencyLevel);
+ assertNull(spec.keyStrength);
+ assertEquals(Strength.WEAK, spec.valueStrength);
+ assertNull(spec.writeExpirationTimeUnit);
+ assertNull(spec.accessExpirationTimeUnit);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().weakValues(), CacheBuilder.from(spec));
+ }
+
+ public void testParse_weakValuesCannotHaveValue() {
+ try {
+ parse("weakValues=true");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_repeatedValueStrength() {
+ try {
+ parse("softValues, softValues");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+
+ try {
+ parse("softValues, weakValues");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+
+ try {
+ parse("weakValues, softValues");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+
+ try {
+ parse("weakValues, weakValues");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_writeExpirationDays() {
+ CacheBuilderSpec spec = parse("expireAfterWrite=10d");
+ assertNull(spec.initialCapacity);
+ assertNull(spec.maximumSize);
+ assertNull(spec.maximumWeight);
+ assertNull(spec.concurrencyLevel);
+ assertNull(spec.keyStrength);
+ assertNull(spec.valueStrength);
+ assertEquals(TimeUnit.DAYS, spec.writeExpirationTimeUnit);
+ assertEquals(10L, spec.writeExpirationDuration);
+ assertNull(spec.accessExpirationTimeUnit);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().expireAfterWrite(10L, TimeUnit.DAYS), CacheBuilder.from(spec));
+ }
+
+ public void testParse_writeExpirationHours() {
+ CacheBuilderSpec spec = parse("expireAfterWrite=150h");
+ assertEquals(TimeUnit.HOURS, spec.writeExpirationTimeUnit);
+ assertEquals(150L, spec.writeExpirationDuration);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().expireAfterWrite(150L, TimeUnit.HOURS), CacheBuilder.from(spec));
+ }
+
+ public void testParse_writeExpirationMinutes() {
+ CacheBuilderSpec spec = parse("expireAfterWrite=10m");
+ assertEquals(TimeUnit.MINUTES, spec.writeExpirationTimeUnit);
+ assertEquals(10L, spec.writeExpirationDuration);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().expireAfterWrite(10L, TimeUnit.MINUTES), CacheBuilder.from(spec));
+ }
+
+ public void testParse_writeExpirationSeconds() {
+ CacheBuilderSpec spec = parse("expireAfterWrite=10s");
+ assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
+ assertEquals(10L, spec.writeExpirationDuration);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().expireAfterWrite(10L, TimeUnit.SECONDS), CacheBuilder.from(spec));
+ }
+
+ public void testParse_writeExpirationRepeated() {
+ try {
+ parse(
+ "expireAfterWrite=10s,expireAfterWrite=10m");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_accessExpirationDays() {
+ CacheBuilderSpec spec = parse("expireAfterAccess=10d");
+ assertNull(spec.initialCapacity);
+ assertNull(spec.maximumSize);
+ assertNull(spec.maximumWeight);
+ assertNull(spec.concurrencyLevel);
+ assertNull(spec.keyStrength);
+ assertNull(spec.valueStrength);
+ assertNull(spec.writeExpirationTimeUnit);
+ assertEquals(TimeUnit.DAYS, spec.accessExpirationTimeUnit);
+ assertEquals(10L, spec.accessExpirationDuration);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().expireAfterAccess(10L, TimeUnit.DAYS), CacheBuilder.from(spec));
+ }
+
+ public void testParse_accessExpirationHours() {
+ CacheBuilderSpec spec = parse("expireAfterAccess=150h");
+ assertEquals(TimeUnit.HOURS, spec.accessExpirationTimeUnit);
+ assertEquals(150L, spec.accessExpirationDuration);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().expireAfterAccess(150L, TimeUnit.HOURS), CacheBuilder.from(spec));
+ }
+
+ public void testParse_accessExpirationMinutes() {
+ CacheBuilderSpec spec = parse("expireAfterAccess=10m");
+ assertEquals(TimeUnit.MINUTES, spec.accessExpirationTimeUnit);
+ assertEquals(10L, spec.accessExpirationDuration);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().expireAfterAccess(10L, TimeUnit.MINUTES),
+ CacheBuilder.from(spec));
+ }
+
+ public void testParse_accessExpirationSeconds() {
+ CacheBuilderSpec spec = parse("expireAfterAccess=10s");
+ assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
+ assertEquals(10L, spec.accessExpirationDuration);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder().expireAfterAccess(10L, TimeUnit.SECONDS),
+ CacheBuilder.from(spec));
+ }
+
+ public void testParse_accessExpirationRepeated() {
+ try {
+ parse(
+ "expireAfterAccess=10s,expireAfterAccess=10m");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_accessExpirationAndWriteExpiration() {
+ CacheBuilderSpec spec = parse("expireAfterAccess=10s,expireAfterWrite=9m");
+ assertEquals(TimeUnit.MINUTES, spec.writeExpirationTimeUnit);
+ assertEquals(9L, spec.writeExpirationDuration);
+ assertEquals(TimeUnit.SECONDS, spec.accessExpirationTimeUnit);
+ assertEquals(10L, spec.accessExpirationDuration);
+ assertCacheBuilderEquivalence(
+ CacheBuilder.newBuilder()
+ .expireAfterAccess(10L, TimeUnit.SECONDS)
+ .expireAfterWrite(9L, TimeUnit.MINUTES),
+ CacheBuilder.from(spec));
+ }
+
+ public void testParse_multipleKeys() {
+ CacheBuilderSpec spec = parse("initialCapacity=10,maximumSize=20,concurrencyLevel=30,"
+ + "weakKeys,weakValues,expireAfterAccess=10m,expireAfterWrite=1h");
+ assertEquals(10, spec.initialCapacity.intValue());
+ assertEquals(20, spec.maximumSize.intValue());
+ assertNull(spec.maximumWeight);
+ assertEquals(30, spec.concurrencyLevel.intValue());
+ assertEquals(Strength.WEAK, spec.keyStrength);
+ assertEquals(Strength.WEAK, spec.valueStrength);
+ assertEquals(TimeUnit.HOURS, spec.writeExpirationTimeUnit);
+ assertEquals(TimeUnit.MINUTES, spec.accessExpirationTimeUnit);
+ assertEquals(1L, spec.writeExpirationDuration);
+ assertEquals(10L, spec.accessExpirationDuration);
+ CacheBuilder expected = CacheBuilder.newBuilder()
+ .initialCapacity(10)
+ .maximumSize(20)
+ .concurrencyLevel(30)
+ .weakKeys()
+ .weakValues()
+ .expireAfterAccess(10L, TimeUnit.MINUTES)
+ .expireAfterWrite(1L, TimeUnit.HOURS);
+ assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec));
+ }
+
+ public void testParse_whitespaceAllowed() {
+ CacheBuilderSpec spec = parse(" initialCapacity=10,\nmaximumSize=20,\t\r"
+ + "weakKeys \t ,softValues \n , \r expireAfterWrite \t = 15s\n\n");
+ assertEquals(10, spec.initialCapacity.intValue());
+ assertEquals(20, spec.maximumSize.intValue());
+ assertNull(spec.maximumWeight);
+ assertNull(spec.concurrencyLevel);
+ assertEquals(Strength.WEAK, spec.keyStrength);
+ assertEquals(Strength.SOFT, spec.valueStrength);
+ assertEquals(TimeUnit.SECONDS, spec.writeExpirationTimeUnit);
+ assertEquals(15L, spec.writeExpirationDuration);
+ assertNull(spec.accessExpirationTimeUnit);
+ CacheBuilder expected = CacheBuilder.newBuilder()
+ .initialCapacity(10)
+ .maximumSize(20)
+ .weakKeys()
+ .softValues()
+ .expireAfterWrite(15L, TimeUnit.SECONDS);
+ assertCacheBuilderEquivalence(expected, CacheBuilder.from(spec));
+ }
+
+ public void testParse_unknownKey() {
+ try {
+ parse("foo=17");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testParse_extraCommaIsInvalid() {
+ try {
+ parse("weakKeys,");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+
+ try {
+ parse(",weakKeys");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+
+ try {
+ parse("weakKeys,,softValues");
+ fail("Expected exception");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ }
+
+ public void testEqualsAndHashCode() {
+ new EqualsTester()
+ .addEqualityGroup(parse(""), parse(""))
+ .addEqualityGroup(parse("concurrencyLevel=7"), parse("concurrencyLevel=7"))
+ .addEqualityGroup(parse("concurrencyLevel=15"), parse("concurrencyLevel=15"))
+ .addEqualityGroup(parse("initialCapacity=7"), parse("initialCapacity=7"))
+ .addEqualityGroup(parse("initialCapacity=15"), parse("initialCapacity=15"))
+ .addEqualityGroup(parse("maximumSize=7"), parse("maximumSize=7"))
+ .addEqualityGroup(parse("maximumSize=15"), parse("maximumSize=15"))
+ .addEqualityGroup(parse("maximumWeight=7"), parse("maximumWeight=7"))
+ .addEqualityGroup(parse("maximumWeight=15"), parse("maximumWeight=15"))
+ .addEqualityGroup(parse("expireAfterAccess=60s"), parse("expireAfterAccess=1m"))
+ .addEqualityGroup(parse("expireAfterAccess=60m"), parse("expireAfterAccess=1h"))
+ .addEqualityGroup(parse("expireAfterWrite=60s"), parse("expireAfterWrite=1m"))
+ .addEqualityGroup(parse("expireAfterWrite=60m"), parse("expireAfterWrite=1h"))
+ .addEqualityGroup(parse("weakKeys"), parse("weakKeys"))
+ .addEqualityGroup(parse("softValues"), parse("softValues"))
+ .addEqualityGroup(parse("weakValues"), parse("weakValues"))
+ .testEquals();
+ }
+
+ public void testMaximumWeight_withWeigher() {
+ CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumWeight=9000"));
+ builder
+ .weigher(constantWeigher(42))
+ .build(CacheLoader.from(Suppliers.ofInstance(null)));
+ }
+
+ public void testMaximumWeight_withoutWeigher() {
+ CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumWeight=9000"));
+ try {
+ builder.build(CacheLoader.from(Suppliers.ofInstance(null)));
+ fail();
+ } catch (IllegalStateException expected) {}
+ }
+
+ public void testMaximumSize_withWeigher() {
+ CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumSize=9000"));
+ builder
+ .weigher(constantWeigher(42))
+ .build(CacheLoader.from(Suppliers.ofInstance(null)));
+ }
+
+ public void testMaximumSize_withoutWeigher() {
+ CacheBuilder<Object, Object> builder = CacheBuilder.from(parse("maximumSize=9000"));
+ builder.build(CacheLoader.from(Suppliers.ofInstance(null)));
+ }
+
+ public void testDisableCaching() {
+ // Functional test: assert that CacheBuilderSpec.disableCaching()
+ // disables caching. It's irrelevant how it does so.
+ CacheBuilder<Object, Object> builder = CacheBuilder.from(CacheBuilderSpec.disableCaching());
+ Object key = new Object();
+ Object value = new Object();
+ LoadingCache<Object, Object> cache = builder.build(
+ CacheLoader.from(Suppliers.ofInstance(value)));
+ assertSame(value, cache.getUnchecked(key));
+ assertEquals(0, cache.size());
+ assertFalse(cache.asMap().containsKey(key));
+ }
+
+ public void testCacheBuilderFrom_string() {
+ CacheBuilder fromString = CacheBuilder.from(
+ "initialCapacity=10,maximumSize=20,concurrencyLevel=30,"
+ + "weakKeys,weakValues,expireAfterAccess=10m");
+ CacheBuilder expected = CacheBuilder.newBuilder()
+ .initialCapacity(10)
+ .maximumSize(20)
+ .concurrencyLevel(30)
+ .weakKeys()
+ .weakValues()
+ .expireAfterAccess(10L, TimeUnit.MINUTES);
+ assertCacheBuilderEquivalence(expected, fromString);
+ }
+
+ private static void assertCacheBuilderEquivalence(CacheBuilder a, CacheBuilder b) {
+ assertEquals("concurrencyLevel", a.concurrencyLevel, b.concurrencyLevel);
+ assertEquals("expireAfterAccessNanos", a.expireAfterAccessNanos, b.expireAfterAccessNanos);
+ assertEquals("expireAfterWriteNanos", a.expireAfterWriteNanos, b.expireAfterWriteNanos);
+ assertEquals("initialCapacity", a.initialCapacity, b.initialCapacity);
+ assertEquals("maximumSize", a.maximumSize, b.maximumSize);
+ assertEquals("maximumWeight", a.maximumWeight, b.maximumWeight);
+ assertEquals("refreshNanos", a.refreshNanos, b.refreshNanos);
+ assertEquals("keyEquivalence", a.keyEquivalence, b.keyEquivalence);
+ assertEquals("keyStrength", a.keyStrength, b.keyStrength);
+ assertEquals("removalListener", a.removalListener, b.removalListener);
+ assertEquals("weigher", a.weigher, b.weigher);
+ assertEquals("valueEquivalence", a.valueEquivalence, b.valueEquivalence);
+ assertEquals("valueStrength", a.valueStrength, b.valueStrength);
+ assertEquals("statsCounterSupplier", a.statsCounterSupplier, b.statsCounterSupplier);
+ assertEquals("ticker", a.ticker, b.ticker);
+ }
+}
diff --git a/guava-tests/test/com/google/common/cache/CacheBuilderTest.java b/guava-tests/test/com/google/common/cache/CacheBuilderTest.java
index 31b917d..1d882e6 100644
--- a/guava-tests/test/com/google/common/cache/CacheBuilderTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheBuilderTest.java
@@ -52,7 +52,6 @@ import java.util.concurrent.atomic.AtomicInteger;
@GwtCompatible(emulated = true)
public class CacheBuilderTest extends TestCase {
- @GwtIncompatible("removalListener")
public void testNewBuilder() {
CacheLoader<Object, Integer> loader = constantLoader(1);
@@ -289,7 +288,6 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalStateException expected) {}
}
- @GwtIncompatible("expireAfterAccess")
public void testTimeToIdle_negative() {
CacheBuilder<Object, Object> builder = new CacheBuilder<Object, Object>();
try {
@@ -298,7 +296,6 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalArgumentException expected) {}
}
- @GwtIncompatible("expireAfterAccess")
public void testTimeToIdle_small() {
CacheBuilder.newBuilder()
.expireAfterAccess(1, NANOSECONDS)
@@ -306,7 +303,6 @@ public class CacheBuilderTest extends TestCase {
// well, it didn't blow up.
}
- @GwtIncompatible("expireAfterAccess")
public void testTimeToIdle_setTwice() {
CacheBuilder<Object, Object> builder =
new CacheBuilder<Object, Object>().expireAfterAccess(3600, SECONDS);
@@ -317,7 +313,6 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalStateException expected) {}
}
- @GwtIncompatible("expireAfterAccess")
public void testTimeToIdleAndToLive() {
CacheBuilder.newBuilder()
.expireAfterWrite(1, NANOSECONDS)
@@ -346,7 +341,6 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalStateException expected) {}
}
- @GwtIncompatible("ticker")
public void testTicker_setTwice() {
Ticker testTicker = Ticker.systemTicker();
CacheBuilder<Object, Object> builder =
@@ -358,7 +352,6 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalStateException expected) {}
}
- @GwtIncompatible("removalListener")
public void testRemovalListener_setTwice() {
RemovalListener<Object, Object> testListener = nullRemovalListener();
CacheBuilder<Object, Object> builder =
@@ -370,7 +363,7 @@ public class CacheBuilderTest extends TestCase {
} catch (IllegalStateException expected) {}
}
- @GwtIncompatible("removalListener")
+ @GwtIncompatible("CacheTesting")
public void testNullCache() {
CountingRemovalListener<Object, Object> listener = countingRemovalListener();
LoadingCache<Object, Object> nullCache = new CacheBuilder<Object, Object>()
@@ -385,7 +378,7 @@ public class CacheBuilderTest extends TestCase {
CacheTesting.checkEmpty(nullCache.asMap());
}
- @GwtIncompatible("removalListener")
+ @GwtIncompatible("QueuingRemovalListener")
public void testRemovalNotification_clear() throws InterruptedException {
// If a clear() happens while a computation is pending, we should not get a removal
@@ -450,7 +443,7 @@ public class CacheBuilderTest extends TestCase {
* removal listener), or else is not affected by the {@code clear()} (and therefore exists in the
* cache afterward).
*/
- @GwtIncompatible("removalListener")
+ @GwtIncompatible("QueuingRemovalListener")
public void testRemovalNotification_clear_basher() throws InterruptedException {
// If a clear() happens close to the end of computation, one of two things should happen:
@@ -528,10 +521,10 @@ public class CacheBuilderTest extends TestCase {
* Calls get() repeatedly from many different threads, and tests that all of the removed entries
* (removed because of size limits or expiration) trigger appropriate removal notifications.
*/
- @GwtIncompatible("removalListener")
+ @GwtIncompatible("QueuingRemovalListener")
public void testRemovalNotification_get_basher() throws InterruptedException {
- int nTasks = 3000;
+ int nTasks = 1000;
int nThreads = 100;
final int getsPerTask = 1000;
final int nUniqueKeys = 10000;
@@ -562,6 +555,7 @@ public class CacheBuilderTest extends TestCase {
}
};
final LoadingCache<String, String> cache = CacheBuilder.newBuilder()
+ .recordStats()
.concurrencyLevel(2)
.expireAfterWrite(100, TimeUnit.MILLISECONDS)
.removalListener(removalListener)
diff --git a/guava-tests/test/com/google/common/cache/CacheEvictionTest.java b/guava-tests/test/com/google/common/cache/CacheEvictionTest.java
index 64e322e..4011542 100644
--- a/guava-tests/test/com/google/common/cache/CacheEvictionTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheEvictionTest.java
@@ -19,7 +19,7 @@ import static com.google.common.cache.TestingRemovalListeners.countingRemovalLis
import static com.google.common.cache.TestingWeighers.constantWeigher;
import static com.google.common.cache.TestingWeighers.intKeyWeigher;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.cache.CacheTesting.Receiver;
import com.google.common.cache.LocalCache.ReferenceEntry;
@@ -169,27 +169,27 @@ public class CacheEvictionTest extends TestCase {
.build(loader);
CacheTesting.warmUp(cache, 0, 10);
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// re-order
getAll(cache, asList(0, 1, 2));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
+ ASSERT.that(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
// evict 3, 4, 5
getAll(cache, asList(10, 11, 12));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(6, 7, 8, 9, 0, 1, 2, 10, 11, 12);
+ ASSERT.that(keySet).has().allOf(6, 7, 8, 9, 0, 1, 2, 10, 11, 12);
// re-order
getAll(cache, asList(6, 7, 8));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(9, 0, 1, 2, 10, 11, 12, 6, 7, 8);
+ ASSERT.that(keySet).has().allOf(9, 0, 1, 2, 10, 11, 12, 6, 7, 8);
// evict 9, 0, 1
getAll(cache, asList(13, 14, 15));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(2, 10, 11, 12, 6, 7, 8, 13, 14, 15);
+ ASSERT.that(keySet).has().allOf(2, 10, 11, 12, 6, 7, 8, 13, 14, 15);
}
public void testEviction_weightedLru() {
@@ -202,37 +202,37 @@ public class CacheEvictionTest extends TestCase {
.build(loader);
CacheTesting.warmUp(cache, 0, 10);
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// re-order
getAll(cache, asList(0, 1, 2));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
+ ASSERT.that(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
// evict 3, 4, 5
getAll(cache, asList(10));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(6, 7, 8, 9, 0, 1, 2, 10);
+ ASSERT.that(keySet).has().allOf(6, 7, 8, 9, 0, 1, 2, 10);
// re-order
getAll(cache, asList(6, 7, 8));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(9, 0, 1, 2, 10, 6, 7, 8);
+ ASSERT.that(keySet).has().allOf(9, 0, 1, 2, 10, 6, 7, 8);
// evict 9, 1, 2, 10
getAll(cache, asList(15));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(0, 6, 7, 8, 15);
+ ASSERT.that(keySet).has().allOf(0, 6, 7, 8, 15);
// fill empty space
getAll(cache, asList(9));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(0, 6, 7, 8, 15, 9);
+ ASSERT.that(keySet).has().allOf(0, 6, 7, 8, 15, 9);
// evict 6
getAll(cache, asList(1));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(0, 7, 8, 15, 9, 1);
+ ASSERT.that(keySet).has().allOf(0, 7, 8, 15, 9, 1);
}
public void testEviction_overweight() {
@@ -245,17 +245,17 @@ public class CacheEvictionTest extends TestCase {
.build(loader);
CacheTesting.warmUp(cache, 0, 10);
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// add an at-the-maximum-weight entry
getAll(cache, asList(45));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(0, 45);
+ ASSERT.that(keySet).has().allOf(0, 45);
// add an over-the-maximum-weight entry
getAll(cache, asList(46));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(0);
+ ASSERT.that(keySet).has().item(0);
}
public void testEviction_invalidateAll() {
@@ -272,7 +272,7 @@ public class CacheEvictionTest extends TestCase {
// add 0, 1, 2, 3, 4
getAll(cache, asList(0, 1, 2, 3, 4));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4);
+ ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4);
// invalidate all
cache.invalidateAll();
@@ -282,7 +282,7 @@ public class CacheEvictionTest extends TestCase {
// add 5, 6, 7, 8, 9, 10, 11, 12
getAll(cache, asList(5, 6, 7, 8, 9, 10, 11, 12));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(5, 6, 7, 8, 9, 10, 11, 12);
+ ASSERT.that(keySet).has().allOf(5, 6, 7, 8, 9, 10, 11, 12);
}
private void getAll(LoadingCache<Integer, Integer> cache, List<Integer> keys) {
diff --git a/guava-tests/test/com/google/common/cache/CacheExpirationTest.java b/guava-tests/test/com/google/common/cache/CacheExpirationTest.java
index 97677cf..a2dd701 100644
--- a/guava-tests/test/com/google/common/cache/CacheExpirationTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheExpirationTest.java
@@ -18,7 +18,7 @@ import static com.google.common.cache.TestingCacheLoaders.identityLoader;
import static com.google.common.cache.TestingRemovalListeners.countingRemovalListener;
import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.cache.TestingCacheLoaders.IdentityLoader;
import com.google.common.cache.TestingRemovalListeners.CountingRemovalListener;
@@ -252,7 +252,7 @@ public class CacheExpirationTest extends TestCase {
IdentityLoader<Integer> loader = identityLoader();
LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
.concurrencyLevel(1)
- .expireAfterAccess(10, MILLISECONDS)
+ .expireAfterAccess(11, MILLISECONDS)
.ticker(ticker)
.build(loader);
for (int i = 0; i < 10; i++) {
@@ -260,42 +260,42 @@ public class CacheExpirationTest extends TestCase {
ticker.advance(1, MILLISECONDS);
}
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// 0 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).has().allOf(1, 2, 3, 4, 5, 6, 7, 8, 9);
// reorder
getAll(cache, asList(0, 1, 2));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(2, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
+ ASSERT.that(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0, 1, 2);
// 3 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(4, 5, 6, 7, 8, 9, 0, 1, 2);
+ ASSERT.that(keySet).has().allOf(4, 5, 6, 7, 8, 9, 0, 1, 2);
// reorder
getAll(cache, asList(5, 7, 9));
CacheTesting.drainRecencyQueues(cache);
- ASSERT.that(keySet).hasContentsAnyOrder(4, 6, 8, 0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).has().allOf(4, 6, 8, 0, 1, 2, 5, 7, 9);
// 4 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(6, 8, 0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).has().allOf(6, 8, 0, 1, 2, 5, 7, 9);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(6, 8, 0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).has().allOf(6, 8, 0, 1, 2, 5, 7, 9);
// 6 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(8, 0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).has().allOf(8, 0, 1, 2, 5, 7, 9);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(8, 0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).has().allOf(8, 0, 1, 2, 5, 7, 9);
// 8 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 5, 7, 9);
+ ASSERT.that(keySet).has().allOf(0, 1, 2, 5, 7, 9);
}
public void testExpirationOrder_write() throws ExecutionException {
@@ -304,7 +304,7 @@ public class CacheExpirationTest extends TestCase {
IdentityLoader<Integer> loader = identityLoader();
LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
.concurrencyLevel(1)
- .expireAfterWrite(10, MILLISECONDS)
+ .expireAfterWrite(11, MILLISECONDS)
.ticker(ticker)
.build(loader);
for (int i = 0; i < 10; i++) {
@@ -312,37 +312,37 @@ public class CacheExpirationTest extends TestCase {
ticker.advance(1, MILLISECONDS);
}
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// 0 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).has().allOf(1, 2, 3, 4, 5, 6, 7, 8, 9);
// get doesn't stop 1 from expiring
getAll(cache, asList(0, 1, 2));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(2, 3, 4, 5, 6, 7, 8, 9, 0);
+ ASSERT.that(keySet).has().allOf(2, 3, 4, 5, 6, 7, 8, 9, 0);
// get(K, Callable) doesn't stop 2 from expiring
cache.get(2, Callables.returning(-2));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(3, 4, 5, 6, 7, 8, 9, 0);
+ ASSERT.that(keySet).has().allOf(3, 4, 5, 6, 7, 8, 9, 0);
// asMap.put saves 3
cache.asMap().put(3, -3);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(4, 5, 6, 7, 8, 9, 0, 3);
+ ASSERT.that(keySet).has().allOf(4, 5, 6, 7, 8, 9, 0, 3);
// asMap.replace saves 4
cache.asMap().replace(4, -4);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(5, 6, 7, 8, 9, 0, 3, 4);
+ ASSERT.that(keySet).has().allOf(5, 6, 7, 8, 9, 0, 3, 4);
// 5 expires
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(6, 7, 8, 9, 0, 3, 4);
+ ASSERT.that(keySet).has().allOf(6, 7, 8, 9, 0, 3, 4);
}
public void testExpirationOrder_writeAccess() throws ExecutionException {
@@ -351,8 +351,8 @@ public class CacheExpirationTest extends TestCase {
IdentityLoader<Integer> loader = identityLoader();
LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
.concurrencyLevel(1)
- .expireAfterWrite(4, MILLISECONDS)
- .expireAfterAccess(2, MILLISECONDS)
+ .expireAfterWrite(5, MILLISECONDS)
+ .expireAfterAccess(3, MILLISECONDS)
.ticker(ticker)
.build(loader);
for (int i = 0; i < 5; i++) {
@@ -365,33 +365,33 @@ public class CacheExpirationTest extends TestCase {
ticker.advance(1, MILLISECONDS);
Set<Integer> keySet = cache.asMap().keySet();
- ASSERT.that(keySet).hasContentsAnyOrder(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ ASSERT.that(keySet).has().allOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
// get saves 1, 3; 0, 2, 4 expire
getAll(cache, asList(1, 3));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(5, 6, 7, 8, 9, 1, 3);
+ ASSERT.that(keySet).has().allOf(5, 6, 7, 8, 9, 1, 3);
// get saves 6, 8; 5, 7, 9 expire
getAll(cache, asList(6, 8));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(1, 3, 6, 8);
+ ASSERT.that(keySet).has().allOf(1, 3, 6, 8);
// get fails to save 1, put saves 3
cache.asMap().put(3, -3);
getAll(cache, asList(1));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(6, 8, 3);
+ ASSERT.that(keySet).has().allOf(6, 8, 3);
// get(K, Callable) fails to save 8, replace saves 6
cache.asMap().replace(6, -6);
cache.get(8, Callables.returning(-8));
CacheTesting.drainRecencyQueues(cache);
ticker.advance(1, MILLISECONDS);
- ASSERT.that(keySet).hasContentsAnyOrder(3, 6);
+ ASSERT.that(keySet).has().allOf(3, 6);
}
private void runRemovalScheduler(LoadingCache<String, Integer> cache,
diff --git a/guava-tests/test/com/google/common/cache/CacheLoadingTest.java b/guava-tests/test/com/google/common/cache/CacheLoadingTest.java
index f108b63..90b9ff3 100644
--- a/guava-tests/test/com/google/common/cache/CacheLoadingTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheLoadingTest.java
@@ -22,7 +22,7 @@ import static com.google.common.cache.TestingCacheLoaders.identityLoader;
import static com.google.common.cache.TestingRemovalListeners.countingRemovalListener;
import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.cache.CacheLoader.InvalidCacheLoadException;
import com.google.common.cache.TestingCacheLoaders.CountingLoader;
@@ -98,6 +98,7 @@ public class CacheLoadingTest extends TestCase {
public void testLoad() throws ExecutionException {
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.build(identityLoader());
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -170,7 +171,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -218,6 +219,7 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -277,6 +279,7 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -321,6 +324,7 @@ public class CacheLoadingTest extends TestCase {
public void testBulkLoad_default() throws ExecutionException {
LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder()
+ .recordStats()
.build(TestingCacheLoaders.<Integer>identityLoader());
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -367,7 +371,7 @@ public class CacheLoadingTest extends TestCase {
public void testBulkLoad_loadAll() throws ExecutionException {
IdentityLoader<Integer> backingLoader = identityLoader();
CacheLoader<Integer, Integer> loader = bulkLoader(backingLoader);
- LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Integer, Integer> cache = CacheBuilder.newBuilder().recordStats().build(loader);
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
@@ -433,7 +437,7 @@ public class CacheLoadingTest extends TestCase {
Object[] lookupKeys = new Object[] { new Object(), new Object(), new Object() };
Map<Object, Object> result = cache.getAll(asList(lookupKeys));
- ASSERT.that(result.keySet()).hasContentsAnyOrder(lookupKeys);
+ ASSERT.that(result.keySet()).has().allFrom(asList(lookupKeys));
for (Map.Entry<Object, Object> entry : result.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
@@ -470,7 +474,7 @@ public class CacheLoadingTest extends TestCase {
Object[] lookupKeys = new Object[] { new Object(), new Object(), new Object() };
Map<Object, Object> result = cache.getAll(asList(lookupKeys));
- ASSERT.that(result.keySet()).hasContentsAnyOrder(lookupKeys);
+ ASSERT.that(result.keySet()).has().allFrom(asList(lookupKeys));
for (Map.Entry<Object, Object> entry : result.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
@@ -586,6 +590,7 @@ public class CacheLoadingTest extends TestCase {
public void testLoadNull() throws ExecutionException {
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.build(constantLoader(null));
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -656,7 +661,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -701,7 +706,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -748,6 +753,7 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -793,6 +799,7 @@ public class CacheLoadingTest extends TestCase {
public void testBulkLoadNull() throws ExecutionException {
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.build(bulkLoader(constantLoader(null)));
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -812,8 +819,9 @@ public class CacheLoadingTest extends TestCase {
}
public void testBulkLoadNullMap() throws ExecutionException {
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(
- new CacheLoader<Object, Object>() {
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
+ .build(new CacheLoader<Object, Object>() {
@Override
public Object load(Object key) {
throw new AssertionError();
@@ -845,7 +853,7 @@ public class CacheLoadingTest extends TestCase {
public void testLoadError() throws ExecutionException {
Error e = new Error();
CacheLoader<Object, Object> loader = errorLoader(e);
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
@@ -930,7 +938,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -976,7 +984,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1024,6 +1032,7 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -1071,6 +1080,7 @@ public class CacheLoadingTest extends TestCase {
Error e = new Error();
CacheLoader<Object, Object> loader = errorLoader(e);
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.build(bulkLoader(loader));
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1094,7 +1104,7 @@ public class CacheLoadingTest extends TestCase {
public void testLoadCheckedException() {
Exception e = new Exception();
CacheLoader<Object, Object> loader = exceptionLoader(e);
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
@@ -1174,7 +1184,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1220,7 +1230,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1268,6 +1278,7 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -1315,6 +1326,7 @@ public class CacheLoadingTest extends TestCase {
Exception e = new Exception();
CacheLoader<Object, Object> loader = exceptionLoader(e);
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.build(bulkLoader(loader));
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1338,7 +1350,7 @@ public class CacheLoadingTest extends TestCase {
public void testLoadUncheckedException() throws ExecutionException {
Exception e = new RuntimeException();
CacheLoader<Object, Object> loader = exceptionLoader(e);
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
@@ -1418,7 +1430,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1464,7 +1476,7 @@ public class CacheLoadingTest extends TestCase {
}
};
- LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().build(loader);
+ LoadingCache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build(loader);
Object key = new Object();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1512,6 +1524,7 @@ public class CacheLoadingTest extends TestCase {
};
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.ticker(ticker)
.refreshAfterWrite(1, MILLISECONDS)
.build(loader);
@@ -1559,6 +1572,7 @@ public class CacheLoadingTest extends TestCase {
Exception e = new RuntimeException();
CacheLoader<Object, Object> loader = exceptionLoader(e);
LoadingCache<Object, Object> cache = CacheBuilder.newBuilder()
+ .recordStats()
.build(bulkLoader(loader));
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
@@ -1594,7 +1608,6 @@ public class CacheLoadingTest extends TestCase {
};
CountingRemovalListener<Integer, String> removalListener = countingRemovalListener();
LoadingCache<Integer, String> cache = CacheBuilder.newBuilder()
- .weakValues()
.removalListener(removalListener)
.build(failOnceFunction);
@@ -2132,6 +2145,79 @@ public class CacheLoadingTest extends TestCase {
assertEquals(2, cache.size());
assertEquals(getKey + suffix, map.get(getKey));
assertEquals(refreshKey + suffix, map.get(refreshKey));
+ assertEquals(2, cache.size());
+ }
+
+ public void testInvalidateAndReloadDuringLoading()
+ throws InterruptedException, ExecutionException {
+ // computation starts; clear() is called, computation finishes
+ final CountDownLatch computationStarted = new CountDownLatch(2);
+ final CountDownLatch letGetFinishSignal = new CountDownLatch(1);
+ final CountDownLatch getFinishedSignal = new CountDownLatch(4);
+ final String getKey = "get";
+ final String refreshKey = "refresh";
+ final String suffix = "Suffix";
+
+ CacheLoader<String, String> computeFunction = new CacheLoader<String, String>() {
+ @Override
+ public String load(String key) throws InterruptedException {
+ computationStarted.countDown();
+ letGetFinishSignal.await();
+ return key + suffix;
+ }
+ };
+
+ final LoadingCache<String, String> cache = CacheBuilder.newBuilder()
+ .build(computeFunction);
+ ConcurrentMap<String,String> map = cache.asMap();
+ map.put(refreshKey, refreshKey);
+
+ new Thread() {
+ @Override
+ public void run() {
+ cache.getUnchecked(getKey);
+ getFinishedSignal.countDown();
+ }
+ }.start();
+ new Thread() {
+ @Override
+ public void run() {
+ cache.refresh(refreshKey);
+ getFinishedSignal.countDown();
+ }
+ }.start();
+
+ computationStarted.await();
+ cache.invalidate(getKey);
+ cache.invalidate(refreshKey);
+ assertFalse(map.containsKey(getKey));
+ assertFalse(map.containsKey(refreshKey));
+
+ // start new computations
+ new Thread() {
+ @Override
+ public void run() {
+ cache.getUnchecked(getKey);
+ getFinishedSignal.countDown();
+ }
+ }.start();
+ new Thread() {
+ @Override
+ public void run() {
+ cache.refresh(refreshKey);
+ getFinishedSignal.countDown();
+ }
+ }.start();
+
+ // let computation complete
+ letGetFinishSignal.countDown();
+ getFinishedSignal.await();
+ checkNothingLogged();
+
+ // results should be visible
+ assertEquals(2, cache.size());
+ assertEquals(getKey + suffix, map.get(getKey));
+ assertEquals(refreshKey + suffix, map.get(refreshKey));
}
public void testExpandDuringLoading() throws InterruptedException {
diff --git a/guava-tests/test/com/google/common/cache/CacheManualTest.java b/guava-tests/test/com/google/common/cache/CacheManualTest.java
index d8db9b6..5bea1a6 100644
--- a/guava-tests/test/com/google/common/cache/CacheManualTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheManualTest.java
@@ -27,7 +27,7 @@ import junit.framework.TestCase;
public class CacheManualTest extends TestCase {
public void testGetIfPresent() {
- Cache<Object, Object> cache = CacheBuilder.newBuilder().build();
+ Cache<Object, Object> cache = CacheBuilder.newBuilder().recordStats().build();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
@@ -103,7 +103,7 @@ public class CacheManualTest extends TestCase {
}
public void testGetAllPresent() {
- Cache<Integer, Integer> cache = CacheBuilder.newBuilder().build();
+ Cache<Integer, Integer> cache = CacheBuilder.newBuilder().recordStats().build();
CacheStats stats = cache.stats();
assertEquals(0, stats.missCount());
assertEquals(0, stats.loadSuccessCount());
diff --git a/guava-tests/test/com/google/common/cache/CacheReferencesTest.java b/guava-tests/test/com/google/common/cache/CacheReferencesTest.java
index ce74b67..295cf59 100644
--- a/guava-tests/test/com/google/common/cache/CacheReferencesTest.java
+++ b/guava-tests/test/com/google/common/cache/CacheReferencesTest.java
@@ -17,7 +17,7 @@ package com.google.common.cache;
import static com.google.common.cache.LocalCache.Strength.STRONG;
import static com.google.common.cache.TestingRemovalListeners.countingRemovalListener;
import static com.google.common.collect.Maps.immutableEntry;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.base.Function;
import com.google.common.cache.LocalCache.Strength;
@@ -95,7 +95,7 @@ public class CacheReferencesTest extends TestCase {
assertSame(value1, cache.getUnchecked(key1));
assertSame(value2, cache.getUnchecked(key2));
assertEquals(ImmutableSet.of(key1, key2), cache.asMap().keySet());
- ASSERT.that(cache.asMap().values()).hasContentsAnyOrder(value1, value2);
+ ASSERT.that(cache.asMap().values()).has().allOf(value1, value2);
assertEquals(ImmutableSet.of(immutableEntry(key1, value1), immutableEntry(key2, value2)),
cache.asMap().entrySet());
}
@@ -114,7 +114,7 @@ public class CacheReferencesTest extends TestCase {
assertTrue(cache.asMap().containsKey(key2));
assertEquals(1, cache.size());
assertEquals(ImmutableSet.of(key2), cache.asMap().keySet());
- ASSERT.that(cache.asMap().values()).hasContentsAnyOrder(value2);
+ ASSERT.that(cache.asMap().values()).has().item(value2);
assertEquals(ImmutableSet.of(immutableEntry(key2, value2)), cache.asMap().entrySet());
}
}
diff --git a/guava-tests/test/com/google/common/cache/CacheTesting.java b/guava-tests/test/com/google/common/cache/CacheTesting.java
index febd766..62a7270 100644
--- a/guava-tests/test/com/google/common/cache/CacheTesting.java
+++ b/guava-tests/test/com/google/common/cache/CacheTesting.java
@@ -14,6 +14,7 @@
package com.google.common.cache;
+import static com.google.common.base.Preconditions.checkNotNull;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
@@ -91,6 +92,8 @@ class CacheTesting {
}
static <K, V> ReferenceEntry<K, V> getReferenceEntry(Cache<K, V> cache, K key) {
+ checkNotNull(cache);
+ checkNotNull(key);
LocalCache<K, V> map = toLocalCache(cache);
return map.getEntry(key);
}
@@ -100,6 +103,8 @@ class CacheTesting {
* {@link Segment#expand()}.
*/
static <K, V> void forceExpandSegment(Cache<K, V> cache, K key) {
+ checkNotNull(cache);
+ checkNotNull(key);
LocalCache<K, V> map = toLocalCache(cache);
int hash = map.hash(key);
Segment<K, V> segment = map.segmentFor(hash);
@@ -123,7 +128,7 @@ class CacheTesting {
* {@link #toLocalCache} without throwing an exception.
*/
static boolean hasLocalCache(Cache<?, ?> cache) {
- return (cache instanceof LocalLoadingCache);
+ return (checkNotNull(cache) instanceof LocalLoadingCache);
}
static void drainRecencyQueues(Cache<?, ?> cache) {
@@ -375,7 +380,7 @@ class CacheTesting {
*/
static void checkRecency(LoadingCache<Integer, Integer> cache, int maxSize,
Receiver<ReferenceEntry<Integer, Integer>> operation) {
-
+ checkNotNull(operation);
if (hasLocalCache(cache)) {
warmUp(cache, 0, 2 * maxSize);
@@ -400,12 +405,14 @@ class CacheTesting {
* Warms the given cache by getting all values in {@code [start, end)}, in order.
*/
static void warmUp(LoadingCache<Integer, Integer> map, int start, int end) {
+ checkNotNull(map);
for (int i = start; i < end; i++) {
map.getUnchecked(i);
}
}
static void expireEntries(Cache<?, ?> cache, long expiringTime, FakeTicker ticker) {
+ checkNotNull(ticker);
expireEntries(toLocalCache(cache), expiringTime, ticker);
}
diff --git a/guava-tests/test/com/google/common/cache/EmptyCachesTest.java b/guava-tests/test/com/google/common/cache/EmptyCachesTest.java
index c31cf68..994f236 100644
--- a/guava-tests/test/com/google/common/cache/EmptyCachesTest.java
+++ b/guava-tests/test/com/google/common/cache/EmptyCachesTest.java
@@ -40,7 +40,9 @@ import java.util.concurrent.ExecutionException;
*
* @author mike nonemacher
*/
+
public class EmptyCachesTest extends TestCase {
+
public void testEmpty() {
for (LoadingCache<Object, Object> cache : caches()) {
checkEmpty(cache);
@@ -314,7 +316,7 @@ public class EmptyCachesTest extends TestCase {
assertFalse(entrySet.remove(entryOf(6, 6)));
assertFalse(entrySet.remove(entryOf(-6, -6)));
assertFalse(entrySet.removeAll(asList(null, entryOf(0, 0), entryOf(15, 15))));
- assertFalse(entrySet.retainAll( asList(null, entryOf(0, 0), entryOf(15, 15))));
+ assertFalse(entrySet.retainAll(asList(null, entryOf(0, 0), entryOf(15, 15))));
checkEmpty(entrySet);
checkEmpty(cache);
}
diff --git a/guava-tests/test/com/google/common/cache/LocalCacheTest.java b/guava-tests/test/com/google/common/cache/LocalCacheTest.java
index 7f926e3..731de62 100644
--- a/guava-tests/test/com/google/common/cache/LocalCacheTest.java
+++ b/guava-tests/test/com/google/common/cache/LocalCacheTest.java
@@ -30,7 +30,6 @@ import static com.google.common.collect.Maps.immutableEntry;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.easymock.EasyMock.createMock;
import com.google.common.base.Equivalence;
import com.google.common.base.Ticker;
@@ -253,7 +252,7 @@ public class LocalCacheTest extends TestCase {
public void testSetMaximumSize() {
// vary maximumSize wrt concurrencyLevel
- for (int maxSize = 1; maxSize < 8; maxSize++) {
+ for (int maxSize = 1; maxSize < 100; maxSize++) {
checkMaximumSize(1, 8, maxSize);
checkMaximumSize(2, 8, maxSize);
checkMaximumSize(4, 8, maxSize);
@@ -281,6 +280,8 @@ public class LocalCacheTest extends TestCase {
.initialCapacity(initialCapacity)
.maximumSize(maxSize));
long totalCapacity = 0;
+ assertTrue("segments=" + map.segments.length + ", maxSize=" + maxSize,
+ map.segments.length <= Math.max(1, maxSize / 10));
for (int i = 0; i < map.segments.length; i++) {
totalCapacity += map.segments[i].maxSegmentWeight;
}
@@ -291,6 +292,8 @@ public class LocalCacheTest extends TestCase {
.initialCapacity(initialCapacity)
.maximumWeight(maxSize)
.weigher(constantWeigher(1)));
+ assertTrue("segments=" + map.segments.length + ", maxSize=" + maxSize,
+ map.segments.length <= Math.max(1, maxSize / 10));
totalCapacity = 0;
for (int i = 0; i < map.segments.length; i++) {
totalCapacity += map.segments[i].maxSegmentWeight;
@@ -482,7 +485,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value, entry);
+ DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value);
entry.setValueReference(valueRef);
table.set(index, entry);
segment.count++;
@@ -511,7 +514,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value, entry);
+ DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value);
entry.setValueReference(valueRef);
table.set(index, entry);
segment.count++;
@@ -710,11 +713,11 @@ public class LocalCacheTest extends TestCase {
// already loading
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> valueRef = DummyValueReference.create(null, entry);
+ DummyValueReference<Object, Object> valueRef = DummyValueReference.create(null);
valueRef.setLoading(true);
entry.setValueReference(valueRef);
table.set(index, entry);
- assertNull(segment.refresh(key, hash, identityLoader()));
+ assertNull(segment.refresh(key, hash, identityLoader(), false));
}
// Removal listener tests
@@ -819,7 +822,7 @@ public class LocalCacheTest extends TestCase {
QueuingRemovalListener<Object, Object> listener = queuingRemovalListener();
LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()
.concurrencyLevel(1)
- .expireAfterWrite(2, TimeUnit.NANOSECONDS)
+ .expireAfterWrite(3, TimeUnit.NANOSECONDS)
.ticker(ticker)
.removalListener(listener));
assertTrue(listener.isEmpty());
@@ -1048,7 +1051,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
entry.setValueReference(oldValueRef);
// no entry
@@ -1092,7 +1095,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
entry.setValueReference(oldValueRef);
// no entry
@@ -1140,7 +1143,7 @@ public class LocalCacheTest extends TestCase {
// cleared
ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
entry.setValueReference(oldValueRef);
assertSame(oldValue, segment.get(key, hash));
oldValueRef.clear();
@@ -1172,7 +1175,7 @@ public class LocalCacheTest extends TestCase {
// cleared
ReferenceEntry<Object, Object> entry = segment.getEntry(key, hash);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
entry.setValueReference(oldValueRef);
assertSame(oldValue, segment.get(key, hash));
oldValueRef.clear();
@@ -1268,7 +1271,7 @@ public class LocalCacheTest extends TestCase {
// replaced
Object value4 = new Object();
- DummyValueReference<Object, Object> value3Ref = DummyValueReference.create(value3, entry);
+ DummyValueReference<Object, Object> value3Ref = DummyValueReference.create(value3);
valueRef = new LoadingValueReference<Object, Object>(value3Ref);
entry.setValueReference(valueRef);
table.set(index, entry);
@@ -1308,7 +1311,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
entry.setValueReference(oldValueRef);
// no entry
@@ -1348,7 +1351,7 @@ public class LocalCacheTest extends TestCase {
int index = hash & (table.length() - 1);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue, entry);
+ DummyValueReference<Object, Object> oldValueRef = DummyValueReference.create(oldValue);
entry.setValueReference(oldValueRef);
// no entry
@@ -1417,6 +1420,49 @@ public class LocalCacheTest extends TestCase {
}
}
+ public void testGetCausesExpansion() throws ExecutionException {
+ for (int count = 1; count <= 100; count++) {
+ LocalCache<Object, Object> map =
+ makeLocalCache(createCacheBuilder().concurrencyLevel(1).initialCapacity(1));
+ Segment<Object, Object> segment = map.segments[0];
+ assertEquals(1, segment.table.length());
+
+ for (int i = 0; i < count; i++) {
+ Object key = new Object();
+ final Object value = new Object();
+ segment.get(key, key.hashCode(), new CacheLoader<Object, Object>() {
+ @Override
+ public Object load(Object key) {
+ return value;
+ }
+ });
+ }
+ assertEquals(count, segment.count);
+ assertTrue(count <= segment.threshold);
+ assertTrue(count <= (segment.table.length() * 3 / 4));
+ assertTrue(count > (segment.table.length() * 3 / 8));
+ }
+ }
+
+ public void testPutCausesExpansion() {
+ for (int count = 1; count <= 100; count++) {
+ LocalCache<Object, Object> map =
+ makeLocalCache(createCacheBuilder().concurrencyLevel(1).initialCapacity(1));
+ Segment<Object, Object> segment = map.segments[0];
+ assertEquals(1, segment.table.length());
+
+ for (int i = 0; i < count; i++) {
+ Object key = new Object();
+ Object value = new Object();
+ segment.put(key, key.hashCode(), value, true);
+ }
+ assertEquals(count, segment.count);
+ assertTrue(count <= segment.threshold);
+ assertTrue(count <= (segment.table.length() * 3 / 4));
+ assertTrue(count > (segment.table.length() * 3 / 8));
+ }
+ }
+
public void testReclaimKey() {
CountingRemovalListener<Object, Object> listener = countingRemovalListener();
LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()
@@ -1532,7 +1578,7 @@ public class LocalCacheTest extends TestCase {
}
// chain all entries together as we only have a single bucket
entry = DummyEntry.create(key, hash, entry);
- ValueReference<Object, Object> valueRef = DummyValueReference.create(value, entry);
+ ValueReference<Object, Object> valueRef = DummyValueReference.create(value);
entry.setValueReference(valueRef);
}
segment.table.set(0, entry);
@@ -1690,7 +1736,7 @@ public class LocalCacheTest extends TestCase {
Object value = new Object();
int hash = map.hash(key);
DummyEntry<Object, Object> entry = DummyEntry.create(key, hash, null);
- DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value, entry);
+ DummyValueReference<Object, Object> valueRef = DummyValueReference.create(value);
entry.setValueReference(valueRef);
// reclaim absent
@@ -1712,7 +1758,7 @@ public class LocalCacheTest extends TestCase {
// reclaim wrong value reference
table.set(0, entry);
- DummyValueReference<Object, Object> otherValueRef = DummyValueReference.create(value, entry);
+ DummyValueReference<Object, Object> otherValueRef = DummyValueReference.create(value);
entry.setValueReference(otherValueRef);
assertFalse(segment.reclaimValue(key, hash, valueRef));
assertEquals(1, listener.getCount());
@@ -1753,7 +1799,7 @@ public class LocalCacheTest extends TestCase {
// active
Object value = new Object();
- DummyValueReference<Object, Object> previousRef = DummyValueReference.create(value, entry);
+ DummyValueReference<Object, Object> previousRef = DummyValueReference.create(value);
valueRef = new LoadingValueReference<Object, Object>(previousRef);
entry.setValueReference(valueRef);
table.set(0, entry);
@@ -1764,7 +1810,7 @@ public class LocalCacheTest extends TestCase {
// wrong value reference
table.set(0, entry);
- DummyValueReference<Object, Object> otherValueRef = DummyValueReference.create(value, entry);
+ DummyValueReference<Object, Object> otherValueRef = DummyValueReference.create(value);
entry.setValueReference(otherValueRef);
assertFalse(segment.removeLoadingValue(key, hash, valueRef));
entry.setValueReference(valueRef);
@@ -2039,7 +2085,7 @@ public class LocalCacheTest extends TestCase {
LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()
.concurrencyLevel(1)
.ticker(ticker)
- .expireAfterWrite(1, TimeUnit.NANOSECONDS));
+ .expireAfterWrite(2, TimeUnit.NANOSECONDS));
Segment<Object, Object> segment = map.segments[0];
Object key = new Object();
@@ -2078,7 +2124,7 @@ public class LocalCacheTest extends TestCase {
LocalCache<Object, Object> map = makeLocalCache(createCacheBuilder()
.concurrencyLevel(1)
.ticker(ticker)
- .expireAfterAccess(1, TimeUnit.NANOSECONDS));
+ .expireAfterAccess(2, TimeUnit.NANOSECONDS));
Segment<Object, Object> segment = map.segments[0];
Object key = new Object();
@@ -2471,7 +2517,7 @@ public class LocalCacheTest extends TestCase {
private static <K, V> DummyEntry<K, V> createDummyEntry(
K key, int hash, V value, ReferenceEntry<K, V> next) {
DummyEntry<K, V> entry = DummyEntry.create(key, hash, next);
- DummyValueReference<K, V> valueRef = DummyValueReference.create(value, entry);
+ DummyValueReference<K, V> valueRef = DummyValueReference.create(value);
entry.setValueReference(valueRef);
return entry;
}
@@ -2596,26 +2642,23 @@ public class LocalCacheTest extends TestCase {
}
static class DummyValueReference<K, V> implements ValueReference<K, V> {
- final ReferenceEntry<K, V> entry;
private V value;
boolean loading = false;
- public DummyValueReference(ReferenceEntry<K, V> entry) {
- this(null, entry);
+ public DummyValueReference() {
this.loading = true;
}
- public DummyValueReference(V value, ReferenceEntry<K, V> entry) {
+ public DummyValueReference(V value) {
this.value = value;
- this.entry = entry;
}
- public static <K, V> DummyValueReference<K, V> create(V value, ReferenceEntry<K, V> entry) {
- return new DummyValueReference<K, V>(value, entry);
+ public static <K, V> DummyValueReference<K, V> create(V value) {
+ return new DummyValueReference<K, V>(value);
}
- public static <K, V> DummyValueReference<K, V> createLoading(ReferenceEntry<K, V> entry) {
- return new DummyValueReference<K, V>(entry);
+ public static <K, V> DummyValueReference<K, V> createLoading() {
+ return new DummyValueReference<K, V>();
}
@Override
@@ -2630,12 +2673,13 @@ public class LocalCacheTest extends TestCase {
@Override
public ReferenceEntry<K, V> getEntry() {
- return entry;
+ return null;
}
@Override
- public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
- return new DummyValueReference<K, V>(value, entry);
+ public ValueReference<K, V> copyFor(
+ ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
+ return this;
}
public void setLoading(boolean loading) {
diff --git a/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java b/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java
index c590cd7..90f6efb 100644
--- a/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java
+++ b/guava-tests/test/com/google/common/cache/LocalLoadingCacheTest.java
@@ -19,23 +19,19 @@ package com.google.common.cache;
import static com.google.common.cache.CacheBuilder.EMPTY_STATS;
import static com.google.common.cache.LocalCacheTest.SMALL_MAX_SIZE;
import static com.google.common.cache.TestingCacheLoaders.identityLoader;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.cache.LocalCache.LocalLoadingCache;
import com.google.common.cache.LocalCache.Segment;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
import com.google.common.testing.NullPointerTester;
-import com.google.common.util.concurrent.Callables;
import junit.framework.TestCase;
import java.lang.Thread.UncaughtExceptionHandler;
-import java.util.Collection;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -52,7 +48,7 @@ public class LocalLoadingCacheTest extends TestCase {
}
private CacheBuilder<Object, Object> createCacheBuilder() {
- return new CacheBuilder<Object, Object>();
+ return CacheBuilder.newBuilder().recordStats();
}
// constructor tests
@@ -72,7 +68,6 @@ public class LocalLoadingCacheTest extends TestCase {
public void testNullParameters() throws Exception {
NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Callable.class, Callables.returning(null));
CacheLoader<Object, Object> loader = identityLoader();
tester.testAllPublicInstanceMethods(makeCache(createCacheBuilder(), loader));
}
@@ -165,24 +160,27 @@ public class LocalLoadingCacheTest extends TestCase {
assertNull(map.put(three, one));
assertNull(map.put(one, two));
- Set<Map.Entry<Object, Object>> entries = map.entrySet();
- ASSERT.that(entries).hasContentsAnyOrder(
- Maps.immutableEntry(three, one), Maps.immutableEntry(one, two));
- Set<Object> keys = map.keySet();
- ASSERT.that(keys).hasContentsAnyOrder(one, three);
- Collection<Object> values = map.values();
- ASSERT.that(values).hasContentsAnyOrder(one, two);
+ ASSERT.that(map).hasKey(three).withValue(one);
+ ASSERT.that(map).hasKey(one).withValue(two);
+
+ //TODO(user): Confirm with fry@ that this is a reasonable substitute.
+ //Set<Map.Entry<Object, Object>> entries = map.entrySet();
+ //ASSERT.that(entries).has().allOf(
+ // Maps.immutableEntry(three, one), Maps.immutableEntry(one, two));
+ //Set<Object> keys = map.keySet();
+ //ASSERT.that(keys).has().allOf(one, three);
+ //Collection<Object> values = map.values();
+ //ASSERT.that(values).has().allOf(one, two);
map.clear();
assertEquals(EMPTY_STATS, cache.stats());
}
- public void testDisableStats() {
- CacheBuilder<Object, Object> builder = createCacheBuilder()
+ public void testNoStats() {
+ CacheBuilder<Object, Object> builder = CacheBuilder.newBuilder()
.concurrencyLevel(1)
- .maximumSize(2)
- .disableStats();
+ .maximumSize(2);
LocalLoadingCache<Object, Object> cache = makeCache(builder, identityLoader());
assertEquals(EMPTY_STATS, cache.stats());
@@ -202,6 +200,35 @@ public class LocalLoadingCacheTest extends TestCase {
assertEquals(EMPTY_STATS, cache.stats());
}
+ public void testRecordStats() {
+ CacheBuilder<Object, Object> builder = createCacheBuilder()
+ .recordStats()
+ .concurrencyLevel(1)
+ .maximumSize(2);
+ LocalLoadingCache<Object, Object> cache = makeCache(builder, identityLoader());
+ assertEquals(0, cache.stats().hitCount());
+ assertEquals(0, cache.stats().missCount());
+
+ Object one = new Object();
+ cache.getUnchecked(one);
+ assertEquals(0, cache.stats().hitCount());
+ assertEquals(1, cache.stats().missCount());
+
+ cache.getUnchecked(one);
+ assertEquals(1, cache.stats().hitCount());
+ assertEquals(1, cache.stats().missCount());
+
+ Object two = new Object();
+ cache.getUnchecked(two);
+ assertEquals(1, cache.stats().hitCount());
+ assertEquals(2, cache.stats().missCount());
+
+ Object three = new Object();
+ cache.getUnchecked(three);
+ assertEquals(1, cache.stats().hitCount());
+ assertEquals(3, cache.stats().missCount());
+ }
+
// asMap tests
public void testAsMap() {
diff --git a/guava-tests/test/com/google/common/cache/PackageSanityTests.java b/guava-tests/test/com/google/common/cache/PackageSanityTests.java
new file mode 100644
index 0000000..17f8ad0
--- /dev/null
+++ b/guava-tests/test/com/google/common/cache/PackageSanityTests.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.cache;
+
+import com.google.common.testing.AbstractPackageSanityTests;
+
+/**
+ * Basic sanity tests for the entire package.
+ *
+ * @author Ben Yu
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {
+ public PackageSanityTests() {
+ setDefault(CacheLoader.class, new CacheLoader<Object, Object>() {
+ @Override public Object load(Object key) {
+ return key;
+ }});
+ setDefault(LocalCache.class, new LocalCache<Object, Object>(CacheBuilder.newBuilder(), null));
+ setDefault(CacheBuilder.class, CacheBuilder.newBuilder());
+ }
+}
diff --git a/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java b/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java
index 28aa5f8..7d8e662 100644
--- a/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java
+++ b/guava-tests/test/com/google/common/cache/PopulatedCachesTest.java
@@ -17,11 +17,9 @@ package com.google.common.cache;
import static com.google.common.cache.CacheTesting.checkEmpty;
import static com.google.common.cache.CacheTesting.checkValidState;
import static com.google.common.cache.TestingCacheLoaders.identityLoader;
-import static java.util.Arrays.asList;
import static java.util.concurrent.TimeUnit.DAYS;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.base.Function;
import com.google.common.cache.CacheBuilderFactory.DurationSpec;
@@ -47,6 +45,7 @@ import java.util.Set;
*
* @author mike nonemacher
*/
+
public class PopulatedCachesTest extends TestCase {
// we use integers as keys; make sure the range covers some values that ARE cached by
// Integer.valueOf(int), and some that are not cached. (127 is the highest cached value.)
@@ -195,11 +194,10 @@ public class PopulatedCachesTest extends TestCase {
Set<Object> keys = cache.asMap().keySet();
List<Entry<Object, Object>> warmed = warmUp(cache);
- Object[] expectedArray = Maps.newHashMap(cache.asMap()).keySet().toArray(new Object[0]);
- ASSERT.that(keys).hasContentsAnyOrder(expectedArray);
- ASSERT.that(asList(keys.toArray())).hasContentsAnyOrder(expectedArray);
- ASSERT.that(asList(keys.toArray(new Object[(int) cache.size()])))
- .hasContentsAnyOrder(expectedArray);
+ Set<Object> expected = Maps.newHashMap(cache.asMap()).keySet();
+ ASSERT.that(keys).has().allFrom(expected);
+ ASSERT.that(keys.toArray()).has().allFrom(expected);
+ ASSERT.that(keys.toArray(new Object[0])).has().allFrom(expected);
new EqualsTester()
.addEqualityGroup(cache.asMap().keySet(), keys)
@@ -223,11 +221,10 @@ public class PopulatedCachesTest extends TestCase {
Collection<Object> values = cache.asMap().values();
List<Entry<Object, Object>> warmed = warmUp(cache);
- Object[] expectedArray = Maps.newHashMap(cache.asMap()).values().toArray(new Object[0]);
- ASSERT.that(values).hasContentsAnyOrder(expectedArray);
- ASSERT.that(asList(values.toArray())).hasContentsAnyOrder(expectedArray);
- ASSERT.that(asList(values.toArray(new Object[(int) cache.size()])))
- .hasContentsAnyOrder(expectedArray);
+ Collection<Object> expected = Maps.newHashMap(cache.asMap()).values();
+ ASSERT.that(values).has().allFrom(expected);
+ ASSERT.that(values.toArray()).has().allFrom(expected);
+ ASSERT.that(values.toArray(new Object[0])).has().allFrom(expected);
assertEquals(WARMUP_SIZE, values.size());
for (int i = WARMUP_MIN; i < WARMUP_MAX; i++) {
@@ -243,16 +240,16 @@ public class PopulatedCachesTest extends TestCase {
}
@SuppressWarnings("unchecked") // generic array creation
+
public void testEntrySet_populated() {
for (LoadingCache<Object, Object> cache : caches()) {
Set<Entry<Object, Object>> entries = cache.asMap().entrySet();
List<Entry<Object, Object>> warmed = warmUp(cache, WARMUP_MIN, WARMUP_MAX);
- Set<Entry<Object, Object>> entrySet = Maps.newHashMap(cache.asMap()).entrySet();
- ASSERT.that(entries).is(entrySet);
- ASSERT.that(entries.toArray()).hasContentsAnyOrder(entrySet.toArray());
- ASSERT.that(entries.toArray(new Entry[0]))
- .hasContentsAnyOrder(entrySet.toArray(new Entry[0]));
+ Set<?> expected = Maps.newHashMap(cache.asMap()).entrySet();
+ ASSERT.that(entries).has().allFrom((Collection<Entry<Object, Object>>)expected);
+ ASSERT.that(entries.toArray()).has().allFrom((Collection<Object>)expected);
+ ASSERT.that(entries.toArray(new Entry[0])).has().allFrom((Collection<Entry>)expected);
new EqualsTester()
.addEqualityGroup(cache.asMap().entrySet(), entries)
@@ -301,7 +298,7 @@ public class PopulatedCachesTest extends TestCase {
new Function<CacheBuilder<Object, Object>, LoadingCache<Object, Object>>() {
@Override public LoadingCache<Object, Object> apply(
CacheBuilder<Object, Object> builder) {
- return builder.build(identityLoader());
+ return builder.recordStats().build(identityLoader());
}
});
}
diff --git a/guava-tests/test/com/google/common/cache/RemovalNotificationTest.java b/guava-tests/test/com/google/common/cache/RemovalNotificationTest.java
new file mode 100644
index 0000000..0932829
--- /dev/null
+++ b/guava-tests/test/com/google/common/cache/RemovalNotificationTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.cache;
+
+import com.google.common.testing.EqualsTester;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests of {@link RemovalNotification}.
+ *
+ * @author Ben Yu
+ */
+public class RemovalNotificationTest extends TestCase {
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(
+ new RemovalNotification<String, Integer>("one", 1, RemovalCause.EXPLICIT),
+ new RemovalNotification<String, Integer>("one", 1, RemovalCause.REPLACED))
+ .addEqualityGroup(
+ new RemovalNotification<String, Integer>("1", 1, RemovalCause.EXPLICIT))
+ .addEqualityGroup(
+ new RemovalNotification<String, Integer>("one", 2, RemovalCause.EXPLICIT))
+ .testEquals();
+ }
+}
diff --git a/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java b/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java
index 960fed7..3b09ed5 100644
--- a/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java
+++ b/guava-tests/test/com/google/common/cache/TestingCacheLoaders.java
@@ -14,6 +14,8 @@
package com.google.common.cache;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.Maps;
@@ -23,6 +25,8 @@ import com.google.common.util.concurrent.ListenableFuture;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
+import javax.annotation.Nullable;
+
/**
* Utility {@link CacheLoader} implementations intended for use in testing.
*
@@ -36,6 +40,7 @@ class TestingCacheLoaders {
* {@link CacheLoader#load} calls to {@code loader}.
*/
static <K, V> CacheLoader<K, V> bulkLoader(final CacheLoader<K, V> loader) {
+ checkNotNull(loader);
return new CacheLoader<K, V>() {
@Override
public V load(K key) throws Exception {
@@ -56,7 +61,7 @@ class TestingCacheLoaders {
/**
* Returns a {@link CacheLoader} that returns the given {@code constant} for every request.
*/
- static <K, V> ConstantLoader<K, V> constantLoader(V constant) {
+ static <K, V> ConstantLoader<K, V> constantLoader(@Nullable V constant) {
return new ConstantLoader<K, V>(constant);
}
@@ -71,6 +76,7 @@ class TestingCacheLoaders {
* Returns a {@link CacheLoader} that throws the given error for every request.
*/
static <K, V> CacheLoader<K, V> errorLoader(final Error e) {
+ checkNotNull(e);
return new CacheLoader<K, V>() {
@Override
public V load(K key) {
@@ -83,6 +89,7 @@ class TestingCacheLoaders {
* Returns a {@link CacheLoader} that throws the given exception for every request.
*/
static <K, V> CacheLoader<K, V> exceptionLoader(final Exception e) {
+ checkNotNull(e);
return new CacheLoader<K, V>() {
@Override
public V load(K key) throws Exception {
diff --git a/guava-tests/test/com/google/common/cache/TestingRemovalListeners.java b/guava-tests/test/com/google/common/cache/TestingRemovalListeners.java
index 67c71da..5c7912a 100644
--- a/guava-tests/test/com/google/common/cache/TestingRemovalListeners.java
+++ b/guava-tests/test/com/google/common/cache/TestingRemovalListeners.java
@@ -14,6 +14,9 @@
package com.google.common.cache;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
@@ -22,6 +25,7 @@ import java.util.concurrent.atomic.AtomicInteger;
*
* @author mike nonemacher
*/
+@GwtCompatible(emulated = true)
class TestingRemovalListeners {
/**
@@ -34,6 +38,7 @@ class TestingRemovalListeners {
/**
* Type-inferring factory method for creating a {@link QueuingRemovalListener}.
*/
+ @GwtIncompatible("ConcurrentLinkedQueue")
static <K, V> QueuingRemovalListener<K, V> queuingRemovalListener() {
return new QueuingRemovalListener<K,V>();
}
@@ -48,6 +53,7 @@ class TestingRemovalListeners {
/**
* {@link RemovalListener} that adds all {@link RemovalNotification} objects to a queue.
*/
+ @GwtIncompatible("ConcurrentLinkedQueue")
static class QueuingRemovalListener<K, V>
extends ConcurrentLinkedQueue<RemovalNotification<K, V>> implements RemovalListener<K, V> {
diff --git a/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java b/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java
index 20f171d..5616ecc 100644
--- a/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractBiMapTest.java
@@ -1,551 +1,65 @@
/*
- * Copyright (C) 2007 The Guava Authors
+ * Copyright (C) 2012 The Guava Authors
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
*/
package com.google.common.collect;
-import static java.util.Arrays.asList;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.testing.SerializableTester;
-
import junit.framework.TestCase;
-import java.io.Serializable;
-import java.util.Collections;
+import java.util.IdentityHashMap;
import java.util.Iterator;
-import java.util.Map;
import java.util.Map.Entry;
-import java.util.Set;
/**
- * Common tests for any {@code BiMap}.
+ * Tests for {@code AbstractBiMap}.
*
- * @author Kevin Bourrillion
+ * @author Mike Bostock
*/
-@GwtCompatible(emulated = true)
-public abstract class AbstractBiMapTest extends TestCase {
-
- protected abstract BiMap<Integer, String> create();
-
- protected BiMap<Integer, String> bimap;
- protected Set<Entry<Integer, String>> entrySet;
-
- // public for GWT
- @Override public void setUp() throws Exception {
- super.setUp();
- bimap = create();
- entrySet = bimap.entrySet();
- }
-
- public void testClear() {
- bimap.clear();
- assertTrue(bimap.isEmpty());
- putOneTwoThree();
- bimap.clear();
- assertTrue(bimap.isEmpty());
- }
-
- public void testContainsKey() {
- assertFalse(bimap.containsKey(null));
- assertFalse(bimap.containsKey(1));
- assertFalse(bimap.containsKey("one"));
-
- bimap.put(1, "one");
- assertTrue(bimap.containsKey(1));
-
- bimap.put(null, null);
- assertTrue(bimap.containsKey(null));
- }
-
- public void testContainsValue() {
- assertFalse(bimap.containsValue(null));
- assertFalse(bimap.containsValue(1));
- assertFalse(bimap.containsValue("one"));
-
- bimap.put(1, "one");
- assertTrue(bimap.containsValue("one"));
-
- bimap.put(null, null);
- assertTrue(bimap.containsValue(null));
- }
-
- public void testEquals() {
- BiMap<Integer, String> biMap = create();
- assertEquals(biMap, biMap);
- assertEquals(create(), biMap);
- biMap.put(1, null);
- assertFalse(create().equals(biMap));
- }
-
- public void testGet() {
- assertNull(bimap.get(1));
- assertNull(bimap.get(null));
- assertNull(bimap.get("bad"));
-
- bimap.put(1, "one");
- bimap.put(0, null);
- bimap.put(null, "nothing");
- assertEquals("one", bimap.get(1));
- assertNull(bimap.get(0));
- assertEquals("nothing", bimap.get(null));
- assertNull(bimap.get("bad"));
-
- bimap.forcePut(null, null);
- assertNull(bimap.get(null));
- bimap.remove(null);
- assertNull(bimap.get(null));
- }
-
- public void testInverseSimple() {
- BiMap<String, Integer> inverse = bimap.inverse();
- bimap.put(1, "one");
- bimap.put(2, "two");
- assertEquals(ImmutableMap.of("one", 1, "two", 2), inverse);
- // see InverseBiMapTest
-
- assertSame(bimap, inverse.inverse());
- }
-
- public void testInversePut() {
- BiMap<String, Integer> inverse = bimap.inverse();
- bimap.put(1, "one");
- bimap.inverse().put("two", 2);
- assertEquals(ImmutableMap.of("one", 1, "two", 2), inverse);
- assertEquals(ImmutableMap.of(1, "one", 2, "two"), bimap);
- }
-
- public void testIsEmpty() {
- assertTrue(bimap.isEmpty());
- bimap.put(1, "one");
- assertFalse(bimap.isEmpty());
- bimap.remove(1);
- assertTrue(bimap.isEmpty());
- }
-
- public void testPut() {
- bimap.put(1, "one");
- assertEquals(ImmutableMap.of(1, "one"), bimap);
-
- bimap.put(2, "two");
- assertEquals(ImmutableMap.of(1, "one", 2, "two"), bimap);
-
- bimap.put(2, "two");
- assertEquals(ImmutableMap.of(1, "one", 2, "two"), bimap);
-
- bimap.put(1, "ONE");
- assertEquals(ImmutableMap.of(1, "ONE", 2, "two"), bimap);
-
- try {
- bimap.put(3, "two");
- fail();
- } catch (IllegalArgumentException e) {
- }
- assertEquals(ImmutableMap.of(1, "ONE", 2, "two"), bimap);
-
- bimap.put(-1, null);
- bimap.put(null, "null");
- Map<Integer, String> expected = Maps.newHashMap();
- expected.put(1, "ONE");
- expected.put(2, "two");
- expected.put(-1, null);
- expected.put(null, "null");
-
- assertEquals(expected, bimap);
-
- bimap.remove(-1);
- bimap.put(null, null);
+public class AbstractBiMapTest extends TestCase {
- expected.remove(-1);
- expected.put(null, null);
-
- assertEquals(expected, bimap);
- }
-
- public void testPutNull() {
- bimap.put(-1, null);
- assertTrue(bimap.containsValue(null));
- bimap.put(1, "one");
- assertTrue(bimap.containsValue(null));
- }
-
- public void testPutAll() {
- bimap.put(1, "one");
- Map<Integer, String> newEntries = ImmutableMap.of(2, "two", 3, "three");
- bimap.putAll(newEntries);
- assertEquals(ImmutableMap.of(1, "one", 2, "two", 3, "three"), bimap);
- }
-
- public void testForcePut() {
- assertNull(bimap.forcePut(1, "one"));
- assertEquals(ImmutableMap.of(1, "one"), bimap);
- assertEquals("one", bimap.forcePut(1, "one"));
- assertEquals(ImmutableMap.of(1, "one"), bimap);
- assertEquals("one", bimap.forcePut(1, "ONE"));
- assertEquals(ImmutableMap.of(1, "ONE"), bimap);
- assertNull(bimap.forcePut(-1, "ONE")); // key 1 disappears without a trace
- assertEquals(ImmutableMap.of(-1, "ONE"), bimap);
- assertNull(bimap.forcePut(2, "two"));
- assertEquals(ImmutableMap.of(-1, "ONE", 2, "two"), bimap);
- assertEquals("two", bimap.forcePut(2, "ONE"));
- assertEquals(ImmutableMap.of(2, "ONE"), bimap);
- }
-
- public void testRemove() {
- Map<Integer, String> map = Maps.newHashMap();
- map.put(0, null);
- map.put(1, "one");
- map.put(null, "null");
-
- bimap.putAll(map);
- assertNull(bimap.remove(0));
-
- map.remove(0);
- assertEquals(map, bimap);
-
- assertEquals("null", bimap.remove(null));
- assertEquals(Collections.singletonMap(1, "one"), bimap);
-
- assertNull(bimap.remove(15));
-
- assertEquals("one", bimap.remove(1));
- assertTrue(bimap.isEmpty());
- }
-
- public void testSize() {
- assertEquals(0, bimap.size());
- bimap.put(1, "one");
- assertEquals(1, bimap.size());
- bimap.put(1, "ONE");
- assertEquals(1, bimap.size());
- bimap.put(2, "two");
- assertEquals(2, bimap.size());
- bimap.forcePut(1, "two");
- assertEquals(1, bimap.size());
- }
-
- public void testToString() {
+ // The next two tests verify that map entries are not accessed after they're
+ // removed, since IdentityHashMap throws an exception when that occurs.
+ public void testIdentityKeySetIteratorRemove() {
+ BiMap<Integer, String> bimap = new AbstractBiMap<Integer, String>(
+ new IdentityHashMap<Integer, String>(),
+ new IdentityHashMap<String, Integer>()) {};
bimap.put(1, "one");
bimap.put(2, "two");
-
- String string = bimap.toString();
- String expected = string.startsWith("{1")
- ? "{1=one, 2=two}"
- : "{2=two, 1=one}";
- assertEquals(expected, bimap.toString());
- }
-
- // Entry Set
-
- public void testEntrySetAdd() {
- try {
- entrySet.add(Maps.immutableEntry(1, "one"));
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- public void testEntrySetAddAll() {
- try {
- entrySet.addAll(Collections.singleton(Maps.immutableEntry(1, "one")));
- fail();
- } catch (UnsupportedOperationException expected) {
- }
- }
-
- public void testEntrySetClear() {
- entrySet.clear();
- assertTrue(entrySet.isEmpty());
- assertTrue(bimap.isEmpty());
- putOneTwoThree();
- entrySet.clear();
- assertTrue(entrySet.isEmpty());
- assertTrue(bimap.isEmpty());
- }
-
- public void testEntrySetContains() {
- assertFalse(entrySet.contains(Maps.immutableEntry(1, "one")));
- bimap.put(1, "one");
- assertTrue(entrySet.contains(Maps.immutableEntry(1, "one")));
- assertFalse(entrySet.contains(Maps.immutableEntry(1, "")));
- assertFalse(entrySet.contains(Maps.immutableEntry(0, "one")));
- assertFalse(entrySet.contains(Maps.immutableEntry(1, null)));
- assertFalse(entrySet.contains(Maps.immutableEntry(null, "one")));
- assertFalse(entrySet.contains(Maps.immutableEntry(null, null)));
-
- bimap.put(null, null);
- assertTrue(entrySet.contains(Maps.immutableEntry(1, "one")));
- assertTrue(entrySet.contains(Maps.immutableEntry(null, null)));
- assertFalse(entrySet.contains(Maps.immutableEntry(1, "")));
- assertFalse(entrySet.contains(Maps.immutableEntry(0, "one")));
- assertFalse(entrySet.contains(Maps.immutableEntry(1, null)));
- assertFalse(entrySet.contains(Maps.immutableEntry(null, "one")));
-
- bimap.put(null, "null");
- bimap.put(0, null);
- assertTrue(entrySet.contains(Maps.immutableEntry(1, "one")));
- assertTrue(entrySet.contains(Maps.immutableEntry(null, "null")));
- assertTrue(entrySet.contains(Maps.immutableEntry(0, null)));
- assertFalse(entrySet.contains(Maps.immutableEntry(1, "")));
- assertFalse(entrySet.contains(Maps.immutableEntry(0, "one")));
- assertFalse(entrySet.contains(Maps.immutableEntry(1, null)));
- assertFalse(entrySet.contains(Maps.immutableEntry(null, "one")));
- assertFalse(entrySet.contains(Maps.immutableEntry(null, null)));
- }
-
- public void testEntrySetIsEmpty() {
- assertTrue(entrySet.isEmpty());
- bimap.put(1, "one");
- assertFalse(entrySet.isEmpty());
- bimap.remove(1);
- assertTrue(entrySet.isEmpty());
- }
-
- public void testEntrySetRemove() {
- putOneTwoThree();
- assertTrue(bimap.containsKey(1));
- assertTrue(bimap.containsValue("one"));
- assertTrue(entrySet.remove(Maps.immutableEntry(1, "one")));
- assertFalse(bimap.containsKey(1));
- assertFalse(bimap.containsValue("one"));
- assertEquals(2, bimap.size());
- assertEquals(2, bimap.inverse().size());
- assertFalse(entrySet.remove(Maps.immutableEntry(2, "three")));
- assertFalse(entrySet.remove(3));
- assertEquals(2, bimap.size());
- assertEquals(2, bimap.inverse().size());
- }
-
- public void testEntrySetRemoveAll() {
- putOneTwoThree();
- assertTrue(bimap.containsKey(1));
- assertTrue(bimap.containsValue("one"));
- assertTrue(entrySet.removeAll(
- Collections.singleton(Maps.immutableEntry(1, "one"))));
- assertFalse(bimap.containsKey(1));
- assertFalse(bimap.containsValue("one"));
- assertEquals(2, bimap.size());
- assertEquals(2, bimap.inverse().size());
- }
-
- public void testEntrySetValue() {
- bimap.put(1, "one");
- Entry<Integer, String> entry = bimap.entrySet().iterator().next();
- bimap.put(2, "two");
- assertEquals("one", entry.getValue());
- bimap.put(1, "one");
- assertEquals("one", entry.getValue());
- assertEquals("one", bimap.get(1));
- assertEquals(Integer.valueOf(1), bimap.inverse().get("one"));
- bimap.put(1, "uno");
- assertEquals("uno", entry.getValue());
- assertEquals("uno", bimap.get(1));
- assertEquals(Integer.valueOf(1), bimap.inverse().get("uno"));
- assertEquals(2, bimap.size());
- assertEquals(2, bimap.inverse().size());
- try {
- entry.setValue("two");
- fail();
- } catch (IllegalArgumentException expected) {}
- assertEquals("uno", entry.getValue());
- assertEquals("uno", bimap.get(1));
- assertEquals(Integer.valueOf(1), bimap.inverse().get("uno"));
- assertEquals(2, bimap.size());
- assertEquals(2, bimap.inverse().size());
- }
-
- public void testEntrySetValueRemovedEntry() {
- bimap.put(1, "a");
- Entry<Integer, String> entry = bimap.entrySet().iterator().next();
- bimap.clear();
- try {
- entry.setValue("b");
- fail();
- } catch (IllegalStateException expected) {}
- assertEquals(0, bimap.size());
- assertEquals(0, bimap.inverse().size());
- }
-
- public void testEntrySetValueRemovedEntryNullOldValue() {
- bimap.put(1, null);
- Entry<Integer, String> entry = bimap.entrySet().iterator().next();
- bimap.clear();
- try {
- entry.setValue("b");
- fail();
- } catch (IllegalStateException expected) {}
- assertEquals(0, bimap.size());
- assertEquals(0, bimap.inverse().size());
- }
-
- public void testEntrySetValueRemovedEntryAddedEqualEntry() {
- bimap.put(1, "a");
- Entry<Integer, String> entry = bimap.entrySet().iterator().next();
- bimap.clear();
- bimap.put(1, "a");
- try {
- entry.setValue("b");
- fail();
- } catch (IllegalStateException expected) {}
- assertEquals(1, bimap.size());
- assertEquals("a", bimap.get(1));
- assertEquals(1, bimap.inverse().size());
- assertEquals((Integer) 1, bimap.inverse().get("a"));
- }
-
- public void testKeySetIteratorRemove() {
- putOneTwoThree();
+ bimap.put(3, "three");
Iterator<Integer> iterator = bimap.keySet().iterator();
iterator.next();
- iterator.remove();
- assertEquals(2, bimap.size());
- assertEquals(2, bimap.inverse().size());
- }
-
- public void testKeySetRemoveAll() {
- putOneTwoThree();
- Set<Integer> keySet = bimap.keySet();
- assertTrue(keySet.removeAll(asList(1, 3)));
- assertEquals(1, bimap.size());
- assertTrue(keySet.contains(2));
- }
-
- public void testKeySetRetainAll() {
- putOneTwoThree();
- Set<Integer> keySet = bimap.keySet();
- assertTrue(keySet.retainAll(Collections.singleton(2)));
- assertEquals(1, bimap.size());
- assertTrue(keySet.contains(2));
- }
-
- public void testEntriesIteratorRemove() {
- putOneTwoThree();
- Iterator<Entry<Integer, String>> iterator = bimap.entrySet().iterator();
iterator.next();
iterator.remove();
- assertEquals(2, bimap.size());
- assertEquals(2, bimap.inverse().size());
- }
-
- public void testEntriesRetainAll() {
- putOneTwoThree();
- Set<Map.Entry<Integer, String>> entries = bimap.entrySet();
- Map.Entry<Integer, String> entry = Maps.immutableEntry(2, "two");
- assertTrue(entries.retainAll(Collections.singleton(entry)));
- assertEquals(1, bimap.size());
- assertTrue(bimap.containsKey(2));
- }
-
- public void testValuesIteratorRemove() {
- putOneTwoThree();
- Iterator<String> iterator = bimap.values().iterator();
iterator.next();
iterator.remove();
- assertEquals(2, bimap.size());
- assertEquals(2, bimap.inverse().size());
- }
-
- public void testValuesToArray() {
- bimap.put(1, "one");
- String[] array = new String[3];
- array[1] = "garbage";
- assertSame(array, bimap.values().toArray(array));
- assertEquals("one", array[0]);
- assertNull(array[1]);
- }
-
- public void testValuesToString() {
- bimap.put(1, "one");
- assertEquals("[one]", bimap.values().toString());
- }
-
- @GwtIncompatible("SerializableTester")
- public void testSerialization() {
- bimap.put(1, "one");
- bimap.put(2, "two");
- bimap.put(3, "three");
- bimap.put(null, null);
-
- BiMap<Integer, String> copy =
- SerializableTester.reserializeAndAssert(bimap);
- assertEquals(bimap.inverse(), copy.inverse());
- }
-
- void putOneTwoThree() {
- bimap.put(1, "one");
- bimap.put(2, "two");
- bimap.put(3, "three");
- }
-
- @GwtIncompatible("used only by @GwtIncompatible code")
- private static class BiMapPair implements Serializable {
- final BiMap<Integer, String> forward;
- final BiMap<String, Integer> backward;
-
- BiMapPair(BiMap<Integer, String> original) {
- this.forward = original;
- this.backward = original.inverse();
- }
-
- private static final long serialVersionUID = 0;
- }
-
- @GwtIncompatible("SerializableTester")
- public void testSerializationWithInverseEqual() {
- bimap.put(1, "one");
- bimap.put(2, "two");
- bimap.put(3, "three");
- bimap.put(null, null);
-
- BiMapPair pair = new BiMapPair(bimap);
- BiMapPair copy = SerializableTester.reserialize(pair);
- assertEquals(pair.forward, copy.forward);
- assertEquals(pair.backward, copy.backward);
-
- copy.forward.put(4, "four");
- copy.backward.put("five", 5);
- assertEquals(copy.backward, copy.forward.inverse());
- assertEquals(copy.forward, copy.backward.inverse());
-
- assertTrue(copy.forward.containsKey(4));
- assertTrue(copy.forward.containsKey(5));
- assertTrue(copy.backward.containsValue(4));
- assertTrue(copy.backward.containsValue(5));
- assertTrue(copy.forward.containsValue("four"));
- assertTrue(copy.forward.containsValue("five"));
- assertTrue(copy.backward.containsKey("four"));
- assertTrue(copy.backward.containsKey("five"));
+ assertEquals(1, bimap.size());
+ assertEquals(1, bimap.inverse().size());
}
- /**
- * The sameness checks ensure that a bimap and its inverse remain consistent,
- * even after the deserialized instances are updated. Also, the relationship
- * {@code a == b.inverse()} should continue to hold after both bimaps are
- * serialized and deserialized together.
- */
- @GwtIncompatible("SerializableTester")
- public void testSerializationWithInverseSame() {
+ public void testIdentityEntrySetIteratorRemove() {
+ BiMap<Integer, String> bimap = new AbstractBiMap<Integer, String>(
+ new IdentityHashMap<Integer, String>(),
+ new IdentityHashMap<String, Integer>()) {};
bimap.put(1, "one");
bimap.put(2, "two");
bimap.put(3, "three");
- bimap.put(null, null);
-
- BiMapPair pair = new BiMapPair(bimap);
- BiMapPair copy = SerializableTester.reserialize(pair);
- assertSame(copy.backward, copy.forward.inverse());
- assertSame(copy.forward, copy.backward.inverse());
+ Iterator<Entry<Integer, String>> iterator = bimap.entrySet().iterator();
+ iterator.next();
+ iterator.next();
+ iterator.remove();
+ iterator.next();
+ iterator.remove();
+ assertEquals(1, bimap.size());
+ assertEquals(1, bimap.inverse().size());
}
}
diff --git a/guava-tests/test/com/google/common/collect/AbstractBstBalancePolicyTest.java b/guava-tests/test/com/google/common/collect/AbstractBstBalancePolicyTest.java
deleted file mode 100644
index 0f53f54..0000000
--- a/guava-tests/test/com/google/common/collect/AbstractBstBalancePolicyTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BstTesting.assertInOrderTraversalIs;
-import static com.google.common.collect.BstTesting.nodeFactory;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.BstTesting.SimpleNode;
-
-import junit.framework.TestCase;
-
-import javax.annotation.Nullable;
-
-/**
- * Tests for an arbitrary {@code BSTRebalancePolicy}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public abstract class AbstractBstBalancePolicyTest extends TestCase {
- protected abstract BstBalancePolicy<SimpleNode> getBalancePolicy();
-
- public void testBalanceLeaf() {
- SimpleNode a = new SimpleNode('a', null, null);
- assertInOrderTraversalIs(getBalancePolicy().balance(nodeFactory, a, null, null), "a");
- }
-
- private SimpleNode balanceNew(char c, @Nullable SimpleNode left, @Nullable SimpleNode right) {
- return getBalancePolicy().balance(nodeFactory, new SimpleNode(c, null, null), left, right);
- }
-
- public void testBalanceTree1() {
- // b
- // \
- // c
- SimpleNode c = balanceNew('c', null, null);
- SimpleNode b = balanceNew('b', null, c);
- assertInOrderTraversalIs(b, "bc");
- }
-
- public void testBalanceTree2() {
- // b
- // /
- // a
- SimpleNode a = balanceNew('a', null, null);
- SimpleNode b = balanceNew('b', a, null);
- assertInOrderTraversalIs(b, "ab");
- }
-
- public void testBalanceTree3() {
- // b
- // / \
- // a c
- SimpleNode a = balanceNew('a', null, null);
- SimpleNode c = balanceNew('c', null, null);
- SimpleNode b = balanceNew('b', a, c);
- assertInOrderTraversalIs(b, "abc");
- }
-
- public void testBalanceTree4() {
- // a
- // \
- // b
- // \
- // c
- // \
- // d
- // \
- // e
- // \
- // f
-
- SimpleNode f = balanceNew('f', null, null);
- SimpleNode e = balanceNew('e', null, f);
- SimpleNode d = balanceNew('d', null, e);
- SimpleNode c = balanceNew('c', null, d);
- SimpleNode b = balanceNew('b', null, c);
- SimpleNode a = balanceNew('a', null, b);
- assertInOrderTraversalIs(a, "abcdef");
- }
-
- public void testBalanceTree5() {
- // f
- // /
- // e
- // /
- // d
- // /
- // c
- // /
- // b
- // /
- // a
- SimpleNode a = balanceNew('a', null, null);
- SimpleNode b = balanceNew('b', a, null);
- SimpleNode c = balanceNew('c', b, null);
- SimpleNode d = balanceNew('d', c, null);
- SimpleNode e = balanceNew('e', d, null);
- SimpleNode f = balanceNew('f', e, null);
- assertInOrderTraversalIs(f, "abcdef");
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java b/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java
index 13c3df2..f3bc17c 100644
--- a/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractCollectionTest.java
@@ -17,7 +17,7 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -203,7 +203,7 @@ public abstract class AbstractCollectionTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicInstanceMethods(c);
}
@@ -221,6 +221,6 @@ public abstract class AbstractCollectionTest extends TestCase {
}
protected void assertContents(String... expected) {
- ASSERT.that(c).hasContentsAnyOrder(expected);
+ ASSERT.that(c).has().allFrom(asList(expected));
}
}
diff --git a/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java b/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java
index ca475da..cef2c0e 100644
--- a/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractImmutableSetTest.java
@@ -18,7 +18,7 @@ package com.google.common.collect;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -295,8 +295,17 @@ public abstract class AbstractImmutableSetTest extends TestCase {
.add("d", "e", "f")
.add("g", "h", "i", "j")
.build();
- ASSERT.that(set).hasContentsInOrder(
- "a", "b", "c", "d", "e", "f", "g", "h", "i", "j");
+ ASSERT.that(set).has().allOf(
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j").inOrder();
+ }
+
+ public void testReuseBuilderWithNonDuplicateElements() {
+ ImmutableSet.Builder<String> builder = this.<String>builder()
+ .add("a")
+ .add("b");
+ ASSERT.that(builder.build()).has().allOf("a", "b").inOrder();
+ builder.add("c", "d");
+ ASSERT.that(builder.build()).has().allOf("a", "b", "c", "d").inOrder();
}
public void testBuilderWithDuplicateElements() {
@@ -311,6 +320,16 @@ public abstract class AbstractImmutableSetTest extends TestCase {
assertEquals(1, set.size());
}
+ public void testReuseBuilderWithDuplicateElements() {
+ ImmutableSet.Builder<String> builder = this.<String>builder()
+ .add("a")
+ .add("a", "a")
+ .add("b");
+ ASSERT.that(builder.build()).has().allOf("a", "b").inOrder();
+ builder.add("a", "b", "c", "c");
+ ASSERT.that(builder.build()).has().allOf("a", "b", "c").inOrder();
+ }
+
public void testBuilderAddAll() {
List<String> a = asList("a", "b", "c");
List<String> b = asList("c", "d", "e");
@@ -318,7 +337,7 @@ public abstract class AbstractImmutableSetTest extends TestCase {
.addAll(a)
.addAll(b)
.build();
- ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e");
+ ASSERT.that(set).has().allOf("a", "b", "c", "d", "e").inOrder();
}
static final int LAST_COLOR_ADDED = 0x00BFFF;
diff --git a/guava-tests/test/com/google/common/collect/AbstractImmutableTableTest.java b/guava-tests/test/com/google/common/collect/AbstractImmutableTableTest.java
index a456c6a..b65e88d 100644
--- a/guava-tests/test/com/google/common/collect/AbstractImmutableTableTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractImmutableTableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,21 +16,24 @@
package com.google.common.collect;
+import com.google.common.annotations.GwtCompatible;
+
import junit.framework.TestCase;
/**
* Tests {@link ImmutableTable}
*
- * @author gak@google.com (Gregory Kick)
+ * @author Gregory Kick
*/
+@GwtCompatible
public abstract class AbstractImmutableTableTest extends TestCase {
abstract Iterable<ImmutableTable<Character, Integer, String>>
getTestInstances();
+ @SuppressWarnings("deprecation")
public final void testClear() {
- for(ImmutableTable<Character, Integer, String> testInstance :
- getTestInstances()) {
+ for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
try {
testInstance.clear();
fail();
@@ -40,9 +43,9 @@ public abstract class AbstractImmutableTableTest extends TestCase {
}
}
+ @SuppressWarnings("deprecation")
public final void testPut() {
- for(ImmutableTable<Character, Integer, String> testInstance :
- getTestInstances()) {
+ for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
try {
testInstance.put('a', 1, "blah");
fail();
@@ -52,9 +55,9 @@ public abstract class AbstractImmutableTableTest extends TestCase {
}
}
+ @SuppressWarnings("deprecation")
public final void testPutAll() {
- for(ImmutableTable<Character, Integer, String> testInstance :
- getTestInstances()) {
+ for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
try {
testInstance.putAll(ImmutableTable.of('a', 1, "blah"));
fail();
@@ -64,9 +67,9 @@ public abstract class AbstractImmutableTableTest extends TestCase {
}
}
+ @SuppressWarnings("deprecation")
public final void testRemove() {
- for(ImmutableTable<Character, Integer, String> testInstance :
- getTestInstances()) {
+ for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
try {
testInstance.remove('a', 1);
fail();
@@ -77,15 +80,13 @@ public abstract class AbstractImmutableTableTest extends TestCase {
}
public final void testConsistentToString() {
- for(ImmutableTable<Character, Integer, String> testInstance :
- getTestInstances()) {
+ for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
assertEquals(testInstance.rowMap().toString(), testInstance.toString());
}
}
public final void testConsistentHashCode() {
- for(ImmutableTable<Character, Integer, String> testInstance :
- getTestInstances()) {
+ for (ImmutableTable<Character, Integer, String> testInstance : getTestInstances()) {
assertEquals(testInstance.cellSet().hashCode(), testInstance.hashCode());
}
}
diff --git a/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java b/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java
index 1741af6..b830c0a 100644
--- a/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractListMultimapTest.java
@@ -18,7 +18,7 @@ package com.google.common.collect;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -182,11 +182,11 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
list.add(1, 2);
assertEquals(4, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 5).inOrder();
list.addAll(3, asList(4, 8));
assertEquals(6, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 8, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 8, 5).inOrder();
assertEquals(8, list.get(4).intValue());
assertEquals(4, list.indexOf(8));
@@ -194,11 +194,11 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
list.remove(4);
assertEquals(5, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
list.set(4, 10);
assertEquals(5, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 10);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 10).inOrder();
}
public void testListMethodsIncludingSublist() {
@@ -211,9 +211,9 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
List<Integer> list = multimap.get("foo");
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
+ ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
list.set(3, 6);
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 6, 10);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 6, 10).inOrder();
}
/**
@@ -229,10 +229,10 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
List<Integer> list = multimap.get("foo");
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
+ ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
list.set(3, 6);
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 6, 5);
- ASSERT.that(sublist).hasContentsInOrder(2, 3, 6);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 6, 5).inOrder();
+ ASSERT.that(sublist).has().allOf(2, 3, 6).inOrder();
}
/**
@@ -272,11 +272,11 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
assertEquals(1, iterator.next().intValue());
iterator.set(2);
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(2, 3, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(2, 3, 5).inOrder();
assertEquals(3, iterator.next().intValue());
iterator.remove();
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(2, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(2, 5).inOrder();
}
/**
@@ -296,12 +296,12 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
+ ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
sublist.set(1, 6);
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 6, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 6, 4, 5).inOrder();
}
/**
@@ -311,21 +311,21 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
+ ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
sublist.remove(1);
assertEquals(4, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 4, 5).inOrder();
sublist.removeAll(Collections.singleton(4));
assertEquals(3, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 5).inOrder();
sublist.remove(0);
assertEquals(2, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 5).inOrder();
}
/**
@@ -335,17 +335,17 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
+ ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
sublist.add(6);
assertEquals(6, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 6, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 6, 5).inOrder();
sublist.add(0, 7);
assertEquals(7, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 7, 2, 3, 4, 6, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 7, 2, 3, 4, 6, 5).inOrder();
}
/**
@@ -355,13 +355,13 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
List<Integer> sublist = list.subList(1, 4);
- ASSERT.that(sublist).hasContentsInOrder(2, 3, 4);
+ ASSERT.that(sublist).has().allOf(2, 3, 4).inOrder();
sublist.clear();
assertEquals(2, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 5).inOrder();
}
/**
@@ -371,9 +371,9 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
List<Integer> sublist = list.subList(0, 5);
- ASSERT.that(sublist).hasContentsInOrder(1, 2, 3, 4, 5);
+ ASSERT.that(sublist).has().allOf(1, 2, 3, 4, 5).inOrder();
sublist.retainAll(Collections.EMPTY_LIST);
assertTrue(multimap.isEmpty());
@@ -394,12 +394,12 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
assertEquals(2, iterator.next().intValue());
iterator.set(6);
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 6, 3, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 6, 3, 4, 5).inOrder();
assertTrue(iterator.hasNext());
assertEquals(3, iterator.next().intValue());
iterator.remove();
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 6, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 6, 4, 5).inOrder();
assertEquals(4, multimap.size());
}
@@ -485,7 +485,7 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
multimap.put("bar", 11);
multimap.put("bar", 12);
multimap.get("bar").add(0, 13);
- ASSERT.that(multimap.get("bar")).hasContentsInOrder(13, 11, 12);
+ ASSERT.that(multimap.get("bar")).has().allOf(13, 11, 12).inOrder();
}
/**
@@ -501,7 +501,7 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
multimap.putAll("foo", asList(1, 2, 2, 3, 3, 3));
multimap.get("foo").retainAll(asList(1, 2, 4));
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 2);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 2).inOrder();
}
/**
@@ -517,6 +517,6 @@ public abstract class AbstractListMultimapTest extends AbstractMultimapTest {
multimap.putAll("foo", asList(1, 2, 2, 3, 3, 3));
multimap.get("foo").removeAll(asList(2, 3, 3, 4));
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1);
+ ASSERT.that(multimap.get("foo")).has().item(1);
}
}
diff --git a/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java b/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java
index da55ee0..d5f1da1 100644
--- a/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractMultimapTest.java
@@ -17,7 +17,7 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -508,6 +508,15 @@ public abstract class AbstractMultimapTest extends TestCase {
assertFalse(values.contains(5));
}
+ public void testValuesToArray() {
+ multimap.put("foo", 1);
+ multimap.put("foo", nullValue());
+ multimap.put(nullKey(), 3);
+ Collection<Integer> values = multimap.values();
+ ASSERT.that(values.toArray()).has().allOf(1, 3, nullValue());
+ ASSERT.that(values.toArray(new Integer[3])).has().allOf(1, 3, nullValue());
+ }
+
public void testValuesClear() {
multimap.put("foo", 1);
multimap.put("foo", nullValue());
@@ -540,7 +549,7 @@ public abstract class AbstractMultimapTest extends TestCase {
multimap.put("foo", nullValue());
multimap.put(nullKey(), 3);
Collection<Entry<String, Integer>> entries = multimap.entries();
- ASSERT.that(entries).hasContentsAnyOrder(
+ ASSERT.that(entries).has().allOf(
Maps.immutableEntry("foo", 1),
Maps.immutableEntry("foo", nullValue()),
Maps.immutableEntry(nullKey(), 3));
@@ -562,14 +571,14 @@ public abstract class AbstractMultimapTest extends TestCase {
Map<String, Collection<Integer>> map = multimap.asMap();
assertEquals(2, map.size());
- ASSERT.that(map.get("foo")).hasContentsAnyOrder(1, nullValue());
- ASSERT.that(map.get(nullKey())).hasContentsAnyOrder(3);
+ ASSERT.that(map.get("foo")).has().allOf(1, nullValue());
+ ASSERT.that(map.get(nullKey())).has().item(3);
assertNull(map.get("bar"));
assertTrue(map.containsKey("foo"));
assertTrue(map.containsKey(nullKey()));
assertFalse(multimap.containsKey("bar"));
- ASSERT.that(map.remove("foo")).hasContentsAnyOrder(1, nullValue());
+ ASSERT.that(map.remove("foo")).has().allOf(1, nullValue());
assertFalse(multimap.containsKey("foo"));
assertEquals(1, multimap.size());
assertNull(map.remove("bar"));
@@ -629,6 +638,44 @@ public abstract class AbstractMultimapTest extends TestCase {
assertFalse(iterator.hasNext());
}
+ public void testAsMapEntriesToArray() {
+ multimap.put("foo", 1);
+ multimap.put("foo", nullValue());
+ multimap.put(nullKey(), 3);
+ Collection<Entry<String, Collection<Integer>>> entries =
+ multimap.asMap().entrySet();
+
+ ASSERT.that(entries.toArray()).has().allOf(
+ Maps.immutableEntry("foo", multimap.get("foo")),
+ Maps.immutableEntry(nullKey(), multimap.get(nullKey())));
+ ASSERT.that(entries.toArray(new Entry[2])).has().allOf(
+ Maps.immutableEntry("foo", multimap.get("foo")),
+ Maps.immutableEntry(nullKey(), multimap.get(nullKey())));
+ }
+
+ public void testAsMapValuesToArray() {
+ multimap.put("foo", 1);
+ multimap.put("foo", nullValue());
+ multimap.put(nullKey(), 3);
+ Collection<Collection<Integer>> values =
+ multimap.asMap().values();
+
+ ASSERT.that(values.toArray()).has().allOf(
+ multimap.get("foo"), multimap.get(nullKey()));
+ ASSERT.that(values.toArray(new Collection[2])).has().allOf(
+ multimap.get("foo"), multimap.get(nullKey()));
+ }
+
+ public void testAsMapKeySetToArray() {
+ multimap.put("foo", 1);
+ multimap.put("foo", nullValue());
+ multimap.put(nullKey(), 3);
+ Set<String> keySet = multimap.asMap().keySet();
+
+ ASSERT.that(keySet.toArray()).has().allOf("foo", nullKey());
+ ASSERT.that(keySet.toArray(new String[2])).has().allOf("foo", nullKey());
+ }
+
public void testAsMapToString() {
multimap.put("foo", 1);
assertEquals("{foo=[1]}", multimap.asMap().toString());
@@ -642,7 +689,7 @@ public abstract class AbstractMultimapTest extends TestCase {
Multiset<String> multiset = multimap.keys();
assertEquals(3, multiset.count("foo"));
assertEquals(1, multiset.count(nullKey()));
- ASSERT.that(multiset.elementSet()).hasContentsAnyOrder("foo", nullKey());
+ ASSERT.that(multiset.elementSet()).has().allOf("foo", nullKey());
assertEquals(2, multiset.entrySet().size());
assertEquals(4, multiset.size());
@@ -676,6 +723,17 @@ public abstract class AbstractMultimapTest extends TestCase {
assertEquals(0, multiset.setCount("bar", 0));
}
+ public void testKeysToArray() {
+ multimap.put("foo", 1);
+ multimap.put("foo", 5);
+ multimap.put("foo", nullValue());
+ multimap.put(nullKey(), 3);
+ ASSERT.that(multimap.keys().toArray()).has().allOf(
+ "foo", "foo", "foo", nullKey());
+ ASSERT.that(multimap.keys().toArray(new String[3])).has().allOf(
+ "foo", "foo", "foo", nullKey());
+ }
+
public void testKeysAdd() {
multimap.put("foo", 1);
Multiset<String> multiset = multimap.keys();
@@ -819,7 +877,7 @@ public abstract class AbstractMultimapTest extends TestCase {
assertTrue(values.contains(1));
assertTrue(values.contains(5));
assertFalse(values.contains(6));
- ASSERT.that(values).hasContentsAnyOrder(1, 3, 5);
+ ASSERT.that(values).has().allOf(1, 3, 5);
assertTrue(values.containsAll(asList(3, 5)));
assertFalse(values.isEmpty());
assertEquals(multimap.get("foo"), values);
@@ -834,8 +892,8 @@ public abstract class AbstractMultimapTest extends TestCase {
multimap.get("bar").addAll(asList(6, 8));
multimap.get("cow").addAll(Arrays.<Integer>asList());
assertSize(6);
- ASSERT.that(multimap.get("foo")).hasContentsAnyOrder(1, 3, 5, 7);
- ASSERT.that(multimap.get("bar")).hasContentsAnyOrder(6, 8);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 3, 5, 7);
+ ASSERT.that(multimap.get("bar")).has().allOf(6, 8);
ASSERT.that(multimap.get("cow")).isEmpty();
}
@@ -913,13 +971,13 @@ public abstract class AbstractMultimapTest extends TestCase {
assertTrue(values.removeAll(asList(11, 15)));
assertSize(4);
- ASSERT.that(multimap.get("foo")).hasContentsAnyOrder(9, 13, 17);
+ ASSERT.that(multimap.get("foo")).has().allOf(9, 13, 17);
assertFalse(values.removeAll(asList(21, 25)));
assertSize(4);
assertTrue(values.retainAll(asList(13, 17, 19)));
assertSize(3);
- ASSERT.that(multimap.get("foo")).hasContentsAnyOrder(13, 17);
+ ASSERT.that(multimap.get("foo")).has().allOf(13, 17);
assertFalse(values.retainAll(asList(13, 17, 19)));
assertSize(3);
@@ -947,7 +1005,7 @@ public abstract class AbstractMultimapTest extends TestCase {
Integer v3 = iterator.next();
assertFalse(iterator.hasNext());
- ASSERT.that(asList(v1, v2, v3)).hasContentsAnyOrder(1, 3, 5);
+ ASSERT.that(asList(v1, v2, v3)).has().allOf(1, 3, 5);
assertSize(3);
assertTrue(multimap.containsEntry("foo", v1));
assertFalse(multimap.containsEntry("foo", v2));
@@ -962,7 +1020,7 @@ public abstract class AbstractMultimapTest extends TestCase {
iterator.remove();
assertFalse(iterator.hasNext());
- ASSERT.that(asList(n1, n3)).hasContentsAnyOrder(v1, v3);
+ ASSERT.that(asList(n1, n3)).has().allOf(v1, v3);
assertSize(1);
assertFalse(multimap.containsKey("foo"));
}
@@ -979,7 +1037,7 @@ public abstract class AbstractMultimapTest extends TestCase {
Collection<Integer> values = multimap.get("foo");
Collection<Integer> collection = Lists.newArrayList(1, 3);
multimap.putAll("foo", collection);
- ASSERT.that(values).hasContentsAnyOrder(1, 3);
+ ASSERT.that(values).has().allOf(1, 3);
}
public void testGetPutAllMultimap() {
@@ -996,10 +1054,10 @@ public abstract class AbstractMultimapTest extends TestCase {
multimap2.put(nullKey(), nullValue());
multimap.putAll(multimap2);
- ASSERT.that(valuesFoo).hasContentsAnyOrder(1, 2);
- ASSERT.that(valuesBar).hasContentsAnyOrder(3);
- ASSERT.that(valuesCow).hasContentsAnyOrder(5);
- ASSERT.that(valuesNull).hasContentsAnyOrder(nullValue(), 2);
+ ASSERT.that(valuesFoo).has().allOf(1, 2);
+ ASSERT.that(valuesBar).has().item(3);
+ ASSERT.that(valuesCow).has().item(5);
+ ASSERT.that(valuesNull).has().allOf(nullValue(), 2);
}
public void testGetRemove() {
@@ -1007,7 +1065,7 @@ public abstract class AbstractMultimapTest extends TestCase {
multimap.put("foo", 3);
Collection<Integer> values = multimap.get("foo");
multimap.remove("foo", 1);
- ASSERT.that(values).hasContentsAnyOrder(3);
+ ASSERT.that(values).has().item(3);
}
public void testGetRemoveAll() {
@@ -1023,7 +1081,7 @@ public abstract class AbstractMultimapTest extends TestCase {
multimap.put("foo", 3);
Collection<Integer> values = multimap.get("foo");
multimap.replaceValues("foo", asList(1, 5));
- ASSERT.that(values).hasContentsAnyOrder(1, 5);
+ ASSERT.that(values).has().allOf(1, 5);
multimap.replaceValues("foo", new ArrayList<Integer>());
assertTrue(multimap.isEmpty());
diff --git a/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java b/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java
index af50029..3ca8175 100644
--- a/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractMultisetTest.java
@@ -69,15 +69,6 @@ public abstract class AbstractMultisetTest extends AbstractCollectionTest {
assertSize();
}
- /**
- * Don't run {@code NullPointerTester} on multisets, since they fail with
- * Java 6 due to a bug in the JDK, as illustrated in the commented out
- * method {@code HashMultisetTest#testAnnotations()}.
- */
- // TODO: Figure out if this is still true...
- @GwtIncompatible("NullPointerTester")
- @Override public void testNullPointerExceptions() throws Exception {}
-
public void testCountZero() {
assertEquals(0, ms.count("a"));
assertSize();
diff --git a/guava-tests/test/com/google/common/collect/AbstractRangeSetTest.java b/guava-tests/test/com/google/common/collect/AbstractRangeSetTest.java
new file mode 100644
index 0000000..1a44e87
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/AbstractRangeSetTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.annotations.GwtIncompatible;
+
+import junit.framework.TestCase;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * Base class for {@link RangeSet} tests.
+ *
+ * @author Louis Wasserman
+ */
+@GwtIncompatible("TreeRangeSet")
+public abstract class AbstractRangeSetTest extends TestCase {
+ public static void testInvariants(RangeSet<?> rangeSet) {
+ testInvariantsInternal(rangeSet);
+ testInvariantsInternal(rangeSet.complement());
+ }
+
+ private static <C extends Comparable> void testInvariantsInternal(RangeSet<C> rangeSet) {
+ assertEquals(rangeSet.asRanges().isEmpty(), rangeSet.isEmpty());
+ assertEquals(!rangeSet.asRanges().iterator().hasNext(), rangeSet.isEmpty());
+
+ List<Range<C>> asRanges = ImmutableList.copyOf(rangeSet.asRanges());
+
+ // test that connected ranges are coalesced
+ for (int i = 0; i + 1 < asRanges.size(); i++) {
+ Range<C> range1 = asRanges.get(i);
+ Range<C> range2 = asRanges.get(i + 1);
+ assertFalse(range1.isConnected(range2));
+ }
+
+ // test that there are no empty ranges
+ for (Range<C> range : asRanges) {
+ assertFalse(range.isEmpty());
+ }
+
+ Iterator<Range<C>> itr = rangeSet.asRanges().iterator();
+ Range<C> expectedSpan = null;
+ if (itr.hasNext()) {
+ expectedSpan = itr.next();
+ while (itr.hasNext()) {
+ expectedSpan = expectedSpan.span(itr.next());
+ }
+ }
+
+ try {
+ Range<C> span = rangeSet.span();
+ assertEquals(expectedSpan, span);
+ } catch (NoSuchElementException e) {
+ assertNull(expectedSpan);
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/AbstractLinkedIteratorTest.java b/guava-tests/test/com/google/common/collect/AbstractSequentialIteratorTest.java
index b51f29f..803ea5a 100644
--- a/guava-tests/test/com/google/common/collect/AbstractLinkedIteratorTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractSequentialIteratorTest.java
@@ -17,7 +17,7 @@
package com.google.common.collect;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -29,9 +29,9 @@ import junit.framework.TestCase;
import java.util.Iterator;
import java.util.NoSuchElementException;
-/** Tests for {@link AbstractLinkedIterator}. */
+/** Tests for {@link AbstractSequentialIterator}. */
@GwtCompatible(emulated = true)
-public class AbstractLinkedIteratorTest extends TestCase {
+public class AbstractSequentialIteratorTest extends TestCase {
@GwtIncompatible("Too slow")
public void testDoublerExhaustive() {
new IteratorTester<Integer>(3, UNMODIFIABLE, ImmutableList.of(1, 2),
@@ -50,14 +50,14 @@ public class AbstractLinkedIteratorTest extends TestCase {
return newDoubler(2, 32);
}
};
- ASSERT.that(doubled).hasContentsInOrder(2, 4, 8, 16, 32);
+ ASSERT.that(doubled).iteratesOverSequence(2, 4, 8, 16, 32);
}
public void testSampleCode() {
Iterable<Integer> actual = new Iterable<Integer>() {
@Override
public Iterator<Integer> iterator() {
- Iterator<Integer> powersOfTwo = new AbstractLinkedIterator<Integer>(1) {
+ Iterator<Integer> powersOfTwo = new AbstractSequentialIterator<Integer>(1) {
protected Integer computeNext(Integer previous) {
return (previous == 1 << 30) ? null : previous * 2;
}
@@ -65,9 +65,9 @@ public class AbstractLinkedIteratorTest extends TestCase {
return powersOfTwo;
}
};
- ASSERT.that(actual).hasContentsInOrder(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096,
- 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608,
- 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824);
+ ASSERT.that(actual).iteratesOverSequence(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
+ 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304,
+ 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824);
}
public void testEmpty() {
@@ -102,7 +102,7 @@ public class AbstractLinkedIteratorTest extends TestCase {
}
private static Iterator<Integer> newDoubler(int first, final int last) {
- return new AbstractLinkedIterator<Integer>(first) {
+ return new AbstractSequentialIterator<Integer>(first) {
@Override
protected Integer computeNext(Integer previous) {
return (previous == last) ? null : previous * 2;
@@ -111,7 +111,7 @@ public class AbstractLinkedIteratorTest extends TestCase {
}
private static <T> Iterator<T> newEmpty() {
- return new AbstractLinkedIterator<T>(null) {
+ return new AbstractSequentialIterator<T>(null) {
@Override
protected T computeNext(T previous) {
throw new AssertionFailedError();
@@ -120,7 +120,7 @@ public class AbstractLinkedIteratorTest extends TestCase {
}
private static Iterator<Object> newBroken() {
- return new AbstractLinkedIterator<Object>("UNUSED") {
+ return new AbstractSequentialIterator<Object>("UNUSED") {
@Override
protected Object computeNext(Object previous) {
throw new MyException();
diff --git a/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java b/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java
index b808951..5c0bc76 100644
--- a/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java
+++ b/guava-tests/test/com/google/common/collect/AbstractTableReadTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -183,11 +183,11 @@ public abstract class AbstractTableReadTest extends TestCase {
public void testColumnSetPartialOverlap() {
table = create(
"foo", 1, 'a', "bar", 1, 'b', "foo", 2, 'c', "bar", 3, 'd');
- ASSERT.that(table.columnKeySet()).hasContentsAnyOrder(1, 2, 3);
+ ASSERT.that(table.columnKeySet()).has().allOf(1, 2, 3);
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerInstance() throws Exception {
+ public void testNullPointerInstance() {
table = create(
"foo", 1, 'a', "bar", 1, 'b', "foo", 2, 'c', "bar", 3, 'd');
new NullPointerTester().testAllPublicInstanceMethods(table);
diff --git a/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java b/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java
index ca53f2c..51012b0 100644
--- a/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/ArrayListMultimapTest.java
@@ -17,12 +17,22 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringListMultimapGenerator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
import java.util.ConcurrentModificationException;
import java.util.List;
+import java.util.Map.Entry;
import java.util.RandomAccess;
/**
@@ -30,9 +40,35 @@ import java.util.RandomAccess;
*
* @author Jared Levy
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class ArrayListMultimapTest extends AbstractListMultimapTest {
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(ListMultimapTestSuiteBuilder.using(new TestStringListMultimapGenerator() {
+ @Override
+ protected ListMultimap<String, String> create(Entry<String, String>[] entries) {
+ ListMultimap<String, String> multimap = ArrayListMultimap.create();
+ for (Entry<String, String> entry : entries) {
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return multimap;
+ }
+ })
+ .named("ArrayListMultimap")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
+ CollectionFeature.SERIALIZABLE,
+ CollectionSize.ANY)
+ .createTestSuite());
+ suite.addTestSuite(ArrayListMultimapTest.class);
+ return suite;
+ }
+
@Override protected ListMultimap<String, Integer> create() {
return ArrayListMultimap.create();
}
@@ -80,9 +116,9 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest {
ListMultimap<String, Integer> multimap = create();
multimap.putAll("foo", asList(1, 2, 3, 4, 5));
List<Integer> list = multimap.get("foo");
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2, 3, 4, 5);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2, 3, 4, 5).inOrder();
List<Integer> sublist = list.subList(0, 5);
- ASSERT.that(sublist).hasContentsInOrder(1, 2, 3, 4, 5);
+ ASSERT.that(sublist).has().allOf(1, 2, 3, 4, 5).inOrder();
sublist.clear();
assertTrue(sublist.isEmpty());
@@ -104,7 +140,7 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest {
public void testCreate() {
ArrayListMultimap<String, Integer> multimap
= ArrayListMultimap.create();
- assertEquals(10, multimap.expectedValuesPerKey);
+ assertEquals(3, multimap.expectedValuesPerKey);
}
public void testCreateFromSizes() {
@@ -129,7 +165,7 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest {
Multimap<String, Integer> original = HashMultimap.create();
ArrayListMultimap<String, Integer> multimap
= ArrayListMultimap.create(original);
- assertEquals(10, multimap.expectedValuesPerKey);
+ assertEquals(3, multimap.expectedValuesPerKey);
}
public void testCreateFromArrayListMultimap() {
@@ -148,7 +184,7 @@ public class ArrayListMultimapTest extends AbstractListMultimapTest {
multimap.put("bar", 3);
multimap.trimToSize();
assertEquals(3, multimap.size());
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 2);
- ASSERT.that(multimap.get("bar")).hasContentsInOrder(3);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 2).inOrder();
+ ASSERT.that(multimap.get("bar")).has().item(3);
}
}
diff --git a/guava-tests/test/com/google/common/collect/ArrayTableTest.java b/guava-tests/test/com/google/common/collect/ArrayTableTest.java
index 8c2bf0c..38bc927 100644
--- a/guava-tests/test/com/google/common/collect/ArrayTableTest.java
+++ b/guava-tests/test/com/google/common/collect/ArrayTableTest.java
@@ -17,8 +17,10 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Objects;
import com.google.common.collect.Table.Cell;
import com.google.common.testing.EqualsTester;
@@ -33,6 +35,7 @@ import java.util.Map;
*
* @author Jared Levy
*/
+@GwtCompatible(emulated = true)
public class ArrayTableTest extends AbstractTableTest {
@Override protected ArrayTable<String, Integer, Character> create(
@@ -239,7 +242,8 @@ public class ArrayTableTest extends AbstractTableTest {
SerializableTester.reserializeAndAssert(table);
}
- public void testNullPointerStatic() throws Exception {
+ @GwtIncompatible("reflection")
+ public void testNullPointerStatic() {
new NullPointerTester().testAllPublicStaticMethods(ArrayTable.class);
}
@@ -282,13 +286,13 @@ public class ArrayTableTest extends AbstractTableTest {
public void testRowKeyList() {
ArrayTable<String, Integer, Character> table
= create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- ASSERT.that(table.rowKeyList()).hasContentsInOrder("foo", "bar", "cat");
+ ASSERT.that(table.rowKeyList()).has().allOf("foo", "bar", "cat").inOrder();
}
public void testColumnKeyList() {
ArrayTable<String, Integer, Character> table
= create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- ASSERT.that(table.columnKeyList()).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(table.columnKeyList()).has().allOf(1, 2, 3).inOrder();
}
public void testGetMissingKeys() {
@@ -390,14 +394,15 @@ public class ArrayTableTest extends AbstractTableTest {
assertNull(table.erase("bar", null));
}
+ @GwtIncompatible("ArrayTable.toArray(Class)")
public void testToArray() {
ArrayTable<String, Integer, Character> table
= create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Character[][] array = table.toArray(Character.class);
assertEquals(3, array.length);
- ASSERT.that(array[0]).hasContentsInOrder('a', null, 'c');
- ASSERT.that(array[1]).hasContentsInOrder('b', null, null);
- ASSERT.that(array[2]).hasContentsInOrder(null, null, null);
+ ASSERT.that(array[0]).has().allOf('a', null, 'c').inOrder();
+ ASSERT.that(array[1]).has().allOf('b', null, null).inOrder();
+ ASSERT.that(array[2]).has().allOf(null, null, null).inOrder();
table.set(0, 2, 'd');
assertEquals((Character) 'c', array[0][2]);
array[0][2] = 'e';
@@ -453,4 +458,14 @@ public class ArrayTableTest extends AbstractTableTest {
assertEquals("Row dog not in [foo, bar, cat]", expected.getMessage());
}
}
+
+ @GwtIncompatible("reflection")
+ public void testNulls() {
+ new NullPointerTester().testAllPublicInstanceMethods(create());
+ }
+
+ @GwtIncompatible("serialize")
+ public void testSerializable() {
+ SerializableTester.reserializeAndAssert(create());
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java b/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java
new file mode 100644
index 0000000..794a3a5
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/BenchmarkHelpers.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+/**
+ * Helper classes for various benchmarks.
+ *
+ * @author Christopher Swenson
+ */
+final class BenchmarkHelpers {
+ /**
+ * So far, this is the best way to test various implementations of {@link Set} subclasses.
+ */
+ public enum SetImpl {
+ Hash {
+ @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
+ return new HashSet<E>(contents);
+ }
+ },
+ LinkedHash {
+ @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
+ return new LinkedHashSet<E>(contents);
+ }
+ },
+ Tree {
+ @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
+ return new TreeSet<E>(contents);
+ }
+ },
+ Unmodifiable {
+ @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
+ return Collections.unmodifiableSet(new HashSet<E>(contents));
+ }
+ },
+ Synchronized {
+ @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
+ return Collections.synchronizedSet(new HashSet<E>(contents));
+ }
+ },
+ Immutable {
+ @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
+ return ImmutableSet.copyOf(contents);
+ }
+ },
+ ImmutableSorted {
+ @Override <E extends Comparable<E>> Set<E> create(Collection<E> contents) {
+ return ImmutableSortedSet.copyOf(contents);
+ }
+ },
+ ;
+
+ abstract <E extends Comparable<E>> Set<E> create(Collection<E> contents);
+ }
+
+ public enum ListMultimapImpl {
+ ArrayList {
+ @Override
+ <K, V> ListMultimap<K, V> create(Multimap<K, V> contents) {
+ return ArrayListMultimap.create(contents);
+ }
+ },
+ LinkedList {
+ @Override
+ <K, V> ListMultimap<K, V> create(Multimap<K, V> contents) {
+ return LinkedListMultimap.create(contents);
+ }
+ },
+ ImmutableList {
+ @Override
+ <K, V> ListMultimap<K, V> create(Multimap<K, V> contents) {
+ return ImmutableListMultimap.copyOf(contents);
+ }
+ };
+
+ abstract <K, V> ListMultimap<K, V> create(Multimap<K, V> contents);
+ }
+
+ public enum SetMultimapImpl {
+ Hash {
+ @Override
+ <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create(
+ Multimap<K, V> contents) {
+ return HashMultimap.create(contents);
+ }
+ },
+ LinkedHash {
+ @Override
+ <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create(
+ Multimap<K, V> contents) {
+ return LinkedHashMultimap.create(contents);
+ }
+ },
+ Tree {
+ @Override
+ <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create(
+ Multimap<K, V> contents) {
+ return TreeMultimap.create(contents);
+ }
+ },
+ ImmutableSet {
+ @Override
+ <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create(
+ Multimap<K, V> contents) {
+ return ImmutableSetMultimap.copyOf(contents);
+ }
+ };
+
+ abstract <K extends Comparable<K>, V extends Comparable<V>> SetMultimap<K, V> create(
+ Multimap<K, V> contents);
+ }
+
+ public enum MapImpl {
+ Hash {
+ @Override
+ <K, V> Map<K, V> create(Map<K, V> map) {
+ return Maps.newHashMap(map);
+ }
+ },
+ LinkedHash {
+ @Override
+ <K, V> Map<K, V> create(Map<K, V> map) {
+ return Maps.newLinkedHashMap(map);
+ }
+ },
+ ConcurrentHash {
+ @Override
+ <K, V> Map<K, V> create(Map<K, V> map) {
+ return new ConcurrentHashMap<K, V>(map);
+ }
+ },
+ Immutable {
+ @Override
+ <K, V> Map<K, V> create(Map<K, V> map) {
+ return ImmutableMap.copyOf(map);
+ }
+ };
+
+ abstract <K, V> Map<K, V> create(Map<K, V> map);
+ }
+
+ enum SortedMapImpl {
+ Tree {
+ @Override
+ <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map) {
+ SortedMap<K, V> result = Maps.newTreeMap();
+ result.putAll(map);
+ return result;
+ }
+ },
+ ConcurrentSkipList {
+ @Override
+ <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map) {
+ return new ConcurrentSkipListMap<K, V>(map);
+ }
+ },
+ ImmutableSorted {
+ @Override
+ <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map) {
+ return ImmutableSortedMap.copyOf(map);
+ }
+ };
+
+ abstract <K extends Comparable<K>, V> SortedMap<K, V> create(Map<K, V> map);
+ }
+
+ enum BiMapImpl {
+ Hash{
+ @Override
+ <K, V> BiMap<K, V> create(BiMap<K, V> map) {
+ return HashBiMap.create(map);
+ }
+ },
+ Immutable {
+ @Override
+ <K, V> BiMap<K, V> create(BiMap<K, V> map) {
+ return ImmutableBiMap.copyOf(map);
+ }
+ };
+
+ abstract <K, V> BiMap<K, V> create(BiMap<K, V> map);
+ }
+
+ enum MultisetImpl {
+ Hash {
+ @Override
+ <E> Multiset<E> create(Multiset<E> contents) {
+ return HashMultiset.create(contents);
+ }
+ },
+ LinkedHash {
+ @Override
+ <E> Multiset<E> create(Multiset<E> contents) {
+ return LinkedHashMultiset.create(contents);
+ }
+ },
+ ConcurrentHash {
+ @Override
+ <E> Multiset<E> create(Multiset<E> contents) {
+ return ConcurrentHashMultiset.create(contents);
+ }
+ },
+ Immutable {
+ @Override
+ <E> Multiset<E> create(Multiset<E> contents) {
+ return ImmutableMultiset.copyOf(contents);
+ }
+ };
+
+ abstract <E> Multiset<E> create(Multiset<E> contents);
+ }
+
+ enum SortedMultisetImpl {
+ Tree {
+ @Override
+ <E extends Comparable<E>> SortedMultiset<E> create(Multiset<E> contents) {
+ return TreeMultiset.create(contents);
+ }
+ },
+ ImmutableSorted {
+ @Override
+ <E extends Comparable<E>> SortedMultiset<E> create(Multiset<E> contents) {
+ return ImmutableSortedMultiset.copyOf(contents);
+ }
+ };
+
+ abstract <E extends Comparable<E>> SortedMultiset<E> create(Multiset<E> contents);
+ }
+
+ enum TableImpl {
+ HashBased {
+ @Override
+ <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create(
+ Table<R, C, V> contents) {
+ return HashBasedTable.create(contents);
+ }
+ },
+ TreeBased {
+ @Override
+ <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create(
+ Table<R, C, V> contents) {
+ Table<R, C, V> table = TreeBasedTable.create();
+ table.putAll(contents);
+ return table;
+ }
+ },
+ Array {
+ @Override
+ <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create(
+ Table<R, C, V> contents) {
+ if (contents.isEmpty()) {
+ return ImmutableTable.of();
+ } else {
+ return ArrayTable.create(contents);
+ }
+ }
+ },
+ Immutable {
+ @Override
+ <R extends Comparable<R>, C extends Comparable<C>, V> Table<R, C, V> create(
+ Table<R, C, V> contents) {
+ return ImmutableTable.copyOf(contents);
+ }
+ };
+
+ abstract <R extends Comparable<R>, C extends Comparable<C>, V>
+ Table<R, C, V> create(Table<R, C, V> contents);
+ }
+
+ public enum Value {
+ INSTANCE;
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/BiMapCollectionTest.java b/guava-tests/test/com/google/common/collect/BiMapCollectionTest.java
deleted file mode 100644
index 9bee5f1..0000000
--- a/guava-tests/test/com/google/common/collect/BiMapCollectionTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestStringSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.Set;
-
-/**
- * Collection tests for bimaps.
- *
- * @author Jared Levy
- */
-@GwtCompatible
-public class BiMapCollectionTest extends TestCase {
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- BiMap<String, Integer> bimap = HashBiMap.create();
- for (int i = 0; i < elements.length; i++) {
- bimap.put(elements[i], i);
- }
- return bimap.keySet();
- }
- })
- .named("HashBiMap.keySet")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.REMOVE_OPERATIONS)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- BiMap<Integer, String> bimap = HashBiMap.create();
- for (int i = 0; i < elements.length; i++) {
- bimap.put(i, elements[i]);
- }
- return bimap.values();
- }
- })
- .named("HashBiMap.values")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.REMOVE_OPERATIONS,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION)
- .createTestSuite());
-
- return suite;
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/BiMapMapInterfaceTest.java b/guava-tests/test/com/google/common/collect/BiMapMapInterfaceTest.java
deleted file mode 100644
index 6f3ae3e..0000000
--- a/guava-tests/test/com/google/common/collect/BiMapMapInterfaceTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.testing.MapInterfaceTest;
-
-import junit.framework.TestCase;
-
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Map interface tests for bimaps.
- *
- * @author Jared Levy
- */
-@GwtCompatible
-public class BiMapMapInterfaceTest extends TestCase {
-
- private abstract static class AbstractMapInterfaceTest
- extends MapInterfaceTest<String, Integer> {
-
- protected AbstractMapInterfaceTest(boolean modifiable) {
- super(true, true, modifiable, modifiable, modifiable);
- }
-
- @Override protected String getKeyNotInPopulatedMap() {
- return "cat";
- }
-
- @Override protected Integer getValueNotInPopulatedMap() {
- return 3;
- }
-
- @Override protected Map<String, Integer> makeEmptyMap() {
- return HashBiMap.create();
- }
-
- @Override protected Map<String, Integer> makePopulatedMap() {
- Map<String, Integer> map = makeEmptyMap();
- map.put("foo", 1);
- map.put("bar", 2);
- return map;
- }
-
- @Override protected void assertMoreInvariants(Map<String, Integer> map) {
- BiMap<String, Integer> bimap = (BiMap<String, Integer>) map;
- BiMap<Integer, String> inverse = bimap.inverse();
- assertEquals(bimap.size(), inverse.size());
- for (Entry<String, Integer> entry : bimap.entrySet()) {
- assertEquals(entry.getKey(), inverse.get(entry.getValue()));
- }
- for (Entry<Integer, String> entry : inverse.entrySet()) {
- assertEquals(entry.getKey(), bimap.get(entry.getValue()));
- }
- }
- }
-
- public static class HashBiMapInterfaceTest extends AbstractMapInterfaceTest {
- public HashBiMapInterfaceTest() {
- super(true);
- }
- @Override protected Map<String, Integer> makeEmptyMap() {
- return HashBiMap.create();
- }
- }
-
- public static class InverseBiMapInterfaceTest
- extends AbstractMapInterfaceTest {
- public InverseBiMapInterfaceTest() {
- super(true);
- }
- @Override protected Map<String, Integer> makeEmptyMap() {
- return HashBiMap.<Integer, String>create().inverse();
- }
- }
-
- public static class UnmodifiableBiMapInterfaceTest
- extends AbstractMapInterfaceTest {
- public UnmodifiableBiMapInterfaceTest() {
- super(false);
- }
- @Override protected Map<String, Integer> makeEmptyMap() {
- return Maps.unmodifiableBiMap(HashBiMap.<String, Integer>create());
- }
- @Override protected Map<String, Integer> makePopulatedMap() {
- BiMap<String, Integer> bimap = HashBiMap.create();
- bimap.put("foo", 1);
- bimap.put("bar", 2);
- return Maps.unmodifiableBiMap(bimap);
- }
- }
-
- public static class SynchronizedBiMapInterfaceTest
- extends AbstractMapInterfaceTest {
- public SynchronizedBiMapInterfaceTest() {
- super(true);
- }
- @Override protected Map<String, Integer> makeEmptyMap() {
- return Maps.synchronizedBiMap(HashBiMap.<String, Integer>create());
- }
- }
-
- public void testNothing() {
- /*
- * It's a warning if a TestCase subclass contains no tests, so we add one.
- * Alternatively, we could stop extending TestCase, but I worry that someone
- * will add a test in the future and not realize that it's being ignored.
- */
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/BstCountBasedBalancePoliciesTest.java b/guava-tests/test/com/google/common/collect/BstCountBasedBalancePoliciesTest.java
deleted file mode 100644
index f084ae7..0000000
--- a/guava-tests/test/com/google/common/collect/BstCountBasedBalancePoliciesTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BstTesting.countAggregate;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.BstTesting.SimpleNode;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Tests for the policies exported by {@link BstCountBasedBalancePolicies}
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class BstCountBasedBalancePoliciesTest extends TestCase {
- public static class NoRebalanceTest extends AbstractBstBalancePolicyTest {
- @Override
- protected BstBalancePolicy<SimpleNode> getBalancePolicy() {
- return BstCountBasedBalancePolicies.noRebalancePolicy(countAggregate);
- }
- }
-
- public static class SingleRebalanceTest extends AbstractBstBalancePolicyTest {
- @Override
- protected BstBalancePolicy<SimpleNode> getBalancePolicy() {
- return BstCountBasedBalancePolicies.<Character, SimpleNode>singleRebalancePolicy(
- countAggregate);
- }
- }
-
- public static class FullRebalanceTest extends AbstractBstBalancePolicyTest {
- @Override
- protected BstBalancePolicy<SimpleNode> getBalancePolicy() {
- return BstCountBasedBalancePolicies.<Character, SimpleNode>fullRebalancePolicy(
- countAggregate);
- }
- }
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
- suite.addTestSuite(NoRebalanceTest.class);
- suite.addTestSuite(SingleRebalanceTest.class);
- suite.addTestSuite(FullRebalanceTest.class);
- return suite;
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/BstInOrderPathTest.java b/guava-tests/test/com/google/common/collect/BstInOrderPathTest.java
deleted file mode 100644
index 0498401..0000000
--- a/guava-tests/test/com/google/common/collect/BstInOrderPathTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BstSide.LEFT;
-import static com.google.common.collect.BstSide.RIGHT;
-import static com.google.common.collect.BstTesting.defaultNullPointerTester;
-import static com.google.common.collect.BstTesting.extension;
-import static com.google.common.collect.BstTesting.pathToList;
-import static org.junit.contrib.truth.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.BstTesting.SimpleNode;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@code BstInOrderPath}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class BstInOrderPathTest extends TestCase {
- public void testFullTreeRight() {
- // d
- // / \
- // b f
- // / \ / \
- // a c e g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', a, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
- BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
- BstInOrderPath.inOrderFactory();
- BstInOrderPath<SimpleNode> path = extension(factory, d, LEFT, LEFT);
- ASSERT.that(pathToList(path)).hasContentsInOrder(a, b, d);
- path = testNextPathIs(path, b, d);
- path = testNextPathIs(path, c, b, d);
- path = testNextPathIs(path, d);
- path = testNextPathIs(path, e, f, d);
- path = testNextPathIs(path, f, d);
- path = testNextPathIs(path, g, f, d);
- assertFalse(path.hasNext(RIGHT));
- }
-
- public void testFullTreeLeft() {
- // d
- // / \
- // b f
- // / \ / \
- // a c e g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', a, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
- BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
- BstInOrderPath.inOrderFactory();
- BstInOrderPath<SimpleNode> path = extension(factory, d, RIGHT, RIGHT);
- ASSERT.that(pathToList(path)).hasContentsInOrder(g, f, d);
- path = testPrevPathIs(path, f, d);
- path = testPrevPathIs(path, e, f, d);
- path = testPrevPathIs(path, d);
- path = testPrevPathIs(path, c, b, d);
- path = testPrevPathIs(path, b, d);
- path = testPrevPathIs(path, a, b, d);
- assertFalse(path.hasNext(LEFT));
- }
-
- public void testPartialTree1Right() {
-
- // d
- // / \
- // b f
- // / \
- // a g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
- BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
- BstInOrderPath.inOrderFactory();
- BstInOrderPath<SimpleNode> path = extension(factory, d, LEFT, LEFT);
- ASSERT.that(pathToList(path)).hasContentsInOrder(a, b, d);
- path = testNextPathIs(path, b, d);
- path = testNextPathIs(path, d);
- path = testNextPathIs(path, f, d);
- path = testNextPathIs(path, g, f, d);
- assertFalse(path.hasNext(RIGHT));
- }
-
- public void testPartialTree1Left() {
-
- // d
- // / \
- // b f
- // / \
- // a g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
- BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
- BstInOrderPath.inOrderFactory();
- BstInOrderPath<SimpleNode> path = extension(factory, d, RIGHT, RIGHT);
- ASSERT.that(pathToList(path)).hasContentsInOrder(g, f, d);
- path = testPrevPathIs(path, f, d);
- path = testPrevPathIs(path, d);
- path = testPrevPathIs(path, b, d);
- path = testPrevPathIs(path, a, b, d);
- assertFalse(path.hasNext(LEFT));
- }
-
- public void testPartialTree2Right() {
- // d
- // / \
- // b f
- // \ /
- // c e
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode f = new SimpleNode('f', e, null);
- SimpleNode d = new SimpleNode('d', b, f);
- BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
- BstInOrderPath.inOrderFactory();
- BstInOrderPath<SimpleNode> path = extension(factory, d, LEFT);
- ASSERT.that(pathToList(path)).hasContentsInOrder(b, d);
- path = testNextPathIs(path, c, b, d);
- path = testNextPathIs(path, d);
- path = testNextPathIs(path, e, f, d);
- path = testNextPathIs(path, f, d);
- assertFalse(path.hasNext(RIGHT));
- }
-
- public void testPartialTree2Left() {
- // d
- // / \
- // b f
- // \ /
- // c e
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode f = new SimpleNode('f', e, null);
- SimpleNode d = new SimpleNode('d', b, f);
- BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> factory =
- BstInOrderPath.inOrderFactory();
- BstInOrderPath<SimpleNode> path = extension(factory, d, RIGHT);
- ASSERT.that(pathToList(path)).hasContentsInOrder(f, d);
- path = testPrevPathIs(path, e,f,d);
- path = testPrevPathIs(path, d);
- path = testPrevPathIs(path, c,b, d);
- path = testPrevPathIs(path, b, d);
- assertFalse(path.hasNext(LEFT));
- }
-
- private static BstInOrderPath<SimpleNode> testNextPathIs(
- BstInOrderPath<SimpleNode> path, SimpleNode... nodes) {
- assertTrue(path.hasNext(RIGHT));
- path = path.next(RIGHT);
- ASSERT.that(pathToList(path)).hasContentsInOrder(nodes);
- return path;
- }
-
- private static BstInOrderPath<SimpleNode> testPrevPathIs(
- BstInOrderPath<SimpleNode> path, SimpleNode... nodes) {
- assertTrue(path.hasNext(LEFT));
- path = path.next(LEFT);
- ASSERT.that(pathToList(path)).hasContentsInOrder(nodes);
- return path;
- }
-
- @GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
- defaultNullPointerTester().testAllPublicStaticMethods(BstInOrderPath.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/BstMutationResultTest.java b/guava-tests/test/com/google/common/collect/BstMutationResultTest.java
deleted file mode 100644
index bb942c2..0000000
--- a/guava-tests/test/com/google/common/collect/BstMutationResultTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BstTesting.defaultNullPointerTester;
-
-import com.google.common.annotations.GwtIncompatible;
-
-import junit.framework.TestCase;
-
-/**
- * Tests for {@code BstMutationResult}.
- *
- * @author Louis Wasserman
- */
-@GwtIncompatible("NullPointerTester")
-public class BstMutationResultTest extends TestCase {
- public void testNullPointers() throws Exception {
- defaultNullPointerTester().testAllPublicStaticMethods(BstMutationResult.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/BstNodeTest.java b/guava-tests/test/com/google/common/collect/BstNodeTest.java
deleted file mode 100644
index 37f2bbc..0000000
--- a/guava-tests/test/com/google/common/collect/BstNodeTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 'b'.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-'b'.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BstSide.LEFT;
-import static com.google.common.collect.BstSide.RIGHT;
-import static com.google.common.collect.BstTesting.defaultNullPointerTester;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.BstTesting.SimpleNode;
-
-import junit.framework.TestCase;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Tests for {@code BstNode}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class BstNodeTest extends TestCase {
- private void testLacksChild(SimpleNode node, BstSide side) {
- assertNull(node.childOrNull(side));
- assertFalse(node.hasChild(side));
- try {
- node.getChild(side);
- fail("Expected IllegalStateException");
- } catch (IllegalStateException expected) {}
- }
-
- private void testChildIs(SimpleNode node, BstSide side, SimpleNode expectedChild) {
- assertEquals(expectedChild, node.childOrNull(side));
- assertTrue(node.hasChild(side));
- assertEquals(expectedChild, node.getChild(side));
- }
-
- public void testHasChildLeaf() {
- SimpleNode leaf = new SimpleNode('a', null, null);
- testLacksChild(leaf, LEFT);
- testLacksChild(leaf, RIGHT);
- }
-
- public void testHasChildLeftOnly() {
- SimpleNode leaf = new SimpleNode('a', null, null);
- SimpleNode node = new SimpleNode('b', leaf, null);
- testChildIs(node, LEFT, leaf);
- testLacksChild(node, RIGHT);
- }
-
- public void testHasChildRightOnly() {
- SimpleNode leaf = new SimpleNode('c', null, null);
- SimpleNode node = new SimpleNode('b', null, leaf);
- testLacksChild(node, LEFT);
- testChildIs(node, RIGHT, leaf);
- }
-
- public void testHasChildBoth() {
- SimpleNode left = new SimpleNode('a', null, null);
- SimpleNode right = new SimpleNode('c', null, null);
- SimpleNode node = new SimpleNode('b', left, right);
- testChildIs(node, LEFT, left);
- testChildIs(node, RIGHT, right);
- }
-
- private static final char MIDDLE_KEY = 'b';
-
- private static final List<SimpleNode> GOOD_LEFTS =
- Arrays.asList(null, new SimpleNode('a', null, null));
- private static final List<SimpleNode> BAD_LEFTS =
- Arrays.asList(new SimpleNode('b', null, null), new SimpleNode('c', null, null));
- private static final Iterable<SimpleNode> ALL_LEFTS = Iterables.concat(GOOD_LEFTS, BAD_LEFTS);
-
- private static final List<SimpleNode> GOOD_RIGHTS =
- Arrays.asList(null, new SimpleNode('c', null, null));
- private static final List<SimpleNode> BAD_RIGHTS =
- Arrays.asList(new SimpleNode('b', null, null), new SimpleNode('a', null, null));
- private static final Iterable<SimpleNode> ALL_RIGHTS = Iterables.concat(GOOD_RIGHTS, BAD_RIGHTS);
-
- public void testOrderingInvariantHoldsForGood() {
- for (SimpleNode left : GOOD_LEFTS) {
- for (SimpleNode right : GOOD_RIGHTS) {
- assertTrue(
- new SimpleNode(MIDDLE_KEY, left, right).orderingInvariantHolds(Ordering.natural()));
- }
- }
- }
-
- public void testOrderingInvariantBadLeft() {
- for (SimpleNode left : BAD_LEFTS) {
- for (SimpleNode right : ALL_RIGHTS) {
- assertFalse(
- new SimpleNode(MIDDLE_KEY, left, right).orderingInvariantHolds(Ordering.natural()));
- }
- }
- }
-
- public void testOrderingInvariantBadRight() {
- for (SimpleNode left : ALL_LEFTS) {
- for (SimpleNode right : BAD_RIGHTS) {
- assertFalse(
- new SimpleNode(MIDDLE_KEY, left, right).orderingInvariantHolds(Ordering.natural()));
- }
- }
- }
-
- @GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
- defaultNullPointerTester().testAllPublicStaticMethods(BstNode.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/BstOperationsTest.java b/guava-tests/test/com/google/common/collect/BstOperationsTest.java
deleted file mode 100644
index 7ced712..0000000
--- a/guava-tests/test/com/google/common/collect/BstOperationsTest.java
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BstSide.LEFT;
-import static com.google.common.collect.BstTesting.assertInOrderTraversalIs;
-import static com.google.common.collect.BstTesting.balancePolicy;
-import static com.google.common.collect.BstTesting.defaultNullPointerTester;
-import static com.google.common.collect.BstTesting.extension;
-import static com.google.common.collect.BstTesting.nodeFactory;
-import static com.google.common.collect.BstTesting.pathFactory;
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.isNull;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.reportMatcher;
-import static org.easymock.EasyMock.same;
-import static org.easymock.EasyMock.verify;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.BstModificationResult.ModificationType;
-import com.google.common.collect.BstTesting.SimpleNode;
-
-import junit.framework.TestCase;
-
-import org.easymock.EasyMock;
-import org.easymock.IArgumentMatcher;
-
-/**
- * Tests for {@code BstOperations}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class BstOperationsTest extends TestCase {
- public void testSeek1() {
- // d
- // / \
- // b f
- // / \
- // a g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
- assertEquals(a, BstOperations.seek(Ordering.natural(), d, 'a'));
- assertEquals(b, BstOperations.seek(Ordering.natural(), d, 'b'));
- assertNull(BstOperations.seek(Ordering.natural(), d, 'c'));
- assertEquals(d, BstOperations.seek(Ordering.natural(), d, 'd'));
- assertNull(BstOperations.seek(Ordering.natural(), d, 'e'));
- assertEquals(f, BstOperations.seek(Ordering.natural(), d, 'f'));
- assertEquals(g, BstOperations.seek(Ordering.natural(), d, 'g'));
- }
-
- public void testSeek2() {
- // d
- // / \
- // b f
- // \ /
- // c e
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode f = new SimpleNode('f', e, null);
- SimpleNode d = new SimpleNode('d', b, f);
- assertNull(BstOperations.seek(Ordering.natural(), d, 'a'));
- assertEquals(b, BstOperations.seek(Ordering.natural(), d, 'b'));
- assertEquals(c, BstOperations.seek(Ordering.natural(), d, 'c'));
- assertEquals(d, BstOperations.seek(Ordering.natural(), d, 'd'));
- assertEquals(e, BstOperations.seek(Ordering.natural(), d, 'e'));
- assertEquals(f, BstOperations.seek(Ordering.natural(), d, 'f'));
- assertNull(BstOperations.seek(Ordering.natural(), d, 'g'));
- }
-
- @GwtIncompatible("EasyMock")
- @SuppressWarnings("unchecked")
- public void testModifyInsertAbsentNode() {
- // d
- // / \
- // b f
- // / \
- // a g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
- BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
- BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
-
- SimpleNode c = new SimpleNode('c', null, null);
- expect(modifier.modify(eq('c'), (SimpleNode) isNull())).andReturn(
- BstModificationResult.rebalancingChange(null, c));
-
- expect(balancePolicy.balance(
- same(nodeFactory), same(c), (SimpleNode) isNull(), (SimpleNode) isNull()))
- .andReturn(c)
- .times(0, 1);
-
- SimpleNode bWithC = new SimpleNode('b', a, c);
- expectPossibleEntryfication(nodeFactory, b);
- expect(balancePolicy.balance(
- same(nodeFactory), withKey('b'), same(a), withKey('c')))
- .andReturn(bWithC);
-
- SimpleNode dWithBWithC = new SimpleNode('d', bWithC, f);
- expectPossibleEntryfication(nodeFactory, d);
- expect(
- balancePolicy.balance(same(nodeFactory), withKey('d'), same(bWithC), same(f)))
- .andReturn(dWithBWithC);
- replay(nodeFactory, balancePolicy, modifier);
- BstMutationRule<Character, SimpleNode> mutationRule =
- BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
- BstMutationResult<Character, SimpleNode> mutationResult =
- BstOperations.mutate(Ordering.natural(), mutationRule, d, 'c');
- assertEquals('c', mutationResult.getTargetKey().charValue());
- assertNull(mutationResult.getOriginalTarget());
- assertEquals('c', mutationResult
- .getChangedTarget()
- .getKey()
- .charValue());
- assertSame(d, mutationResult.getOriginalRoot());
- assertSame(dWithBWithC, mutationResult.getChangedRoot());
- assertEquals(ModificationType.REBALANCING_CHANGE, mutationResult.modificationType());
- verify(nodeFactory, balancePolicy, modifier);
- }
-
- @GwtIncompatible("EasyMock")
- @SuppressWarnings("unchecked")
- public void testModifyInsertPresentNode() {
- // We wish to test that BstOperations & co. treat IDENTITY modifications as the same.
- // d
- // / \
- // b f
- // / \
- // a g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
- BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
- BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
-
- expectPossibleEntryfication(nodeFactory, a);
- expect(modifier.modify(eq('a'), withKey('a'))).andReturn(
- BstModificationResult.identity(a));
- replay(nodeFactory, balancePolicy, modifier);
- BstMutationRule<Character, SimpleNode> mutationRule =
- BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
- BstMutationResult<Character, SimpleNode> mutationResult =
- BstOperations.mutate(Ordering.natural(), mutationRule, d, 'a');
- assertEquals('a', mutationResult.getTargetKey().charValue());
- assertSame(a, mutationResult.getOriginalTarget());
- assertSame(a, mutationResult.getChangedTarget());
- assertSame(d, mutationResult.getOriginalRoot());
- assertSame(d, mutationResult.getChangedRoot());
- assertEquals(ModificationType.IDENTITY, mutationResult.modificationType());
- verify(nodeFactory, balancePolicy, modifier);
- }
-
- @GwtIncompatible("EasyMock")
- @SuppressWarnings("unchecked")
- public void testModifyInsertInequivalentNode() {
- // We wish to test that BstOperations & co. treat non-equivalent() nodes as different.
- // d
- // / \
- // b f
- // / \
- // a g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
- BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
- BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
-
- expectPossibleEntryfication(nodeFactory, a);
- SimpleNode a2 = new SimpleNode('a', null, null);
- expect(modifier.modify(eq('a'), withKey('a'))).andReturn(
- BstModificationResult.rebuildingChange(a, a2));
-
- expectPossibleEntryfication(nodeFactory, a2);
-
- SimpleNode bWithA2 = new SimpleNode('b', a2, null);
- expect(nodeFactory.createNode(same(b), withKey('a'), (SimpleNode) isNull())).andReturn(
- bWithA2);
-
- SimpleNode dWithA2 = new SimpleNode('d', bWithA2, f);
- expect(nodeFactory.createNode(same(d), same(bWithA2), same(f))).andReturn(
- dWithA2);
-
- replay(nodeFactory, balancePolicy, modifier);
- BstMutationRule<Character, SimpleNode> mutationRule =
- BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
- BstMutationResult<Character, SimpleNode> mutationResult =
- BstOperations.mutate(Ordering.natural(), mutationRule, d, 'a');
- assertEquals('a', mutationResult.getTargetKey().charValue());
- assertSame(a, mutationResult.getOriginalTarget());
- assertEquals('a', mutationResult.getChangedTarget().getKey().charValue());
- assertSame(d, mutationResult.getOriginalRoot());
- assertSame(dWithA2, mutationResult.getChangedRoot());
- assertEquals(ModificationType.REBUILDING_CHANGE, mutationResult.modificationType());
- verify(nodeFactory, balancePolicy, modifier);
- }
-
- @GwtIncompatible("EasyMock")
- @SuppressWarnings("unchecked")
- public void testModifyDeletePresentNode() {
- // d
- // / \
- // b f
- // / \
- // a g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
- BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
- BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
-
- expectPossibleEntryfication(nodeFactory, a);
- expect(modifier.modify(eq('a'), withKey('a'))).andReturn(
- BstModificationResult.rebalancingChange(a, null));
-
- expect(balancePolicy.combine(same(nodeFactory), (SimpleNode) isNull(), (SimpleNode) isNull()))
- .andReturn(null);
-
- expectPossibleEntryfication(nodeFactory, b);
- SimpleNode leafB = new SimpleNode('b', null, null);
- expect(
- balancePolicy.balance(same(nodeFactory), withKey('b'), (SimpleNode) isNull(),
- (SimpleNode) isNull())).andReturn(leafB);
-
- SimpleNode dWithLeafB = new SimpleNode('d', leafB, f);
- expectPossibleEntryfication(nodeFactory, d);
- expect(
- balancePolicy.balance(same(nodeFactory), withKey('d'), same(leafB), same(f)))
- .andReturn(dWithLeafB);
- replay(nodeFactory, balancePolicy, modifier);
- BstMutationRule<Character, SimpleNode> mutationRule =
- BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
- BstMutationResult<Character, SimpleNode> mutationResult =
- BstOperations.mutate(Ordering.natural(), mutationRule, d, 'a');
- assertEquals('a', mutationResult.getTargetKey().charValue());
- assertEquals('a', mutationResult
- .getOriginalTarget()
- .getKey()
- .charValue());
- assertNull(mutationResult.getChangedTarget());
- assertSame(d, mutationResult.getOriginalRoot());
- assertSame(dWithLeafB, mutationResult.getChangedRoot());
- assertEquals(ModificationType.REBALANCING_CHANGE, mutationResult.modificationType());
- verify(nodeFactory, balancePolicy, modifier);
- }
-
- @GwtIncompatible("EasyMock")
- @SuppressWarnings("unchecked")
- public void testModifyDeleteAbsentNode() {
- // d
- // / \
- // b f
- // / \
- // a g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
- BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
- BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
-
- expectPossibleEntryfication(nodeFactory, a);
- expect(modifier.modify(eq('c'), (SimpleNode) isNull())).andReturn(
- BstModificationResult.<SimpleNode> identity(null));
- replay(nodeFactory, balancePolicy, modifier);
- BstMutationRule<Character, SimpleNode> mutationRule =
- BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
- BstMutationResult<Character, SimpleNode> mutationResult =
- BstOperations.mutate(Ordering.natural(), mutationRule, d, 'c');
- assertEquals('c', mutationResult.getTargetKey().charValue());
- assertEquals(d, mutationResult.getOriginalRoot());
- assertEquals(d, mutationResult.getChangedRoot());
- assertNull(mutationResult.getOriginalTarget());
- assertNull(mutationResult.getChangedTarget());
- assertEquals(ModificationType.IDENTITY, mutationResult.modificationType());
- verify(nodeFactory, balancePolicy, modifier);
- }
-
- @GwtIncompatible("EasyMock")
- @SuppressWarnings("unchecked")
- public void testModifyPathInsertPresentNode() {
- // We wish to test that BstOperations & co. treat identity-different nodes as changed,
- // instead of using SimpleNode.equals().
- // d
- // / \
- // b f
- // / \
- // a g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- BstNodeFactory<SimpleNode> nodeFactory = EasyMock.createStrictMock(BstNodeFactory.class);
- BstBalancePolicy<SimpleNode> balancePolicy = EasyMock.createStrictMock(BstBalancePolicy.class);
- BstModifier<Character, SimpleNode> modifier = EasyMock.createStrictMock(BstModifier.class);
-
- expectPossibleEntryfication(nodeFactory, a);
- expect(modifier.modify(eq('a'), withKey('a'))).andReturn(BstModificationResult.identity(a));
- replay(nodeFactory, balancePolicy, modifier);
- BstInOrderPath<SimpleNode> path = extension(pathFactory, d, LEFT, LEFT);
- BstMutationRule<Character, SimpleNode> mutationRule =
- BstMutationRule.createRule(modifier, balancePolicy, nodeFactory);
- BstMutationResult<Character, SimpleNode> mutationResult =
- BstOperations.mutate(path, mutationRule);
- assertEquals('a', mutationResult.getTargetKey().charValue());
- assertSame(a, mutationResult.getOriginalTarget());
- assertSame(a, mutationResult.getChangedTarget());
- assertSame(d, mutationResult.getOriginalRoot());
- assertSame(d, mutationResult.getChangedRoot());
- assertEquals(ModificationType.IDENTITY, mutationResult.modificationType());
- verify(nodeFactory, balancePolicy, modifier);
- }
-
- @GwtIncompatible("EasyMock")
- private SimpleNode withKey(final char c) {
- reportMatcher(new IArgumentMatcher() {
- @Override
- public void appendTo(StringBuffer buffer) {
- buffer.append("Expected BstNode with key ").append(c);
- }
-
- @Override
- public boolean matches(Object argument) {
- return argument instanceof SimpleNode
- && ((SimpleNode) argument).getKey().charValue() == c;
- }
- });
- return null;
- }
-
- /**
- * The implementation may remove the children of a node it treats as an entry for safety. Expect
- * this and handle it.
- */
- @GwtIncompatible("EasyMock")
- private void expectPossibleEntryfication(BstNodeFactory<SimpleNode> factory, SimpleNode entry) {
- expect(factory.createNode(same(entry), (SimpleNode) isNull(), (SimpleNode) isNull()))
- .andReturn(new SimpleNode(entry.getKey(), null, null))
- .times(0, 1);
- }
- public void testInsertMin1() {
- // d
- // / \
- // b f
- // \ \
- // c g
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode newRoot = BstOperations.insertMin(d, a, nodeFactory, balancePolicy);
- assertInOrderTraversalIs(newRoot, "abcdfg");
- }
-
- public void testInsertMin2() {
- // d
- // / \
- // b f
- // \
- // g
- SimpleNode b = new SimpleNode('b', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode newRoot = BstOperations.insertMin(d, a, nodeFactory, balancePolicy);
- assertInOrderTraversalIs(newRoot, "abdfg");
- }
-
- public void testInsertMinEmpty() {
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode newRoot = BstOperations.insertMin(null, a, nodeFactory, balancePolicy);
- assertInOrderTraversalIs(newRoot, "a");
- }
-
- public void testInsertMax1() {
- // d
- // / \
- // b f
- // \ \
- // c g
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- SimpleNode h = new SimpleNode('h', null, null);
- SimpleNode newRoot = BstOperations.insertMax(d, h, nodeFactory, balancePolicy);
- assertInOrderTraversalIs(newRoot, "bcdfgh");
- }
-
- public void testInsertMax2() {
- // d
- // / \
- // b f
- // /
- // e
- SimpleNode b = new SimpleNode('b', null, null);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode f = new SimpleNode('f', e, null);
- SimpleNode d = new SimpleNode('d', b, f);
-
- SimpleNode h = new SimpleNode('h', null, null);
- SimpleNode newRoot = BstOperations.insertMax(d, h, nodeFactory, balancePolicy);
- assertInOrderTraversalIs(newRoot, "bdefh");
- }
-
- public void testInsertMaxEmpty() {
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode newRoot = BstOperations.insertMax(null, a, nodeFactory, balancePolicy);
- assertInOrderTraversalIs(newRoot, "a");
- }
-
- public void testExtractMin1() {
- // d
- // / \
- // b f
- // \ \
- // c g
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- BstMutationResult<Character, SimpleNode> extractMin =
- BstOperations.extractMin(d, nodeFactory, balancePolicy);
- assertEquals('b', extractMin.getTargetKey().charValue());
- assertEquals(d, extractMin.getOriginalRoot());
- assertEquals(b, extractMin.getOriginalTarget());
- assertNull(extractMin.getChangedTarget());
- assertInOrderTraversalIs(extractMin.getChangedRoot(), "cdfg");
- }
-
- public void testExtractMin2() {
- // d
- // / \
- // b f
- // \
- // g
- SimpleNode b = new SimpleNode('b', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- BstMutationResult<Character, SimpleNode> extractMin =
- BstOperations.extractMin(d, nodeFactory, balancePolicy);
- assertEquals('b', extractMin.getTargetKey().charValue());
- assertEquals(d, extractMin.getOriginalRoot());
- assertEquals(b, extractMin.getOriginalTarget());
- assertNull(extractMin.getChangedTarget());
- assertInOrderTraversalIs(extractMin.getChangedRoot(), "dfg");
- }
-
- public void testExtractMax1() {
- // d
- // / \
- // b f
- // \ \
- // c g
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', null, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- BstMutationResult<Character, SimpleNode> extractMax =
- BstOperations.extractMax(d, nodeFactory, balancePolicy);
- assertEquals('g', extractMax.getTargetKey().charValue());
- assertEquals(d, extractMax.getOriginalRoot());
- assertEquals(g, extractMax.getOriginalTarget());
- assertNull(extractMax.getChangedTarget());
- assertInOrderTraversalIs(extractMax.getChangedRoot(), "bcdf");
- }
-
- public void testExtractMax2() {
- // d
- // / \
- // b f
- // /
- // e
- SimpleNode b = new SimpleNode('b', null, null);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode f = new SimpleNode('f', e, null);
- SimpleNode d = new SimpleNode('d', b, f);
-
- BstMutationResult<Character, SimpleNode> extractMax =
- BstOperations.extractMax(d, nodeFactory, balancePolicy);
- assertEquals('f', extractMax.getTargetKey().charValue());
- assertEquals(d, extractMax.getOriginalRoot());
- assertEquals(f, extractMax.getOriginalTarget());
- assertNull(extractMax.getChangedTarget());
- assertInOrderTraversalIs(extractMax.getChangedRoot(), "bde");
- }
-
- @GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
- defaultNullPointerTester().testAllPublicStaticMethods(BstOperations.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/BstPathTest.java b/guava-tests/test/com/google/common/collect/BstPathTest.java
deleted file mode 100644
index 08c582d..0000000
--- a/guava-tests/test/com/google/common/collect/BstPathTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.BstTesting.SimpleNode;
-
-import junit.framework.TestCase;
-
-/**
- * Simple tests for {@code BstPath}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible
-public class BstPathTest extends TestCase {
- static class SimplePath extends BstPath<SimpleNode, SimplePath> {
- private SimplePath(SimpleNode tip, SimplePath tail) {
- super(tip, tail);
- }
- }
-
- public void testTailAtRoot() {
- SimpleNode root = new SimpleNode('a', null, null);
- SimplePath rootPath = new SimplePath(root, null);
- assertFalse(rootPath.hasPrefix());
- assertNull(rootPath.prefixOrNull());
- try {
- rootPath.getPrefix();
- fail("Expected IllegalStateException");
- } catch (IllegalStateException expected) {}
- }
-
- public void testTailDown() {
- SimpleNode node = new SimpleNode('a', null, null);
- SimpleNode root = new SimpleNode('b', node, null);
- SimplePath rootPath = new SimplePath(root, null);
- SimplePath nodePath = new SimplePath(node, rootPath);
- assertTrue(nodePath.hasPrefix());
- assertEquals(rootPath, nodePath.prefixOrNull());
- assertEquals(rootPath, nodePath.getPrefix());
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/BstRangeOpsTest.java b/guava-tests/test/com/google/common/collect/BstRangeOpsTest.java
deleted file mode 100644
index d98041a..0000000
--- a/guava-tests/test/com/google/common/collect/BstRangeOpsTest.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.BoundType.CLOSED;
-import static com.google.common.collect.BoundType.OPEN;
-import static com.google.common.collect.BstSide.LEFT;
-import static com.google.common.collect.BstSide.RIGHT;
-import static com.google.common.collect.BstTesting.assertInOrderTraversalIs;
-import static com.google.common.collect.BstTesting.balancePolicy;
-import static com.google.common.collect.BstTesting.countAggregate;
-import static com.google.common.collect.BstTesting.defaultNullPointerTester;
-import static com.google.common.collect.BstTesting.nodeFactory;
-import static com.google.common.collect.BstTesting.pathFactory;
-import static com.google.common.collect.BstTesting.pathToList;
-import static org.junit.contrib.truth.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.BstTesting.SimpleNode;
-
-import junit.framework.TestCase;
-
-import java.util.SortedSet;
-
-/**
- * Tests for {@code BSTRangeOps}.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class BstRangeOpsTest extends TestCase {
- private static final SortedSet<Character> MODEL =
- ImmutableSortedSet.of('a', 'b', 'c', 'd', 'e', 'f', 'g');
- private static final SimpleNode ROOT;
-
- static {
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', a, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
- ROOT = d;
- }
-
- public void testCountInRangeLowerBound() {
- for (char c : "abcdefg".toCharArray()) {
- for (BoundType type : BoundType.values()) {
- long count = BstRangeOps.totalInRange(
- countAggregate, GeneralRange.downTo(Ordering.natural(), c, type), ROOT);
- char d = c;
- if (type == BoundType.OPEN) {
- d++;
- }
- assertEquals(MODEL.tailSet(d).size(), count);
- }
- }
- }
-
- public void testCountInRangeUpperBound() {
- for (char c : "abcdefg".toCharArray()) {
- for (BoundType type : BoundType.values()) {
- long count = BstRangeOps.totalInRange(
- countAggregate, GeneralRange.upTo(Ordering.natural(), c, type), ROOT);
- char d = c;
- if (type == BoundType.CLOSED) {
- d++;
- }
- assertEquals(MODEL.headSet(d).size(), count);
- }
- }
- }
-
- public void testCountInRangeBothBounds() {
- String chars = "abcdefg";
- for (int i = 0; i < chars.length(); i++) {
- for (BoundType lb : BoundType.values()) {
- for (int j = i; j < chars.length(); j++) {
- for (BoundType ub : BoundType.values()) {
- if (i == j && lb == BoundType.OPEN && ub == BoundType.OPEN) {
- continue;
- }
- long count = BstRangeOps.totalInRange(countAggregate, GeneralRange.range(
- Ordering.natural(), chars.charAt(i), lb, chars.charAt(j), ub), ROOT);
- char lo = chars.charAt(i);
- if (lb == BoundType.OPEN) {
- lo++;
- }
- char hi = chars.charAt(j);
- if (ub == BoundType.CLOSED) {
- hi++;
- }
- if (lo > hi) {
- lo = hi;
- }
- assertEquals(MODEL.subSet(lo, hi).size(), count);
- }
- }
- }
- }
- }
-
- public void testCountInRangeAll() {
- assertEquals(MODEL.size(), BstRangeOps.totalInRange(
- countAggregate, GeneralRange.<Character>all(Ordering.natural()), ROOT));
- }
-
- public void testCountInRangeEmpty() {
- SimpleNode empty = null;
- GeneralRange<Character> range = GeneralRange.all(Ordering.natural());
- assertEquals(0, BstRangeOps.totalInRange(countAggregate, range, empty));
- }
-
- public void testClearRangeLowerBound() {
- // d
- // / \
- // b f
- // / / \
- // a e g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- assertInOrderTraversalIs(d, "abdefg");
- GeneralRange<Character> range1 = GeneralRange.downTo(Ordering.natural(), 'f', CLOSED);
- testTraversalAfterClearingRangeIs(d, range1, "abde");
-
- GeneralRange<Character> range2 = GeneralRange.downTo(Ordering.natural(), 'f', OPEN);
- testTraversalAfterClearingRangeIs(d, range2, "abdef");
-
- GeneralRange<Character> range3 = GeneralRange.downTo(Ordering.natural(), 'a', CLOSED);
- testTraversalAfterClearingRangeIs(d, range3, "");
-
- GeneralRange<Character> range4 = GeneralRange.downTo(Ordering.natural(), 'a', OPEN);
- testTraversalAfterClearingRangeIs(d, range4, "a");
-
- GeneralRange<Character> range5 = GeneralRange.downTo(Ordering.natural(), 'c', OPEN);
- testTraversalAfterClearingRangeIs(d, range5, "ab");
-
- GeneralRange<Character> range6 = GeneralRange.downTo(Ordering.natural(), 'c', CLOSED);
- testTraversalAfterClearingRangeIs(d, range6, "ab");
- }
-
- public void testClearRangeUpperBound() {
- // d
- // / \
- // b f
- // / / \
- // a e g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode b = new SimpleNode('b', a, null);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- assertInOrderTraversalIs(d, "abdefg");
- GeneralRange<Character> range1 = GeneralRange.upTo(Ordering.natural(), 'f', CLOSED);
- testTraversalAfterClearingRangeIs(d, range1, "g");
-
- GeneralRange<Character> range2 = GeneralRange.upTo(Ordering.natural(), 'f', OPEN);
- testTraversalAfterClearingRangeIs(d, range2, "fg");
-
- GeneralRange<Character> range3 = GeneralRange.upTo(Ordering.natural(), 'a', CLOSED);
- testTraversalAfterClearingRangeIs(d, range3, "bdefg");
-
- GeneralRange<Character> range4 = GeneralRange.upTo(Ordering.natural(), 'a', OPEN);
- testTraversalAfterClearingRangeIs(d, range4, "abdefg");
-
- GeneralRange<Character> range5 = GeneralRange.upTo(Ordering.natural(), 'c', OPEN);
- testTraversalAfterClearingRangeIs(d, range5, "defg");
-
- GeneralRange<Character> range6 = GeneralRange.upTo(Ordering.natural(), 'c', CLOSED);
- testTraversalAfterClearingRangeIs(d, range6, "defg");
- }
-
- public void testClearRangeDoublyBounded() {
- // d
- // / \
- // b f
- // / \ / \
- // a c e g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', a, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- GeneralRange<Character> range1 =
- GeneralRange.range(Ordering.natural(), 'c', OPEN, 'f', CLOSED);
- testTraversalAfterClearingRangeIs(d, range1, "abcg");
-
- GeneralRange<Character> range2 =
- GeneralRange.range(Ordering.natural(), 'a', CLOSED, 'h', OPEN);
- testTraversalAfterClearingRangeIs(d, range2, "");
-
- }
-
- public void testClearRangeAll() {
- // d
- // / \
- // b f
- // / \ / \
- // a c e g
- SimpleNode a = new SimpleNode('a', null, null);
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', a, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- testTraversalAfterClearingRangeIs(d, GeneralRange.<Character>all(Ordering.natural()), "");
- }
-
- private void testTraversalAfterClearingRangeIs(
- SimpleNode d, GeneralRange<Character> range, String expected) {
- assertInOrderTraversalIs(
- BstRangeOps.minusRange(range, balancePolicy, nodeFactory, d), expected);
- }
-
- public void testLeftmostPathAll() {
- // d
- // / \
- // b f
- // \ / \
- // c e g
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- GeneralRange<Character> range1 = GeneralRange.all(Ordering.natural());
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, LEFT, pathFactory, d)))
- .hasContentsInOrder(b, d);
-
- assertNull(BstRangeOps.furthestPath(range1, LEFT, pathFactory, null));
- }
-
- public void testLeftmostPathDownTo() {
- // d
- // / \
- // b f
- // \ / \
- // c e g
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- GeneralRange<Character> range1 = GeneralRange.downTo(Ordering.natural(), 'd', OPEN);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, LEFT, pathFactory, d)))
- .hasContentsInOrder(e, f, d);
-
- GeneralRange<Character> range2 = GeneralRange.downTo(Ordering.natural(), 'd', CLOSED);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range2, LEFT, pathFactory, d)))
- .hasContentsInOrder(d);
-
- GeneralRange<Character> range3 = GeneralRange.downTo(Ordering.natural(), 'a', CLOSED);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range3, LEFT, pathFactory, d)))
- .hasContentsInOrder(b, d);
-
- GeneralRange<Character> range4 = GeneralRange.downTo(Ordering.natural(), 'h', CLOSED);
- assertNull(BstRangeOps.furthestPath(range4, LEFT, pathFactory, d));
- }
-
- public void testLeftmostPathUpTo() {
- // d
- // / \
- // b f
- // \ / \
- // c e g
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- GeneralRange<Character> range1 = GeneralRange.upTo(Ordering.natural(), 'd', OPEN);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, LEFT, pathFactory, d)))
- .hasContentsInOrder(b, d);
-
- GeneralRange<Character> range2 = GeneralRange.upTo(Ordering.natural(), 'd', CLOSED);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range2, LEFT, pathFactory, d)))
- .hasContentsInOrder(b, d);
-
- GeneralRange<Character> range3 = GeneralRange.upTo(Ordering.natural(), 'a', CLOSED);
- assertNull(BstRangeOps.furthestPath(range3, LEFT, pathFactory, d));
- }
-
- public void testRightmostPathAll() {
- // d
- // / \
- // b f
- // \ / \
- // c e g
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- GeneralRange<Character> range1 = GeneralRange.all(Ordering.natural());
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, RIGHT, pathFactory, d)))
- .hasContentsInOrder(g, f, d);
-
- assertNull(BstRangeOps.furthestPath(range1, RIGHT, pathFactory, null));
- }
-
- public void testRightmostPathDownTo() {
- // d
- // / \
- // b f
- // \ / \
- // c e g
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- GeneralRange<Character> range1 = GeneralRange.downTo(Ordering.natural(), 'd', OPEN);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, RIGHT, pathFactory, d)))
- .hasContentsInOrder(g, f, d);
-
- GeneralRange<Character> range2 = GeneralRange.downTo(Ordering.natural(), 'd', CLOSED);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range2, RIGHT, pathFactory, d)))
- .hasContentsInOrder(g, f, d);
-
- GeneralRange<Character> range3 = GeneralRange.downTo(Ordering.natural(), 'a', CLOSED);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range3, RIGHT, pathFactory, d)))
- .hasContentsInOrder(g, f, d);
-
- GeneralRange<Character> range4 = GeneralRange.downTo(Ordering.natural(), 'h', CLOSED);
- assertNull(BstRangeOps.furthestPath(range4, RIGHT, pathFactory, d));
- }
-
- public void testRightmostPathUpTo() {
- // d
- // / \
- // b f
- // \ / \
- // c e g
- SimpleNode c = new SimpleNode('c', null, null);
- SimpleNode b = new SimpleNode('b', null, c);
- SimpleNode e = new SimpleNode('e', null, null);
- SimpleNode g = new SimpleNode('g', null, null);
- SimpleNode f = new SimpleNode('f', e, g);
- SimpleNode d = new SimpleNode('d', b, f);
-
- GeneralRange<Character> range1 = GeneralRange.upTo(Ordering.natural(), 'd', OPEN);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range1, RIGHT, pathFactory, d)))
- .hasContentsInOrder(c, b, d);
-
- GeneralRange<Character> range2 = GeneralRange.upTo(Ordering.natural(), 'd', CLOSED);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range2, RIGHT, pathFactory, d)))
- .hasContentsInOrder(d);
-
- GeneralRange<Character> range3 = GeneralRange.upTo(Ordering.natural(), 'a', CLOSED);
- assertNull(BstRangeOps.furthestPath(range3, RIGHT, pathFactory, d));
-
- GeneralRange<Character> range4 = GeneralRange.upTo(Ordering.natural(), 'h', CLOSED);
- ASSERT.that(pathToList(BstRangeOps.furthestPath(range4, RIGHT, pathFactory, d)))
- .hasContentsInOrder(g, f, d);
- }
-
- @GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
- defaultNullPointerTester().testAllPublicStaticMethods(BstRangeOps.class);
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/BstTesting.java b/guava-tests/test/com/google/common/collect/BstTesting.java
deleted file mode 100644
index af929b2..0000000
--- a/guava-tests/test/com/google/common/collect/BstTesting.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.BstSide.LEFT;
-import static com.google.common.collect.BstSide.RIGHT;
-import static junit.framework.Assert.assertEquals;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Objects;
-import com.google.common.testing.NullPointerTester;
-
-import java.util.List;
-
-import javax.annotation.Nullable;
-
-/**
- * Testing classes and utilities to be used in tests of the binary search tree framework.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-public class BstTesting {
- static final class SimpleNode extends BstNode<Character, SimpleNode> {
- SimpleNode(Character key, @Nullable SimpleNode left, @Nullable SimpleNode right) {
- super(key, left, right);
- }
-
- @Override
- public String toString() {
- return getKey().toString();
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (obj instanceof SimpleNode) {
- SimpleNode node = (SimpleNode) obj;
- return getKey().equals(node.getKey())
- && Objects.equal(childOrNull(LEFT), node.childOrNull(LEFT))
- && Objects.equal(childOrNull(RIGHT), node.childOrNull(RIGHT));
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(getKey(), childOrNull(LEFT), childOrNull(RIGHT));
- }
- }
-
- static final BstNodeFactory<SimpleNode> nodeFactory = new BstNodeFactory<SimpleNode>() {
- @Override
- public SimpleNode createNode(
- SimpleNode source, @Nullable SimpleNode left, @Nullable SimpleNode right) {
- return new SimpleNode(source.getKey(), left, right);
- }
- };
-
- static final BstBalancePolicy<SimpleNode> balancePolicy = new BstBalancePolicy<SimpleNode>() {
- @Override
- public SimpleNode balance(BstNodeFactory<SimpleNode> nodeFactory, SimpleNode source,
- @Nullable SimpleNode left, @Nullable SimpleNode right) {
- return checkNotNull(nodeFactory).createNode(source, left, right);
- }
-
- @Nullable
- @Override
- public SimpleNode combine(BstNodeFactory<SimpleNode> nodeFactory, @Nullable SimpleNode left,
- @Nullable SimpleNode right) {
- // Shove right into the rightmost position in the left tree.
- if (left == null) {
- return right;
- } else if (right == null) {
- return left;
- } else if (left.hasChild(RIGHT)) {
- return nodeFactory.createNode(
- left, left.childOrNull(LEFT), combine(nodeFactory, left.childOrNull(RIGHT), right));
- } else {
- return nodeFactory.createNode(left, left.childOrNull(LEFT), right);
- }
- }
- };
-
- static final BstPathFactory<SimpleNode, BstInOrderPath<SimpleNode>> pathFactory =
- BstInOrderPath.inOrderFactory();
-
- // A direct, if dumb, way to count total nodes in a tree.
- static final BstAggregate<SimpleNode> countAggregate = new BstAggregate<SimpleNode>() {
- @Override
- public int entryValue(SimpleNode entry) {
- return 1;
- }
-
- @Override
- public long treeValue(@Nullable SimpleNode tree) {
- if (tree == null) {
- return 0;
- } else {
- return 1 + treeValue(tree.childOrNull(LEFT)) + treeValue(tree.childOrNull(RIGHT));
- }
- }
- };
-
- static <P extends BstPath<SimpleNode, P>> List<SimpleNode> pathToList(P path) {
- List<SimpleNode> list = Lists.newArrayList();
- for (; path != null; path = path.prefixOrNull()) {
- list.add(path.getTip());
- }
- return list;
- }
-
- static <N extends BstNode<?, N>, P extends BstPath<N, P>> P extension(
- BstPathFactory<N, P> factory, N root, BstSide... sides) {
- P path = factory.initialPath(root);
- for (BstSide side : sides) {
- path = factory.extension(path, side);
- }
- return path;
- }
-
- static void assertInOrderTraversalIs(@Nullable SimpleNode root, String order) {
- if (root == null) {
- assertEquals("", order);
- } else {
- BstInOrderPath<SimpleNode> path = pathFactory.initialPath(root);
- while (path.getTip().hasChild(LEFT)) {
- path = pathFactory.extension(path, LEFT);
- }
- assertEquals(order.charAt(0), path
- .getTip()
- .getKey()
- .charValue());
- int i;
- for (i = 1; path.hasNext(RIGHT); i++) {
- path = path.next(RIGHT);
- assertEquals(order.charAt(i), path
- .getTip()
- .getKey()
- .charValue());
- }
- assertEquals(i, order.length());
- }
- }
-
- @GwtIncompatible("NullPointerTester")
- static NullPointerTester defaultNullPointerTester() {
- NullPointerTester tester = new NullPointerTester();
- SimpleNode node = new SimpleNode('a', null, null);
- tester.setDefault(BstNode.class, node);
- tester.setDefault(BstSide.class, LEFT);
- tester.setDefault(BstNodeFactory.class, nodeFactory);
- tester.setDefault(BstBalancePolicy.class, balancePolicy);
- tester.setDefault(BstPathFactory.class, pathFactory);
- tester.setDefault(BstPath.class, pathFactory.initialPath(node));
- tester.setDefault(BstInOrderPath.class, pathFactory.initialPath(node));
- tester.setDefault(Object.class, 'a');
- tester.setDefault(GeneralRange.class, GeneralRange.all(Ordering.natural()));
- tester.setDefault(BstAggregate.class, countAggregate);
- BstModifier<Character, SimpleNode> modifier = new BstModifier<Character, SimpleNode>() {
- @Nullable
- @Override
- public BstModificationResult<SimpleNode> modify(
- Character key, @Nullable SimpleNode originalEntry) {
- return BstModificationResult.identity(originalEntry);
- }
- };
- tester.setDefault(
- BstModificationResult.class, BstModificationResult.<SimpleNode>identity(null));
- tester.setDefault(BstModifier.class, modifier);
- tester.setDefault(
- BstMutationRule.class, BstMutationRule.createRule(modifier, balancePolicy, nodeFactory));
- return tester;
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/CollectionBenchmarkSampleData.java b/guava-tests/test/com/google/common/collect/CollectionBenchmarkSampleData.java
new file mode 100644
index 0000000..5e6473b
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/CollectionBenchmarkSampleData.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.primitives.Ints;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Package up sample data for common collections benchmarking.
+ *
+ * @author Nicholaus Shupe
+ */
+class CollectionBenchmarkSampleData {
+ private final boolean isUserTypeFast;
+ private final SpecialRandom random;
+ private final double hitRate;
+ private final int size;
+
+ private final Set<Element> valuesInSet;
+ private final Element[] queries;
+
+ CollectionBenchmarkSampleData(int size) {
+ this(true, new SpecialRandom(), 1.0, size);
+ }
+
+ CollectionBenchmarkSampleData(
+ boolean isUserTypeFast,
+ SpecialRandom random,
+ double hitRate,
+ int size) {
+ this.isUserTypeFast = isUserTypeFast;
+ this.random = checkNotNull(random);
+ this.hitRate = hitRate;
+ this.size = size;
+
+ this.valuesInSet = createData();
+ this.queries = createQueries(valuesInSet, 1024);
+ }
+
+ Set<Element> getValuesInSet() {
+ return valuesInSet;
+ }
+
+ Element[] getQueries() {
+ return queries;
+ }
+
+ private Element[] createQueries(Set<Element> elementsInSet, int numQueries) {
+ List<Element> queryList = Lists.newArrayListWithCapacity(numQueries);
+
+ int numGoodQueries = (int) (numQueries * hitRate + 0.5);
+
+ // add good queries
+ int size = elementsInSet.size();
+ if (size > 0) {
+ int minCopiesOfEachGoodQuery = numGoodQueries / size;
+ int extras = numGoodQueries % size;
+
+ for (int i = 0; i < minCopiesOfEachGoodQuery; i++) {
+ queryList.addAll(elementsInSet);
+ }
+ List<Element> tmp = Lists.newArrayList(elementsInSet);
+ Collections.shuffle(tmp, random);
+ queryList.addAll(tmp.subList(0, extras));
+ }
+
+ // now add bad queries
+ while (queryList.size() < numQueries) {
+ Element candidate = newElement();
+ if (!elementsInSet.contains(candidate)) {
+ queryList.add(candidate);
+ }
+ }
+ Collections.shuffle(queryList, random);
+ return queryList.toArray(new Element[0]);
+ }
+
+ private Set<Element> createData() {
+ Set<Element> set = Sets.newHashSetWithExpectedSize(size);
+ while (set.size() < size) {
+ set.add(newElement());
+ }
+ return set;
+ }
+
+ private Element newElement() {
+ int value = random.nextInt();
+ return isUserTypeFast
+ ? new Element(value)
+ : new SlowElement(value);
+ }
+
+ static class Element implements Comparable<Element> {
+ final int hash;
+ Element(int hash) {
+ this.hash = hash;
+ }
+ @Override public boolean equals(Object obj) {
+ return this == obj
+ || (obj instanceof Element && ((Element) obj).hash == hash);
+ }
+ @Override public int hashCode() {
+ return hash;
+ }
+ @Override
+ public int compareTo(Element that) {
+ return Ints.compare(hash, that.hash);
+ }
+ @Override public String toString() {
+ return String.valueOf(hash);
+ }
+ }
+
+ static class SlowElement extends Element {
+ SlowElement(int hash) {
+ super(hash);
+ }
+ @Override public boolean equals(Object obj) {
+ return slowItDown() != 1 && super.equals(obj);
+ }
+ @Override public int hashCode() {
+ return slowItDown() + hash;
+ }
+ @Override public int compareTo(Element e) {
+ int x = slowItDown();
+ return x + super.compareTo(e) - x; // silly attempt to prevent opt
+ }
+ static int slowItDown() {
+ int result = 0;
+ for (int i = 1; i <= 1000; i++) {
+ result += i;
+ }
+ return result;
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/Collections2Test.java b/guava-tests/test/com/google/common/collect/Collections2Test.java
index e17cd05..d9763da 100644
--- a/guava-tests/test/com/google/common/collect/Collections2Test.java
+++ b/guava-tests/test/com/google/common/collect/Collections2Test.java
@@ -16,11 +16,13 @@
package com.google.common.collect;
+import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.newLinkedList;
import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static java.util.Collections.nCopies;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -38,7 +40,9 @@ import junit.framework.TestSuite;
import java.util.Collection;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
+import java.util.NoSuchElementException;
/**
* Tests for {@link Collections2}.
@@ -192,140 +196,6 @@ public class Collections2Test extends TestCase {
.createTestSuite();
}
- public abstract static class FilterChangeTest extends TestCase {
- protected abstract <E> List<E> newList();
-
- public void testFilterIllegalAdd() {
- List<String> unfiltered = newList();
- Collection<String> filtered
- = Collections2.filter(unfiltered, NOT_YYY_ZZZ);
- filtered.add("a");
- filtered.add("b");
- ASSERT.that(filtered).hasContentsInOrder("a", "b");
-
- try {
- filtered.add("yyy");
- fail();
- } catch (IllegalArgumentException expected) {}
-
- try {
- filtered.addAll(asList("c", "zzz", "d"));
- fail();
- } catch (IllegalArgumentException expected) {}
-
- ASSERT.that(filtered).hasContentsInOrder("a", "b");
- }
-
- public void testFilterChangeUnfiltered() {
- List<String> unfiltered = newList();
- Collection<String> filtered
- = Collections2.filter(unfiltered, NOT_YYY_ZZZ);
-
- unfiltered.add("a");
- unfiltered.add("yyy");
- unfiltered.add("b");
- ASSERT.that(unfiltered).hasContentsInOrder("a", "yyy", "b");
- ASSERT.that(filtered).hasContentsInOrder("a", "b");
-
- unfiltered.remove("a");
- ASSERT.that(unfiltered).hasContentsInOrder("yyy", "b");
- ASSERT.that(filtered).hasContentsInOrder("b");
-
- unfiltered.clear();
- ASSERT.that(unfiltered).isEmpty();
- ASSERT.that(filtered).isEmpty();
-
- unfiltered.add("yyy");
- ASSERT.that(unfiltered).hasContentsInOrder("yyy");
- ASSERT.that(filtered).isEmpty();
- filtered.clear();
- ASSERT.that(unfiltered).hasContentsInOrder("yyy");
- ASSERT.that(filtered).isEmpty();
-
- unfiltered.clear();
- filtered.clear();
- ASSERT.that(unfiltered).isEmpty();
- ASSERT.that(filtered).isEmpty();
-
- unfiltered.add("a");
- ASSERT.that(unfiltered).hasContentsInOrder("a");
- ASSERT.that(filtered).hasContentsInOrder("a");
- filtered.clear();
- ASSERT.that(unfiltered).isEmpty();
- ASSERT.that(filtered).isEmpty();
-
- unfiltered.clear();
- Collections.addAll(unfiltered,
- "a", "b", "yyy", "zzz", "c", "d", "yyy", "zzz");
- ASSERT.that(unfiltered).hasContentsInOrder(
- "a", "b", "yyy", "zzz", "c", "d", "yyy", "zzz");
- ASSERT.that(filtered).hasContentsInOrder("a", "b", "c", "d");
- filtered.clear();
- ASSERT.that(unfiltered).hasContentsInOrder("yyy", "zzz", "yyy", "zzz");
- ASSERT.that(filtered).isEmpty();
- }
-
- public void testFilterChangeFiltered() {
- List<String> unfiltered = newList();
- Collection<String> filtered
- = Collections2.filter(unfiltered, NOT_YYY_ZZZ);
-
- unfiltered.add("a");
- unfiltered.add("yyy");
- filtered.add("b");
- ASSERT.that(unfiltered).hasContentsInOrder("a", "yyy", "b");
- ASSERT.that(filtered).hasContentsInOrder("a", "b");
-
- filtered.remove("a");
- ASSERT.that(unfiltered).hasContentsInOrder("yyy", "b");
- ASSERT.that(filtered).hasContentsInOrder("b");
-
- filtered.clear();
- ASSERT.that(unfiltered).hasContentsInOrder("yyy");
- ASSERT.that(filtered);
- }
-
- public void testFilterFiltered() {
- List<String> unfiltered = newList();
- Collection<String> filtered = Collections2.filter(
- Collections2.filter(unfiltered, LENGTH_1), STARTS_WITH_VOWEL);
- unfiltered.add("a");
- unfiltered.add("b");
- unfiltered.add("apple");
- unfiltered.add("banana");
- unfiltered.add("e");
- ASSERT.that(filtered).hasContentsInOrder("a", "e");
- ASSERT.that(unfiltered).hasContentsInOrder("a", "b", "apple", "banana", "e");
-
- try {
- filtered.add("d");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- filtered.add("egg");
- fail();
- } catch (IllegalArgumentException expected) {}
- ASSERT.that(filtered).hasContentsInOrder("a", "e");
- ASSERT.that(unfiltered).hasContentsInOrder("a", "b", "apple", "banana", "e");
-
- filtered.clear();
- ASSERT.that(filtered).isEmpty();
- ASSERT.that(unfiltered).hasContentsInOrder("b", "apple", "banana");
- }
- }
-
- public static class ArrayListFilterChangeTest extends FilterChangeTest {
- @Override protected <E> List<E> newList() {
- return Lists.newArrayList();
- }
- }
-
- public static class LinkedListFilterChangeTest extends FilterChangeTest {
- @Override protected <E> List<E> newList() {
- return Lists.newLinkedList();
- }
- }
-
private static final Function<String, String> REMOVE_FIRST_CHAR
= new Function<String, String>() {
@Override
@@ -349,7 +219,7 @@ public class Collections2Test extends TestCase {
})
.named("Collections2.transform")
.withFeatures(
- CollectionFeature.REMOVE_OPERATIONS,
+ CollectionFeature.SUPPORTS_REMOVE,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionFeature.KNOWN_ORDER,
CollectionSize.ANY)
@@ -357,8 +227,277 @@ public class Collections2Test extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Collections2.class);
}
+
+ public void testOrderedPermutationSetEmpty() {
+ List<Integer> list = newArrayList();
+ Collection<List<Integer>> permutationSet =
+ Collections2.orderedPermutations(list);
+
+ assertEquals(1, permutationSet.size());
+ ASSERT.that(permutationSet).has().item(list);
+
+ Iterator<List<Integer>> permutations = permutationSet.iterator();
+
+ assertNextPermutation(Lists.<Integer>newArrayList(), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testOrderedPermutationSetOneElement() {
+ List<Integer> list = newArrayList(1);
+ Iterator<List<Integer>> permutations =
+ Collections2.orderedPermutations(list).iterator();
+
+ assertNextPermutation(newArrayList(1), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testOrderedPermutationSetThreeElements() {
+ List<String> list = newArrayList("b", "a", "c");
+ Iterator<List<String>> permutations =
+ Collections2.orderedPermutations(list).iterator();
+
+ assertNextPermutation(newArrayList("a", "b", "c"), permutations);
+ assertNextPermutation(newArrayList("a", "c", "b"), permutations);
+ assertNextPermutation(newArrayList("b", "a", "c"), permutations);
+ assertNextPermutation(newArrayList("b", "c", "a"), permutations);
+ assertNextPermutation(newArrayList("c", "a", "b"), permutations);
+ assertNextPermutation(newArrayList("c", "b", "a"), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testOrderedPermutationSetRepeatedElements() {
+ List<Integer> list = newArrayList(1, 1, 2, 2);
+ Iterator<List<Integer>> permutations =
+ Collections2.orderedPermutations(list, Ordering.natural()).iterator();
+
+ assertNextPermutation(newArrayList(1, 1, 2, 2), permutations);
+ assertNextPermutation(newArrayList(1, 2, 1, 2), permutations);
+ assertNextPermutation(newArrayList(1, 2, 2, 1), permutations);
+ assertNextPermutation(newArrayList(2, 1, 1, 2), permutations);
+ assertNextPermutation(newArrayList(2, 1, 2, 1), permutations);
+ assertNextPermutation(newArrayList(2, 2, 1, 1), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testOrderedPermutationSetRepeatedElementsSize() {
+ List<Integer> list = newArrayList(1, 1, 1, 1, 2, 2, 3);
+ Collection<List<Integer>> permutations =
+ Collections2.orderedPermutations(list, Ordering.natural());
+
+ assertPermutationsCount(105, permutations);
+ }
+
+ public void testOrderedPermutationSetSizeOverflow() {
+ // 12 elements won't overflow
+ assertEquals(479001600 /*12!*/, Collections2.orderedPermutations(
+ newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)).size());
+ // 13 elements overflow an int
+ assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations(
+ newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)).size());
+ // 21 elements overflow a long
+ assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations(
+ newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21)).size());
+
+ // Almost force an overflow in the binomial coefficient calculation
+ assertEquals(1391975640 /*C(34,14)*/, Collections2.orderedPermutations(
+ concat(nCopies(20, 1), nCopies(14, 2))).size());
+ // Do force an overflow in the binomial coefficient calculation
+ assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations(
+ concat(nCopies(21, 1), nCopies(14, 2))).size());
+ }
+
+ public void testOrderedPermutationSetContains() {
+ List<Integer> list = newArrayList(3, 2, 1);
+ Collection<List<Integer>> permutationSet =
+ Collections2.orderedPermutations(list);
+
+ assertTrue(permutationSet.contains(newArrayList(1, 2, 3)));
+ assertTrue(permutationSet.contains(newArrayList(2, 3, 1)));
+ assertFalse(permutationSet.contains(newArrayList(1, 2)));
+ assertFalse(permutationSet.contains(newArrayList(1, 1, 2, 3)));
+ assertFalse(permutationSet.contains(newArrayList(1, 2, 3, 4)));
+ assertFalse(permutationSet.contains(null));
+ }
+
+ public void testPermutationSetEmpty() {
+ Collection<List<Integer>> permutationSet =
+ Collections2.permutations(Collections.<Integer>emptyList());
+
+ assertEquals(1, permutationSet.size());
+ assertTrue(permutationSet.contains(Collections.<Integer> emptyList()));
+
+ Iterator<List<Integer>> permutations = permutationSet.iterator();
+ assertNextPermutation(Collections.<Integer> emptyList(), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testPermutationSetOneElement() {
+ Iterator<List<Integer>> permutations =
+ Collections2.permutations(Collections.<Integer> singletonList(1))
+ .iterator();
+ assertNextPermutation(newArrayList(1), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testPermutationSetTwoElements() {
+ Iterator<List<Integer>> permutations = Collections2.permutations(
+ newArrayList(1, 2)).iterator();
+ assertNextPermutation(newArrayList(1, 2), permutations);
+ assertNextPermutation(newArrayList(2, 1), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testPermutationSetThreeElements() {
+ Iterator<List<Integer>> permutations = Collections2.permutations(
+ newArrayList(1, 2, 3)).iterator();
+ assertNextPermutation(newArrayList(1, 2, 3), permutations);
+ assertNextPermutation(newArrayList(1, 3, 2), permutations);
+ assertNextPermutation(newArrayList(3, 1, 2), permutations);
+
+ assertNextPermutation(newArrayList(3, 2, 1), permutations);
+ assertNextPermutation(newArrayList(2, 3, 1), permutations);
+ assertNextPermutation(newArrayList(2, 1, 3), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testPermutationSetThreeElementsOutOfOrder() {
+ Iterator<List<Integer>> permutations = Collections2.permutations(
+ newArrayList(3, 2, 1)).iterator();
+ assertNextPermutation(newArrayList(3, 2, 1), permutations);
+ assertNextPermutation(newArrayList(3, 1, 2), permutations);
+ assertNextPermutation(newArrayList(1, 3, 2), permutations);
+
+ assertNextPermutation(newArrayList(1, 2, 3), permutations);
+ assertNextPermutation(newArrayList(2, 1, 3), permutations);
+ assertNextPermutation(newArrayList(2, 3, 1), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testPermutationSetThreeRepeatedElements() {
+ Iterator<List<Integer>> permutations = Collections2.permutations(
+ newArrayList(1, 1, 2)).iterator();
+ assertNextPermutation(newArrayList(1, 1, 2), permutations);
+ assertNextPermutation(newArrayList(1, 2, 1), permutations);
+ assertNextPermutation(newArrayList(2, 1, 1), permutations);
+ assertNextPermutation(newArrayList(2, 1, 1), permutations);
+ assertNextPermutation(newArrayList(1, 2, 1), permutations);
+ assertNextPermutation(newArrayList(1, 1, 2), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testPermutationSetFourElements() {
+ Iterator<List<Integer>> permutations = Collections2.permutations(
+ newArrayList(1, 2, 3, 4)).iterator();
+ assertNextPermutation(newArrayList(1, 2, 3, 4), permutations);
+ assertNextPermutation(newArrayList(1, 2, 4, 3), permutations);
+ assertNextPermutation(newArrayList(1, 4, 2, 3), permutations);
+ assertNextPermutation(newArrayList(4, 1, 2, 3), permutations);
+
+ assertNextPermutation(newArrayList(4, 1, 3, 2), permutations);
+ assertNextPermutation(newArrayList(1, 4, 3, 2), permutations);
+ assertNextPermutation(newArrayList(1, 3, 4, 2), permutations);
+ assertNextPermutation(newArrayList(1, 3, 2, 4), permutations);
+
+ assertNextPermutation(newArrayList(3, 1, 2, 4), permutations);
+ assertNextPermutation(newArrayList(3, 1, 4, 2), permutations);
+ assertNextPermutation(newArrayList(3, 4, 1, 2), permutations);
+ assertNextPermutation(newArrayList(4, 3, 1, 2), permutations);
+
+ assertNextPermutation(newArrayList(4, 3, 2, 1), permutations);
+ assertNextPermutation(newArrayList(3, 4, 2, 1), permutations);
+ assertNextPermutation(newArrayList(3, 2, 4, 1), permutations);
+ assertNextPermutation(newArrayList(3, 2, 1, 4), permutations);
+
+ assertNextPermutation(newArrayList(2, 3, 1, 4), permutations);
+ assertNextPermutation(newArrayList(2, 3, 4, 1), permutations);
+ assertNextPermutation(newArrayList(2, 4, 3, 1), permutations);
+ assertNextPermutation(newArrayList(4, 2, 3, 1), permutations);
+
+ assertNextPermutation(newArrayList(4, 2, 1, 3), permutations);
+ assertNextPermutation(newArrayList(2, 4, 1, 3), permutations);
+ assertNextPermutation(newArrayList(2, 1, 4, 3), permutations);
+ assertNextPermutation(newArrayList(2, 1, 3, 4), permutations);
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testPermutationSetSize() {
+ assertPermutationsCount(1,
+ Collections2.permutations(Collections.<Integer>emptyList()));
+ assertPermutationsCount(1, Collections2.permutations(newArrayList(1)));
+ assertPermutationsCount(2, Collections2.permutations(newArrayList(1, 2)));
+ assertPermutationsCount(6,
+ Collections2.permutations(newArrayList(1, 2, 3)));
+ assertPermutationsCount(5040,
+ Collections2.permutations(newArrayList(1, 2, 3, 4, 5, 6, 7)));
+ assertPermutationsCount(40320,
+ Collections2.permutations(newArrayList(1, 2, 3, 4, 5, 6, 7, 8)));
+ }
+
+ public void testPermutationSetSizeOverflow() {
+ // 13 elements overflow an int
+ assertEquals(Integer.MAX_VALUE, Collections2.permutations(newArrayList(
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)).size());
+ // 21 elements overflow a long
+ assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations(
+ newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20)).size());
+ assertEquals(Integer.MAX_VALUE, Collections2.orderedPermutations(
+ newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21)).size());
+ }
+
+ public void testPermutationSetContains() {
+ List<Integer> list = newArrayList(3, 2, 1);
+ Collection<List<Integer>> permutationSet =
+ Collections2.permutations(list);
+
+ assertTrue(permutationSet.contains(newArrayList(1, 2, 3)));
+ assertTrue(permutationSet.contains(newArrayList(2, 3, 1)));
+ assertFalse(permutationSet.contains(newArrayList(1, 2)));
+ assertFalse(permutationSet.contains(newArrayList(1, 1, 2, 3)));
+ assertFalse(permutationSet.contains(newArrayList(1, 2, 3, 4)));
+ assertFalse(permutationSet.contains(null));
+ }
+
+ private <T> void assertNextPermutation(List<T> expectedPermutation,
+ Iterator<List<T>> permutations) {
+ assertTrue("Expected another permutation, but there was none.",
+ permutations.hasNext());
+ assertEquals(expectedPermutation, permutations.next());
+ }
+
+ private <T> void assertNoMorePermutations(
+ Iterator<List<T>> permutations) {
+ assertFalse("Expected no more permutations, but there was one.",
+ permutations.hasNext());
+ try {
+ permutations.next();
+ fail("Expected NoSuchElementException.");
+ } catch (NoSuchElementException expected) {}
+ }
+
+ private <T> void assertPermutationsCount(int expected,
+ Collection<List<T>> permutationSet) {
+ assertEquals(expected, permutationSet.size());
+ Iterator<List<T>> permutations = permutationSet.iterator();
+ for (int i = 0; i < expected; i++) {
+ assertTrue(permutations.hasNext());
+ permutations.next();
+ }
+ assertNoMorePermutations(permutations);
+ }
+
+ public void testToStringImplWithNullEntries() throws Exception {
+ List<String> list = Lists.newArrayList();
+ list.add("foo");
+ list.add(null);
+
+ assertEquals(list.toString(), Collections2.toStringImpl(list));
+ }
+
}
diff --git a/guava-tests/test/com/google/common/collect/ComparisonChainTest.java b/guava-tests/test/com/google/common/collect/ComparisonChainTest.java
index c0ddcd5..0a75056 100644
--- a/guava-tests/test/com/google/common/collect/ComparisonChainTest.java
+++ b/guava-tests/test/com/google/common/collect/ComparisonChainTest.java
@@ -58,7 +58,7 @@ public class ComparisonChainTest extends TestCase {
assertEquals(0, ComparisonChain.start()
.compare(1, 1)
.compare(1L, 1L)
- .compare(true, true)
+ .compareFalseFirst(true, true)
.compare(1.0, 1.0)
.compare(1.0f, 1.0f)
.compare("a", "a", Ordering.usingToString())
@@ -86,4 +86,26 @@ public class ComparisonChainTest extends TestCase {
.compare(DONT_COMPARE_ME, DONT_COMPARE_ME)
.result() < 0);
}
+
+ public void testCompareFalseFirst() {
+ assertTrue(ComparisonChain.start().compareFalseFirst(true, true).result() == 0);
+ assertTrue(ComparisonChain.start().compareFalseFirst(true, false).result() > 0);
+ assertTrue(ComparisonChain.start().compareFalseFirst(false, true).result() < 0);
+ assertTrue(ComparisonChain.start().compareFalseFirst(false, false).result() == 0);
+ }
+
+ public void testCompareTrueFirst() {
+ assertTrue(ComparisonChain.start().compareTrueFirst(true, true).result() == 0);
+ assertTrue(ComparisonChain.start().compareTrueFirst(true, false).result() < 0);
+ assertTrue(ComparisonChain.start().compareTrueFirst(false, true).result() > 0);
+ assertTrue(ComparisonChain.start().compareTrueFirst(false, false).result() == 0);
+ }
+
+ @SuppressWarnings("deprecation") // test of a deprecated method
+ public void testCompareBooleans() {
+ assertTrue(ComparisonChain.start().compare(true, true).result() == 0);
+ assertTrue(ComparisonChain.start().compare(true, false).result() > 0);
+ assertTrue(ComparisonChain.start().compare(false, true).result() < 0);
+ assertTrue(ComparisonChain.start().compare(false, false).result() == 0);
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java b/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java
index 8a96b62..dba499c 100644
--- a/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/ConcurrentHashMultisetTest.java
@@ -16,7 +16,6 @@
package com.google.common.collect;
-import static com.google.common.collect.MapMakerInternalMap.Strength.SOFT;
import static com.google.common.collect.MapMakerInternalMap.Strength.STRONG;
import static com.google.common.collect.MapMakerInternalMap.Strength.WEAK;
import static com.google.common.collect.testing.IteratorFeature.SUPPORTS_REMOVE;
@@ -26,13 +25,19 @@ import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.isA;
-import com.google.common.base.Equivalences;
+import com.google.common.base.Equivalence;
import com.google.common.collect.MapMaker.RemovalListener;
import com.google.common.collect.MapMaker.RemovalNotification;
import com.google.common.collect.Multiset.Entry;
import com.google.common.collect.testing.IteratorTester;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringMultisetGenerator;
+import junit.framework.Test;
import junit.framework.TestCase;
+import junit.framework.TestSuite;
import org.easymock.EasyMock;
@@ -49,6 +54,28 @@ import java.util.concurrent.atomic.AtomicInteger;
* @author mike nonemacher
*/
public class ConcurrentHashMultisetTest extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(MultisetTestSuiteBuilder.using(concurrentMultisetGenerator())
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.GENERAL_PURPOSE,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("ConcurrentHashMultiset")
+ .createTestSuite());
+ suite.addTestSuite(ConcurrentHashMultisetTest.class);
+ return suite;
+ }
+
+ private static TestStringMultisetGenerator concurrentMultisetGenerator() {
+ return new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ return ConcurrentHashMultiset.create(asList(elements));
+ }
+ };
+ }
+
private static final String KEY = "puppies";
ConcurrentMap<String, AtomicInteger> backingMap;
@@ -343,10 +370,6 @@ public class ConcurrentHashMultisetTest extends TestCase {
public void testIdentityKeyEquality_strongKeys() {
testIdentityKeyEquality(STRONG);
}
-
- public void testIdentityKeyEquality_softKeys() {
- testIdentityKeyEquality(SOFT);
- }
public void testIdentityKeyEquality_weakKeys() {
testIdentityKeyEquality(WEAK);
@@ -357,7 +380,7 @@ public class ConcurrentHashMultisetTest extends TestCase {
MapMaker mapMaker = new MapMaker()
.setKeyStrength(keyStrength)
- .keyEquivalence(Equivalences.identity());
+ .keyEquivalence(Equivalence.identity());
ConcurrentHashMultiset<String> multiset =
ConcurrentHashMultiset.create(mapMaker);
@@ -387,10 +410,6 @@ public class ConcurrentHashMultisetTest extends TestCase {
testLogicalKeyEquality(STRONG);
}
- public void testLogicalKeyEquality_softKeys() {
- testLogicalKeyEquality(SOFT);
- }
-
public void testLogicalKeyEquality_weakKeys() {
testLogicalKeyEquality(WEAK);
}
@@ -400,7 +419,7 @@ public class ConcurrentHashMultisetTest extends TestCase {
MapMaker mapMaker = new MapMaker()
.setKeyStrength(keyStrength)
- .keyEquivalence(Equivalences.equals());
+ .keyEquivalence(Equivalence.equals());
ConcurrentHashMultiset<String> multiset =
ConcurrentHashMultiset.create(mapMaker);
@@ -446,7 +465,7 @@ public class ConcurrentHashMultisetTest extends TestCase {
public void testSerializationWithMapMaker_preservesIdentityKeyEquivalence() {
MapMaker mapMaker = new MapMaker()
- .keyEquivalence(Equivalences.identity());
+ .keyEquivalence(Equivalence.identity());
ConcurrentHashMultiset<String> multiset =
ConcurrentHashMultiset.create(mapMaker);
diff --git a/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java b/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java
index 4f02c13..cb22217 100644
--- a/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ConstrainedBiMapTest.java
@@ -16,28 +16,106 @@
package com.google.common.collect;
+import static com.google.common.base.Preconditions.checkArgument;
+
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.MapConstraintsTest.TestKeyException;
import com.google.common.collect.MapConstraintsTest.TestValueException;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringBiMapGenerator;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.Map.Entry;
/**
* Tests for {@link MapConstraints#constrainedBiMap}.
*
* @author Jared Levy
+ * @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
-public class ConstrainedBiMapTest extends AbstractBiMapTest {
+public class ConstrainedBiMapTest extends TestCase {
- private static final Integer TEST_KEY = 42;
+ private static final String TEST_KEY = "42";
private static final String TEST_VALUE = "test";
- private static final MapConstraint<Integer, String> TEST_CONSTRAINT
- = new TestConstraint();
+ private static final MapConstraint<String, String> TEST_CONSTRAINT = new TestConstraint();
+
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(BiMapTestSuiteBuilder
+ .using(new ConstrainedBiMapGenerator())
+ .named("Maps.constrainedBiMap[HashBiMap]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.REJECTS_DUPLICATES_AT_CREATION)
+ .createTestSuite());
+ suite.addTestSuite(ConstrainedBiMapTest.class);
+ return suite;
+ }
+
+ public void testPutWithForbiddenKeyForbiddenValue() {
+ BiMap<String, String> map = MapConstraints.constrainedBiMap(
+ HashBiMap.<String, String> create(),
+ TEST_CONSTRAINT);
+ try {
+ map.put(TEST_KEY, TEST_VALUE);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // success
+ }
+ }
+
+ public void testPutWithForbiddenKeyAllowedValue() {
+ BiMap<String, String> map = MapConstraints.constrainedBiMap(
+ HashBiMap.<String, String> create(),
+ TEST_CONSTRAINT);
+ try {
+ map.put(TEST_KEY, "allowed");
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // success
+ }
+ }
- private static final class TestConstraint
- implements MapConstraint<Integer, String> {
+ public void testPutWithAllowedKeyForbiddenValue() {
+ BiMap<String, String> map = MapConstraints.constrainedBiMap(
+ HashBiMap.<String, String> create(),
+ TEST_CONSTRAINT);
+ try {
+ map.put("allowed", TEST_VALUE);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // success
+ }
+ }
+
+ public static final class ConstrainedBiMapGenerator extends TestStringBiMapGenerator {
@Override
- public void checkKeyValue(Integer key, String value) {
+ protected BiMap<String, String> create(Entry<String, String>[] entries) {
+ BiMap<String, String> bimap = MapConstraints.constrainedBiMap(
+ HashBiMap.<String, String> create(),
+ TEST_CONSTRAINT);
+ for (Entry<String, String> entry : entries) {
+ checkArgument(!bimap.containsKey(entry.getKey()));
+ bimap.put(entry.getKey(), entry.getValue());
+ }
+ return bimap;
+ }
+ }
+
+ private static final class TestConstraint implements MapConstraint<String, String> {
+ @Override
+ public void checkKeyValue(String key, String value) {
if (TEST_KEY.equals(key)) {
throw new TestKeyException();
}
@@ -45,24 +123,7 @@ public class ConstrainedBiMapTest extends AbstractBiMapTest {
throw new TestValueException();
}
}
- private static final long serialVersionUID = 0;
- }
- @Override protected BiMap<Integer, String> create() {
- return MapConstraints.constrainedBiMap(
- HashBiMap.<Integer, String>create(), TEST_CONSTRAINT);
+ private static final long serialVersionUID = 0;
}
-
- // not serializable
- @GwtIncompatible("SerializableTester")
- @Override
- public void testSerialization() {}
-
- @GwtIncompatible("SerializableTester")
- @Override
- public void testSerializationWithInverseEqual() {}
-
- @GwtIncompatible("SerializableTester")
- @Override
- public void testSerializationWithInverseSame() {}
}
diff --git a/guava-tests/test/com/google/common/collect/ConstraintsTest.java b/guava-tests/test/com/google/common/collect/ConstraintsTest.java
index 64dbc8a..b7b6dbb 100644
--- a/guava-tests/test/com/google/common/collect/ConstraintsTest.java
+++ b/guava-tests/test/com/google/common/collect/ConstraintsTest.java
@@ -17,7 +17,7 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -80,8 +80,9 @@ public class ConstraintsTest extends TestCase {
constrained.add("qux");
constrained.addAll(asList("cat", "dog"));
/* equals and hashCode aren't defined for Collection */
- ASSERT.that(collection).hasContentsInOrder("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog");
- ASSERT.that(constrained).hasContentsInOrder("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog");
+ ASSERT.that(collection).has().allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder();
+ ASSERT.that(constrained).has()
+ .allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder();
}
public void testConstrainedCollectionIllegal() {
@@ -96,8 +97,8 @@ public class ConstraintsTest extends TestCase {
constrained.addAll(asList("baz", TEST_ELEMENT));
fail("TestElementException expected");
} catch (TestElementException expected) {}
- ASSERT.that(constrained).hasContentsInOrder("foo", "bar");
- ASSERT.that(collection).hasContentsInOrder("foo", "bar");
+ ASSERT.that(constrained).has().allOf("foo", "bar").inOrder();
+ ASSERT.that(collection).has().allOf("foo", "bar").inOrder();
}
public void testConstrainedSetLegal() {
@@ -110,8 +111,9 @@ public class ConstraintsTest extends TestCase {
assertTrue(constrained.equals(set));
assertEquals(set.toString(), constrained.toString());
assertEquals(set.hashCode(), constrained.hashCode());
- ASSERT.that(set).hasContentsInOrder("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog");
- ASSERT.that(constrained).hasContentsInOrder("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog");
+ ASSERT.that(set).has().allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder();
+ ASSERT.that(constrained).has()
+ .allOf("foo", "bar", TEST_ELEMENT, "qux", "cat", "dog").inOrder();
}
public void testConstrainedSetIllegal() {
@@ -125,8 +127,8 @@ public class ConstraintsTest extends TestCase {
constrained.addAll(asList("baz", TEST_ELEMENT));
fail("TestElementException expected");
} catch (TestElementException expected) {}
- ASSERT.that(constrained).hasContentsInOrder("foo", "bar");
- ASSERT.that(set).hasContentsInOrder("foo", "bar");
+ ASSERT.that(constrained).has().allOf("foo", "bar").inOrder();
+ ASSERT.that(set).has().allOf("foo", "bar").inOrder();
}
public void testConstrainedSortedSetLegal() {
@@ -140,8 +142,9 @@ public class ConstraintsTest extends TestCase {
assertTrue(constrained.equals(sortedSet));
assertEquals(sortedSet.toString(), constrained.toString());
assertEquals(sortedSet.hashCode(), constrained.hashCode());
- ASSERT.that(sortedSet).hasContentsInOrder("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT);
- ASSERT.that(constrained).hasContentsInOrder("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT);
+ ASSERT.that(sortedSet).has().allOf("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT).inOrder();
+ ASSERT.that(constrained).has()
+ .allOf("bar", "cat", "dog", "foo", "qux", TEST_ELEMENT).inOrder();
assertNull(constrained.comparator());
assertEquals("bar", constrained.first());
assertEquals(TEST_ELEMENT, constrained.last());
@@ -171,8 +174,8 @@ public class ConstraintsTest extends TestCase {
constrained.addAll(asList("baz", TEST_ELEMENT));
fail("TestElementException expected");
} catch (TestElementException expected) {}
- ASSERT.that(constrained).hasContentsInOrder("bar", "foo");
- ASSERT.that(sortedSet).hasContentsInOrder("bar", "foo");
+ ASSERT.that(constrained).has().allOf("bar", "foo").inOrder();
+ ASSERT.that(sortedSet).has().allOf("bar", "foo").inOrder();
}
public void testConstrainedListLegal() {
@@ -189,18 +192,18 @@ public class ConstraintsTest extends TestCase {
assertTrue(constrained.equals(list));
assertEquals(list.toString(), constrained.toString());
assertEquals(list.hashCode(), constrained.hashCode());
- ASSERT.that(list).hasContentsInOrder(
- "foo", "cow", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog");
- ASSERT.that(constrained).hasContentsInOrder(
- "foo", "cow", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog");
+ ASSERT.that(list).has().allOf(
+ "foo", "cow", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder();
+ ASSERT.that(constrained).has().allOf(
+ "foo", "cow", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder();
ListIterator<String> iterator = constrained.listIterator();
iterator.next();
iterator.set("sun");
constrained.listIterator(2).add("sky");
- ASSERT.that(list).hasContentsInOrder(
- "sun", "cow", "sky", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog");
- ASSERT.that(constrained).hasContentsInOrder(
- "sun", "cow", "sky", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog");
+ ASSERT.that(list).has().allOf(
+ "sun", "cow", "sky", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder();
+ ASSERT.that(constrained).has().allOf(
+ "sun", "cow", "sky", "baz", TEST_ELEMENT, "box", "fan", "qux", "cat", "dog").inOrder();
assertTrue(constrained instanceof RandomAccess);
}
@@ -257,8 +260,8 @@ public class ConstraintsTest extends TestCase {
constrained.addAll(1, asList("baz", TEST_ELEMENT));
fail("TestElementException expected");
} catch (TestElementException expected) {}
- ASSERT.that(constrained).hasContentsInOrder("foo", "bar");
- ASSERT.that(list).hasContentsInOrder("foo", "bar");
+ ASSERT.that(constrained).has().allOf("foo", "bar").inOrder();
+ ASSERT.that(list).has().allOf("foo", "bar").inOrder();
}
public void testConstrainedMultisetLegal() {
@@ -273,15 +276,15 @@ public class ConstraintsTest extends TestCase {
assertTrue(constrained.equals(multiset));
assertEquals(multiset.toString(), constrained.toString());
assertEquals(multiset.hashCode(), constrained.hashCode());
- ASSERT.that(multiset).hasContentsAnyOrder(
+ ASSERT.that(multiset).has().allOf(
"foo", "bar", TEST_ELEMENT, "qux", "cat", "dog", "cow", "cow");
- ASSERT.that(constrained).hasContentsAnyOrder(
+ ASSERT.that(constrained).has().allOf(
"foo", "bar", TEST_ELEMENT, "qux", "cat", "dog", "cow", "cow");
assertEquals(1, constrained.count("foo"));
assertEquals(1, constrained.remove("foo", 3));
assertEquals(2, constrained.setCount("cow", 0));
- ASSERT.that(multiset).hasContentsAnyOrder("bar", TEST_ELEMENT, "qux", "cat", "dog");
- ASSERT.that(constrained).hasContentsAnyOrder("bar", TEST_ELEMENT, "qux", "cat", "dog");
+ ASSERT.that(multiset).has().allOf("bar", TEST_ELEMENT, "qux", "cat", "dog");
+ ASSERT.that(constrained).has().allOf("bar", TEST_ELEMENT, "qux", "cat", "dog");
}
public void testConstrainedMultisetIllegal() {
@@ -300,8 +303,8 @@ public class ConstraintsTest extends TestCase {
constrained.addAll(asList("baz", TEST_ELEMENT));
fail("TestElementException expected");
} catch (TestElementException expected) {}
- ASSERT.that(constrained).hasContentsAnyOrder("foo", "bar");
- ASSERT.that(multiset).hasContentsAnyOrder("foo", "bar");
+ ASSERT.that(constrained).has().allOf("foo", "bar");
+ ASSERT.that(multiset).has().allOf("foo", "bar");
}
public void testNefariousAddAll() {
@@ -310,8 +313,8 @@ public class ConstraintsTest extends TestCase {
list, TEST_CONSTRAINT);
Collection<String> onceIterable = onceIterableCollection("baz");
constrained.addAll(onceIterable);
- ASSERT.that(constrained).hasContentsInOrder("foo", "bar", "baz");
- ASSERT.that(list).hasContentsInOrder("foo", "bar", "baz");
+ ASSERT.that(constrained).has().allOf("foo", "bar", "baz").inOrder();
+ ASSERT.that(list).has().allOf("foo", "bar", "baz").inOrder();
}
/**
diff --git a/guava-tests/test/com/google/common/collect/ContiguousSetNonGwtTest.java b/guava-tests/test/com/google/common/collect/ContiguousSetNonGwtTest.java
deleted file mode 100644
index d36e471..0000000
--- a/guava-tests/test/com/google/common/collect/ContiguousSetNonGwtTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.collect.DiscreteDomains.integers;
-
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.testers.SetHashCodeTester;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * @author Gregory Kick
- */
-public class ContiguousSetNonGwtTest extends TestCase {
- public static class BuiltTests extends TestCase {
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTest(
- SetTestSuiteBuilder
- .using(
- new TestIntegerSetGenerator() {
- @Override
- protected Set<Integer> create(Integer[] elements) {
- // reject duplicates at creation, just so that I can use
- // that SetFeature below, which stops a test from running
- // that doesn't work. hack!
- SortedSet<Integer> set = new TreeSet<Integer>();
- Collections.addAll(set, elements);
- checkArgument(set.size() == elements.length);
- return Ranges.closed(set.first(), set.last()).asSet(integers());
- }
- })
- .withFeatures(
- CollectionSize.ONE,
- CollectionSize.SEVERAL,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES,
- CollectionFeature.NON_STANDARD_TOSTRING,
- CollectionFeature.RESTRICTS_ELEMENTS,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION)
- .suppressing(SetHashCodeTester.getHashCodeMethods())
- .named("DiscreteRange.asSet, closed")
- .createTestSuite());
-
- return suite;
- }
- }
-
- abstract static class TestIntegerSetGenerator implements TestSetGenerator<Integer> {
- @Override public SampleElements<Integer> samples() {
- return new SampleElements<Integer>(1, 2, 3, 4, 5);
- }
-
- @Override public Set<Integer> create(Object... elements) {
- Integer[] array = new Integer[elements.length];
- int i = 0;
- for (Object e : elements) {
- array[i++] = (Integer) e;
- }
- return create(array);
- }
-
- protected abstract Set<Integer> create(Integer[] elements);
-
- @Override public Integer[] createArray(int length) {
- return new Integer[length];
- }
-
- @Override public List<Integer> order(List<Integer> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- }
-
- public void testNothing() {
- /*
- * It's a warning if a TestCase subclass contains no tests, so we add one.
- * Alternatively, we could stop extending TestCase, but I worry that someone
- * will add a test in the future and not realize that it's being ignored.
- */
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ContiguousSetTest.java b/guava-tests/test/com/google/common/collect/ContiguousSetTest.java
index 6909f7a..373cf64 100644
--- a/guava-tests/test/com/google/common/collect/ContiguousSetTest.java
+++ b/guava-tests/test/com/google/common/collect/ContiguousSetTest.java
@@ -18,16 +18,30 @@ package com.google.common.collect;
import static com.google.common.collect.BoundType.CLOSED;
import static com.google.common.collect.BoundType.OPEN;
-import static com.google.common.collect.DiscreteDomains.integers;
+import static com.google.common.collect.DiscreteDomain.integers;
+import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES;
+import static com.google.common.collect.testing.features.CollectionFeature.KNOWN_ORDER;
+import static com.google.common.collect.testing.features.CollectionFeature.NON_STANDARD_TOSTRING;
+import static com.google.common.collect.testing.features.CollectionFeature.RESTRICTS_ELEMENTS;
+import static com.google.common.collect.testing.testers.NavigableSetNavigationTester.getHoleMethods;
import static com.google.common.testing.SerializableTester.reserialize;
import static com.google.common.testing.SerializableTester.reserializeAndAssert;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.google.SetGenerators.ContiguousSetDescendingGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ContiguousSetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ContiguousSetHeadsetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ContiguousSetSubsetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ContiguousSetTailsetGenerator;
import com.google.common.testing.EqualsTester;
+import junit.framework.Test;
import junit.framework.TestCase;
+import junit.framework.TestSuite;
import java.util.Set;
@@ -61,32 +75,35 @@ public class ContiguousSetTest extends TestCase {
public void testEquals() {
new EqualsTester()
.addEqualityGroup(
- Ranges.closed(1, 3).asSet(integers()),
- Ranges.closedOpen(1, 4).asSet(integers()),
- Ranges.openClosed(0, 3).asSet(integers()),
- Ranges.open(0, 4).asSet(integers()),
- Ranges.closed(1, 3).asSet(NOT_EQUAL_TO_INTEGERS),
- Ranges.closedOpen(1, 4).asSet(NOT_EQUAL_TO_INTEGERS),
- Ranges.openClosed(0, 3).asSet(NOT_EQUAL_TO_INTEGERS),
- Ranges.open(0, 4).asSet(NOT_EQUAL_TO_INTEGERS),
+ ContiguousSet.create(Range.closed(1, 3), integers()),
+ ContiguousSet.create(Range.closedOpen(1, 4), integers()),
+ ContiguousSet.create(Range.openClosed(0, 3), integers()),
+ ContiguousSet.create(Range.open(0, 4), integers()),
+ ContiguousSet.create(Range.closed(1, 3), NOT_EQUAL_TO_INTEGERS),
+ ContiguousSet.create(Range.closedOpen(1, 4), NOT_EQUAL_TO_INTEGERS),
+ ContiguousSet.create(Range.openClosed(0, 3), NOT_EQUAL_TO_INTEGERS),
+ ContiguousSet.create(Range.open(0, 4), NOT_EQUAL_TO_INTEGERS),
ImmutableSortedSet.of(1, 2, 3))
.testEquals();
// not testing hashCode for these because it takes forever to compute
- assertEquals(Ranges.closed(Integer.MIN_VALUE, Integer.MAX_VALUE).asSet(integers()),
- Ranges.<Integer>all().asSet(integers()));
- assertEquals(Ranges.closed(Integer.MIN_VALUE, Integer.MAX_VALUE).asSet(integers()),
- Ranges.atLeast(Integer.MIN_VALUE).asSet(integers()));
- assertEquals(Ranges.closed(Integer.MIN_VALUE, Integer.MAX_VALUE).asSet(integers()),
- Ranges.atMost(Integer.MAX_VALUE).asSet(integers()));
+ assertEquals(
+ ContiguousSet.create(Range.closed(Integer.MIN_VALUE, Integer.MAX_VALUE), integers()),
+ ContiguousSet.create(Range.<Integer>all(), integers()));
+ assertEquals(
+ ContiguousSet.create(Range.closed(Integer.MIN_VALUE, Integer.MAX_VALUE), integers()),
+ ContiguousSet.create(Range.atLeast(Integer.MIN_VALUE), integers()));
+ assertEquals(
+ ContiguousSet.create(Range.closed(Integer.MIN_VALUE, Integer.MAX_VALUE), integers()),
+ ContiguousSet.create(Range.atMost(Integer.MAX_VALUE), integers()));
}
@GwtIncompatible("SerializableTester")
public void testSerialization() {
- ContiguousSet<Integer> empty = Ranges.closedOpen(1, 1).asSet(integers());
+ ContiguousSet<Integer> empty = ContiguousSet.create(Range.closedOpen(1, 1), integers());
assertTrue(empty instanceof EmptyContiguousSet);
reserializeAndAssert(empty);
- ContiguousSet<Integer> regular = Ranges.closed(1, 3).asSet(integers());
+ ContiguousSet<Integer> regular = ContiguousSet.create(Range.closed(1, 3), integers());
assertTrue(regular instanceof RegularContiguousSet);
reserializeAndAssert(regular);
@@ -94,7 +111,7 @@ public class ContiguousSetTest extends TestCase {
* Make sure that we're using RegularContiguousSet.SerializedForm and not
* ImmutableSet.SerializedForm, which would be enormous.
*/
- ContiguousSet<Integer> enormous = Ranges.<Integer>all().asSet(integers());
+ ContiguousSet<Integer> enormous = ContiguousSet.create(Range.<Integer>all(), integers());
assertTrue(enormous instanceof RegularContiguousSet);
// We can't use reserializeAndAssert because it calls hashCode, which is enormously slow.
ContiguousSet<Integer> enormousReserialized = reserialize(enormous);
@@ -102,66 +119,58 @@ public class ContiguousSetTest extends TestCase {
}
public void testHeadSet() {
- ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
ASSERT.that(set.headSet(1)).isEmpty();
- ASSERT.that(set.headSet(2)).hasContentsInOrder(1);
- ASSERT.that(set.headSet(3)).hasContentsInOrder(1, 2);
- ASSERT.that(set.headSet(4)).hasContentsInOrder(1, 2, 3);
- ASSERT.that(set.headSet(Integer.MAX_VALUE)).hasContentsInOrder(1, 2, 3);
- ASSERT.that(set.headSet(1, true)).hasContentsInOrder(1);
- ASSERT.that(set.headSet(2, true)).hasContentsInOrder(1, 2);
- ASSERT.that(set.headSet(3, true)).hasContentsInOrder(1, 2, 3);
- ASSERT.that(set.headSet(4, true)).hasContentsInOrder(1, 2, 3);
- ASSERT.that(set.headSet(Integer.MAX_VALUE, true)).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(set.headSet(2)).has().item(1);
+ ASSERT.that(set.headSet(3)).has().allOf(1, 2).inOrder();
+ ASSERT.that(set.headSet(4)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.headSet(Integer.MAX_VALUE)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.headSet(1, true)).has().item(1);
+ ASSERT.that(set.headSet(2, true)).has().allOf(1, 2).inOrder();
+ ASSERT.that(set.headSet(3, true)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.headSet(4, true)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.headSet(Integer.MAX_VALUE, true)).has().allOf(1, 2, 3).inOrder();
}
public void testHeadSet_tooSmall() {
- ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
- try {
- set.headSet(0);
- fail();
- } catch (IllegalArgumentException e) {}
+ ASSERT.that(ContiguousSet.create(Range.closed(1, 3), integers()).headSet(0)).isEmpty();
}
public void testTailSet() {
- ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
- ASSERT.that(set.tailSet(Integer.MIN_VALUE)).hasContentsInOrder(1, 2, 3);
- ASSERT.that(set.tailSet(1)).hasContentsInOrder(1, 2, 3);
- ASSERT.that(set.tailSet(2)).hasContentsInOrder(2, 3);
- ASSERT.that(set.tailSet(3)).hasContentsInOrder(3);
- ASSERT.that(set.tailSet(Integer.MIN_VALUE, false)).hasContentsInOrder(1, 2, 3);
- ASSERT.that(set.tailSet(1, false)).hasContentsInOrder(2, 3);
- ASSERT.that(set.tailSet(2, false)).hasContentsInOrder(3);
+ ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
+ ASSERT.that(set.tailSet(Integer.MIN_VALUE)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.tailSet(1)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.tailSet(2)).has().allOf(2, 3).inOrder();
+ ASSERT.that(set.tailSet(3)).has().item(3);
+ ASSERT.that(set.tailSet(Integer.MIN_VALUE, false)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.tailSet(1, false)).has().allOf(2, 3).inOrder();
+ ASSERT.that(set.tailSet(2, false)).has().item(3);
ASSERT.that(set.tailSet(3, false)).isEmpty();
}
public void testTailSet_tooLarge() {
- ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
- try {
- set.tailSet(4);
- fail();
- } catch (IllegalArgumentException e) {}
+ ASSERT.that(ContiguousSet.create(Range.closed(1, 3), integers()).tailSet(4)).isEmpty();
}
public void testSubSet() {
- ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
- ASSERT.that(set.subSet(1, 4)).hasContentsInOrder(1, 2, 3);
- ASSERT.that(set.subSet(2, 4)).hasContentsInOrder(2, 3);
- ASSERT.that(set.subSet(3, 4)).hasContentsInOrder(3);
+ ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
+ ASSERT.that(set.subSet(1, 4)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.subSet(2, 4)).has().allOf(2, 3).inOrder();
+ ASSERT.that(set.subSet(3, 4)).has().item(3);
ASSERT.that(set.subSet(3, 3)).isEmpty();
- ASSERT.that(set.subSet(2, 3)).hasContentsInOrder(2);
- ASSERT.that(set.subSet(1, 3)).hasContentsInOrder(1, 2);
- ASSERT.that(set.subSet(1, 2)).hasContentsInOrder(1);
+ ASSERT.that(set.subSet(2, 3)).has().item(2);
+ ASSERT.that(set.subSet(1, 3)).has().allOf(1, 2).inOrder();
+ ASSERT.that(set.subSet(1, 2)).has().item(1);
ASSERT.that(set.subSet(2, 2)).isEmpty();
- ASSERT.that(set.subSet(Integer.MIN_VALUE, Integer.MAX_VALUE)).hasContentsInOrder(1, 2, 3);
- ASSERT.that(set.subSet(1, true, 3, true)).hasContentsInOrder(1, 2, 3);
- ASSERT.that(set.subSet(1, false, 3, true)).hasContentsInOrder(2, 3);
- ASSERT.that(set.subSet(1, true, 3, false)).hasContentsInOrder(1, 2);
- ASSERT.that(set.subSet(1, false, 3, false)).hasContentsInOrder(2);
+ ASSERT.that(set.subSet(Integer.MIN_VALUE, Integer.MAX_VALUE)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.subSet(1, true, 3, true)).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(set.subSet(1, false, 3, true)).has().allOf(2, 3).inOrder();
+ ASSERT.that(set.subSet(1, true, 3, false)).has().allOf(1, 2).inOrder();
+ ASSERT.that(set.subSet(1, false, 3, false)).has().item(2);
}
public void testSubSet_outOfOrder() {
- ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
try {
set.subSet(3, 2);
fail();
@@ -169,41 +178,35 @@ public class ContiguousSetTest extends TestCase {
}
public void testSubSet_tooLarge() {
- ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
- try {
- set.subSet(4, 6);
- fail();
- } catch (IllegalArgumentException expected) {}
+ ASSERT.that(ContiguousSet.create(Range.closed(1, 3), integers()).subSet(4, 6)).isEmpty();
}
public void testSubSet_tooSmall() {
- ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
- try {
- set.subSet(-1, 0);
- fail();
- } catch (IllegalArgumentException expected) {}
+ ASSERT.that(ContiguousSet.create(Range.closed(1, 3), integers()).subSet(-1, 0)).isEmpty();
}
public void testFirst() {
- assertEquals(1, Ranges.closed(1, 3).asSet(integers()).first().intValue());
- assertEquals(1, Ranges.open(0, 4).asSet(integers()).first().intValue());
- assertEquals(Integer.MIN_VALUE, Ranges.<Integer>all().asSet(integers()).first().intValue());
+ assertEquals(1, ContiguousSet.create(Range.closed(1, 3), integers()).first().intValue());
+ assertEquals(1, ContiguousSet.create(Range.open(0, 4), integers()).first().intValue());
+ assertEquals(Integer.MIN_VALUE,
+ ContiguousSet.create(Range.<Integer>all(), integers()).first().intValue());
}
public void testLast() {
- assertEquals(3, Ranges.closed(1, 3).asSet(integers()).last().intValue());
- assertEquals(3, Ranges.open(0, 4).asSet(integers()).last().intValue());
- assertEquals(Integer.MAX_VALUE, Ranges.<Integer>all().asSet(integers()).last().intValue());
+ assertEquals(3, ContiguousSet.create(Range.closed(1, 3), integers()).last().intValue());
+ assertEquals(3, ContiguousSet.create(Range.open(0, 4), integers()).last().intValue());
+ assertEquals(Integer.MAX_VALUE,
+ ContiguousSet.create(Range.<Integer>all(), integers()).last().intValue());
}
public void testContains() {
- ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
assertFalse(set.contains(0));
assertTrue(set.contains(1));
assertTrue(set.contains(2));
assertTrue(set.contains(3));
assertFalse(set.contains(4));
- set = Ranges.open(0, 4).asSet(integers());
+ set = ContiguousSet.create(Range.open(0, 4), integers());
assertFalse(set.contains(0));
assertTrue(set.contains(1));
assertTrue(set.contains(2));
@@ -213,7 +216,7 @@ public class ContiguousSetTest extends TestCase {
}
public void testContainsAll() {
- ImmutableSortedSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
+ ImmutableSortedSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
for (Set<Integer> subset : Sets.powerSet(ImmutableSet.of(1, 2, 3))) {
assertTrue(set.containsAll(subset));
}
@@ -224,55 +227,117 @@ public class ContiguousSetTest extends TestCase {
}
public void testRange() {
- assertEquals(Ranges.closed(1, 3), Ranges.closed(1, 3).asSet(integers()).range());
- assertEquals(Ranges.closed(1, 3), Ranges.closedOpen(1, 4).asSet(integers()).range());
- assertEquals(Ranges.closed(1, 3), Ranges.open(0, 4).asSet(integers()).range());
- assertEquals(Ranges.closed(1, 3), Ranges.openClosed(0, 3).asSet(integers()).range());
-
- assertEquals(Ranges.openClosed(0, 3),
- Ranges.closed(1, 3).asSet(integers()).range(OPEN, CLOSED));
- assertEquals(Ranges.openClosed(0, 3),
- Ranges.closedOpen(1, 4).asSet(integers()).range(OPEN, CLOSED));
- assertEquals(Ranges.openClosed(0, 3), Ranges.open(0, 4).asSet(integers()).range(OPEN, CLOSED));
- assertEquals(Ranges.openClosed(0, 3),
- Ranges.openClosed(0, 3).asSet(integers()).range(OPEN, CLOSED));
-
- assertEquals(Ranges.open(0, 4), Ranges.closed(1, 3).asSet(integers()).range(OPEN, OPEN));
- assertEquals(Ranges.open(0, 4), Ranges.closedOpen(1, 4).asSet(integers()).range(OPEN, OPEN));
- assertEquals(Ranges.open(0, 4), Ranges.open(0, 4).asSet(integers()).range(OPEN, OPEN));
- assertEquals(Ranges.open(0, 4), Ranges.openClosed(0, 3).asSet(integers()).range(OPEN, OPEN));
-
- assertEquals(Ranges.closedOpen(1, 4),
- Ranges.closed(1, 3).asSet(integers()).range(CLOSED, OPEN));
- assertEquals(Ranges.closedOpen(1, 4),
- Ranges.closedOpen(1, 4).asSet(integers()).range(CLOSED, OPEN));
- assertEquals(Ranges.closedOpen(1, 4), Ranges.open(0, 4).asSet(integers()).range(CLOSED, OPEN));
- assertEquals(Ranges.closedOpen(1, 4),
- Ranges.openClosed(0, 3).asSet(integers()).range(CLOSED, OPEN));
+ assertEquals(Range.closed(1, 3),
+ ContiguousSet.create(Range.closed(1, 3), integers()).range());
+ assertEquals(Range.closed(1, 3),
+ ContiguousSet.create(Range.closedOpen(1, 4), integers()).range());
+ assertEquals(Range.closed(1, 3), ContiguousSet.create(Range.open(0, 4), integers()).range());
+ assertEquals(Range.closed(1, 3),
+ ContiguousSet.create(Range.openClosed(0, 3), integers()).range());
+
+ assertEquals(Range.openClosed(0, 3),
+ ContiguousSet.create(Range.closed(1, 3), integers()).range(OPEN, CLOSED));
+ assertEquals(Range.openClosed(0, 3),
+ ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(OPEN, CLOSED));
+ assertEquals(Range.openClosed(0, 3),
+ ContiguousSet.create(Range.open(0, 4), integers()).range(OPEN, CLOSED));
+ assertEquals(Range.openClosed(0, 3),
+ ContiguousSet.create(Range.openClosed(0, 3), integers()).range(OPEN, CLOSED));
+
+ assertEquals(Range.open(0, 4),
+ ContiguousSet.create(Range.closed(1, 3), integers()).range(OPEN, OPEN));
+ assertEquals(Range.open(0, 4),
+ ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(OPEN, OPEN));
+ assertEquals(Range.open(0, 4),
+ ContiguousSet.create(Range.open(0, 4), integers()).range(OPEN, OPEN));
+ assertEquals(Range.open(0, 4),
+ ContiguousSet.create(Range.openClosed(0, 3), integers()).range(OPEN, OPEN));
+
+ assertEquals(Range.closedOpen(1, 4),
+ ContiguousSet.create(Range.closed(1, 3), integers()).range(CLOSED, OPEN));
+ assertEquals(Range.closedOpen(1, 4),
+ ContiguousSet.create(Range.closedOpen(1, 4), integers()).range(CLOSED, OPEN));
+ assertEquals(Range.closedOpen(1, 4),
+ ContiguousSet.create(Range.open(0, 4), integers()).range(CLOSED, OPEN));
+ assertEquals(Range.closedOpen(1, 4),
+ ContiguousSet.create(Range.openClosed(0, 3), integers()).range(CLOSED, OPEN));
}
- public void testRange_unboundedRanges() {
- assertEquals(Ranges.closed(Integer.MIN_VALUE, Integer.MAX_VALUE),
- Ranges.<Integer>all().asSet(integers()).range());
- assertEquals(Ranges.atLeast(Integer.MIN_VALUE),
- Ranges.<Integer>all().asSet(integers()).range(CLOSED, OPEN));
- assertEquals(Ranges.all(), Ranges.<Integer>all().asSet(integers()).range(OPEN, OPEN));
- assertEquals(Ranges.atMost(Integer.MAX_VALUE),
- Ranges.<Integer>all().asSet(integers()).range(OPEN, CLOSED));
+ public void testRange_unboundedRange() {
+ assertEquals(Range.closed(Integer.MIN_VALUE, Integer.MAX_VALUE),
+ ContiguousSet.create(Range.<Integer>all(), integers()).range());
+ assertEquals(Range.atLeast(Integer.MIN_VALUE),
+ ContiguousSet.create(Range.<Integer>all(), integers()).range(CLOSED, OPEN));
+ assertEquals(Range.all(),
+ ContiguousSet.create(Range.<Integer>all(), integers()).range(OPEN, OPEN));
+ assertEquals(Range.atMost(Integer.MAX_VALUE),
+ ContiguousSet.create(Range.<Integer>all(), integers()).range(OPEN, CLOSED));
}
public void testIntersection_empty() {
- ContiguousSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
- ContiguousSet<Integer> emptySet = Ranges.closedOpen(2,2).asSet(integers());
+ ContiguousSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
+ ContiguousSet<Integer> emptySet = ContiguousSet.create(Range.closedOpen(2, 2), integers());
assertEquals(ImmutableSet.of(), set.intersection(emptySet));
assertEquals(ImmutableSet.of(), emptySet.intersection(set));
- assertEquals(ImmutableSet.of(), Ranges.closed(-5, -1).asSet(integers()).intersection(
- Ranges.open(3, 64).asSet(integers())));
+ assertEquals(ImmutableSet.of(),
+ ContiguousSet.create(Range.closed(-5, -1), integers()).intersection(
+ ContiguousSet.create(Range.open(3, 64), integers())));
}
public void testIntersection() {
- ContiguousSet<Integer> set = Ranges.closed(1, 3).asSet(integers());
- assertEquals(ImmutableSet.of(1, 2, 3), Ranges.open(-1, 4).asSet(integers()).intersection(set));
- assertEquals(ImmutableSet.of(1, 2, 3), set.intersection(Ranges.open(-1, 4).asSet(integers())));
+ ContiguousSet<Integer> set = ContiguousSet.create(Range.closed(1, 3), integers());
+ assertEquals(ImmutableSet.of(1, 2, 3),
+ ContiguousSet.create(Range.open(-1, 4), integers()).intersection(set));
+ assertEquals(ImmutableSet.of(1, 2, 3),
+ set.intersection(ContiguousSet.create(Range.open(-1, 4), integers())));
+ }
+
+ @GwtIncompatible("suite")
+ public static class BuiltTests extends TestCase {
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ContiguousSetGenerator())
+ .named("Range.asSet")
+ .withFeatures(CollectionSize.ANY, KNOWN_ORDER, ALLOWS_NULL_QUERIES,
+ NON_STANDARD_TOSTRING, RESTRICTS_ELEMENTS)
+ .suppressing(getHoleMethods())
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ContiguousSetHeadsetGenerator())
+ .named("Range.asSet, headset")
+ .withFeatures(CollectionSize.ANY, KNOWN_ORDER, ALLOWS_NULL_QUERIES,
+ NON_STANDARD_TOSTRING, RESTRICTS_ELEMENTS)
+ .suppressing(getHoleMethods())
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ContiguousSetTailsetGenerator())
+ .named("Range.asSet, tailset")
+ .withFeatures(CollectionSize.ANY, KNOWN_ORDER, ALLOWS_NULL_QUERIES,
+ NON_STANDARD_TOSTRING, RESTRICTS_ELEMENTS)
+ .suppressing(getHoleMethods())
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ContiguousSetSubsetGenerator())
+ .named("Range.asSet, subset")
+ .withFeatures(CollectionSize.ANY, KNOWN_ORDER, ALLOWS_NULL_QUERIES,
+ NON_STANDARD_TOSTRING, RESTRICTS_ELEMENTS)
+ .suppressing(getHoleMethods())
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ContiguousSetDescendingGenerator())
+ .named("Range.asSet.descendingSet")
+ .withFeatures(CollectionSize.ANY, KNOWN_ORDER, ALLOWS_NULL_QUERIES,
+ NON_STANDARD_TOSTRING, RESTRICTS_ELEMENTS)
+ .suppressing(getHoleMethods())
+ .createTestSuite());
+
+ return suite;
+ }
}
}
diff --git a/guava-tests/test/com/google/common/collect/CountTest.java b/guava-tests/test/com/google/common/collect/CountTest.java
index be40ff8..85839bc 100644
--- a/guava-tests/test/com/google/common/collect/CountTest.java
+++ b/guava-tests/test/com/google/common/collect/CountTest.java
@@ -46,7 +46,7 @@ public class CountTest extends TestCase {
assertEquals(20, holder.get());
}
- public void testSet(){
+ public void testSet() {
Count holder = new Count(10);
holder.set(20);
assertEquals(20, holder.get());
diff --git a/guava-tests/test/com/google/common/collect/DiscreteDomainsTest.java b/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java
index 2aec2db..fdf2acd 100644
--- a/guava-tests/test/com/google/common/collect/DiscreteDomainsTest.java
+++ b/guava-tests/test/com/google/common/collect/DiscreteDomainTest.java
@@ -23,15 +23,14 @@ import com.google.common.annotations.GwtIncompatible;
import junit.framework.TestCase;
/**
- * Tests for {@link DiscreteDomains}.
+ * Tests for {@link DiscreteDomain}.
*
* @author Chris Povirk
*/
@GwtIncompatible("SerializableTester")
-public class DiscreteDomainsTest extends TestCase {
+public class DiscreteDomainTest extends TestCase {
public void testSerialization() {
- reserializeAndAssert(DiscreteDomains.integers());
- reserializeAndAssert(DiscreteDomains.longs());
- reserializeAndAssert(DiscreteDomains.bigIntegers());
+ reserializeAndAssert(DiscreteDomain.integers());
+ reserializeAndAssert(DiscreteDomain.longs());
}
}
diff --git a/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java b/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java
index 38f4f32..d1bd97a 100644
--- a/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java
+++ b/guava-tests/test/com/google/common/collect/EmptyImmutableTableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,19 +16,20 @@
package com.google.common.collect;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.testing.EqualsTester;
/**
* Tests {@link EmptyImmutableTable}
*
- * @author gak@google.com (Gregory Kick)
+ * @author Gregory Kick
*/
+@GwtCompatible(emulated = true)
public class EmptyImmutableTableTest extends AbstractImmutableTableTest {
- private static final ImmutableTable<Character, Integer, String> INSTANCE =
- ImmutableTable.of();
+ private static final ImmutableTable<Character, Integer, String> INSTANCE = ImmutableTable.of();
- @Override Iterable<ImmutableTable<Character, Integer, String>>
- getTestInstances() {
+ @Override Iterable<ImmutableTable<Character, Integer, String>> getTestInstances() {
return ImmutableSet.of(INSTANCE);
}
@@ -37,11 +38,20 @@ public class EmptyImmutableTableTest extends AbstractImmutableTableTest {
}
public void testEqualsObject() {
+ Table<Character, Integer, String> nonEmptyTable = HashBasedTable.create();
+ nonEmptyTable.put('A', 1, "blah");
+
+ new EqualsTester()
+ .addEqualityGroup(INSTANCE, HashBasedTable.create(), TreeBasedTable.create())
+ .addEqualityGroup(nonEmptyTable)
+ .testEquals();
+ }
+
+ @GwtIncompatible("ArrayTable")
+ public void testEqualsObjectNullValues() {
new EqualsTester()
- .addEqualityGroup(INSTANCE, HashBasedTable.create(),
- TreeBasedTable.create())
- .addEqualityGroup(ArrayTable.create(ImmutableSet.of("A"),
- ImmutableSet.of(1)))
+ .addEqualityGroup(INSTANCE)
+ .addEqualityGroup(ArrayTable.create(ImmutableSet.of('A'), ImmutableSet.of(1)))
.testEquals();
}
@@ -110,8 +120,7 @@ public class EmptyImmutableTableTest extends AbstractImmutableTableTest {
}
public void testReadResolve() {
- assertSame(EmptyImmutableTable.INSTANCE,
- EmptyImmutableTable.INSTANCE.readResolve());
+ assertSame(EmptyImmutableTable.INSTANCE, EmptyImmutableTable.INSTANCE.readResolve());
}
}
diff --git a/guava-tests/test/com/google/common/collect/EnumBiMapTest.java b/guava-tests/test/com/google/common/collect/EnumBiMapTest.java
index c592f79..c972606 100644
--- a/guava-tests/test/com/google/common/collect/EnumBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/EnumBiMapTest.java
@@ -16,16 +16,31 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static com.google.common.collect.testing.Helpers.orderEntriesByKey;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.Helpers;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestBiMapGenerator;
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
+import junit.framework.Test;
import junit.framework.TestCase;
+import junit.framework.TestSuite;
import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
/**
@@ -36,8 +51,66 @@ import java.util.Set;
*/
@GwtCompatible(emulated = true)
public class EnumBiMapTest extends TestCase {
- private enum Currency { DOLLAR, FRANC, PESO }
- private enum Country { CANADA, CHILE, SWITZERLAND }
+ private enum Currency { DOLLAR, FRANC, PESO, POUND, YEN }
+ private enum Country { CANADA, CHILE, JAPAN, SWITZERLAND, UK }
+
+ public static final class EnumBiMapGenerator implements TestBiMapGenerator<Country, Currency> {
+ @SuppressWarnings("unchecked")
+ @Override
+ public BiMap<Country, Currency> create(Object... entries) {
+ BiMap<Country, Currency> result = EnumBiMap.create(Country.class, Currency.class);
+ for (Object object : entries) {
+ Entry<Country, Currency> entry = (Entry<Country, Currency>) object;
+ result.put(entry.getKey(), entry.getValue());
+ }
+ return result;
+ }
+
+ @Override
+ public SampleElements<Entry<Country, Currency>> samples() {
+ return new SampleElements<Entry<Country, Currency>>(
+ Helpers.mapEntry(Country.CANADA, Currency.DOLLAR),
+ Helpers.mapEntry(Country.CHILE, Currency.PESO),
+ Helpers.mapEntry(Country.UK, Currency.POUND),
+ Helpers.mapEntry(Country.JAPAN, Currency.YEN),
+ Helpers.mapEntry(Country.SWITZERLAND, Currency.FRANC));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Entry<Country, Currency>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<Country, Currency>> order(List<Entry<Country, Currency>> insertionOrder) {
+ return orderEntriesByKey(insertionOrder);
+ }
+
+ @Override
+ public Country[] createKeyArray(int length) {
+ return new Country[length];
+ }
+
+ @Override
+ public Currency[] createValueArray(int length) {
+ return new Currency[length];
+ }
+ }
+
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(BiMapTestSuiteBuilder.using(new EnumBiMapGenerator())
+ .named("EnumBiMap")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+ suite.addTestSuite(EnumBiMapTest.class);
+ return suite;
+ }
public void testCreate() {
EnumBiMap<Currency, Country> bimap =
@@ -112,20 +185,30 @@ public class EnumBiMapTest extends TestCase {
assertEquals(Country.class, bimap.valueType());
}
- @GwtIncompatible("SerializationTester")
- public void testSerialization() {
+ public void testIterationOrder() {
+ // The enum orderings are alphabetical, leading to the bimap and its inverse
+ // having inconsistent iteration orderings.
Map<Currency, Country> map = ImmutableMap.of(
Currency.DOLLAR, Country.CANADA,
Currency.PESO, Country.CHILE,
Currency.FRANC, Country.SWITZERLAND);
EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map);
- BiMap<Currency, Country> copy =
- SerializableTester.reserializeAndAssert(bimap);
- assertEquals(bimap.inverse(), copy.inverse());
+ // forward map ordered by currency
+ ASSERT.that(bimap.keySet())
+ .has().allOf(Currency.DOLLAR, Currency.FRANC, Currency.PESO).inOrder();
+ // forward map ordered by currency (even for country values)
+ ASSERT.that(bimap.values())
+ .has().allOf(Country.CANADA, Country.SWITZERLAND, Country.CHILE).inOrder();
+ // backward map ordered by country
+ ASSERT.that(bimap.inverse().keySet())
+ .has().allOf(Country.CANADA, Country.CHILE, Country.SWITZERLAND).inOrder();
+ // backward map ordered by country (even for currency values)
+ ASSERT.that(bimap.inverse().values())
+ .has().allOf(Currency.DOLLAR, Currency.PESO, Currency.FRANC).inOrder();
}
- public void testIterationOrder() {
+ public void testKeySetIteratorRemove() {
// The enum orderings are alphabetical, leading to the bimap and its inverse
// having inconsistent iteration orderings.
Map<Currency, Country> map = ImmutableMap.of(
@@ -134,21 +217,54 @@ public class EnumBiMapTest extends TestCase {
Currency.FRANC, Country.SWITZERLAND);
EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map);
+ Iterator<Currency> iter = bimap.keySet().iterator();
+ assertEquals(Currency.DOLLAR, iter.next());
+ iter.remove();
+
// forward map ordered by currency
ASSERT.that(bimap.keySet())
- .hasContentsInOrder(Currency.DOLLAR, Currency.FRANC, Currency.PESO);
+ .has().allOf(Currency.FRANC, Currency.PESO).inOrder();
// forward map ordered by currency (even for country values)
ASSERT.that(bimap.values())
- .hasContentsInOrder(Country.CANADA, Country.SWITZERLAND, Country.CHILE);
+ .has().allOf(Country.SWITZERLAND, Country.CHILE).inOrder();
// backward map ordered by country
ASSERT.that(bimap.inverse().keySet())
- .hasContentsInOrder(Country.CANADA, Country.CHILE, Country.SWITZERLAND);
+ .has().allOf(Country.CHILE, Country.SWITZERLAND).inOrder();
// backward map ordered by country (even for currency values)
ASSERT.that(bimap.inverse().values())
- .hasContentsInOrder(Currency.DOLLAR, Currency.PESO, Currency.FRANC);
+ .has().allOf(Currency.PESO, Currency.FRANC).inOrder();
+ }
+
+ public void testValuesIteratorRemove() {
+ // The enum orderings are alphabetical, leading to the bimap and its inverse
+ // having inconsistent iteration orderings.
+ Map<Currency, Country> map = ImmutableMap.of(
+ Currency.DOLLAR, Country.CANADA,
+ Currency.PESO, Country.CHILE,
+ Currency.FRANC, Country.SWITZERLAND);
+ EnumBiMap<Currency, Country> bimap = EnumBiMap.create(map);
+
+ Iterator<Currency> iter = bimap.keySet().iterator();
+ assertEquals(Currency.DOLLAR, iter.next());
+ assertEquals(Currency.FRANC, iter.next());
+ iter.remove();
+
+ // forward map ordered by currency
+ ASSERT.that(bimap.keySet())
+ .has().allOf(Currency.DOLLAR, Currency.PESO).inOrder();
+ // forward map ordered by currency (even for country values)
+ ASSERT.that(bimap.values())
+ .has().allOf(Country.CANADA, Country.CHILE).inOrder();
+ // backward map ordered by country
+ ASSERT.that(bimap.inverse().keySet())
+ .has().allOf(Country.CANADA, Country.CHILE).inOrder();
+ // backward map ordered by country (even for currency values)
+ ASSERT.that(bimap.inverse().values())
+ .has().allOf(Currency.DOLLAR, Currency.PESO).inOrder();
}
public void testEntrySet() {
+ // Bug 3168290
Map<Currency, Country> map = ImmutableMap.of(
Currency.DOLLAR, Country.CANADA,
Currency.PESO, Country.CHILE,
@@ -159,5 +275,29 @@ public class EnumBiMapTest extends TestCase {
assertEquals(3, uniqueEntries.size());
}
+ @GwtIncompatible("serialization")
+ public void testSerializable() {
+ SerializableTester.reserializeAndAssert(
+ EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CANADA)));
+ }
+
+ @GwtIncompatible("reflection")
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(EnumBiMap.class);
+ new NullPointerTester()
+ .testAllPublicInstanceMethods(
+ EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CHILE)));
+ }
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(
+ EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CANADA)),
+ EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CANADA)))
+ .addEqualityGroup(EnumBiMap.create(ImmutableMap.of(Currency.DOLLAR, Country.CHILE)))
+ .addEqualityGroup(EnumBiMap.create(ImmutableMap.of(Currency.FRANC, Country.CANADA)))
+ .testEquals();
+ }
+
/* Remaining behavior tested by AbstractBiMapTest. */
}
diff --git a/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java b/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java
index e85811e..01a4afe 100644
--- a/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/EnumHashBiMapTest.java
@@ -18,12 +18,23 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestBiMapGenerator;
+import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
+import junit.framework.Test;
import junit.framework.TestCase;
+import junit.framework.TestSuite;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
/**
@@ -33,8 +44,67 @@ import java.util.Set;
*/
@GwtCompatible(emulated = true)
public class EnumHashBiMapTest extends TestCase {
- private enum Currency { DOLLAR, PESO, FRANC }
- private enum Country { CANADA, CHILE, SWITZERLAND }
+ private enum Currency { DOLLAR, FRANC, PESO, POUND, YEN }
+ private enum Country { CANADA, CHILE, JAPAN, SWITZERLAND, UK }
+
+ public static final class EnumHashBiMapGenerator implements TestBiMapGenerator<Country, String> {
+ @SuppressWarnings("unchecked")
+ @Override
+ public BiMap<Country, String> create(Object... entries) {
+ BiMap<Country, String> result = EnumHashBiMap.create(Country.class);
+ for (Object o : entries) {
+ Entry<Country, String> entry = (Entry<Country, String>) o;
+ result.put(entry.getKey(), entry.getValue());
+ }
+ return result;
+ }
+
+ @Override
+ public SampleElements<Entry<Country, String>> samples() {
+ return new SampleElements<Entry<Country, String>>(
+ Maps.immutableEntry(Country.CANADA, "DOLLAR"),
+ Maps.immutableEntry(Country.CHILE, "PESO"),
+ Maps.immutableEntry(Country.UK, "POUND"),
+ Maps.immutableEntry(Country.JAPAN, "YEN"),
+ Maps.immutableEntry(Country.SWITZERLAND, "FRANC"));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Entry<Country, String>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<Country, String>> order(List<Entry<Country, String>> insertionOrder) {
+ return insertionOrder;
+ }
+
+ @Override
+ public Country[] createKeyArray(int length) {
+ return new Country[length];
+ }
+
+ @Override
+ public String[] createValueArray(int length) {
+ return new String[length];
+ }
+ }
+
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(BiMapTestSuiteBuilder.using(new EnumHashBiMapGenerator())
+ .named("EnumHashBiMap")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+ suite.addTestSuite(EnumHashBiMapTest.class);
+ return suite;
+ }
public void testCreate() {
EnumHashBiMap<Currency, String> bimap =
@@ -128,8 +198,8 @@ public class EnumHashBiMapTest extends TestCase {
assertEquals(Currency.class, bimap.keyType());
}
- @GwtIncompatible("SerializationTester")
- public void testSerialization() {
+ public void testEntrySet() {
+ // Bug 3168290
Map<Currency, String> map = ImmutableMap.of(
Currency.DOLLAR, "dollar",
Currency.PESO, "peso",
@@ -137,36 +207,19 @@ public class EnumHashBiMapTest extends TestCase {
EnumHashBiMap<Currency, String> bimap
= EnumHashBiMap.create(map);
- BiMap<Currency, String> copy =
- SerializableTester.reserializeAndAssert(bimap);
- assertEquals(bimap.inverse(), copy.inverse());
+ Set<Object> uniqueEntries = Sets.newIdentityHashSet();
+ uniqueEntries.addAll(bimap.entrySet());
+ assertEquals(3, uniqueEntries.size());
}
- public void testForcePut() {
- EnumHashBiMap<Currency, String> bimap =
- EnumHashBiMap.create(Currency.class);
- bimap.put(Currency.DOLLAR, "dollar");
- try {
- bimap.put(Currency.PESO, "dollar");
- } catch (IllegalArgumentException expected) {}
- bimap.forcePut(Currency.PESO, "dollar");
- assertEquals("dollar", bimap.get(Currency.PESO));
- assertEquals(Currency.PESO, bimap.inverse().get("dollar"));
- assertEquals(1, bimap.size());
- assertEquals(1, bimap.inverse().size());
+ @GwtIncompatible("serialize")
+ public void testSerializable() {
+ SerializableTester.reserializeAndAssert(EnumHashBiMap.create(Currency.class));
}
- public void testEntrySet() {
- Map<Currency, String> map = ImmutableMap.of(
- Currency.DOLLAR, "dollar",
- Currency.PESO, "peso",
- Currency.FRANC, "franc");
- EnumHashBiMap<Currency, String> bimap
- = EnumHashBiMap.create(map);
-
- Set<Object> uniqueEntries = Sets.newIdentityHashSet();
- uniqueEntries.addAll(bimap.entrySet());
- assertEquals(3, uniqueEntries.size());
+ @GwtIncompatible("reflection")
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(EnumHashBiMap.class);
+ new NullPointerTester().testAllPublicInstanceMethods(EnumHashBiMap.create(Currency.class));
}
- /* Remaining behavior tested by AbstractBiMapTest. */
}
diff --git a/guava-tests/test/com/google/common/collect/EnumMultisetTest.java b/guava-tests/test/com/google/common/collect/EnumMultisetTest.java
index e22fe5e..b8cceb6 100644
--- a/guava-tests/test/com/google/common/collect/EnumMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/EnumMultisetTest.java
@@ -20,9 +20,18 @@ import static java.util.Arrays.asList;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.AnEnum;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestEnumMultisetGenerator;
+import com.google.common.testing.ClassSanityTester;
+import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
+import junit.framework.Test;
import junit.framework.TestCase;
+import junit.framework.TestSuite;
import java.util.Collection;
import java.util.EnumSet;
@@ -35,6 +44,31 @@ import java.util.Set;
*/
@GwtCompatible(emulated = true)
public class EnumMultisetTest extends TestCase {
+
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(MultisetTestSuiteBuilder.using(enumMultisetGenerator())
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("EnumMultiset")
+ .createTestSuite());
+ suite.addTestSuite(EnumMultisetTest.class);
+ return suite;
+ }
+
+ private static TestEnumMultisetGenerator enumMultisetGenerator() {
+ return new TestEnumMultisetGenerator() {
+ @Override protected Multiset<AnEnum> create(AnEnum[] elements) {
+ return (elements.length == 0)
+ ? EnumMultiset.create(AnEnum.class)
+ : EnumMultiset.create(asList(elements));
+ }
+ };
+ }
+
private static enum Color {
BLUE, RED, YELLOW, GREEN, WHITE
}
@@ -64,6 +98,19 @@ public class EnumMultisetTest extends TestCase {
fail();
} catch (IllegalArgumentException expected) {}
}
+
+ public void testCreateEmptyWithClass() {
+ Multiset<Color> ms = EnumMultiset.create(ImmutableList.<Color>of(), Color.class);
+ ms.add(Color.RED);
+ }
+
+ public void testCreateEmptyWithoutClassFails() {
+ try {
+ Multiset<Color> ms = EnumMultiset.create(ImmutableList.<Color> of());
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
public void testToString() {
Multiset<Color> ms = EnumMultiset.create(Color.class);
@@ -79,15 +126,34 @@ public class EnumMultisetTest extends TestCase {
asList(Color.RED, Color.YELLOW, Color.RED));
assertEquals(ms, SerializableTester.reserialize(ms));
}
-
+
public void testEntrySet() {
Multiset<Color> ms = EnumMultiset.create(Color.class);
ms.add(Color.BLUE, 3);
ms.add(Color.YELLOW, 1);
ms.add(Color.RED, 2);
-
+
Set<Object> uniqueEntries = Sets.newIdentityHashSet();
uniqueEntries.addAll(ms.entrySet());
assertEquals(3, uniqueEntries.size());
}
+
+ @GwtIncompatible("reflection")
+ public void testEquals() throws Exception {
+ new ClassSanityTester()
+ .setSampleInstances(Class.class, ImmutableList.of(Color.class))
+ .setSampleInstances(Enum.class, ImmutableList.copyOf(Color.values()))
+ .setSampleInstances(Iterable.class,
+ ImmutableList.of(ImmutableList.of(Color.RED), ImmutableList.of(Color.GREEN)))
+ .forAllPublicStaticMethods(EnumMultiset.class)
+ .testEquals();
+ }
+
+ @GwtIncompatible("reflection")
+ public void testNulls() throws Exception {
+ new NullPointerTester()
+ .setDefault(Class.class, Color.class)
+ .setDefault(Iterable.class, ImmutableList.copyOf(Color.values()))
+ .testAllPublicStaticMethods(EnumMultiset.class);
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/FauxveridesTest.java b/guava-tests/test/com/google/common/collect/FauxveridesTest.java
index 0bf6df4..c1d861c 100644
--- a/guava-tests/test/com/google/common/collect/FauxveridesTest.java
+++ b/guava-tests/test/com/google/common/collect/FauxveridesTest.java
@@ -42,7 +42,7 @@ import java.util.Set;
* are "overridden" in each immutable-collection class. This ensures, for
* example, that a call written "{@code ImmutableSortedSet.copyOf()}" cannot
* secretly be a call to {@code ImmutableSet.copyOf()}.
- *
+ *
* @author Chris Povirk
*/
public class FauxveridesTest extends TestCase {
@@ -68,6 +68,10 @@ public class FauxveridesTest extends TestCase {
doHasAllFauxveridesTest(ImmutableSortedSet.class, ImmutableSet.class);
}
+ public void testImmutableSortedMultiset() {
+ doHasAllFauxveridesTest(ImmutableSortedMultiset.class, ImmutableMultiset.class);
+ }
+
/*
* Demonstrate that ClassCastException is possible when calling
* ImmutableSorted{Set,Map}.copyOf(), whose type parameters we are unable to
@@ -106,8 +110,7 @@ public class FauxveridesTest extends TestCase {
}
private void doHasAllFauxveridesTest(Class<?> descendant, Class<?> ancestor) {
- Set<MethodSignature> required =
- getAllRequiredToFauxveride(descendant, ancestor);
+ Set<MethodSignature> required = getAllRequiredToFauxveride(ancestor);
Set<MethodSignature> found = getAllFauxveridden(descendant, ancestor);
required.removeAll(found);
@@ -115,8 +118,7 @@ public class FauxveridesTest extends TestCase {
Collections.emptySet(), newTreeSet(required));
}
- private static Set<MethodSignature> getAllRequiredToFauxveride(
- Class<?> descendant, Class<?> ancestor) {
+ private static Set<MethodSignature> getAllRequiredToFauxveride(Class<?> ancestor) {
return getPublicStaticMethodsBetween(ancestor, Object.class);
}
diff --git a/guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java b/guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java
new file mode 100644
index 0000000..6e165b7
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/FilteredCollectionsTest.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.testing.EqualsTester;
+
+import junit.framework.TestCase;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Tests for filtered collection views.
+ *
+ * @author Louis Wasserman
+ */
+public class FilteredCollectionsTest extends TestCase {
+ private static final Predicate<Integer> EVEN = new Predicate<Integer>() {
+ @Override
+ public boolean apply(Integer input) {
+ return input % 2 == 0;
+ }
+ };
+
+ private static final Predicate<Integer> PRIME_DIGIT =
+ Predicates.in(ImmutableSet.of(2, 3, 5, 7));
+
+ private static final ImmutableList<? extends List<Integer>> SAMPLE_INPUTS =
+ ImmutableList.of(ImmutableList.<Integer>of(),
+ ImmutableList.of(1),
+ ImmutableList.of(2),
+ ImmutableList.of(2, 3),
+ ImmutableList.of(1, 2),
+ ImmutableList.of(3, 5),
+ ImmutableList.of(2, 4),
+ ImmutableList.of(1, 2, 3, 5, 6, 8, 9));
+
+ /*
+ * We have a whole series of abstract test classes that "stack", so e.g. the tests for filtered
+ * NavigableSets inherit the tests for filtered Iterables, Collections, Sets, and SortedSets. The
+ * actual implementation tests are further down.
+ */
+
+ public static abstract class AbstractFilteredIterableTest<C extends Iterable<Integer>>
+ extends TestCase {
+ abstract C createUnfiltered(Iterable<Integer> contents);
+
+ abstract C filter(C elements, Predicate<? super Integer> predicate);
+
+ public void testIterationOrderPreserved() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ C unfiltered = createUnfiltered(contents);
+ C filtered = filter(unfiltered, EVEN);
+
+ Iterator<Integer> filteredItr = filtered.iterator();
+ for (Integer i : unfiltered) {
+ if (EVEN.apply(i)) {
+ assertTrue(filteredItr.hasNext());
+ assertEquals(i, filteredItr.next());
+ }
+ }
+ assertFalse(filteredItr.hasNext());
+ }
+ }
+ }
+
+ public static abstract class AbstractFilteredCollectionTest<C extends Collection<Integer>>
+ extends AbstractFilteredIterableTest<C> {
+
+ public void testReadsThroughAdd() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ C unfiltered = createUnfiltered(contents);
+ C filterThenAdd = filter(unfiltered, EVEN);
+ unfiltered.add(4);
+
+ List<Integer> target = Lists.newArrayList(contents);
+ target.add(4);
+ C addThenFilter = filter(createUnfiltered(target), EVEN);
+
+ ASSERT.that(filterThenAdd).has().allFrom(addThenFilter);
+ }
+ }
+
+ public void testAdd() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ for (int toAdd = 0; toAdd < 10; toAdd++) {
+ boolean expectedResult = createUnfiltered(contents).add(toAdd);
+
+ C filtered = filter(createUnfiltered(contents), EVEN);
+ try {
+ assertEquals(expectedResult, filtered.add(toAdd));
+ assertTrue(EVEN.apply(toAdd));
+ } catch (IllegalArgumentException e) {
+ assertFalse(EVEN.apply(toAdd));
+ }
+ }
+ }
+ }
+
+ public void testRemove() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ for (int toRemove = 0; toRemove < 10; toRemove++) {
+ assertEquals(contents.contains(toRemove) && EVEN.apply(toRemove),
+ filter(createUnfiltered(contents), EVEN).remove(toRemove));
+ }
+ }
+ }
+
+ public void testContains() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ for (int i = 0; i < 10; i++) {
+ assertEquals(EVEN.apply(i) && contents.contains(i),
+ filter(createUnfiltered(contents), EVEN).contains(i));
+ }
+ }
+ }
+
+ public void testContainsOnDifferentType() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ assertFalse(filter(createUnfiltered(contents), EVEN).contains(new Object()));
+ }
+ }
+
+ public void testAddAllFailsAtomically() {
+ ImmutableList<Integer> toAdd = ImmutableList.of(2, 4, 3);
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ C filtered = filter(createUnfiltered(contents), EVEN);
+ C filteredToModify = filter(createUnfiltered(contents), EVEN);
+
+ try {
+ filteredToModify.addAll(toAdd);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ ASSERT.that(filteredToModify).has().allFrom(filtered);
+ }
+ }
+
+ public void testAddToFilterFiltered() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ C unfiltered = createUnfiltered(contents);
+ C filtered1 = filter(unfiltered, EVEN);
+ C filtered2 = filter(filtered1, PRIME_DIGIT);
+
+ try {
+ filtered2.add(4);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
+
+ try {
+ filtered2.add(3);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
+
+ filtered2.add(2);
+ }
+ }
+
+ public void testClearFilterFiltered() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ C unfiltered = createUnfiltered(contents);
+ C filtered1 = filter(unfiltered, EVEN);
+ C filtered2 = filter(filtered1, PRIME_DIGIT);
+
+ C inverseFiltered = filter(createUnfiltered(contents),
+ Predicates.not(Predicates.and(EVEN, PRIME_DIGIT)));
+
+ filtered2.clear();
+ ASSERT.that(unfiltered).has().allFrom(inverseFiltered);
+ }
+ }
+ }
+
+ public static abstract class AbstractFilteredSetTest<C extends Set<Integer>>
+ extends AbstractFilteredCollectionTest<C> {
+ public void testEqualsAndHashCode() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ Set<Integer> expected = Sets.newHashSet();
+ for (Integer i : contents) {
+ if (EVEN.apply(i)) {
+ expected.add(i);
+ }
+ }
+ new EqualsTester().addEqualityGroup(expected, filter(createUnfiltered(contents), EVEN))
+ .testEquals();
+ }
+ }
+ }
+
+ public static abstract class AbstractFilteredSortedSetTest<C extends SortedSet<Integer>>
+ extends AbstractFilteredSetTest<C> {
+ public void testFirst() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ C filtered = filter(createUnfiltered(contents), EVEN);
+
+ try {
+ Integer first = filtered.first();
+ assertFalse(filtered.isEmpty());
+ assertEquals(Ordering.natural().min(filtered), first);
+ } catch (NoSuchElementException e) {
+ assertTrue(filtered.isEmpty());
+ }
+ }
+ }
+
+ public void testLast() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ C filtered = filter(createUnfiltered(contents), EVEN);
+
+ try {
+ Integer first = filtered.last();
+ assertFalse(filtered.isEmpty());
+ assertEquals(Ordering.natural().max(filtered), first);
+ } catch (NoSuchElementException e) {
+ assertTrue(filtered.isEmpty());
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testHeadSet() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ for (int i = 0; i < 10; i++) {
+ assertEquals(
+ filter((C) createUnfiltered(contents).headSet(i), EVEN),
+ filter(createUnfiltered(contents), EVEN).headSet(i));
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testTailSet() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ for (int i = 0; i < 10; i++) {
+ assertEquals(
+ filter((C) createUnfiltered(contents).tailSet(i), EVEN),
+ filter(createUnfiltered(contents), EVEN).tailSet(i));
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testSubSet() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ for (int i = 0; i < 10; i++) {
+ for (int j = i; j < 10; j++) {
+ assertEquals(
+ filter((C) createUnfiltered(contents).subSet(i, j), EVEN),
+ filter(createUnfiltered(contents), EVEN).subSet(i, j));
+ }
+ }
+ }
+ }
+ }
+
+ public static abstract class AbstractFilteredNavigableSetTest
+ extends AbstractFilteredSortedSetTest<NavigableSet<Integer>> {
+
+ public void testNavigableHeadSet() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ for (int i = 0; i < 10; i++) {
+ for (boolean inclusive : ImmutableList.of(true, false)) {
+ assertEquals(
+ filter(createUnfiltered(contents).headSet(i, inclusive), EVEN),
+ filter(createUnfiltered(contents), EVEN).headSet(i, inclusive));
+ }
+ }
+ }
+ }
+
+ public void testNavigableTailSet() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ for (int i = 0; i < 10; i++) {
+ for (boolean inclusive : ImmutableList.of(true, false)) {
+ assertEquals(
+ filter(createUnfiltered(contents).tailSet(i, inclusive), EVEN),
+ filter(createUnfiltered(contents), EVEN).tailSet(i, inclusive));
+ }
+ }
+ }
+ }
+
+ public void testNavigableSubSet() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ for (int i = 0; i < 10; i++) {
+ for (int j = i + 1; j < 10; j++) {
+ for (boolean fromInclusive : ImmutableList.of(true, false)) {
+ for (boolean toInclusive : ImmutableList.of(true, false)) {
+ NavigableSet<Integer> filterSubset = filter(
+ createUnfiltered(contents).subSet(i, fromInclusive, j, toInclusive), EVEN);
+ NavigableSet<Integer> subsetFilter = filter(createUnfiltered(contents), EVEN)
+ .subSet(i, fromInclusive, j, toInclusive);
+ assertEquals(filterSubset, subsetFilter);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void testDescendingSet() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ NavigableSet<Integer> filtered = filter(createUnfiltered(contents), EVEN);
+ NavigableSet<Integer> unfiltered = createUnfiltered(filtered);
+
+ ASSERT.that(filtered.descendingSet()).has().allFrom(unfiltered.descendingSet()).inOrder();
+ }
+ }
+
+ public void testPollFirst() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ NavigableSet<Integer> filtered = filter(createUnfiltered(contents), EVEN);
+ NavigableSet<Integer> unfiltered = createUnfiltered(filtered);
+
+ assertEquals(unfiltered.pollFirst(), filtered.pollFirst());
+ assertEquals(unfiltered, filtered);
+ }
+ }
+
+ public void testPollLast() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ NavigableSet<Integer> filtered = filter(createUnfiltered(contents), EVEN);
+ NavigableSet<Integer> unfiltered = createUnfiltered(filtered);
+
+ assertEquals(unfiltered.pollLast(), filtered.pollLast());
+ assertEquals(unfiltered, filtered);
+ }
+ }
+
+ public void testNavigation() {
+ for (List<Integer> contents : SAMPLE_INPUTS) {
+ NavigableSet<Integer> filtered = filter(createUnfiltered(contents), EVEN);
+ NavigableSet<Integer> unfiltered = createUnfiltered(filtered);
+ for (int i = 0; i < 10; i++) {
+ assertEquals(unfiltered.lower(i), filtered.lower(i));
+ assertEquals(unfiltered.floor(i), filtered.floor(i));
+ assertEquals(unfiltered.ceiling(i), filtered.ceiling(i));
+ assertEquals(unfiltered.higher(i), filtered.higher(i));
+ }
+ }
+ }
+ }
+
+ // implementation tests
+
+ public static final class IterablesFilterArrayListTest
+ extends AbstractFilteredIterableTest<Iterable<Integer>> {
+ @Override
+ Iterable<Integer> createUnfiltered(Iterable<Integer> contents) {
+ return Lists.newArrayList(contents);
+ }
+
+ @Override
+ Iterable<Integer> filter(Iterable<Integer> elements, Predicate<? super Integer> predicate) {
+ return Iterables.filter(elements, predicate);
+ }
+ }
+
+ public static final class Collections2FilterArrayListTest
+ extends AbstractFilteredCollectionTest<Collection<Integer>> {
+ @Override
+ Collection<Integer> createUnfiltered(Iterable<Integer> contents) {
+ return Lists.newArrayList(contents);
+ }
+
+ @Override
+ Collection<Integer> filter(Collection<Integer> elements, Predicate<? super Integer> predicate) {
+ return Collections2.filter(elements, predicate);
+ }
+ }
+
+ public static final class SetsFilterHashSetTest
+ extends AbstractFilteredSetTest<Set<Integer>> {
+ @Override
+ Set<Integer> createUnfiltered(Iterable<Integer> contents) {
+ return Sets.newHashSet(contents);
+ }
+
+ @Override
+ Set<Integer> filter(Set<Integer> elements, Predicate<? super Integer> predicate) {
+ return Sets.filter(elements, predicate);
+ }
+ }
+
+ public static final class SetsFilterSortedSetTest
+ extends AbstractFilteredSortedSetTest<SortedSet<Integer>> {
+ @Override
+ SortedSet<Integer> createUnfiltered(Iterable<Integer> contents) {
+ final TreeSet<Integer> result = Sets.newTreeSet(contents);
+ // we have to make the result not Navigable
+ return new ForwardingSortedSet<Integer>() {
+ @Override
+ protected SortedSet<Integer> delegate() {
+ return result;
+ }
+ };
+ }
+
+ @Override
+ SortedSet<Integer> filter(SortedSet<Integer> elements, Predicate<? super Integer> predicate) {
+ return Sets.filter(elements, predicate);
+ }
+ }
+
+ public static final class SetsFilterNavigableSetTest extends AbstractFilteredNavigableSetTest {
+ @Override
+ NavigableSet<Integer> createUnfiltered(Iterable<Integer> contents) {
+ return Sets.newTreeSet(contents);
+ }
+
+ @Override
+ NavigableSet<Integer> filter(
+ NavigableSet<Integer> elements, Predicate<? super Integer> predicate) {
+ return Sets.filter(elements, predicate);
+ }
+ }
+
+ /** No-op test so that the class has at least one method, making Maven's test runner happy. */
+ public void testNoop() {
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/FluentIterableTest.java b/guava-tests/test/com/google/common/collect/FluentIterableTest.java
new file mode 100644
index 0000000..52dc9ba
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/FluentIterableTest.java
@@ -0,0 +1,728 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static java.util.Arrays.asList;
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.testing.IteratorFeature;
+import com.google.common.collect.testing.IteratorTester;
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+
+import javax.annotation.Nullable;
+
+/**
+ * Unit test for {@link FluentIterable}.
+ *
+ * @author Marcin Mikosik
+ */
+@GwtCompatible(emulated = true)
+public class FluentIterableTest extends TestCase {
+
+ @GwtIncompatible("NullPointerTester")
+ public void testNullPointerExceptions() {
+ NullPointerTester tester = new NullPointerTester();
+ tester.testAllPublicStaticMethods(FluentIterable.class);
+ }
+
+ public void testFrom() {
+ assertEquals(ImmutableList.of(1, 2, 3, 4),
+ Lists.newArrayList(FluentIterable.from(ImmutableList.of(1, 2, 3, 4))));
+ }
+
+ @SuppressWarnings("deprecation") // test of deprecated method
+ public void testFrom_alreadyFluentIterable() {
+ FluentIterable<Integer> iterable = FluentIterable.from(asList(1));
+ assertSame(iterable, FluentIterable.from(iterable));
+ }
+
+ public void testSize1Collection() {
+ assertEquals(1, FluentIterable.from(asList("a")).size());
+ }
+
+ public void testSize2NonCollection() {
+ Iterable<Integer> iterable = new Iterable<Integer>() {
+ @Override
+ public Iterator<Integer> iterator() {
+ return asList(0, 1).iterator();
+ }
+ };
+ assertEquals(2, FluentIterable.from(iterable).size());
+ }
+
+ public void testSize_collectionDoesntIterate() {
+ List<Integer> nums = asList(1, 2, 3, 4, 5);
+ List<Integer> collection = new ArrayList<Integer>(nums) {
+ @Override public Iterator<Integer> iterator() {
+ fail("Don't iterate me!");
+ return null;
+ }
+ };
+ assertEquals(5, FluentIterable.from(collection).size());
+ }
+
+ public void testContains_nullSetYes() {
+ Iterable<String> set = Sets.newHashSet("a", null, "b");
+ assertTrue(FluentIterable.from(set).contains(null));
+ }
+
+ public void testContains_nullSetNo() {
+ Iterable<String> set = ImmutableSortedSet.of("a", "b");
+ assertFalse(FluentIterable.from(set).contains(null));
+ }
+
+ public void testContains_nullIterableYes() {
+ Iterable<String> iterable = iterable("a", null, "b");
+ assertTrue(FluentIterable.from(iterable).contains(null));
+ }
+
+ public void testContains_nullIterableNo() {
+ Iterable<String> iterable = iterable("a", "b");
+ assertFalse(FluentIterable.from(iterable).contains(null));
+ }
+
+ public void testContains_nonNullSetYes() {
+ Iterable<String> set = Sets.newHashSet("a", null, "b");
+ assertTrue(FluentIterable.from(set).contains("b"));
+ }
+
+ public void testContains_nonNullSetNo() {
+ Iterable<String> set = Sets.newHashSet("a", "b");
+ assertFalse(FluentIterable.from(set).contains("c"));
+ }
+
+ public void testContains_nonNullIterableYes() {
+ Iterable<String> set = iterable("a", null, "b");
+ assertTrue(FluentIterable.from(set).contains("b"));
+ }
+
+ public void testContains_nonNullIterableNo() {
+ Iterable<String> iterable = iterable("a", "b");
+ assertFalse(FluentIterable.from(iterable).contains("c"));
+ }
+
+ public void testCycle() {
+ FluentIterable<String> cycle = FluentIterable.from(asList("a", "b")).cycle();
+
+ int howManyChecked = 0;
+ for (String string : cycle) {
+ String expected = (howManyChecked % 2 == 0) ? "a" : "b";
+ assertEquals(expected, string);
+ if (howManyChecked++ == 5) {
+ break;
+ }
+ }
+
+ // We left the last iterator pointing to "b". But a new iterator should
+ // always point to "a".
+ assertEquals("a", cycle.iterator().next());
+ }
+
+ public void testCycle_removingAllElementsStopsCycle() {
+ FluentIterable<Integer> cycle = fluent(1, 2).cycle();
+ Iterator<Integer> iterator = cycle.iterator();
+ iterator.next();
+ iterator.remove();
+ iterator.next();
+ iterator.remove();
+ assertFalse(iterator.hasNext());
+ assertFalse(cycle.iterator().hasNext());
+ }
+
+ /*
+ * Tests for partition(int size) method.
+ */
+
+ /*
+ * Tests for partitionWithPadding(int size) method.
+ */
+
+ public void testFilter() {
+ FluentIterable<String> filtered =
+ FluentIterable.from(asList("foo", "bar")).filter(Predicates.equalTo("foo"));
+
+ List<String> expected = Collections.singletonList("foo");
+ List<String> actual = Lists.newArrayList(filtered);
+ assertEquals(expected, actual);
+ assertCanIterateAgain(filtered);
+ assertEquals("[foo]", filtered.toString());
+ }
+
+ private static class TypeA {}
+ private interface TypeB {}
+ private static class HasBoth extends TypeA implements TypeB {}
+
+ @GwtIncompatible("Iterables.filter(Iterable, Class)")
+ public void testFilterByType() throws Exception {
+ HasBoth hasBoth = new HasBoth();
+ FluentIterable<TypeA> alist =
+ FluentIterable.from(asList(new TypeA(), new TypeA(), hasBoth, new TypeA()));
+ Iterable<TypeB> blist = alist.filter(TypeB.class);
+ ASSERT.that(blist).iteratesOverSequence(hasBoth);
+ }
+
+ public void testAnyMatch() {
+ ArrayList<String> list = Lists.newArrayList();
+ FluentIterable<String> iterable = FluentIterable.<String>from(list);
+ Predicate<String> predicate = Predicates.equalTo("pants");
+
+ assertFalse(iterable.anyMatch(predicate));
+ list.add("cool");
+ assertFalse(iterable.anyMatch(predicate));
+ list.add("pants");
+ assertTrue(iterable.anyMatch(predicate));
+ }
+
+ public void testAllMatch() {
+ List<String> list = Lists.newArrayList();
+ FluentIterable<String> iterable = FluentIterable.<String>from(list);
+ Predicate<String> predicate = Predicates.equalTo("cool");
+
+ assertTrue(iterable.allMatch(predicate));
+ list.add("cool");
+ assertTrue(iterable.allMatch(predicate));
+ list.add("pants");
+ assertFalse(iterable.allMatch(predicate));
+ }
+
+ public void testFirstMatch() {
+ FluentIterable<String> iterable = FluentIterable.from(Lists.newArrayList("cool", "pants"));
+ assertEquals(Optional.of("cool"), iterable.firstMatch(Predicates.equalTo("cool")));
+ assertEquals(Optional.of("pants"), iterable.firstMatch(Predicates.equalTo("pants")));
+ assertEquals(Optional.absent(), iterable.firstMatch(Predicates.alwaysFalse()));
+ assertEquals(Optional.of("cool"), iterable.firstMatch(Predicates.alwaysTrue()));
+ }
+
+ private static final class IntegerValueOfFunction implements Function<String, Integer> {
+ @Override
+ public Integer apply(String from) {
+ return Integer.valueOf(from);
+ }
+ }
+
+ public void testTransformWith() {
+ List<String> input = asList("1", "2", "3");
+ Iterable<Integer> iterable =
+ FluentIterable.from(input).transform(new IntegerValueOfFunction());
+
+ assertEquals(asList(1, 2, 3), Lists.newArrayList(iterable));
+ assertCanIterateAgain(iterable);
+ assertEquals("[1, 2, 3]", iterable.toString());
+ }
+
+ public void testTransformWith_poorlyBehavedTransform() {
+ List<String> input = asList("1", null, "3");
+ Iterable<Integer> iterable =
+ FluentIterable.from(input).transform(new IntegerValueOfFunction());
+
+ Iterator<Integer> resultIterator = iterable.iterator();
+ resultIterator.next();
+
+ try {
+ resultIterator.next();
+ fail("Transforming null to int should throw NumberFormatException");
+ } catch (NumberFormatException expected) {
+ }
+ }
+
+ private static final class StringValueOfFunction implements Function<Integer, String> {
+ @Override
+ public String apply(Integer from) {
+ return String.valueOf(from);
+ }
+ }
+
+ public void testTransformWith_nullFriendlyTransform() {
+ List<Integer> input = asList(1, 2, null, 3);
+ Iterable<String> result = FluentIterable.from(input).transform(new StringValueOfFunction());
+
+ assertEquals(asList("1", "2", "null", "3"), Lists.newArrayList(result));
+ }
+
+ private static final class RepeatedStringValueOfFunction
+ implements Function<Integer, List<String>> {
+ @Override
+ public List<String> apply(Integer from) {
+ String value = String.valueOf(from);
+ return ImmutableList.of(value, value);
+ }
+ }
+
+ public void testTransformAndConcat() {
+ List<Integer> input = asList(1, 2, 3);
+ Iterable<String> result =
+ FluentIterable.from(input).transformAndConcat(new RepeatedStringValueOfFunction());
+ assertEquals(asList("1", "1", "2", "2", "3", "3"), Lists.newArrayList(result));
+ }
+
+ private static final class RepeatedStringValueOfWildcardFunction
+ implements Function<Integer, List<? extends String>> {
+ @Override
+ public List<String> apply(Integer from) {
+ String value = String.valueOf(from);
+ return ImmutableList.of(value, value);
+ }
+ }
+
+ public void testTransformAndConcat_wildcardFunctionGenerics() {
+ List<Integer> input = asList(1, 2, 3);
+ FluentIterable.from(input).transformAndConcat(new RepeatedStringValueOfWildcardFunction());
+ }
+
+ public void testFirst_list() {
+ List<String> list = Lists.newArrayList("a", "b", "c");
+ assertEquals("a", FluentIterable.from(list).first().get());
+ }
+
+ public void testFirst_null() {
+ List<String> list = Lists.newArrayList(null, "a", "b");
+ try {
+ FluentIterable.from(list).first();
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testFirst_emptyList() {
+ List<String> list = Collections.emptyList();
+ assertEquals(Optional.absent(), FluentIterable.from(list).first());
+ }
+
+ public void testFirst_sortedSet() {
+ SortedSet<String> sortedSet = ImmutableSortedSet.of("b", "c", "a");
+ assertEquals("a", FluentIterable.from(sortedSet).first().get());
+ }
+
+ public void testFirst_emptySortedSet() {
+ SortedSet<String> sortedSet = ImmutableSortedSet.of();
+ assertEquals(Optional.absent(), FluentIterable.from(sortedSet).first());
+ }
+
+ public void testFirst_iterable() {
+ Set<String> set = ImmutableSet.of("a", "b", "c");
+ assertEquals("a", FluentIterable.from(set).first().get());
+ }
+
+ public void testFirst_emptyIterable() {
+ Set<String> set = Sets.newHashSet();
+ assertEquals(Optional.absent(), FluentIterable.from(set).first());
+ }
+
+ public void testLast_list() {
+ List<String> list = Lists.newArrayList("a", "b", "c");
+ assertEquals("c", FluentIterable.from(list).last().get());
+ }
+
+ public void testLast_null() {
+ List<String> list = Lists.newArrayList("a", "b", null);
+ try {
+ FluentIterable.from(list).last();
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testLast_emptyList() {
+ List<String> list = Collections.emptyList();
+ assertEquals(Optional.absent(), FluentIterable.from(list).last());
+ }
+
+ public void testLast_sortedSet() {
+ SortedSet<String> sortedSet = ImmutableSortedSet.of("b", "c", "a");
+ assertEquals("c", FluentIterable.from(sortedSet).last().get());
+ }
+
+ public void testLast_emptySortedSet() {
+ SortedSet<String> sortedSet = ImmutableSortedSet.of();
+ assertEquals(Optional.absent(), FluentIterable.from(sortedSet).last());
+ }
+
+ public void testLast_iterable() {
+ Set<String> set = ImmutableSet.of("a", "b", "c");
+ assertEquals("c", FluentIterable.from(set).last().get());
+ }
+
+ public void testLast_emptyIterable() {
+ Set<String> set = Sets.newHashSet();
+ assertEquals(Optional.absent(), FluentIterable.from(set).last());
+ }
+
+ public void testSkip_simple() {
+ Collection<String> set = ImmutableSet.of("a", "b", "c", "d", "e");
+ assertEquals(Lists.newArrayList("c", "d", "e"),
+ Lists.newArrayList(FluentIterable.from(set).skip(2)));
+ assertEquals("[c, d, e]", FluentIterable.from(set).skip(2).toString());
+ }
+
+ public void testSkip_simpleList() {
+ Collection<String> list = Lists.newArrayList("a", "b", "c", "d", "e");
+ assertEquals(Lists.newArrayList("c", "d", "e"),
+ Lists.newArrayList(FluentIterable.from(list).skip(2)));
+ assertEquals("[c, d, e]", FluentIterable.from(list).skip(2).toString());
+ }
+
+ public void testSkip_pastEnd() {
+ Collection<String> set = ImmutableSet.of("a", "b");
+ assertEquals(Collections.emptyList(), Lists.newArrayList(FluentIterable.from(set).skip(20)));
+ }
+
+ public void testSkip_pastEndList() {
+ Collection<String> list = Lists.newArrayList("a", "b");
+ assertEquals(Collections.emptyList(), Lists.newArrayList(FluentIterable.from(list).skip(20)));
+ }
+
+ public void testSkip_skipNone() {
+ Collection<String> set = ImmutableSet.of("a", "b");
+ assertEquals(Lists.newArrayList("a", "b"),
+ Lists.newArrayList(FluentIterable.from(set).skip(0)));
+ }
+
+ public void testSkip_skipNoneList() {
+ Collection<String> list = Lists.newArrayList("a", "b");
+ assertEquals(Lists.newArrayList("a", "b"),
+ Lists.newArrayList(FluentIterable.from(list).skip(0)));
+ }
+
+ public void testSkip_iterator() throws Exception {
+ new IteratorTester<Integer>(5, IteratorFeature.MODIFIABLE, Lists.newArrayList(2, 3),
+ IteratorTester.KnownOrder.KNOWN_ORDER) {
+ @Override protected Iterator<Integer> newTargetIterator() {
+ Collection<Integer> collection = Sets.newLinkedHashSet();
+ Collections.addAll(collection, 1, 2, 3);
+ return FluentIterable.from(collection).skip(1).iterator();
+ }
+ }.test();
+ }
+
+ public void testSkip_iteratorList() throws Exception {
+ new IteratorTester<Integer>(5, IteratorFeature.MODIFIABLE, Lists.newArrayList(2, 3),
+ IteratorTester.KnownOrder.KNOWN_ORDER) {
+ @Override protected Iterator<Integer> newTargetIterator() {
+ return FluentIterable.from(Lists.newArrayList(1, 2, 3)).skip(1).iterator();
+ }
+ }.test();
+ }
+
+ public void testSkip_nonStructurallyModifiedList() throws Exception {
+ List<String> list = Lists.newArrayList("a", "b", "c");
+ FluentIterable<String> tail = FluentIterable.from(list).skip(1);
+ Iterator<String> tailIterator = tail.iterator();
+ list.set(2, "c2");
+ assertEquals("b", tailIterator.next());
+ assertEquals("c2", tailIterator.next());
+ assertFalse(tailIterator.hasNext());
+ }
+
+ public void testSkip_structurallyModifiedSkipSome() throws Exception {
+ Collection<String> set = Sets.newLinkedHashSet();
+ Collections.addAll(set, "a", "b", "c");
+ FluentIterable<String> tail = FluentIterable.from(set).skip(1);
+ set.remove("b");
+ set.addAll(Lists.newArrayList("X", "Y", "Z"));
+ ASSERT.that(tail).iteratesOverSequence("c", "X", "Y", "Z");
+ }
+
+ public void testSkip_structurallyModifiedSkipSomeList() throws Exception {
+ List<String> list = Lists.newArrayList("a", "b", "c");
+ FluentIterable<String> tail = FluentIterable.from(list).skip(1);
+ list.subList(1, 3).clear();
+ list.addAll(0, Lists.newArrayList("X", "Y", "Z"));
+ ASSERT.that(tail).iteratesOverSequence("Y", "Z", "a");
+ }
+
+ public void testSkip_structurallyModifiedSkipAll() throws Exception {
+ Collection<String> set = Sets.newLinkedHashSet();
+ Collections.addAll(set, "a", "b", "c");
+ FluentIterable<String> tail = FluentIterable.from(set).skip(2);
+ set.remove("a");
+ set.remove("b");
+ assertFalse(tail.iterator().hasNext());
+ }
+
+ public void testSkip_structurallyModifiedSkipAllList() throws Exception {
+ List<String> list = Lists.newArrayList("a", "b", "c");
+ FluentIterable<String> tail = FluentIterable.from(list).skip(2);
+ list.subList(0, 2).clear();
+ ASSERT.that(tail).isEmpty();
+ }
+
+ public void testSkip_illegalArgument() {
+ try {
+ FluentIterable.from(asList("a", "b", "c")).skip(-1);
+ fail("Skipping negative number of elements should throw IllegalArgumentException.");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testLimit() {
+ Iterable<String> iterable = Lists.newArrayList("foo", "bar", "baz");
+ FluentIterable<String> limited = FluentIterable.from(iterable).limit(2);
+
+ assertEquals(ImmutableList.of("foo", "bar"), Lists.newArrayList(limited));
+ assertCanIterateAgain(limited);
+ assertEquals("[foo, bar]", limited.toString());
+ }
+
+ public void testLimit_illegalArgument() {
+ try {
+ FluentIterable.from(Lists.newArrayList("a", "b", "c")).limit(-1);
+ fail("Passing negative number to limit(...) method should throw IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testIsEmpty() {
+ assertTrue(FluentIterable.<String>from(Collections.<String>emptyList()).isEmpty());
+ assertFalse(FluentIterable.<String>from(Lists.newArrayList("foo")).isEmpty());
+ }
+
+ public void testToList() {
+ assertEquals(Lists.newArrayList(1, 2, 3, 4), fluent(1, 2, 3, 4).toList());
+ }
+
+ public void testToList_empty() {
+ assertTrue(fluent().toList().isEmpty());
+ }
+
+ public void testToSortedList_withComparator() {
+ assertEquals(Lists.newArrayList(4, 3, 2, 1),
+ fluent(4, 1, 3, 2).toSortedList(Ordering.<Integer>natural().reverse()));
+ }
+
+ public void testToSortedList_withDuplicates() {
+ assertEquals(Lists.newArrayList(4, 3, 1, 1),
+ fluent(1, 4, 1, 3).toSortedList(Ordering.<Integer>natural().reverse()));
+ }
+
+ public void testToSet() {
+ ASSERT.that(fluent(1, 2, 3, 4).toSet()).has().allOf(1, 2, 3, 4).inOrder();
+ }
+
+ public void testToSet_removeDuplicates() {
+ ASSERT.that(fluent(1, 2, 1, 2).toSet()).has().allOf(1, 2).inOrder();
+ }
+
+ public void testToSet_empty() {
+ assertTrue(fluent().toSet().isEmpty());
+ }
+
+ public void testToSortedSet() {
+ ASSERT.that(fluent(1, 4, 2, 3).toSortedSet(Ordering.<Integer>natural().reverse()))
+ .has().allOf(4, 3, 2, 1).inOrder();
+ }
+
+ public void testToSortedSet_removeDuplicates() {
+ ASSERT.that(fluent(1, 4, 1, 3).toSortedSet(Ordering.<Integer>natural().reverse()))
+ .has().allOf(4, 3, 1).inOrder();
+ }
+
+ public void testToMap() {
+ ASSERT.that(fluent(1, 2, 3).toMap(Functions.toStringFunction()).entrySet())
+ .has().allOf(
+ Maps.immutableEntry(1, "1"),
+ Maps.immutableEntry(2, "2"),
+ Maps.immutableEntry(3, "3")).inOrder();
+ }
+
+ public void testToMap_nullKey() {
+ try {
+ fluent(1, null, 2).toMap(Functions.constant("foo"));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testToMap_nullValue() {
+ try {
+ fluent(1, 2, 3).toMap(Functions.constant(null));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testIndex() {
+ ImmutableListMultimap<Integer, String> expected =
+ ImmutableListMultimap.<Integer, String>builder()
+ .putAll(3, "one", "two")
+ .put(5, "three")
+ .put(4, "four")
+ .build();
+ ImmutableListMultimap<Integer, String> index =
+ FluentIterable.from(asList("one", "two", "three", "four")).index(
+ new Function<String, Integer>() {
+ @Override
+ public Integer apply(String input) {
+ return input.length();
+ }
+ });
+ assertEquals(expected, index);
+ }
+
+ public void testIndex_nullKey() {
+ try {
+ fluent(1, 2, 3).index(Functions.constant(null));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testIndex_nullValue() {
+ try {
+ fluent(1, null, 2).index(Functions.constant("foo"));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testUniqueIndex() {
+ ImmutableMap<Integer, String> expected =
+ ImmutableMap.of(3, "two", 5, "three", 4, "four");
+ ImmutableMap<Integer, String> index =
+ FluentIterable.from(asList("two", "three", "four")).uniqueIndex(
+ new Function<String, Integer>() {
+ @Override
+ public Integer apply(String input) {
+ return input.length();
+ }
+ });
+ assertEquals(expected, index);
+ }
+
+ public void testUniqueIndex_duplicateKey() {
+ try {
+ FluentIterable.from(asList("one", "two", "three", "four")).uniqueIndex(
+ new Function<String, Integer>() {
+ @Override
+ public Integer apply(String input) {
+ return input.length();
+ }
+ });
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testUniqueIndex_nullKey() {
+ try {
+ fluent(1, 2, 3).uniqueIndex(Functions.constant(null));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testUniqueIndex_nullValue() {
+ try {
+ fluent(1, null, 2).uniqueIndex(new Function<Integer, Object>() {
+ @Override
+ public Object apply(@Nullable Integer input) {
+ return String.valueOf(input);
+ }
+ });
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testCopyInto_List() {
+ ASSERT.that(fluent(1, 3, 5).copyInto(Lists.newArrayList(1, 2)))
+ .has().allOf(1, 2, 1, 3, 5).inOrder();
+ }
+
+ public void testCopyInto_Set() {
+ ASSERT.that(fluent(1, 3, 5).copyInto(Sets.newHashSet(1, 2)))
+ .has().allOf(1, 2, 3, 5);
+ }
+
+ public void testCopyInto_SetAllDuplicates() {
+ ASSERT.that(fluent(1, 3, 5).copyInto(Sets.newHashSet(1, 2, 3, 5)))
+ .has().allOf(1, 2, 3, 5);
+ }
+
+ public void testCopyInto_NonCollection() {
+ final ArrayList<Integer> list = Lists.newArrayList(1, 2, 3);
+
+ final ArrayList<Integer> iterList = Lists.newArrayList(9, 8, 7);
+ Iterable<Integer> iterable = new Iterable<Integer>() {
+ @Override
+ public Iterator<Integer> iterator() {
+ return iterList.iterator();
+ }
+ };
+
+ ASSERT.that(FluentIterable.from(iterable).copyInto(list))
+ .has().allOf(1, 2, 3, 9, 8, 7).inOrder();
+ }
+
+ public void testGet() {
+ assertEquals("a", FluentIterable
+ .from(Lists.newArrayList("a", "b", "c")).get(0));
+ assertEquals("b", FluentIterable
+ .from(Lists.newArrayList("a", "b", "c")).get(1));
+ assertEquals("c", FluentIterable
+ .from(Lists.newArrayList("a", "b", "c")).get(2));
+ }
+
+ public void testGet_outOfBounds() {
+ try {
+ FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(-1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+
+ try {
+ FluentIterable.from(Lists.newArrayList("a", "b", "c")).get(3);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ private static void assertCanIterateAgain(Iterable<?> iterable) {
+ for (@SuppressWarnings("unused") Object obj : iterable) {
+ }
+ }
+
+ private static FluentIterable<Integer> fluent(Integer... elements) {
+ return FluentIterable.from(Lists.newArrayList(elements));
+ }
+
+ private static Iterable<String> iterable(String... elements) {
+ final List<String> list = asList(elements);
+ return new Iterable<String>() {
+ @Override
+ public Iterator<String> iterator() {
+ return list.iterator();
+ }
+ };
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingBlockingDequeTest.java b/guava-tests/test/com/google/common/collect/ForwardingBlockingDequeTest.java
new file mode 100644
index 0000000..ecb67bb
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/ForwardingBlockingDequeTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import java.util.concurrent.BlockingDeque;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test for {@link ForwardingBlockingDeque}
+ *
+ * @author Emily Soldal
+ */
+public class ForwardingBlockingDequeTest extends ForwardingTestCase {
+ private BlockingDeque<String> forward;
+
+ /*
+ * Class parameters must be raw, so we can't create a proxy with generic
+ * type arguments. The created proxy only records calls and returns null, so
+ * the type is irrelevant at runtime.
+ */
+ @SuppressWarnings("unchecked")
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ final BlockingDeque<String> deque = createProxyInstance(BlockingDeque.class);
+ forward = new ForwardingBlockingDeque<String>() {
+ @Override protected BlockingDeque<String> delegate() {
+ return deque;
+ }
+ };
+ }
+
+ public void testRemainingCapacity() {
+ forward.remainingCapacity();
+ assertEquals("[remainingCapacity]", getCalls());
+ }
+
+ public void testPutFirst_T() throws InterruptedException {
+ forward.putFirst("asf");
+ assertEquals("[putFirst(Object)]", getCalls());
+ }
+
+ public void testPutLast_T() throws InterruptedException {
+ forward.putFirst("asf");
+ assertEquals("[putFirst(Object)]", getCalls());
+ }
+
+ public void testOfferFirst_T() throws InterruptedException {
+ forward.offerFirst("asf", 2L, TimeUnit.SECONDS);
+ assertEquals("[offerFirst(Object,long,TimeUnit)]", getCalls());
+ }
+
+ public void testOfferLast_T() throws InterruptedException {
+ forward.offerLast("asf", 2L, TimeUnit.SECONDS);
+ assertEquals("[offerLast(Object,long,TimeUnit)]", getCalls());
+ }
+
+ public void testTakeFirst() throws InterruptedException {
+ forward.takeFirst();
+ assertEquals("[takeFirst]", getCalls());
+ }
+
+ public void testTakeLast() throws InterruptedException {
+ forward.takeLast();
+ assertEquals("[takeLast]", getCalls());
+ }
+
+ public void testPollFirst() throws InterruptedException {
+ forward.pollFirst(2L, TimeUnit.SECONDS);
+ assertEquals("[pollFirst(long,TimeUnit)]", getCalls());
+ }
+
+ public void testPollLast() throws InterruptedException {
+ forward.pollLast(2L, TimeUnit.SECONDS);
+ assertEquals("[pollLast(long,TimeUnit)]", getCalls());
+ }
+
+ public void testPut_T() throws InterruptedException {
+ forward.put("asf");
+ assertEquals("[put(Object)]", getCalls());
+ }
+
+ public void testOffer_T() throws InterruptedException {
+ forward.offer("asf", 2L, TimeUnit.SECONDS);
+ assertEquals("[offer(Object,long,TimeUnit)]", getCalls());
+ }
+
+ public void testTake() throws InterruptedException {
+ forward.take();
+ assertEquals("[take]", getCalls());
+ }
+
+ public void testPoll() throws InterruptedException {
+ forward.poll(2L, TimeUnit.SECONDS);
+ assertEquals("[poll(long,TimeUnit)]", getCalls());
+ }
+
+ public void testDrainTo_T() {
+ forward.drainTo(Lists.newArrayList());
+ assertEquals("[drainTo(Collection)]", getCalls());
+ }
+
+ public void testDrainTo_T_maxElements() {
+ forward.drainTo(Lists.newArrayList(), 3);
+ assertEquals("[drainTo(Collection,int)]", getCalls());
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java b/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java
index 47942c5..bf45998 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingCollectionTest.java
@@ -96,7 +96,7 @@ public class ForwardingCollectionTest extends ForwardingTestCase {
private Collection<String> forward;
- public static Test suite(){
+ public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingCollectionTest.class);
diff --git a/guava-tests/test/com/google/common/collect/ForwardingDequeTest.java b/guava-tests/test/com/google/common/collect/ForwardingDequeTest.java
new file mode 100644
index 0000000..0ff18fb
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/ForwardingDequeTest.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import java.util.Collections;
+import java.util.Deque;
+
+/**
+ * Tests for {@code ForwardingDeque}.
+ *
+ * @author Kurt Alfred Kluever
+ */
+public class ForwardingDequeTest extends ForwardingTestCase {
+ private Deque<String> forward;
+
+ /*
+ * Class parameters must be raw, so we can't create a proxy with generic
+ * type arguments. The created proxy only records calls and returns null, so
+ * the type is irrelevant at runtime.
+ */
+ @SuppressWarnings("unchecked")
+ @Override protected void setUp() throws Exception {
+ super.setUp();
+ final Deque<String> deque = createProxyInstance(Deque.class);
+ forward = new ForwardingDeque<String>() {
+ @Override protected Deque<String> delegate() {
+ return deque;
+ }
+ };
+ }
+
+ public void testAdd_T() {
+ forward.add("asdf");
+ assertEquals("[add(Object)]", getCalls());
+ }
+
+ public void testAddFirst_T() {
+ forward.addFirst("asdf");
+ assertEquals("[addFirst(Object)]", getCalls());
+ }
+
+ public void testAddLast_T() {
+ forward.addLast("asdf");
+ assertEquals("[addLast(Object)]", getCalls());
+ }
+
+ public void testAddAll_Collection() {
+ forward.addAll(Collections.singleton("asdf"));
+ assertEquals("[addAll(Collection)]", getCalls());
+ }
+
+ public void testClear() {
+ forward.clear();
+ assertEquals("[clear]", getCalls());
+ }
+
+ public void testContains_T() {
+ forward.contains("asdf");
+ assertEquals("[contains(Object)]", getCalls());
+ }
+
+ public void testContainsAll_Collection() {
+ forward.containsAll(Collections.singleton("asdf"));
+ assertEquals("[containsAll(Collection)]", getCalls());
+ }
+
+ public void testDescendingIterator() {
+ forward.descendingIterator();
+ assertEquals("[descendingIterator]", getCalls());
+ }
+
+ public void testElement() {
+ forward.element();
+ assertEquals("[element]", getCalls());
+ }
+
+ public void testGetFirst() {
+ forward.getFirst();
+ assertEquals("[getFirst]", getCalls());
+ }
+
+ public void testGetLast() {
+ forward.getLast();
+ assertEquals("[getLast]", getCalls());
+ }
+
+ public void testIterator() {
+ forward.iterator();
+ assertEquals("[iterator]", getCalls());
+ }
+
+ public void testIsEmpty() {
+ forward.isEmpty();
+ assertEquals("[isEmpty]", getCalls());
+ }
+
+ public void testOffer_T() {
+ forward.offer("asdf");
+ assertEquals("[offer(Object)]", getCalls());
+ }
+
+ public void testOfferFirst_T() {
+ forward.offerFirst("asdf");
+ assertEquals("[offerFirst(Object)]", getCalls());
+ }
+
+ public void testOfferLast_T() {
+ forward.offerLast("asdf");
+ assertEquals("[offerLast(Object)]", getCalls());
+ }
+
+ public void testPeek() {
+ forward.peek();
+ assertEquals("[peek]", getCalls());
+ }
+
+ public void testPeekFirst() {
+ forward.peekFirst();
+ assertEquals("[peekFirst]", getCalls());
+ }
+
+ public void testPeekLast() {
+ forward.peekLast();
+ assertEquals("[peekLast]", getCalls());
+ }
+
+ public void testPoll() {
+ forward.poll();
+ assertEquals("[poll]", getCalls());
+ }
+
+ public void testPollFirst() {
+ forward.pollFirst();
+ assertEquals("[pollFirst]", getCalls());
+ }
+
+ public void testPollLast() {
+ forward.pollLast();
+ assertEquals("[pollLast]", getCalls());
+ }
+
+ public void testPop() {
+ forward.pop();
+ assertEquals("[pop]", getCalls());
+ }
+
+ public void testPush_Object() {
+ forward.push("asdf");
+ assertEquals("[push(Object)]", getCalls());
+ }
+
+ public void testRemove() {
+ forward.remove();
+ assertEquals("[remove]", getCalls());
+ }
+
+ public void testRemoveFirst() {
+ forward.removeFirst();
+ assertEquals("[removeFirst]", getCalls());
+ }
+
+ public void testRemoveLast() {
+ forward.removeLast();
+ assertEquals("[removeLast]", getCalls());
+ }
+
+ public void testRemove_Object() {
+ forward.remove(Object.class);
+ assertEquals("[remove(Object)]", getCalls());
+ }
+
+ public void testRemoveFirstOccurrence_Object() {
+ forward.removeFirstOccurrence(Object.class);
+ assertEquals("[removeFirstOccurrence(Object)]", getCalls());
+ }
+
+ public void testRemoveLastOccurrence_Object() {
+ forward.removeLastOccurrence(Object.class);
+ assertEquals("[removeLastOccurrence(Object)]", getCalls());
+ }
+
+ public void testRemoveAll_Collection() {
+ forward.removeAll(Collections.singleton("asdf"));
+ assertEquals("[removeAll(Collection)]", getCalls());
+ }
+
+ public void testRetainAll_Collection() {
+ forward.retainAll(Collections.singleton("asdf"));
+ assertEquals("[retainAll(Collection)]", getCalls());
+ }
+
+ public void testSize() {
+ forward.size();
+ assertEquals("[size]", getCalls());
+ }
+
+ public void testToArray() {
+ forward.toArray();
+ assertEquals("[toArray]", getCalls());
+ }
+
+ public void testToArray_TArray() {
+ forward.toArray(new String[0]);
+ assertEquals("[toArray(Object[])]", getCalls());
+ }
+
+ public void testToString() {
+ forward.toString();
+ assertEquals("[toString]", getCalls());
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingListTest.java b/guava-tests/test/com/google/common/collect/ForwardingListTest.java
index aaa106e..a6a71b4 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingListTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingListTest.java
@@ -137,7 +137,7 @@ public class ForwardingListTest extends ForwardingTestCase {
private List<String> forward;
- public static Test suite(){
+ public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingListTest.class);
diff --git a/guava-tests/test/com/google/common/collect/ForwardingMapTest.java b/guava-tests/test/com/google/common/collect/ForwardingMapTest.java
index 1f92e90..6874627 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingMapTest.java
@@ -24,6 +24,7 @@ import static org.easymock.EasyMock.verify;
import com.google.common.collect.testing.MapTestSuiteBuilder;
import com.google.common.collect.testing.TestStringMapGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
@@ -131,7 +132,8 @@ public class ForwardingMapTest extends ForwardingTestCase {
}).named("ForwardingMap[LinkedHashMap] with standard implementations")
.withFeatures(CollectionSize.ANY, MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.ALLOWS_NULL_KEYS, MapFeature.GENERAL_PURPOSE)
+ MapFeature.ALLOWS_NULL_KEYS, MapFeature.GENERAL_PURPOSE,
+ CollectionFeature.KNOWN_ORDER)
.createTestSuite());
suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
@@ -147,7 +149,7 @@ public class ForwardingMapTest extends ForwardingTestCase {
}).named("ForwardingMap[ImmutableMap] with standard implementations")
.withFeatures(
CollectionSize.ANY, MapFeature.REJECTS_DUPLICATES_AT_CREATION,
- MapFeature.ALLOWS_NULL_QUERIES)
+ MapFeature.ALLOWS_NULL_QUERIES, CollectionFeature.KNOWN_ORDER)
.createTestSuite());
return suite;
@@ -243,7 +245,7 @@ public class ForwardingMapTest extends ForwardingTestCase {
forward().hashCode();
assertEquals("[hashCode]", getCalls());
}
-
+
public void testStandardEntrySet() throws InvocationTargetException {
@SuppressWarnings("unchecked")
final Map<String, Boolean> map = createMock(Map.class);
@@ -280,7 +282,7 @@ public class ForwardingMapTest extends ForwardingTestCase {
verify(map, entrySet);
}
-
+
public void testStandardKeySet() throws InvocationTargetException {
@SuppressWarnings("unchecked")
Set<Entry<String, Boolean>> entrySet = createMock(Set.class);
@@ -312,7 +314,7 @@ public class ForwardingMapTest extends ForwardingTestCase {
verify(entrySet, map);
}
-
+
public void testStandardValues() throws InvocationTargetException {
@SuppressWarnings("unchecked")
Set<Entry<String, Boolean>> entrySet = createMock(Set.class);
@@ -344,6 +346,34 @@ public class ForwardingMapTest extends ForwardingTestCase {
verify(entrySet, map);
}
+ public void testToStringWithNullKeys() throws Exception {
+ Map<String, String> hashmap = Maps.newHashMap();
+ hashmap.put("foo", "bar");
+ hashmap.put(null, "baz");
+
+ StandardImplForwardingMap<String, String> forwardingMap =
+ new StandardImplForwardingMap<String, String>(
+ Maps.<String, String>newHashMap());
+ forwardingMap.put("foo", "bar");
+ forwardingMap.put(null, "baz");
+
+ assertEquals(hashmap.toString(), forwardingMap.toString());
+ }
+
+ public void testToStringWithNullValues() throws Exception {
+ Map<String, String> hashmap = Maps.newHashMap();
+ hashmap.put("foo", "bar");
+ hashmap.put("baz", null);
+
+ StandardImplForwardingMap<String, String> forwardingMap =
+ new StandardImplForwardingMap<String, String>(
+ Maps.<String, String>newHashMap());
+ forwardingMap.put("foo", "bar");
+ forwardingMap.put("baz", null);
+
+ assertEquals(hashmap.toString(), forwardingMap.toString());
+ }
+
Map<String, Boolean> forward() {
return forward;
}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java b/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java
index a7d4d8c..f6c903c 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingMultisetTest.java
@@ -183,7 +183,7 @@ public class ForwardingMultisetTest extends ForwardingTestCase {
@Override public Set<String> elementSet() {
return new StandardElementSet();
}
-
+
@Override public int add(String element, int occurrences) {
throw new UnsupportedOperationException();
}
@@ -259,7 +259,7 @@ public class ForwardingMultisetTest extends ForwardingTestCase {
}
}).named("standardElementSet tripwire").withFeatures(CollectionSize.ANY,
CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.REMOVE_OPERATIONS).createTestSuite());
+ CollectionFeature.SUPPORTS_REMOVE).createTestSuite());
return suite;
}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingNavigableMapTest.java b/guava-tests/test/com/google/common/collect/ForwardingNavigableMapTest.java
new file mode 100644
index 0000000..16e2400
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/ForwardingNavigableMapTest.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.Maps.immutableEntry;
+
+import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
+import com.google.common.collect.testing.SafeTreeMap;
+import com.google.common.collect.testing.TestStringSortedMapGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.SortedMap;
+
+/**
+ * Tests for {@code ForwardingNavigableMap}.
+ *
+ * @author Robert Konigsberg
+ * @author Louis Wasserman
+ */
+public class ForwardingNavigableMapTest extends ForwardingSortedMapTest {
+ static class StandardImplForwardingNavigableMap<K, V>
+ extends ForwardingNavigableMap<K, V> {
+ private final NavigableMap<K, V> backingMap;
+
+ StandardImplForwardingNavigableMap(NavigableMap<K, V> backingMap) {
+ this.backingMap = backingMap;
+ }
+
+ @Override protected NavigableMap<K, V> delegate() {
+ return backingMap;
+ }
+
+ @Override public boolean containsKey(Object key) {
+ return standardContainsKey(key);
+ }
+
+ @Override public boolean containsValue(Object value) {
+ return standardContainsValue(value);
+ }
+
+ @Override public void putAll(Map<? extends K, ? extends V> map) {
+ standardPutAll(map);
+ }
+
+ @Override public V remove(Object object) {
+ return standardRemove(object);
+ }
+
+ @Override public boolean equals(Object object) {
+ return standardEquals(object);
+ }
+
+ @Override public int hashCode() {
+ return standardHashCode();
+ }
+
+ @Override public Set<K> keySet() {
+ /*
+ * We can't use StandardKeySet, as NavigableMapTestSuiteBuilder assumes that our keySet is a
+ * NavigableSet. We test StandardKeySet in the superclass, so it's still covered.
+ */
+ return navigableKeySet();
+ }
+
+ @Override public Collection<V> values() {
+ return new StandardValues();
+ }
+
+ @Override public String toString() {
+ return standardToString();
+ }
+
+ @Override public Set<Entry<K, V>> entrySet() {
+ return new StandardEntrySet() {
+ @Override
+ public Iterator<Entry<K, V>> iterator() {
+ return backingMap.entrySet().iterator();
+ }
+ };
+ }
+
+ @Override public void clear() {
+ standardClear();
+ }
+
+ @Override public boolean isEmpty() {
+ return standardIsEmpty();
+ }
+
+ @Override public SortedMap<K, V> subMap(K fromKey, K toKey) {
+ return standardSubMap(fromKey, toKey);
+ }
+
+ @Override
+ public Entry<K, V> lowerEntry(K key) {
+ return standardLowerEntry(key);
+ }
+
+ @Override
+ public K lowerKey(K key) {
+ return standardLowerKey(key);
+ }
+
+ @Override
+ public Entry<K, V> floorEntry(K key) {
+ return standardFloorEntry(key);
+ }
+
+ @Override
+ public K floorKey(K key) {
+ return standardFloorKey(key);
+ }
+
+ @Override
+ public Entry<K, V> ceilingEntry(K key) {
+ return standardCeilingEntry(key);
+ }
+
+ @Override
+ public K ceilingKey(K key) {
+ return standardCeilingKey(key);
+ }
+
+ @Override
+ public Entry<K, V> higherEntry(K key) {
+ return standardHigherEntry(key);
+ }
+
+ @Override
+ public K higherKey(K key) {
+ return standardHigherKey(key);
+ }
+
+ @Override
+ public Entry<K, V> firstEntry() {
+ return standardFirstEntry();
+ }
+
+ /*
+ * We can't override lastEntry to delegate to standardLastEntry, as it would create an infinite
+ * loop. Instead, we test standardLastEntry manually below.
+ */
+
+ @Override
+ public Entry<K, V> pollFirstEntry() {
+ return standardPollFirstEntry();
+ }
+
+ @Override
+ public Entry<K, V> pollLastEntry() {
+ return standardPollLastEntry();
+ }
+
+ @Override
+ public NavigableMap<K, V> descendingMap() {
+ return new StandardDescendingMap();
+ }
+
+ @Override
+ public NavigableSet<K> navigableKeySet() {
+ return new StandardNavigableKeySet();
+ }
+
+ @Override
+ public NavigableSet<K> descendingKeySet() {
+ return standardDescendingKeySet();
+ }
+
+ @Override
+ public K firstKey() {
+ return standardFirstKey();
+ }
+
+ @Override
+ public SortedMap<K, V> headMap(K toKey) {
+ return standardHeadMap(toKey);
+ }
+
+ @Override
+ public K lastKey() {
+ return standardLastKey();
+ }
+
+ @Override
+ public SortedMap<K, V> tailMap(K fromKey) {
+ return standardTailMap(fromKey);
+ }
+ }
+
+ static class StandardLastEntryForwardingNavigableMap<K, V>
+ extends ForwardingNavigableMap<K, V> {
+ private final NavigableMap<K, V> backingMap;
+
+ StandardLastEntryForwardingNavigableMap(NavigableMap<K, V> backingMap) {
+ this.backingMap = backingMap;
+ }
+
+ @Override protected NavigableMap<K, V> delegate() {
+ return backingMap;
+ }
+
+ @Override
+ public Entry<K, V> lastEntry() {
+ return standardLastEntry();
+ }
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTestSuite(ForwardingNavigableMapTest.class);
+ suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ @Override protected SortedMap<String, String> create(
+ Entry<String, String>[] entries) {
+ NavigableMap<String, String> map = new SafeTreeMap<String, String>();
+ for (Entry<String, String> entry : entries) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ return new StandardImplForwardingNavigableMap<String, String>(map);
+ }
+ }).named("ForwardingNavigableMap[SafeTreeMap] with no comparator and standard "
+ + "implementations").withFeatures(CollectionSize.ANY,
+ CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE).createTestSuite());
+ // TODO(user): add forwarding-to-ImmutableSortedMap test
+ return suite;
+ }
+
+ @Override public void setUp() throws Exception {
+ super.setUp();
+ /*
+ * Class parameters must be raw, so we can't create a proxy with generic
+ * type arguments. The created proxy only records calls and returns null, so
+ * the type is irrelevant at runtime.
+ */
+ @SuppressWarnings("unchecked")
+ final NavigableMap<String, Boolean> sortedMap =
+ createProxyInstance(NavigableMap.class);
+ forward = new ForwardingNavigableMap<String, Boolean>() {
+ @Override protected NavigableMap<String, Boolean> delegate() {
+ return sortedMap;
+ }
+ };
+ }
+
+ public void testStandardLastEntry() {
+ NavigableMap<String, Integer> forwarding =
+ new StandardLastEntryForwardingNavigableMap<String, Integer>(
+ new SafeTreeMap<String, Integer>());
+ assertNull(forwarding.lastEntry());
+ forwarding.put("b", 2);
+ assertEquals(immutableEntry("b", 2), forwarding.lastEntry());
+ forwarding.put("c", 3);
+ assertEquals(immutableEntry("c", 3), forwarding.lastEntry());
+ forwarding.put("a", 1);
+ assertEquals(immutableEntry("c", 3), forwarding.lastEntry());
+ forwarding.remove("c");
+ assertEquals(immutableEntry("b", 2), forwarding.lastEntry());
+ }
+
+ public void testLowerEntry() {
+ forward().lowerEntry("key");
+ assertEquals("[lowerEntry(Object)]", getCalls());
+ }
+
+ public void testLowerKey() {
+ forward().lowerKey("key");
+ assertEquals("[lowerKey(Object)]", getCalls());
+ }
+
+ public void testFloorEntry() {
+ forward().floorEntry("key");
+ assertEquals("[floorEntry(Object)]", getCalls());
+ }
+
+ public void testFloorKey() {
+ forward().floorKey("key");
+ assertEquals("[floorKey(Object)]", getCalls());
+ }
+
+ public void testCeilingEntry() {
+ forward().ceilingEntry("key");
+ assertEquals("[ceilingEntry(Object)]", getCalls());
+ }
+
+ public void testCeilingKey() {
+ forward().ceilingKey("key");
+ assertEquals("[ceilingKey(Object)]", getCalls());
+ }
+
+ public void testHigherEntry() {
+ forward().higherEntry("key");
+ assertEquals("[higherEntry(Object)]", getCalls());
+ }
+
+ public void testHigherKey() {
+ forward().higherKey("key");
+ assertEquals("[higherKey(Object)]", getCalls());
+ }
+
+ public void testPollFirstEntry() {
+ forward().pollFirstEntry();
+ assertEquals("[pollFirstEntry]", getCalls());
+ }
+
+ public void testPollLastEntry() {
+ forward().pollLastEntry();
+ assertEquals("[pollLastEntry]", getCalls());
+ }
+
+ public void testFirstEntry() {
+ forward().firstEntry();
+ assertEquals("[firstEntry]", getCalls());
+ }
+
+ public void testLastEntry() {
+ forward().lastEntry();
+ assertEquals("[lastEntry]", getCalls());
+ }
+
+ public void testDescendingMap() {
+ forward().descendingMap();
+ assertEquals("[descendingMap]", getCalls());
+ }
+
+ public void testNavigableKeySet() {
+ forward().navigableKeySet();
+ assertEquals("[navigableKeySet]", getCalls());
+ }
+
+ public void testDescendingKeySet() {
+ forward().descendingKeySet();
+ assertEquals("[descendingKeySet]", getCalls());
+ }
+
+ public void testSubMap_K_Bool_K_Bool() {
+ forward().subMap("a", false, "b", true);
+ assertEquals("[subMap(Object,boolean,Object,boolean)]", getCalls());
+ }
+
+ public void testHeadMap_K_Bool() {
+ forward().headMap("a", false);
+ assertEquals("[headMap(Object,boolean)]", getCalls());
+ }
+
+ public void testTailMap_K_Bool() {
+ forward().tailMap("a", false);
+ assertEquals("[tailMap(Object,boolean)]", getCalls());
+ }
+
+ @Override NavigableMap<String, Boolean> forward() {
+ return (NavigableMap<String, Boolean>) super.forward();
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingNavigableSetTest.java b/guava-tests/test/com/google/common/collect/ForwardingNavigableSetTest.java
new file mode 100644
index 0000000..37b65f0
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/ForwardingNavigableSetTest.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.collect.testing.SafeTreeSet;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.TestStringSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.SortedSet;
+
+/**
+ * Tests for {@code ForwardingNavigableSet}.
+ *
+ * @author Louis Wasserman
+ */
+public class ForwardingNavigableSetTest extends ForwardingSortedSetTest {
+ static class StandardImplForwardingNavigableSet<T>
+ extends ForwardingNavigableSet<T> {
+ private final NavigableSet<T> backingSet;
+
+ StandardImplForwardingNavigableSet(NavigableSet<T> backingSet) {
+ this.backingSet = backingSet;
+ }
+
+ @Override protected NavigableSet<T> delegate() {
+ return backingSet;
+ }
+
+ @Override public boolean equals(Object object) {
+ return standardEquals(object);
+ }
+
+ @Override public int hashCode() {
+ return standardHashCode();
+ }
+
+ @Override public boolean addAll(Collection<? extends T> collection) {
+ return standardAddAll(collection);
+ }
+
+ @Override public void clear() {
+ standardClear();
+ }
+
+ @Override public boolean contains(Object object) {
+ return standardContains(object);
+ }
+
+ @Override public boolean containsAll(Collection<?> collection) {
+ return standardContainsAll(collection);
+ }
+
+ @Override public boolean remove(Object object) {
+ return standardRemove(object);
+ }
+
+ @Override public boolean removeAll(Collection<?> collection) {
+ return standardRemoveAll(collection);
+ }
+
+ @Override public boolean retainAll(Collection<?> collection) {
+ return standardRetainAll(collection);
+ }
+
+ @Override public Object[] toArray() {
+ return standardToArray();
+ }
+
+ @Override public <T> T[] toArray(T[] array) {
+ return standardToArray(array);
+ }
+
+ @Override public String toString() {
+ return standardToString();
+ }
+
+ @Override public SortedSet<T> subSet(T fromElement, T toElement) {
+ return standardSubSet(fromElement, toElement);
+ }
+
+ @Override
+ public T lower(T e) {
+ return standardLower(e);
+ }
+
+ @Override
+ public T floor(T e) {
+ return standardFloor(e);
+ }
+
+ @Override
+ public T ceiling(T e) {
+ return standardCeiling(e);
+ }
+
+ @Override
+ public T higher(T e) {
+ return standardHigher(e);
+ }
+
+ @Override
+ public T pollFirst() {
+ return standardPollFirst();
+ }
+
+ @Override
+ public T pollLast() {
+ return standardPollLast();
+ }
+
+ @Override
+ public SortedSet<T> headSet(T toElement) {
+ return standardHeadSet(toElement);
+ }
+
+ @Override
+ public SortedSet<T> tailSet(T fromElement) {
+ return standardTailSet(fromElement);
+ }
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTestSuite(ForwardingNavigableSetTest.class);
+ suite.addTest(
+ SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ return new StandardImplForwardingNavigableSet<String>(
+ new SafeTreeSet<String>(Arrays.asList(elements)));
+ }
+
+ @Override public List<String> order(List<String> insertionOrder) {
+ return Lists.newArrayList(Sets.newTreeSet(insertionOrder));
+ }
+ }).named(
+ "ForwardingNavigableSet[SafeTreeSet] with standard implementations")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE).createTestSuite());
+ suite.addTest(
+ SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ SafeTreeSet<String> set = new SafeTreeSet<String>(Ordering.natural().nullsFirst());
+ set.addAll(Arrays.asList(elements));
+ return new StandardImplForwardingNavigableSet<String>(set);
+ }
+
+ @Override public List<String> order(List<String> insertionOrder) {
+ return Lists.newArrayList(Sets.newTreeSet(insertionOrder));
+ }
+ }).named(
+ "ForwardingNavigableSet[SafeTreeSet[Ordering.natural.nullsFirst]]"
+ + " with standard implementations")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE, CollectionFeature.ALLOWS_NULL_VALUES)
+ .createTestSuite());
+
+ return suite;
+ }
+
+ @Override public void setUp() throws Exception {
+ super.setUp();
+ /*
+ * Class parameters must be raw, so we can't create a proxy with generic
+ * type arguments. The created proxy only records calls and returns null, so
+ * the type is irrelevant at runtime.
+ */
+ @SuppressWarnings("unchecked")
+ final NavigableSet<String> navigableSet
+ = createProxyInstance(NavigableSet.class);
+ forward = new ForwardingNavigableSet<String>() {
+ @Override protected NavigableSet<String> delegate() {
+ return navigableSet;
+ }
+ };
+ }
+
+ public void testLower() {
+ forward().lower("a");
+ assertEquals("[lower(Object)]", getCalls());
+ }
+
+ public void testFloor() {
+ forward().floor("a");
+ assertEquals("[floor(Object)]", getCalls());
+ }
+
+ public void testCeiling() {
+ forward().ceiling("a");
+ assertEquals("[ceiling(Object)]", getCalls());
+ }
+
+ public void testHigher() {
+ forward().higher("a");
+ assertEquals("[higher(Object)]", getCalls());
+ }
+
+ public void testPollFirst() {
+ forward().pollFirst();
+ assertEquals("[pollFirst]", getCalls());
+ }
+
+ public void testPollLast() {
+ forward().pollLast();
+ assertEquals("[pollLast]", getCalls());
+ }
+
+ public void testDescendingIterator() {
+ forward().descendingIterator();
+ assertEquals("[descendingIterator]", getCalls());
+ }
+
+ public void testHeadSet_K_Boolean() {
+ forward().headSet("key", false);
+ assertEquals("[headSet(Object,boolean)]", getCalls());
+ }
+
+ public void testSubSet_K_Boolean_K_Boolean() {
+ forward().subSet("a", true, "b", false);
+ assertEquals("[subSet(Object,boolean,Object,boolean)]", getCalls());
+ }
+
+ public void testTailSet_K_Boolean() {
+ forward().tailSet("key", false);
+ assertEquals("[tailSet(Object,boolean)]", getCalls());
+ }
+
+ @Override NavigableSet<String> forward() {
+ return (NavigableSet<String>) super.forward();
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java b/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java
index c8f0bfe..6c3a2b6 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingQueueTest.java
@@ -106,7 +106,7 @@ public class ForwardingQueueTest extends ForwardingTestCase {
private Queue<String> forward;
private Queue<String> queue;
- public static Test suite(){
+ public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingQueueTest.class);
diff --git a/guava-tests/test/com/google/common/collect/ForwardingSetTest.java b/guava-tests/test/com/google/common/collect/ForwardingSetTest.java
index 19484fc..c4b7b3c 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingSetTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingSetTest.java
@@ -104,7 +104,7 @@ public class ForwardingSetTest extends ForwardingTestCase {
Set<String> forward;
- public static Test suite(){
+ public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingSetTest.class);
diff --git a/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java b/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java
index 54947ba..2f0e46d 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingSortedMapTest.java
@@ -16,9 +16,10 @@
package com.google.common.collect;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
+import com.google.common.collect.testing.Helpers.NullsBeforeTwo;
import com.google.common.collect.testing.SafeTreeMap;
-import com.google.common.collect.testing.TestStringMapGenerator;
+import com.google.common.collect.testing.SortedMapTestSuiteBuilder;
+import com.google.common.collect.testing.TestStringSortedMapGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
@@ -29,7 +30,6 @@ import junit.framework.TestSuite;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -115,8 +115,8 @@ public class ForwardingSortedMapTest extends ForwardingMapTest {
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingSortedMapTest.class);
- suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
- @Override protected Map<String, String> create(
+ suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ @Override protected SortedMap<String, String> create(
Entry<String, String>[] entries) {
SortedMap<String, String> map = new SafeTreeMap<String, String>();
for (Entry<String, String> entry : entries) {
@@ -124,20 +124,14 @@ public class ForwardingSortedMapTest extends ForwardingMapTest {
}
return new StandardImplForwardingSortedMap<String, String>(map);
}
-
- @Override public Iterable<Entry<String, String>> order(
- List<Entry<String, String>> insertionOrder) {
- return sort(insertionOrder);
- }
}).named("ForwardingSortedMap[SafeTreeMap] with no comparator and standard "
+ "implementations").withFeatures(CollectionSize.ANY,
CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES,
MapFeature.GENERAL_PURPOSE).createTestSuite());
- suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
- private final Comparator<String> comparator =
- Ordering.natural().nullsFirst();
+ suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ private final Comparator<String> comparator = NullsBeforeTwo.INSTANCE;
- @Override protected Map<String, String> create(
+ @Override protected SortedMap<String, String> create(
Entry<String, String>[] entries) {
SortedMap<String, String> map =
new SafeTreeMap<String, String>(comparator);
@@ -146,18 +140,13 @@ public class ForwardingSortedMapTest extends ForwardingMapTest {
}
return new StandardImplForwardingSortedMap<String, String>(map);
}
-
- @Override public Iterable<Entry<String, String>> order(
- List<Entry<String, String>> insertionOrder) {
- return sort(insertionOrder);
- }
}).named("ForwardingSortedMap[SafeTreeMap] with natural comparator and "
+ "standard implementations").withFeatures(CollectionSize.ANY,
CollectionFeature.KNOWN_ORDER, MapFeature.ALLOWS_NULL_VALUES,
MapFeature.ALLOWS_NULL_KEYS, MapFeature.GENERAL_PURPOSE)
.createTestSuite());
- suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
- @Override protected Map<String, String> create(
+ suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ @Override protected SortedMap<String, String> create(
Entry<String, String>[] entries) {
ImmutableSortedMap.Builder<String, String> builder =
ImmutableSortedMap.naturalOrder();
@@ -167,11 +156,6 @@ public class ForwardingSortedMapTest extends ForwardingMapTest {
return new StandardImplForwardingSortedMap<String, String>(
builder.build());
}
-
- @Override public Iterable<Entry<String, String>> order(
- List<Entry<String, String>> insertionOrder) {
- return sort(insertionOrder);
- }
}).named("ForwardingSortedMap[ImmutableSortedMap] with standard "
+ "implementations").withFeatures(
CollectionSize.ANY, MapFeature.REJECTS_DUPLICATES_AT_CREATION,
@@ -180,16 +164,6 @@ public class ForwardingSortedMapTest extends ForwardingMapTest {
return suite;
}
-
- private static Iterable<Entry<String, String>> sort(
- List<Entry<String, String>> entries) {
- SortedMap<String, String> map =
- new SafeTreeMap<String, String>(Ordering.natural().nullsFirst());
- for (Entry<String, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- return map.entrySet();
- }
@Override public void setUp() throws Exception {
super.setUp();
diff --git a/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java b/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java
index 4bf9dd7..3f51db3 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingSortedSetTest.java
@@ -102,7 +102,7 @@ public class ForwardingSortedSetTest extends ForwardingSetTest {
}
}
- public static Test suite(){
+ public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(ForwardingSortedSetTest.class);
diff --git a/guava-tests/test/com/google/common/collect/ForwardingTestCase.java b/guava-tests/test/com/google/common/collect/ForwardingTestCase.java
index d43d7b7..9696176 100644
--- a/guava-tests/test/com/google/common/collect/ForwardingTestCase.java
+++ b/guava-tests/test/com/google/common/collect/ForwardingTestCase.java
@@ -42,7 +42,7 @@ import java.util.Set;
*/
public abstract class ForwardingTestCase extends TestCase {
- private List<String> calls = new ArrayList<String>();
+ private final List<String> calls = new ArrayList<String>();
private void called(String id) {
calls.add(id);
diff --git a/guava-tests/test/com/google/common/collect/GeneralRangeTest.java b/guava-tests/test/com/google/common/collect/GeneralRangeTest.java
index a90e5d1..46f2e75 100644
--- a/guava-tests/test/com/google/common/collect/GeneralRangeTest.java
+++ b/guava-tests/test/com/google/common/collect/GeneralRangeTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -17,20 +17,19 @@ package com.google.common.collect;
import static com.google.common.collect.BoundType.CLOSED;
import static com.google.common.collect.BoundType.OPEN;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-
-import junit.framework.TestCase;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Objects;
import com.google.common.testing.NullPointerTester;
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.List;
+
/**
* Tests for {@code GeneralRange}.
- *
+ *
* @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
@@ -43,7 +42,7 @@ public class GeneralRangeTest extends TestCase {
for (BoundType lboundType : BoundType.values()) {
for (BoundType uboundType : BoundType.values()) {
try {
- GeneralRange<Integer> range = GeneralRange.range(ORDERING, 4, lboundType, 2, uboundType);
+ GeneralRange.range(ORDERING, 4, lboundType, 2, uboundType);
fail("Expected IAE");
} catch (IllegalArgumentException expected) {}
}
@@ -122,7 +121,7 @@ public class GeneralRangeTest extends TestCase {
public void testDoublyBoundedAgainstRange() {
for (BoundType lboundType : BoundType.values()) {
for (BoundType uboundType : BoundType.values()) {
- Range<Integer> range = Ranges.range(2, lboundType, 4, uboundType);
+ Range<Integer> range = Range.range(2, lboundType, 4, uboundType);
GeneralRange<Integer> gRange = GeneralRange.range(ORDERING, 2, lboundType, 4, uboundType);
for (Integer i : IN_ORDER_VALUES) {
assertEquals(i != null && range.contains(i), gRange.contains(i));
@@ -171,16 +170,16 @@ public class GeneralRangeTest extends TestCase {
}
public void testFromRangeAll() {
- assertEquals(GeneralRange.all(Ordering.natural()), GeneralRange.from(Ranges.all()));
+ assertEquals(GeneralRange.all(Ordering.natural()), GeneralRange.from(Range.all()));
}
public void testFromRangeOneEnd() {
for (BoundType endpointType : BoundType.values()) {
assertEquals(GeneralRange.upTo(Ordering.natural(), 3, endpointType),
- GeneralRange.from(Ranges.upTo(3, endpointType)));
+ GeneralRange.from(Range.upTo(3, endpointType)));
assertEquals(GeneralRange.downTo(Ordering.natural(), 3, endpointType),
- GeneralRange.from(Ranges.downTo(3, endpointType)));
+ GeneralRange.from(Range.downTo(3, endpointType)));
}
}
@@ -188,7 +187,7 @@ public class GeneralRangeTest extends TestCase {
for (BoundType lowerType : BoundType.values()) {
for (BoundType upperType : BoundType.values()) {
assertEquals(GeneralRange.range(Ordering.natural(), 3, lowerType, 4, upperType),
- GeneralRange.from(Ranges.range(3, lowerType, 4, upperType)));
+ GeneralRange.from(Range.range(3, lowerType, 4, upperType)));
}
}
}
@@ -204,10 +203,7 @@ public class GeneralRangeTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Comparator.class, Ordering.arbitrary());
- tester.setDefault(BoundType.class, BoundType.CLOSED);
- tester.testAllPublicStaticMethods(GeneralRange.class);
+ public void testNullPointers() {
+ new NullPointerTester().testAllPublicStaticMethods(GeneralRange.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/HashBasedTableTest.java b/guava-tests/test/com/google/common/collect/HashBasedTableTest.java
index 66f033b..11a1c2c 100644
--- a/guava-tests/test/com/google/common/collect/HashBasedTableTest.java
+++ b/guava-tests/test/com/google/common/collect/HashBasedTableTest.java
@@ -23,7 +23,7 @@ import com.google.common.testing.SerializableTester;
/**
* Test cases for {@link HashBasedTable}.
- *
+ *
* @author Jared Levy
*/
@GwtCompatible(emulated = true)
@@ -38,20 +38,20 @@ public class HashBasedTableTest extends AbstractTableTest {
populate(table, data);
return table;
}
-
+
public void testCreateWithValidSizes() {
Table<String, Integer, Character> table1 = HashBasedTable.create(100, 20);
table1.put("foo", 1, 'a');
assertEquals((Character) 'a', table1.get("foo", 1));
-
+
Table<String, Integer, Character> table2 = HashBasedTable.create(100, 0);
table2.put("foo", 1, 'a');
assertEquals((Character) 'a', table2.get("foo", 1));
-
+
Table<String, Integer, Character> table3 = HashBasedTable.create(0, 20);
table3.put("foo", 1, 'a');
assertEquals((Character) 'a', table3.get("foo", 1));
-
+
Table<String, Integer, Character> table4 = HashBasedTable.create(0, 0);
table4.put("foo", 1, 'a');
assertEquals((Character) 'a', table4.get("foo", 1));
@@ -62,29 +62,29 @@ public class HashBasedTableTest extends AbstractTableTest {
HashBasedTable.create(100, -5);
fail();
} catch (IllegalArgumentException expected) {}
-
+
try {
HashBasedTable.create(-5, 20);
fail();
} catch (IllegalArgumentException expected) {}
}
-
+
public void testCreateCopy() {
Table<String, Integer, Character> original
= create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Table<String, Integer, Character> copy = HashBasedTable.create(original);
assertEquals(original, copy);
- assertEquals((Character) 'a', copy.get("foo", 1));
+ assertEquals((Character) 'a', copy.get("foo", 1));
}
-
+
@GwtIncompatible("SerializableTester")
public void testSerialization() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
SerializableTester.reserializeAndAssert(table);
}
-
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointerStatic() throws Exception {
+ public void testNullPointerStatic() {
new NullPointerTester().testAllPublicStaticMethods(HashBasedTable.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/HashBiMapTest.java b/guava-tests/test/com/google/common/collect/HashBiMapTest.java
index f8661ad..935e228 100644
--- a/guava-tests/test/com/google/common/collect/HashBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/HashBiMapTest.java
@@ -17,8 +17,17 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringBiMapGenerator;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
-import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
@@ -29,19 +38,33 @@ import java.util.Set;
*
* @author Mike Bostock
*/
-@GwtCompatible
-public class HashBiMapTest extends AbstractBiMapTest {
+@GwtCompatible(emulated = true)
+public class HashBiMapTest extends TestCase {
- @Override protected BiMap<Integer, String> create() {
- return HashBiMap.create();
+ public static final class HashBiMapGenerator extends TestStringBiMapGenerator {
+ @Override
+ protected BiMap<String, String> create(Entry<String, String>[] entries) {
+ BiMap<String, String> result = HashBiMap.create();
+ for (Entry<String, String> entry : entries) {
+ result.put(entry.getKey(), entry.getValue());
+ }
+ return result;
+ }
}
- public void testCreate() {
- BiMap<String, String> bimap = HashBiMap.create();
- assertEquals(0, bimap.size());
- bimap.put("canada", "dollar");
- assertEquals("dollar", bimap.get("canada"));
- assertEquals("canada", bimap.inverse().get("dollar"));
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(BiMapTestSuiteBuilder.using(new HashBiMapGenerator())
+ .named("HashBiMap")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE)
+ .createTestSuite());
+ suite.addTestSuite(HashBiMapTest.class);
+ return suite;
}
public void testMapConstructor() {
@@ -89,35 +112,16 @@ public class HashBiMapTest extends AbstractBiMapTest {
}
}
- // The next two tests verify that map entries are not accessed after they're
- // removed, since IdentityHashMap throws an exception when that occurs.
- public void testIdentityKeySetIteratorRemove() {
- bimap = new AbstractBiMap<Integer, String>(
- new IdentityHashMap<Integer, String>(),
- new IdentityHashMap<String, Integer>()) {};
- putOneTwoThree();
- Iterator<Integer> iterator = bimap.keySet().iterator();
- iterator.next();
- iterator.next();
- iterator.remove();
- iterator.next();
- iterator.remove();
- assertEquals(1, bimap.size());
- assertEquals(1, bimap.inverse().size());
- }
-
- public void testIdentityEntrySetIteratorRemove() {
- bimap = new AbstractBiMap<Integer, String>(
- new IdentityHashMap<Integer, String>(),
- new IdentityHashMap<String, Integer>()) {};
- putOneTwoThree();
- Iterator<Entry<Integer, String>> iterator = bimap.entrySet().iterator();
- iterator.next();
- iterator.next();
- iterator.remove();
- iterator.next();
- iterator.remove();
- assertEquals(1, bimap.size());
- assertEquals(1, bimap.inverse().size());
+ public void testBiMapEntrySetIteratorRemove() {
+ BiMap<Integer, String> map = HashBiMap.create();
+ map.put(1, "one");
+ Set<Map.Entry<Integer, String>> entries = map.entrySet();
+ Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
+ Map.Entry<Integer, String> entry = iterator.next();
+ entry.setValue("two"); // changes the iterator's current entry value
+ assertEquals("two", map.get(1));
+ assertEquals(Integer.valueOf(1), map.inverse().get("two"));
+ iterator.remove(); // removes the updated entry
+ assertTrue(map.isEmpty());
}
}
diff --git a/guava-tests/test/com/google/common/collect/HashMultimapTest.java b/guava-tests/test/com/google/common/collect/HashMultimapTest.java
index 4264a94..490cd84 100644
--- a/guava-tests/test/com/google/common/collect/HashMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/HashMultimapTest.java
@@ -17,14 +17,52 @@
package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.util.Map.Entry;
/**
* Unit tests for {@link HashMultimap}.
*
* @author Jared Levy
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class HashMultimapTest extends AbstractSetMultimapTest {
+
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(SetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() {
+ @Override
+ protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
+ SetMultimap<String, String> multimap = HashMultimap.create();
+ for (Entry<String, String> entry : entries) {
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return multimap;
+ }
+ })
+ .named("HashMultimap")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
+ CollectionFeature.SERIALIZABLE,
+ CollectionSize.ANY)
+ .createTestSuite());
+ suite.addTestSuite(HashMultimapTest.class);
+ return suite;
+ }
+
@Override protected Multimap<String, Integer> create() {
return HashMultimap.create();
}
@@ -39,14 +77,14 @@ public class HashMultimapTest extends AbstractSetMultimapTest {
multimap.put("bar", 2);
multimap.put("foo", 3);
assertEquals(ImmutableSet.of(1, 3), multimap.get("foo"));
- assertEquals(8, multimap.expectedValuesPerKey);
+ assertEquals(2, multimap.expectedValuesPerKey);
}
public void testCreateFromMultimap() {
Multimap<String, Integer> multimap = createSample();
HashMultimap<String, Integer> copy = HashMultimap.create(multimap);
assertEquals(multimap, copy);
- assertEquals(8, copy.expectedValuesPerKey);
+ assertEquals(2, copy.expectedValuesPerKey);
}
public void testCreateFromSizes() {
diff --git a/guava-tests/test/com/google/common/collect/HashMultisetTest.java b/guava-tests/test/com/google/common/collect/HashMultisetTest.java
index 6e20b07..9e68156 100644
--- a/guava-tests/test/com/google/common/collect/HashMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/HashMultisetTest.java
@@ -16,10 +16,19 @@
package com.google.common.collect;
+import static java.util.Arrays.asList;
+
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringMultisetGenerator;
import com.google.common.testing.SerializableTester;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
import java.io.Serializable;
import java.util.Arrays;
@@ -31,6 +40,29 @@ import java.util.Arrays;
*/
@GwtCompatible(emulated = true)
public class HashMultisetTest extends AbstractMultisetTest {
+
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(MultisetTestSuiteBuilder.using(hashMultisetGenerator())
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.GENERAL_PURPOSE)
+ .named("HashMultiset")
+ .createTestSuite());
+ suite.addTestSuite(HashMultisetTest.class);
+ return suite;
+ }
+
+ private static TestStringMultisetGenerator hashMultisetGenerator() {
+ return new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ return HashMultiset.create(asList(elements));
+ }
+ };
+ }
+
@Override protected <E> Multiset<E> create() {
return HashMultiset.create();
}
@@ -92,30 +124,20 @@ public class HashMultisetTest extends AbstractMultisetTest {
* iteration order.
*/
- /**
- * This test fails with Java 6, preventing us from running
- * NullPointerTester on multisets.
- public void testAnnotations() throws Exception {
- Method method = HashMultiset.class.getDeclaredMethod(
- "add", Object.class, int.class);
- assertTrue(method.getParameterAnnotations()[0].length > 0);
- }
- */
-
@Override
@GwtIncompatible(
"http://code.google.com/p/google-web-toolkit/issues/detail?id=3421")
public void testEntryAfterRemove() {
super.testEntryAfterRemove();
}
-
+
@Override
@GwtIncompatible(
"http://code.google.com/p/google-web-toolkit/issues/detail?id=3421")
public void testEntryAfterClear() {
super.testEntryAfterClear();
}
-
+
@Override
@GwtIncompatible(
"http://code.google.com/p/google-web-toolkit/issues/detail?id=3421")
@@ -129,7 +151,7 @@ public class HashMultisetTest extends AbstractMultisetTest {
public void testEntryAfterEntrySetIteratorRemove() {
super.testEntryAfterEntrySetIteratorRemove();
}
-
+
@Override
@GwtIncompatible(
"http://code.google.com/p/google-web-toolkit/issues/detail?id=3421")
diff --git a/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java
index 223b0aa..c74a43d 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableBiMapTest.java
@@ -16,23 +16,19 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableBiMap.Builder;
import com.google.common.collect.testing.MapInterfaceTest;
-import com.google.common.collect.testing.ReserializingTestSetGenerator;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapEntrySetGenerator;
-import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapInverseEntrySetGenerator;
-import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapInverseKeySetGenerator;
-import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapInverseValuesGenerator;
-import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapKeySetGenerator;
-import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapValuesGenerator;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.BiMapGenerators.ImmutableBiMapGenerator;
+import com.google.common.collect.testing.google.BiMapInverseTester;
+import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
import com.google.common.testing.SerializableTester;
import junit.framework.Test;
@@ -64,77 +60,14 @@ public class ImmutableBiMapTest extends TestCase {
suite.addTestSuite(CreationTests.class);
suite.addTestSuite(BiMapSpecificTests.class);
- suite.addTest(SetTestSuiteBuilder.using(new ImmutableBiMapKeySetGenerator())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableBiMap.keySet")
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableBiMapEntrySetGenerator())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableBiMap.entrySet")
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new ImmutableBiMapValuesGenerator())
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableBiMap.values")
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableBiMapInverseKeySetGenerator())
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableBiMap.inverse.keys")
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableBiMapInverseEntrySetGenerator())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableBiMap.inverse.entrySet")
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableBiMapInverseValuesGenerator())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableBiMap.inverse.values")
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- ReserializingTestSetGenerator.newInstance(
- new ImmutableBiMapKeySetGenerator()))
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableBiMap.keySet, reserialized")
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- ReserializingTestSetGenerator.newInstance(
- new ImmutableBiMapEntrySetGenerator()))
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableBiMap.entrySet, reserialized")
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- ReserializingTestSetGenerator.newInstance(
- new ImmutableBiMapValuesGenerator()))
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ suite.addTest(BiMapTestSuiteBuilder.using(new ImmutableBiMapGenerator())
+ .named("ImmutableBiMap")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableBiMap.values, reserialized")
+ MapFeature.REJECTS_DUPLICATES_AT_CREATION,
+ MapFeature.ALLOWS_NULL_QUERIES)
+ .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods())
.createTestSuite());
return suite;
@@ -334,7 +267,7 @@ public class ImmutableBiMapTest extends TestCase {
builder.build();
fail();
} catch (IllegalArgumentException expected) {
- assertEquals("duplicate key: one", expected.getMessage());
+ assertTrue(expected.getMessage().contains("one"));
}
}
@@ -407,7 +340,7 @@ public class ImmutableBiMapTest extends TestCase {
ImmutableBiMap.of("one", 1, "one", 1);
fail();
} catch (IllegalArgumentException expected) {
- assertEquals("duplicate key: one", expected.getMessage());
+ assertTrue(expected.getMessage().contains("one"));
}
}
@@ -481,13 +414,14 @@ public class ImmutableBiMapTest extends TestCase {
ImmutableBiMap.copyOf(map);
fail();
} catch (IllegalArgumentException expected) {
- assertEquals("duplicate key: 1", expected.getMessage());
+ assertTrue(expected.getMessage().contains("1"));
}
}
}
public static class BiMapSpecificTests extends TestCase {
+ @SuppressWarnings("deprecation")
public void testForcePut() {
ImmutableBiMap<String, Integer> bimap = ImmutableBiMap.copyOf(
ImmutableMap.of("one", 1, "two", 2));
@@ -502,7 +436,7 @@ public class ImmutableBiMapTest extends TestCase {
ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4));
Set<String> keys = bimap.keySet();
assertEquals(Sets.newHashSet("one", "two", "three", "four"), keys);
- ASSERT.that(keys).hasContentsInOrder("one", "two", "three", "four");
+ ASSERT.that(keys).has().allOf("one", "two", "three", "four").inOrder();
}
public void testValues() {
@@ -510,7 +444,7 @@ public class ImmutableBiMapTest extends TestCase {
ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4));
Set<Integer> values = bimap.values();
assertEquals(Sets.newHashSet(1, 2, 3, 4), values);
- ASSERT.that(values).hasContentsInOrder(1, 2, 3, 4);
+ ASSERT.that(values).has().allOf(1, 2, 3, 4).inOrder();
}
public void testDoubleInverse() {
diff --git a/guava-tests/test/com/google/common/collect/ImmutableCollectionTest.java b/guava-tests/test/com/google/common/collect/ImmutableCollectionTest.java
new file mode 100644
index 0000000..535c85a
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/ImmutableCollectionTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@code ImmutableCollection}.
+ *
+ * @author Louis Wasserman
+ */
+public class ImmutableCollectionTest extends TestCase {
+ public void testCapacityExpansion() {
+ assertEquals(1, ImmutableCollection.Builder.expandedCapacity(0, 1));
+ assertEquals(2, ImmutableCollection.Builder.expandedCapacity(0, 2));
+ assertEquals(2, ImmutableCollection.Builder.expandedCapacity(1, 2));
+ assertEquals(Integer.MAX_VALUE,
+ ImmutableCollection.Builder.expandedCapacity(0, Integer.MAX_VALUE));
+ assertEquals(Integer.MAX_VALUE,
+ ImmutableCollection.Builder.expandedCapacity(1, Integer.MAX_VALUE));
+ assertEquals(Integer.MAX_VALUE,
+ ImmutableCollection.Builder.expandedCapacity(Integer.MAX_VALUE - 1, Integer.MAX_VALUE));
+
+ assertEquals(13, ImmutableCollection.Builder.expandedCapacity(8, 9));
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java
new file mode 100644
index 0000000..48c0a0b
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/ImmutableEnumMapTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.testing.AnEnum;
+import com.google.common.collect.testing.Helpers;
+import com.google.common.collect.testing.MapTestSuiteBuilder;
+import com.google.common.collect.testing.TestEnumMapGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Tests for {@code ImmutableEnumMap}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible
+public class ImmutableEnumMapTest extends TestCase {
+ public static class ImmutableEnumMapGenerator extends TestEnumMapGenerator {
+ @Override
+ protected Map<AnEnum, String> create(Entry<AnEnum, String>[] entries) {
+ Map<AnEnum, String> map = Maps.newHashMap();
+ for (Entry<AnEnum, String> entry : entries) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ return Maps.immutableEnumMap(map);
+ }
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(MapTestSuiteBuilder.using(new ImmutableEnumMapGenerator())
+ .named("Maps.immutableEnumMap")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+ suite.addTestSuite(ImmutableEnumMapTest.class);
+ return suite;
+ }
+
+ public void testEmptyImmutableEnumMap() {
+ ImmutableMap<AnEnum, String> map = Maps.immutableEnumMap(ImmutableMap.<AnEnum, String>of());
+ assertEquals(ImmutableMap.of(), map);
+ }
+
+ public void testImmutableEnumMapOrdering() {
+ ImmutableMap<AnEnum, String> map = Maps.immutableEnumMap(
+ ImmutableMap.of(AnEnum.C, "c", AnEnum.A, "a", AnEnum.E, "e"));
+
+ ASSERT.that(map.entrySet()).has().allOf(
+ Helpers.mapEntry(AnEnum.A, "a"),
+ Helpers.mapEntry(AnEnum.C, "c"),
+ Helpers.mapEntry(AnEnum.E, "e")).inOrder();
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java b/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java
index fb8f6b4..d2a8d98 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableListMultimapTest.java
@@ -16,16 +16,23 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableListMultimap.Builder;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringListMultimapGenerator;
import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.SerializableTester;
+import junit.framework.Test;
import junit.framework.TestCase;
+import junit.framework.TestSuite;
import java.util.Arrays;
import java.util.Collection;
@@ -39,6 +46,31 @@ import java.util.Map.Entry;
*/
@GwtCompatible(emulated = true)
public class ImmutableListMultimapTest extends TestCase {
+ public static class ImmutableListMultimapGenerator extends TestStringListMultimapGenerator {
+ @Override
+ protected ListMultimap<String, String> create(Entry<String, String>[] entries) {
+ ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
+ for (Entry<String, String> entry : entries) {
+ builder.put(entry.getKey(), entry.getValue());
+ }
+ return builder.build();
+ }
+ }
+
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(ListMultimapTestSuiteBuilder.using(new ImmutableListMultimapGenerator())
+ .named("ImmutableListMultimap")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_QUERIES,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionSize.ANY)
+ .createTestSuite());
+ suite.addTestSuite(ImmutableListMultimapTest.class);
+ return suite;
+ }
public void testBuilder_withImmutableEntry() {
ImmutableListMultimap<String, Integer> multimap = new Builder<String, Integer>()
@@ -231,10 +263,32 @@ public class ImmutableListMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableListMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).hasContentsInOrder("d", "c", "b", "a");
- ASSERT.that(multimap.values()).hasContentsInOrder(2, 4, 3, 6, 5, 2);
- ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
- ASSERT.that(multimap.get("b")).hasContentsInOrder(3, 6);
+ ASSERT.that(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder();
+ ASSERT.that(multimap.values()).has().allOf(2, 4, 3, 6, 5, 2).inOrder();
+ ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
+ ASSERT.that(multimap.get("b")).has().allOf(3, 6).inOrder();
+ }
+
+ public void testBuilderOrderKeysByDuplicates() {
+ ImmutableListMultimap.Builder<String, Integer> builder
+ = ImmutableListMultimap.builder();
+ builder.put("bb", 3);
+ builder.put("d", 2);
+ builder.put("a", 5);
+ builder.orderKeysBy(new Ordering<String>() {
+ @Override
+ public int compare(String left, String right) {
+ return left.length() - right.length();
+ }
+ });
+ builder.put("cc", 4);
+ builder.put("a", 2);
+ builder.put("bb", 6);
+ ImmutableListMultimap<String, Integer> multimap = builder.build();
+ ASSERT.that(multimap.keySet()).has().allOf("d", "a", "bb", "cc").inOrder();
+ ASSERT.that(multimap.values()).has().allOf(2, 5, 2, 3, 6, 4).inOrder();
+ ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
+ ASSERT.that(multimap.get("bb")).has().allOf(3, 6).inOrder();
}
public void testBuilderOrderValuesBy() {
@@ -248,10 +302,10 @@ public class ImmutableListMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableListMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).hasContentsInOrder("b", "d", "a", "c");
- ASSERT.that(multimap.values()).hasContentsInOrder(6, 3, 2, 5, 2, 4);
- ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
- ASSERT.that(multimap.get("b")).hasContentsInOrder(6, 3);
+ ASSERT.that(multimap.keySet()).has().allOf("b", "d", "a", "c").inOrder();
+ ASSERT.that(multimap.values()).has().allOf(6, 3, 2, 5, 2, 4).inOrder();
+ ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
+ ASSERT.that(multimap.get("b")).has().allOf(6, 3).inOrder();
}
public void testBuilderOrderKeysAndValuesBy() {
@@ -266,10 +320,10 @@ public class ImmutableListMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableListMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).hasContentsInOrder("d", "c", "b", "a");
- ASSERT.that(multimap.values()).hasContentsInOrder(2, 4, 6, 3, 5, 2);
- ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
- ASSERT.that(multimap.get("b")).hasContentsInOrder(6, 3);
+ ASSERT.that(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder();
+ ASSERT.that(multimap.values()).has().allOf(2, 4, 6, 3, 5, 2).inOrder();
+ ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
+ ASSERT.that(multimap.get("b")).has().allOf(6, 3).inOrder();
}
public void testCopyOf() {
@@ -461,7 +515,7 @@ public class ImmutableListMultimapTest extends TestCase {
SerializableTester.reserialize(multimap).size());
SerializableTester.reserializeAndAssert(multimap.get("foo"));
LenientSerializableTester.reserializeAndAssertLenient(multimap.keySet());
- SerializableTester.reserializeAndAssert(multimap.keys());
+ LenientSerializableTester.reserializeAndAssertLenient(multimap.keys());
SerializableTester.reserializeAndAssert(multimap.asMap());
Collection<Integer> valuesCopy
= SerializableTester.reserialize(multimap.values());
diff --git a/guava-tests/test/com/google/common/collect/ImmutableListTest.java b/guava-tests/test/com/google/common/collect/ImmutableListTest.java
index ced0635..e53fabf 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableListTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableListTest.java
@@ -28,7 +28,6 @@ import com.google.common.collect.testing.Helpers;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.MinimalIterable;
-import com.google.common.collect.testing.TestStringListGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.google.ListGenerators.BuilderAddAllListGenerator;
@@ -49,6 +48,7 @@ import junit.framework.TestSuite;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
@@ -65,56 +65,53 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
@GwtCompatible(emulated = true)
public class ImmutableListTest extends TestCase {
-
+
@GwtIncompatible("suite")
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest(ListTestSuiteBuilder.using(new ImmutableListOfGenerator())
.named("ImmutableList")
.withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(new BuilderAddAllListGenerator())
.named("ImmutableList, built with Builder.add")
.withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(new BuilderAddAllListGenerator())
.named("ImmutableList, built with Builder.addAll")
.withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(new BuilderReversedListGenerator())
.named("ImmutableList, reversed")
.withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
- suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
- @Override protected List<String> create(String[] elements) {
- return SerializableTester.reserialize(
- ImmutableList.copyOf(elements));
- }
- })
- .named("ImmutableList, reserialized")
- .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(
new ImmutableListHeadSubListGenerator())
.named("ImmutableList, head subList")
.withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(
new ImmutableListTailSubListGenerator())
.named("ImmutableList, tail subList")
.withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(
new ImmutableListMiddleSubListGenerator())
.named("ImmutableList, middle subList")
.withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(
@@ -197,7 +194,7 @@ public class ImmutableListTest extends TestCase {
}
// Varargs versions
-
+
public void testCreation_twelveElements() {
List<String> list = ImmutableList.of(
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l");
@@ -247,7 +244,7 @@ public class ImmutableListTest extends TestCase {
String[] array = new String[] { "a" };
List<String[]> list = ImmutableList.<String[]>of(array);
assertEquals(Collections.singletonList(array), list);
- }
+ }
public void testCopyOf_emptyArray() {
String[] array = new String[0];
@@ -265,7 +262,7 @@ public class ImmutableListTest extends TestCase {
try {
ImmutableList.copyOf((String[]) null);
fail();
- } catch(NullPointerException expected) {
+ } catch(NullPointerException expected) {
}
}
@@ -336,7 +333,7 @@ public class ImmutableListTest extends TestCase {
} catch (NullPointerException expected) {
}
}
-
+
public void testCopyOf_iteratorNull() {
try {
ImmutableList.copyOf((Iterator<String>) null);
@@ -344,7 +341,7 @@ public class ImmutableListTest extends TestCase {
} catch(NullPointerException expected) {
}
}
-
+
public void testCopyOf_concurrentlyMutating() {
List<String> sample = Lists.newArrayList("a", "b", "c");
for (int delta : new int[] {-1, 0, 1}) {
@@ -395,10 +392,44 @@ public class ImmutableListTest extends TestCase {
Collection<String> c = ImmutableList.of("a", "b", "c");
assertSame(c, ImmutableList.copyOf(c));
}
+
+ public void testBuilderAddArrayHandlesNulls() {
+ String[] elements = {"a", null, "b"};
+ ImmutableList.Builder<String> builder = ImmutableList.builder();
+ try {
+ builder.add(elements);
+ fail ("Expected NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ ImmutableList<String> result = builder.build();
+
+ /*
+ * Maybe it rejects all elements, or maybe it adds "a" before failing.
+ * Either way is fine with us.
+ */
+ if (result.isEmpty()) {
+ return;
+ }
+ assertTrue(ImmutableList.of("a").equals(result));
+ assertEquals(1, result.size());
+ }
+
+ public void testBuilderAddCollectionHandlesNulls() {
+ List<String> elements = Arrays.asList("a", null, "b");
+ ImmutableList.Builder<String> builder = ImmutableList.builder();
+ try {
+ builder.addAll(elements);
+ fail ("Expected NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ ImmutableList<String> result = builder.build();
+ assertEquals(ImmutableList.of("a"), result);
+ assertEquals(1, result.size());
+ }
}
-
+
@GwtIncompatible("reflection")
- public static class ConcurrentTests extends TestCase {
+ public static class ConcurrentTests extends TestCase {
enum WrapWithIterable { WRAP, NO_WRAP }
private static void runConcurrentlyMutatedTest(
@@ -604,11 +635,11 @@ public class ImmutableListTest extends TestCase {
return list;
}
}
-
+
public static class BasicTests extends TestCase {
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(ImmutableList.class);
tester.testAllPublicInstanceMethods(ImmutableList.of(1, 2, 3));
@@ -623,8 +654,7 @@ public class ImmutableListTest extends TestCase {
@GwtIncompatible("SerializableTester")
public void testSerialization_singleton() {
Collection<String> c = ImmutableList.of("a");
- ImmutableList<String> copy = (SingletonImmutableList<String>)
- SerializableTester.reserializeAndAssert(c);
+ SerializableTester.reserializeAndAssert(c);
}
@GwtIncompatible("SerializableTester")
diff --git a/guava-tests/test/com/google/common/collect/ImmutableMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableMapTest.java
index 4c04803..2708f39 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableMapTest.java
@@ -22,23 +22,25 @@ import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.testing.AnEnum;
import com.google.common.collect.testing.CollectionTestSuiteBuilder;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.MapInterfaceTest;
+import com.google.common.collect.testing.MapTestSuiteBuilder;
import com.google.common.collect.testing.MinimalSet;
-import com.google.common.collect.testing.ReserializingTestCollectionGenerator;
-import com.google.common.collect.testing.ReserializingTestSetGenerator;
import com.google.common.collect.testing.SampleElements.Colliders;
import com.google.common.collect.testing.SampleElements.Unhashables;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
import com.google.common.collect.testing.UnhashableObject;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.MapGenerators.ImmutableMapEntrySetGenerator;
-import com.google.common.collect.testing.google.MapGenerators.ImmutableMapKeySetGenerator;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.MapGenerators.ImmutableMapCopyOfEnumMapGenerator;
+import com.google.common.collect.testing.google.MapGenerators.ImmutableMapEntryListGenerator;
+import com.google.common.collect.testing.google.MapGenerators.ImmutableMapGenerator;
+import com.google.common.collect.testing.google.MapGenerators.ImmutableMapKeyListGenerator;
import com.google.common.collect.testing.google.MapGenerators.ImmutableMapUnhashableValuesGenerator;
import com.google.common.collect.testing.google.MapGenerators.ImmutableMapValueListGenerator;
-import com.google.common.collect.testing.google.MapGenerators.ImmutableMapValuesGenerator;
+import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -49,6 +51,7 @@ import junit.framework.TestSuite;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
+import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -67,72 +70,55 @@ public class ImmutableMapTest extends TestCase {
TestSuite suite = new TestSuite();
suite.addTestSuite(ImmutableMapTest.class);
- suite.addTest(SetTestSuiteBuilder.using(new ImmutableMapKeySetGenerator())
+ suite.addTest(MapTestSuiteBuilder.using(new ImmutableMapGenerator())
.withFeatures(
CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ MapFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableMap.keySet")
+ .named("ImmutableMap")
.createTestSuite());
- suite.addTest(SetTestSuiteBuilder.using(new ImmutableMapEntrySetGenerator())
+ suite.addTest(MapTestSuiteBuilder.using(new ImmutableMapCopyOfEnumMapGenerator())
.withFeatures(
CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableMap.entrySet")
+ .named("ImmutableMap.copyOf[EnumMap]")
.createTestSuite());
suite.addTest(CollectionTestSuiteBuilder.using(
- new ImmutableMapValuesGenerator())
+ new ImmutableMapUnhashableValuesGenerator())
.withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableMap.values")
+ .named("ImmutableMap.values, unhashable")
.createTestSuite());
- suite.addTest(SetTestSuiteBuilder.using(
- ReserializingTestSetGenerator.newInstance(
- new ImmutableMapKeySetGenerator()))
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER,
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableMapKeyListGenerator())
+ .named("ImmutableMap.keySet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableMap.keySet, reserialized")
.createTestSuite());
- suite.addTest(SetTestSuiteBuilder.using(
- ReserializingTestSetGenerator.newInstance(
- new ImmutableMapKeySetGenerator()))
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER,
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableMapEntryListGenerator())
+ .named("ImmutableMap.entrySet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableMap.entrySet, reserialized")
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- ReserializingTestCollectionGenerator.newInstance(
- new ImmutableMapValuesGenerator()))
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableMap.values, reserialized")
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new ImmutableMapUnhashableValuesGenerator())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableMap.values, unhashable")
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(
new ImmutableMapValueListGenerator())
.named("ImmutableMap.values.asList")
.withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -522,8 +508,29 @@ public class ImmutableMapTest extends TestCase {
assertNull(map.get(null));
}
+ public void testAsMultimap() {
+ ImmutableMap<String, Integer> map = ImmutableMap.of(
+ "one", 1, "won", 1, "two", 2, "too", 2, "three", 3);
+ ImmutableSetMultimap<String, Integer> expected = ImmutableSetMultimap.of(
+ "one", 1, "won", 1, "two", 2, "too", 2, "three", 3);
+ assertEquals(expected, map.asMultimap());
+ }
+
+ public void testAsMultimapWhenEmpty() {
+ ImmutableMap<String, Integer> map = ImmutableMap.of();
+ ImmutableSetMultimap<String, Integer> expected = ImmutableSetMultimap.of();
+ assertEquals(expected, map.asMultimap());
+ }
+
+ public void testAsMultimapCaches() {
+ ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1);
+ ImmutableSetMultimap<String, Integer> multimap1 = map.asMultimap();
+ ImmutableSetMultimap<String, Integer> multimap2 = map.asMultimap();
+ assertSame(multimap1, multimap2);
+ }
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(ImmutableMap.class);
tester.testAllPublicInstanceMethods(
@@ -574,6 +581,13 @@ public class ImmutableMapTest extends TestCase {
assertEquals(intMap.hashCode(), map.hashCode());
}
+ public void testCopyOfEnumMap() {
+ EnumMap<AnEnum, String> map = new EnumMap<AnEnum, String>(AnEnum.class);
+ map.put(AnEnum.B, "foo");
+ map.put(AnEnum.C, "bar");
+ assertTrue(ImmutableMap.copyOf(map) instanceof ImmutableEnumMap);
+ }
+
@GwtIncompatible("SerializableTester")
public void testViewSerialization() {
Map<String, Integer> map = ImmutableMap.of("one", 1, "two", 2, "three", 3);
@@ -585,4 +599,35 @@ public class ImmutableMapTest extends TestCase {
Lists.newArrayList(reserializedValues));
assertTrue(reserializedValues instanceof ImmutableCollection);
}
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(ImmutableList.of(), ImmutableList.of())
+ .addEqualityGroup(ImmutableList.of(1), ImmutableList.of(1))
+ .addEqualityGroup(ImmutableList.of(1, 2), ImmutableList.of(1, 2))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
+ .addEqualityGroup(ImmutableList.of(100, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
+ .addEqualityGroup(ImmutableList.of(1, 200, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
+ .addEqualityGroup(ImmutableList.of(1, 2, 300, 4, 5, 6, 7, 8, 9, 10, 11, 12))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 400, 5, 6, 7, 8, 9, 10, 11, 12))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 500, 6, 7, 8, 9, 10, 11, 12))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 600, 7, 8, 9, 10, 11, 12))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 700, 8, 9, 10, 11, 12))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 800, 9, 10, 11, 12))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 900, 10, 11, 12))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 1000, 11, 12))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1100, 12))
+ .addEqualityGroup(ImmutableList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 1200))
+ .testEquals();
+
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java b/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java
index 0b917e9..d02359c 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableMultimapTest.java
@@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableMultimap.Builder;
import com.google.common.collect.testing.SampleElements;
import com.google.common.collect.testing.SampleElements.Unhashables;
import com.google.common.collect.testing.UnhashableObject;
+import com.google.common.testing.EqualsTester;
import junit.framework.TestCase;
@@ -32,7 +33,7 @@ import java.util.Map.Entry;
*
* @author Jared Levy
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class ImmutableMultimapTest extends TestCase {
public void testBuilder_withImmutableEntry() {
@@ -114,4 +115,14 @@ public class ImmutableMultimapTest extends TestCase {
assertTrue(multimap.get(0).contains(unhashables.e1));
assertTrue(multimap.get(2).contains("hey you"));
}
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(ImmutableMultimap.of(), ImmutableMultimap.of())
+ .addEqualityGroup(ImmutableMultimap.of(1, "a"), ImmutableMultimap.of(1, "a"))
+ .addEqualityGroup(
+ ImmutableMultimap.of(1, "a", 2, "b"),
+ ImmutableMultimap.of(2, "b", 1, "a"))
+ .testEquals();
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java b/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java
index 657cf5c..5af65a8 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableMultisetTest.java
@@ -16,19 +16,23 @@
package com.google.common.collect;
+import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.MinimalCollection;
import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.TestStringListGenerator;
import com.google.common.collect.testing.TestStringSetGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
import com.google.common.collect.testing.google.TestStringMultisetGenerator;
import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
+import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -36,7 +40,9 @@ import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -61,30 +67,63 @@ public class ImmutableMultisetTest extends TestCase {
}
})
.named("ImmutableMultiset")
- .withFeatures(CollectionSize.ANY,
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- return SerializableTester.reserialize(
- ImmutableMultiset.copyOf(elements));
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ return ImmutableMultiset.copyOf(elements).elementSet();
}
})
- .named("ImmutableMultiset, reserialized")
+ .named("ImmutableMultiset, element set")
.withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- return SerializableTester.reserialize(
- ImmutableMultiset.copyOf(elements).elementSet());
+ suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
+ @Override protected List<String> create(String[] elements) {
+ return ImmutableMultiset.copyOf(elements).asList();
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ List<String> order = new ArrayList<String>();
+ for (String s : insertionOrder) {
+ int index = order.indexOf(s);
+ if (index == -1) {
+ order.add(s);
+ } else {
+ order.add(index, s);
+ }
+ }
+ return order;
}
})
- .named("ImmutableMultiset, element set")
+ .named("ImmutableMultiset.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
+ @Override protected List<String> create(String[] elements) {
+ Set<String> set = new HashSet<String>();
+ ImmutableMultiset.Builder<String> builder = ImmutableMultiset.builder();
+ for (String s : elements) {
+ checkArgument(set.add(s));
+ builder.addCopies(s, 2);
+ }
+ ImmutableSet<String> elementSet = (ImmutableSet<String>) builder.build().elementSet();
+ return elementSet.asList();
+ }
+ })
+ .named("ImmutableMultiset.elementSet.asList")
.withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -398,7 +437,7 @@ public class ImmutableMultisetTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(ImmutableMultiset.class);
}
@@ -413,7 +452,7 @@ public class ImmutableMultisetTest extends TestCase {
public void testSerialization_multiple() {
Collection<String> c = ImmutableMultiset.of("a", "b", "a");
Collection<String> copy = SerializableTester.reserializeAndAssert(c);
- ASSERT.that(copy).hasContentsInOrder("a", "a", "b");
+ ASSERT.that(copy).has().allOf("a", "a", "b").inOrder();
}
@GwtIncompatible("SerializableTester")
@@ -421,7 +460,7 @@ public class ImmutableMultisetTest extends TestCase {
Multiset<String> c = ImmutableMultiset.of("a", "b", "a");
Collection<String> copy =
LenientSerializableTester.reserializeAndAssertLenient(c.elementSet());
- ASSERT.that(copy).hasContentsInOrder("a", "b");
+ ASSERT.that(copy).has().allOf("a", "b").inOrder();
}
@GwtIncompatible("SerializableTester")
@@ -440,7 +479,7 @@ public class ImmutableMultisetTest extends TestCase {
public void testIterationOrder() {
Collection<String> c = ImmutableMultiset.of("a", "b", "a");
- ASSERT.that(c).hasContentsInOrder("a", "a", "b");
+ ASSERT.that(c).has().allOf("a", "a", "b").inOrder();
}
public void testMultisetWrites() {
@@ -463,4 +502,13 @@ public class ImmutableMultisetTest extends TestCase {
= ImmutableMultiset.of("a", "a", "b", "b", "b");
SerializableTester.reserializeAndAssert(multiset.asList());
}
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(ImmutableMultiset.of(), ImmutableMultiset.of())
+ .addEqualityGroup(ImmutableMultiset.of(1), ImmutableMultiset.of(1))
+ .addEqualityGroup(ImmutableMultiset.of(1, 1), ImmutableMultiset.of(1, 1))
+ .addEqualityGroup(ImmutableMultiset.of(1, 2, 1), ImmutableMultiset.of(2, 1, 1))
+ .testEquals();
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableRangeMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableRangeMapTest.java
new file mode 100644
index 0000000..3d1d7b4
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/ImmutableRangeMapTest.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.BoundType.OPEN;
+
+import com.google.common.annotations.GwtIncompatible;
+
+import junit.framework.TestCase;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+
+/**
+ * Tests for {@code ImmutableRangeMap}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtIncompatible("NavigableMap")
+public class ImmutableRangeMapTest extends TestCase {
+ private static final ImmutableList<Range<Integer>> RANGES;
+ private static final int MIN_BOUND = 0;
+ private static final int MAX_BOUND = 10;
+ static {
+ ImmutableList.Builder<Range<Integer>> builder = ImmutableList.builder();
+
+ builder.add(Range.<Integer>all());
+
+ // Add one-ended ranges
+ for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
+ for (BoundType type : BoundType.values()) {
+ builder.add(Range.upTo(i, type));
+ builder.add(Range.downTo(i, type));
+ }
+ }
+
+ // Add two-ended ranges
+ for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
+ for (int j = i + 1; j <= MAX_BOUND; j++) {
+ for (BoundType lowerType : BoundType.values()) {
+ for (BoundType upperType : BoundType.values()) {
+ if (i == j & lowerType == OPEN & upperType == OPEN) {
+ continue;
+ }
+ builder.add(Range.range(i, lowerType, j, upperType));
+ }
+ }
+ }
+ }
+ RANGES = builder.build();
+ }
+
+ public void testBuilderRejectsEmptyRanges() {
+ for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
+ ImmutableRangeMap.Builder<Integer, Integer> builder = ImmutableRangeMap.builder();
+ try {
+ builder.put(Range.closedOpen(i, i), 1);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // success
+ }
+ try {
+ builder.put(Range.openClosed(i, i), 1);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+ }
+
+ public void testOverlapRejection() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ boolean expectRejection =
+ range1.isConnected(range2) && !range1.intersection(range2).isEmpty();
+ ImmutableRangeMap.Builder<Integer, Integer> builder = ImmutableRangeMap.builder();
+ builder.put(range1, 1);
+ try {
+ builder.put(range2, 2);
+ assertFalse(expectRejection);
+ } catch (IllegalArgumentException e) {
+ assertTrue(expectRejection);
+ }
+ }
+ }
+ }
+
+ public void testGet() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
+ ImmutableRangeMap<Integer, Integer> rangeMap =
+ ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build();
+
+ for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
+ Integer expectedValue = null;
+ if (range1.contains(i)) {
+ expectedValue = 1;
+ } else if (range2.contains(i)) {
+ expectedValue = 2;
+ }
+
+ assertEquals(expectedValue, rangeMap.get(i));
+ }
+ }
+ }
+ }
+ }
+
+ public void testSpanEmpty() {
+ try {
+ ImmutableRangeMap.of().span();
+ fail("Expected NoSuchElementException");
+ } catch (NoSuchElementException expected) {
+ }
+ }
+
+ public void testSpanSingleRange() {
+ for (Range<Integer> range : RANGES) {
+ RangeMap<Integer, Integer> rangemap =
+ ImmutableRangeMap.<Integer, Integer>builder().put(range, 1).build();
+ assertEquals(range, rangemap.span());
+ }
+ }
+
+ public void testSpanTwoRanges() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
+ RangeMap<Integer, Integer> rangemap =
+ ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build();
+ assertEquals(range1.span(range2), rangemap.span());
+ }
+ }
+ }
+ }
+
+ public void testGetEntry() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
+ ImmutableRangeMap<Integer, Integer> rangeMap =
+ ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build();
+
+ for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
+ Entry<Range<Integer>, Integer> expectedEntry = null;
+ if (range1.contains(i)) {
+ expectedEntry = Maps.immutableEntry(range1, 1);
+ } else if (range2.contains(i)) {
+ expectedEntry = Maps.immutableEntry(range2, 2);
+ }
+
+ assertEquals(expectedEntry, rangeMap.getEntry(i));
+ }
+ }
+ }
+ }
+ }
+
+ public void testGetLargeRangeMap() {
+ ImmutableRangeMap.Builder<Integer, Integer> builder = ImmutableRangeMap.builder();
+ for (int i = 0; i < 100; i++) {
+ builder.put(Range.closedOpen(i, i + 1), i);
+ }
+ ImmutableRangeMap<Integer, Integer> map = builder.build();
+ for (int i = 0; i < 100; i++) {
+ assertEquals(Integer.valueOf(i), map.get(i));
+ }
+ }
+
+ public void testAsMapOfRanges() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
+ ImmutableRangeMap<Integer, Integer> rangeMap =
+ ImmutableRangeMap.<Integer, Integer>builder().put(range1, 1).put(range2, 2).build();
+
+ ImmutableMap<Range<Integer>, Integer> expectedAsMap =
+ ImmutableMap.of(range1, 1, range2, 2);
+ ImmutableMap<Range<Integer>, Integer> asMap = rangeMap.asMapOfRanges();
+ assertEquals(expectedAsMap, asMap);
+
+ for (Range<Integer> query : RANGES) {
+ assertEquals(expectedAsMap.get(query), asMap.get(query));
+ }
+ }
+ }
+ }
+ }
+
+ public void testSubRangeMap() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
+ for (Range<Integer> subRange : RANGES) {
+ ImmutableRangeMap<Integer, Integer> rangeMap =
+ ImmutableRangeMap.<Integer, Integer>builder()
+ .put(range1, 1).put(range2, 2).build();
+
+ ImmutableRangeMap.Builder<Integer, Integer> expectedBuilder =
+ ImmutableRangeMap.builder();
+ for (Map.Entry<Range<Integer>, Integer> entry : rangeMap.asMapOfRanges().entrySet()) {
+ if (entry.getKey().isConnected(subRange)
+ && !entry.getKey().intersection(subRange).isEmpty()) {
+ expectedBuilder.put(entry.getKey().intersection(subRange), entry.getValue());
+ }
+ }
+
+ ImmutableRangeMap<Integer, Integer> expected = expectedBuilder.build();
+ assertEquals(expected, rangeMap.subRangeMap(subRange));
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java b/guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java
new file mode 100644
index 0000000..352ac78
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/ImmutableRangeSetTest.java
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.collect;
+
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.TestSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.testing.SerializableTester;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Tests for {@link ImmutableRangeSet}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtIncompatible("ImmutableRangeSet")
+public class ImmutableRangeSetTest extends AbstractRangeSetTest {
+ @SuppressWarnings("unchecked") // varargs
+ private static final ImmutableSet<Range<Integer>> RANGES = ImmutableSet.of(
+ Range.<Integer>all(),
+ Range.closedOpen(3, 5),
+ Range.singleton(1),
+ Range.lessThan(2),
+ Range.greaterThan(10),
+ Range.atMost(4),
+ Range.atLeast(3),
+ Range.closed(4, 6),
+ Range.closedOpen(1, 3),
+ Range.openClosed(5, 7),
+ Range.open(3, 4));
+
+ static final class ImmutableRangeSetIntegerAsSetGenerator implements TestSetGenerator<Integer> {
+ @Override
+ public SampleElements<Integer> samples() {
+ return new SampleElements<Integer>(1, 4, 3, 2, 5);
+ }
+
+ @Override
+ public Integer[] createArray(int length) {
+ return new Integer[length];
+ }
+
+ @Override
+ public Iterable<Integer> order(List<Integer> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+
+ @Override
+ public Set<Integer> create(Object... elements) {
+ ImmutableRangeSet.Builder<Integer> builder = ImmutableRangeSet.builder();
+ for (Object o : elements) {
+ Integer i = (Integer) o;
+ builder.add(Range.singleton(i));
+ }
+ return builder.build().asSet(DiscreteDomains.integers());
+ }
+ }
+
+ static final class ImmutableRangeSetBigIntegerAsSetGenerator
+ implements TestSetGenerator<BigInteger> {
+ @Override
+ public SampleElements<BigInteger> samples() {
+ return new SampleElements<BigInteger>(
+ BigInteger.valueOf(1),
+ BigInteger.valueOf(4),
+ BigInteger.valueOf(3),
+ BigInteger.valueOf(2),
+ BigInteger.valueOf(5));
+ }
+
+ @Override
+ public BigInteger[] createArray(int length) {
+ return new BigInteger[length];
+ }
+
+ @Override
+ public Iterable<BigInteger> order(List<BigInteger> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+
+ @Override
+ public Set<BigInteger> create(Object... elements) {
+ ImmutableRangeSet.Builder<BigInteger> builder = ImmutableRangeSet.builder();
+ for (Object o : elements) {
+ BigInteger i = (BigInteger) o;
+ builder.add(Range.closedOpen(i, i.add(BigInteger.ONE)));
+ }
+ return builder.build().asSet(DiscreteDomain.bigIntegers());
+ }
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(ImmutableRangeSetTest.class);
+ suite.addTest(NavigableSetTestSuiteBuilder.using(new ImmutableRangeSetIntegerAsSetGenerator())
+ .named("ImmutableRangeSet.asSet[DiscreteDomains.integers[]]")
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.ALLOWS_NULL_QUERIES,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.NON_STANDARD_TOSTRING,
+ CollectionFeature.SERIALIZABLE)
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ImmutableRangeSetBigIntegerAsSetGenerator())
+ .named("ImmutableRangeSet.asSet[DiscreteDomains.bigIntegers[]]")
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.ALLOWS_NULL_QUERIES,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.NON_STANDARD_TOSTRING,
+ CollectionFeature.SERIALIZABLE)
+ .createTestSuite());
+ return suite;
+ }
+
+ public void testEmpty() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.of();
+
+ ASSERT.that(rangeSet.asRanges()).isEmpty();
+ assertEquals(ImmutableRangeSet.<Integer>all(), rangeSet.complement());
+ assertFalse(rangeSet.contains(0));
+ assertFalse(rangeSet.encloses(Range.singleton(0)));
+ assertTrue(rangeSet.enclosesAll(rangeSet));
+ assertTrue(rangeSet.isEmpty());
+ }
+
+ public void testAll() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.all();
+
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.<Integer>all());
+ assertTrue(rangeSet.contains(0));
+ assertTrue(rangeSet.encloses(Range.<Integer>all()));
+ assertTrue(rangeSet.enclosesAll(rangeSet));
+ assertEquals(ImmutableRangeSet.<Integer>of(), rangeSet.complement());
+ }
+
+ public void testSingleBoundedRange() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.of(Range.closedOpen(1, 5));
+
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closedOpen(1, 5));
+
+ assertTrue(rangeSet.encloses(Range.closed(3, 4)));
+ assertTrue(rangeSet.encloses(Range.closedOpen(1, 4)));
+ assertTrue(rangeSet.encloses(Range.closedOpen(1, 5)));
+ assertFalse(rangeSet.encloses(Range.greaterThan(2)));
+
+ assertTrue(rangeSet.contains(3));
+ assertFalse(rangeSet.contains(5));
+ assertFalse(rangeSet.contains(0));
+
+ RangeSet<Integer> expectedComplement = TreeRangeSet.create();
+ expectedComplement.add(Range.lessThan(1));
+ expectedComplement.add(Range.atLeast(5));
+
+ assertEquals(expectedComplement, rangeSet.complement());
+ }
+
+ public void testSingleBoundedBelowRange() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.of(Range.greaterThan(2));
+
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.greaterThan(2));
+
+ assertTrue(rangeSet.encloses(Range.closed(3, 4)));
+ assertTrue(rangeSet.encloses(Range.greaterThan(3)));
+ assertFalse(rangeSet.encloses(Range.closedOpen(1, 5)));
+
+ assertTrue(rangeSet.contains(3));
+ assertTrue(rangeSet.contains(5));
+ assertFalse(rangeSet.contains(0));
+ assertFalse(rangeSet.contains(2));
+
+ assertEquals(ImmutableRangeSet.of(Range.atMost(2)), rangeSet.complement());
+ }
+
+ public void testSingleBoundedAboveRange() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.of(Range.atMost(3));
+
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.atMost(3));
+
+ assertTrue(rangeSet.encloses(Range.closed(2, 3)));
+ assertTrue(rangeSet.encloses(Range.lessThan(1)));
+ assertFalse(rangeSet.encloses(Range.closedOpen(1, 5)));
+
+ assertTrue(rangeSet.contains(3));
+ assertTrue(rangeSet.contains(0));
+ assertFalse(rangeSet.contains(4));
+ assertFalse(rangeSet.contains(5));
+
+ assertEquals(ImmutableRangeSet.of(Range.greaterThan(3)), rangeSet.complement());
+ }
+
+ public void testMultipleBoundedRanges() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.closed(5, 8)).add(Range.closedOpen(1, 3)).build();
+
+ ASSERT.that(rangeSet.asRanges())
+ .has().allOf(Range.closedOpen(1, 3), Range.closed(5, 8)).inOrder();
+
+ assertTrue(rangeSet.encloses(Range.closed(1, 2)));
+ assertTrue(rangeSet.encloses(Range.open(5, 8)));
+ assertFalse(rangeSet.encloses(Range.closed(1, 8)));
+ assertFalse(rangeSet.encloses(Range.greaterThan(5)));
+
+ RangeSet<Integer> expectedComplement = ImmutableRangeSet.<Integer>builder()
+ .add(Range.lessThan(1))
+ .add(Range.closedOpen(3, 5))
+ .add(Range.greaterThan(8))
+ .build();
+
+ assertEquals(expectedComplement, rangeSet.complement());
+ }
+
+ public void testMultipleBoundedBelowRanges() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.greaterThan(6)).add(Range.closedOpen(1, 3)).build();
+
+ ASSERT.that(rangeSet.asRanges())
+ .has().allOf(Range.closedOpen(1, 3), Range.greaterThan(6)).inOrder();
+
+ assertTrue(rangeSet.encloses(Range.closed(1, 2)));
+ assertTrue(rangeSet.encloses(Range.open(6, 8)));
+ assertFalse(rangeSet.encloses(Range.closed(1, 8)));
+ assertFalse(rangeSet.encloses(Range.greaterThan(5)));
+
+ RangeSet<Integer> expectedComplement = ImmutableRangeSet.<Integer>builder()
+ .add(Range.lessThan(1))
+ .add(Range.closed(3, 6))
+ .build();
+
+ assertEquals(expectedComplement, rangeSet.complement());
+ }
+
+ public void testMultipleBoundedAboveRanges() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.atMost(0)).add(Range.closedOpen(2, 5)).build();
+
+ ASSERT.that(rangeSet.asRanges())
+ .has().allOf(Range.atMost(0), Range.closedOpen(2, 5)).inOrder();
+
+ assertTrue(rangeSet.encloses(Range.closed(2, 4)));
+ assertTrue(rangeSet.encloses(Range.open(-5, -2)));
+ assertFalse(rangeSet.encloses(Range.closed(1, 8)));
+ assertFalse(rangeSet.encloses(Range.greaterThan(5)));
+
+ RangeSet<Integer> expectedComplement = ImmutableRangeSet.<Integer>builder()
+ .add(Range.open(0, 2))
+ .add(Range.atLeast(5))
+ .build();
+
+ assertEquals(expectedComplement, rangeSet.complement());
+ }
+
+ public void testAddUnsupported() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.closed(5, 8)).add(Range.closedOpen(1, 3)).build();
+
+ try {
+ rangeSet.add(Range.open(3, 4));
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ // success
+ }
+ }
+
+ public void testAddAllUnsupported() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.closed(5, 8)).add(Range.closedOpen(1, 3)).build();
+
+ try {
+ rangeSet.addAll(ImmutableRangeSet.<Integer>of());
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ // success
+ }
+ }
+
+ public void testRemoveUnsupported() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.closed(5, 8)).add(Range.closedOpen(1, 3)).build();
+
+ try {
+ rangeSet.remove(Range.closed(6, 7));
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ // success
+ }
+ }
+
+ public void testRemoveAllUnsupported() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.closed(5, 8)).add(Range.closedOpen(1, 3)).build();
+
+ try {
+ rangeSet.removeAll(ImmutableRangeSet.<Integer>of());
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ // success
+ }
+
+ try {
+ rangeSet.removeAll(ImmutableRangeSet.of(Range.closed(6, 8)));
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ // success
+ }
+ }
+
+ public void testExhaustive() {
+ @SuppressWarnings("unchecked")
+ ImmutableSet<Range<Integer>> ranges = ImmutableSet.of(
+ Range.<Integer>all(),
+ Range.<Integer>closedOpen(3, 5),
+ Range.singleton(1),
+ Range.lessThan(2),
+ Range.greaterThan(10),
+ Range.atMost(4),
+ Range.atLeast(3),
+ Range.closed(4, 6),
+ Range.closedOpen(1, 3),
+ Range.openClosed(5, 7),
+ Range.open(3, 4));
+ for (Set<Range<Integer>> subset : Sets.powerSet(ranges)) {
+ RangeSet<Integer> mutable = TreeRangeSet.create();
+ ImmutableRangeSet.Builder<Integer> builder = ImmutableRangeSet.builder();
+
+ int expectedRanges = 0;
+ for (Range<Integer> range : subset) {
+ boolean overlaps = false;
+ for (Range<Integer> other : mutable.asRanges()) {
+ if (other.isConnected(range) && !other.intersection(range).isEmpty()) {
+ overlaps = true;
+ }
+ }
+
+ try {
+ builder.add(range);
+ assertFalse(overlaps);
+ mutable.add(range);
+ } catch (IllegalArgumentException e) {
+ assertTrue(overlaps);
+ }
+ }
+
+ ImmutableRangeSet<Integer> built = builder.build();
+ assertEquals(mutable, built);
+ assertEquals(ImmutableRangeSet.copyOf(mutable), built);
+ assertEquals(mutable.complement(), built.complement());
+
+ for (int i = 0; i <= 11; i++) {
+ assertEquals(mutable.contains(i), built.contains(i));
+ }
+
+ SerializableTester.reserializeAndAssert(built);
+ }
+ }
+
+ public void testAsSet() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.closed(2, 4))
+ .add(Range.open(6, 7))
+ .add(Range.closedOpen(8, 10))
+ .add(Range.openClosed(15, 17))
+ .build();
+ ImmutableSortedSet<Integer> expectedSet = ImmutableSortedSet.of(2, 3, 4, 8, 9, 16, 17);
+ ImmutableSortedSet<Integer> asSet = rangeSet.asSet(DiscreteDomains.integers());
+ assertEquals(expectedSet, asSet);
+ ASSERT.that(asSet).has().allFrom(expectedSet).inOrder();
+ assertTrue(asSet.containsAll(expectedSet));
+ SerializableTester.reserializeAndAssert(asSet);
+ }
+
+ public void testAsSetHeadSet() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.closed(2, 4))
+ .add(Range.open(6, 7))
+ .add(Range.closedOpen(8, 10))
+ .add(Range.openClosed(15, 17))
+ .build();
+
+ ImmutableSortedSet<Integer> expectedSet = ImmutableSortedSet.of(2, 3, 4, 8, 9, 16, 17);
+ ImmutableSortedSet<Integer> asSet = rangeSet.asSet(DiscreteDomains.integers());
+
+ for (int i = 0; i <= 20; i++) {
+ assertEquals(asSet.headSet(i, false), expectedSet.headSet(i, false));
+ assertEquals(asSet.headSet(i, true), expectedSet.headSet(i, true));
+ }
+ }
+
+ public void testAsSetTailSet() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.closed(2, 4))
+ .add(Range.open(6, 7))
+ .add(Range.closedOpen(8, 10))
+ .add(Range.openClosed(15, 17))
+ .build();
+
+ ImmutableSortedSet<Integer> expectedSet = ImmutableSortedSet.of(2, 3, 4, 8, 9, 16, 17);
+ ImmutableSortedSet<Integer> asSet = rangeSet.asSet(DiscreteDomains.integers());
+
+ for (int i = 0; i <= 20; i++) {
+ assertEquals(asSet.tailSet(i, false), expectedSet.tailSet(i, false));
+ assertEquals(asSet.tailSet(i, true), expectedSet.tailSet(i, true));
+ }
+ }
+
+ public void testAsSetSubSet() {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(Range.closed(2, 4))
+ .add(Range.open(6, 7))
+ .add(Range.closedOpen(8, 10))
+ .add(Range.openClosed(15, 17))
+ .build();
+
+ ImmutableSortedSet<Integer> expectedSet = ImmutableSortedSet.of(2, 3, 4, 8, 9, 16, 17);
+ ImmutableSortedSet<Integer> asSet = rangeSet.asSet(DiscreteDomains.integers());
+
+ for (int i = 0; i <= 20; i++) {
+ for (int j = i + 1; j <= 20; j++) {
+ assertEquals(expectedSet.subSet(i, false, j, false),
+ asSet.subSet(i, false, j, false));
+ assertEquals(expectedSet.subSet(i, true, j, false),
+ asSet.subSet(i, true, j, false));
+ assertEquals(expectedSet.subSet(i, false, j, true),
+ asSet.subSet(i, false, j, true));
+ assertEquals(expectedSet.subSet(i, true, j, true),
+ asSet.subSet(i, true, j, true));
+ }
+ }
+ }
+
+ public void testSubRangeSet() {
+ ImmutableList.Builder<Range<Integer>> rangesBuilder = ImmutableList.builder();
+ rangesBuilder.add(Range.<Integer>all());
+ for (int i = -2; i <= 2; i++) {
+ for (BoundType boundType : BoundType.values()) {
+ rangesBuilder.add(Range.upTo(i, boundType));
+ rangesBuilder.add(Range.downTo(i, boundType));
+ }
+ for (int j = i + 1; j <= 2; j++) {
+ for (BoundType lbType : BoundType.values()) {
+ for (BoundType ubType : BoundType.values()) {
+ rangesBuilder.add(Range.range(i, lbType, j, ubType));
+ }
+ }
+ }
+ }
+ ImmutableList<Range<Integer>> ranges = rangesBuilder.build();
+ for (int i = -2; i <= 2; i++) {
+ rangesBuilder.add(Range.closedOpen(i, i));
+ rangesBuilder.add(Range.openClosed(i, i));
+ }
+ ImmutableList<Range<Integer>> subRanges = rangesBuilder.build();
+ for (Range<Integer> range1 : ranges) {
+ for (Range<Integer> range2 : ranges) {
+ if (!range1.isConnected(range2) || range1.intersection(range2).isEmpty()) {
+ ImmutableRangeSet<Integer> rangeSet = ImmutableRangeSet.<Integer>builder()
+ .add(range1)
+ .add(range2)
+ .build();
+ for (Range<Integer> subRange : subRanges) {
+ RangeSet<Integer> expected = TreeRangeSet.create();
+ for (Range<Integer> range : rangeSet.asRanges()) {
+ if (range.isConnected(subRange)) {
+ expected.add(range.intersection(subRange));
+ }
+ }
+ ImmutableRangeSet<Integer> subRangeSet = rangeSet.subRangeSet(subRange);
+ assertEquals(expected, subRangeSet);
+ assertEquals(expected.asRanges(), subRangeSet.asRanges());
+ if (!expected.isEmpty()) {
+ assertEquals(expected.span(), subRangeSet.span());
+ }
+ for (int i = -3; i <= 3; i++) {
+ assertEquals(expected.contains(i), subRangeSet.contains(i));
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSetCollectionTest.java b/guava-tests/test/com/google/common/collect/ImmutableSetCollectionTest.java
deleted file mode 100644
index 9ebceec..0000000
--- a/guava-tests/test/com/google/common/collect/ImmutableSetCollectionTest.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.ListTestSuiteBuilder;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestStringSetGenerator;
-import com.google.common.collect.testing.TestStringSortedSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.SetGenerators.DegeneratedImmutableSetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSetAsListGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSetCopyOfGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSetWithBadHashesGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetAsListGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetAsListSubListGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetCopyOfGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitComparator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitSuperclassComparatorGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetHeadsetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetReversedOrderGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetAsListGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetTailsetGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetUnhashableGenerator;
-import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedsetSubsetAsListSubListGenerator;
-import com.google.common.collect.testing.testers.SetHashCodeTester;
-import com.google.common.testing.SerializableTester;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.List;
-import java.util.Set;
-import java.util.SortedSet;
-
-/**
- * Collection tests for {@link ImmutableSet} and {@link ImmutableSortedSet}.
- *
- * @author Kevin Bourrillion
- * @author Jared Levy
- */
-@GwtIncompatible("suite") // handled by collect/gwt/suites
-public class ImmutableSetCollectionTest extends TestCase {
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTest(SetTestSuiteBuilder.using(new ImmutableSetCopyOfGenerator())
- .named(ImmutableSetTest.class.getName())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- Set<String> set = ImmutableSet.copyOf(elements);
- return SerializableTester.reserialize(set);
- }
- })
- .named(ImmutableSetTest.class.getName() + ", reserialized")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSetWithBadHashesGenerator())
- .named(ImmutableSetTest.class.getName() + ", with bad hashes")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new DegeneratedImmutableSetGenerator())
- .named(ImmutableSetTest.class.getName() + ", degenerate")
- .withFeatures(CollectionSize.ONE, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedSetCopyOfGenerator())
- .named(ImmutableSortedSetTest.class.getName())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSortedSetGenerator() {
- @Override protected SortedSet<String> create(String[] elements) {
- SortedSet<String> set = ImmutableSortedSet.copyOf(elements);
- return SerializableTester.reserialize(set);
- }
- })
- .named(ImmutableSortedSetTest.class.getName() + ", reserialized")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedSetHeadsetGenerator())
- .named(ImmutableSortedSetTest.class.getName() + ", headset")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedSetTailsetGenerator())
- .named(ImmutableSortedSetTest.class.getName() + ", tailset")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedSetSubsetGenerator())
- .named(ImmutableSortedSetTest.class.getName() + ", subset")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new TestStringSortedSetGenerator() {
- @Override protected SortedSet<String> create(String[] elements) {
- List<String> list = Lists.newArrayList(elements);
- list.add("zzz");
- return SerializableTester.reserialize(
- ImmutableSortedSet.copyOf(list).headSet("zzy"));
- }
- })
- .named(
- ImmutableSortedSetTest.class.getName() + ", headset, reserialized")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new TestStringSortedSetGenerator() {
- @Override protected SortedSet<String> create(String[] elements) {
- List<String> list = Lists.newArrayList(elements);
- list.add("\0");
- return SerializableTester.reserialize(
- ImmutableSortedSet.copyOf(list).tailSet("\0\0"));
- }
- })
- .named(
- ImmutableSortedSetTest.class.getName() + ", tailset, reserialized")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new TestStringSortedSetGenerator() {
- @Override protected SortedSet<String> create(String[] elements) {
- List<String> list = Lists.newArrayList(elements);
- list.add("\0");
- list.add("zzz");
- return SerializableTester.reserialize(
- ImmutableSortedSet.copyOf(list).subSet("\0\0", "zzy"));
- }
- })
- .named(
- ImmutableSortedSetTest.class.getName() + ", subset, reserialized")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedSetExplicitComparator())
- .named(ImmutableSortedSetTest.class.getName()
- + ", explicit comparator, vararg")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedSetExplicitSuperclassComparatorGenerator())
- .named(ImmutableSortedSetTest.class.getName()
- + ", explicit superclass comparator, iterable")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedSetReversedOrderGenerator())
- .named(ImmutableSortedSetTest.class.getName()
- + ", reverseOrder, iterator")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedSetUnhashableGenerator())
- .suppressing(SetHashCodeTester.getHashCodeMethods())
- .named(ImmutableSortedSetTest.class.getName() + ", unhashable")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(new ImmutableSetAsListGenerator())
- .named("ImmutableSet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableSortedSetAsListGenerator())
- .named("ImmutableSortedSet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableSortedSetSubsetAsListGenerator())
- .named("ImmutableSortedSet.subSet.asList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableSortedSetAsListSubListGenerator())
- .named("ImmutableSortedSet.asList.subList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(
- new ImmutableSortedsetSubsetAsListSubListGenerator())
- .named("ImmutableSortedSet.subSet.asList.subList")
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .createTestSuite());
-
- return suite;
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java b/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java
index 8c182cf..654d80e 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableSetMultimapTest.java
@@ -16,16 +16,23 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableSetMultimap.Builder;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
import com.google.common.collect.testing.google.UnmodifiableCollectionTests;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.SerializableTester;
+import junit.framework.Test;
import junit.framework.TestCase;
+import junit.framework.TestSuite;
import java.util.Arrays;
import java.util.Collection;
@@ -39,6 +46,29 @@ import java.util.Map.Entry;
*/
@GwtCompatible(emulated = true)
public class ImmutableSetMultimapTest extends TestCase {
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(ImmutableSetMultimapTest.class);
+ suite.addTest(SetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() {
+ @Override
+ protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
+ ImmutableSetMultimap.Builder<String, String> builder = ImmutableSetMultimap.builder();
+ for (Entry<String, String> entry : entries) {
+ builder.put(entry.getKey(), entry.getValue());
+ }
+ return builder.build();
+ }
+ })
+ .named("ImmutableSetMultimap")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_QUERIES,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionSize.ANY)
+ .createTestSuite());
+ return suite;
+ }
public void testBuilder_withImmutableEntry() {
ImmutableSetMultimap<String, Integer> multimap = new Builder<String, Integer>()
@@ -219,10 +249,35 @@ public class ImmutableSetMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableSetMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).hasContentsInOrder("d", "c", "b", "a");
- ASSERT.that(multimap.values()).hasContentsInOrder(2, 4, 3, 6, 5, 2);
- ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
- ASSERT.that(multimap.get("b")).hasContentsInOrder(3, 6);
+ ASSERT.that(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder();
+ ASSERT.that(multimap.values()).has().allOf(2, 4, 3, 6, 5, 2).inOrder();
+ ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
+ ASSERT.that(multimap.get("b")).has().allOf(3, 6).inOrder();
+ assertFalse(multimap.get("a") instanceof ImmutableSortedSet);
+ assertFalse(multimap.get("x") instanceof ImmutableSortedSet);
+ assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet);
+ }
+
+ public void testBuilderOrderKeysByDuplicates() {
+ ImmutableSetMultimap.Builder<String, Integer> builder
+ = ImmutableSetMultimap.builder();
+ builder.put("bb", 3);
+ builder.put("d", 2);
+ builder.put("a", 5);
+ builder.orderKeysBy(new Ordering<String>() {
+ @Override
+ public int compare(String left, String right) {
+ return left.length() - right.length();
+ }
+ });
+ builder.put("cc", 4);
+ builder.put("a", 2);
+ builder.put("bb", 6);
+ ImmutableSetMultimap<String, Integer> multimap = builder.build();
+ ASSERT.that(multimap.keySet()).has().allOf("d", "a", "bb", "cc").inOrder();
+ ASSERT.that(multimap.values()).has().allOf(2, 5, 2, 3, 6, 4).inOrder();
+ ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
+ ASSERT.that(multimap.get("bb")).has().allOf(3, 6).inOrder();
assertFalse(multimap.get("a") instanceof ImmutableSortedSet);
assertFalse(multimap.get("x") instanceof ImmutableSortedSet);
assertFalse(multimap.asMap().get("a") instanceof ImmutableSortedSet);
@@ -239,18 +294,18 @@ public class ImmutableSetMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableSetMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).hasContentsInOrder("b", "d", "a", "c");
- ASSERT.that(multimap.values()).hasContentsInOrder(6, 3, 2, 5, 2, 4);
- ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
- ASSERT.that(multimap.get("b")).hasContentsInOrder(6, 3);
+ ASSERT.that(multimap.keySet()).has().allOf("b", "d", "a", "c").inOrder();
+ ASSERT.that(multimap.values()).has().allOf(6, 3, 2, 5, 2, 4).inOrder();
+ ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
+ ASSERT.that(multimap.get("b")).has().allOf(6, 3).inOrder();
assertTrue(multimap.get("a") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
assertTrue(multimap.get("x") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.get("x")).comparator());
assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator());
}
@@ -266,21 +321,21 @@ public class ImmutableSetMultimapTest extends TestCase {
builder.put("a", 2);
builder.put("b", 6);
ImmutableSetMultimap<String, Integer> multimap = builder.build();
- ASSERT.that(multimap.keySet()).hasContentsInOrder("d", "c", "b", "a");
- ASSERT.that(multimap.values()).hasContentsInOrder(2, 4, 6, 3, 5, 2);
- ASSERT.that(multimap.get("a")).hasContentsInOrder(5, 2);
- ASSERT.that(multimap.get("b")).hasContentsInOrder(6, 3);
+ ASSERT.that(multimap.keySet()).has().allOf("d", "c", "b", "a").inOrder();
+ ASSERT.that(multimap.values()).has().allOf(2, 4, 6, 3, 5, 2).inOrder();
+ ASSERT.that(multimap.get("a")).has().allOf(5, 2).inOrder();
+ ASSERT.that(multimap.get("b")).has().allOf(6, 3).inOrder();
assertTrue(multimap.get("a") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.get("a")).comparator());
assertTrue(multimap.get("x") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.get("x")).comparator());
assertTrue(multimap.asMap().get("a") instanceof ImmutableSortedSet);
- assertEquals(Collections.reverseOrder(),
+ assertEquals(Collections.reverseOrder(),
((ImmutableSortedSet<Integer>) multimap.asMap().get("a")).comparator());
}
-
+
public void testCopyOf() {
HashMultimap<String, Integer> input = HashMultimap.create();
input.put("foo", 1);
@@ -447,7 +502,7 @@ public class ImmutableSetMultimapTest extends TestCase {
assertEquals(alternatingKeysAndValues[i++], entry.getKey());
assertEquals(alternatingKeysAndValues[i++], entry.getValue());
}
- }
+ }
@GwtIncompatible("SerializableTester")
public void testSerialization() {
@@ -457,7 +512,7 @@ public class ImmutableSetMultimapTest extends TestCase {
SerializableTester.reserialize(multimap).size());
SerializableTester.reserializeAndAssert(multimap.get("foo"));
LenientSerializableTester.reserializeAndAssertLenient(multimap.keySet());
- SerializableTester.reserializeAndAssert(multimap.keys());
+ LenientSerializableTester.reserializeAndAssertLenient(multimap.keys());
SerializableTester.reserializeAndAssert(multimap.asMap());
Collection<Integer> valuesCopy
= SerializableTester.reserialize(multimap.values());
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSetTest.java b/guava-tests/test/com/google/common/collect/ImmutableSetTest.java
index 6ed82ec..dba83a5 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableSetTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableSetTest.java
@@ -16,13 +16,23 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableSet.Builder;
-import com.google.common.testing.NullPointerTester;
-import com.google.common.testing.SerializableTester;
+import com.google.common.collect.testing.ListTestSuiteBuilder;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.google.SetGenerators.DegeneratedImmutableSetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSetAsListGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSetCopyOfGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSetWithBadHashesGenerator;
+import com.google.common.testing.EqualsTester;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
import java.util.Collection;
import java.util.Collections;
@@ -39,6 +49,44 @@ import java.util.Set;
@GwtCompatible(emulated = true)
public class ImmutableSetTest extends AbstractImmutableSetTest {
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTest(SetTestSuiteBuilder.using(new ImmutableSetCopyOfGenerator())
+ .named(ImmutableSetTest.class.getName())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new ImmutableSetWithBadHashesGenerator())
+ .named(ImmutableSetTest.class.getName() + ", with bad hashes")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new DegeneratedImmutableSetGenerator())
+ .named(ImmutableSetTest.class.getName() + ", degenerate")
+ .withFeatures(CollectionSize.ONE, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(new ImmutableSetAsListGenerator())
+ .named("ImmutableSet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTestSuite(ImmutableSetTest.class);
+
+ return suite;
+ }
+
@Override protected Set<String> of() {
return ImmutableSet.of();
}
@@ -105,7 +153,7 @@ public class ImmutableSetTest extends AbstractImmutableSetTest {
// now we'll get the varargs overload
ImmutableSet<String> set = ImmutableSet.of(
"a", "b", "c", "c", "c", "c", "b", "b", "a", "a", "c", "c", "c", "a");
- ASSERT.that(set).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(set).has().allOf("a", "b", "c").inOrder();
}
public void testCreation_arrayOfArray() {
@@ -114,19 +162,13 @@ public class ImmutableSetTest extends AbstractImmutableSetTest {
assertEquals(Collections.singleton(array), set);
}
- @GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.testAllPublicStaticMethods(ImmutableSet.class);
- }
-
@GwtIncompatible("ImmutableSet.chooseTableSize")
public void testChooseTableSize() {
assertEquals(8, ImmutableSet.chooseTableSize(3));
- assertEquals(16, ImmutableSet.chooseTableSize(4));
+ assertEquals(8, ImmutableSet.chooseTableSize(4));
- assertEquals(1 << 30, ImmutableSet.chooseTableSize(1 << 28));
- assertEquals(1 << 30, ImmutableSet.chooseTableSize(1 << 29 - 1));
+ assertEquals(1 << 29, ImmutableSet.chooseTableSize(1 << 28));
+ assertEquals(1 << 29, ImmutableSet.chooseTableSize(1 << 29 - 1));
// Now we hit the cap
assertEquals(1 << 30, ImmutableSet.chooseTableSize(1 << 29));
@@ -142,12 +184,12 @@ public class ImmutableSetTest extends AbstractImmutableSetTest {
@GwtIncompatible("RegularImmutableSet.table not in emulation")
public void testResizeTable() {
- verifyTableSize(100, 2, 8);
- verifyTableSize(100, 5, 16);
- verifyTableSize(100, 33, 256);
- verifyTableSize(17, 17, 64);
- verifyTableSize(17, 16, 64);
- verifyTableSize(17, 15, 64);
+ verifyTableSize(100, 2, 4);
+ verifyTableSize(100, 5, 8);
+ verifyTableSize(100, 33, 64);
+ verifyTableSize(17, 17, 32);
+ verifyTableSize(17, 16, 32);
+ verifyTableSize(17, 15, 32);
}
@GwtIncompatible("RegularImmutableSet.table not in emulation")
@@ -173,21 +215,6 @@ public class ImmutableSetTest extends AbstractImmutableSetTest {
verifyThreadSafe();
}
- public void testAsList() {
- ImmutableSet<String> set = ImmutableSet.of("a", "b", "c", "d", "e");
- ImmutableList<String> list = set.asList();
- assertEquals(ImmutableList.of("a", "b", "c", "d", "e"), list);
- }
-
- @GwtIncompatible("SerializableTester, ImmutableAsList")
- public void testAsListReturnTypeAndSerialization() {
- ImmutableSet<String> set = ImmutableSet.of("a", "b", "c", "d", "e");
- ImmutableList<String> list = set.asList();
- assertTrue(list instanceof ImmutableAsList);
- ImmutableList<String> copy = SerializableTester.reserializeAndAssert(list);
- assertTrue(copy instanceof ImmutableAsList);
- }
-
@Override <E extends Comparable<E>> Builder<E> builder() {
return ImmutableSet.builder();
}
@@ -195,4 +222,12 @@ public class ImmutableSetTest extends AbstractImmutableSetTest {
@Override int getComplexBuilderSetLastElement() {
return LAST_COLOR_ADDED;
}
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(ImmutableSet.of(), ImmutableSet.of())
+ .addEqualityGroup(ImmutableSet.of(1), ImmutableSet.of(1), ImmutableSet.of(1, 1))
+ .addEqualityGroup(ImmutableSet.of(1, 2, 1), ImmutableSet.of(2, 1, 1))
+ .testEquals();
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java b/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java
index 988aa4e..b4a2632 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableSortedMapTest.java
@@ -16,25 +16,22 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSortedMap.Builder;
-import com.google.common.collect.testing.CollectionTestSuiteBuilder;
-import com.google.common.collect.testing.ReserializingTestCollectionGenerator;
-import com.google.common.collect.testing.ReserializingTestSetGenerator;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.ListTestSuiteBuilder;
+import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
import com.google.common.collect.testing.SortedMapInterfaceTest;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapEntrySetGenerator;
-import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapHeadMapKeySetGenerator;
-import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapKeySetGenerator;
-import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapSubMapEntryGenerator;
-import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapTailMapValuesGenerator;
-import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapValuesGenerator;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapEntryListGenerator;
+import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapGenerator;
+import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapKeyListGenerator;
+import com.google.common.collect.testing.google.SortedMapGenerators.ImmutableSortedMapValueListGenerator;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -66,88 +63,42 @@ public class ImmutableSortedMapTest extends TestCase {
TestSuite suite = new TestSuite();
suite.addTestSuite(ImmutableSortedMapTest.class);
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedMapKeySetGenerator())
+ suite.addTest(NavigableMapTestSuiteBuilder.using(
+ new ImmutableSortedMapGenerator())
.withFeatures(
CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableSortedMap.keySet")
+ MapFeature.REJECTS_DUPLICATES_AT_CREATION,
+ MapFeature.ALLOWS_NULL_QUERIES)
+ .named("ImmutableSortedMap")
.createTestSuite());
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedMapEntrySetGenerator())
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER,
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableSortedMapEntryListGenerator())
+ .named("ImmutableSortedMap.entrySet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableSortedMap.entrySet")
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new ImmutableSortedMapValuesGenerator())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableSortedMap.values")
.createTestSuite());
- suite.addTest(SetTestSuiteBuilder.using(
- ReserializingTestSetGenerator.newInstance(
- new ImmutableSortedMapKeySetGenerator()))
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER,
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableSortedMapKeyListGenerator())
+ .named("ImmutableSortedMap.keySet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableSortedMap.keySet, reserialized")
.createTestSuite());
- suite.addTest(SetTestSuiteBuilder.using(
- ReserializingTestSetGenerator.newInstance(
- new ImmutableSortedMapEntrySetGenerator()))
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER,
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableSortedMapValueListGenerator())
+ .named("ImmutableSortedMap.values.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableSortedMap.entrySet, reserialized")
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- ReserializingTestCollectionGenerator.newInstance(
- new ImmutableSortedMapValuesGenerator()))
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableSortedMap.values, reserialized")
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedMapHeadMapKeySetGenerator())
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableSortedMap.headMap.keySet")
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new ImmutableSortedMapSubMapEntryGenerator())
- .withFeatures(
- CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableSortedMap.subMap.entrySet")
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new ImmutableSortedMapTailMapValuesGenerator())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ImmutableSortedMap.tailMap.values")
.createTestSuite());
return suite;
@@ -265,7 +216,7 @@ public class ImmutableSortedMapTest extends TestCase {
return 4;
}
}
-
+
public static class TailMapTests extends AbstractMapTests<String, Integer> {
@Override protected SortedMap<String, Integer> makePopulatedMap() {
return ImmutableSortedMap.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5)
@@ -699,7 +650,7 @@ public class ImmutableSortedMapTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(ImmutableSortedMap.class);
tester.testAllPublicInstanceMethods(
@@ -744,8 +695,7 @@ public class ImmutableSortedMapTest extends TestCase {
Map<String, IntHolder> map
= ImmutableSortedMap.of("a", holderA, "b", holderB);
holderA.value = 3;
- assertTrue(map.entrySet().contains(
- Maps.immutableEntry("a", new IntHolder(3))));
+ assertTrue(map.entrySet().contains(Maps.immutableEntry("a", new IntHolder(3))));
Map<String, Integer> intMap
= ImmutableSortedMap.of("a", 3, "b", 2);
assertEquals(intMap.hashCode(), map.entrySet().hashCode());
@@ -766,60 +716,86 @@ public class ImmutableSortedMapTest extends TestCase {
public void testHeadMapInclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).headMap("three", true);
- ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1),
- Maps.immutableEntry("three", 3));
+ ASSERT.that(map.entrySet()).has().allOf(
+ Maps.immutableEntry("one", 1),
+ Maps.immutableEntry("three", 3)).inOrder();
}
@SuppressWarnings("unchecked") // varargs
public void testHeadMapExclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).headMap("three", false);
- ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1));
+ ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("one", 1)).inOrder();
}
@SuppressWarnings("unchecked") // varargs
public void testTailMapInclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).tailMap("three", true);
- ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("three", 3),
- Maps.immutableEntry("two", 2));
+ ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("three", 3),
+ Maps.immutableEntry("two", 2)).inOrder();
}
@SuppressWarnings("unchecked") // varargs
public void testTailMapExclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).tailMap("three", false);
- ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("two", 2));
+ ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("two", 2)).inOrder();
}
@SuppressWarnings("unchecked") // varargs
public void testSubMapExclusiveExclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", false, "two", false);
- ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("three", 3));
+ ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("three", 3)).inOrder();
}
@SuppressWarnings("unchecked") // varargs
public void testSubMapInclusiveExclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", true, "two", false);
- ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1),
- Maps.immutableEntry("three", 3));
+ ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("one", 1),
+ Maps.immutableEntry("three", 3)).inOrder();
}
@SuppressWarnings("unchecked") // varargs
public void testSubMapExclusiveInclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", false, "two", true);
- ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("three", 3),
- Maps.immutableEntry("two", 2));
+ ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("three", 3),
+ Maps.immutableEntry("two", 2)).inOrder();
}
@SuppressWarnings("unchecked") // varargs
public void testSubMapInclusiveInclusive() {
Map<String, Integer> map =
ImmutableSortedMap.of("one", 1, "two", 2, "three", 3).subMap("one", true, "two", true);
- ASSERT.that(map.entrySet()).hasContentsInOrder(Maps.immutableEntry("one", 1),
- Maps.immutableEntry("three", 3), Maps.immutableEntry("two", 2));
+ ASSERT.that(map.entrySet()).has().allOf(Maps.immutableEntry("one", 1),
+ Maps.immutableEntry("three", 3), Maps.immutableEntry("two", 2)).inOrder();
+ }
+
+ private static class SelfComparableExample implements Comparable<SelfComparableExample> {
+ @Override
+ public int compareTo(SelfComparableExample o) {
+ return 0;
+ }
+ }
+
+ public void testBuilderGenerics_SelfComparable() {
+ ImmutableSortedMap.Builder<SelfComparableExample, Object> natural =
+ ImmutableSortedMap.naturalOrder();
+
+ ImmutableSortedMap.Builder<SelfComparableExample, Object> reverse =
+ ImmutableSortedMap.reverseOrder();
+ }
+
+ private static class SuperComparableExample extends SelfComparableExample {}
+
+ public void testBuilderGenerics_SuperComparable() {
+ ImmutableSortedMap.Builder<SuperComparableExample, Object> natural =
+ ImmutableSortedMap.naturalOrder();
+
+ ImmutableSortedMap.Builder<SuperComparableExample, Object> reverse =
+ ImmutableSortedMap.reverseOrder();
}
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java b/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java
index 5ecb339..fe661d4 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableSortedMultisetTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
@@ -14,13 +14,15 @@
package com.google.common.collect;
+import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.base.Function;
+import com.google.common.collect.Multiset.Entry;
+import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.MinimalCollection;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestStringSetGenerator;
+import com.google.common.collect.testing.TestStringListGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder;
@@ -33,9 +35,10 @@ import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import org.easymock.EasyMock;
+
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
@@ -43,7 +46,7 @@ import java.util.Set;
/**
* Tests for {@link ImmutableSortedMultiset}.
- *
+ *
* @author Louis Wasserman
*/
public class ImmutableSortedMultisetTest extends TestCase {
@@ -52,47 +55,61 @@ public class ImmutableSortedMultisetTest extends TestCase {
suite.addTestSuite(ImmutableSortedMultisetTest.class);
suite.addTest(SortedMultisetTestSuiteBuilder.using(new TestStringMultisetGenerator() {
- @Override
- protected Multiset<String> create(String[] elements) {
- return ImmutableSortedMultiset.copyOf(elements);
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- }).named("ImmutableSortedMultiset").withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_QUERIES)
+ @Override
+ protected Multiset<String> create(String[] elements) {
+ return ImmutableSortedMultiset.copyOf(elements);
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ })
+ .named("ImmutableSortedMultiset")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE_INCLUDING_VIEWS,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(SortedMultisetTestSuiteBuilder.using(new TestStringMultisetGenerator() {
- @Override
- protected Multiset<String> create(String[] elements) {
- return SerializableTester.reserialize(ImmutableSortedMultiset.copyOf(elements));
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- }).named("ImmutableSortedMultiset, reserialized").withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_QUERIES)
+ suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
+ @Override
+ protected List<String> create(String[] elements) {
+ return ImmutableSortedMultiset.copyOf(elements).asList();
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ })
+ .named("ImmutableSortedMultiset.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(SetTestSuiteBuilder
- .using(new TestStringSetGenerator() {
- @Override
- protected Set<String> create(String[] elements) {
- return SerializableTester.reserialize(ImmutableSortedMultiset.copyOf(elements)
- .elementSet());
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().immutableSortedCopy(insertionOrder);
+ suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
+ @Override
+ protected List<String> create(String[] elements) {
+ Set<String> set = Sets.newHashSet();
+ ImmutableSortedMultiset.Builder<String> builder = ImmutableSortedMultiset.naturalOrder();
+ for (String s : elements) {
+ checkArgument(set.add(s));
+ builder.addCopies(s, 2);
}
- }).named("ImmutableSortedMultiset, element set").withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_QUERIES)
+ return builder.build().elementSet().asList();
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ })
+ .named("ImmutableSortedMultiset.elementSet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
return suite;
@@ -391,14 +408,8 @@ public class ImmutableSortedMultisetTest extends TestCase {
} catch (IllegalArgumentException expected) {}
}
- public void testNullPointers() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Comparator.class, Ordering.natural());
- tester.setDefault(Comparable.class, "");
- tester.setDefault(Iterator.class, Iterators.emptyIterator());
- tester.setDefault(Iterable.class, Collections.emptySet());
- tester.setDefault(Comparable[].class, new Comparable[0]);
- tester.testAllPublicStaticMethods(ImmutableSortedMultiset.class);
+ public void testNullPointers() {
+ new NullPointerTester().testAllPublicStaticMethods(ImmutableSortedMultiset.class);
}
public void testSerialization_empty() {
@@ -409,13 +420,13 @@ public class ImmutableSortedMultisetTest extends TestCase {
public void testSerialization_multiple() {
Collection<String> c = ImmutableSortedMultiset.of("a", "b", "a");
Collection<String> copy = SerializableTester.reserializeAndAssert(c);
- ASSERT.that(copy).hasContentsInOrder("a", "a", "b");
+ ASSERT.that(copy).has().allOf("a", "a", "b").inOrder();
}
public void testSerialization_elementSet() {
Multiset<String> c = ImmutableSortedMultiset.of("a", "b", "a");
Collection<String> copy = SerializableTester.reserializeAndAssert(c.elementSet());
- ASSERT.that(copy).hasContentsInOrder("a", "b");
+ ASSERT.that(copy).has().allOf("a", "b").inOrder();
}
public void testSerialization_entrySet() {
@@ -433,7 +444,7 @@ public class ImmutableSortedMultisetTest extends TestCase {
public void testIterationOrder() {
Collection<String> c = ImmutableSortedMultiset.of("a", "b", "a");
- ASSERT.that(c).hasContentsInOrder("a", "a", "b");
+ ASSERT.that(c).has().allOf("a", "a", "b").inOrder();
}
public void testMultisetWrites() {
@@ -451,4 +462,62 @@ public class ImmutableSortedMultisetTest extends TestCase {
assertEquals(2, list.indexOf("b"));
assertEquals(4, list.lastIndexOf("b"));
}
+
+ public void testCopyOfDefensiveCopy() {
+ // Test that toArray() is used to make a defensive copy in copyOf(), so concurrently modified
+ // synchronized collections can be safely copied.
+ @SuppressWarnings("unchecked")
+ Collection<String> toCopy = EasyMock.createMock(Collection.class);
+ EasyMock.expect(toCopy.toArray()).andReturn(new Object[0]);
+ EasyMock.replay(toCopy);
+ ImmutableSortedMultiset<String> multiset =
+ ImmutableSortedMultiset.copyOf(Ordering.natural(), toCopy);
+ EasyMock.verify(toCopy);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testCopyOfSortedDefensiveCopy() {
+ // Test that toArray() is used to make a defensive copy in copyOf(), so concurrently modified
+ // synchronized collections can be safely copied.
+ SortedMultiset<String> toCopy = EasyMock.createMock(SortedMultiset.class);
+ Set<Entry<String>> entrySet = EasyMock.createMock(Set.class);
+ EasyMock.expect((Comparator<Comparable>) toCopy.comparator())
+ .andReturn(Ordering.natural());
+ EasyMock.expect(toCopy.entrySet()).andReturn(entrySet);
+ EasyMock.expect(entrySet.toArray()).andReturn(new Object[0]);
+ EasyMock.replay(toCopy, entrySet);
+ ImmutableSortedMultiset<String> multiset =
+ ImmutableSortedMultiset.copyOfSorted(toCopy);
+ EasyMock.verify(toCopy, entrySet);
+ }
+
+ private static class IntegerDiv10 implements Comparable<IntegerDiv10> {
+ final int value;
+
+ IntegerDiv10(int value) {
+ this.value = value;
+ }
+
+ @Override
+ public int compareTo(IntegerDiv10 o) {
+ return value / 10 - o.value / 10;
+ }
+
+ @Override public String toString() {
+ return Integer.toString(value);
+ }
+ }
+
+ public void testCopyOfDuplicateInconsistentWithEquals() {
+ IntegerDiv10 three = new IntegerDiv10(3);
+ IntegerDiv10 eleven = new IntegerDiv10(11);
+ IntegerDiv10 twelve = new IntegerDiv10(12);
+ IntegerDiv10 twenty = new IntegerDiv10(20);
+
+ List<IntegerDiv10> original = ImmutableList.of(three, eleven, twelve, twenty);
+
+ Multiset<IntegerDiv10> copy = ImmutableSortedMultiset.copyOf(original);
+ assertTrue(copy.contains(eleven));
+ assertTrue(copy.contains(twelve));
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java b/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java
index 59506db..b4820b2 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableSortedSetTest.java
@@ -17,14 +17,33 @@
package com.google.common.collect;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.ImmutableSet.Builder;
+import com.google.common.collect.testing.ListTestSuiteBuilder;
+import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetAsListGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetCopyOfGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetDescendingAsListGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetDescendingGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitComparator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetExplicitSuperclassComparatorGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetHeadsetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetReversedOrderGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetAsListGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetSubsetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetTailsetGenerator;
+import com.google.common.collect.testing.google.SetGenerators.ImmutableSortedSetUnhashableGenerator;
+import com.google.common.collect.testing.testers.SetHashCodeTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -43,6 +62,117 @@ import java.util.TreeSet;
@GwtCompatible(emulated = true)
public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ImmutableSortedSetCopyOfGenerator())
+ .named(ImmutableSortedSetTest.class.getName())
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ImmutableSortedSetHeadsetGenerator())
+ .named(ImmutableSortedSetTest.class.getName() + ", headset")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ImmutableSortedSetTailsetGenerator())
+ .named(ImmutableSortedSetTest.class.getName() + ", tailset")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ImmutableSortedSetSubsetGenerator())
+ .named(ImmutableSortedSetTest.class.getName() + ", subset")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ImmutableSortedSetExplicitComparator())
+ .named(ImmutableSortedSetTest.class.getName()
+ + ", explicit comparator, vararg")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ImmutableSortedSetExplicitSuperclassComparatorGenerator())
+ .named(ImmutableSortedSetTest.class.getName()
+ + ", explicit superclass comparator, iterable")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ImmutableSortedSetReversedOrderGenerator())
+ .named(ImmutableSortedSetTest.class.getName()
+ + ", reverseOrder, iterator")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ImmutableSortedSetUnhashableGenerator())
+ .suppressing(SetHashCodeTester.getHashCodeMethods())
+ .named(ImmutableSortedSetTest.class.getName() + ", unhashable")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(
+ new ImmutableSortedSetDescendingGenerator())
+ .named(ImmutableSortedSetTest.class.getName() + ", descending")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableSortedSetAsListGenerator())
+ .named("ImmutableSortedSet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableSortedSetSubsetAsListGenerator())
+ .named("ImmutableSortedSet.subSet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTest(ListTestSuiteBuilder.using(
+ new ImmutableSortedSetDescendingAsListGenerator())
+ .named("ImmutableSortedSet.descendingSet.asList")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ suite.addTestSuite(ImmutableSortedSetTest.class);
+
+ return suite;
+ }
+
// enum singleton pattern
private enum StringLengthComparator implements Comparator<String> {
INSTANCE;
@@ -104,10 +234,8 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Comparable[].class, new Comparable[] { 0 });
- tester.testAllPublicStaticMethods(ImmutableSortedSet.class);
+ public void testNullPointers() {
+ new NullPointerTester().testAllPublicStaticMethods(ImmutableSortedSet.class);
}
public void testEmpty_comparator() {
@@ -163,7 +291,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testSingle_headSet() {
SortedSet<String> set = of("e");
assertTrue(set.headSet("g") instanceof ImmutableSortedSet);
- ASSERT.that(set.headSet("g")).hasContentsInOrder("e");
+ ASSERT.that(set.headSet("g")).has().item("e");
assertSame(of(), set.headSet("c"));
assertSame(of(), set.headSet("e"));
}
@@ -171,16 +299,16 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testSingle_tailSet() {
SortedSet<String> set = of("e");
assertTrue(set.tailSet("c") instanceof ImmutableSortedSet);
- ASSERT.that(set.tailSet("c")).hasContentsInOrder("e");
- ASSERT.that(set.tailSet("e")).hasContentsInOrder("e");
+ ASSERT.that(set.tailSet("c")).has().item("e");
+ ASSERT.that(set.tailSet("e")).has().item("e");
assertSame(of(), set.tailSet("g"));
}
public void testSingle_subSet() {
SortedSet<String> set = of("e");
assertTrue(set.subSet("c", "g") instanceof ImmutableSortedSet);
- ASSERT.that(set.subSet("c", "g")).hasContentsInOrder("e");
- ASSERT.that(set.subSet("e", "g")).hasContentsInOrder("e");
+ ASSERT.that(set.subSet("c", "g")).has().item("e");
+ ASSERT.that(set.subSet("e", "g")).has().item("e");
assertSame(of(), set.subSet("f", "g"));
assertSame(of(), set.subSet("c", "e"));
assertSame(of(), set.subSet("c", "d"));
@@ -205,7 +333,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testOf_ordering() {
SortedSet<String> set = of("e", "a", "f", "b", "d", "c");
- ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
}
/*
@@ -254,7 +382,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testOf_ordering_dupes() {
SortedSet<String> set = of("e", "a", "e", "f", "b", "b", "d", "a", "c");
- ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
}
public void testOf_comparator() {
@@ -265,8 +393,8 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testOf_headSet() {
SortedSet<String> set = of("e", "f", "b", "d", "c");
assertTrue(set.headSet("e") instanceof ImmutableSortedSet);
- ASSERT.that(set.headSet("e")).hasContentsInOrder("b", "c", "d");
- ASSERT.that(set.headSet("g")).hasContentsInOrder("b", "c", "d", "e", "f");
+ ASSERT.that(set.headSet("e")).has().allOf("b", "c", "d").inOrder();
+ ASSERT.that(set.headSet("g")).has().allOf("b", "c", "d", "e", "f").inOrder();
assertSame(of(), set.headSet("a"));
assertSame(of(), set.headSet("b"));
}
@@ -274,16 +402,16 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testOf_tailSet() {
SortedSet<String> set = of("e", "f", "b", "d", "c");
assertTrue(set.tailSet("e") instanceof ImmutableSortedSet);
- ASSERT.that(set.tailSet("e")).hasContentsInOrder("e", "f");
- ASSERT.that(set.tailSet("a")).hasContentsInOrder("b", "c", "d", "e", "f");
+ ASSERT.that(set.tailSet("e")).has().allOf("e", "f").inOrder();
+ ASSERT.that(set.tailSet("a")).has().allOf("b", "c", "d", "e", "f").inOrder();
assertSame(of(), set.tailSet("g"));
}
public void testOf_subSet() {
SortedSet<String> set = of("e", "f", "b", "d", "c");
assertTrue(set.subSet("c", "e") instanceof ImmutableSortedSet);
- ASSERT.that(set.subSet("c", "e")).hasContentsInOrder("c", "d");
- ASSERT.that(set.subSet("a", "g")).hasContentsInOrder("b", "c", "d", "e", "f");
+ ASSERT.that(set.subSet("c", "e")).has().allOf("c", "d").inOrder();
+ ASSERT.that(set.subSet("a", "g")).has().allOf("b", "c", "d", "e", "f").inOrder();
assertSame(of(), set.subSet("a", "b"));
assertSame(of(), set.subSet("g", "h"));
assertSame(of(), set.subSet("c", "c"));
@@ -323,14 +451,14 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testExplicit_ordering() {
SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
"in", "the", "quick", "jumped", "over", "a").build();
- ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
+ ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
}
public void testExplicit_ordering_dupes() {
SortedSet<String> set = ImmutableSortedSet.orderedBy(STRING_LENGTH).add(
"in", "the", "quick", "brown", "fox", "jumped",
"over", "a", "lazy", "dog").build();
- ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
+ ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
}
public void testExplicit_contains() {
@@ -360,9 +488,9 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
"in", "the", "quick", "jumped", "over", "a").build();
assertTrue(set.headSet("a") instanceof ImmutableSortedSet);
assertTrue(set.headSet("fish") instanceof ImmutableSortedSet);
- ASSERT.that(set.headSet("fish")).hasContentsInOrder("a", "in", "the");
- ASSERT.that(
- set.headSet("california")).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
+ ASSERT.that(set.headSet("fish")).has().allOf("a", "in", "the").inOrder();
+ ASSERT.that(set.headSet("california")).has()
+ .allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
assertTrue(set.headSet("a").isEmpty());
assertTrue(set.headSet("").isEmpty());
}
@@ -372,9 +500,9 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
"in", "the", "quick", "jumped", "over", "a").build();
assertTrue(set.tailSet("california") instanceof ImmutableSortedSet);
assertTrue(set.tailSet("fish") instanceof ImmutableSortedSet);
- ASSERT.that(set.tailSet("fish")).hasContentsInOrder("over", "quick", "jumped");
+ ASSERT.that(set.tailSet("fish")).has().allOf("over", "quick", "jumped").inOrder();
ASSERT.that(
- set.tailSet("a")).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
+ set.tailSet("a")).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
assertTrue(set.tailSet("california").isEmpty());
}
@@ -383,9 +511,9 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
"in", "the", "quick", "jumped", "over", "a").build();
assertTrue(set.subSet("the", "quick") instanceof ImmutableSortedSet);
assertTrue(set.subSet("", "b") instanceof ImmutableSortedSet);
- ASSERT.that(set.subSet("the", "quick")).hasContentsInOrder("the", "over");
+ ASSERT.that(set.subSet("the", "quick")).has().allOf("the", "over").inOrder();
ASSERT.that(set.subSet("a", "california"))
- .hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
+ .has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
assertTrue(set.subSet("", "b").isEmpty());
assertTrue(set.subSet("vermont", "california").isEmpty());
assertTrue(set.subSet("aaa", "zzz").isEmpty());
@@ -429,13 +557,13 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testCopyOf_ordering() {
SortedSet<String> set =
copyOf(asList("e", "a", "f", "b", "d", "c"));
- ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
}
public void testCopyOf_ordering_dupes() {
SortedSet<String> set =
copyOf(asList("e", "a", "e", "f", "b", "b", "d", "a", "c"));
- ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
}
public void testCopyOf_subSet() {
@@ -466,13 +594,13 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testCopyOf_iterator_ordering() {
SortedSet<String> set = copyOf(asIterator("e", "a", "f", "b", "d", "c"));
- ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
}
public void testCopyOf_iterator_ordering_dupes() {
SortedSet<String> set =
copyOf(asIterator("e", "a", "e", "f", "b", "b", "d", "a", "c"));
- ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
}
public void testCopyOf_iterator_comparator() {
@@ -483,7 +611,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testCopyOf_sortedSet_ordering() {
SortedSet<String> set =
copyOf(Sets.newTreeSet(asList("e", "a", "f", "b", "d", "c")));
- ASSERT.that(set).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(set).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
}
public void testCopyOf_sortedSet_comparator() {
@@ -495,7 +623,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
SortedSet<String> set =
ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
"in", "the", "quick", "jumped", "over", "a"));
- ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
+ ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
}
public void testCopyOfExplicit_ordering_dupes() {
@@ -503,7 +631,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
ImmutableSortedSet.copyOf(STRING_LENGTH, asList(
"in", "the", "quick", "brown", "fox", "jumped", "over", "a",
"lazy", "dog"));
- ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
+ ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
}
public void testCopyOfExplicit_comparator() {
@@ -517,7 +645,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
SortedSet<String> set =
ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
"in", "the", "quick", "jumped", "over", "a"));
- ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
+ ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
}
public void testCopyOfExplicit_iterator_ordering_dupes() {
@@ -525,7 +653,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
ImmutableSortedSet.copyOf(STRING_LENGTH, asIterator(
"in", "the", "quick", "brown", "fox", "jumped", "over", "a",
"lazy", "dog"));
- ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
+ ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
}
public void testCopyOfExplicit_iterator_comparator() {
@@ -539,14 +667,14 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH);
Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a");
SortedSet<String> set = copyOf(input);
- ASSERT.that(set).hasContentsInOrder("a", "in", "jumped", "over", "quick", "the");
+ ASSERT.that(set).has().allOf("a", "in", "jumped", "over", "quick", "the").inOrder();
}
public void testCopyOfSorted_natural_ordering() {
SortedSet<String> input = Sets.newTreeSet(
asList("in", "the", "quick", "jumped", "over", "a"));
SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
- ASSERT.that(set).hasContentsInOrder("a", "in", "jumped", "over", "quick", "the");
+ ASSERT.that(set).has().allOf("a", "in", "jumped", "over", "quick", "the").inOrder();
}
public void testCopyOfSorted_natural_comparator() {
@@ -560,7 +688,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
SortedSet<String> input = Sets.newTreeSet(STRING_LENGTH);
Collections.addAll(input, "in", "the", "quick", "jumped", "over", "a");
SortedSet<String> set = ImmutableSortedSet.copyOfSorted(input);
- ASSERT.that(set).hasContentsInOrder("a", "in", "the", "over", "quick", "jumped");
+ ASSERT.that(set).has().allOf("a", "in", "the", "over", "quick", "jumped").inOrder();
assertSame(STRING_LENGTH, set.comparator());
}
@@ -658,7 +786,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testReverseOrder() {
SortedSet<String> set = ImmutableSortedSet.<String>reverseOrder()
.add("a", "b", "c").build();
- ASSERT.that(set).hasContentsInOrder("c", "b", "a");
+ ASSERT.that(set).has().allOf("c", "b", "a").inOrder();
assertEquals(Ordering.natural().reverse(), set.comparator());
}
@@ -673,16 +801,16 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
public void testSupertypeComparator() {
SortedSet<Integer> set = new ImmutableSortedSet.Builder<Integer>(TO_STRING)
.add(3, 12, 101, 44).build();
- ASSERT.that(set).hasContentsInOrder(101, 12, 3, 44);
+ ASSERT.that(set).has().allOf(101, 12, 3, 44).inOrder();
}
public void testSupertypeComparatorSubtypeElements() {
SortedSet<Number> set = new ImmutableSortedSet.Builder<Number>(TO_STRING)
.add(3, 12, 101, 44).build();
- ASSERT.that(set).hasContentsInOrder(101, 12, 3, 44);
+ ASSERT.that(set).has().allOf(101, 12, 3, 44).inOrder();
}
- @Override <E extends Comparable<E>> Builder<E> builder() {
+ @Override <E extends Comparable<E>> ImmutableSortedSet.Builder<E> builder() {
return ImmutableSortedSet.naturalOrder();
}
@@ -821,7 +949,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
Arrays.sort(strings);
for (int i = 0; i < strings.length; i++) {
ASSERT.that(set.headSet(strings[i], true))
- .hasContentsInOrder(sortedNumberNames(0, i + 1));
+ .has().allFrom(sortedNumberNames(0, i + 1)).inOrder();
}
}
@@ -830,7 +958,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
Arrays.sort(strings);
for (int i = 0; i < strings.length; i++) {
- ASSERT.that(set.headSet(strings[i], false)).hasContentsInOrder(sortedNumberNames(0, i));
+ ASSERT.that(set.headSet(strings[i], false)).has().allFrom(sortedNumberNames(0, i)).inOrder();
}
}
@@ -839,8 +967,8 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
Arrays.sort(strings);
for (int i = 0; i < strings.length; i++) {
- ASSERT.that(set.tailSet(strings[i], true)).hasContentsInOrder(
- sortedNumberNames(i, strings.length));
+ ASSERT.that(set.tailSet(strings[i], true)).has().allFrom(
+ sortedNumberNames(i, strings.length)).inOrder();
}
}
@@ -849,8 +977,8 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
ImmutableSortedSet<String> set = ImmutableSortedSet.copyOf(strings);
Arrays.sort(strings);
for (int i = 0; i < strings.length; i++) {
- ASSERT.that(set.tailSet(strings[i], false)).hasContentsInOrder(
- sortedNumberNames(i + 1, strings.length));
+ ASSERT.that(set.tailSet(strings[i], false)).has().allFrom(
+ sortedNumberNames(i + 1, strings.length)).inOrder();
}
}
@@ -861,7 +989,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
for (int i = 0; i < strings.length; i++) {
for (int j = i; j < strings.length; j++) {
ASSERT.that(set.subSet(strings[i], false, strings[j], false))
- .hasContentsInOrder(sortedNumberNames(Math.min(i + 1, j), j));
+ .has().allFrom(sortedNumberNames(Math.min(i + 1, j), j)).inOrder();
}
}
}
@@ -873,7 +1001,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
for (int i = 0; i < strings.length; i++) {
for (int j = i; j < strings.length; j++) {
ASSERT.that(set.subSet(strings[i], true, strings[j], false))
- .hasContentsInOrder(sortedNumberNames(i, j));
+ .has().allFrom(sortedNumberNames(i, j)).inOrder();
}
}
}
@@ -885,7 +1013,7 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
for (int i = 0; i < strings.length; i++) {
for (int j = i; j < strings.length; j++) {
ASSERT.that(set.subSet(strings[i], false, strings[j], true))
- .hasContentsInOrder(sortedNumberNames(i + 1, j + 1));
+ .has().allFrom(sortedNumberNames(i + 1, j + 1)).inOrder();
}
}
}
@@ -897,13 +1025,13 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
for (int i = 0; i < strings.length; i++) {
for (int j = i; j < strings.length; j++) {
ASSERT.that(set.subSet(strings[i], true, strings[j], true))
- .hasContentsInOrder(sortedNumberNames(i, j + 1));
+ .has().allFrom(sortedNumberNames(i, j + 1)).inOrder();
}
}
}
- private static String[] sortedNumberNames(int i, int j) {
- return SORTED_NUMBER_NAMES.subList(i, j).toArray(new String[0]);
+ private static ImmutableList<String> sortedNumberNames(int i, int j) {
+ return ImmutableList.copyOf(SORTED_NUMBER_NAMES.subList(i, j));
}
private static final ImmutableList<String> NUMBER_NAMES =
@@ -912,4 +1040,22 @@ public class ImmutableSortedSetTest extends AbstractImmutableSetTest {
private static final ImmutableList<String> SORTED_NUMBER_NAMES =
Ordering.natural().immutableSortedCopy(NUMBER_NAMES);
+ private static class SelfComparableExample implements Comparable<SelfComparableExample> {
+ @Override
+ public int compareTo(SelfComparableExample o) {
+ return 0;
+ }
+ }
+
+ public void testBuilderGenerics_SelfComparable() {
+ ImmutableSortedSet.Builder<SelfComparableExample> natural = ImmutableSortedSet.naturalOrder();
+ ImmutableSortedSet.Builder<SelfComparableExample> reverse = ImmutableSortedSet.reverseOrder();
+ }
+
+ private static class SuperComparableExample extends SelfComparableExample {}
+
+ public void testBuilderGenerics_SuperComparable() {
+ ImmutableSortedSet.Builder<SuperComparableExample> natural = ImmutableSortedSet.naturalOrder();
+ ImmutableSortedSet.Builder<SuperComparableExample> reverse = ImmutableSortedSet.reverseOrder();
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/ImmutableTableTest.java b/guava-tests/test/com/google/common/collect/ImmutableTableTest.java
index 6311b68..97570fa 100644
--- a/guava-tests/test/com/google/common/collect/ImmutableTableTest.java
+++ b/guava-tests/test/com/google/common/collect/ImmutableTableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,13 +16,16 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.annotations.GwtCompatible;
/**
* Tests common methods in {@link ImmutableTable}
*
- * @author gak@google.com (Gregory Kick)
+ * @author Gregory Kick
*/
+@GwtCompatible(emulated = true)
public class ImmutableTableTest extends AbstractTableReadTest {
@Override protected Table<String, Integer, Character> create(Object... data) {
ImmutableTable.Builder<String, Integer, Character> builder =
@@ -181,9 +184,9 @@ public class ImmutableTableTest extends AbstractTableReadTest {
validateTableCopies(table);
// Even though rowKeySet, columnKeySet, and cellSet have the same
// iteration ordering, row has an inconsistent ordering.
- ASSERT.that(table.row('b').keySet()).hasContentsInOrder(1, 2);
+ ASSERT.that(table.row('b').keySet()).has().allOf(1, 2).inOrder();
ASSERT.that(ImmutableTable.copyOf(table).row('b').keySet())
- .hasContentsInOrder(2, 1);
+ .has().allOf(2, 1).inOrder();
}
public void testCopyOfSparse() {
@@ -224,10 +227,10 @@ public class ImmutableTableTest extends AbstractTableReadTest {
= builder.orderRowsBy(Ordering.natural())
.orderColumnsBy(Ordering.natural())
.putAll(table).build();
- ASSERT.that(copy.rowKeySet()).hasContentsInOrder('a', 'b');
- ASSERT.that(copy.columnKeySet()).hasContentsInOrder(1, 2);
- ASSERT.that(copy.values()).hasContentsInOrder("baz", "bar", "foo");
- ASSERT.that(copy.row('b').keySet()).hasContentsInOrder(1, 2);
+ ASSERT.that(copy.rowKeySet()).has().allOf('a', 'b').inOrder();
+ ASSERT.that(copy.columnKeySet()).has().allOf(1, 2).inOrder();
+ ASSERT.that(copy.values()).has().allOf("baz", "bar", "foo").inOrder();
+ ASSERT.that(copy.row('b').keySet()).has().allOf(1, 2).inOrder();
}
public void testBuilder_orderRowsAndColumnsBy_sparse() {
@@ -245,12 +248,12 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('r', 4, "foo");
builder.put('x', 5, "bar");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.rowKeySet()).hasContentsInOrder('b', 'c', 'e', 'r', 'x');
- ASSERT.that(table.columnKeySet()).hasContentsInOrder(0, 1, 2, 3, 4, 5, 7);
- ASSERT.that(table.values()).hasContentsInOrder("cat", "axe", "baz", "tub",
- "dog", "bar", "foo", "foo", "bar");
- ASSERT.that(table.row('c').keySet()).hasContentsInOrder(0, 3);
- ASSERT.that(table.column(5).keySet()).hasContentsInOrder('e', 'x');
+ ASSERT.that(table.rowKeySet()).has().allOf('b', 'c', 'e', 'r', 'x').inOrder();
+ ASSERT.that(table.columnKeySet()).has().allOf(0, 1, 2, 3, 4, 5, 7).inOrder();
+ ASSERT.that(table.values()).has().allOf("cat", "axe", "baz", "tub",
+ "dog", "bar", "foo", "foo", "bar").inOrder();
+ ASSERT.that(table.row('c').keySet()).has().allOf(0, 3).inOrder();
+ ASSERT.that(table.column(5).keySet()).has().allOf('e', 'x').inOrder();
}
public void testBuilder_orderRowsAndColumnsBy_dense() {
@@ -267,12 +270,12 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('a', 2, "bar");
builder.put('a', 1, "baz");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.rowKeySet()).hasContentsInOrder('a', 'b', 'c');
- ASSERT.that(table.columnKeySet()).hasContentsInOrder(1, 2, 3);
- ASSERT.that(table.values()).hasContentsInOrder("baz", "bar", "foo", "dog",
- "cat", "baz", "bar", "foo");
- ASSERT.that(table.row('c').keySet()).hasContentsInOrder(1, 2, 3);
- ASSERT.that(table.column(1).keySet()).hasContentsInOrder('a', 'b', 'c');
+ ASSERT.that(table.rowKeySet()).has().allOf('a', 'b', 'c').inOrder();
+ ASSERT.that(table.columnKeySet()).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(table.values()).has().allOf("baz", "bar", "foo", "dog",
+ "cat", "baz", "bar", "foo").inOrder();
+ ASSERT.that(table.row('c').keySet()).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(table.column(1).keySet()).has().allOf('a', 'b', 'c').inOrder();
}
public void testBuilder_orderRowsBy_sparse() {
@@ -289,8 +292,8 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('r', 4, "foo");
builder.put('x', 5, "bar");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.rowKeySet()).hasContentsInOrder('b', 'c', 'e', 'r', 'x');
- ASSERT.that(table.column(5).keySet()).hasContentsInOrder('e', 'x');
+ ASSERT.that(table.rowKeySet()).has().allOf('b', 'c', 'e', 'r', 'x').inOrder();
+ ASSERT.that(table.column(5).keySet()).has().allOf('e', 'x').inOrder();
}
public void testBuilder_orderRowsBy_dense() {
@@ -306,8 +309,8 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('a', 2, "bar");
builder.put('a', 1, "baz");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.rowKeySet()).hasContentsInOrder('a', 'b', 'c');
- ASSERT.that(table.column(1).keySet()).hasContentsInOrder('a', 'b', 'c');
+ ASSERT.that(table.rowKeySet()).has().allOf('a', 'b', 'c').inOrder();
+ ASSERT.that(table.column(1).keySet()).has().allOf('a', 'b', 'c').inOrder();
}
public void testBuilder_orderColumnsBy_sparse() {
@@ -324,8 +327,8 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('r', 4, "foo");
builder.put('x', 5, "bar");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.columnKeySet()).hasContentsInOrder(0, 1, 2, 3, 4, 5, 7);
- ASSERT.that(table.row('c').keySet()).hasContentsInOrder(0, 3);
+ ASSERT.that(table.columnKeySet()).has().allOf(0, 1, 2, 3, 4, 5, 7).inOrder();
+ ASSERT.that(table.row('c').keySet()).has().allOf(0, 3).inOrder();
}
public void testBuilder_orderColumnsBy_dense() {
@@ -341,7 +344,7 @@ public class ImmutableTableTest extends AbstractTableReadTest {
builder.put('a', 2, "bar");
builder.put('a', 1, "baz");
Table<Character, Integer, String> table = builder.build();
- ASSERT.that(table.columnKeySet()).hasContentsInOrder(1, 2, 3);
- ASSERT.that(table.row('c').keySet()).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(table.columnKeySet()).has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(table.row('c').keySet()).has().allOf(1, 2, 3).inOrder();
}
}
diff --git a/guava-tests/test/com/google/common/collect/InternersTest.java b/guava-tests/test/com/google/common/collect/InternersTest.java
index db11ad2..49ea67c 100644
--- a/guava-tests/test/com/google/common/collect/InternersTest.java
+++ b/guava-tests/test/com/google/common/collect/InternersTest.java
@@ -17,6 +17,7 @@
package com.google.common.collect;
import com.google.common.base.Function;
+import com.google.common.testing.GcFinalization;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -72,17 +73,10 @@ public class InternersTest extends TestCase {
assertSame(canonical, pool.intern(canonical));
WeakReference<Integer> signal = new WeakReference<Integer>(canonical);
- canonical = null;
-
- for (int i = 0; i < 3000; i++) {
- System.gc();
- if (signal.get() == null) { // it was collected
- assertSame(not, pool.intern(not));
- return;
- }
- Thread.sleep(1);
- }
- fail("reference didn't get cleaned up");
+ canonical = null; // Hint to the JIT that canonical is unreachable
+
+ GcFinalization.awaitClear(signal);
+ assertSame(not, pool.intern(not));
}
public void testAsFunction_simplistic() {
@@ -96,7 +90,7 @@ public class InternersTest extends TestCase {
assertSame(canonical, internerFunction.apply(not));
}
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
new NullPointerTester().testAllPublicStaticMethods(Interners.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/IterablesTest.java b/guava-tests/test/com/google/common/collect/IterablesTest.java
index b0ea688..ba989b1 100644
--- a/guava-tests/test/com/google/common/collect/IterablesTest.java
+++ b/guava-tests/test/com/google/common/collect/IterablesTest.java
@@ -23,7 +23,7 @@ import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -32,6 +32,7 @@ import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.testing.IteratorTester;
+import com.google.common.testing.ClassSanityTester;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -210,18 +211,6 @@ public class IterablesTest extends TestCase {
assertTrue(Arrays.equals(sourceArray, newArray));
}
- public void testFilter() {
- Iterable<String> unfiltered = newArrayList("foo", "bar");
- Iterable<String> filtered = Iterables.filter(unfiltered,
- Predicates.equalTo("foo"));
-
- List<String> expected = Collections.singletonList("foo");
- List<String> actual = newArrayList(filtered);
- assertEquals(expected, actual);
- assertCanIterateAgain(filtered);
- assertEquals("[foo]", filtered.toString());
- }
-
public void testAny() {
List<String> list = newArrayList();
Predicate<String> predicate = Predicates.equalTo("pants");
@@ -294,7 +283,7 @@ public class IterablesTest extends TestCase {
Iterable<TypeA> alist = Lists
.newArrayList(new TypeA(), new TypeA(), hasBoth, new TypeA());
Iterable<TypeB> blist = Iterables.filter(alist, TypeB.class);
- ASSERT.that(blist).hasContentsInOrder(hasBoth);
+ ASSERT.that(blist).iteratesOverSequence(hasBoth);
}
public void testTransform() {
@@ -422,7 +411,7 @@ public class IterablesTest extends TestCase {
int n = 4;
Iterable<Integer> repeated
= Iterables.concat(Collections.nCopies(n, iterable));
- ASSERT.that(repeated).hasContentsInOrder(
+ ASSERT.that(repeated).iteratesOverSequence(
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3);
}
@@ -521,8 +510,8 @@ public class IterablesTest extends TestCase {
List<String> freshlyAdded = newArrayList("freshly", "added");
boolean changed = Iterables.addAll(alreadyThere, freshlyAdded);
- ASSERT.that(alreadyThere).hasContentsInOrder(
- "already", "there", "freshly", "added");
+ ASSERT.that(alreadyThere).has().allOf(
+ "already", "there", "freshly", "added").inOrder();
assertTrue(changed);
}
@@ -532,7 +521,7 @@ public class IterablesTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Iterables.class);
}
@@ -565,42 +554,6 @@ public class IterablesTest extends TestCase {
assertFalse(Iterables.elementsEqual(b, a));
}
- @GwtIncompatible("slow (~30s)")
- @SuppressWarnings("deprecation") // test of a deprecated method
- public void testReversePassesIteratorsTester() {
- new IteratorTester<Integer>(5, MODIFIABLE, newArrayList(2, 4, 6, 8),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- @Override protected Iterator<Integer> newTargetIterator() {
- return Iterables.reverse(newArrayList(8, 6, 4, 2)).iterator();
- }
- }.test();
- }
-
- @SuppressWarnings("deprecation") // test of a deprecated method
- public void testReverseWorksAsExpected() {
- String[] testStrs = new String[] {"foo", "bar", "baz"};
- String[] expected = new String[] {"baz", "bar", "foo"};
-
- List<String> stuff = ImmutableList.copyOf(testStrs);
-
- Iterable<String> reversed = Iterables.reverse(stuff);
- ASSERT.that(reversed).hasContentsInOrder(expected);
- assertEquals("[baz, bar, foo]", reversed.toString());
-
- List<String> removable = newArrayList("foo", "bar", "bad", "baz");
-
- reversed = Iterables.reverse(removable);
- ASSERT.that(reversed).hasContentsInOrder("baz", "bad", "bar", "foo");
-
- Iterator<String> reverseIter = reversed.iterator();
- assertEquals("baz", reverseIter.next());
- assertEquals("bad", reverseIter.next());
- reverseIter.remove();
-
- ASSERT.that(reversed).hasContentsInOrder(expected);
- ASSERT.that(reversed).hasContentsInOrder(expected);
- }
-
public void testToString() {
List<String> list = Collections.emptyList();
assertEquals("[]", Iterables.toString(list));
@@ -703,7 +656,7 @@ public class IterablesTest extends TestCase {
Iterable<String> tail = skip(set, 1);
set.remove("b");
set.addAll(newArrayList("A", "B", "C"));
- ASSERT.that(tail).hasContentsInOrder("c", "A", "B", "C");
+ ASSERT.that(tail).iteratesOverSequence("c", "A", "B", "C");
}
public void testSkip_structurallyModifiedSkipSomeList() throws Exception {
@@ -711,7 +664,7 @@ public class IterablesTest extends TestCase {
Iterable<String> tail = skip(list, 1);
list.subList(1, 3).clear();
list.addAll(0, newArrayList("A", "B", "C"));
- ASSERT.that(tail).hasContentsInOrder("B", "C", "a");
+ ASSERT.that(tail).iteratesOverSequence("B", "C", "a");
}
public void testSkip_structurallyModifiedSkipAll() throws Exception {
@@ -1133,7 +1086,7 @@ public class IterablesTest extends TestCase {
/** Returns a new iterable over the specified strings. */
private static Iterable<String> create(String... strings) {
final List<String> list = asList(strings);
- return new Iterables.IterableWithToString<String>() {
+ return new FluentIterable<String>() {
@Override
public Iterator<String> iterator() {
return list.iterator();
@@ -1149,12 +1102,12 @@ public class IterablesTest extends TestCase {
Iterable<String> consumingIterable = Iterables.consumingIterable(list);
Iterator<String> consumingIterator = consumingIterable.iterator();
- ASSERT.that(list).hasContentsInOrder("a", "b");
+ ASSERT.that(list).has().allOf("a", "b").inOrder();
assertTrue(consumingIterator.hasNext());
- ASSERT.that(list).hasContentsInOrder("a", "b");
+ ASSERT.that(list).has().allOf("a", "b").inOrder();
assertEquals("a", consumingIterator.next());
- ASSERT.that(list).hasContentsInOrder("b");
+ ASSERT.that(list).has().item("b");
assertTrue(consumingIterator.hasNext());
assertEquals("b", consumingIterator.next());
@@ -1361,7 +1314,15 @@ public class IterablesTest extends TestCase {
verifyMergeSorted(iterables, allIntegers);
}
- private void verifyMergeSorted(Iterable<Iterable<Integer>> iterables,
+ @GwtIncompatible("reflection")
+ public void testIterables_nullCheck() throws Exception {
+ new ClassSanityTester()
+ .forAllPublicStaticMethods(Iterables.class)
+ .thatReturn(Iterable.class)
+ .testNulls();
+ }
+
+ private static void verifyMergeSorted(Iterable<Iterable<Integer>> iterables,
Iterable<Integer> unsortedExpected) {
Iterable<Integer> expected =
Ordering.natural().sortedCopy(unsortedExpected);
diff --git a/guava-tests/test/com/google/common/collect/IteratorsTest.java b/guava-tests/test/com/google/common/collect/IteratorsTest.java
index 60f3a3a..4c348f6 100644
--- a/guava-tests/test/com/google/common/collect/IteratorsTest.java
+++ b/guava-tests/test/com/google/common/collect/IteratorsTest.java
@@ -16,15 +16,15 @@
package com.google.common.collect;
+import static com.google.common.collect.Iterators.advance;
import static com.google.common.collect.Iterators.get;
import static com.google.common.collect.Iterators.getLast;
-import static com.google.common.collect.Iterators.skip;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static java.util.Arrays.asList;
import static java.util.Collections.singleton;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -44,7 +44,6 @@ import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -52,6 +51,7 @@ import java.util.ConcurrentModificationException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
+import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.RandomAccess;
import java.util.Set;
@@ -88,6 +88,39 @@ public class IteratorsTest extends TestCase {
}
}
+ public void testEmptyListIterator() {
+ ListIterator<String> iterator = Iterators.emptyListIterator();
+ assertFalse(iterator.hasNext());
+ assertFalse(iterator.hasPrevious());
+ assertEquals(0, iterator.nextIndex());
+ assertEquals(-1, iterator.previousIndex());
+ try {
+ iterator.next();
+ fail("no exception thrown");
+ } catch (NoSuchElementException expected) {
+ }
+ try {
+ iterator.previous();
+ fail("no exception thrown");
+ } catch (NoSuchElementException expected) {
+ }
+ try {
+ iterator.remove();
+ fail("no exception thrown");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ iterator.set("a");
+ fail("no exception thrown");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ iterator.add("a");
+ fail("no exception thrown");
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
public void testSize0() {
Iterator<String> iterator = Iterators.emptyIterator();
assertEquals(0, Iterators.size(iterator));
@@ -717,7 +750,7 @@ public class IteratorsTest extends TestCase {
boolean changed = Iterators.addAll(alreadyThere,
Iterators.<String>emptyIterator());
- ASSERT.that(alreadyThere).hasContentsInOrder("already", "there");
+ ASSERT.that(alreadyThere).has().allOf("already", "there").inOrder();
assertFalse(changed);
}
@@ -727,7 +760,7 @@ public class IteratorsTest extends TestCase {
boolean changed = Iterators.addAll(alreadyThere, freshlyAdded.iterator());
- ASSERT.that(alreadyThere).hasContentsInOrder("already", "there", "freshly", "added");
+ ASSERT.that(alreadyThere).has().allOf("already", "there", "freshly", "added");
assertTrue(changed);
}
@@ -737,12 +770,12 @@ public class IteratorsTest extends TestCase {
List<String> oneMore = Lists.newArrayList("there");
boolean changed = Iterators.addAll(alreadyThere, oneMore.iterator());
- ASSERT.that(alreadyThere).hasContentsInOrder("already", "there");
+ ASSERT.that(alreadyThere).has().allOf("already", "there").inOrder();
assertFalse(changed);
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Iterators.class);
}
@@ -999,29 +1032,29 @@ public class IteratorsTest extends TestCase {
public void testForArrayOffset() {
String[] array = {"foo", "bar", "cat", "dog"};
- Iterator<String> iterator = Iterators.forArray(array, 1, 2);
+ Iterator<String> iterator = Iterators.forArray(array, 1, 2, 0);
assertTrue(iterator.hasNext());
assertEquals("bar", iterator.next());
assertTrue(iterator.hasNext());
assertEquals("cat", iterator.next());
assertFalse(iterator.hasNext());
try {
- Iterators.forArray(array, 2, 3);
+ Iterators.forArray(array, 2, 3, 0);
fail();
} catch (IndexOutOfBoundsException expected) {}
}
public void testForArrayLength0() {
String[] array = {"foo", "bar"};
- assertFalse(Iterators.forArray(array, 0, 0).hasNext());
- assertFalse(Iterators.forArray(array, 1, 0).hasNext());
- assertFalse(Iterators.forArray(array, 2, 0).hasNext());
+ assertFalse(Iterators.forArray(array, 0, 0, 0).hasNext());
+ assertFalse(Iterators.forArray(array, 1, 0, 0).hasNext());
+ assertFalse(Iterators.forArray(array, 2, 0, 0).hasNext());
try {
- Iterators.forArray(array, -1, 0);
+ Iterators.forArray(array, -1, 0, 0);
fail();
} catch (IndexOutOfBoundsException expected) {}
try {
- Iterators.forArray(array, 3, 0);
+ Iterators.forArray(array, 3, 0, 0);
fail();
} catch (IndexOutOfBoundsException expected) {}
}
@@ -1041,7 +1074,7 @@ public class IteratorsTest extends TestCase {
new IteratorTester<Integer>(6, UNMODIFIABLE, asList(1, 2, 3),
IteratorTester.KnownOrder.KNOWN_ORDER) {
@Override protected Iterator<Integer> newTargetIterator() {
- return Iterators.forArray(new Integer[] { 0, 1, 2, 3, 4 }, 1, 3);
+ return Iterators.forArray(new Integer[] { 0, 1, 2, 3, 4 }, 1, 3, 0);
}
}.test();
}
@@ -1138,11 +1171,18 @@ public class IteratorsTest extends TestCase {
}
public void testToString() {
- List<String> list = Collections.emptyList();
- assertEquals("[]", Iterators.toString(list.iterator()));
+ Iterator<String> iterator = Lists.newArrayList("yam", "bam", "jam", "ham").iterator();
+ assertEquals("[yam, bam, jam, ham]", Iterators.toString(iterator));
+ }
- list = Lists.newArrayList("yam", "bam", "jam", "ham");
- assertEquals("[yam, bam, jam, ham]", Iterators.toString(list.iterator()));
+ public void testToStringWithNull() {
+ Iterator<String> iterator = Lists.newArrayList("hello", null, "world").iterator();
+ assertEquals("[hello, null, world]", Iterators.toString(iterator));
+ }
+
+ public void testToStringEmptyIterator() {
+ Iterator<String> iterator = Collections.<String>emptyList().iterator();
+ assertEquals("[]", Iterators.toString(iterator));
}
public void testLimit() {
@@ -1342,29 +1382,29 @@ public class IteratorsTest extends TestCase {
assertTrue(iterator.hasNext());
}
- public void testSkip_basic() {
+ public void testAdvance_basic() {
List<String> list = newArrayList();
list.add("a");
list.add("b");
Iterator<String> iterator = list.iterator();
- skip(iterator, 1);
+ advance(iterator, 1);
assertEquals("b", iterator.next());
}
- public void testSkip_pastEnd() {
+ public void testAdvance_pastEnd() {
List<String> list = newArrayList();
list.add("a");
list.add("b");
Iterator<String> iterator = list.iterator();
- skip(iterator, 5);
+ advance(iterator, 5);
assertFalse(iterator.hasNext());
}
- public void testSkip_illegalArgument() {
+ public void testAdvance_illegalArgument() {
List<String> list = newArrayList("a", "b", "c");
Iterator<String> iterator = list.iterator();
try {
- skip(iterator, -1);
+ advance(iterator, -1);
fail();
} catch (IllegalArgumentException expected) {}
}
@@ -1466,12 +1506,12 @@ public class IteratorsTest extends TestCase {
Iterator<String> consumingIterator =
Iterators.consumingIterator(list.iterator());
- ASSERT.that(list).hasContentsInOrder("a", "b");
+ ASSERT.that(list).has().allOf("a", "b").inOrder();
assertTrue(consumingIterator.hasNext());
- ASSERT.that(list).hasContentsInOrder("a", "b");
+ ASSERT.that(list).has().allOf("a", "b").inOrder();
assertEquals("a", consumingIterator.next());
- ASSERT.that(list).hasContentsInOrder("b");
+ ASSERT.that(list).has().item("b");
assertTrue(consumingIterator.hasNext());
assertEquals("b", consumingIterator.next());
diff --git a/guava-tests/test/com/google/common/collect/LenientSerializableTester.java b/guava-tests/test/com/google/common/collect/LenientSerializableTester.java
index 5f4f771..ec286d5 100644
--- a/guava-tests/test/com/google/common/collect/LenientSerializableTester.java
+++ b/guava-tests/test/com/google/common/collect/LenientSerializableTester.java
@@ -42,6 +42,7 @@ final class LenientSerializableTester {
* TODO(cpovirk): move this to c.g.c.testing if we allow for c.g.c.annotations dependencies so
* that it can be GWTified?
*/
+
@GwtIncompatible("SerializableTester")
static <E> Set<E> reserializeAndAssertLenient(Set<E> original) {
Set<E> copy = reserialize(original);
@@ -50,5 +51,13 @@ final class LenientSerializableTester {
return copy;
}
+ @GwtIncompatible("SerializableTester")
+ static <E> Multiset<E> reserializeAndAssertLenient(Multiset<E> original) {
+ Multiset<E> copy = reserialize(original);
+ assertEquals(original, copy);
+ assertTrue(copy instanceof ImmutableMultiset);
+ return copy;
+ }
+
private LenientSerializableTester() {}
}
diff --git a/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java b/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java
index fb728b3..ea0490f 100644
--- a/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/LinkedHashMultimapTest.java
@@ -19,15 +19,24 @@ package com.google.common.collect;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.collect.Sets.newLinkedHashSet;
+import static com.google.common.collect.testing.Helpers.mapEntry;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.IteratorTester;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.SetMultimapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
import com.google.common.testing.SerializableTester;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -43,10 +52,51 @@ import java.util.Set;
@GwtCompatible(emulated = true)
public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(SetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() {
+ @Override
+ protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
+ SetMultimap<String, String> multimap = LinkedHashMultimap.create();
+ for (Entry<String, String> entry : entries) {
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return multimap;
+ }
+ })
+ .named("LinkedHashMultimap")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionSize.ANY)
+ .createTestSuite());
+ suite.addTestSuite(LinkedHashMultimapTest.class);
+ return suite;
+ }
+
@Override protected Multimap<String, Integer> create() {
return LinkedHashMultimap.create();
}
+ public void testValueSetHashTableExpansion() {
+ LinkedHashMultimap<String, Integer> multimap = LinkedHashMultimap.create();
+ for (int z = 1; z <= 100; z++) {
+ multimap.put("a", z);
+ // The Eclipse compiler (and hence GWT) rejects a parameterized cast.
+ @SuppressWarnings("unchecked")
+ LinkedHashMultimap<String, Integer>.ValueSet valueSet =
+ (LinkedHashMultimap.ValueSet) multimap.backingMap().get("a");
+ assertEquals(z, valueSet.size());
+ assertFalse(Hashing.needsResizing(valueSet.size(), valueSet.hashTable.length,
+ LinkedHashMultimap.VALUE_SET_LOAD_FACTOR));
+ }
+ }
+
private Multimap<String, Integer> initializeMultimap5() {
Multimap<String, Integer> multimap = getMultimap();
multimap.put("foo", 5);
@@ -85,13 +135,30 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
assertOrderingReadOnly(copy);
}
+ @GwtIncompatible("SeriazableTester")
+ public void testSerializationOrderingKeysAndEntries() {
+ Multimap<String, Integer> multimap = LinkedHashMultimap.create();
+ multimap.put("a", 1);
+ multimap.put("b", 2);
+ multimap.put("a", 3);
+ multimap.put("c", 4);
+ multimap.remove("a", 1);
+ multimap = SerializableTester.reserializeAndAssert(multimap);
+ ASSERT.that(multimap.keySet()).has().allOf("a", "b", "c").inOrder();
+ ASSERT.that(multimap.entries()).has().allOf(
+ mapEntry("b", 2),
+ mapEntry("a", 3),
+ mapEntry("c", 4)).inOrder();
+ // note that the keys and entries are in different orders
+ }
+
private void assertOrderingReadOnly(Multimap<String, Integer> multimap) {
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(5, 3);
- ASSERT.that(multimap.get("bar")).hasContentsInOrder(4, 1);
- ASSERT.that(multimap.get("cow")).hasContentsInOrder(2);
+ ASSERT.that(multimap.get("foo")).has().allOf(5, 3).inOrder();
+ ASSERT.that(multimap.get("bar")).has().allOf(4, 1).inOrder();
+ ASSERT.that(multimap.get("cow")).has().item(2);
- ASSERT.that(multimap.keySet()).hasContentsInOrder("foo", "bar", "cow");
- ASSERT.that(multimap.values()).hasContentsInOrder(5, 4, 3, 2, 1);
+ ASSERT.that(multimap.keySet()).has().allOf("foo", "bar", "cow").inOrder();
+ ASSERT.that(multimap.values()).has().allOf(5, 4, 3, 2, 1).inOrder();
Iterator<Map.Entry<String, Integer>> entryIterator =
multimap.entries().iterator();
@@ -105,28 +172,28 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
multimap.asMap().entrySet().iterator();
Map.Entry<String, Collection<Integer>> entry = collectionIterator.next();
assertEquals("foo", entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsInOrder(5, 3);
+ ASSERT.that(entry.getValue()).has().allOf(5, 3).inOrder();
entry = collectionIterator.next();
assertEquals("bar", entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsInOrder(4, 1);
+ ASSERT.that(entry.getValue()).has().allOf(4, 1).inOrder();
entry = collectionIterator.next();
assertEquals("cow", entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsInOrder(2);
+ ASSERT.that(entry.getValue()).has().item(2);
}
public void testOrderingUpdates() {
Multimap<String, Integer> multimap = initializeMultimap5();
- ASSERT.that(multimap.replaceValues("foo", asList(6, 7))).hasContentsInOrder(5, 3);
- ASSERT.that(multimap.keySet()).hasContentsInOrder("foo", "bar", "cow");
- ASSERT.that(multimap.removeAll("foo")).hasContentsInOrder(6, 7);
- ASSERT.that(multimap.keySet()).hasContentsInOrder("bar", "cow");
+ ASSERT.that(multimap.replaceValues("foo", asList(6, 7))).has().allOf(5, 3).inOrder();
+ ASSERT.that(multimap.keySet()).has().allOf("foo", "bar", "cow").inOrder();
+ ASSERT.that(multimap.removeAll("foo")).has().allOf(6, 7).inOrder();
+ ASSERT.that(multimap.keySet()).has().allOf("bar", "cow").inOrder();
assertTrue(multimap.remove("bar", 4));
- ASSERT.that(multimap.keySet()).hasContentsInOrder("bar", "cow");
+ ASSERT.that(multimap.keySet()).has().allOf("bar", "cow").inOrder();
assertTrue(multimap.remove("bar", 1));
- ASSERT.that(multimap.keySet()).hasContentsInOrder("cow");
+ ASSERT.that(multimap.keySet()).has().item("cow");
multimap.put("bar", 9);
- ASSERT.that(multimap.keySet()).hasContentsInOrder("cow", "bar");
+ ASSERT.that(multimap.keySet()).has().allOf("cow", "bar").inOrder();
}
public void testToStringNullExact() {
@@ -169,7 +236,6 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
multimap.put("bar", 2);
multimap.put("foo", 3);
assertEquals(ImmutableSet.of(1, 3), multimap.get("foo"));
- assertEquals(8, multimap.expectedValuesPerKey);
}
public void testCreateFromMultimap() {
@@ -177,7 +243,6 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
LinkedHashMultimap<String, Integer> copy =
LinkedHashMultimap.create(multimap);
assertEquals(multimap, copy);
- assertEquals(8, copy.expectedValuesPerKey);
}
public void testCreateFromSizes() {
@@ -187,7 +252,6 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
multimap.put("bar", 2);
multimap.put("foo", 3);
assertEquals(ImmutableSet.of(1, 3), multimap.get("foo"));
- assertEquals(15, multimap.expectedValuesPerKey);
}
public void testCreateFromIllegalSizes() {
@@ -293,8 +357,8 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
@GwtIncompatible("unreasonable slow")
public void testKeySetIteration() {
- new IteratorTester<String>(6, MODIFIABLE, newLinkedHashSet(asList(
- "foo", "bar", "baz", "dog", "cat")),
+ new IteratorTester<String>(6, MODIFIABLE,
+ newLinkedHashSet(asList("foo", "bar", "baz", "dog", "cat")),
IteratorTester.KnownOrder.KNOWN_ORDER) {
private Multimap<String, Integer> multimap;
@@ -354,5 +418,4 @@ public class LinkedHashMultimapTest extends AbstractSetMultimapTest {
}
}.test();
}
-
}
diff --git a/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java b/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java
index dee3760..c6148c8 100644
--- a/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/LinkedHashMultisetTest.java
@@ -18,15 +18,24 @@ package com.google.common.collect;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static java.util.Arrays.asList;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.IteratorTester;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringMultisetGenerator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
+import java.util.List;
/**
* Unit test for {@link LinkedHashMultiset}.
@@ -35,6 +44,44 @@ import java.util.Iterator;
*/
@GwtCompatible(emulated = true)
public class LinkedHashMultisetTest extends AbstractMultisetTest {
+
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(MultisetTestSuiteBuilder.using(linkedHashMultisetGenerator())
+ .named("LinkedHashMultiset")
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.GENERAL_PURPOSE)
+ .createTestSuite());
+ suite.addTestSuite(LinkedHashMultisetTest.class);
+ return suite;
+ }
+
+ private static TestStringMultisetGenerator linkedHashMultisetGenerator() {
+ return new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ return LinkedHashMultiset.create(asList(elements));
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ List<String> order = Lists.newArrayList();
+ for (String s : insertionOrder) {
+ int index = order.indexOf(s);
+ if (index == -1) {
+ order.add(s);
+ } else {
+ order.add(index, s);
+ }
+ }
+ return order;
+ }
+ };
+ }
+
@Override protected <E> Multiset<E> create() {
return LinkedHashMultiset.create();
}
@@ -106,14 +153,14 @@ public class LinkedHashMultisetTest extends AbstractMultisetTest {
ms.add("a");
ms.add("b", 2);
ms.add("c");
- ASSERT.that(ms.elementSet()).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(ms.elementSet()).has().allOf("a", "b", "c").inOrder();
ms.remove("b");
- ASSERT.that(ms.elementSet()).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(ms.elementSet()).has().allOf("a", "b", "c").inOrder();
ms.add("b");
- ASSERT.that(ms.elementSet()).hasContentsInOrder("a", "b", "c");
+ ASSERT.that(ms.elementSet()).has().allOf("a", "b", "c").inOrder();
ms.remove("b", 2);
ms.add("b");
- ASSERT.that(ms.elementSet()).hasContentsInOrder("a", "c", "b");
+ ASSERT.that(ms.elementSet()).has().allOf("a", "c", "b").inOrder();
}
public void testIteratorRemoveConcurrentModification() {
diff --git a/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java b/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java
index fd19386..ffa2435 100644
--- a/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/LinkedListMultimapTest.java
@@ -23,12 +23,21 @@ import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static com.google.common.collect.testing.IteratorFeature.SUPPORTS_REMOVE;
import static com.google.common.collect.testing.IteratorFeature.SUPPORTS_SET;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.IteratorTester;
import com.google.common.collect.testing.ListIteratorTester;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringListMultimapGenerator;
+import com.google.common.testing.EqualsTester;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
import java.util.Arrays;
import java.util.Collection;
@@ -49,6 +58,32 @@ import java.util.Set;
@GwtCompatible(emulated = true)
public class LinkedListMultimapTest extends AbstractListMultimapTest {
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(ListMultimapTestSuiteBuilder.using(new TestStringListMultimapGenerator() {
+ @Override
+ protected ListMultimap<String, String> create(Entry<String, String>[] entries) {
+ ListMultimap<String, String> multimap = LinkedListMultimap.create();
+ for (Entry<String, String> entry : entries) {
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return multimap;
+ }
+ })
+ .named("LinkedListMultimap")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionSize.ANY)
+ .createTestSuite());
+ suite.addTestSuite(LinkedListMultimapTest.class);
+ return suite;
+ }
+
@Override protected LinkedListMultimap<String, Integer> create() {
return LinkedListMultimap.create();
}
@@ -195,10 +230,10 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest {
List<Integer> foos = map.get("foo");
Collection<Integer> values = map.values();
assertEquals(asList(1, 2), foos);
- ASSERT.that(values).hasContentsInOrder(1, 2, 3);
+ ASSERT.that(values).has().allOf(1, 2, 3).inOrder();
map.clear();
assertEquals(Collections.emptyList(), foos);
- ASSERT.that(values).hasContentsInOrder();
+ ASSERT.that(values).isEmpty();
assertEquals("[]", map.entries().toString());
assertEquals("{}", map.toString());
}
@@ -222,7 +257,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest {
map.put("bar", 4);
assertEquals("[bar=1, foo=2, bar=3, bar=4]",
map.entries().toString());
- ASSERT.that(map.keys()).hasContentsInOrder("bar", "foo", "bar", "bar");
+ ASSERT.that(map.keys()).has().allOf("bar", "foo", "bar", "bar").inOrder();
map.keys().remove("bar"); // bar is no longer the first key!
assertEquals("{foo=[2], bar=[3, 4]}", map.toString());
}
@@ -268,7 +303,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest {
= map.asMap().entrySet().iterator();
Map.Entry<String, Collection<Integer>> entry = entries.next();
assertEquals("bar", entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsInOrder(1, 3);
+ ASSERT.that(entry.getValue()).has().allOf(1, 3).inOrder();
try {
entry.setValue(Arrays.<Integer>asList());
fail("UnsupportedOperationException expected");
@@ -276,7 +311,7 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest {
entries.remove(); // clear
entry = entries.next();
assertEquals("foo", entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsInOrder(2);
+ ASSERT.that(entry.getValue()).has().item(2);
assertFalse(entries.hasNext());
assertEquals("{foo=[2]}", map.toString());
}
@@ -470,4 +505,13 @@ public class LinkedListMultimapTest extends AbstractListMultimapTest {
}
}.test();
}
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(
+ LinkedListMultimap.create(),
+ LinkedListMultimap.create(),
+ LinkedListMultimap.create(1))
+ .testEquals();
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/ListsTest.java b/guava-tests/test/com/google/common/collect/ListsTest.java
index cd7f710..8dd557c 100644
--- a/guava-tests/test/com/google/common/collect/ListsTest.java
+++ b/guava-tests/test/com/google/common/collect/ListsTest.java
@@ -20,7 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -28,12 +28,12 @@ import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.collect.testing.IteratorTester;
import com.google.common.collect.testing.ListTestSuiteBuilder;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.TestListGenerator;
import com.google.common.collect.testing.TestStringListGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.ListFeature;
+import com.google.common.collect.testing.google.ListGenerators.CharactersOfCharSequenceGenerator;
+import com.google.common.collect.testing.google.ListGenerators.CharactersOfStringGenerator;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -53,6 +53,7 @@ import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.RandomAccess;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* Unit test for {@code Lists}.
@@ -69,6 +70,14 @@ public class ListsTest extends TestCase {
private static final Iterable<Integer> SOME_ITERABLE = new SomeIterable();
+ private static final class RemoveFirstFunction
+ implements Function<String, String>, Serializable {
+ @Override
+ public String apply(String from) {
+ return (from.length() == 0) ? from : from.substring(1);
+ }
+ }
+
private static class SomeIterable implements Iterable<Integer>, Serializable {
@Override
public Iterator<Integer> iterator() {
@@ -106,34 +115,31 @@ public class ListsTest extends TestCase {
suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
@Override protected List<String> create(String[] elements) {
String[] rest = new String[elements.length - 1];
- Platform.unsafeArrayCopy(elements, 1, rest, 0, elements.length - 1);
+ System.arraycopy(elements, 1, rest, 0, elements.length - 1);
return Lists.asList(elements[0], rest);
}
})
.named("Lists.asList, 2 parameter")
.withFeatures(CollectionSize.SEVERAL, CollectionSize.ONE,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES)
.createTestSuite());
suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
@Override protected List<String> create(String[] elements) {
String[] rest = new String[elements.length - 2];
- Platform.unsafeArrayCopy(elements, 2, rest, 0, elements.length - 2);
+ System.arraycopy(elements, 2, rest, 0, elements.length - 2);
return Lists.asList(elements[0], elements[1], rest);
}
})
.named("Lists.asList, 3 parameter")
.withFeatures(CollectionSize.SEVERAL,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES)
.createTestSuite());
final Function<String, String> removeFirst
- = new Function<String, String>() {
- @Override
- public String apply(String from) {
- return (from.length() == 0) ? from : from.substring(1);
- }
- };
+ = new RemoveFirstFunction();
suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
@Override protected List<String> create(String[] elements) {
@@ -147,6 +153,7 @@ public class ListsTest extends TestCase {
.named("Lists.transform, random access, no nulls")
.withFeatures(CollectionSize.ANY,
ListFeature.REMOVE_OPERATIONS,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -162,6 +169,7 @@ public class ListsTest extends TestCase {
.named("Lists.transform, sequential access, no nulls")
.withFeatures(CollectionSize.ANY,
ListFeature.REMOVE_OPERATIONS,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -174,6 +182,7 @@ public class ListsTest extends TestCase {
.named("Lists.transform, random access, nulls")
.withFeatures(CollectionSize.ANY,
ListFeature.REMOVE_OPERATIONS,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES)
.createTestSuite());
@@ -187,6 +196,7 @@ public class ListsTest extends TestCase {
.named("Lists.transform, sequential access, nulls")
.withFeatures(CollectionSize.ANY,
ListFeature.REMOVE_OPERATIONS,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_VALUES)
.createTestSuite());
@@ -234,55 +244,15 @@ public class ListsTest extends TestCase {
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(
- ListTestSuiteBuilder.using(new TestListGenerator<Character>() {
- @Override public List<Character> create(Object... elements) {
- char[] chars = new char[elements.length];
- for (int i = 0; i < elements.length; i++)
- chars[i] = (Character) elements[i];
- return Lists.charactersOf(String.copyValueOf(chars));
- }
-
- @Override public Character[] createArray(int length) {
- return new Character[length];
- }
-
- @Override public Iterable<Character> order(
- List<Character> insertionOrder) {
- return ImmutableList.copyOf(insertionOrder);
- }
-
- @Override public SampleElements<Character> samples() {
- return new SampleElements<Character>('a', 'b', 'c', 'd', 'e');
- }
- }).named("Lists.charactersOf[String]").withFeatures(
- CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES)
+ suite.addTest(ListTestSuiteBuilder.using(new CharactersOfStringGenerator())
+ .named("Lists.charactersOf[String]").withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
- suite.addTest(
- ListTestSuiteBuilder.using(new TestListGenerator<Character>() {
- @Override public List<Character> create(Object... elements) {
- char[] chars = new char[elements.length];
- for (int i = 0; i < elements.length; i++)
- chars[i] = (Character) elements[i];
- StringBuilder str = new StringBuilder();
- str.append(chars);
- return Lists.charactersOf(str);
- }
-
- @Override public Character[] createArray(int length) {
- return new Character[length];
- }
-
- @Override public Iterable<Character> order(
- List<Character> insertionOrder) {
- return ImmutableList.copyOf(insertionOrder);
- }
-
- @Override public SampleElements<Character> samples() {
- return new SampleElements<Character>('a', 'b', 'c', 'd', 'e');
- }
- }).named("Lists.charactersOf[CharSequence]").withFeatures(
+ suite.addTest(ListTestSuiteBuilder.using(new CharactersOfCharSequenceGenerator())
+ .named("Lists.charactersOf[CharSequence]").withFeatures(
CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -382,8 +352,21 @@ public class ListsTest extends TestCase {
assertEquals(SOME_COLLECTION, list);
}
+ @GwtIncompatible("CopyOnWriteArrayList")
+ public void testNewCOWALEmpty() {
+ CopyOnWriteArrayList<Integer> list = Lists.newCopyOnWriteArrayList();
+ assertEquals(Collections.emptyList(), list);
+ }
+
+ @GwtIncompatible("CopyOnWriteArrayList")
+ public void testNewCOWALFromIterable() {
+ CopyOnWriteArrayList<Integer> list = Lists.newCopyOnWriteArrayList(
+ SOME_ITERABLE);
+ assertEquals(SOME_COLLECTION, list);
+ }
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Lists.class);
}
@@ -435,7 +418,7 @@ public class ListsTest extends TestCase {
}
private void checkFooBarBazList(List<String> list) {
- ASSERT.that(list).hasContentsInOrder("foo", "bar", "baz");
+ ASSERT.that(list).has().allOf("foo", "bar", "baz").inOrder();
assertEquals(3, list.size());
assertIndexIsOutOfBounds(list, -1);
assertEquals("foo", list.get(0));
@@ -446,7 +429,7 @@ public class ListsTest extends TestCase {
public void testAsList1Small() {
List<String> list = Lists.asList("foo", new String[0]);
- ASSERT.that(list).hasContentsInOrder("foo");
+ ASSERT.that(list).has().item("foo");
assertEquals(1, list.size());
assertIndexIsOutOfBounds(list, -1);
assertEquals("foo", list.get(0));
@@ -477,7 +460,7 @@ public class ListsTest extends TestCase {
@GwtIncompatible("SerializableTester")
public void testAsList2Small() {
List<String> list = Lists.asList("foo", "bar", new String[0]);
- ASSERT.that(list).hasContentsInOrder("foo", "bar");
+ ASSERT.that(list).has().allOf("foo", "bar").inOrder();
assertEquals(2, list.size());
assertIndexIsOutOfBounds(list, -1);
assertEquals("foo", list.get(0));
@@ -543,18 +526,64 @@ public class ListsTest extends TestCase {
assertEquals(Collections.emptyList(), fromList);
}
- @GwtIncompatible("SerializableTester")
- public void testTransformEqualityRandomAccess() {
- List<String> list = Lists.transform(SOME_LIST, SOME_FUNCTION);
- assertEquals(SOME_STRING_LIST, list);
- SerializableTester.reserializeAndAssert(list);
+ private static <E> List<E> list(E... elements) {
+ return ImmutableList.copyOf(elements);
}
- @GwtIncompatible("SerializableTester")
- public void testTransformEqualitySequential() {
- List<String> list = Lists.transform(SOME_SEQUENTIAL_LIST, SOME_FUNCTION);
- assertEquals(SOME_STRING_LIST, list);
- SerializableTester.reserializeAndAssert(list);
+ @SuppressWarnings("unchecked") // varargs!
+ public void testCartesianProduct_binary1x1() {
+ ASSERT.that(Lists.cartesianProduct(list(1), list(2))).has().item(list(1, 2));
+ }
+
+ @SuppressWarnings("unchecked") // varargs!
+ public void testCartesianProduct_binary1x2() {
+ ASSERT.that(Lists.cartesianProduct(list(1), list(2, 3)))
+ .has().allOf(list(1, 2), list(1, 3)).inOrder();
+ }
+
+ @SuppressWarnings("unchecked") // varargs!
+ public void testCartesianProduct_binary2x2() {
+ ASSERT.that(Lists.cartesianProduct(list(1, 2), list(3, 4)))
+ .has().allOf(list(1, 3), list(1, 4), list(2, 3), list(2, 4)).inOrder();
+ }
+
+ @SuppressWarnings("unchecked") // varargs!
+ public void testCartesianProduct_2x2x2() {
+ ASSERT.that(Lists.cartesianProduct(list(0, 1), list(0, 1), list(0, 1))).has().allOf(
+ list(0, 0, 0), list(0, 0, 1), list(0, 1, 0), list(0, 1, 1),
+ list(1, 0, 0), list(1, 0, 1), list(1, 1, 0), list(1, 1, 1)).inOrder();
+ }
+
+ @SuppressWarnings("unchecked") // varargs!
+ public void testCartesianProduct_contains() {
+ List<List<Integer>> actual = Lists.cartesianProduct(list(1, 2), list(3, 4));
+ assertTrue(actual.contains(list(1, 3)));
+ assertTrue(actual.contains(list(1, 4)));
+ assertTrue(actual.contains(list(2, 3)));
+ assertTrue(actual.contains(list(2, 4)));
+ assertFalse(actual.contains(list(3, 1)));
+ }
+
+ @SuppressWarnings("unchecked") // varargs!
+ public void testCartesianProduct_unrelatedTypes() {
+ List<Integer> x = list(1, 2);
+ List<String> y = list("3", "4");
+
+ List<Object> exp1 = list((Object) 1, "3");
+ List<Object> exp2 = list((Object) 1, "4");
+ List<Object> exp3 = list((Object) 2, "3");
+ List<Object> exp4 = list((Object) 2, "4");
+
+ ASSERT.that(Lists.<Object>cartesianProduct(x, y)).has().allOf(exp1, exp2, exp3, exp4).inOrder();
+ }
+
+ @SuppressWarnings("unchecked") // varargs!
+ public void testCartesianProductTooBig() {
+ List<String> list = Collections.nCopies(10000, "foo");
+ try {
+ Lists.cartesianProduct(list, list, list, list, list);
+ fail("Expected IAE");
+ } catch (IllegalArgumentException expected) {}
}
public void testTransformHashCodeRandomAccess() {
@@ -721,6 +750,7 @@ public class ListsTest extends TestCase {
ListIterator<Integer> sampleListIterator =
SOME_SEQUENTIAL_LIST.listIterator();
List<Integer> listMock = EasyMock.createMock(IntegerList.class);
+ EasyMock.expect(listMock.size()).andReturn(SOME_SEQUENTIAL_LIST.size());
EasyMock.expect(listMock.listIterator(0)).andReturn(sampleListIterator);
EasyMock.replay(listMock);
List<String> transform = Lists.transform(listMock, SOME_FUNCTION);
diff --git a/guava-tests/test/com/google/common/collect/MapConstraintsTest.java b/guava-tests/test/com/google/common/collect/MapConstraintsTest.java
index 6cf647b..d743032 100644
--- a/guava-tests/test/com/google/common/collect/MapConstraintsTest.java
+++ b/guava-tests/test/com/google/common/collect/MapConstraintsTest.java
@@ -17,7 +17,7 @@
package com.google.common.collect;
import static com.google.common.collect.testing.Helpers.nefariousMapEntry;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -115,11 +115,11 @@ public class MapConstraintsTest extends TestCase {
assertFalse(map.values() instanceof Serializable);
assertEquals(map.toString(), constrained.toString());
assertEquals(map.hashCode(), constrained.hashCode());
- ASSERT.that(map.entrySet()).hasContentsInOrder(
+ ASSERT.that(map.entrySet()).has().allOf(
Maps.immutableEntry(TEST_KEY, TEST_VALUE),
Maps.immutableEntry("foo", 1),
Maps.immutableEntry("bar", 2),
- Maps.immutableEntry("baz", 3));
+ Maps.immutableEntry("baz", 3)).inOrder();
}
public void testConstrainedMapIllegal() {
@@ -163,11 +163,11 @@ public class MapConstraintsTest extends TestCase {
assertEquals(map.values(), constrained.values());
assertEquals(map.toString(), constrained.toString());
assertEquals(map.hashCode(), constrained.hashCode());
- ASSERT.that(map.entrySet()).hasContentsInOrder(
+ ASSERT.that(map.entrySet()).has().allOf(
Maps.immutableEntry(TEST_KEY, TEST_VALUE),
Maps.immutableEntry("foo", 1),
Maps.immutableEntry("bar", 2),
- Maps.immutableEntry("baz", 3));
+ Maps.immutableEntry("baz", 3)).inOrder();
}
public void testConstrainedBiMapIllegal() {
@@ -232,7 +232,7 @@ public class MapConstraintsTest extends TestCase {
assertTrue(constrained.equals(multimap));
ASSERT.that(ImmutableList.copyOf(multimap.entries()))
.is(ImmutableList.copyOf(constrained.entries()));
- ASSERT.that(constrained.asMap().get("foo")).hasContentsInOrder(1);
+ ASSERT.that(constrained.asMap().get("foo")).has().item(1);
assertNull(constrained.asMap().get("missing"));
assertEquals(multimap.asMap(), constrained.asMap());
assertEquals(multimap.values(), constrained.values());
@@ -240,7 +240,7 @@ public class MapConstraintsTest extends TestCase {
assertEquals(multimap.keySet(), constrained.keySet());
assertEquals(multimap.toString(), constrained.toString());
assertEquals(multimap.hashCode(), constrained.hashCode());
- ASSERT.that(multimap.entries()).hasContentsInOrder(
+ ASSERT.that(multimap.entries()).has().allOf(
Maps.immutableEntry(TEST_KEY, TEST_VALUE),
Maps.immutableEntry("foo", 1),
Maps.immutableEntry("bar", 2),
@@ -252,7 +252,7 @@ public class MapConstraintsTest extends TestCase {
Maps.immutableEntry("bim", 8),
Maps.immutableEntry("bop", 9),
Maps.immutableEntry("dig", 10),
- Maps.immutableEntry("dag", 11));
+ Maps.immutableEntry("dag", 11)).inOrder();
assertFalse(constrained.asMap().values() instanceof Serializable);
Iterator<Collection<Integer>> iterator =
constrained.asMap().values().iterator();
diff --git a/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java b/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java
index 443a8a8..c8c4d47 100644
--- a/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java
+++ b/guava-tests/test/com/google/common/collect/MapMakerInternalMapTest.java
@@ -122,25 +122,6 @@ public class MapMakerInternalMapTest extends TestCase {
assertSame(map.valueStrength.defaultEquivalence(), map.valueEquivalence);
}
- public void testSetValueEquivalence() {
- Equivalence<Object> testEquivalence = new Equivalence<Object>() {
- @Override
- protected boolean doEquivalent(Object a, Object b) {
- return false;
- }
-
- @Override
- protected int doHash(Object t) {
- return 0;
- }
- };
-
- MapMakerInternalMap<Object, Object> map =
- makeMap(createMapMaker().valueEquivalence(testEquivalence));
- assertSame(testEquivalence, map.valueEquivalence);
- assertSame(map.keyStrength.defaultEquivalence(), map.keyEquivalence);
- }
-
public void testSetConcurrencyLevel() {
// round up to nearest power of two
@@ -246,13 +227,6 @@ public class MapMakerInternalMapTest extends TestCase {
assertSame(EntryFactory.WEAK, map.entryFactory);
}
- @SuppressWarnings("deprecation")
- public void testSetSoftKeys() {
- MapMakerInternalMap<Object, Object> map = makeMap(createMapMaker().softKeys());
- checkStrength(map, Strength.SOFT, Strength.STRONG);
- assertSame(EntryFactory.SOFT, map.entryFactory);
- }
-
public void testSetWeakValues() {
MapMakerInternalMap<Object, Object> map = makeMap(createMapMaker().weakValues());
checkStrength(map, Strength.STRONG, Strength.WEAK);
@@ -1104,7 +1078,7 @@ public class MapMakerInternalMapTest extends TestCase {
table.set(0, entry);
segment.count = 1;
assertTrue(segment.removeEntry(entry, hash, RemovalCause.COLLECTED));
- assertNotificationEnqueued(map, key, value, hash);
+ assertNotificationEnqueued(map, key, value);
assertTrue(map.removalNotificationQueue.isEmpty());
assertFalse(segment.evictionQueue.contains(entry));
assertFalse(segment.expirationQueue.contains(entry));
@@ -1204,7 +1178,7 @@ public class MapMakerInternalMapTest extends TestCase {
}
private static <K, V> void assertNotificationEnqueued(
- MapMakerInternalMap<K, V> map, K key, V value, int hash) {
+ MapMakerInternalMap<K, V> map, K key, V value) {
RemovalNotification<K, V> notification = map.removalNotificationQueue.poll();
assertSame(key, notification.getKey());
assertSame(value, notification.getValue());
@@ -1627,7 +1601,7 @@ public class MapMakerInternalMapTest extends TestCase {
/**
* Returns an iterable containing all combinations of maximumSize, expireAfterAccess/Write,
- * weak/softKeys and weak/softValues.
+ * weakKeys and weak/softValues.
*/
private static Iterable<MapMaker> allEntryTypeMakers() {
List<MapMaker> result = newArrayList(allKeyValueStrengthMakers());
@@ -1665,19 +1639,15 @@ public class MapMakerInternalMapTest extends TestCase {
}
/**
- * Returns an iterable containing all combinations weak/softKeys and weak/softValues.
+ * Returns an iterable containing all combinations weakKeys and weak/softValues.
*/
- @SuppressWarnings("deprecation")
private static Iterable<MapMaker> allKeyValueStrengthMakers() {
return ImmutableList.of(createMapMaker(),
createMapMaker().weakValues(),
createMapMaker().softValues(),
createMapMaker().weakKeys(),
createMapMaker().weakKeys().weakValues(),
- createMapMaker().weakKeys().softValues(),
- createMapMaker().softKeys(),
- createMapMaker().softKeys().weakValues(),
- createMapMaker().softKeys().softValues());
+ createMapMaker().weakKeys().softValues());
}
// listeners
@@ -1856,7 +1826,8 @@ public class MapMakerInternalMapTest extends TestCase {
}
@Override
- public ValueReference<K, V> copyFor(ReferenceQueue<V> queue, ReferenceEntry<K, V> entry) {
+ public ValueReference<K, V> copyFor(
+ ReferenceQueue<V> queue, V value, ReferenceEntry<K, V> entry) {
return new DummyValueReference<K, V>(value, entry);
}
diff --git a/guava-tests/test/com/google/common/collect/MapsCollectionTest.java b/guava-tests/test/com/google/common/collect/MapsCollectionTest.java
new file mode 100644
index 0000000..f921859
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/MapsCollectionTest.java
@@ -0,0 +1,639 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.common.collect;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.testing.Helpers.mapEntry;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.testing.Helpers;
+import com.google.common.collect.testing.MapTestSuiteBuilder;
+import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
+import com.google.common.collect.testing.SafeTreeMap;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.SortedMapTestSuiteBuilder;
+import com.google.common.collect.testing.TestMapGenerator;
+import com.google.common.collect.testing.TestStringMapGenerator;
+import com.google.common.collect.testing.TestStringSortedMapGenerator;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.BiMapRemoveTester;
+import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringBiMapGenerator;
+import com.google.common.collect.testing.testers.CollectionIteratorTester;
+import com.google.common.testing.SerializableTester;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+
+import javax.annotation.Nullable;
+
+/**
+ * Test suites for wrappers in {@code Maps}.
+ *
+ * @author Louis Wasserman
+ */
+public class MapsCollectionTest extends TestCase {
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTest(NavigableMapTestSuiteBuilder
+ .using(new TestStringSortedMapGenerator() {
+ @Override
+ protected SortedMap<String, String> create(Entry<String, String>[] entries) {
+ SafeTreeMap<String, String> map = new SafeTreeMap<String, String>();
+ putEntries(map, entries);
+ return Maps.unmodifiableNavigableMap(map);
+ }
+ })
+ .named("unmodifiableNavigableMap[SafeTreeMap]")
+ .withFeatures(CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_VALUES)
+ .createTestSuite());
+ suite.addTest(NavigableMapTestSuiteBuilder
+ .using(new TestStringSortedMapGenerator() {
+
+ @Override
+ protected SortedMap<String, String> create(Entry<String, String>[] entries) {
+ SafeTreeMap<String, String> map = new SafeTreeMap<String, String>();
+ putEntries(map, entries);
+ return SerializableTester.reserialize(Maps.unmodifiableNavigableMap(map));
+ }
+ })
+ .named("unmodifiableNavigableMap[SafeTreeMap], reserialized")
+ .withFeatures(CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_VALUES)
+ .createTestSuite());
+ suite.addTest(BiMapTestSuiteBuilder
+ .using(new TestStringBiMapGenerator() {
+ @Override
+ protected BiMap<String, String> create(Entry<String, String>[] entries) {
+ BiMap<String, String> bimap = HashBiMap.create(entries.length);
+ for (Entry<String, String> entry : entries) {
+ checkArgument(!bimap.containsKey(entry.getKey()));
+ bimap.put(entry.getKey(), entry.getValue());
+ }
+ return Maps.unmodifiableBiMap(bimap);
+ }
+ })
+ .named("unmodifiableBiMap[HashBiMap]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.REJECTS_DUPLICATES_AT_CREATION)
+ .createTestSuite());
+ suite.addTest(BiMapTestSuiteBuilder
+ .using(new TestStringBiMapGenerator() {
+ @Override
+ protected BiMap<String, String> create(Entry<String, String>[] entries) {
+ BiMap<String, String> bimap = HashBiMap.create(entries.length);
+ for (Entry<String, String> entry : entries) {
+ checkArgument(!bimap.containsKey(entry.getKey()));
+ bimap.put(entry.getKey(), entry.getValue());
+ }
+ return SerializableTester.reserialize(Maps.unmodifiableBiMap(bimap));
+ }
+ })
+ .named("unmodifiableBiMap[HashBiMap], reserialized")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.REJECTS_DUPLICATES_AT_CREATION)
+ .createTestSuite());
+ suite.addTest(MapTestSuiteBuilder
+ .using(new TestMapGenerator<String, Integer>() {
+ @Override
+ public SampleElements<Entry<String, Integer>> samples() {
+ return new SampleElements<Entry<String, Integer>>(
+ mapEntry("x", 1),
+ mapEntry("xxx", 3),
+ mapEntry("xx", 2),
+ mapEntry("xxxx", 4),
+ mapEntry("aaaaa", 5));
+ }
+
+ @Override
+ public Map<String, Integer> create(Object... elements) {
+ Set<String> set = Sets.newLinkedHashSet();
+ for (Object e : elements) {
+ Entry<?, ?> entry = (Entry<?, ?>) e;
+ checkNotNull(entry.getValue());
+ set.add((String) checkNotNull(entry.getKey()));
+ }
+ return Maps.asMap(set, new Function<String, Integer>() {
+ @Override
+ public Integer apply(String input) {
+ return input.length();
+ }
+ });
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Entry<String, Integer>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<String, Integer>> order(
+ List<Entry<String, Integer>> insertionOrder) {
+ return insertionOrder;
+ }
+
+ @Override
+ public String[] createKeyArray(int length) {
+ return new String[length];
+ }
+
+ @Override
+ public Integer[] createValueArray(int length) {
+ return new Integer[length];
+ }
+ })
+ .named("Maps.asMap[Set, Function]")
+ .withFeatures(CollectionSize.ANY,
+ MapFeature.SUPPORTS_REMOVE)
+ .createTestSuite());
+ suite.addTest(SortedMapTestSuiteBuilder
+ .using(new TestMapGenerator<String, Integer>() {
+ @Override
+ public String[] createKeyArray(int length) {
+ return new String[length];
+ }
+
+ @Override
+ public Integer[] createValueArray(int length) {
+ return new Integer[length];
+ }
+
+ @Override
+ public SampleElements<Entry<String, Integer>> samples() {
+ return new SampleElements<Entry<String, Integer>>(
+ mapEntry("a", 1),
+ mapEntry("aa", 2),
+ mapEntry("aba", 3),
+ mapEntry("bbbb", 4),
+ mapEntry("ccccc", 5));
+ }
+
+ @Override
+ public SortedMap<String, Integer> create(Object... elements) {
+ SortedSet<String> set = new NonNavigableSortedSet();
+ for (Object e : elements) {
+ Entry<?, ?> entry = (Entry<?, ?>) e;
+ checkNotNull(entry.getValue());
+ set.add((String) checkNotNull(entry.getKey()));
+ }
+ return Maps.asMap(set, new Function<String, Integer>() {
+ @Override
+ public Integer apply(String input) {
+ return input.length();
+ }
+ });
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Entry<String, Integer>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<String, Integer>> order(
+ List<Entry<String, Integer>> insertionOrder) {
+ Collections.sort(insertionOrder, new Comparator<Entry<String, Integer>>() {
+ @Override
+ public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
+ return o1.getKey().compareTo(o2.getKey());
+ }
+ });
+ return insertionOrder;
+ }
+ })
+ .named("Maps.asMap[SortedSet, Function]")
+ .withFeatures(CollectionSize.ANY,
+ MapFeature.SUPPORTS_REMOVE)
+ .createTestSuite());
+ suite.addTest(NavigableMapTestSuiteBuilder
+ .using(new TestMapGenerator<String, Integer>() {
+ @Override
+ public String[] createKeyArray(int length) {
+ return new String[length];
+ }
+
+ @Override
+ public Integer[] createValueArray(int length) {
+ return new Integer[length];
+ }
+
+ @Override
+ public SampleElements<Entry<String, Integer>> samples() {
+ return new SampleElements<Entry<String, Integer>>(
+ mapEntry("a", 1),
+ mapEntry("aa", 2),
+ mapEntry("aba", 3),
+ mapEntry("bbbb", 4),
+ mapEntry("ccccc", 5));
+ }
+
+ @Override
+ public NavigableMap<String, Integer> create(Object... elements) {
+ NavigableSet<String> set = Sets.newTreeSet(Ordering.natural());
+ for (Object e : elements) {
+ Map.Entry<?, ?> entry = (Entry<?, ?>) e;
+ checkNotNull(entry.getValue());
+ set.add((String) checkNotNull(entry.getKey()));
+ }
+ return Maps.asMap(set, new Function<String, Integer>() {
+ @Override
+ public Integer apply(String input) {
+ return input.length();
+ }
+ });
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Entry<String, Integer>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<String, Integer>> order(
+ List<Entry<String, Integer>> insertionOrder) {
+ Collections.sort(insertionOrder, new Comparator<Entry<String, Integer>>() {
+ @Override
+ public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
+ return o1.getKey().compareTo(o2.getKey());
+ }
+ });
+ return insertionOrder;
+ }
+ })
+ .named("Maps.asMap[NavigableSet, Function]")
+ .withFeatures(CollectionSize.ANY,
+ MapFeature.SUPPORTS_REMOVE)
+ .createTestSuite());
+ suite.addTest(filterSuite());
+ return suite;
+ }
+
+ static TestSuite filterSuite() {
+ TestSuite suite = new TestSuite("Filter");
+ suite.addTest(filterMapSuite());
+ suite.addTest(filterBiMapSuite());
+ suite.addTest(filterSortedMapSuite());
+ suite.addTest(filterNavigableMapSuite());
+ return suite;
+ }
+
+ static TestSuite filterMapSuite() {
+ TestSuite suite = new TestSuite("FilterMap");
+ suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
+ @Override
+ protected Map<String, String> create(Entry<String, String>[] entries) {
+ Map<String, String> map = Maps.newHashMap();
+ putEntries(map, entries);
+ map.putAll(ENTRIES_TO_FILTER);
+ return Maps.filterKeys(map, FILTER_KEYS);
+ }
+ })
+ .named("Maps.filterKeys[Map, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
+ @Override
+ protected Map<String, String> create(Entry<String, String>[] entries) {
+ Map<String, String> map = Maps.newHashMap();
+ putEntries(map, entries);
+ map.putAll(ENTRIES_TO_FILTER);
+ return Maps.filterValues(map, FILTER_VALUES);
+ }
+ })
+ .named("Maps.filterValues[Map, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
+ @Override
+ protected Map<String, String> create(Entry<String, String>[] entries) {
+ Map<String, String> map = Maps.newHashMap();
+ putEntries(map, entries);
+ map.putAll(ENTRIES_TO_FILTER);
+ return Maps.filterEntries(map, FILTER_ENTRIES);
+ }
+ })
+ .named("Maps.filterEntries[Map, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
+ @Override
+ protected Map<String, String> create(Entry<String, String>[] entries) {
+ Map<String, String> map = Maps.newHashMap();
+ putEntries(map, entries);
+ map.putAll(ENTRIES_TO_FILTER);
+ map = Maps.filterEntries(map, FILTER_ENTRIES_1);
+ return Maps.filterEntries(map, FILTER_ENTRIES_2);
+ }
+ })
+ .named("Maps.filterEntries[Maps.filterEntries[Map, Predicate], Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ return suite;
+ }
+
+ static TestSuite filterBiMapSuite() {
+ TestSuite suite = new TestSuite("FilterBiMap");
+ suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() {
+ @Override
+ protected BiMap<String, String> create(Entry<String, String>[] entries) {
+ BiMap<String, String> map = HashBiMap.create();
+ putEntries(map, entries);
+ map.putAll(ENTRIES_TO_FILTER);
+ return Maps.filterKeys(map, FILTER_KEYS);
+ }
+ })
+ .named("Maps.filterKeys[BiMap, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ BiMapRemoveTester.getKeySetIteratorRemoveMethod())
+ .createTestSuite());
+ suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() {
+ @Override
+ protected BiMap<String, String> create(Entry<String, String>[] entries) {
+ BiMap<String, String> map = HashBiMap.create();
+ putEntries(map, entries);
+ map.putAll(ENTRIES_TO_FILTER);
+ return Maps.filterValues(map, FILTER_VALUES);
+ }
+ })
+ .named("Maps.filterValues[BiMap, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ BiMapRemoveTester.getKeySetIteratorRemoveMethod())
+ .createTestSuite());
+ suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() {
+ @Override
+ protected BiMap<String, String> create(Entry<String, String>[] entries) {
+ BiMap<String, String> map = HashBiMap.create();
+ putEntries(map, entries);
+ map.putAll(ENTRIES_TO_FILTER);
+ return Maps.filterEntries(map, FILTER_ENTRIES);
+ }
+ })
+ .named("Maps.filterEntries[BiMap, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ BiMapRemoveTester.getKeySetIteratorRemoveMethod())
+ .createTestSuite());
+ return suite;
+ }
+
+ static TestSuite filterSortedMapSuite() {
+ TestSuite suite = new TestSuite("FilterSortedMap");
+ suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ @Override
+ protected SortedMap<String, String> create(Entry<String, String>[] entries) {
+ SortedMap<String, String> map = new NonNavigableSortedMap();
+ putEntries(map, entries);
+ map.putAll(ENTRIES_TO_FILTER);
+ return Maps.filterKeys(map, FILTER_KEYS);
+ }
+ })
+ .named("Maps.filterKeys[SortedMap, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ @Override
+ protected SortedMap<String, String> create(Entry<String, String>[] entries) {
+ SortedMap<String, String> map = new NonNavigableSortedMap();
+ putEntries(map, entries);
+ map.putAll(ENTRIES_TO_FILTER);
+ return Maps.filterValues(map, FILTER_VALUES);
+ }
+ })
+ .named("Maps.filterValues[SortedMap, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ @Override
+ protected SortedMap<String, String> create(Entry<String, String>[] entries) {
+ SortedMap<String, String> map = new NonNavigableSortedMap();
+ putEntries(map, entries);
+ map.putAll(ENTRIES_TO_FILTER);
+ return Maps.filterEntries(map, FILTER_ENTRIES);
+ }
+ })
+ .named("Maps.filterEntries[SortedMap, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ return suite;
+ }
+
+ static TestSuite filterNavigableMapSuite() {
+ TestSuite suite = new TestSuite("FilterNavigableMap");
+ suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ @Override
+ protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
+ NavigableMap<String, String> map = new SafeTreeMap<String, String>();
+ putEntries(map, entries);
+ map.put("banana", "toast");
+ map.put("eggplant", "spam");
+ return Maps.filterKeys(map, FILTER_KEYS);
+ }
+ })
+ .named("Maps.filterKeys[NavigableMap, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ @Override
+ protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
+ NavigableMap<String, String> map = new SafeTreeMap<String, String>();
+ putEntries(map, entries);
+ map.put("banana", "toast");
+ map.put("eggplant", "spam");
+ return Maps.filterValues(map, FILTER_VALUES);
+ }
+ })
+ .named("Maps.filterValues[NavigableMap, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ @Override
+ protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
+ NavigableMap<String, String> map = new SafeTreeMap<String, String>();
+ putEntries(map, entries);
+ map.put("banana", "toast");
+ map.put("eggplant", "spam");
+ return Maps.filterEntries(map, FILTER_ENTRIES);
+ }
+ })
+ .named("Maps.filterEntries[NavigableMap, Predicate]")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ CollectionSize.ANY)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ return suite;
+ }
+
+ static void putEntries(Map<String, String> map, Entry<String, String>[] entries) {
+ for (Entry<String, String> entry : entries) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ static final Predicate<String> FILTER_KEYS = new Predicate<String>() {
+ @Override
+ public boolean apply(@Nullable String string) {
+ return !"banana".equals(string) && !"eggplant".equals(string);
+ }
+ };
+
+ static final Predicate<String> FILTER_VALUES = new Predicate<String>() {
+ @Override
+ public boolean apply(@Nullable String string) {
+ return !"toast".equals(string) && !"spam".equals(string);
+ }
+ };
+
+ static final Predicate<Entry<String, String>> FILTER_ENTRIES =
+ new Predicate<Entry<String, String>>() {
+ @Override
+ public boolean apply(Entry<String, String> entry) {
+ return !Helpers.mapEntry("banana", "toast").equals(entry)
+ && !Helpers.mapEntry("eggplant", "spam").equals(entry);
+ }
+ };
+
+ static final Predicate<Entry<String, String>> FILTER_ENTRIES_1 =
+ new Predicate<Entry<String, String>>() {
+ @Override
+ public boolean apply(Entry<String, String> entry) {
+ return !Helpers.mapEntry("banana", "toast").equals(entry);
+ }
+ };
+
+ static final Predicate<Entry<String, String>> FILTER_ENTRIES_2 =
+ new Predicate<Entry<String, String>>() {
+ @Override
+ public boolean apply(Entry<String, String> entry) {
+ return !Helpers.mapEntry("eggplant", "spam").equals(entry);
+ }
+ };
+
+ static final Map<String, String> ENTRIES_TO_FILTER =
+ ImmutableMap.of("banana", "toast", "eggplant", "spam");
+
+ static final Predicate<Entry<String, String>> NOT_NULL_ENTRY =
+ new Predicate<Entry<String, String>>() {
+ @Override
+ public boolean apply(Entry<String, String> entry) {
+ return entry.getKey() != null && entry.getValue() != null;
+ }
+ };
+
+ private static class NonNavigableSortedSet
+ extends ForwardingSortedSet<String> {
+
+ private final SortedSet<String> delegate = Sets.newTreeSet(Ordering.natural());
+
+ @Override
+ protected SortedSet<String> delegate() {
+ return delegate;
+ }
+ }
+
+ private static class NonNavigableSortedMap
+ extends ForwardingSortedMap<String, String> {
+
+ private final SortedMap<String, String> delegate =
+ new SafeTreeMap<String, String>(Ordering.natural());
+
+ @Override
+ protected SortedMap<String, String> delegate() {
+ return delegate;
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/MapsSortedTransformValuesTest.java b/guava-tests/test/com/google/common/collect/MapsSortedTransformValuesTest.java
index 34768ea..01a3f13 100644
--- a/guava-tests/test/com/google/common/collect/MapsSortedTransformValuesTest.java
+++ b/guava-tests/test/com/google/common/collect/MapsSortedTransformValuesTest.java
@@ -16,13 +16,13 @@
package com.google.common.collect;
-import java.util.Map;
-import java.util.SortedMap;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Function;
import com.google.common.base.Functions;
+import java.util.Map;
+import java.util.SortedMap;
+
/**
* Tests for {@link Maps#transformValues(SortedMap, Function)}.
*
diff --git a/guava-tests/test/com/google/common/collect/MapsTest.java b/guava-tests/test/com/google/common/collect/MapsTest.java
index 823afa7..c893953 100644
--- a/guava-tests/test/com/google/common/collect/MapsTest.java
+++ b/guava-tests/test/com/google/common/collect/MapsTest.java
@@ -17,13 +17,15 @@
package com.google.common.collect;
import static com.google.common.collect.Maps.transformEntries;
-import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static com.google.common.collect.Maps.transformValues;
+import static com.google.common.collect.Maps.unmodifiableNavigableMap;
+import static com.google.common.collect.testing.Helpers.mapEntry;
+import static java.util.Arrays.asList;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Equivalence;
-import com.google.common.base.Equivalences;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Predicate;
@@ -31,21 +33,16 @@ import com.google.common.base.Predicates;
import com.google.common.collect.Maps.EntryTransformer;
import com.google.common.collect.Maps.ValueDifferenceImpl;
import com.google.common.collect.SetsTest.Derived;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
-import com.google.common.collect.testing.SortedMapInterfaceTest;
-import com.google.common.collect.testing.TestStringMapGenerator;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.MapFeature;
import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
-import junit.framework.Test;
import junit.framework.TestCase;
-import junit.framework.TestSuite;
import java.io.IOException;
+import java.io.StringReader;
import java.lang.reflect.Field;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
@@ -57,9 +54,12 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
import java.util.Properties;
import java.util.Set;
import java.util.SortedMap;
+import java.util.SortedSet;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentMap;
@@ -231,9 +231,9 @@ public class MapsTest extends TestCase {
assertEquals(Collections.emptyMap(), map);
map.put(new Derived("foo"), 1);
map.put(new Derived("bar"), 2);
- ASSERT.that(map.keySet()).hasContentsInOrder(
- new Derived("bar"), new Derived("foo"));
- ASSERT.that(map.values()).hasContentsInOrder(2, 1);
+ ASSERT.that(map.keySet()).has().allOf(
+ new Derived("bar"), new Derived("foo")).inOrder();
+ ASSERT.that(map.values()).has().allOf(2, 1).inOrder();
assertNull(map.comparator());
}
@@ -242,9 +242,9 @@ public class MapsTest extends TestCase {
assertEquals(Collections.emptyMap(), map);
map.put(new LegacyComparable("foo"), 1);
map.put(new LegacyComparable("bar"), 2);
- ASSERT.that(map.keySet()).hasContentsInOrder(
- new LegacyComparable("bar"), new LegacyComparable("foo"));
- ASSERT.that(map.values()).hasContentsInOrder(2, 1);
+ ASSERT.that(map.keySet()).has().allOf(
+ new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
+ ASSERT.that(map.values()).has().allOf(2, 1).inOrder();
assertNull(map.comparator());
}
@@ -310,24 +310,26 @@ public class MapsTest extends TestCase {
} catch (IllegalArgumentException expected) {}
}
+ public void testToStringImplWithNullKeys() throws Exception {
+ Map<String, String> hashmap = Maps.newHashMap();
+ hashmap.put("foo", "bar");
+ hashmap.put(null, "baz");
+
+ assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
+ }
+
+ public void testToStringImplWithNullValues() throws Exception {
+ Map<String, String> hashmap = Maps.newHashMap();
+ hashmap.put("foo", "bar");
+ hashmap.put("baz", null);
+
+ assertEquals(hashmap.toString(), Maps.toStringImpl(hashmap));
+ }
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(BiMap.class, ImmutableBiMap.of());
- tester.setDefault(EntryTransformer.class, ALWAYS_NULL);
- tester.setDefault(Equivalence.class, Equivalences.equals());
- tester.setDefault(SortedMap.class, Maps.newTreeMap());
- tester.ignore(Maps.class.getDeclaredMethod("uniqueIndex", Object.class, Function.class));
- tester.testAllPublicStaticMethods(Maps.class);
- }
-
- private static final EntryTransformer<Object, Object, Object> ALWAYS_NULL =
- new EntryTransformer<Object, Object, Object>() {
- @Override
- public Object transformEntry(Object k, Object v1) {
- return null;
- }
- };
+ public void testNullPointerExceptions() {
+ new NullPointerTester().testAllPublicStaticMethods(Maps.class);
+ }
private static final Map<Integer, Integer> EMPTY
= Collections.emptyMap();
@@ -422,7 +424,7 @@ public class MapsTest extends TestCase {
// TODO(kevinb): replace with Ascii.caseInsensitiveEquivalence() when it
// exists
- Equivalence<String> caseInsensitiveEquivalence = Equivalences.equals().onResultOf(
+ Equivalence<String> caseInsensitiveEquivalence = Equivalence.equals().onResultOf(
new Function<String, String>() {
@Override public String apply(String input) {
return input.toLowerCase();
@@ -511,26 +513,26 @@ public class MapsTest extends TestCase {
SortedMapDifference<Integer, String> diff1 =
Maps.difference(left, right);
assertFalse(diff1.areEqual());
- ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).hasContentsInOrder(
- Maps.immutableEntry(4, "d"), Maps.immutableEntry(2, "b"));
- ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).hasContentsInOrder(
+ ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has().allOf(
+ Maps.immutableEntry(4, "d"), Maps.immutableEntry(2, "b")).inOrder();
+ ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item(
Maps.immutableEntry(6, "z"));
- ASSERT.that(diff1.entriesInCommon().entrySet()).hasContentsInOrder(
+ ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(
Maps.immutableEntry(1, "a"));
- ASSERT.that(diff1.entriesDiffering().entrySet()).hasContentsInOrder(
+ ASSERT.that(diff1.entriesDiffering().entrySet()).has().allOf(
Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g")),
- Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f")));
+ Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f"))).inOrder();
assertEquals("not equal: only on left={4=d, 2=b}: only on right={6=z}: "
+ "value differences={5=(e, g), 3=(c, f)}", diff1.toString());
SortedMapDifference<Integer, String> diff2 =
Maps.difference(right, left);
assertFalse(diff2.areEqual());
- ASSERT.that(diff2.entriesOnlyOnLeft().entrySet()).hasContentsInOrder(
+ ASSERT.that(diff2.entriesOnlyOnLeft().entrySet()).has().item(
Maps.immutableEntry(6, "z"));
- ASSERT.that(diff2.entriesOnlyOnRight().entrySet()).hasContentsInOrder(
- Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d"));
- ASSERT.that(diff1.entriesInCommon().entrySet()).hasContentsInOrder(
+ ASSERT.that(diff2.entriesOnlyOnRight().entrySet()).has().allOf(
+ Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
+ ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(
Maps.immutableEntry(1, "a"));
assertEquals(ImmutableMap.of(
3, ValueDifferenceImpl.create("f", "c"),
@@ -550,15 +552,15 @@ public class MapsTest extends TestCase {
Maps.difference(left, right);
left.put(6, "z");
assertFalse(diff1.areEqual());
- ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).hasContentsInOrder(
- Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d"));
- ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).hasContentsInOrder(
+ ASSERT.that(diff1.entriesOnlyOnLeft().entrySet()).has().allOf(
+ Maps.immutableEntry(2, "b"), Maps.immutableEntry(4, "d")).inOrder();
+ ASSERT.that(diff1.entriesOnlyOnRight().entrySet()).has().item(
Maps.immutableEntry(6, "z"));
- ASSERT.that(diff1.entriesInCommon().entrySet()).hasContentsInOrder(
+ ASSERT.that(diff1.entriesInCommon().entrySet()).has().item(
Maps.immutableEntry(1, "a"));
- ASSERT.that(diff1.entriesDiffering().entrySet()).hasContentsInOrder(
+ ASSERT.that(diff1.entriesDiffering().entrySet()).has().allOf(
Maps.immutableEntry(3, ValueDifferenceImpl.create("c", "f")),
- Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g")));
+ Maps.immutableEntry(5, ValueDifferenceImpl.create("e", "g"))).inOrder();
try {
diff1.entriesInCommon().put(7, "x");
fail();
@@ -599,6 +601,364 @@ public class MapsTest extends TestCase {
.testEquals();
}
+ private static final Function<String, Integer> LENGTH_FUNCTION =
+ new Function<String, Integer>() {
+ @Override
+ public Integer apply(String input) {
+ return input.length();
+ }
+ };
+
+ public void testAsMap() {
+ Set<String> strings = ImmutableSet.of("one", "two", "three");
+ Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
+ assertEquals(Integer.valueOf(5), map.get("three"));
+ assertNull(map.get("five"));
+ ASSERT.that(map.entrySet()).has().allOf(
+ mapEntry("one", 3),
+ mapEntry("two", 3),
+ mapEntry("three", 5)).inOrder();
+ }
+
+ public void testAsMapReadsThrough() {
+ Set<String> strings = Sets.newLinkedHashSet();
+ Collections.addAll(strings, "one", "two", "three");
+ Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
+ assertNull(map.get("four"));
+ strings.add("four");
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5, "four", 4), map);
+ assertEquals(Integer.valueOf(4), map.get("four"));
+ }
+
+ public void testAsMapWritesThrough() {
+ Set<String> strings = Sets.newLinkedHashSet();
+ Collections.addAll(strings, "one", "two", "three");
+ Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
+ assertEquals(Integer.valueOf(3), map.remove("two"));
+ ASSERT.that(strings).has().allOf("one", "three").inOrder();
+ }
+
+ public void testAsMapEmpty() {
+ Set<String> strings = ImmutableSet.of();
+ Map<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ ASSERT.that(map.entrySet()).isEmpty();
+ assertTrue(map.isEmpty());
+ assertNull(map.get("five"));
+ }
+
+ private static class NonNavigableSortedSet
+ extends ForwardingSortedSet<String> {
+ private final SortedSet<String> delegate = Sets.newTreeSet();
+
+ @Override
+ protected SortedSet<String> delegate() {
+ return delegate;
+ }
+ }
+
+ public void testAsMapReturnsSortedMapForSortedSetInput() {
+ Set<String> set = new NonNavigableSortedSet();
+ assertTrue(Maps.asMap(set, Functions.identity()) instanceof SortedMap);
+ }
+
+ public void testAsMapSorted() {
+ SortedSet<String> strings = new NonNavigableSortedSet();
+ Collections.addAll(strings, "one", "two", "three");
+ SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
+ assertEquals(Integer.valueOf(5), map.get("three"));
+ assertNull(map.get("five"));
+ ASSERT.that(map.entrySet()).has().allOf(
+ mapEntry("one", 3),
+ mapEntry("three", 5),
+ mapEntry("two", 3)).inOrder();
+ ASSERT.that(map.tailMap("onea").entrySet()).has().allOf(
+ mapEntry("three", 5),
+ mapEntry("two", 3)).inOrder();
+ ASSERT.that(map.subMap("one", "two").entrySet()).has().allOf(
+ mapEntry("one", 3),
+ mapEntry("three", 5)).inOrder();
+ }
+
+ public void testAsMapSortedReadsThrough() {
+ SortedSet<String> strings = new NonNavigableSortedSet();
+ Collections.addAll(strings, "one", "two", "three");
+ SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ assertNull(map.comparator());
+ assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
+ assertNull(map.get("four"));
+ strings.add("four");
+ assertEquals(
+ ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4),
+ map);
+ assertEquals(Integer.valueOf(4), map.get("four"));
+ SortedMap<String, Integer> headMap = map.headMap("two");
+ assertEquals(
+ ImmutableSortedMap.of("four", 4, "one", 3, "three", 5),
+ headMap);
+ strings.add("five");
+ strings.remove("one");
+ assertEquals(
+ ImmutableSortedMap.of("five", 4, "four", 4, "three", 5),
+ headMap);
+ ASSERT.that(map.entrySet()).has().allOf(
+ mapEntry("five", 4),
+ mapEntry("four", 4),
+ mapEntry("three", 5),
+ mapEntry("two", 3)).inOrder();
+ }
+
+ public void testAsMapSortedWritesThrough() {
+ SortedSet<String> strings = new NonNavigableSortedSet();
+ Collections.addAll(strings, "one", "two", "three");
+ SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
+ assertEquals(Integer.valueOf(3), map.remove("two"));
+ ASSERT.that(strings).has().allOf("one", "three").inOrder();
+ }
+
+ public void testAsMapSortedSubViewKeySetsDoNotSupportAdd() {
+ SortedMap<String, Integer> map = Maps.asMap(
+ new NonNavigableSortedSet(), LENGTH_FUNCTION);
+ try {
+ map.subMap("a", "z").keySet().add("a");
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ map.tailMap("a").keySet().add("a");
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ map.headMap("r").keySet().add("a");
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ map.headMap("r").tailMap("m").keySet().add("a");
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ public void testAsMapSortedEmpty() {
+ SortedSet<String> strings = new NonNavigableSortedSet();
+ SortedMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ ASSERT.that(map.entrySet()).isEmpty();
+ assertTrue(map.isEmpty());
+ assertNull(map.get("five"));
+ }
+
+ @GwtIncompatible("NavigableMap")
+ public void testAsMapReturnsNavigableMapForNavigableSetInput() {
+ Set<String> set = Sets.newTreeSet();
+ assertTrue(Maps.asMap(set, Functions.identity()) instanceof NavigableMap);
+ }
+
+ @GwtIncompatible("NavigableMap")
+ public void testAsMapNavigable() {
+ NavigableSet<String> strings =
+ Sets.newTreeSet(asList("one", "two", "three"));
+ NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
+ assertEquals(Integer.valueOf(5), map.get("three"));
+ assertNull(map.get("five"));
+ ASSERT.that(map.entrySet()).has().allOf(
+ mapEntry("one", 3),
+ mapEntry("three", 5),
+ mapEntry("two", 3)).inOrder();
+ ASSERT.that(map.tailMap("onea").entrySet()).has().allOf(
+ mapEntry("three", 5),
+ mapEntry("two", 3)).inOrder();
+ ASSERT.that(map.subMap("one", "two").entrySet()).has().allOf(
+ mapEntry("one", 3),
+ mapEntry("three", 5)).inOrder();
+
+ assertEquals(ImmutableSortedMap.of("two", 3, "three", 5),
+ map.tailMap("three", true));
+ assertEquals(ImmutableSortedMap.of("one", 3, "three", 5),
+ map.headMap("two", false));
+ assertEquals(ImmutableSortedMap.of("three", 5),
+ map.subMap("one", false, "tr", true));
+
+ assertEquals("three", map.higherKey("one"));
+ assertEquals("three", map.higherKey("r"));
+ assertEquals("three", map.ceilingKey("r"));
+ assertEquals("one", map.ceilingKey("one"));
+ assertEquals(mapEntry("three", 5), map.higherEntry("one"));
+ assertEquals(mapEntry("one", 3), map.ceilingEntry("one"));
+ assertEquals("one", map.lowerKey("three"));
+ assertEquals("one", map.lowerKey("r"));
+ assertEquals("one", map.floorKey("r"));
+ assertEquals("three", map.floorKey("three"));
+
+ ASSERT.that(map.descendingMap().entrySet()).has().allOf(
+ mapEntry("two", 3),
+ mapEntry("three", 5),
+ mapEntry("one", 3)).inOrder();
+ assertEquals(map.headMap("three", true),
+ map.descendingMap().tailMap("three", true));
+ ASSERT.that(map.tailMap("three", false).entrySet()).has().item(
+ mapEntry("two", 3));
+ assertNull(map.tailMap("three", true).lowerEntry("three"));
+ ASSERT.that(map.headMap("two", false).values()).has().allOf(3, 5).inOrder();
+ ASSERT.that(map.headMap("two", false).descendingMap().values())
+ .has().allOf(5, 3).inOrder();
+ ASSERT.that(map.descendingKeySet()).has().allOf(
+ "two", "three", "one").inOrder();
+
+ assertEquals(mapEntry("one", 3), map.pollFirstEntry());
+ assertEquals(mapEntry("two", 3), map.pollLastEntry());
+ assertEquals(1, map.size());
+ }
+
+ @GwtIncompatible("NavigableMap")
+ public void testAsMapNavigableReadsThrough() {
+ NavigableSet<String> strings = Sets.newTreeSet();
+ Collections.addAll(strings, "one", "two", "three");
+ NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ assertNull(map.comparator());
+ assertEquals(ImmutableSortedMap.of("one", 3, "two", 3, "three", 5), map);
+ assertNull(map.get("four"));
+ strings.add("four");
+ assertEquals(
+ ImmutableSortedMap.of("one", 3, "two", 3, "three", 5, "four", 4),
+ map);
+ assertEquals(Integer.valueOf(4), map.get("four"));
+ SortedMap<String, Integer> headMap = map.headMap("two");
+ assertEquals(
+ ImmutableSortedMap.of("four", 4, "one", 3, "three", 5),
+ headMap);
+ strings.add("five");
+ strings.remove("one");
+ assertEquals(
+ ImmutableSortedMap.of("five", 4, "four", 4, "three", 5),
+ headMap);
+ ASSERT.that(map.entrySet()).has().allOf(
+ mapEntry("five", 4),
+ mapEntry("four", 4),
+ mapEntry("three", 5),
+ mapEntry("two", 3)).inOrder();
+
+ NavigableMap<String, Integer> tailMap = map.tailMap("s", true);
+ NavigableMap<String, Integer> subMap = map.subMap("a", true, "t", false);
+
+ strings.add("six");
+ strings.remove("two");
+ ASSERT.that(tailMap.entrySet()).has().allOf(
+ mapEntry("six", 3),
+ mapEntry("three", 5)).inOrder();
+ ASSERT.that(subMap.entrySet()).has().allOf(
+ mapEntry("five", 4),
+ mapEntry("four", 4),
+ mapEntry("six", 3)).inOrder();
+ }
+
+ @GwtIncompatible("NavigableMap")
+ public void testAsMapNavigableWritesThrough() {
+ NavigableSet<String> strings = Sets.newTreeSet();
+ Collections.addAll(strings, "one", "two", "three");
+ NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
+ assertEquals(Integer.valueOf(3), map.remove("two"));
+ ASSERT.that(strings).has().allOf("one", "three").inOrder();
+ assertEquals(mapEntry("three", 5),
+ map.subMap("one", false, "zzz", true).pollLastEntry());
+ ASSERT.that(strings).has().item("one");
+ }
+
+ @GwtIncompatible("NavigableMap")
+ public void testAsMapNavigableSubViewKeySetsDoNotSupportAdd() {
+ NavigableMap<String, Integer> map = Maps.asMap(
+ Sets.<String>newTreeSet(), LENGTH_FUNCTION);
+ try {
+ map.descendingKeySet().add("a");
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ map.subMap("a", true, "z", false).keySet().add("a");
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ map.tailMap("a", true).keySet().add("a");
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ map.headMap("r", true).keySet().add("a");
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ map.headMap("r", false).tailMap("m", true).keySet().add("a");
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ @GwtIncompatible("NavigableMap")
+ public void testAsMapNavigableEmpty() {
+ NavigableSet<String> strings = ImmutableSortedSet.of();
+ NavigableMap<String, Integer> map = Maps.asMap(strings, LENGTH_FUNCTION);
+ ASSERT.that(map.entrySet()).isEmpty();
+ assertTrue(map.isEmpty());
+ assertNull(map.get("five"));
+ }
+
+ public void testToMap() {
+ Iterable<String> strings = ImmutableList.of("one", "two", "three");
+ ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
+ ASSERT.that(map.entrySet()).has().allOf(
+ mapEntry("one", 3),
+ mapEntry("two", 3),
+ mapEntry("three", 5)).inOrder();
+ }
+
+ public void testToMapIterator() {
+ Iterator<String> strings = ImmutableList.of("one", "two", "three").iterator();
+ ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
+ ASSERT.that(map.entrySet()).has().allOf(
+ mapEntry("one", 3),
+ mapEntry("two", 3),
+ mapEntry("three", 5)).inOrder();
+ }
+
+ public void testToMapWithDuplicateKeys() {
+ Iterable<String> strings = ImmutableList.of("one", "two", "three", "two", "one");
+ ImmutableMap<String, Integer> map = Maps.toMap(strings, LENGTH_FUNCTION);
+ assertEquals(ImmutableMap.of("one", 3, "two", 3, "three", 5), map);
+ ASSERT.that(map.entrySet()).has().allOf(
+ mapEntry("one", 3),
+ mapEntry("two", 3),
+ mapEntry("three", 5)).inOrder();
+ }
+
+ public void testToMapWithNullKeys() {
+ Iterable<String> strings = Arrays.asList("one", null, "three");
+ try {
+ Maps.toMap(strings, Functions.constant("foo"));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ public void testToMapWithNullValues() {
+ Iterable<String> strings = ImmutableList.of("one", "two", "three");
+ try {
+ Maps.toMap(strings, Functions.constant(null));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
private static final BiMap<Integer, String> INT_TO_STRING_MAP =
new ImmutableBiMap.Builder<Integer, String>()
.put(1, "one")
@@ -625,29 +985,6 @@ public class MapsTest extends TestCase {
assertEquals(INT_TO_STRING_MAP, outputMap);
}
- // NOTE: evil, never do this
- private abstract static class IterableIterator<T>
- extends ForwardingIterator<T> implements Iterable<T> {
- @Override
- public Iterator<T> iterator() {
- return this;
- }
- }
-
- @SuppressWarnings("deprecation") // that is the purpose of this test
- public void testUniqueIndexIterableIterator() {
- ImmutableMap<Integer, String> outputMap =
- Maps.uniqueIndex(new IterableIterator<String>() {
- private final Iterator<String> iterator = INT_TO_STRING_MAP.values().iterator();
-
- public Iterator<String> delegate() {
- return iterator;
- }
- },
- Functions.forMap(INT_TO_STRING_MAP.inverse()));
- assertEquals(INT_TO_STRING_MAP, outputMap);
- }
-
public void testUniqueIndexIterator() {
ImmutableMap<Integer, String> outputMap =
Maps.uniqueIndex(INT_TO_STRING_MAP.values().iterator(),
@@ -706,8 +1043,7 @@ public class MapsTest extends TestCase {
// Now test values loaded from a stream.
String props = "test\n second = 2\n Third item : a short phrase ";
- // TODO: change to StringReader in Java 1.6
- testProp.load(new java.io.StringBufferInputStream(props));
+ testProp.load(new StringReader(props));
result = Maps.fromProperties(testProp);
assertEquals(4, result.size());
@@ -725,8 +1061,7 @@ public class MapsTest extends TestCase {
testProp = new Properties(System.getProperties());
String override = "test\njava.version : hidden";
- // TODO: change to StringReader in Java 1.6
- testProp.load(new java.io.StringBufferInputStream(override));
+ testProp.load(new StringReader(override));
result = Maps.fromProperties(testProp);
assertTrue(result.size() > 2);
@@ -792,7 +1127,7 @@ public class MapsTest extends TestCase {
}
@SuppressWarnings("unchecked")
@Override public boolean equals(Object o) {
- if (o instanceof Map.Entry<?, ?>) {
+ if (o instanceof Map.Entry) {
Map.Entry<K, V> e = (Map.Entry<K, V>) o;
e.setValue(value); // muhahaha!
}
@@ -866,18 +1201,6 @@ public class MapsTest extends TestCase {
} catch (UnsupportedOperationException expected) {}
}
- public void testBiMapEntrySetIteratorRemove() {
- BiMap<Integer, String> map = HashBiMap.create();
- map.put(1, "one");
- Set<Map.Entry<Integer, String>> entries = map.entrySet();
- Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
- Map.Entry<Integer, String> entry = iterator.next();
- entry.setValue("two"); // changes the iterator's current entry value
- assertEquals("two", map.get(1));
- iterator.remove(); // removes the updated entry
- assertTrue(map.isEmpty());
- }
-
public void testImmutableEntry() {
Map.Entry<String, Integer> e = Maps.immutableEntry("foo", 1);
assertEquals("foo", e.getKey());
@@ -938,195 +1261,305 @@ public class MapsTest extends TestCase {
}
};
- public void testFilteredKeysIllegalPut() {
- Map<String, Integer> unfiltered = Maps.newHashMap();
- Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
- filtered.put("a", 1);
- filtered.put("b", 2);
- assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
+ private static final Function<Integer, Double> SQRT_FUNCTION = new Function<Integer, Double>() {
+ @Override
+ public Double apply(Integer in) {
+ return Math.sqrt(in);
+ }
+ };
- try {
- filtered.put("yyy", 3);
- fail();
- } catch (IllegalArgumentException expected) {}
+ public static class FilteredMapTest extends TestCase {
+ Map<String, Integer> createUnfiltered() {
+ return Maps.newHashMap();
+ }
- try {
- filtered.putAll(ImmutableMap.of("c", 3, "zzz", 4, "b", 5));
- fail();
- } catch (IllegalArgumentException expected) {}
+ public void testFilteredKeysIllegalPut() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
+ filtered.put("a", 1);
+ filtered.put("b", 2);
+ assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
- assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
- }
+ try {
+ filtered.put("yyy", 3);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
- public void testFilteredKeysChangeFiltered() {
- Map<String, Integer> unfiltered = Maps.newHashMap();
- Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
- unfiltered.put("two", 2);
- unfiltered.put("three", 3);
- unfiltered.put("four", 4);
- assertEquals(ImmutableMap.of("two", 2, "three", 3, "four", 4), unfiltered);
- assertEquals(ImmutableMap.of("three", 3, "four", 4), filtered);
+ public void testFilteredKeysIllegalPutAll() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
+ filtered.put("a", 1);
+ filtered.put("b", 2);
+ assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
- unfiltered.remove("three");
- assertEquals(ImmutableMap.of("two", 2, "four", 4), unfiltered);
- assertEquals(ImmutableMap.of("four", 4), filtered);
+ try {
+ filtered.putAll(ImmutableMap.of("c", 3, "zzz", 4, "b", 5));
+ fail();
+ } catch (IllegalArgumentException expected) {}
- unfiltered.clear();
- assertEquals(ImmutableMap.of(), unfiltered);
- assertEquals(ImmutableMap.of(), filtered);
- }
+ assertEquals(ImmutableMap.of("a", 1, "b", 2), filtered);
+ }
- public void testFilteredKeysChangeUnfiltered() {
- Map<String, Integer> unfiltered = Maps.newHashMap();
- Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
- unfiltered.put("two", 2);
- unfiltered.put("three", 3);
- unfiltered.put("four", 4);
- assertEquals(ImmutableMap.of("two", 2, "three", 3, "four", 4), unfiltered);
- assertEquals(ImmutableMap.of("three", 3, "four", 4), filtered);
+ public void testFilteredKeysFilteredReflectsBackingChanges() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ Map<String, Integer> filtered = Maps.filterKeys(unfiltered, NOT_LENGTH_3);
+ unfiltered.put("two", 2);
+ unfiltered.put("three", 3);
+ unfiltered.put("four", 4);
+ assertEquals(ImmutableMap.of("two", 2, "three", 3, "four", 4), unfiltered);
+ assertEquals(ImmutableMap.of("three", 3, "four", 4), filtered);
+
+ unfiltered.remove("three");
+ assertEquals(ImmutableMap.of("two", 2, "four", 4), unfiltered);
+ assertEquals(ImmutableMap.of("four", 4), filtered);
+
+ unfiltered.clear();
+ assertEquals(ImmutableMap.of(), unfiltered);
+ assertEquals(ImmutableMap.of(), filtered);
+ }
- filtered.remove("three");
- assertEquals(ImmutableMap.of("two", 2, "four", 4), unfiltered);
- assertEquals(ImmutableMap.of("four", 4), filtered);
+ public void testFilteredValuesIllegalPut() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
+ filtered.put("a", 2);
+ unfiltered.put("b", 4);
+ unfiltered.put("c", 5);
+ assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
- filtered.clear();
- assertEquals(ImmutableMap.of("two", 2), unfiltered);
- assertEquals(ImmutableMap.of(), filtered);
- }
+ try {
+ filtered.put("yyy", 3);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
+ }
- public void testFilteredValuesIllegalPut() {
- Map<String, Integer> unfiltered = Maps.newHashMap();
- Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
- filtered.put("a", 2);
- unfiltered.put("b", 4);
- unfiltered.put("c", 5);
- assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
+ public void testFilteredValuesIllegalPutAll() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
+ filtered.put("a", 2);
+ unfiltered.put("b", 4);
+ unfiltered.put("c", 5);
+ assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
- try {
- filtered.put("yyy", 3);
- fail();
- } catch (IllegalArgumentException expected) {}
+ try {
+ filtered.putAll(ImmutableMap.of("c", 4, "zzz", 5, "b", 6));
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
+ }
- try {
- filtered.putAll(ImmutableMap.of("c", 4, "zzz", 5, "b", 6));
- fail();
- } catch (IllegalArgumentException expected) {}
+ public void testFilteredValuesIllegalSetValue() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
+ filtered.put("a", 2);
+ filtered.put("b", 4);
+ assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
- assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
- }
+ Entry<String, Integer> entry = filtered.entrySet().iterator().next();
+ try {
+ entry.setValue(5);
+ fail();
+ } catch (IllegalArgumentException expected) {}
- public void testFilteredValuesIllegalSetValue() {
- Map<String, Integer> unfiltered = Maps.newHashMap();
- Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
- filtered.put("a", 2);
- filtered.put("b", 4);
- assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
+ assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
+ }
- Entry<String, Integer> entry = filtered.entrySet().iterator().next();
- try {
- entry.setValue(5);
- fail();
- } catch (IllegalArgumentException expected) {}
+ public void testFilteredValuesClear() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ unfiltered.put("one", 1);
+ unfiltered.put("two", 2);
+ unfiltered.put("three", 3);
+ unfiltered.put("four", 4);
+ Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
+ assertEquals(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4),
+ unfiltered);
+ assertEquals(ImmutableMap.of("two", 2, "four", 4), filtered);
+
+ filtered.clear();
+ assertEquals(ImmutableMap.of("one", 1, "three", 3), unfiltered);
+ assertTrue(filtered.isEmpty());
+ }
+
+ public void testFilteredEntriesIllegalPut() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ unfiltered.put("cat", 3);
+ unfiltered.put("dog", 2);
+ unfiltered.put("horse", 5);
+ Map<String, Integer> filtered
+ = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
+ assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
+
+ filtered.put("chicken", 7);
+ assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
+
+ try {
+ filtered.put("cow", 7);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
+ }
+
+ public void testFilteredEntriesIllegalPutAll() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ unfiltered.put("cat", 3);
+ unfiltered.put("dog", 2);
+ unfiltered.put("horse", 5);
+ Map<String, Integer> filtered
+ = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
+ assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
+
+ filtered.put("chicken", 7);
+ assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
+
+ try {
+ filtered.putAll(ImmutableMap.of("sheep", 5, "cow", 7));
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
+ }
- assertEquals(ImmutableMap.of("a", 2, "b", 4), filtered);
+ public void testFilteredEntriesObjectPredicate() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ unfiltered.put("cat", 3);
+ unfiltered.put("dog", 2);
+ unfiltered.put("horse", 5);
+ Predicate<Object> predicate = Predicates.alwaysFalse();
+ Map<String, Integer> filtered
+ = Maps.filterEntries(unfiltered, predicate);
+ assertTrue(filtered.isEmpty());
+ }
+
+ public void testFilteredEntriesWildCardEntryPredicate() {
+ Map<String, Integer> unfiltered = createUnfiltered();
+ unfiltered.put("cat", 3);
+ unfiltered.put("dog", 2);
+ unfiltered.put("horse", 5);
+ Predicate<Entry<?, ?>> predicate = new Predicate<Entry<?, ?>>() {
+ @Override
+ public boolean apply(Entry<?, ?> input) {
+ return "cat".equals(input.getKey())
+ || Integer.valueOf(2) == input.getValue();
+ }
+ };
+ Map<String, Integer> filtered
+ = Maps.filterEntries(unfiltered, predicate);
+ assertEquals(ImmutableMap.of("cat", 3, "dog", 2), filtered);
+ }
}
- public void testFilteredValuesClear() {
- Map<String, Integer> unfiltered = Maps.newHashMap();
- unfiltered.put("one", 1);
- unfiltered.put("two", 2);
- unfiltered.put("three", 3);
- unfiltered.put("four", 4);
- Map<String, Integer> filtered = Maps.filterValues(unfiltered, EVEN);
- assertEquals(ImmutableMap.of("one", 1, "two", 2, "three", 3, "four", 4),
- unfiltered);
- assertEquals(ImmutableMap.of("two", 2, "four", 4), filtered);
+ public static class FilteredSortedMapTest extends FilteredMapTest {
+ @Override
+ SortedMap<String, Integer> createUnfiltered() {
+ return Maps.newTreeMap();
+ }
- filtered.clear();
- assertEquals(ImmutableMap.of("one", 1, "three", 3), unfiltered);
- assertTrue(filtered.isEmpty());
+ public void testFilterKeysIdentifiesSortedMap() {
+ SortedMap<String, Integer> map = createUnfiltered();
+ assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3)
+ instanceof SortedMap);
+ }
+
+ public void testFilterValuesIdentifiesSortedMap() {
+ SortedMap<String, Integer> map = createUnfiltered();
+ assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN)
+ instanceof SortedMap);
+ }
+
+ public void testFilterEntriesIdentifiesSortedMap() {
+ SortedMap<String, Integer> map = createUnfiltered();
+ assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH)
+ instanceof SortedMap);
+ }
+
+ public void testFirstAndLastKeyFilteredMap() {
+ SortedMap<String, Integer> unfiltered = createUnfiltered();
+ unfiltered.put("apple", 2);
+ unfiltered.put("banana", 6);
+ unfiltered.put("cat", 3);
+ unfiltered.put("dog", 5);
+
+ SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
+ assertEquals("banana", filtered.firstKey());
+ assertEquals("cat", filtered.lastKey());
+ }
+
+ public void testHeadSubTailMap_FilteredMap() {
+ SortedMap<String, Integer> unfiltered = createUnfiltered();
+ unfiltered.put("apple", 2);
+ unfiltered.put("banana", 6);
+ unfiltered.put("cat", 4);
+ unfiltered.put("dog", 3);
+ SortedMap<String, Integer> filtered = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
+
+ assertEquals(ImmutableMap.of("banana", 6), filtered.headMap("dog"));
+ assertEquals(ImmutableMap.of(), filtered.headMap("banana"));
+ assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.headMap("emu"));
+
+ assertEquals(ImmutableMap.of("banana", 6), filtered.subMap("banana", "dog"));
+ assertEquals(ImmutableMap.of("dog", 3), filtered.subMap("cat", "emu"));
+
+ assertEquals(ImmutableMap.of("dog", 3), filtered.tailMap("cat"));
+ assertEquals(ImmutableMap.of("banana", 6, "dog", 3), filtered.tailMap("banana"));
+ }
}
- public void testFilteredEntriesIllegalPut() {
- Map<String, Integer> unfiltered = Maps.newHashMap();
- unfiltered.put("cat", 3);
- unfiltered.put("dog", 2);
- unfiltered.put("horse", 5);
- Map<String, Integer> filtered
- = Maps.filterEntries(unfiltered, CORRECT_LENGTH);
- assertEquals(ImmutableMap.of("cat", 3, "horse", 5), filtered);
+ public static class FilteredBiMapTest extends FilteredMapTest {
+ @Override
+ BiMap<String, Integer> createUnfiltered() {
+ return HashBiMap.create();
+ }
- filtered.put("chicken", 7);
- assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
+ public void testFilterKeysIdentifiesBiMap() {
+ BiMap<String, Integer> map = createUnfiltered();
+ assertTrue(Maps.filterKeys((Map<String, Integer>) map, NOT_LENGTH_3)
+ instanceof BiMap);
+ }
- try {
- filtered.put("cow", 7);
- fail();
- } catch (IllegalArgumentException expected) {}
- assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
+ public void testFilterValuesIdentifiesBiMap() {
+ BiMap<String, Integer> map = createUnfiltered();
+ assertTrue(Maps.filterValues((Map<String, Integer>) map, EVEN)
+ instanceof BiMap);
+ }
- try {
- filtered.putAll(ImmutableMap.of("sheep", 5, "cow", 7));
- fail();
- } catch (IllegalArgumentException expected) {}
- assertEquals(ImmutableMap.of("cat", 3, "horse", 5, "chicken", 7), filtered);
- }
-
- public void testFilteredEntriesObjectPredicate() {
- Map<String, Integer> unfiltered = Maps.newHashMap();
- unfiltered.put("cat", 3);
- unfiltered.put("dog", 2);
- unfiltered.put("horse", 5);
- Predicate<Object> predicate = Predicates.alwaysFalse();
- Map<String, Integer> filtered
- = Maps.filterEntries(unfiltered, predicate);
- assertTrue(filtered.isEmpty());
- }
-
- public void testFilteredEntriesWildCardEntryPredicate() {
- Map<String, Integer> unfiltered = Maps.newHashMap();
- unfiltered.put("cat", 3);
- unfiltered.put("dog", 2);
- unfiltered.put("horse", 5);
- Predicate<Entry<?, ?>> predicate = new Predicate<Entry<?, ?>>() {
- @Override
- public boolean apply(Entry<?, ?> input) {
- return "cat".equals(input.getKey())
- || Integer.valueOf(2) == input.getValue();
- }
- };
- Map<String, Integer> filtered
- = Maps.filterEntries(unfiltered, predicate);
- assertEquals(ImmutableMap.of("cat", 3, "dog", 2), filtered);
+ public void testFilterEntriesIdentifiesBiMap() {
+ BiMap<String, Integer> map = createUnfiltered();
+ assertTrue(Maps.filterEntries((Map<String, Integer>) map, CORRECT_LENGTH)
+ instanceof BiMap);
+ }
}
public void testTransformValues() {
Map<String, Integer> map = ImmutableMap.of("a", 4, "b", 9);
- Function<Integer, Double> sqrt = new Function<Integer, Double>() {
- @Override
- public Double apply(Integer in) {
- return Math.sqrt(in);
- }
- };
- Map<String, Double> transformed = Maps.transformValues(map, sqrt);
+ Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
}
public void testTransformValuesSecretlySorted() {
- Map<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
- Function<Integer, Double> sqrt = new Function<Integer, Double>() {
- @Override
- public Double apply(Integer in) {
- return Math.sqrt(in);
- }
- };
- Map<String, Double> transformed = Maps.transformValues(map, sqrt);
+ Map<String, Integer> map =
+ sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
+ Map<String, Double> transformed = transformValues(map, SQRT_FUNCTION);
assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
assertTrue(transformed instanceof SortedMap);
}
+ @GwtIncompatible("NavigableMap")
+ public void testTransformValuesSecretlyNavigable() {
+ Map<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
+ Map<String, Double> transformed;
+
+ transformed = transformValues(map, SQRT_FUNCTION);
+ assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
+ assertTrue(transformed instanceof NavigableMap);
+
+ transformed =
+ transformValues((SortedMap<String, Integer>) map, SQRT_FUNCTION);
+ assertEquals(ImmutableMap.of("a", 2.0, "b", 3.0), transformed);
+ assertTrue(transformed instanceof NavigableMap);
+ }
+
public void testTransformEntries() {
Map<String, String> map = ImmutableMap.of("a", "4", "b", "9");
EntryTransformer<String, String, String> concat =
@@ -1136,7 +1569,7 @@ public class MapsTest extends TestCase {
return key + value;
}
};
- Map<String, String> transformed = Maps.transformEntries(map, concat);
+ Map<String, String> transformed = transformEntries(map, concat);
assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
}
@@ -1150,12 +1583,33 @@ public class MapsTest extends TestCase {
return key + value;
}
};
- Map<String, String> transformed = Maps.transformEntries(map, concat);
+ Map<String, String> transformed = transformEntries(map, concat);
assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
assertTrue(transformed instanceof SortedMap);
}
+ @GwtIncompatible("NavigableMap")
+ public void testTransformEntriesSecretlyNavigable() {
+ Map<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
+ EntryTransformer<String, String, String> concat =
+ new EntryTransformer<String, String, String>() {
+ @Override
+ public String transformEntry(String key, String value) {
+ return key + value;
+ }
+ };
+ Map<String, String> transformed;
+
+ transformed = transformEntries(map, concat);
+ assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
+ assertTrue(transformed instanceof NavigableMap);
+
+ transformed = transformEntries((SortedMap<String, String>) map, concat);
+ assertEquals(ImmutableMap.of("a", "a4", "b", "b9"), transformed);
+ assertTrue(transformed instanceof NavigableMap);
+ }
+
public void testTransformEntriesGenerics() {
Map<Object, Object> map1 = ImmutableMap.<Object, Object>of(1, 2);
Map<Object, Number> map2 = ImmutableMap.<Object, Number>of(1, 2);
@@ -1222,169 +1676,45 @@ public class MapsTest extends TestCase {
return value ? key : "no" + key;
}
};
- Map<String, String> transformed =
- Maps.transformEntries(options, flagPrefixer);
+ Map<String, String> transformed = transformEntries(options, flagPrefixer);
assertEquals("{verbose=verbose, sort=nosort}", transformed.toString());
}
- // TestStringMapGenerator uses entries of the form "one=January" and so forth.
- // To test the filtered collections, we'll create a map containing the entries
- // they ask for, plus some bogus numeric entries. Then our predicates will
- // simply filter numeric entries back out.
-
- private static ImmutableMap<String, String> ENTRIES_TO_FILTER_OUT =
- new ImmutableMap.Builder<String, String>()
- .put("0", "0")
- .put("1", "1")
- .put("2", "2")
- .build();
-
- @GwtIncompatible("suite")
- public static class FilteredMapTests extends TestCase {
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTest(MapTestSuiteBuilder.using(
- new TestStringMapGenerator() {
- @Override protected Map<String, String> create(
- Entry<String, String>[] entries) {
- Map<String, String> map = Maps.newHashMap();
- for (Entry<String, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- map.putAll(ENTRIES_TO_FILTER_OUT);
- return Maps.filterKeys(map, new Predicate<String>() {
- @Override
- public boolean apply(String input) {
- return input == null
- || (input.charAt(0) >= 'a' && input.charAt(0) <= 'z');
- }
- });
- }
- })
- .named("Maps.filterKeys")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE)
- .suppressing(getIteratorUnknownOrderRemoveSupportedMethod())
- .createTestSuite());
-
- suite.addTest(MapTestSuiteBuilder.using(
- new TestStringMapGenerator() {
- @Override protected Map<String, String> create(
- Entry<String, String>[] entries) {
- Map<String, String> map = Maps.newHashMap();
- for (Entry<String, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- map.putAll(ENTRIES_TO_FILTER_OUT);
- return Maps.filterValues(map, new Predicate<String>() {
- @Override
- public boolean apply(String input) {
- return input == null
- || (input.charAt(0) >= 'A' && input.charAt(0) <= 'Z');
- }
- });
- }
- })
- .named("Maps.filterValues")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE)
- .suppressing(getIteratorUnknownOrderRemoveSupportedMethod())
- .createTestSuite());
-
- suite.addTest(MapTestSuiteBuilder.using(
- new TestStringMapGenerator() {
- @Override protected Map<String, String> create(
- Entry<String, String>[] entries) {
- Map<String, String> map = Maps.newHashMap();
- for (Entry<String, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- map.putAll(ENTRIES_TO_FILTER_OUT);
- return Maps.filterEntries(map,
- new Predicate<Entry<String, String>>() {
- @Override
- public boolean apply(Entry<String, String> entry) {
- String input = entry.getKey();
- return input == null
- || (input.charAt(0) >= 'a' && input.charAt(0) <= 'z');
- }
- });
- }
- })
- .named("Maps.filterEntries")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE)
- .suppressing(getIteratorUnknownOrderRemoveSupportedMethod())
- .createTestSuite());
-
- suite.addTest(MapTestSuiteBuilder.using(
- new TestStringMapGenerator() {
- @Override protected Map<String, String> create(
- Entry<String, String>[] entries) {
- Map<String, String> map = Maps.newHashMap();
- for (Entry<String, String> entry : entries) {
- map.put(entry.getKey(), entry.getValue());
- }
- map.putAll(ENTRIES_TO_FILTER_OUT);
- map.put("", "weird");
- Map<String, String> withoutEmptyKey = Maps.filterKeys(map,
- new Predicate<String>() {
- @Override
- public boolean apply(String input) {
- return input == null || input.length() != 0;
- }
- });
- return Maps.filterKeys(withoutEmptyKey, new Predicate<String>() {
- @Override
- public boolean apply(String input) {
- return input == null
- || (input.charAt(0) >= 'a' && input.charAt(0) <= 'z');
- }
- });
- // note: these filters were deliberately chosen so that an
- // element somehow getting around the first filter would cause
- // an exception in the second
- }
- })
- .named("Maps.filterKeys, chained")
- .withFeatures(
- CollectionSize.ANY,
- MapFeature.ALLOWS_NULL_KEYS,
- MapFeature.ALLOWS_NULL_VALUES,
- MapFeature.GENERAL_PURPOSE)
- .suppressing(getIteratorUnknownOrderRemoveSupportedMethod())
- .createTestSuite());
-
- return suite;
- }
+ // Logically this would accept a NavigableMap, but that won't work under GWT.
+ private static <K, V> SortedMap<K, V> sortedNotNavigable(
+ final SortedMap<K, V> map) {
+ return new ForwardingSortedMap<K, V>() {
+ @Override protected SortedMap<K, V> delegate() {
+ return map;
+ }
+ };
}
public void testSortedMapTransformValues() {
- SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
- Function<Integer, Double> sqrt = new Function<Integer, Double>() {
- @Override
- public Double apply(Integer in) {
- return Math.sqrt(in);
- }
- };
+ SortedMap<String, Integer> map =
+ sortedNotNavigable(ImmutableSortedMap.of("a", 4, "b", 9));
SortedMap<String, Double> transformed =
- Maps.transformValues(map, sqrt);
+ transformValues(map, SQRT_FUNCTION);
+
+ /*
+ * We'd like to sanity check that we didn't get a NavigableMap out, but we
+ * can't easily do so while maintaining GWT compatibility.
+ */
+ assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
+ }
+
+ @GwtIncompatible("NavigableMap")
+ public void testNavigableMapTransformValues() {
+ NavigableMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
+ NavigableMap<String, Double> transformed =
+ transformValues(map, SQRT_FUNCTION);
assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
}
public void testSortedMapTransformEntries() {
- SortedMap<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
+ SortedMap<String, String> map =
+ sortedNotNavigable(ImmutableSortedMap.of("a", "4", "b", "9"));
EntryTransformer<String, String, String> concat =
new EntryTransformer<String, String, String>() {
@Override
@@ -1392,128 +1722,168 @@ public class MapsTest extends TestCase {
return key + value;
}
};
- SortedMap<String, String> transformed =
- Maps.transformEntries(map, concat);
+ SortedMap<String, String> transformed = transformEntries(map, concat);
+ /*
+ * We'd like to sanity check that we didn't get a NavigableMap out, but we
+ * can't easily do so while maintaining GWT compatibility.
+ */
assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
}
- /*
- * Not testing Map methods of Maps.filter*(SortedMap), since the
- * implementation doesn't override Maps.FilteredEntryMap, which is already
- * tested.
- */
-
- public void testSortedMapFilterKeys() {
- Comparator<Integer> comparator = Ordering.natural();
- SortedMap<Integer, String> unfiltered = Maps.newTreeMap(comparator);
- unfiltered.put(1, "one");
- unfiltered.put(2, "two");
- unfiltered.put(3, "three");
- unfiltered.put(4, "four");
- unfiltered.put(5, "five");
- unfiltered.put(6, "six");
- unfiltered.put(7, "seven");
- SortedMap<Integer, String> filtered
- = Maps.filterKeys(unfiltered, EVEN);
- ASSERT.that(filtered.keySet()).hasContentsInOrder(2, 4, 6);
- assertSame(comparator, filtered.comparator());
- assertEquals((Integer) 2, filtered.firstKey());
- assertEquals((Integer) 6, filtered.lastKey());
- ASSERT.that(filtered.headMap(5).keySet()).hasContentsInOrder(2, 4);
- ASSERT.that(filtered.tailMap(3).keySet()).hasContentsInOrder(4, 6);
- ASSERT.that(filtered.subMap(3, 5).keySet()).hasContentsInOrder(4);
- }
-
- public void testSortedMapFilterValues() {
- Comparator<Integer> comparator = Ordering.natural();
- SortedMap<Integer, String> unfiltered = Maps.newTreeMap(comparator);
- unfiltered.put(1, "one");
- unfiltered.put(2, "two");
- unfiltered.put(3, "three");
- unfiltered.put(4, "four");
- unfiltered.put(5, "five");
- unfiltered.put(6, "six");
- unfiltered.put(7, "seven");
- SortedMap<Integer, String> filtered
- = Maps.filterValues(unfiltered, NOT_LENGTH_3);
- ASSERT.that(filtered.keySet()).hasContentsInOrder(3, 4, 5, 7);
- assertSame(comparator, filtered.comparator());
- assertEquals((Integer) 3, filtered.firstKey());
- assertEquals((Integer) 7, filtered.lastKey());
- ASSERT.that(filtered.headMap(5).keySet()).hasContentsInOrder(3, 4);
- ASSERT.that(filtered.tailMap(4).keySet()).hasContentsInOrder(4, 5, 7);
- ASSERT.that(filtered.subMap(4, 6).keySet()).hasContentsInOrder(4, 5);
- }
-
- private static final Predicate<Map.Entry<Integer, String>>
- EVEN_AND_LENGTH_3 = new Predicate<Map.Entry<Integer, String>>() {
- @Override public boolean apply(Entry<Integer, String> entry) {
- return (entry.getKey() == null || entry.getKey() % 2 == 0)
- && (entry.getValue() == null || entry.getValue().length() == 3);
- }
- };
-
- private static class ContainsKeySafeSortedMap
- extends ForwardingSortedMap<Integer, String> {
- SortedMap<Integer, String> delegate
- = Maps.newTreeMap(Ordering.natural().nullsFirst());
-
- @Override protected SortedMap<Integer, String> delegate() {
- return delegate;
+ @GwtIncompatible("NavigableMap")
+ public void testNavigableMapTransformEntries() {
+ NavigableMap<String, String> map =
+ ImmutableSortedMap.of("a", "4", "b", "9");
+ EntryTransformer<String, String, String> concat =
+ new EntryTransformer<String, String, String>() {
+ @Override
+ public String transformEntry(String key, String value) {
+ return key + value;
+ }
+ };
+ NavigableMap<String, String> transformed = transformEntries(map, concat);
+
+ assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
+ }
+
+ @GwtIncompatible("NavigableMap")
+ public void testUnmodifiableNavigableMap() {
+ TreeMap<Integer, String> mod = Maps.newTreeMap();
+ mod.put(1, "one");
+ mod.put(2, "two");
+ mod.put(3, "three");
+
+ NavigableMap<Integer, String> unmod = unmodifiableNavigableMap(mod);
+
+ /* unmod is a view. */
+ mod.put(4, "four");
+ assertEquals("four", unmod.get(4));
+ assertEquals("four", unmod.descendingMap().get(4));
+
+ ensureNotDirectlyModifiable(unmod);
+ ensureNotDirectlyModifiable(unmod.descendingMap());
+ ensureNotDirectlyModifiable(unmod.headMap(2, true));
+ ensureNotDirectlyModifiable(unmod.subMap(1, true, 3, true));
+ ensureNotDirectlyModifiable(unmod.tailMap(2, true));
+
+ Collection<String> values = unmod.values();
+ try {
+ values.add("4");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
}
-
- // Needed by MapInterfaceTest.testContainsKey()
- @Override public boolean containsKey(Object key) {
- try {
- return super.containsKey(key);
- } catch (ClassCastException e) {
- return false;
- }
+ try {
+ values.remove("four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
}
- }
-
- public static class FilteredEntriesSortedMapInterfaceTest
- extends SortedMapInterfaceTest<Integer, String> {
- public FilteredEntriesSortedMapInterfaceTest() {
- super(true, true, true, true, true);
+ try {
+ values.removeAll(Collections.singleton("four"));
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
}
-
- @Override protected SortedMap<Integer, String> makeEmptyMap() {
- SortedMap<Integer, String> unfiltered = new ContainsKeySafeSortedMap();
- unfiltered.put(1, "one");
- unfiltered.put(3, "three");
- unfiltered.put(4, "four");
- unfiltered.put(5, "five");
- return Maps.filterEntries(unfiltered, EVEN_AND_LENGTH_3);
+ try {
+ values.retainAll(Collections.singleton("four"));
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
}
-
- @Override protected SortedMap<Integer, String> makePopulatedMap() {
- SortedMap<Integer, String> unfiltered = new ContainsKeySafeSortedMap();
- unfiltered.put(1, "one");
- unfiltered.put(2, "two");
- unfiltered.put(3, "three");
- unfiltered.put(4, "four");
- unfiltered.put(5, "five");
- unfiltered.put(6, "six");
- return Maps.filterEntries(unfiltered, EVEN_AND_LENGTH_3);
+ try {
+ Iterator<String> iterator = values.iterator();
+ iterator.next();
+ iterator.remove();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
}
- @Override protected Integer getKeyNotInPopulatedMap() {
- return 10;
+ Set<Map.Entry<Integer, String>> entries = unmod.entrySet();
+ try {
+ Iterator<Map.Entry<Integer, String>> iterator = entries.iterator();
+ iterator.next();
+ iterator.remove();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
}
+ Map.Entry<Integer, String> entry = entries.iterator().next();
+ try {
+ entry.setValue("four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ entry = unmod.lowerEntry(1);
+ assertNull(entry);
+ entry = unmod.floorEntry(2);
+ try {
+ entry.setValue("four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ entry = unmod.ceilingEntry(2);
+ try {
+ entry.setValue("four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ entry = unmod.lowerEntry(2);
+ try {
+ entry.setValue("four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ entry = unmod.higherEntry(2);
+ try {
+ entry.setValue("four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ entry = unmod.firstEntry();
+ try {
+ entry.setValue("four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ entry = unmod.lastEntry();
+ try {
+ entry.setValue("four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ @SuppressWarnings("unchecked")
+ Map.Entry<Integer, String> entry2 =
+ (Map.Entry<Integer, String>) entries.toArray()[0];
+ try {
+ entry2.setValue("four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
- @Override protected String getValueNotInPopulatedMap() {
- return "ten";
+ @GwtIncompatible("NavigableMap")
+ void ensureNotDirectlyModifiable(NavigableMap<Integer, String> unmod) {
+ try {
+ unmod.put(4, "four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ unmod.putAll(Collections.singletonMap(4, "four"));
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ unmod.remove("four");
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ unmod.pollFirstEntry();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ unmod.pollLastEntry();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
}
-
- // Iterators don't support remove.
- @Override public void testEntrySetIteratorRemove() {}
- @Override public void testValuesIteratorRemove() {}
-
- // These tests fail on GWT.
- // TODO: Investigate why.
- @Override public void testEntrySetRemoveAll() {}
- @Override public void testEntrySetRetainAll() {}
}
}
diff --git a/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java b/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java
index 549cb52..00679cc 100644
--- a/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java
+++ b/guava-tests/test/com/google/common/collect/MapsTransformValuesTest.java
@@ -16,6 +16,11 @@
package com.google.common.collect;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.collect.testing.MapInterfaceTest;
+
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
@@ -23,11 +28,6 @@ import java.util.Set;
import javax.annotation.Nullable;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.collect.testing.MapInterfaceTest;
-
/**
* Tests for {@link Maps#transformValues}.
*
diff --git a/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java b/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java
index 8cc8559..48ebea3 100644
--- a/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java
+++ b/guava-tests/test/com/google/common/collect/MinMaxPriorityQueueTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.collect.testing.IteratorFeature;
import com.google.common.collect.testing.IteratorTester;
@@ -26,6 +26,7 @@ import junit.framework.TestCase;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
@@ -354,7 +355,7 @@ public class MinMaxPriorityQueueTest extends TestCase {
}
}
assertTrue(q.isIntact());
- ASSERT.that(result).hasContentsAnyOrder(1, 15, 13, 8, 14);
+ ASSERT.that(result).has().allOf(1, 15, 13, 8, 14);
}
/**
@@ -561,6 +562,18 @@ public class MinMaxPriorityQueueTest extends TestCase {
}
}
+ public void testRemoveAt_exhaustive() {
+ int size = 8;
+ List<Integer> expected = createOrderedList(size);
+ for (Collection<Integer> perm : Collections2.permutations(expected)) {
+ for (int i = 0; i < perm.size(); i++) {
+ MinMaxPriorityQueue<Integer> q = MinMaxPriorityQueue.create(perm);
+ q.removeAt(i);
+ assertTrue("Remove at " + i + " perm " + perm, q.isIntact());
+ }
+ }
+ }
+
/**
* Regression test for bug found.
*/
@@ -677,6 +690,26 @@ public class MinMaxPriorityQueueTest extends TestCase {
assertTrue(q.isEmpty());
}
+ public void testExhaustive_pollAndPush() {
+ int size = 8;
+ List<Integer> expected = createOrderedList(size);
+ for (Collection<Integer> perm : Collections2.permutations(expected)) {
+ MinMaxPriorityQueue<Integer> q = MinMaxPriorityQueue.create(perm);
+ List<Integer> elements = Lists.newArrayListWithCapacity(size);
+ while (!q.isEmpty()) {
+ Integer next = q.pollFirst();
+ for (int i = 0; i <= size; i++) {
+ assertTrue(q.add(i));
+ assertTrue(q.add(next));
+ assertTrue(q.remove(i));
+ assertEquals(next, q.poll());
+ }
+ elements.add(next);
+ }
+ assertEquals("Started with " + perm, expected, elements);
+ }
+ }
+
/**
* Regression test for b/4124577
*/
@@ -687,23 +720,23 @@ public class MinMaxPriorityQueueTest extends TestCase {
List<Integer> contents = Lists.newArrayList(expected);
List<Integer> elements = Lists.newArrayListWithCapacity(size);
while (!q.isEmpty()) {
- ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
+ ASSERT.that(q).has().allFrom(contents);
Integer next = q.pollFirst();
contents.remove(next);
- ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
+ ASSERT.that(q).has().allFrom(contents);
for (int i = 0; i <= size; i++) {
q.add(i);
contents.add(i);
- ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
+ ASSERT.that(q).has().allFrom(contents);
q.add(next);
contents.add(next);
- ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
+ ASSERT.that(q).has().allFrom(contents);
q.remove(i);
assertTrue(contents.remove(Integer.valueOf(i)));
- ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
+ ASSERT.that(q).has().allFrom(contents);
assertEquals(next, q.poll());
contents.remove(next);
- ASSERT.that(q).hasContentsAnyOrder(contents.toArray(new Integer[0]));
+ ASSERT.that(q).has().allFrom(contents);
}
elements.add(next);
}
@@ -786,7 +819,7 @@ public class MinMaxPriorityQueueTest extends TestCase {
}
}
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicConstructors(MinMaxPriorityQueue.class);
tester.testAllPublicStaticMethods(MinMaxPriorityQueue.class);
diff --git a/guava-tests/test/com/google/common/collect/MultimapCollectionTest.java b/guava-tests/test/com/google/common/collect/MultimapCollectionTest.java
deleted file mode 100644
index 886dfd1..0000000
--- a/guava-tests/test/com/google/common/collect/MultimapCollectionTest.java
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static com.google.common.collect.Maps.newHashMap;
-import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
-import static com.google.common.collect.testing.features.CollectionFeature.REMOVE_OPERATIONS;
-import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods;
-import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods;
-import static com.google.common.collect.testing.google.MultisetReadsTester.getReadsDuplicateInitializingMethods;
-import static java.lang.reflect.Proxy.newProxyInstance;
-
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Functions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
-import com.google.common.collect.testing.CollectionTestSuiteBuilder;
-import com.google.common.collect.testing.ListTestSuiteBuilder;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestCollectionGenerator;
-import com.google.common.collect.testing.TestListGenerator;
-import com.google.common.collect.testing.TestStringCollectionGenerator;
-import com.google.common.collect.testing.TestStringListGenerator;
-import com.google.common.collect.testing.TestStringSetGenerator;
-import com.google.common.collect.testing.TestStringSortedSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.Feature;
-import com.google.common.collect.testing.features.ListFeature;
-import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
-import com.google.common.collect.testing.google.MultisetWritesTester;
-import com.google.common.collect.testing.google.TestStringMultisetGenerator;
-import com.google.common.collect.testing.testers.CollectionIteratorTester;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- * Run collection tests on {@link Multimap} implementations.
- *
- * @author Jared Levy
- */
-@GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version
-public class MultimapCollectionTest extends TestCase {
-
- private static final Feature<?>[] COLLECTION_FEATURES = {
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.GENERAL_PURPOSE
- };
-
- static final Feature<?>[] COLLECTION_FEATURES_ORDER = {
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE
- };
- static final Feature<?>[] COLLECTION_FEATURES_REMOVE = {
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.REMOVE_OPERATIONS
- };
-
- static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = {
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.REMOVE_OPERATIONS
- };
-
- private static final Feature<?>[] LIST_FEATURES = {
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- ListFeature.GENERAL_PURPOSE
- };
-
- private static final Feature<?>[] LIST_FEATURES_REMOVE_SET = {
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- ListFeature.REMOVE_OPERATIONS,
- ListFeature.SUPPORTS_SET
- };
-
- private static final Feature<?>[] FOR_MAP_FEATURES_ONE = {
- CollectionSize.ONE,
- ALLOWS_NULL_VALUES,
- REMOVE_OPERATIONS,
- };
-
- private static final Feature<?>[] FOR_MAP_FEATURES_ANY = {
- CollectionSize.ANY,
- ALLOWS_NULL_VALUES,
- REMOVE_OPERATIONS,
- };
-
- static final Supplier<TreeSet<String>> STRING_TREESET_FACTORY
- = new Supplier<TreeSet<String>>() {
- @Override
- public TreeSet<String> get() {
- return new TreeSet<String>(Ordering.natural().nullsLast());
- }
- };
-
- static void populateMultimapForGet(
- Multimap<Integer, String> multimap, String[] elements) {
- multimap.put(2, "foo");
- for (String element : elements) {
- multimap.put(3, element);
- }
- }
-
- static void populateMultimapForKeySet(
- Multimap<String, Integer> multimap, String[] elements) {
- for (String element : elements) {
- multimap.put(element, 2);
- multimap.put(element, 3);
- }
- }
-
- static void populateMultimapForValues(
- Multimap<Integer, String> multimap, String[] elements) {
- for (int i = 0; i < elements.length; i++) {
- multimap.put(i % 2, elements[i]);
- }
- }
-
- static void populateMultimapForKeys(
- Multimap<String, Integer> multimap, String[] elements) {
- for (int i = 0; i < elements.length; i++) {
- multimap.put(elements[i], i);
- }
- }
-
- /**
- * Implements {@code Multimap.put()} -- and no other methods -- for a {@code
- * Map} by ignoring all but the latest value for each key. This class exists
- * only so that we can use
- * {@link MultimapCollectionTest#populateMultimapForGet(Multimap, String[])}
- * and similar methods to populate a map to be passed to
- * {@link Multimaps#forMap(Map)}. All tests should run against the result of
- * {@link #build()}.
- */
- private static final class PopulatableMapAsMultimap<K, V>
- extends ForwardingMultimap<K, V> {
- final Map<K, V> map;
- final SetMultimap<K, V> unusableDelegate;
-
- static <K, V> PopulatableMapAsMultimap<K, V> create() {
- return new PopulatableMapAsMultimap<K, V>();
- }
-
- @SuppressWarnings("unchecked") // all methods throw immediately
- PopulatableMapAsMultimap() {
- this.map = newHashMap();
- this.unusableDelegate = (SetMultimap<K, V>) newProxyInstance(
- SetMultimap.class.getClassLoader(),
- new Class<?>[] {SetMultimap.class},
- new InvocationHandler() {
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- throw new UnsupportedOperationException();
- }
- });
- }
-
- @Override protected Multimap<K, V> delegate() {
- return unusableDelegate;
- }
-
- @Override public boolean put(K key, V value) {
- map.put(key, value);
- return true;
- }
-
- SetMultimap<K, V> build() {
- return Multimaps.forMap(map);
- }
- }
-
- static abstract class TestEntriesGenerator
- implements TestCollectionGenerator<Entry<String, Integer>> {
- @Override
- public SampleElements<Entry<String, Integer>> samples() {
- return new SampleElements<Entry<String, Integer>>(
- Maps.immutableEntry("bar", 1),
- Maps.immutableEntry("bar", 2),
- Maps.immutableEntry("foo", 3),
- Maps.immutableEntry("bar", 3),
- Maps.immutableEntry("cat", 2));
- }
-
- @Override
- public Collection<Entry<String, Integer>> create(Object... elements) {
- Multimap<String, Integer> multimap = createMultimap();
- for (Object element : elements) {
- @SuppressWarnings("unchecked")
- Entry<String, Integer> entry = (Entry<String, Integer>) element;
- multimap.put(entry.getKey(), entry.getValue());
- }
- return multimap.entries();
- }
-
- abstract Multimap<String, Integer> createMultimap();
-
- @Override
- @SuppressWarnings("unchecked")
- public Entry<String, Integer>[] createArray(int length) {
- return (Entry<String, Integer>[]) new Entry<?, ?>[length];
- }
-
- @Override
- public List<Entry<String, Integer>> order(
- List<Entry<String, Integer>> insertionOrder) {
- return insertionOrder;
- }
- }
-
- public static abstract class TestEntriesListGenerator
- extends TestEntriesGenerator
- implements TestListGenerator<Entry<String, Integer>> {
- @Override public List<Entry<String, Integer>> create(Object... elements) {
- return (List<Entry<String, Integer>>) super.create(elements);
- }
- }
-
- private static abstract class TestEntrySetGenerator
- extends TestEntriesGenerator {
- @Override abstract SetMultimap<String, Integer> createMultimap();
-
- @Override public Set<Entry<String, Integer>> create(Object... elements) {
- return (Set<Entry<String, Integer>>) super.create(elements);
- }
- }
-
- private static final Predicate<Map.Entry<Integer, String>> FILTER_GET_PREDICATE
- = new Predicate<Map.Entry<Integer, String>>() {
- @Override public boolean apply(Entry<Integer, String> entry) {
- return !"badvalue".equals(entry.getValue()) && 55556 != entry.getKey();
- }
- };
-
- private static final Predicate<Map.Entry<String, Integer>> FILTER_KEYSET_PREDICATE
- = new Predicate<Map.Entry<String, Integer>>() {
- @Override public boolean apply(Entry<String, Integer> entry) {
- return !"badkey".equals(entry.getKey()) && 55556 != entry.getValue();
- }
- };
-
- public static Test suite() {
- TestSuite suite = new TestSuite();
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- SetMultimap<Integer, String> multimap = HashMultimap.create();
- populateMultimapForGet(multimap, elements);
- return multimap.get(3);
- }
- })
- .named("HashMultimap.get")
- .withFeatures(COLLECTION_FEATURES)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- SetMultimap<Integer, String> multimap
- = LinkedHashMultimap.create();
- populateMultimapForGet(multimap, elements);
- return multimap.get(3);
- }
- })
- .named("LinkedHashMultimap.get")
- .withFeatures(COLLECTION_FEATURES_ORDER)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new TestStringSortedSetGenerator() {
- @Override protected SortedSet<String> create(String[] elements) {
- SortedSetMultimap<Integer, String> multimap =
- TreeMultimap.create(Ordering.natural().nullsFirst(),
- Ordering.natural().nullsLast());
- populateMultimapForGet(multimap, elements);
- return multimap.get(3);
- }
- })
- .named("TreeMultimap.get")
- .withFeatures(COLLECTION_FEATURES_ORDER)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
- @Override protected List<String> create(String[] elements) {
- ListMultimap<Integer, String> multimap
- = ArrayListMultimap.create();
- populateMultimapForGet(multimap, elements);
- return multimap.get(3);
- }
- })
- .named("ArrayListMultimap.get")
- .withFeatures(LIST_FEATURES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
- @Override protected List<String> create(String[] elements) {
- ListMultimap<Integer, String> multimap
- = Multimaps.synchronizedListMultimap(
- ArrayListMultimap.<Integer, String>create());
- populateMultimapForGet(multimap, elements);
- return multimap.get(3);
- }
- })
- .named("synchronized ArrayListMultimap.get")
- .withFeatures(LIST_FEATURES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
- @Override protected List<String> create(String[] elements) {
- ListMultimap<Integer, String> multimap
- = LinkedListMultimap.create();
- populateMultimapForGet(multimap, elements);
- return multimap.get(3);
- }
- })
- .named("LinkedListMultimap.get")
- .withFeatures(LIST_FEATURES)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
- @Override protected List<String> create(String[] elements) {
- ImmutableListMultimap.Builder<Integer, String> builder
- = ImmutableListMultimap.builder();
- ListMultimap<Integer, String> multimap
- = builder.put(2, "foo")
- .putAll(3, elements)
- .build();
- return multimap.get(3);
- }
- })
- .named("ImmutableListMultimap.get")
- .withFeatures(CollectionSize.ANY)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- PopulatableMapAsMultimap<Integer, String> multimap
- = PopulatableMapAsMultimap.create();
- populateMultimapForGet(multimap, elements);
- return multimap.build().get(3);
- }
- })
- .named("Multimaps.forMap.get")
- .withFeatures(FOR_MAP_FEATURES_ONE)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- SetMultimap<Integer, String> multimap
- = LinkedHashMultimap.create();
- populateMultimapForGet(multimap, elements);
- multimap.put(3, "badvalue");
- multimap.put(55556, "foo");
- return (Set<String>) Multimaps.filterEntries(multimap, FILTER_GET_PREDICATE).get(3);
- }
- })
- .named("Multimaps.filterEntries.get")
- .withFeatures(COLLECTION_FEATURES_ORDER)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- Multimap<String, Integer> multimap = HashMultimap.create();
- populateMultimapForKeySet(multimap, elements);
- return multimap.keySet();
- }
- })
- .named("HashMultimap.keySet")
- .withFeatures(COLLECTION_FEATURES_REMOVE)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- Multimap<String, Integer> multimap
- = LinkedHashMultimap.create();
- populateMultimapForKeySet(multimap, elements);
- return multimap.keySet();
- }
- })
- .named("LinkedHashMultimap.keySet")
- .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new TestStringSortedSetGenerator() {
- @Override protected SortedSet<String> create(String[] elements) {
- TreeMultimap<String, Integer> multimap =
- TreeMultimap.create(Ordering.natural().nullsFirst(),
- Ordering.natural().nullsLast());
- populateMultimapForKeySet(multimap, elements);
- return multimap.keySet();
- }
- })
- .named("TreeMultimap.keySet")
- .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- Multimap<String, Integer> multimap
- = ArrayListMultimap.create();
- populateMultimapForKeySet(multimap, elements);
- return multimap.keySet();
- }
- })
- .named("ArrayListMultimap.keySet")
- .withFeatures(COLLECTION_FEATURES_REMOVE)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- Multimap<String, Integer> multimap
- = LinkedListMultimap.create();
- populateMultimapForKeySet(multimap, elements);
- return multimap.keySet();
- }
- })
- .named("LinkedListMultimap.keySet")
- .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- ImmutableListMultimap.Builder<String, Integer> builder
- = ImmutableListMultimap.builder();
- for (String element : elements) {
- builder.put(element, 2);
- builder.put(element, 3);
- }
- Multimap<String, Integer> multimap = builder.build();
- return multimap.keySet();
- }
- })
- .named("ImmutableListMultimap.keySet")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- PopulatableMapAsMultimap<String, Integer> multimap
- = PopulatableMapAsMultimap.create();
- populateMultimapForKeySet(multimap, elements);
- return multimap.build().keySet();
- }
- })
- .named("Multimaps.forMap.keySet")
- .withFeatures(FOR_MAP_FEATURES_ANY)
- .createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(
- new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- SetMultimap<String, Integer> multimap = LinkedHashMultimap.create();
- populateMultimapForKeySet(multimap, elements);
- multimap.put("badkey", 3);
- multimap.put("a", 55556);
- return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE).keySet();
- }
- })
- .named("Multimaps.filterEntries.keySet")
- .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestStringCollectionGenerator() {
- @Override public Collection<String> create(String[] elements) {
- Multimap<Integer, String> multimap = HashMultimap.create();
- populateMultimapForValues(multimap, elements);
- return multimap.values();
- }
- })
- .named("HashMultimap.values")
- .withFeatures(COLLECTION_FEATURES_REMOVE)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestStringCollectionGenerator() {
- @Override public Collection<String> create(String[] elements) {
- Multimap<Integer, String> multimap
- = LinkedHashMultimap.create();
- populateMultimapForValues(multimap, elements);
- return multimap.values();
- }
- })
- .named("LinkedHashMultimap.values")
- .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestStringCollectionGenerator() {
- @Override public Collection<String> create(String[] elements) {
- Multimap<Integer, String> multimap
- = TreeMultimap.create(Ordering.natural().nullsFirst(),
- Ordering.natural().nullsLast());
- populateMultimapForValues(multimap, elements);
- return multimap.values();
- }
- })
- .named("TreeMultimap.values")
- .withFeatures(COLLECTION_FEATURES_REMOVE)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestStringCollectionGenerator() {
- @Override public Collection<String> create(String[] elements) {
- Multimap<Integer, String> multimap
- = ArrayListMultimap.create();
- populateMultimapForValues(multimap, elements);
- return multimap.values();
- }
- })
- .named("ArrayListMultimap.values")
- .withFeatures(COLLECTION_FEATURES_REMOVE)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(
- new TestStringListGenerator() {
- @Override public List<String> create(String[] elements) {
- LinkedListMultimap<Integer, String> multimap
- = LinkedListMultimap.create();
- populateMultimapForValues(multimap, elements);
- return multimap.values();
- }
- })
- .named("LinkedListMultimap.values")
- .withFeatures(LIST_FEATURES_REMOVE_SET)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestStringCollectionGenerator() {
- @Override public Collection<String> create(String[] elements) {
- ImmutableListMultimap.Builder<Integer, String> builder
- = ImmutableListMultimap.builder();
- for (int i = 0; i < elements.length; i++) {
- builder.put(i % 2, elements[i]);
- }
- return builder.build().values();
- }
- })
- .named("ImmutableListMultimap.values")
- .withFeatures(CollectionSize.ANY)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestStringCollectionGenerator() {
- @Override public Collection<String> create(String[] elements) {
- Multimap<Integer, String> multimap
- = LinkedHashMultimap.create();
- populateMultimapForValues(multimap, elements);
- multimap.put(3, "badvalue");
- multimap.put(55556, "foo");
- return Multimaps.filterEntries(multimap, FILTER_GET_PREDICATE).values();
- }
- })
- .named("Multimaps.filterEntries.values")
- .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
-
- // TODO: use collection testers on Multimaps.forMap.values
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- Multimap<String, Integer> multimap = HashMultimap.create();
- populateMultimapForKeys(multimap, elements);
- return multimap.keys();
- }
- })
- .named("HashMultimap.keys")
- .withFeatures(COLLECTION_FEATURES_REMOVE)
- .createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- Multimap<String, Integer> multimap
- = LinkedHashMultimap.create();
- populateMultimapForKeys(multimap, elements);
- return multimap.keys();
- }
- })
- .named("LinkedHashMultimap.keys")
- .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
- .createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- Multimap<String, Integer> multimap
- = TreeMultimap.create(Ordering.natural().nullsFirst(),
- Ordering.natural().nullsLast());
- populateMultimapForKeys(multimap, elements);
- return multimap.keys();
- }
-
- @Override public List<String> order(List<String> insertionOrder) {
- Collections.sort(insertionOrder, Ordering.natural().nullsFirst());
- return insertionOrder;
- }
- })
- .named("TreeMultimap.keys")
- .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
- .createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- Multimap<String, Integer> multimap
- = ArrayListMultimap.create();
- populateMultimapForKeys(multimap, elements);
- return multimap.keys();
- }
- })
- .named("ArrayListMultimap.keys")
- .withFeatures(COLLECTION_FEATURES_REMOVE)
- .createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- Multimap<String, Integer> multimap
- = Multimaps.synchronizedListMultimap(
- ArrayListMultimap.<String, Integer>create());
- populateMultimapForKeys(multimap, elements);
- return multimap.keys();
- }
- })
- .named("synchronized ArrayListMultimap.keys")
- .withFeatures(COLLECTION_FEATURES_REMOVE)
- .createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- Multimap<String, Integer> multimap
- = LinkedListMultimap.create();
- populateMultimapForKeys(multimap, elements);
- return multimap.keys();
- }
- })
- .named("LinkedListMultimap.keys")
- .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
- .createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- ImmutableListMultimap.Builder<String, Integer> builder
- = ImmutableListMultimap.builder();
- for (int i = 0; i < elements.length; i++) {
- builder.put(elements[i], i);
- }
- Multimap<String, Integer> multimap = builder.build();
- return multimap.keys();
- }
- })
- .named("ImmutableListMultimap.keys")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- PopulatableMapAsMultimap<String, Integer> multimap
- = PopulatableMapAsMultimap.create();
- populateMultimapForKeys(multimap, elements);
- return multimap.build().keys();
- }
- })
- .named("Multimaps.forMap.keys")
- .withFeatures(FOR_MAP_FEATURES_ANY)
- .suppressing(getReadsDuplicateInitializingMethods())
- .suppressing(getSetCountDuplicateInitializingMethods())
- .suppressing(getIteratorDuplicateInitializingMethods())
- .createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- SetMultimap<String, Integer> multimap = LinkedHashMultimap.create();
- populateMultimapForKeys(multimap, elements);
- multimap.put("badkey", 3);
- multimap.put("a", 55556);
- return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE).keys();
- }
- })
- .named("Multimaps.filterEntries.keys")
- .withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .suppressing(MultisetWritesTester.getEntrySetIteratorMethod())
- .suppressing(getIteratorDuplicateInitializingMethods())
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestEntrySetGenerator() {
- @Override SetMultimap<String, Integer> createMultimap() {
- return HashMultimap.create();
- }
- })
- .named("HashMultimap.entries")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestEntrySetGenerator() {
- @Override SetMultimap<String, Integer> createMultimap() {
- return LinkedHashMultimap.create();
- }
- })
- .named("LinkedHashMultimap.entries")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
- CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestEntrySetGenerator() {
- @Override SetMultimap<String, Integer> createMultimap() {
- return TreeMultimap.create(Ordering.natural().nullsFirst(),
- Ordering.natural().nullsLast());
- }
- })
- .named("TreeMultimap.entries")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
- CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestEntriesGenerator() {
- @Override Multimap<String, Integer> createMultimap() {
- return ArrayListMultimap.create();
- }
- })
- .named("ArrayListMultimap.entries")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestEntriesGenerator() {
- @Override Multimap<String, Integer> createMultimap() {
- return Multimaps.synchronizedListMultimap(
- ArrayListMultimap.<String, Integer>create());
- }
- })
- .named("synchronized ArrayListMultimap.entries")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS)
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(
- new TestEntriesListGenerator() {
- @Override Multimap<String, Integer> createMultimap() {
- return LinkedListMultimap.create();
- }
- })
- .named("LinkedListMultimap.entries")
- .withFeatures(CollectionSize.ANY, ListFeature.REMOVE_OPERATIONS,
- CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestEntriesGenerator() {
- @Override Multimap<String, Integer> createMultimap() {
- return ImmutableListMultimap.of();
- }
-
- @Override public Collection<Entry<String, Integer>> create(
- Object... elements) {
- ImmutableListMultimap.Builder<String, Integer> builder
- = ImmutableListMultimap.builder();
- for (Object element : elements) {
- @SuppressWarnings("unchecked")
- Entry<String, Integer> entry = (Entry<String, Integer>) element;
- builder.put(entry.getKey(), entry.getValue());
- }
- return builder.build().entries();
- }
- })
- .named("ImmutableListMultimap.entries")
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER)
- .createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(
- new TestEntriesGenerator() {
- @Override Multimap<String, Integer> createMultimap() {
- Multimap<String, Integer> multimap = LinkedHashMultimap.create();
- multimap.put("badkey", 3);
- multimap.put("a", 55556);
- return Multimaps.filterEntries(multimap, FILTER_KEYSET_PREDICATE);
- }
- })
- .named("Multimap.filterEntries.entries")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
- CollectionFeature.KNOWN_ORDER)
- .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite());
-
- suite.addTest(ListTestSuiteBuilder.using(new TestStringListGenerator() {
- @Override protected List<String> create(String[] elements) {
- ListMultimap<Integer, String> multimap = ArrayListMultimap.create();
- populateMultimapForGet(multimap, elements);
- return Multimaps.transformValues(
- multimap, Functions.<String> identity()).get(3);
- }
- }).named("Multimaps.transformValues[ListMultimap].get").withFeatures(
- CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.REMOVE_OPERATIONS,
- ListFeature.SUPPORTS_REMOVE_WITH_INDEX).createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- ListMultimap<String, Integer> multimap = ArrayListMultimap.create();
- populateMultimapForKeySet(multimap, elements);
- return Multimaps.transformValues(
- multimap, Functions.<Integer> identity()).keySet();
- }
- }).named("Multimaps.transformValues[ListMultimap].keySet").withFeatures(
- CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.REMOVE_OPERATIONS).createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- ListMultimap<String, Integer> multimap
- = ArrayListMultimap.create();
- populateMultimapForKeys(multimap, elements);
- return Multimaps.transformValues(
- multimap, Functions.<Integer> identity()).keys();
- }
- })
- .named("Multimaps.transform[ListMultimap].keys")
- .withFeatures(COLLECTION_FEATURES_REMOVE)
- .createTestSuite());
-
- suite.addTest(
- CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() {
- @Override public Collection<String> create(String[] elements) {
- ListMultimap<Integer, String> multimap = ArrayListMultimap.create();
- populateMultimapForValues(multimap, elements);
- return Multimaps.transformValues(
- multimap, Functions.<String> identity()).values();
- }
- }).named("Multimaps.transformValues[ListMultimap].values").withFeatures(
- COLLECTION_FEATURES_REMOVE).createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(new TestEntriesGenerator() {
- @Override public Collection<Entry<String, Integer>> create(
- Object... elements) {
- ListMultimap<String, Integer> multimap = ArrayListMultimap.create();
- for (Object element : elements) {
- @SuppressWarnings("unchecked")
- Entry<String, Integer> entry = (Entry<String, Integer>) element;
- multimap.put(entry.getKey(), entry.getValue());
- }
- return Multimaps.transformValues(
- multimap, Functions.<Integer> identity()).entries();
- }
-
- @Override Multimap<String, Integer> createMultimap() {
- return Multimaps.transformValues(
- ArrayListMultimap.<String, Integer> create(),
- Functions.<Integer> identity());
- }
- }).named("Multimaps.transformValues[ListMultimap].entries")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS)
- .createTestSuite());
-
- suite.addTest(
- CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() {
- @Override protected Collection<String> create(String[] elements) {
- Multimap<Integer, String> multimap = ArrayListMultimap.create();
- populateMultimapForGet(multimap, elements);
- return Multimaps.transformValues(
- multimap, Functions.<String> identity()).get(3);
- }
- }).named("Multimaps.transformValues[Multimap].get").withFeatures(
- CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.REMOVE_OPERATIONS).createTestSuite());
-
- suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
- @Override protected Set<String> create(String[] elements) {
- Multimap<String, Integer> multimap = ArrayListMultimap.create();
- populateMultimapForKeySet(multimap, elements);
- return Multimaps.transformValues(
- multimap, Functions.<Integer> identity()).keySet();
- }
- }).named("Multimaps.transformValues[Multimap].keySet").withFeatures(
- COLLECTION_FEATURES_REMOVE).createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(
- new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- Multimap<String, Integer> multimap
- = ArrayListMultimap.create();
- populateMultimapForKeys(multimap, elements);
- return Multimaps.transformValues(
- multimap, Functions.<Integer> identity()).keys();
- }
- })
- .named("Multimaps.transformValues[Multimap].keys")
- .withFeatures(COLLECTION_FEATURES_REMOVE)
- .createTestSuite());
-
- suite.addTest(
- CollectionTestSuiteBuilder.using(new TestStringCollectionGenerator() {
- @Override public Collection<String> create(String[] elements) {
- Multimap<Integer, String> multimap = ArrayListMultimap.create();
- populateMultimapForValues(multimap, elements);
- return Multimaps.transformValues(
- multimap, Functions.<String> identity()).values();
- }
- }).named("Multimaps.transformValues[Multimap].values").withFeatures(
- COLLECTION_FEATURES_REMOVE).createTestSuite());
-
- suite.addTest(CollectionTestSuiteBuilder.using(new TestEntriesGenerator() {
- @Override public Collection<Entry<String, Integer>> create(
- Object... elements) {
- Multimap<String, Integer> multimap = ArrayListMultimap.create();
- for (Object element : elements) {
- @SuppressWarnings("unchecked")
- Entry<String, Integer> entry = (Entry<String, Integer>) element;
- multimap.put(entry.getKey(), entry.getValue());
- }
- return Multimaps.transformValues(
- multimap, Functions.<Integer> identity()).entries();
- }
- @Override Multimap<String, Integer> createMultimap() {
- return Multimaps.transformValues(
- (Multimap<String, Integer>)
- ArrayListMultimap.<String, Integer> create(),
- Functions.<Integer> identity());
- }
- }).named("Multimaps.transformValues[Multimap].entries")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS)
- .createTestSuite());
-
- // TODO: use collection testers on Multimaps.forMap.entries
-
- return suite;
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java b/guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java
new file mode 100644
index 0000000..48be857
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/MultimapsCollectionTest.java
@@ -0,0 +1,661 @@
+/*
+ * Copyright (C) 2008 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.Maps.newHashMap;
+import static com.google.common.collect.testing.Helpers.mapEntry;
+import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
+import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
+import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods;
+import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods;
+import static com.google.common.collect.testing.google.MultisetReadsTester.getReadsDuplicateInitializingMethods;
+import static java.lang.reflect.Proxy.newProxyInstance;
+
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Ascii;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Maps.EntryTransformer;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.SetTestSuiteBuilder;
+import com.google.common.collect.testing.TestCollectionGenerator;
+import com.google.common.collect.testing.TestListGenerator;
+import com.google.common.collect.testing.TestStringSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.Feature;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.ListMultimapTestSuiteBuilder;
+import com.google.common.collect.testing.google.MultimapTestSuiteBuilder;
+import com.google.common.collect.testing.google.MultisetIteratorTester;
+import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
+import com.google.common.collect.testing.google.MultisetWritesTester;
+import com.google.common.collect.testing.google.TestListMultimapGenerator;
+import com.google.common.collect.testing.google.TestMultimapGenerator;
+import com.google.common.collect.testing.google.TestStringListMultimapGenerator;
+import com.google.common.collect.testing.google.TestStringMultisetGenerator;
+import com.google.common.collect.testing.testers.CollectionIteratorTester;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeSet;
+
+/**
+ * Run collection tests on wrappers from {@link Multimaps}.
+ *
+ * @author Jared Levy
+ */
+@GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version
+public class MultimapsCollectionTest extends TestCase {
+
+ static final Feature<?>[] COLLECTION_FEATURES_ORDER = {
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE
+ };
+ static final Feature<?>[] COLLECTION_FEATURES_REMOVE = {
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.SUPPORTS_REMOVE
+ };
+
+ static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = {
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SUPPORTS_REMOVE
+ };
+
+ private static final Feature<?>[] FOR_MAP_FEATURES_ONE = {
+ CollectionSize.ONE,
+ ALLOWS_NULL_VALUES,
+ SUPPORTS_REMOVE,
+ };
+
+ private static final Feature<?>[] FOR_MAP_FEATURES_ANY = {
+ CollectionSize.ANY,
+ ALLOWS_NULL_VALUES,
+ SUPPORTS_REMOVE,
+ MultisetTestSuiteBuilder.NoRecurse.NO_ENTRY_SET, // Cannot create entries with count > 1
+ };
+
+ static final Supplier<TreeSet<String>> STRING_TREESET_FACTORY = new Supplier<TreeSet<String>>() {
+ @Override
+ public TreeSet<String> get() {
+ return new TreeSet<String>(Ordering.natural().nullsLast());
+ }
+ };
+
+ static void populateMultimapForGet(
+ Multimap<Integer, String> multimap, String[] elements) {
+ multimap.put(2, "foo");
+ for (String element : elements) {
+ multimap.put(3, element);
+ }
+ }
+
+ static void populateMultimapForKeySet(
+ Multimap<String, Integer> multimap, String[] elements) {
+ for (String element : elements) {
+ multimap.put(element, 2);
+ multimap.put(element, 3);
+ }
+ }
+
+ static void populateMultimapForValues(
+ Multimap<Integer, String> multimap, String[] elements) {
+ for (int i = 0; i < elements.length; i++) {
+ multimap.put(i % 2, elements[i]);
+ }
+ }
+
+ static void populateMultimapForKeys(
+ Multimap<String, Integer> multimap, String[] elements) {
+ for (int i = 0; i < elements.length; i++) {
+ multimap.put(elements[i], i);
+ }
+ }
+
+ /**
+ * Implements {@code Multimap.put()} -- and no other methods -- for a {@code
+ * Map} by ignoring all but the latest value for each key. This class exists
+ * only so that we can use
+ * {@link MultimapsCollectionTest#populateMultimapForGet(Multimap, String[])}
+ * and similar methods to populate a map to be passed to
+ * {@link Multimaps#forMap(Map)}. All tests should run against the result of
+ * {@link #build()}.
+ */
+ private static final class PopulatableMapAsMultimap<K, V>
+ extends ForwardingMultimap<K, V> {
+ final Map<K, V> map;
+ final SetMultimap<K, V> unusableDelegate;
+
+ static <K, V> PopulatableMapAsMultimap<K, V> create() {
+ return new PopulatableMapAsMultimap<K, V>();
+ }
+
+ @SuppressWarnings("unchecked") // all methods throw immediately
+ PopulatableMapAsMultimap() {
+ this.map = newHashMap();
+ this.unusableDelegate = (SetMultimap<K, V>) newProxyInstance(
+ SetMultimap.class.getClassLoader(),
+ new Class<?>[] {SetMultimap.class},
+ new InvocationHandler() {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ throw new UnsupportedOperationException();
+ }
+ });
+ }
+
+ @Override protected Multimap<K, V> delegate() {
+ return unusableDelegate;
+ }
+
+ @Override public boolean put(K key, V value) {
+ map.put(key, value);
+ return true;
+ }
+
+ SetMultimap<K, V> build() {
+ return Multimaps.forMap(map);
+ }
+ }
+
+ abstract static class TestEntriesGenerator
+ implements TestCollectionGenerator<Entry<String, Integer>> {
+ @Override
+ public SampleElements<Entry<String, Integer>> samples() {
+ return new SampleElements<Entry<String, Integer>>(
+ Maps.immutableEntry("bar", 1),
+ Maps.immutableEntry("bar", 2),
+ Maps.immutableEntry("foo", 3),
+ Maps.immutableEntry("bar", 3),
+ Maps.immutableEntry("cat", 2));
+ }
+
+ @Override
+ public Collection<Entry<String, Integer>> create(Object... elements) {
+ Multimap<String, Integer> multimap = createMultimap();
+ for (Object element : elements) {
+ @SuppressWarnings("unchecked")
+ Entry<String, Integer> entry = (Entry<String, Integer>) element;
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return multimap.entries();
+ }
+
+ abstract Multimap<String, Integer> createMultimap();
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Entry<String, Integer>[] createArray(int length) {
+ return (Entry<String, Integer>[]) new Entry<?, ?>[length];
+ }
+
+ @Override
+ public List<Entry<String, Integer>> order(
+ List<Entry<String, Integer>> insertionOrder) {
+ return insertionOrder;
+ }
+ }
+
+ public abstract static class TestEntriesListGenerator
+ extends TestEntriesGenerator
+ implements TestListGenerator<Entry<String, Integer>> {
+ @Override public List<Entry<String, Integer>> create(Object... elements) {
+ return (List<Entry<String, Integer>>) super.create(elements);
+ }
+ }
+
+ private static final Predicate<Map.Entry<Integer, String>> FILTER_GET_PREDICATE
+ = new Predicate<Map.Entry<Integer, String>>() {
+ @Override public boolean apply(Entry<Integer, String> entry) {
+ return !"badvalue".equals(entry.getValue()) && 55556 != entry.getKey();
+ }
+ };
+
+ private static final Predicate<Map.Entry<String, Integer>> FILTER_KEYSET_PREDICATE
+ = new Predicate<Map.Entry<String, Integer>>() {
+ @Override public boolean apply(Entry<String, Integer> entry) {
+ return !"badkey".equals(entry.getKey()) && 55556 != entry.getValue();
+ }
+ };
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+
+ suite.addTest(ListMultimapTestSuiteBuilder.using(new TestStringListMultimapGenerator() {
+ @Override
+ protected ListMultimap<String, String> create(Entry<String, String>[] entries) {
+ ListMultimap<String, String> multimap = Multimaps.synchronizedListMultimap(
+ ArrayListMultimap.<String, String> create());
+ for (Entry<String, String> entry : entries) {
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return multimap;
+ }
+ })
+ .named("synchronized ArrayListMultimap")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
+ CollectionSize.ANY)
+ .createTestSuite());
+ suite.addTest(transformSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ PopulatableMapAsMultimap<Integer, String> multimap
+ = PopulatableMapAsMultimap.create();
+ populateMultimapForGet(multimap, elements);
+ return multimap.build().get(3);
+ }
+ })
+ .named("Multimaps.forMap.get")
+ .withFeatures(FOR_MAP_FEATURES_ONE)
+ .createTestSuite());
+
+ suite.addTest(SetTestSuiteBuilder.using(
+ new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ PopulatableMapAsMultimap<String, Integer> multimap
+ = PopulatableMapAsMultimap.create();
+ populateMultimapForKeySet(multimap, elements);
+ return multimap.build().keySet();
+ }
+ })
+ .named("Multimaps.forMap.keySet")
+ .withFeatures(FOR_MAP_FEATURES_ANY)
+ .createTestSuite());
+
+ // TODO: use collection testers on Multimaps.forMap.values
+
+ suite.addTest(MultisetTestSuiteBuilder.using(
+ new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ PopulatableMapAsMultimap<String, Integer> multimap
+ = PopulatableMapAsMultimap.create();
+ populateMultimapForKeys(multimap, elements);
+ return multimap.build().keys();
+ }
+ })
+ .named("Multimaps.forMap.keys")
+ .withFeatures(FOR_MAP_FEATURES_ANY)
+ .suppressing(getReadsDuplicateInitializingMethods())
+ .suppressing(getSetCountDuplicateInitializingMethods())
+ .suppressing(getIteratorDuplicateInitializingMethods())
+ .createTestSuite());
+
+ // TODO: use collection testers on Multimaps.forMap.entries
+
+ return suite;
+ }
+
+ static abstract class TransformedMultimapGenerator<M extends Multimap<String, String>>
+ implements TestMultimapGenerator<String, String, M> {
+
+ @Override
+ public String[] createKeyArray(int length) {
+ return new String[length];
+ }
+
+ @Override
+ public String[] createValueArray(int length) {
+ return new String[length];
+ }
+
+ @Override
+ public SampleElements<String> sampleKeys() {
+ return new SampleElements<String>("one", "two", "three", "four", "five");
+ }
+
+ @Override
+ public SampleElements<String> sampleValues() {
+ return new SampleElements<String>("january", "february", "march", "april", "may");
+ }
+
+ @Override
+ public Collection<String> createCollection(Iterable<? extends String> values) {
+ return Lists.newArrayList(values);
+ }
+
+ @Override
+ public SampleElements<Entry<String, String>> samples() {
+ return new SampleElements<Entry<String, String>>(
+ mapEntry("one", "january"),
+ mapEntry("two", "february"),
+ mapEntry("three", "march"),
+ mapEntry("four", "april"),
+ mapEntry("five", "may"));
+ }
+
+ @Override
+ public M create(Object... elements) {
+ Multimap<String, String> multimap = ArrayListMultimap.create();
+ for (Object o : elements) {
+ @SuppressWarnings("unchecked")
+ Entry<String, String> entry = (Entry<String, String>) o;
+ multimap.put(entry.getKey(), Ascii.toUpperCase(entry.getValue()));
+ }
+ return transform(multimap);
+ }
+
+ abstract M transform(Multimap<String, String> multimap);
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Entry<String, String>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<String, String>> order(List<Entry<String, String>> insertionOrder) {
+ return insertionOrder;
+ }
+
+ static final Function<String, String> FUNCTION = new Function<String, String>() {
+ @Override
+ public String apply(String value) {
+ return Ascii.toLowerCase(value);
+ }
+ };
+
+ static final EntryTransformer<String, String, String> ENTRY_TRANSFORMER =
+ new EntryTransformer<String, String, String>() {
+ @Override
+ public String transformEntry(String key, String value) {
+ return Ascii.toLowerCase(value);
+ }
+ };
+ }
+
+ static abstract class TransformedListMultimapGenerator
+ extends TransformedMultimapGenerator<ListMultimap<String, String>>
+ implements TestListMultimapGenerator<String, String> {
+ }
+
+ private static Test transformSuite() {
+ TestSuite suite = new TestSuite("Multimaps.transform*");
+ suite.addTest(MultimapTestSuiteBuilder.using(
+ new TransformedMultimapGenerator<Multimap<String,String>>() {
+ @Override
+ Multimap<String, String> transform(Multimap<String, String> multimap) {
+ return Multimaps.transformValues(multimap, FUNCTION);
+ }
+ })
+ .named("Multimaps.transformValues[Multimap]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.SUPPORTS_REMOVE,
+ MapFeature.ALLOWS_NULL_KEYS)
+ .createTestSuite());
+ suite.addTest(MultimapTestSuiteBuilder.using(
+ new TransformedMultimapGenerator<Multimap<String,String>>() {
+ @Override
+ Multimap<String, String> transform(Multimap<String, String> multimap) {
+ return Multimaps.transformEntries(multimap, ENTRY_TRANSFORMER);
+ }
+ })
+ .named("Multimaps.transformEntries[Multimap]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.SUPPORTS_REMOVE,
+ MapFeature.ALLOWS_NULL_KEYS)
+ .createTestSuite());
+ suite.addTest(ListMultimapTestSuiteBuilder.using(new TransformedListMultimapGenerator() {
+ @Override
+ ListMultimap<String, String> transform(Multimap<String, String> multimap) {
+ return Multimaps.transformValues((ListMultimap<String, String>) multimap, FUNCTION);
+ }
+ })
+ .named("Multimaps.transformValues[ListMultimap]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.SUPPORTS_REMOVE,
+ MapFeature.ALLOWS_NULL_KEYS)
+ .createTestSuite());
+ suite.addTest(ListMultimapTestSuiteBuilder.using(new TransformedListMultimapGenerator() {
+ @Override
+ ListMultimap<String, String> transform(Multimap<String, String> multimap) {
+ return Multimaps.transformEntries(
+ (ListMultimap<String, String>) multimap, ENTRY_TRANSFORMER);
+ }
+ })
+ .named("Multimaps.transformEntries[ListMultimap]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.SUPPORTS_REMOVE,
+ MapFeature.ALLOWS_NULL_KEYS)
+ .createTestSuite());
+
+ // TODO: use collection testers on Multimaps.forMap.entries
+
+ suite.addTest(filterSuite());
+
+ return suite;
+ }
+
+ static abstract class TestFilteredMultimapGenerator
+ implements TestMultimapGenerator<String, Integer, Multimap<String, Integer>> {
+
+ @Override
+ public SampleElements<Entry<String, Integer>> samples() {
+ return new SampleElements<Entry<String, Integer>>(
+ mapEntry("one", 114),
+ mapEntry("two", 37),
+ mapEntry("three", 42),
+ mapEntry("four", 19),
+ mapEntry("five", 82));
+ }
+
+ abstract Multimap<String, Integer> filter(Multimap<String, Integer> multimap);
+
+ @Override
+ public Multimap<String, Integer> create(Object... elements) {
+ Multimap<String, Integer> multimap = LinkedHashMultimap.create();
+ for (Object o : elements) {
+ @SuppressWarnings("unchecked")
+ Entry<String, Integer> entry = (Entry<String, Integer>) o;
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return filter(multimap);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Entry<String, Integer>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<String, Integer>> order(List<Entry<String, Integer>> insertionOrder) {
+ return insertionOrder;
+ }
+
+ @Override
+ public String[] createKeyArray(int length) {
+ return new String[length];
+ }
+
+ @Override
+ public Integer[] createValueArray(int length) {
+ return new Integer[length];
+ }
+
+ @Override
+ public SampleElements<String> sampleKeys() {
+ return new SampleElements<String>("one", "two", "three", "four", "five");
+ }
+
+ @Override
+ public SampleElements<Integer> sampleValues() {
+ return new SampleElements<Integer>(114, 37, 42, 19, 82);
+ }
+
+ @Override
+ public Collection<Integer> createCollection(Iterable<? extends Integer> values) {
+ return Sets.newLinkedHashSet(values);
+ }
+ }
+
+ private static Test filterSuite() {
+ TestSuite suite = new TestSuite("Multimaps.filter*");
+ suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
+ @Override
+ Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
+ multimap.put("foo", 17);
+ multimap.put("bar", 32);
+ multimap.put("foo", 16);
+ return Multimaps.filterKeys(multimap,
+ Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar"))));
+ }
+ })
+ .named("Multimaps.filterKeys[Multimap, Predicate]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetWritesTester.getEntrySetIteratorMethod())
+ .createTestSuite());
+ suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
+ @Override
+ Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
+ multimap.put("one", 314);
+ multimap.put("two", 159);
+ multimap.put("one", 265);
+ return Multimaps.filterValues(multimap,
+ Predicates.not(Predicates.in(ImmutableSet.of(314, 159, 265))));
+ }
+ })
+ .named("Multimaps.filterValues[Multimap, Predicate]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetWritesTester.getEntrySetIteratorMethod())
+ .createTestSuite());
+ suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
+ @Override
+ Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
+ ImmutableSetMultimap<String, Integer> badEntries =
+ ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358);
+ multimap.putAll(badEntries);
+ return Multimaps.filterEntries(multimap,
+ Predicates.not(Predicates.in(badEntries.entries())));
+ }
+ })
+ .named("Multimaps.filterEntries[Multimap, Predicate]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetWritesTester.getEntrySetIteratorMethod())
+ .createTestSuite());
+ suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
+ @Override
+ Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
+ ImmutableSetMultimap<String, Integer> badEntries =
+ ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358);
+ multimap.putAll(badEntries);
+ multimap = Multimaps.filterKeys(multimap,
+ Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar"))));
+ return Multimaps.filterEntries(multimap,
+ Predicates.not(Predicates.in(badEntries.entries())));
+ }
+ })
+ .named("Multimaps.filterEntries[Maps.filterKeys[Multimap]]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetWritesTester.getEntrySetIteratorMethod())
+ .createTestSuite());
+ suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
+ @Override
+ Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
+ ImmutableSetMultimap<String, Integer> badEntries =
+ ImmutableSetMultimap.of("foo", 314, "one", 159, "two", 265, "bar", 358);
+ multimap.putAll(badEntries);
+ multimap = Multimaps.filterEntries(multimap,
+ Predicates.not(Predicates.in(ImmutableMap.of("one", 159, "two", 265).entrySet())));
+ return Multimaps.filterKeys(multimap,
+ Predicates.not(Predicates.in(ImmutableSet.of("foo", "bar"))));
+ }
+ })
+ .named("Multimaps.filterKeys[Maps.filterEntries[Multimap]]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetWritesTester.getEntrySetIteratorMethod())
+ .createTestSuite());
+ suite.addTest(MultimapTestSuiteBuilder.using(new TestFilteredMultimapGenerator() {
+ @Override
+ Multimap<String, Integer> filter(Multimap<String, Integer> multimap) {
+ ImmutableSetMultimap<String, Integer> badEntries =
+ ImmutableSetMultimap.of("foo", 314, "bar", 358);
+ multimap.putAll(badEntries);
+ multimap = Multimaps.filterKeys(multimap, Predicates.not(Predicates.equalTo("foo")));
+ multimap = Multimaps.filterKeys(multimap, Predicates.not(Predicates.equalTo("bar")));
+ return multimap;
+ }
+ })
+ .named("Multimaps.filterKeys[Maps.filterKeys[Multimap]]")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES)
+ .suppressing(CollectionIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetIteratorTester.getIteratorUnknownOrderRemoveSupportedMethod(),
+ MultisetWritesTester.getEntrySetIteratorMethod())
+ .createTestSuite());
+ return suite;
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/MultimapsTest.java b/guava-tests/test/com/google/common/collect/MultimapsTest.java
index 5ba5180..5047842 100644
--- a/guava-tests/test/com/google/common/collect/MultimapsTest.java
+++ b/guava-tests/test/com/google/common/collect/MultimapsTest.java
@@ -16,12 +16,13 @@
package com.google.common.collect;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Maps.immutableEntry;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.collect.testing.Helpers.nefariousMapEntry;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -61,6 +62,7 @@ import javax.annotation.Nullable;
*/
@GwtCompatible(emulated = true)
public class MultimapsTest extends AbstractMultimapTest {
+
private static final Comparator<Integer> INT_COMPARATOR =
Ordering.<Integer>natural().reverse().nullsFirst();
@@ -78,7 +80,7 @@ public class MultimapsTest extends AbstractMultimapTest {
}
@SuppressWarnings("deprecation")
- public void testUnmodifiableListMultimapShortCircuit(){
+ public void testUnmodifiableListMultimapShortCircuit() {
ListMultimap<String, Integer> mod = ArrayListMultimap.create();
ListMultimap<String, Integer> unmod = Multimaps.unmodifiableListMultimap(mod);
assertNotSame(mod, unmod);
@@ -91,7 +93,7 @@ public class MultimapsTest extends AbstractMultimapTest {
}
@SuppressWarnings("deprecation")
- public void testUnmodifiableSetMultimapShortCircuit(){
+ public void testUnmodifiableSetMultimapShortCircuit() {
SetMultimap<String, Integer> mod = HashMultimap.create();
SetMultimap<String, Integer> unmod = Multimaps.unmodifiableSetMultimap(mod);
assertNotSame(mod, unmod);
@@ -104,7 +106,7 @@ public class MultimapsTest extends AbstractMultimapTest {
}
@SuppressWarnings("deprecation")
- public void testUnmodifiableMultimapShortCircuit(){
+ public void testUnmodifiableMultimapShortCircuit() {
Multimap<String, Integer> mod = HashMultimap.create();
Multimap<String, Integer> unmod = Multimaps.unmodifiableMultimap(mod);
assertNotSame(mod, unmod);
@@ -230,7 +232,7 @@ public class MultimapsTest extends AbstractMultimapTest {
assertTrue(unmod.containsEntry("foo", 1));
assertEquals(mod, unmod);
}
-
+
@SuppressWarnings("unchecked")
public void testUnmodifiableMultimapEntries() {
Multimap<String, Integer> mod = HashMultimap.create();
@@ -296,7 +298,7 @@ public class MultimapsTest extends AbstractMultimapTest {
assertEquals(multimap.hashCode(), unmodifiable.hashCode());
assertEquals(multimap, unmodifiable);
- ASSERT.that(unmodifiable.asMap().get("bar")).hasContentsAnyOrder(5, -1);
+ ASSERT.that(unmodifiable.asMap().get("bar")).has().allOf(5, -1);
assertNull(unmodifiable.asMap().get("missing"));
assertFalse(unmodifiable.entries() instanceof Serializable);
@@ -428,11 +430,11 @@ public class MultimapsTest extends AbstractMultimapTest {
assertFalse(map.containsKey("bar"));
assertEquals(map.keySet(), multimapView.keySet());
assertEquals(map.keySet(), multimapView.keys().elementSet());
- ASSERT.that(multimapView.keys()).hasContentsAnyOrder("foo");
- ASSERT.that(multimapView.values()).hasContentsAnyOrder(1);
- ASSERT.that(multimapView.entries()).hasContentsAnyOrder(
+ ASSERT.that(multimapView.keys()).has().item("foo");
+ ASSERT.that(multimapView.values()).has().item(1);
+ ASSERT.that(multimapView.entries()).has().item(
Maps.immutableEntry("foo", 1));
- ASSERT.that(multimapView.asMap().entrySet()).hasContentsAnyOrder(
+ ASSERT.that(multimapView.asMap().entrySet()).has().item(
Maps.immutableEntry(
"foo", (Collection<Integer>) Collections.singleton(1)));
multimapView.clear();
@@ -549,6 +551,52 @@ public class MultimapsTest extends AbstractMultimapTest {
private static final long serialVersionUID = 0;
}
+ public void testNewMultimapWithCollectionRejectingNegativeElements() {
+ CountingSupplier<Set<Integer>> factory = new SetSupplier() {
+ @Override
+ public Set<Integer> getImpl() {
+ final Set<Integer> backing = super.getImpl();
+ return new ForwardingSet<Integer>() {
+ @Override
+ protected Set<Integer> delegate() {
+ return backing;
+ }
+
+ @Override
+ public boolean add(Integer element) {
+ checkArgument(element >= 0);
+ return super.add(element);
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends Integer> collection) {
+ return standardAddAll(collection);
+ }
+ };
+ }
+ };
+
+ Map<Color, Collection<Integer>> map = Maps.newEnumMap(Color.class);
+ Multimap<Color, Integer> multimap = Multimaps.newMultimap(map, factory);
+ try {
+ multimap.put(Color.BLUE, -1);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ multimap.put(Color.RED, 1);
+ multimap.put(Color.BLUE, 2);
+ try {
+ multimap.put(Color.GREEN, -1);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // expected
+ }
+ ASSERT.that(multimap.entries()).has().allOf(
+ Maps.immutableEntry(Color.RED, 1),
+ Maps.immutableEntry(Color.BLUE, 2));
+ }
+
public void testNewMultimap() {
// The ubiquitous EnumArrayBlockingQueueMultimap
CountingSupplier<Queue<Integer>> factory = new QueueSupplier();
@@ -618,15 +666,15 @@ public class MultimapsTest extends AbstractMultimapTest {
SerializableTester.reserializeAndAssert(multimap);
}
- private static class SetSupplier extends CountingSupplier<HashSet<Integer>> {
- @Override public HashSet<Integer> getImpl() {
+ private static class SetSupplier extends CountingSupplier<Set<Integer>> {
+ @Override public Set<Integer> getImpl() {
return new HashSet<Integer>(4);
}
private static final long serialVersionUID = 0;
}
public void testNewSetMultimap() {
- CountingSupplier<HashSet<Integer>> factory = new SetSupplier();
+ CountingSupplier<Set<Integer>> factory = new SetSupplier();
Map<Color, Collection<Integer>> map = Maps.newHashMap();
SetMultimap<Color, Integer> multimap =
Multimaps.newSetMultimap(map, factory);
@@ -640,7 +688,7 @@ public class MultimapsTest extends AbstractMultimapTest {
@GwtIncompatible("SerializableTester")
public void testNewSetMultimapSerialization() {
- CountingSupplier<HashSet<Integer>> factory = new SetSupplier();
+ CountingSupplier<Set<Integer>> factory = new SetSupplier();
Map<Color, Collection<Integer>> map = Maps.newHashMap();
SetMultimap<Color, Integer> multimap = Multimaps.newSetMultimap(map, factory);
multimap.putAll(Color.BLUE, asList(3, 1, 4));
@@ -714,39 +762,6 @@ public class MultimapsTest extends AbstractMultimapTest {
assertEquals(stringToObject, outputMap);
}
- // NOTE: evil, never do this
- private abstract static class IterableIterator<T>
- extends ForwardingIterator<T> implements Iterable<T> {
- @Override
- public Iterator<T> iterator() {
- return this;
- }
- }
-
- @SuppressWarnings("deprecation") // that is the purpose of this test
- public void testIndexIterableIterator() {
- final Multimap<String, Object> stringToObject =
- new ImmutableMultimap.Builder<String, Object>()
- .put("1", 1)
- .put("1", 1L)
- .put("1", "1")
- .put("2", 2)
- .put("2", 2L)
- .build();
-
- IterableIterator<Object> iterIter = new IterableIterator<Object>() {
- private final Iterator<Object> iterator = stringToObject.values().iterator();
-
- public Iterator<Object> delegate() {
- return iterator;
- }
- };
-
- ImmutableMultimap<String, Object> outputMap =
- Multimaps.index(iterIter, Functions.toStringFunction());
- assertEquals(stringToObject, outputMap);
- }
-
public void testIndex_ordering() {
final Multimap<Integer, String> expectedIndex =
new ImmutableListMultimap.Builder<Integer, String>()
@@ -799,11 +814,10 @@ public class MultimapsTest extends AbstractMultimapTest {
return in * in;
}
};
- Multimap<String, Integer> transformed =
- Multimaps.transformValues(multimap, square);
- ASSERT.that(transformed.entries()).hasContentsInOrder(immutableEntry("a", 4),
+ Multimap<String, Integer> transformed = Multimaps.transformValues(multimap, square);
+ ASSERT.that(transformed.entries()).has().allOf(immutableEntry("a", 4),
immutableEntry("a", 16), immutableEntry("b", 9), immutableEntry("b", 9),
- immutableEntry("c", 36));
+ immutableEntry("c", 36)).inOrder();
}
@GwtIncompatible(value = "untested")
@@ -819,7 +833,7 @@ public class MultimapsTest extends AbstractMultimapTest {
});
Entry<String, String> entry = multimap.entries().iterator().next();
entry.setValue("bbb");
- ASSERT.that(transformed.entries()).hasContentsInOrder(immutableEntry("a", 3));
+ ASSERT.that(transformed.entries()).has().allOf(immutableEntry("a", 3)).inOrder();
}
@GwtIncompatible(value = "untested")
@@ -834,9 +848,9 @@ public class MultimapsTest extends AbstractMultimapTest {
};
ListMultimap<String, Integer> transformed =
Multimaps.transformValues(multimap, square);
- ASSERT.that(transformed.entries()).hasContentsInOrder(immutableEntry("a", 4),
+ ASSERT.that(transformed.entries()).has().allOf(immutableEntry("a", 4),
immutableEntry("a", 16), immutableEntry("b", 9), immutableEntry("b", 9),
- immutableEntry("c", 36));
+ immutableEntry("c", 36)).inOrder();
}
@GwtIncompatible(value = "untested")
@@ -852,8 +866,8 @@ public class MultimapsTest extends AbstractMultimapTest {
};
Multimap<String, String> transformed =
Multimaps.transformEntries(multimap, transformer);
- ASSERT.that(transformed.entries()).hasContentsInOrder(immutableEntry("a", "a"),
- immutableEntry("a", "a"), immutableEntry("b", "nob"));
+ ASSERT.that(transformed.entries()).has().allOf(immutableEntry("a", "a"),
+ immutableEntry("a", "a"), immutableEntry("b", "nob")).inOrder();
}
@GwtIncompatible(value = "untested")
@@ -875,13 +889,24 @@ public class MultimapsTest extends AbstractMultimapTest {
assertEquals("{a=[a1, a4, a4], b=[b6]}", transformed.toString());
}
+ public <K, V> void testSynchronizedMultimapSampleCodeCompilation() {
+ K key = null;
+
+ Multimap<K, V> multimap = Multimaps.synchronizedMultimap(
+ HashMultimap.<K, V>create());
+ Collection<V> values = multimap.get(key); // Needn't be in synchronized block
+ synchronized (multimap) { // Synchronizing on multimap, not values!
+ Iterator<V> i = values.iterator(); // Must be in synchronized block
+ while (i.hasNext()) {
+ foo(i.next());
+ }
+ }
+ }
+
+ private static void foo(Object o) {}
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Multimap.class, ImmutableMultimap.of());
- tester.setDefault(ListMultimap.class, ImmutableListMultimap.of());
- tester.setDefault(EntryTransformer.class, ALWAYS_NULL);
- tester.ignore(Multimaps.class.getDeclaredMethod("index", Object.class, Function.class));
- tester.testAllPublicStaticMethods(Multimaps.class);
+ public void testNullPointers() {
+ new NullPointerTester().testAllPublicStaticMethods(Multimaps.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/MultisetCollectionTest.java b/guava-tests/test/com/google/common/collect/MultisetsCollectionTest.java
index 47a94d3..a32fdc8 100644
--- a/guava-tests/test/com/google/common/collect/MultisetCollectionTest.java
+++ b/guava-tests/test/com/google/common/collect/MultisetsCollectionTest.java
@@ -16,150 +16,111 @@
package com.google.common.collect;
-import static com.google.common.collect.testing.google.AbstractMultisetSetCountTester.getSetCountDuplicateInitializingMethods;
-import static com.google.common.collect.testing.google.MultisetIteratorTester.getIteratorDuplicateInitializingMethods;
-import static com.google.common.collect.testing.google.MultisetReadsTester.getReadsDuplicateInitializingMethods;
import static java.util.Arrays.asList;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.AnEnum;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.google.MultisetIteratorTester;
import com.google.common.collect.testing.google.MultisetTestSuiteBuilder;
+import com.google.common.collect.testing.google.MultisetWritesTester;
import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder;
-import com.google.common.collect.testing.google.TestEnumMultisetGenerator;
import com.google.common.collect.testing.google.TestStringMultisetGenerator;
+import com.google.common.collect.testing.testers.CollectionIteratorTester;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
- * Collection tests for {@link Multiset} implementations.
+ * Collection tests on wrappers from {@link Multisets}.
*
* @author Jared Levy
*/
@GwtIncompatible("suite") // TODO(cpovirk): set up collect/gwt/suites version
-public class MultisetCollectionTest extends TestCase {
-
+public class MultisetsCollectionTest extends TestCase {
public static Test suite() {
TestSuite suite = new TestSuite();
- suite.addTest(MultisetTestSuiteBuilder.using(hashMultisetGenerator())
- .withFeatures(CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.GENERAL_PURPOSE)
- .named("HashMultiset")
- .createTestSuite());
-
suite.addTest(MultisetTestSuiteBuilder.using(
unmodifiableMultisetGenerator())
.withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("UnmodifiableTreeMultiset")
+ .named("Multisets.unmodifiableMultiset[LinkedHashMultiset]")
.createTestSuite());
- suite.addTest(SortedMultisetTestSuiteBuilder
- .using(new TestStringMultisetGenerator() {
- @Override
- protected Multiset<String> create(String[] elements) {
- return TreeMultiset.create(Arrays.asList(elements));
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().sortedCopy(insertionOrder);
- }
- })
+ suite.addTest(SortedMultisetTestSuiteBuilder.using(unmodifiableSortedMultisetGenerator())
.withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE,
CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("TreeMultiset, Ordering.natural")
+ .named("Multisets.unmodifiableMultiset[TreeMultiset]")
.createTestSuite());
-
- suite.addTest(SortedMultisetTestSuiteBuilder
- .using(new TestStringMultisetGenerator() {
- @Override
- protected Multiset<String> create(String[] elements) {
- Multiset<String> result = TreeMultiset.create(Ordering.natural().nullsFirst());
- result.addAll(Arrays.asList(elements));
- return result;
- }
-
- @Override
- public List<String> order(List<String> insertionOrder) {
- return Ordering.natural().nullsFirst().sortedCopy(insertionOrder);
- }
- })
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE,
+ suite.addTest(MultisetTestSuiteBuilder.using(unionGenerator())
+ .withFeatures(CollectionSize.ANY,
CollectionFeature.ALLOWS_NULL_VALUES)
- .named("TreeMultiset, Ordering.natural.nullsFirst")
- .createTestSuite());
-
- suite.addTest(MultisetTestSuiteBuilder.using(forSetGenerator())
- .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionFeature.REMOVE_OPERATIONS)
- .suppressing(getReadsDuplicateInitializingMethods())
- .suppressing(getSetCountDuplicateInitializingMethods())
- .suppressing(getIteratorDuplicateInitializingMethods())
- .named("ForSetMultiset")
+ .named("Multisets.union")
.createTestSuite());
- suite.addTest(MultisetTestSuiteBuilder.using(
- concurrentMultisetGenerator())
+ suite.addTest(MultisetTestSuiteBuilder.using(intersectionGenerator())
.withFeatures(CollectionSize.ANY,
- CollectionFeature.GENERAL_PURPOSE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("ConcurrentHashMultiset")
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.KNOWN_ORDER)
+ .named("Multisets.intersection")
.createTestSuite());
- suite.addTest(MultisetTestSuiteBuilder.using(enumMultisetGenerator())
+ suite.addTest(MultisetTestSuiteBuilder.using(sumGenerator())
.withFeatures(CollectionSize.ANY,
- CollectionFeature.KNOWN_ORDER,
- CollectionFeature.GENERAL_PURPOSE,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("EnumMultiset")
+ CollectionFeature.ALLOWS_NULL_VALUES)
+ .named("Multisets.sum")
.createTestSuite());
- suite.addTest(MultisetTestSuiteBuilder.using(intersectionGenerator())
+ suite.addTest(MultisetTestSuiteBuilder.using(differenceGenerator())
.withFeatures(CollectionSize.ANY,
CollectionFeature.ALLOWS_NULL_VALUES,
CollectionFeature.KNOWN_ORDER)
- .named("IntersectionMultiset")
+ .named("Multisets.difference")
.createTestSuite());
-
- suite.addTest(SortedMultisetTestSuiteBuilder.using(unmodifiableSortedMultisetGenerator())
- .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
- CollectionFeature.ALLOWS_NULL_QUERIES)
- .named("UnmodifiableSortedTreeMultiset")
+
+ suite.addTest(MultisetTestSuiteBuilder.using(filteredGenerator())
+ .withFeatures(CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE)
+ .named("Multiset.filter[Multiset, Predicate]")
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod(),
+ MultisetIteratorTester.getIteratorKnownOrderRemoveSupportedMethod(),
+ MultisetWritesTester.getEntrySetIteratorMethod())
.createTestSuite());
return suite;
}
- private static TestStringMultisetGenerator hashMultisetGenerator() {
- return new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- return HashMultiset.create(asList(elements));
- }
- };
- }
-
private static TestStringMultisetGenerator unmodifiableMultisetGenerator() {
return new TestStringMultisetGenerator() {
@Override protected Multiset<String> create(String[] elements) {
return Multisets.unmodifiableMultiset(
- TreeMultiset.create(asList(elements)));
+ LinkedHashMultiset.create(asList(elements)));
}
@Override public List<String> order(List<String> insertionOrder) {
- Collections.sort(insertionOrder);
- return insertionOrder;
+ List<String> order = new ArrayList<String>();
+ for (String s : insertionOrder) {
+ int index = order.indexOf(s);
+ if (index == -1) {
+ order.add(s);
+ } else {
+ order.add(index, s);
+ }
+ }
+ return order;
}
};
}
@@ -177,28 +138,26 @@ public class MultisetCollectionTest extends TestCase {
};
}
- private static TestStringMultisetGenerator forSetGenerator() {
- return new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- return Multisets.forSet(Sets.newHashSet(elements));
- }
- };
- }
-
- private static TestStringMultisetGenerator concurrentMultisetGenerator() {
+ private static TestStringMultisetGenerator unionGenerator() {
return new TestStringMultisetGenerator() {
- @Override protected Multiset<String> create(String[] elements) {
- return ConcurrentHashMultiset.create(asList(elements));
- }
- };
- }
-
- private static TestEnumMultisetGenerator enumMultisetGenerator() {
- return new TestEnumMultisetGenerator() {
- @Override protected Multiset<AnEnum> create(AnEnum[] elements) {
- return (elements.length == 0)
- ? EnumMultiset.create(AnEnum.class)
- : EnumMultiset.create(asList(elements));
+ @Override
+ protected Multiset<String> create(String[] elements) {
+ Multiset<String> multiset1 = LinkedHashMultiset.create();
+ Multiset<String> multiset2 = LinkedHashMultiset.create();
+ for (int i = 0; i < elements.length; i++) {
+ String element = elements[i];
+ if (multiset1.contains(element) ||
+ multiset2.contains(element)) {
+ // add to both; the one already containing it will have more
+ multiset1.add(element);
+ multiset2.add(element);
+ } else if (i % 2 == 0) {
+ multiset1.add(elements[i]);
+ } else {
+ multiset2.add(elements[i]);
+ }
+ }
+ return Multisets.union(multiset1, multiset2);
}
};
}
@@ -223,7 +182,7 @@ public class MultisetCollectionTest extends TestCase {
* "add an extra item 0 to A and an extra item 1 to B" really means
* "add an extra item 0 to A and B," which isn't what we want.
*/
- if (!elements[0].equals(elements[1])) {
+ if (!Objects.equal(elements[0], elements[1])) {
multiset2.add(elements[1], 2);
}
}
@@ -231,4 +190,65 @@ public class MultisetCollectionTest extends TestCase {
}
};
}
+
+ private static TestStringMultisetGenerator sumGenerator() {
+ return new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ Multiset<String> multiset1 = LinkedHashMultiset.create();
+ Multiset<String> multiset2 = LinkedHashMultiset.create();
+ for (int i = 0; i < elements.length; i++) {
+ // add to either; sum should contain all
+ if (i % 2 == 0) {
+ multiset1.add(elements[i]);
+ } else {
+ multiset2.add(elements[i]);
+ }
+ }
+ return Multisets.sum(multiset1, multiset2);
+ }
+ };
+ }
+
+ private static TestStringMultisetGenerator differenceGenerator() {
+ return new TestStringMultisetGenerator() {
+ @Override protected Multiset<String> create(String[] elements) {
+ Multiset<String> multiset1 = LinkedHashMultiset.create();
+ Multiset<String> multiset2 = LinkedHashMultiset.create();
+ multiset1.add("equalIn1");
+ multiset1.add("fewerIn1");
+ multiset2.add("equalIn1");
+ multiset2.add("fewerIn1", 3);
+ multiset2.add("onlyIn2", 2);
+ for (int i = 0; i < elements.length; i++) {
+ // add 1 more copy of each element to multiset1 than multiset2
+ multiset1.add(elements[i], i + 2);
+ multiset2.add(elements[i], i + 1);
+ }
+ return Multisets.difference(multiset1, multiset2);
+ }
+ };
+ }
+
+ private static final Multiset<String> ELEMENTS_TO_FILTER_OUT = ImmutableMultiset.of(
+ "foobar", "bazfoo", "foobar", "foobar");
+
+ private static final Predicate<String> PREDICATE =
+ Predicates.not(Predicates.in(ELEMENTS_TO_FILTER_OUT));
+
+ private static TestStringMultisetGenerator filteredGenerator() {
+ return new TestStringMultisetGenerator() {
+ @Override
+ protected Multiset<String> create(String[] elements) {
+ Multiset<String> multiset = LinkedHashMultiset.create();
+ multiset.addAll(Arrays.asList(elements));
+ multiset.addAll(ELEMENTS_TO_FILTER_OUT);
+ return Multisets.filter(multiset, PREDICATE);
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Lists.newArrayList(LinkedHashMultiset.create(insertionOrder));
+ }
+ };
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/MultisetsTest.java b/guava-tests/test/com/google/common/collect/MultisetsTest.java
index 214d736..91b3c14 100644
--- a/guava-tests/test/com/google/common/collect/MultisetsTest.java
+++ b/guava-tests/test/com/google/common/collect/MultisetsTest.java
@@ -16,21 +16,18 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
-import static com.google.common.testing.SerializableTester.reserializeAndAssert;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import junit.framework.TestCase;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.DerivedComparable;
import com.google.common.testing.NullPointerTester;
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Collections;
+
/**
* Tests for {@link Multisets}.
*
@@ -43,79 +40,14 @@ public class MultisetsTest extends TestCase {
/* See MultisetsImmutableEntryTest for immutableEntry() tests. */
- public void testForSet() {
- Set<String> set = new HashSet<String>();
- set.add("foo");
- set.add("bar");
- set.add(null);
- Multiset<String> multiset = HashMultiset.create();
- multiset.addAll(set);
- Multiset<String> multisetView = Multisets.forSet(set);
- assertTrue(multiset.equals(multisetView));
- assertTrue(multisetView.equals(multiset));
- assertEquals(multiset.toString(), multisetView.toString());
- assertEquals(multiset.hashCode(), multisetView.hashCode());
- assertEquals(multiset.size(), multisetView.size());
- assertTrue(multisetView.contains("foo"));
- assertEquals(set, multisetView.elementSet());
- assertEquals(multisetView.elementSet(), set);
- assertEquals(multiset.elementSet(), multisetView.elementSet());
- assertEquals(multisetView.elementSet(), multiset.elementSet());
- try {
- multisetView.add("baz");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {}
- try {
- multisetView.addAll(Collections.singleton("baz"));
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {}
- try {
- multisetView.elementSet().add("baz");
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {}
- try {
- multisetView.elementSet().addAll(Collections.singleton("baz"));
- fail("UnsupportedOperationException expected");
- } catch (UnsupportedOperationException expected) {}
- multisetView.remove("bar");
- assertFalse(multisetView.contains("bar"));
- assertFalse(set.contains("bar"));
- assertEquals(set, multisetView.elementSet());
- ASSERT.that(multisetView.elementSet()).hasContentsAnyOrder("foo", null);
- ASSERT.that(multisetView.entrySet()).hasContentsAnyOrder(
- Multisets.immutableEntry("foo", 1), Multisets.immutableEntry((String) null, 1));
- multisetView.clear();
- assertFalse(multisetView.contains("foo"));
- assertFalse(set.contains("foo"));
- assertTrue(set.isEmpty());
- assertTrue(multisetView.isEmpty());
- multiset.clear();
- assertEquals(multiset.toString(), multisetView.toString());
- assertEquals(multiset.hashCode(), multisetView.hashCode());
- assertEquals(multiset.size(), multisetView.size());
- }
-
- @GwtIncompatible("SerializableTester")
- public void testForSetSerialization() {
- Set<String> set = new HashSet<String>();
- set.add("foo");
- set.add("bar");
- set.add(null);
- Multiset<String> multiset = HashMultiset.create();
- multiset.addAll(set);
- Multiset<String> multisetView = Multisets.forSet(set);
- assertTrue(multiset.equals(multisetView));
- reserializeAndAssert(multisetView);
- }
-
public void testNewTreeMultisetDerived() {
TreeMultiset<DerivedComparable> set = TreeMultiset.create();
assertTrue(set.isEmpty());
set.add(new DerivedComparable("foo"), 2);
set.add(new DerivedComparable("bar"), 3);
- ASSERT.that(set).hasContentsInOrder(
+ ASSERT.that(set).has().allOf(
new DerivedComparable("bar"), new DerivedComparable("bar"), new DerivedComparable("bar"),
- new DerivedComparable("foo"), new DerivedComparable("foo"));
+ new DerivedComparable("foo"), new DerivedComparable("foo")).inOrder();
}
public void testNewTreeMultisetNonGeneric() {
@@ -123,9 +55,9 @@ public class MultisetsTest extends TestCase {
assertTrue(set.isEmpty());
set.add(new LegacyComparable("foo"), 2);
set.add(new LegacyComparable("bar"), 3);
- ASSERT.that(set).hasContentsInOrder(new LegacyComparable("bar"),
+ ASSERT.that(set).has().allOf(new LegacyComparable("bar"),
new LegacyComparable("bar"), new LegacyComparable("bar"),
- new LegacyComparable("foo"), new LegacyComparable("foo"));
+ new LegacyComparable("foo"), new LegacyComparable("foo")).inOrder();
}
public void testNewTreeMultisetComparator() {
@@ -133,7 +65,7 @@ public class MultisetsTest extends TestCase {
= TreeMultiset.create(Collections.reverseOrder());
multiset.add("bar", 3);
multiset.add("foo", 2);
- ASSERT.that(multiset).hasContentsInOrder("foo", "foo", "bar", "bar", "bar");
+ ASSERT.that(multiset).has().allOf("foo", "foo", "bar", "bar", "bar").inOrder();
}
public void testRetainOccurrencesEmpty() {
@@ -141,7 +73,7 @@ public class MultisetsTest extends TestCase {
Multiset<String> toRetain =
HashMultiset.create(Arrays.asList("a", "b", "a"));
assertFalse(Multisets.retainOccurrences(multiset, toRetain));
- ASSERT.that(multiset).hasContentsInOrder();
+ ASSERT.that(multiset).isEmpty();
}
public void testRemoveOccurrencesEmpty() {
@@ -152,18 +84,96 @@ public class MultisetsTest extends TestCase {
assertTrue(multiset.isEmpty());
}
+ public void testUnion() {
+ Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ Multiset<String> ms2 = HashMultiset.create(
+ Arrays.asList("a", "b", "b", "c"));
+ ASSERT.that(Multisets.union(ms1, ms2)).has().allOf("a", "a", "b", "b", "c");
+ }
+
+ public void testUnionEqualMultisets() {
+ Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ assertEquals(ms1, Multisets.union(ms1, ms2));
+ }
+
+ public void testUnionEmptyNonempty() {
+ Multiset<String> ms1 = HashMultiset.create();
+ Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ assertEquals(ms2, Multisets.union(ms1, ms2));
+ }
+
+ public void testUnionNonemptyEmpty() {
+ Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ Multiset<String> ms2 = HashMultiset.create();
+ assertEquals(ms1, Multisets.union(ms1, ms2));
+ }
+
public void testIntersectEmptyNonempty() {
Multiset<String> ms1 = HashMultiset.create();
Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
- ASSERT.that(Multisets.intersection(ms1, ms2)).hasContentsInOrder();
+ ASSERT.that(Multisets.intersection(ms1, ms2)).isEmpty();
}
public void testIntersectNonemptyEmpty() {
Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
Multiset<String> ms2 = HashMultiset.create();
- ASSERT.that(Multisets.intersection(ms1, ms2)).hasContentsInOrder();
+ ASSERT.that(Multisets.intersection(ms1, ms2)).isEmpty();
+ }
+
+ public void testSum() {
+ Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ Multiset<String> ms2 = HashMultiset.create(Arrays.asList("b", "c"));
+ ASSERT.that(Multisets.sum(ms1, ms2)).has().allOf("a", "a", "b", "b", "c");
+ }
+
+ public void testSumEmptyNonempty() {
+ Multiset<String> ms1 = HashMultiset.create();
+ Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ ASSERT.that(Multisets.sum(ms1, ms2)).has().allOf("a", "b", "a");
+ }
+
+ public void testSumNonemptyEmpty() {
+ Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ Multiset<String> ms2 = HashMultiset.create();
+ ASSERT.that(Multisets.sum(ms1, ms2)).has().allOf("a", "b", "a");
+ }
+
+ public void testDifferenceWithNoRemovedElements() {
+ Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a"));
+ ASSERT.that(Multisets.difference(ms1, ms2)).has().allOf("a", "b");
+ }
+
+ public void testDifferenceWithRemovedElement() {
+ Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ Multiset<String> ms2 = HashMultiset.create(Arrays.asList("b"));
+ ASSERT.that(Multisets.difference(ms1, ms2)).has().allOf("a", "a");
+ }
+
+ public void testDifferenceWithMoreElementsInSecondMultiset() {
+ Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "b", "b"));
+ Multiset<String> diff = Multisets.difference(ms1, ms2);
+ ASSERT.that(diff).has().item("a");
+ assertEquals(0, diff.count("b"));
+ assertEquals(1, diff.count("a"));
+ assertFalse(diff.contains("b"));
+ assertTrue(diff.contains("a"));
+ }
+
+ public void testDifferenceEmptyNonempty() {
+ Multiset<String> ms1 = HashMultiset.create();
+ Multiset<String> ms2 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ assertEquals(ms1, Multisets.difference(ms1, ms2));
+ }
+
+ public void testDifferenceNonemptyEmpty() {
+ Multiset<String> ms1 = HashMultiset.create(Arrays.asList("a", "b", "a"));
+ Multiset<String> ms2 = HashMultiset.create();
+ assertEquals(ms1, Multisets.difference(ms1, ms2));
}
-
+
public void testContainsOccurrencesEmpty() {
Multiset<String> superMultiset = HashMultiset.create(Arrays.asList("a", "b", "a"));
Multiset<String> subMultiset = HashMultiset.create();
@@ -180,7 +190,7 @@ public class MultisetsTest extends TestCase {
assertFalse(Multisets.containsOccurrences(superMultiset, diffMultiset));
assertTrue(Multisets.containsOccurrences(diffMultiset, subMultiset));
}
-
+
public void testRetainEmptyOccurrences() {
Multiset<String> multiset =
HashMultiset.create(Arrays.asList("a", "b", "a"));
@@ -195,7 +205,7 @@ public class MultisetsTest extends TestCase {
Multiset<String> toRetain =
HashMultiset.create(Arrays.asList("a", "b", "b"));
assertTrue(Multisets.retainOccurrences(multiset, toRetain));
- ASSERT.that(multiset).hasContentsInOrder("a", "b");
+ ASSERT.that(multiset).has().allOf("a", "b").inOrder();
}
public void testRemoveEmptyOccurrences() {
@@ -203,7 +213,7 @@ public class MultisetsTest extends TestCase {
TreeMultiset.create(Arrays.asList("a", "b", "a"));
Multiset<String> toRemove = HashMultiset.create();
assertFalse(Multisets.removeOccurrences(multiset, toRemove));
- ASSERT.that(multiset).hasContentsInOrder("a", "a", "b");
+ ASSERT.that(multiset).has().allOf("a", "a", "b").inOrder();
}
public void testRemoveOccurrences() {
@@ -212,11 +222,11 @@ public class MultisetsTest extends TestCase {
Multiset<String> toRemove =
HashMultiset.create(Arrays.asList("a", "b", "b"));
assertTrue(Multisets.removeOccurrences(multiset, toRemove));
- ASSERT.that(multiset).hasContentsInOrder("a", "c");
+ ASSERT.that(multiset).has().allOf("a", "c").inOrder();
}
@SuppressWarnings("deprecation")
- public void testUnmodifiableMultisetShortCircuit(){
+ public void testUnmodifiableMultisetShortCircuit() {
Multiset<String> mod = HashMultiset.create();
Multiset<String> unmod = Multisets.unmodifiableMultiset(mod);
assertNotSame(mod, unmod);
@@ -225,32 +235,30 @@ public class MultisetsTest extends TestCase {
assertSame(immutable, Multisets.unmodifiableMultiset(immutable));
assertSame(immutable, Multisets.unmodifiableMultiset((Multiset<String>) immutable));
}
-
+
public void testHighestCountFirst() {
Multiset<String> multiset = HashMultiset.create(
Arrays.asList("a", "a", "a", "b", "c", "c"));
- ImmutableMultiset<String> sortedMultiset =
+ ImmutableMultiset<String> sortedMultiset =
Multisets.copyHighestCountFirst(multiset);
- ASSERT.that(sortedMultiset.entrySet()).hasContentsInOrder(
+ ASSERT.that(sortedMultiset.entrySet()).has().allOf(
Multisets.immutableEntry("a", 3), Multisets.immutableEntry("c", 2),
- Multisets.immutableEntry("b", 1));
+ Multisets.immutableEntry("b", 1)).inOrder();
- ASSERT.that(sortedMultiset).hasContentsInOrder(
+ ASSERT.that(sortedMultiset).has().allOf(
"a",
"a",
"a",
"c",
"c",
- "b");
-
+ "b").inOrder();
+
ASSERT.that(Multisets.copyHighestCountFirst(ImmutableMultiset.of())).isEmpty();
}
-
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Multiset.class, ImmutableMultiset.of());
- tester.testAllPublicStaticMethods(Multisets.class);
+ public void testNullPointers() {
+ new NullPointerTester().testAllPublicStaticMethods(Multisets.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/NewCustomTableTest.java b/guava-tests/test/com/google/common/collect/NewCustomTableTest.java
index a491b71..21ef378 100644
--- a/guava-tests/test/com/google/common/collect/NewCustomTableTest.java
+++ b/guava-tests/test/com/google/common/collect/NewCustomTableTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Supplier;
@@ -51,11 +51,11 @@ public class NewCustomTableTest extends AbstractTableTest {
public void testRowKeySetOrdering() {
table = create("foo", 3, 'a', "bar", 1, 'b', "foo", 2, 'c');
- ASSERT.that(table.rowKeySet()).hasContentsInOrder("foo", "bar");
+ ASSERT.that(table.rowKeySet()).has().allOf("foo", "bar").inOrder();
}
public void testRowOrdering() {
table = create("foo", 3, 'a', "bar", 1, 'b', "foo", 2, 'c');
- ASSERT.that(table.row("foo").keySet()).hasContentsInOrder(2, 3);
+ ASSERT.that(table.row("foo").keySet()).has().allOf(2, 3).inOrder();
}
}
diff --git a/guava-tests/test/com/google/common/collect/ObjectArraysTest.java b/guava-tests/test/com/google/common/collect/ObjectArraysTest.java
index 8fa1009..030895c 100644
--- a/guava-tests/test/com/google/common/collect/ObjectArraysTest.java
+++ b/guava-tests/test/com/google/common/collect/ObjectArraysTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -37,7 +37,7 @@ import java.util.List;
public class ObjectArraysTest extends TestCase {
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(ObjectArrays.class);
}
@@ -98,7 +98,7 @@ public class ObjectArraysTest extends TestCase {
String[] result = ObjectArrays.concat(
new String[0], new String[] { "a", "b" }, String.class);
assertEquals(String[].class, result.getClass());
- ASSERT.that(result).hasContentsInOrder("a", "b");
+ ASSERT.that(result).has().allOf("a", "b").inOrder();
}
@GwtIncompatible("ObjectArrays.concat(Object[], Object[], Class)")
@@ -106,7 +106,7 @@ public class ObjectArraysTest extends TestCase {
String[] result = ObjectArrays.concat(
new String[] { "a", "b" }, new String[0], String.class);
assertEquals(String[].class, result.getClass());
- ASSERT.that(result).hasContentsInOrder("a", "b");
+ ASSERT.that(result).has().allOf("a", "b").inOrder();
}
@GwtIncompatible("ObjectArrays.concat(Object[], Object[], Class)")
@@ -114,7 +114,7 @@ public class ObjectArraysTest extends TestCase {
String[] result = ObjectArrays.concat(
new String[] { "a", "b" }, new String[] { "c", "d" }, String.class);
assertEquals(String[].class, result.getClass());
- ASSERT.that(result).hasContentsInOrder("a", "b", "c", "d");
+ ASSERT.that(result).has().allOf("a", "b", "c", "d").inOrder();
}
@GwtIncompatible("ObjectArrays.concat(Object[], Object[], Class)")
@@ -170,31 +170,81 @@ public class ObjectArraysTest extends TestCase {
public void testPrependZeroElements() {
String[] result = ObjectArrays.concat("foo", new String[] {});
- ASSERT.that(result).hasContentsInOrder("foo");
+ ASSERT.that(result).has().item("foo");
}
public void testPrependOneElement() {
- String[] result = ObjectArrays.concat("foo", new String[]{ "bar" });
- ASSERT.that(result).hasContentsInOrder("foo", "bar");
+ String[] result = ObjectArrays.concat("foo", new String[] { "bar" });
+ ASSERT.that(result).has().allOf("foo", "bar").inOrder();
}
public void testPrependTwoElements() {
- String[] result = ObjectArrays.concat("foo", new String[]{ "bar", "baz" });
- ASSERT.that(result).hasContentsInOrder("foo", "bar", "baz");
+ String[] result = ObjectArrays.concat("foo", new String[] { "bar", "baz" });
+ ASSERT.that(result).has().allOf("foo", "bar", "baz").inOrder();
}
public void testAppendZeroElements() {
String[] result = ObjectArrays.concat(new String[] {}, "foo");
- ASSERT.that(result).hasContentsInOrder("foo");
+ ASSERT.that(result).has().item("foo");
}
public void testAppendOneElement() {
- String[] result = ObjectArrays.concat(new String[]{ "foo" }, "bar");
- ASSERT.that(result).hasContentsInOrder("foo", "bar");
+ String[] result = ObjectArrays.concat(new String[] { "foo" }, "bar");
+ ASSERT.that(result).has().allOf("foo", "bar").inOrder();
}
public void testAppendTwoElements() {
- String[] result = ObjectArrays.concat(new String[]{ "foo", "bar" }, "baz");
- ASSERT.that(result).hasContentsInOrder("foo", "bar", "baz");
+ String[] result = ObjectArrays.concat(new String[] { "foo", "bar" }, "baz");
+ ASSERT.that(result).has().allOf("foo", "bar", "baz").inOrder();
+ }
+
+ public void testEmptyArrayToEmpty() {
+ doTestNewArrayEquals(new Object[0], 0);
+ }
+
+ public void testEmptyArrayToNonEmpty() {
+ checkArrayEquals(new Long[5], ObjectArrays.newArray(new Long[0], 5));
+ }
+
+ public void testNonEmptyToShorter() {
+ checkArrayEquals(new String[9], ObjectArrays.newArray(new String[10], 9));
+ }
+
+ public void testNonEmptyToSameLength() {
+ doTestNewArrayEquals(new String[10], 10);
+ }
+
+ public void testNonEmptyToLonger() {
+ checkArrayEquals(new String[10],
+ ObjectArrays.newArray(new String[] { "a", "b", "c", "d", "e" }, 10));
+ }
+
+ public void testCloneEmptyArray() {
+ checkArrayEquals(new String[0], Platform.clone(new String[0]));
+ }
+
+ public void testCloneSingletonArray() {
+ checkArrayEquals(
+ new String[] { "a" }, Platform.clone(new String[] { "a" }));
+ }
+
+ public void testCloneMultipleElementArray() {
+ checkArrayEquals(
+ new String[] { "a", "b", "c" }, Platform.clone(new String[] { "a", "b", "c" }));
+ }
+
+ private static void checkArrayEquals(Object[] expected, Object[] actual) {
+ assertTrue("expected(" + expected.getClass() + "): " + Arrays.toString(expected)
+ + " actual(" + actual.getClass() + "): " + Arrays.toString(actual),
+ arrayEquals(expected, actual));
+ }
+
+ private static boolean arrayEquals(Object[] array1, Object[] array2) {
+ assertSame(array1.getClass(), array2.getClass());
+ return Arrays.equals(array1, array2);
+ }
+
+ private static void doTestNewArrayEquals(Object[] expected, int length) {
+ checkArrayEquals(expected, ObjectArrays.newArray(expected, length));
}
}
diff --git a/guava-tests/test/com/google/common/collect/OrderingTest.java b/guava-tests/test/com/google/common/collect/OrderingTest.java
index 142c8b9..e3450a0 100644
--- a/guava-tests/test/com/google/common/collect/OrderingTest.java
+++ b/guava-tests/test/com/google/common/collect/OrderingTest.java
@@ -16,11 +16,12 @@
package com.google.common.collect;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.testing.SerializableTester.reserialize;
import static com.google.common.testing.SerializableTester.reserializeAndAssert;
import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -55,6 +56,21 @@ public class OrderingTest extends TestCase {
private final Ordering<Number> numberOrdering = new NumberOrdering();
+ public void testAllEqual() {
+ Ordering<Object> comparator = Ordering.allEqual();
+ assertSame(comparator, comparator.reverse());
+
+ assertEquals(comparator.compare(null, null), 0);
+ assertEquals(comparator.compare(new Object(), new Object()), 0);
+ assertEquals(comparator.compare("apples", "oranges"), 0);
+ assertSame(comparator, reserialize(comparator));
+ assertEquals("Ordering.allEqual()", comparator.toString());
+
+ List<String> strings = ImmutableList.of("b", "a", "d", "c");
+ assertEquals(strings, comparator.sortedCopy(strings));
+ assertEquals(strings, comparator.immutableSortedCopy(strings));
+ }
+
public void testNatural() {
Ordering<Integer> comparator = Ordering.natural();
Helpers.testComparator(comparator,
@@ -140,7 +156,7 @@ public class OrderingTest extends TestCase {
= Ordering.explicit(2, 8, 6, 1, 7, 5, 3, 4, 0, 9);
List<Integer> list = Arrays.asList(0, 3, 5, 6, 7, 8, 9);
Collections.sort(list, c);
- ASSERT.that(list).hasContentsInOrder(8, 6, 7, 5, 3, 0, 9);
+ ASSERT.that(list).has().allOf(8, 6, 7, 5, 3, 0, 9).inOrder();
reserializeAndAssert(c);
}
@@ -224,7 +240,7 @@ public class OrderingTest extends TestCase {
}
public void testCompound_static() {
- Comparator<String> comparator = Ordering.compound(asList(
+ Comparator<String> comparator = Ordering.compound(ImmutableList.of(
byCharAt(0), byCharAt(1), byCharAt(2),
byCharAt(3), byCharAt(4), byCharAt(5)));
Helpers.testComparator(comparator, ImmutableList.of(
@@ -370,16 +386,34 @@ public class OrderingTest extends TestCase {
ImmutableList<String> b = ImmutableList.of("b");
Helpers.testComparator(lexy, empty, a, aa, ab, b);
+
+ new EqualsTester()
+ .addEqualityGroup(lexy, ordering.lexicographical())
+ .addEqualityGroup(numberOrdering.lexicographical())
+ .addEqualityGroup(Ordering.natural())
+ .testEquals();
}
public void testNullsFirst() {
Ordering<Integer> ordering = Ordering.natural().nullsFirst();
Helpers.testComparator(ordering, null, Integer.MIN_VALUE, 0, 1);
+
+ new EqualsTester()
+ .addEqualityGroup(ordering, Ordering.natural().nullsFirst())
+ .addEqualityGroup(numberOrdering.nullsFirst())
+ .addEqualityGroup(Ordering.natural())
+ .testEquals();
}
public void testNullsLast() {
Ordering<Integer> ordering = Ordering.natural().nullsLast();
Helpers.testComparator(ordering, 0, 1, Integer.MAX_VALUE, null);
+
+ new EqualsTester()
+ .addEqualityGroup(ordering, Ordering.natural().nullsLast())
+ .addEqualityGroup(numberOrdering.nullsLast())
+ .addEqualityGroup(Ordering.natural())
+ .testEquals();
}
public void testBinarySearch() {
@@ -436,21 +470,37 @@ public class OrderingTest extends TestCase {
Collections.<Integer>emptyList()));
}
- public void testLeastOf_emptyList_0() {
+ public void testLeastOfIterable_empty_0() {
List<Integer> result = numberOrdering.leastOf(Arrays.<Integer>asList(), 0);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.<Integer>of(), result);
}
- public void testLeastOf_emptyList_1() {
+ public void testLeastOfIterator_empty_0() {
+ List<Integer> result = numberOrdering.leastOf(
+ Iterators.<Integer>emptyIterator(), 0);
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(ImmutableList.<Integer>of(), result);
+ }
+
+ public void testLeastOfIterable_empty_1() {
List<Integer> result = numberOrdering.leastOf(Arrays.<Integer>asList(), 1);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.<Integer>of(), result);
}
- public void testLeastOf_simple_negativeOne() {
+ public void testLeastOfIterator_empty_1() {
+ List<Integer> result = numberOrdering.leastOf(
+ Iterators.<Integer>emptyIterator(), 1);
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(ImmutableList.<Integer>of(), result);
+ }
+
+ public void testLeastOfIterable_simple_negativeOne() {
try {
numberOrdering.leastOf(Arrays.asList(3, 4, 5, -1), -1);
fail();
@@ -458,28 +508,76 @@ public class OrderingTest extends TestCase {
}
}
- public void testLeastOf_singletonList_0() {
+ public void testLeastOfIterator_simple_negativeOne() {
+ try {
+ numberOrdering.leastOf(Iterators.forArray(3, 4, 5, -1), -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testLeastOfIterable_singleton_0() {
List<Integer> result = numberOrdering.leastOf(Arrays.asList(3), 0);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.<Integer>of(), result);
}
- public void testLeastOf_simple_0() {
+ public void testLeastOfIterator_singleton_0() {
+ List<Integer> result = numberOrdering.leastOf(
+ Iterators.singletonIterator(3), 0);
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(ImmutableList.<Integer>of(), result);
+ }
+
+ public void testLeastOfIterable_simple_0() {
List<Integer> result = numberOrdering.leastOf(Arrays.asList(3, 4, 5, -1), 0);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.<Integer>of(), result);
}
- public void testLeastOf_simple_1() {
+ public void testLeastOfIterator_simple_0() {
+ List<Integer> result = numberOrdering.leastOf(
+ Iterators.forArray(3, 4, 5, -1), 0);
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(ImmutableList.<Integer>of(), result);
+ }
+
+ public void testLeastOfIterable_simple_1() {
List<Integer> result = numberOrdering.leastOf(Arrays.asList(3, 4, 5, -1), 1);
assertTrue(result instanceof RandomAccess);
assertListImmutable(result);
assertEquals(ImmutableList.of(-1), result);
}
- public void testLeastOf_simple_nMinusOne() {
+ public void testLeastOfIterator_simple_1() {
+ List<Integer> result = numberOrdering.leastOf(
+ Iterators.forArray(3, 4, 5, -1), 1);
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(ImmutableList.of(-1), result);
+ }
+
+ public void testLeastOfIterable_simple_nMinusOne_withNullElement() {
+ List<Integer> list = Arrays.asList(3, null, 5, -1);
+ List<Integer> result = Ordering.natural().nullsLast().leastOf(list, list.size() - 1);
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(ImmutableList.of(-1, 3, 5), result);
+ }
+
+ public void testLeastOfIterator_simple_nMinusOne_withNullElement() {
+ Iterator<Integer> itr = Iterators.forArray(3, null, 5, -1);
+ List<Integer> result = Ordering.natural().nullsLast().leastOf(itr, 3);
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(ImmutableList.of(-1, 3, 5), result);
+ }
+
+ public void testLeastOfIterable_simple_nMinusOne() {
List<Integer> list = Arrays.asList(3, 4, 5, -1);
List<Integer> result = numberOrdering.leastOf(list, list.size() - 1);
assertTrue(result instanceof RandomAccess);
@@ -487,7 +585,15 @@ public class OrderingTest extends TestCase {
assertEquals(ImmutableList.of(-1, 3, 4), result);
}
- public void testLeastOf_simple_n() {
+ public void testLeastOfIterator_simple_nMinusOne() {
+ List<Integer> list = Arrays.asList(3, 4, 5, -1);
+ List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size() - 1);
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(ImmutableList.of(-1, 3, 4), result);
+ }
+
+ public void testLeastOfIterable_simple_n() {
List<Integer> list = Arrays.asList(3, 4, 5, -1);
List<Integer> result = numberOrdering.leastOf(list, list.size());
assertTrue(result instanceof RandomAccess);
@@ -495,7 +601,32 @@ public class OrderingTest extends TestCase {
assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
}
- public void testLeastOf_simple_nPlusOne() {
+ public void testLeastOfIterator_simple_n() {
+ List<Integer> list = Arrays.asList(3, 4, 5, -1);
+ List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size());
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
+ }
+
+ public void testLeastOfIterable_simple_n_withNullElement() {
+ List<Integer> list = Arrays.asList(3, 4, 5, null, -1);
+ List<Integer> result = Ordering.natural().nullsLast().leastOf(list, list.size());
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(Arrays.asList(-1, 3, 4, 5, null), result);
+ }
+
+ public void testLeastOfIterator_simple_n_withNullElement() {
+ List<Integer> list = Arrays.asList(3, 4, 5, null, -1);
+ List<Integer> result = Ordering.natural().nullsLast().leastOf(
+ list.iterator(), list.size());
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(Arrays.asList(-1, 3, 4, 5, null), result);
+ }
+
+ public void testLeastOfIterable_simple_nPlusOne() {
List<Integer> list = Arrays.asList(3, 4, 5, -1);
List<Integer> result = numberOrdering.leastOf(list, list.size() + 1);
assertTrue(result instanceof RandomAccess);
@@ -503,7 +634,15 @@ public class OrderingTest extends TestCase {
assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
}
- public void testLeastOf_ties() {
+ public void testLeastOfIterator_simple_nPlusOne() {
+ List<Integer> list = Arrays.asList(3, 4, 5, -1);
+ List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size() + 1);
+ assertTrue(result instanceof RandomAccess);
+ assertListImmutable(result);
+ assertEquals(ImmutableList.of(-1, 3, 4, 5), result);
+ }
+
+ public void testLeastOfIterable_ties() {
Integer foo = new Integer(Integer.MAX_VALUE - 10);
Integer bar = new Integer(Integer.MAX_VALUE - 10);
@@ -515,6 +654,18 @@ public class OrderingTest extends TestCase {
assertEquals(ImmutableList.of(-1, 3, foo, bar), result);
}
+ public void testLeastOfIterator_ties() {
+ Integer foo = new Integer(Integer.MAX_VALUE - 10);
+ Integer bar = new Integer(Integer.MAX_VALUE - 10);
+
+ assertNotSame(foo, bar);
+ assertEquals(foo, bar);
+
+ List<Integer> list = Arrays.asList(3, foo, bar, -1);
+ List<Integer> result = numberOrdering.leastOf(list.iterator(), list.size());
+ assertEquals(ImmutableList.of(-1, 3, foo, bar), result);
+ }
+
@GwtIncompatible("slow")
public void testLeastOf_reconcileAgainstSortAndSublist() {
runLeastOfComparison(1000, 300, 20);
@@ -543,7 +694,19 @@ public class OrderingTest extends TestCase {
}
}
- public void testGreatestOf_simple() {
+ public void testLeastOfIterableLargeK() {
+ List<Integer> list = Arrays.asList(4, 2, 3, 5, 1);
+ assertEquals(Arrays.asList(1, 2, 3, 4, 5), Ordering.natural()
+ .leastOf(list, Integer.MAX_VALUE));
+ }
+
+ public void testLeastOfIteratorLargeK() {
+ List<Integer> list = Arrays.asList(4, 2, 3, 5, 1);
+ assertEquals(Arrays.asList(1, 2, 3, 4, 5), Ordering.natural()
+ .leastOf(list.iterator(), Integer.MAX_VALUE));
+ }
+
+ public void testGreatestOfIterable_simple() {
/*
* If greatestOf() promised to be implemented as reverse().leastOf(), this
* test would be enough. It doesn't... but we'll cheat and act like it does
@@ -553,6 +716,17 @@ public class OrderingTest extends TestCase {
assertEquals(Arrays.asList(4, 4, 3, 3), numberOrdering.greatestOf(list, 4));
}
+ public void testGreatestOfIterator_simple() {
+ /*
+ * If greatestOf() promised to be implemented as reverse().leastOf(), this
+ * test would be enough. It doesn't... but we'll cheat and act like it does
+ * anyway. There's a comment there to remind us to fix this if we change it.
+ */
+ List<Integer> list = Arrays.asList(3, 1, 3, 2, 4, 2, 4, 3);
+ assertEquals(Arrays.asList(4, 4, 3, 3),
+ numberOrdering.greatestOf(list.iterator(), 4));
+ }
+
private static void assertListImmutable(List<Integer> result) {
try {
result.set(0, 1);
@@ -659,32 +833,48 @@ public class OrderingTest extends TestCase {
private static final int RECURSE_DEPTH = 2;
public void testCombinationsExhaustively_startingFromNatural() {
- testExhaustively(Ordering.<String>natural(), Arrays.asList("a", "b"));
+ testExhaustively(Ordering.<String>natural(), "a", "b", "d");
}
public void testCombinationsExhaustively_startingFromExplicit() {
testExhaustively(Ordering.explicit("a", "b", "c", "d"),
- Arrays.asList("b", "d"));
+ "a", "b", "d");
}
public void testCombinationsExhaustively_startingFromUsingToString() {
- testExhaustively(Ordering.usingToString(), Arrays.asList(1, 12, 2));
+ testExhaustively(Ordering.usingToString(), 1, 12, 2);
+ }
+
+ public void testCombinationsExhaustively_startingFromFromComparator() {
+ testExhaustively(Ordering.from(String.CASE_INSENSITIVE_ORDER),
+ "A", "b", "C", "d");
}
public void testCombinationsExhaustively_startingFromArbitrary() {
Ordering<Object> arbitrary = Ordering.arbitrary();
- List<Object> list = Arrays.asList(1, "foo", new Object());
+ Object[] array = {1, "foo", new Object()};
// There's no way to tell what the order should be except empirically
- Collections.sort(list, arbitrary);
- testExhaustively(arbitrary, list);
+ Arrays.sort(array, arbitrary);
+ testExhaustively(arbitrary, array);
}
+ /**
+ * Requires at least 3 elements in {@code strictlyOrderedElements} in order to
+ * test the varargs version of min/max.
+ */
private static <T> void testExhaustively(
- Ordering<? super T> ordering, List<T> list) {
+ Ordering<? super T> ordering, T... strictlyOrderedElements) {
+ checkArgument(strictlyOrderedElements.length >= 3, "strictlyOrderedElements "
+ + "requires at least 3 elements");
+ List<T> list = Arrays.asList(strictlyOrderedElements);
+
+ // for use calling Collection.toArray later
+ T[] emptyArray = Platform.newArray(strictlyOrderedElements, 0);
+
// shoot me, but I didn't want to deal with wildcards through the whole test
@SuppressWarnings("unchecked")
- Scenario<T> starter = new Scenario<T>((Ordering) ordering, list);
+ Scenario<T> starter = new Scenario<T>((Ordering) ordering, list, emptyArray);
verifyScenario(starter, 0);
}
@@ -693,6 +883,7 @@ public class OrderingTest extends TestCase {
scenario.testIsOrdered();
scenario.testMinAndMax();
scenario.testBinarySearch();
+ scenario.testSortedCopy();
if (level < RECURSE_DEPTH) {
for (OrderingMutation alteration : OrderingMutation.values()) {
@@ -708,10 +899,12 @@ public class OrderingTest extends TestCase {
private static class Scenario<T> {
final Ordering<T> ordering;
final List<T> strictlyOrderedList;
+ final T[] emptyArray;
- Scenario(Ordering<T> ordering, List<T> strictlyOrderedList) {
+ Scenario(Ordering<T> ordering, List<T> strictlyOrderedList, T[] emptyArray) {
this.ordering = ordering;
this.strictlyOrderedList = strictlyOrderedList;
+ this.emptyArray = emptyArray;
}
void testCompareTo() {
@@ -723,13 +916,30 @@ public class OrderingTest extends TestCase {
assertTrue(ordering.isStrictlyOrdered(strictlyOrderedList));
}
+ @SuppressWarnings("unchecked") // generic arrays and unchecked cast
void testMinAndMax() {
List<T> shuffledList = Lists.newArrayList(strictlyOrderedList);
shuffledList = shuffledCopy(shuffledList, new Random(5));
- assertEquals(strictlyOrderedList.get(0), ordering.min(shuffledList));
- assertEquals(strictlyOrderedList.get(strictlyOrderedList.size() - 1),
- ordering.max(shuffledList));
+ T min = strictlyOrderedList.get(0);
+ T max = strictlyOrderedList.get(strictlyOrderedList.size() - 1);
+
+ T first = shuffledList.get(0);
+ T second = shuffledList.get(1);
+ T third = shuffledList.get(2);
+ T[] rest = shuffledList.subList(3, shuffledList.size()).toArray(emptyArray);
+
+ assertEquals(min, ordering.min(shuffledList));
+ assertEquals(min, ordering.min(shuffledList.iterator()));
+ assertEquals(min, ordering.min(first, second, third, rest));
+ assertEquals(min, ordering.min(min, max));
+ assertEquals(min, ordering.min(max, min));
+
+ assertEquals(max, ordering.max(shuffledList));
+ assertEquals(max, ordering.max(shuffledList.iterator()));
+ assertEquals(max, ordering.max(first, second, third, rest));
+ assertEquals(max, ordering.max(min, max));
+ assertEquals(max, ordering.max(max, min));
}
void testBinarySearch() {
@@ -741,6 +951,17 @@ public class OrderingTest extends TestCase {
T valueNotInList = newList.remove(1);
assertEquals(-2, ordering.binarySearch(newList, valueNotInList));
}
+
+ void testSortedCopy() {
+ List<T> shuffledList = Lists.newArrayList(strictlyOrderedList);
+ shuffledList = shuffledCopy(shuffledList, new Random(5));
+
+ assertEquals(strictlyOrderedList, ordering.sortedCopy(shuffledList));
+
+ if (!strictlyOrderedList.contains(null)) {
+ assertEquals(strictlyOrderedList, ordering.immutableSortedCopy(shuffledList));
+ }
+ }
}
/**
@@ -754,7 +975,7 @@ public class OrderingTest extends TestCase {
@Override <T> Scenario<?> mutate(Scenario<T> scenario) {
List<T> newList = Lists.newArrayList(scenario.strictlyOrderedList);
Collections.reverse(newList);
- return new Scenario<T>(scenario.ordering.reverse(), newList);
+ return new Scenario<T>(scenario.ordering.reverse(), newList, scenario.emptyArray);
}
},
NULLS_FIRST {
@@ -766,7 +987,7 @@ public class OrderingTest extends TestCase {
newList.add(t);
}
}
- return new Scenario<T>(scenario.ordering.nullsFirst(), newList);
+ return new Scenario<T>(scenario.ordering.nullsFirst(), newList, scenario.emptyArray);
}
},
NULLS_LAST {
@@ -778,7 +999,7 @@ public class OrderingTest extends TestCase {
}
}
newList.add(null);
- return new Scenario<T>(scenario.ordering.nullsLast(), newList);
+ return new Scenario<T>(scenario.ordering.nullsLast(), newList, scenario.emptyArray);
}
},
ON_RESULT_OF {
@@ -794,10 +1015,11 @@ public class OrderingTest extends TestCase {
for (int i = 0; i < scenario.strictlyOrderedList.size(); i++) {
list.add(i);
}
- return new Scenario<Integer>(ordering, list);
+ return new Scenario<Integer>(ordering, list, new Integer[0]);
}
},
COMPOUND_THIS_WITH_NATURAL {
+ @SuppressWarnings("unchecked") // raw array
@Override <T> Scenario<?> mutate(Scenario<T> scenario) {
List<Composite<T>> composites = Lists.newArrayList();
for (T t : scenario.strictlyOrderedList) {
@@ -807,10 +1029,11 @@ public class OrderingTest extends TestCase {
Ordering<Composite<T>> ordering =
scenario.ordering.onResultOf(Composite.<T>getValueFunction())
.compound(Ordering.natural());
- return new Scenario<Composite<T>>(ordering, composites);
+ return new Scenario<Composite<T>>(ordering, composites, new Composite[0]);
}
},
COMPOUND_NATURAL_WITH_THIS {
+ @SuppressWarnings("unchecked") // raw array
@Override <T> Scenario<?> mutate(Scenario<T> scenario) {
List<Composite<T>> composites = Lists.newArrayList();
for (T t : scenario.strictlyOrderedList) {
@@ -821,7 +1044,7 @@ public class OrderingTest extends TestCase {
}
Ordering<Composite<T>> ordering = Ordering.natural().compound(
scenario.ordering.onResultOf(Composite.<T>getValueFunction()));
- return new Scenario<Composite<T>>(ordering, composites);
+ return new Scenario<Composite<T>>(ordering, composites, new Composite[0]);
}
},
LEXICOGRAPHICAL {
@@ -836,7 +1059,7 @@ public class OrderingTest extends TestCase {
}
}
return new Scenario<Iterable<T>>(
- scenario.ordering.lexicographical(), words);
+ scenario.ordering.lexicographical(), words, new Iterable[0]);
}
},
;
@@ -875,7 +1098,7 @@ public class OrderingTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Ordering.class);
diff --git a/guava-tests/test/com/google/common/collect/PackageSanityTests.java b/guava-tests/test/com/google/common/collect/PackageSanityTests.java
new file mode 100644
index 0000000..c847140
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/PackageSanityTests.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.testing.AbstractPackageSanityTests;
+
+/**
+ * Covers basic sanity checks for the entire package.
+ *
+ * @author Ben Yu
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {
+ public PackageSanityTests() {
+ publicApiOnly(); // Many package-private classes are tested through the public API.
+ setDefault(DiscreteDomain.class, DiscreteDomain.integers());
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/QueuesTest.java b/guava-tests/test/com/google/common/collect/QueuesTest.java
index bffcb39..d64caae 100644
--- a/guava-tests/test/com/google/common/collect/QueuesTest.java
+++ b/guava-tests/test/com/google/common/collect/QueuesTest.java
@@ -208,6 +208,17 @@ public class QueuesTest extends TestCase {
assertEquals(100, buf.size());
}
+ public void testNewLinkedBlockingDequeCapacity() {
+ try {
+ Queues.newLinkedBlockingDeque(0);
+ fail("Should have thrown IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // any capacity less than 1 should throw IllegalArgumentException
+ }
+ assertEquals(1, Queues.newLinkedBlockingDeque(1).remainingCapacity());
+ assertEquals(11, Queues.newLinkedBlockingDeque(11).remainingCapacity());
+ }
+
public void testNewLinkedBlockingQueueCapacity() {
try {
Queues.newLinkedBlockingQueue(0);
diff --git a/guava-tests/test/com/google/common/collect/RangeNonGwtTest.java b/guava-tests/test/com/google/common/collect/RangeNonGwtTest.java
index 7b1d297..7828f64 100644
--- a/guava-tests/test/com/google/common/collect/RangeNonGwtTest.java
+++ b/guava-tests/test/com/google/common/collect/RangeNonGwtTest.java
@@ -28,16 +28,14 @@ import junit.framework.TestCase;
*/
public class RangeNonGwtTest extends TestCase {
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
- tester.setDefault(BoundType.class, BoundType.OPEN);
- tester.setDefault(Comparable.class, 0);
tester.testAllPublicStaticMethods(Range.class);
- tester.testAllPublicStaticMethods(Ranges.class);
+ tester.testAllPublicStaticMethods(Range.class);
- tester.testAllPublicInstanceMethods(Ranges.all());
- tester.testAllPublicInstanceMethods(Ranges.open(1, 3));
+ tester.testAllPublicInstanceMethods(Range.all());
+ tester.testAllPublicInstanceMethods(Range.open(1, 3));
}
}
diff --git a/guava-tests/test/com/google/common/collect/RangeTest.java b/guava-tests/test/com/google/common/collect/RangeTest.java
index 9b74b0e..8c30ae2 100644
--- a/guava-tests/test/com/google/common/collect/RangeTest.java
+++ b/guava-tests/test/com/google/common/collect/RangeTest.java
@@ -18,7 +18,7 @@ package com.google.common.collect;
import static com.google.common.collect.BoundType.CLOSED;
import static com.google.common.collect.BoundType.OPEN;
-import static com.google.common.collect.DiscreteDomains.integers;
+import static com.google.common.collect.DiscreteDomain.integers;
import static com.google.common.testing.SerializableTester.reserializeAndAssert;
import static java.util.Arrays.asList;
@@ -29,7 +29,10 @@ import com.google.common.testing.EqualsTester;
import junit.framework.TestCase;
+import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
+import java.util.NoSuchElementException;
/**
* Unit test for {@link Range}.
@@ -39,7 +42,7 @@ import java.util.Collections;
@GwtCompatible
public class RangeTest extends TestCase {
public void testOpen() {
- Range<Integer> range = Ranges.open(4, 8);
+ Range<Integer> range = Range.open(4, 8);
checkContains(range);
assertTrue(range.hasLowerBound());
assertEquals(4, (int) range.lowerEndpoint());
@@ -54,19 +57,19 @@ public class RangeTest extends TestCase {
public void testOpen_invalid() {
try {
- Ranges.open(4, 3);
+ Range.open(4, 3);
fail();
} catch (IllegalArgumentException expected) {
}
try {
- Ranges.open(3, 3);
+ Range.open(3, 3);
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testClosed() {
- Range<Integer> range = Ranges.closed(5, 7);
+ Range<Integer> range = Range.closed(5, 7);
checkContains(range);
assertTrue(range.hasLowerBound());
assertEquals(5, (int) range.lowerEndpoint());
@@ -81,14 +84,14 @@ public class RangeTest extends TestCase {
public void testClosed_invalid() {
try {
- Ranges.closed(4, 3);
+ Range.closed(4, 3);
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testOpenClosed() {
- Range<Integer> range = Ranges.openClosed(4, 7);
+ Range<Integer> range = Range.openClosed(4, 7);
checkContains(range);
assertTrue(range.hasLowerBound());
assertEquals(4, (int) range.lowerEndpoint());
@@ -102,7 +105,7 @@ public class RangeTest extends TestCase {
}
public void testClosedOpen() {
- Range<Integer> range = Ranges.closedOpen(5, 8);
+ Range<Integer> range = Range.closedOpen(5, 8);
checkContains(range);
assertTrue(range.hasLowerBound());
assertEquals(5, (int) range.lowerEndpoint());
@@ -116,13 +119,13 @@ public class RangeTest extends TestCase {
}
public void testIsConnected() {
- assertTrue(Ranges.closed(3, 5).isConnected(Ranges.open(5, 6)));
- assertTrue(Ranges.closed(3, 5).isConnected(Ranges.openClosed(5, 5)));
- assertTrue(Ranges.open(3, 5).isConnected(Ranges.closed(5, 6)));
- assertTrue(Ranges.closed(3, 7).isConnected(Ranges.open(6, 8)));
- assertTrue(Ranges.open(3, 7).isConnected(Ranges.closed(5, 6)));
- assertFalse(Ranges.closed(3, 5).isConnected(Ranges.closed(7, 8)));
- assertFalse(Ranges.closed(3, 5).isConnected(Ranges.closedOpen(7, 7)));
+ assertTrue(Range.closed(3, 5).isConnected(Range.open(5, 6)));
+ assertTrue(Range.closed(3, 5).isConnected(Range.openClosed(5, 5)));
+ assertTrue(Range.open(3, 5).isConnected(Range.closed(5, 6)));
+ assertTrue(Range.closed(3, 7).isConnected(Range.open(6, 8)));
+ assertTrue(Range.open(3, 7).isConnected(Range.closed(5, 6)));
+ assertFalse(Range.closed(3, 5).isConnected(Range.closed(7, 8)));
+ assertFalse(Range.closed(3, 5).isConnected(Range.closedOpen(7, 7)));
}
private static void checkContains(Range<Integer> range) {
@@ -133,7 +136,7 @@ public class RangeTest extends TestCase {
}
public void testSingleton() {
- Range<Integer> range = Ranges.closed(4, 4);
+ Range<Integer> range = Range.closed(4, 4);
assertFalse(range.contains(3));
assertTrue(range.contains(4));
assertFalse(range.contains(5));
@@ -149,7 +152,7 @@ public class RangeTest extends TestCase {
}
public void testEmpty1() {
- Range<Integer> range = Ranges.closedOpen(4, 4);
+ Range<Integer> range = Range.closedOpen(4, 4);
assertFalse(range.contains(3));
assertFalse(range.contains(4));
assertFalse(range.contains(5));
@@ -165,7 +168,7 @@ public class RangeTest extends TestCase {
}
public void testEmpty2() {
- Range<Integer> range = Ranges.openClosed(4, 4);
+ Range<Integer> range = Range.openClosed(4, 4);
assertFalse(range.contains(3));
assertFalse(range.contains(4));
assertFalse(range.contains(5));
@@ -181,7 +184,7 @@ public class RangeTest extends TestCase {
}
public void testLessThan() {
- Range<Integer> range = Ranges.lessThan(5);
+ Range<Integer> range = Range.lessThan(5);
assertTrue(range.contains(Integer.MIN_VALUE));
assertTrue(range.contains(4));
assertFalse(range.contains(5));
@@ -195,7 +198,7 @@ public class RangeTest extends TestCase {
}
public void testGreaterThan() {
- Range<Integer> range = Ranges.greaterThan(5);
+ Range<Integer> range = Range.greaterThan(5);
assertFalse(range.contains(5));
assertTrue(range.contains(6));
assertTrue(range.contains(Integer.MAX_VALUE));
@@ -209,7 +212,7 @@ public class RangeTest extends TestCase {
}
public void testAtLeast() {
- Range<Integer> range = Ranges.atLeast(6);
+ Range<Integer> range = Range.atLeast(6);
assertFalse(range.contains(5));
assertTrue(range.contains(6));
assertTrue(range.contains(Integer.MAX_VALUE));
@@ -223,7 +226,7 @@ public class RangeTest extends TestCase {
}
public void testAtMost() {
- Range<Integer> range = Ranges.atMost(4);
+ Range<Integer> range = Range.atMost(4);
assertTrue(range.contains(Integer.MIN_VALUE));
assertTrue(range.contains(4));
assertFalse(range.contains(5));
@@ -237,14 +240,15 @@ public class RangeTest extends TestCase {
}
public void testAll() {
- Range<Integer> range = Ranges.all();
+ Range<Integer> range = Range.all();
assertTrue(range.contains(Integer.MIN_VALUE));
assertTrue(range.contains(Integer.MAX_VALUE));
assertUnboundedBelow(range);
assertUnboundedAbove(range);
assertFalse(range.isEmpty());
assertEquals("(-\u221e\u2025+\u221e)", range.toString());
- reserializeAndAssert(range);
+ assertSame(range, reserializeAndAssert(range));
+ assertSame(range, Range.all());
}
private static void assertUnboundedBelow(Range<Integer> range) {
@@ -276,18 +280,18 @@ public class RangeTest extends TestCase {
}
public void testOrderingCuts() {
- Cut<Integer> a = Ranges.lessThan(0).lowerBound;
- Cut<Integer> b = Ranges.atLeast(0).lowerBound;
- Cut<Integer> c = Ranges.greaterThan(0).lowerBound;
- Cut<Integer> d = Ranges.atLeast(1).lowerBound;
- Cut<Integer> e = Ranges.greaterThan(1).lowerBound;
- Cut<Integer> f = Ranges.greaterThan(1).upperBound;
+ Cut<Integer> a = Range.lessThan(0).lowerBound;
+ Cut<Integer> b = Range.atLeast(0).lowerBound;
+ Cut<Integer> c = Range.greaterThan(0).lowerBound;
+ Cut<Integer> d = Range.atLeast(1).lowerBound;
+ Cut<Integer> e = Range.greaterThan(1).lowerBound;
+ Cut<Integer> f = Range.greaterThan(1).upperBound;
Helpers.testCompareToAndEquals(ImmutableList.of(a, b, c, d, e, f));
}
public void testContainsAll() {
- Range<Integer> range = Ranges.closed(3, 5);
+ Range<Integer> range = Range.closed(3, 5);
assertTrue(range.containsAll(asList(3, 3, 4, 5)));
assertFalse(range.containsAll(asList(3, 3, 4, 5, 6)));
@@ -298,219 +302,219 @@ public class RangeTest extends TestCase {
assertTrue(range.containsAll(ImmutableSortedSet.<Integer>of()));
assertFalse(range.containsAll(ImmutableSortedSet.of(3, 3, 4, 5, 6)));
- assertTrue(Ranges.openClosed(3, 3).containsAll(
+ assertTrue(Range.openClosed(3, 3).containsAll(
Collections.<Integer>emptySet()));
}
public void testEncloses_open() {
- Range<Integer> range = Ranges.open(2, 5);
+ Range<Integer> range = Range.open(2, 5);
assertTrue(range.encloses(range));
- assertTrue(range.encloses(Ranges.open(2, 4)));
- assertTrue(range.encloses(Ranges.open(3, 5)));
- assertTrue(range.encloses(Ranges.closed(3, 4)));
+ assertTrue(range.encloses(Range.open(2, 4)));
+ assertTrue(range.encloses(Range.open(3, 5)));
+ assertTrue(range.encloses(Range.closed(3, 4)));
- assertFalse(range.encloses(Ranges.openClosed(2, 5)));
- assertFalse(range.encloses(Ranges.closedOpen(2, 5)));
- assertFalse(range.encloses(Ranges.closed(1, 4)));
- assertFalse(range.encloses(Ranges.closed(3, 6)));
- assertFalse(range.encloses(Ranges.greaterThan(3)));
- assertFalse(range.encloses(Ranges.lessThan(3)));
- assertFalse(range.encloses(Ranges.atLeast(3)));
- assertFalse(range.encloses(Ranges.atMost(3)));
- assertFalse(range.encloses(Ranges.<Integer>all()));
+ assertFalse(range.encloses(Range.openClosed(2, 5)));
+ assertFalse(range.encloses(Range.closedOpen(2, 5)));
+ assertFalse(range.encloses(Range.closed(1, 4)));
+ assertFalse(range.encloses(Range.closed(3, 6)));
+ assertFalse(range.encloses(Range.greaterThan(3)));
+ assertFalse(range.encloses(Range.lessThan(3)));
+ assertFalse(range.encloses(Range.atLeast(3)));
+ assertFalse(range.encloses(Range.atMost(3)));
+ assertFalse(range.encloses(Range.<Integer>all()));
}
public void testEncloses_closed() {
- Range<Integer> range = Ranges.closed(2, 5);
+ Range<Integer> range = Range.closed(2, 5);
assertTrue(range.encloses(range));
- assertTrue(range.encloses(Ranges.open(2, 5)));
- assertTrue(range.encloses(Ranges.openClosed(2, 5)));
- assertTrue(range.encloses(Ranges.closedOpen(2, 5)));
- assertTrue(range.encloses(Ranges.closed(3, 5)));
- assertTrue(range.encloses(Ranges.closed(2, 4)));
+ assertTrue(range.encloses(Range.open(2, 5)));
+ assertTrue(range.encloses(Range.openClosed(2, 5)));
+ assertTrue(range.encloses(Range.closedOpen(2, 5)));
+ assertTrue(range.encloses(Range.closed(3, 5)));
+ assertTrue(range.encloses(Range.closed(2, 4)));
- assertFalse(range.encloses(Ranges.open(1, 6)));
- assertFalse(range.encloses(Ranges.greaterThan(3)));
- assertFalse(range.encloses(Ranges.lessThan(3)));
- assertFalse(range.encloses(Ranges.atLeast(3)));
- assertFalse(range.encloses(Ranges.atMost(3)));
- assertFalse(range.encloses(Ranges.<Integer>all()));
+ assertFalse(range.encloses(Range.open(1, 6)));
+ assertFalse(range.encloses(Range.greaterThan(3)));
+ assertFalse(range.encloses(Range.lessThan(3)));
+ assertFalse(range.encloses(Range.atLeast(3)));
+ assertFalse(range.encloses(Range.atMost(3)));
+ assertFalse(range.encloses(Range.<Integer>all()));
}
public void testIntersection_empty() {
- Range<Integer> range = Ranges.closedOpen(3, 3);
+ Range<Integer> range = Range.closedOpen(3, 3);
assertEquals(range, range.intersection(range));
try {
- range.intersection(Ranges.open(3, 5));
+ range.intersection(Range.open(3, 5));
fail();
} catch (IllegalArgumentException expected) {
}
try {
- range.intersection(Ranges.closed(0, 2));
+ range.intersection(Range.closed(0, 2));
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testIntersection_deFactoEmpty() {
- Range<Integer> range = Ranges.open(3, 4);
+ Range<Integer> range = Range.open(3, 4);
assertEquals(range, range.intersection(range));
- assertEquals(Ranges.openClosed(3, 3),
- range.intersection(Ranges.atMost(3)));
- assertEquals(Ranges.closedOpen(4, 4),
- range.intersection(Ranges.atLeast(4)));
-
+ assertEquals(Range.openClosed(3, 3),
+ range.intersection(Range.atMost(3)));
+ assertEquals(Range.closedOpen(4, 4),
+ range.intersection(Range.atLeast(4)));
+
try {
- range.intersection(Ranges.lessThan(3));
+ range.intersection(Range.lessThan(3));
fail();
} catch (IllegalArgumentException expected) {
}
try {
- range.intersection(Ranges.greaterThan(4));
+ range.intersection(Range.greaterThan(4));
fail();
} catch (IllegalArgumentException expected) {
}
- range = Ranges.closed(3, 4);
- assertEquals(Ranges.openClosed(4, 4),
- range.intersection(Ranges.greaterThan(4)));
+ range = Range.closed(3, 4);
+ assertEquals(Range.openClosed(4, 4),
+ range.intersection(Range.greaterThan(4)));
}
public void testIntersection_singleton() {
- Range<Integer> range = Ranges.closed(3, 3);
+ Range<Integer> range = Range.closed(3, 3);
assertEquals(range, range.intersection(range));
- assertEquals(range, range.intersection(Ranges.atMost(4)));
- assertEquals(range, range.intersection(Ranges.atMost(3)));
- assertEquals(range, range.intersection(Ranges.atLeast(3)));
- assertEquals(range, range.intersection(Ranges.atLeast(2)));
+ assertEquals(range, range.intersection(Range.atMost(4)));
+ assertEquals(range, range.intersection(Range.atMost(3)));
+ assertEquals(range, range.intersection(Range.atLeast(3)));
+ assertEquals(range, range.intersection(Range.atLeast(2)));
- assertEquals(Ranges.closedOpen(3, 3),
- range.intersection(Ranges.lessThan(3)));
- assertEquals(Ranges.openClosed(3, 3),
- range.intersection(Ranges.greaterThan(3)));
+ assertEquals(Range.closedOpen(3, 3),
+ range.intersection(Range.lessThan(3)));
+ assertEquals(Range.openClosed(3, 3),
+ range.intersection(Range.greaterThan(3)));
try {
- range.intersection(Ranges.atLeast(4));
+ range.intersection(Range.atLeast(4));
fail();
} catch (IllegalArgumentException expected) {
}
try {
- range.intersection(Ranges.atMost(2));
+ range.intersection(Range.atMost(2));
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testIntersection_general() {
- Range<Integer> range = Ranges.closed(4, 8);
+ Range<Integer> range = Range.closed(4, 8);
// separate below
try {
- range.intersection(Ranges.closed(0, 2));
+ range.intersection(Range.closed(0, 2));
fail();
} catch (IllegalArgumentException expected) {
}
// adjacent below
- assertEquals(Ranges.closedOpen(4, 4),
- range.intersection(Ranges.closedOpen(2, 4)));
+ assertEquals(Range.closedOpen(4, 4),
+ range.intersection(Range.closedOpen(2, 4)));
// overlap below
- assertEquals(Ranges.closed(4, 6), range.intersection(Ranges.closed(2, 6)));
+ assertEquals(Range.closed(4, 6), range.intersection(Range.closed(2, 6)));
// enclosed with same start
- assertEquals(Ranges.closed(4, 6), range.intersection(Ranges.closed(4, 6)));
+ assertEquals(Range.closed(4, 6), range.intersection(Range.closed(4, 6)));
// enclosed, interior
- assertEquals(Ranges.closed(5, 7), range.intersection(Ranges.closed(5, 7)));
+ assertEquals(Range.closed(5, 7), range.intersection(Range.closed(5, 7)));
// enclosed with same end
- assertEquals(Ranges.closed(6, 8), range.intersection(Ranges.closed(6, 8)));
+ assertEquals(Range.closed(6, 8), range.intersection(Range.closed(6, 8)));
// equal
assertEquals(range, range.intersection(range));
// enclosing with same start
- assertEquals(range, range.intersection(Ranges.closed(4, 10)));
+ assertEquals(range, range.intersection(Range.closed(4, 10)));
// enclosing with same end
- assertEquals(range, range.intersection(Ranges.closed(2, 8)));
+ assertEquals(range, range.intersection(Range.closed(2, 8)));
// enclosing, exterior
- assertEquals(range, range.intersection(Ranges.closed(2, 10)));
+ assertEquals(range, range.intersection(Range.closed(2, 10)));
// overlap above
- assertEquals(Ranges.closed(6, 8), range.intersection(Ranges.closed(6, 10)));
+ assertEquals(Range.closed(6, 8), range.intersection(Range.closed(6, 10)));
// adjacent above
- assertEquals(Ranges.openClosed(8, 8),
- range.intersection(Ranges.openClosed(8, 10)));
+ assertEquals(Range.openClosed(8, 8),
+ range.intersection(Range.openClosed(8, 10)));
// separate above
try {
- range.intersection(Ranges.closed(10, 12));
+ range.intersection(Range.closed(10, 12));
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testSpan_general() {
- Range<Integer> range = Ranges.closed(4, 8);
+ Range<Integer> range = Range.closed(4, 8);
// separate below
- assertEquals(Ranges.closed(0, 8), range.span(Ranges.closed(0, 2)));
- assertEquals(Ranges.atMost(8), range.span(Ranges.atMost(2)));
+ assertEquals(Range.closed(0, 8), range.span(Range.closed(0, 2)));
+ assertEquals(Range.atMost(8), range.span(Range.atMost(2)));
// adjacent below
- assertEquals(Ranges.closed(2, 8), range.span(Ranges.closedOpen(2, 4)));
- assertEquals(Ranges.atMost(8), range.span(Ranges.lessThan(4)));
+ assertEquals(Range.closed(2, 8), range.span(Range.closedOpen(2, 4)));
+ assertEquals(Range.atMost(8), range.span(Range.lessThan(4)));
// overlap below
- assertEquals(Ranges.closed(2, 8), range.span(Ranges.closed(2, 6)));
- assertEquals(Ranges.atMost(8), range.span(Ranges.atMost(6)));
+ assertEquals(Range.closed(2, 8), range.span(Range.closed(2, 6)));
+ assertEquals(Range.atMost(8), range.span(Range.atMost(6)));
// enclosed with same start
- assertEquals(range, range.span(Ranges.closed(4, 6)));
+ assertEquals(range, range.span(Range.closed(4, 6)));
// enclosed, interior
- assertEquals(range, range.span(Ranges.closed(5, 7)));
+ assertEquals(range, range.span(Range.closed(5, 7)));
// enclosed with same end
- assertEquals(range, range.span(Ranges.closed(6, 8)));
+ assertEquals(range, range.span(Range.closed(6, 8)));
// equal
assertEquals(range, range.span(range));
// enclosing with same start
- assertEquals(Ranges.closed(4, 10), range.span(Ranges.closed(4, 10)));
- assertEquals(Ranges.atLeast(4), range.span(Ranges.atLeast(4)));
+ assertEquals(Range.closed(4, 10), range.span(Range.closed(4, 10)));
+ assertEquals(Range.atLeast(4), range.span(Range.atLeast(4)));
// enclosing with same end
- assertEquals(Ranges.closed(2, 8), range.span(Ranges.closed(2, 8)));
- assertEquals(Ranges.atMost(8), range.span(Ranges.atMost(8)));
+ assertEquals(Range.closed(2, 8), range.span(Range.closed(2, 8)));
+ assertEquals(Range.atMost(8), range.span(Range.atMost(8)));
// enclosing, exterior
- assertEquals(Ranges.closed(2, 10), range.span(Ranges.closed(2, 10)));
- assertEquals(Ranges.<Integer>all(), range.span(Ranges.<Integer>all()));
+ assertEquals(Range.closed(2, 10), range.span(Range.closed(2, 10)));
+ assertEquals(Range.<Integer>all(), range.span(Range.<Integer>all()));
// overlap above
- assertEquals(Ranges.closed(4, 10), range.span(Ranges.closed(6, 10)));
- assertEquals(Ranges.atLeast(4), range.span(Ranges.atLeast(6)));
+ assertEquals(Range.closed(4, 10), range.span(Range.closed(6, 10)));
+ assertEquals(Range.atLeast(4), range.span(Range.atLeast(6)));
// adjacent above
- assertEquals(Ranges.closed(4, 10), range.span(Ranges.openClosed(8, 10)));
- assertEquals(Ranges.atLeast(4), range.span(Ranges.greaterThan(8)));
+ assertEquals(Range.closed(4, 10), range.span(Range.openClosed(8, 10)));
+ assertEquals(Range.atLeast(4), range.span(Range.greaterThan(8)));
// separate above
- assertEquals(Ranges.closed(4, 12), range.span(Ranges.closed(10, 12)));
- assertEquals(Ranges.atLeast(4), range.span(Ranges.atLeast(10)));
+ assertEquals(Range.closed(4, 12), range.span(Range.closed(10, 12)));
+ assertEquals(Range.atLeast(4), range.span(Range.atLeast(10)));
}
public void testApply() {
- Predicate<Integer> predicate = Ranges.closed(2, 3);
+ Predicate<Integer> predicate = Range.closed(2, 3);
assertFalse(predicate.apply(1));
assertTrue(predicate.apply(2));
assertTrue(predicate.apply(3));
@@ -519,36 +523,36 @@ public class RangeTest extends TestCase {
public void testEquals() {
new EqualsTester()
- .addEqualityGroup(Ranges.open(1, 5),
- Ranges.range(1, OPEN, 5, OPEN))
- .addEqualityGroup(Ranges.greaterThan(2), Ranges.greaterThan(2))
- .addEqualityGroup(Ranges.all(), Ranges.all())
+ .addEqualityGroup(Range.open(1, 5),
+ Range.range(1, OPEN, 5, OPEN))
+ .addEqualityGroup(Range.greaterThan(2), Range.greaterThan(2))
+ .addEqualityGroup(Range.all(), Range.all())
.addEqualityGroup("Phil")
.testEquals();
}
public void testLegacyComparable() {
Range<LegacyComparable> range
- = Ranges.closed(LegacyComparable.X, LegacyComparable.Y);
+ = Range.closed(LegacyComparable.X, LegacyComparable.Y);
}
private static final DiscreteDomain<Integer> UNBOUNDED_DOMAIN =
new DiscreteDomain<Integer>() {
@Override public Integer next(Integer value) {
- return DiscreteDomains.integers().next(value);
+ return integers().next(value);
}
@Override public Integer previous(Integer value) {
- return DiscreteDomains.integers().previous(value);
+ return integers().previous(value);
}
@Override public long distance(Integer start, Integer end) {
- return DiscreteDomains.integers().distance(start, end);
+ return integers().distance(start, end);
}
};
public void testAsSet_noMin() {
- Range<Integer> range = Ranges.lessThan(0);
+ Range<Integer> range = Range.lessThan(0);
try {
range.asSet(UNBOUNDED_DOMAIN);
fail();
@@ -556,7 +560,7 @@ public class RangeTest extends TestCase {
}
public void testAsSet_noMax() {
- Range<Integer> range = Ranges.greaterThan(0);
+ Range<Integer> range = Range.greaterThan(0);
try {
range.asSet(UNBOUNDED_DOMAIN);
fail();
@@ -564,41 +568,97 @@ public class RangeTest extends TestCase {
}
public void testAsSet_empty() {
- assertEquals(ImmutableSet.of(), Ranges.closedOpen(1, 1).asSet(integers()));
- assertEquals(ImmutableSet.of(), Ranges.openClosed(5, 5).asSet(integers()));
- assertEquals(ImmutableSet.of(), Ranges.lessThan(Integer.MIN_VALUE).asSet(integers()));
- assertEquals(ImmutableSet.of(), Ranges.greaterThan(Integer.MAX_VALUE).asSet(integers()));
+ assertEquals(ImmutableSet.of(), Range.closedOpen(1, 1).asSet(integers()));
+ assertEquals(ImmutableSet.of(), Range.openClosed(5, 5).asSet(integers()));
+ assertEquals(ImmutableSet.of(), Range.lessThan(Integer.MIN_VALUE).asSet(integers()));
+ assertEquals(ImmutableSet.of(), Range.greaterThan(Integer.MAX_VALUE).asSet(integers()));
}
public void testCanonical() {
- assertEquals(Ranges.closedOpen(1, 5),
- Ranges.closed(1, 4).canonical(integers()));
- assertEquals(Ranges.closedOpen(1, 5),
- Ranges.open(0, 5).canonical(integers()));
- assertEquals(Ranges.closedOpen(1, 5),
- Ranges.closedOpen(1, 5).canonical(integers()));
- assertEquals(Ranges.closedOpen(1, 5),
- Ranges.openClosed(0, 4).canonical(integers()));
+ assertEquals(Range.closedOpen(1, 5),
+ Range.closed(1, 4).canonical(integers()));
+ assertEquals(Range.closedOpen(1, 5),
+ Range.open(0, 5).canonical(integers()));
+ assertEquals(Range.closedOpen(1, 5),
+ Range.closedOpen(1, 5).canonical(integers()));
+ assertEquals(Range.closedOpen(1, 5),
+ Range.openClosed(0, 4).canonical(integers()));
- assertEquals(Ranges.closedOpen(Integer.MIN_VALUE, 0),
- Ranges.closedOpen(Integer.MIN_VALUE, 0).canonical(integers()));
+ assertEquals(Range.closedOpen(Integer.MIN_VALUE, 0),
+ Range.closedOpen(Integer.MIN_VALUE, 0).canonical(integers()));
- assertEquals(Ranges.closedOpen(Integer.MIN_VALUE, 0),
- Ranges.lessThan(0).canonical(integers()));
- assertEquals(Ranges.closedOpen(Integer.MIN_VALUE, 1),
- Ranges.atMost(0).canonical(integers()));
- assertEquals(Ranges.atLeast(0), Ranges.atLeast(0).canonical(integers()));
- assertEquals(Ranges.atLeast(1), Ranges.greaterThan(0).canonical(integers()));
+ assertEquals(Range.closedOpen(Integer.MIN_VALUE, 0),
+ Range.lessThan(0).canonical(integers()));
+ assertEquals(Range.closedOpen(Integer.MIN_VALUE, 1),
+ Range.atMost(0).canonical(integers()));
+ assertEquals(Range.atLeast(0), Range.atLeast(0).canonical(integers()));
+ assertEquals(Range.atLeast(1), Range.greaterThan(0).canonical(integers()));
- assertEquals(Ranges.atLeast(Integer.MIN_VALUE), Ranges.<Integer>all().canonical(integers()));
+ assertEquals(Range.atLeast(Integer.MIN_VALUE), Range.<Integer>all().canonical(integers()));
}
public void testCanonical_unboundedDomain() {
- assertEquals(Ranges.lessThan(0), Ranges.lessThan(0).canonical(UNBOUNDED_DOMAIN));
- assertEquals(Ranges.lessThan(1), Ranges.atMost(0).canonical(UNBOUNDED_DOMAIN));
- assertEquals(Ranges.atLeast(0), Ranges.atLeast(0).canonical(UNBOUNDED_DOMAIN));
- assertEquals(Ranges.atLeast(1), Ranges.greaterThan(0).canonical(UNBOUNDED_DOMAIN));
+ assertEquals(Range.lessThan(0), Range.lessThan(0).canonical(UNBOUNDED_DOMAIN));
+ assertEquals(Range.lessThan(1), Range.atMost(0).canonical(UNBOUNDED_DOMAIN));
+ assertEquals(Range.atLeast(0), Range.atLeast(0).canonical(UNBOUNDED_DOMAIN));
+ assertEquals(Range.atLeast(1), Range.greaterThan(0).canonical(UNBOUNDED_DOMAIN));
+
+ assertEquals(Range.all(), Range.<Integer>all().canonical(UNBOUNDED_DOMAIN));
+ }
+
+ public void testEncloseAll() {
+ assertEquals(Range.closed(0, 0), Range.encloseAll(Arrays.asList(0)));
+ assertEquals(Range.closed(-3, 5), Range.encloseAll(Arrays.asList(5, -3)));
+ assertEquals(Range.closed(-3, 5), Range.encloseAll(Arrays.asList(1, 2, 2, 2, 5, -3, 0, -1)));
+ }
+
+ public void testEncloseAll_empty() {
+ try {
+ Range.encloseAll(ImmutableSet.<Integer>of());
+ fail();
+ } catch (NoSuchElementException expected) {}
+ }
- assertEquals(Ranges.all(), Ranges.<Integer>all().canonical(UNBOUNDED_DOMAIN));
+ public void testEncloseAll_nullValue() {
+ List<Integer> nullFirst = Lists.newArrayList(null, 0);
+ try {
+ Range.encloseAll(nullFirst);
+ fail();
+ } catch (NullPointerException expected) {}
+ List<Integer> nullNotFirst = Lists.newArrayList(0, null);
+ try {
+ Range.encloseAll(nullNotFirst);
+ fail();
+ } catch (NullPointerException expected) {}
+ }
+
+ public void testEquivalentFactories() {
+ new EqualsTester()
+ .addEqualityGroup(Range.all())
+ .addEqualityGroup(
+ Range.atLeast(1),
+ Range.downTo(1, CLOSED))
+ .addEqualityGroup(
+ Range.greaterThan(1),
+ Range.downTo(1, OPEN))
+ .addEqualityGroup(
+ Range.atMost(7),
+ Range.upTo(7, CLOSED))
+ .addEqualityGroup(
+ Range.lessThan(7),
+ Range.upTo(7, OPEN))
+ .addEqualityGroup(
+ Range.open(1, 7),
+ Range.range(1, OPEN, 7, OPEN))
+ .addEqualityGroup(
+ Range.openClosed(1, 7),
+ Range.range(1, OPEN, 7, CLOSED))
+ .addEqualityGroup(
+ Range.closed(1, 7),
+ Range.range(1, CLOSED, 7, CLOSED))
+ .addEqualityGroup(
+ Range.closedOpen(1, 7),
+ Range.range(1, CLOSED, 7, OPEN))
+ .testEquals();
}
}
diff --git a/guava-tests/test/com/google/common/collect/RangesTest.java b/guava-tests/test/com/google/common/collect/RangesTest.java
index a7caf67..54a1074 100644
--- a/guava-tests/test/com/google/common/collect/RangesTest.java
+++ b/guava-tests/test/com/google/common/collect/RangesTest.java
@@ -32,6 +32,7 @@ import java.util.NoSuchElementException;
* @author Gregory Kick
*/
@GwtCompatible
+@SuppressWarnings("deprecation") // since Ranges is deprecated
public class RangesTest extends TestCase {
public void testSingleton() {
assertEquals(Ranges.closed(0, 0), Ranges.singleton(0));
diff --git a/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java b/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java
index 13332a5..3cfa363 100644
--- a/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java
+++ b/guava-tests/test/com/google/common/collect/RegularImmutableTableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,15 +16,17 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
+import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.RegularImmutableTable.DenseImmutableTable;
import com.google.common.collect.RegularImmutableTable.SparseImmutableTable;
import com.google.common.collect.Table.Cell;
/**
- * @author gak@google.com (Gregory Kick)
+ * @author Gregory Kick
*/
+@GwtCompatible
public class RegularImmutableTableTest extends AbstractImmutableTableTest {
private static final ImmutableSet<Cell<Character, Integer, String>> CELLS =
ImmutableSet.of(
@@ -39,11 +41,11 @@ public class RegularImmutableTableTest extends AbstractImmutableTableTest {
ImmutableSet.of(1, 2);
private static final SparseImmutableTable<Character, Integer, String> SPARSE =
- new SparseImmutableTable<Character, Integer, String>(CELLS, ROW_SPACE,
+ new SparseImmutableTable<Character, Integer, String>(CELLS.asList(), ROW_SPACE,
COLUMN_SPACE);
private static final DenseImmutableTable<Character, Integer, String> DENSE =
- new DenseImmutableTable<Character, Integer, String>(CELLS, ROW_SPACE,
+ new DenseImmutableTable<Character, Integer, String>(CELLS.asList(), ROW_SPACE,
COLUMN_SPACE);
@Override Iterable<ImmutableTable<Character, Integer, String>>
@@ -62,8 +64,9 @@ public class RegularImmutableTableTest extends AbstractImmutableTableTest {
public void testValues() {
for (ImmutableTable<Character, Integer, String> testInstance :
getTestInstances()) {
- ASSERT.that(testInstance.values()).hasContentsInOrder("foo", "bar",
- "baz");
+ ASSERT.that(testInstance.values())
+ .has().allOf("foo", "bar", "baz")
+ .inOrder();
}
}
diff --git a/guava-tests/test/com/google/common/collect/SetOperationsTest.java b/guava-tests/test/com/google/common/collect/SetOperationsTest.java
index 4b43c0a..474d9f7 100644
--- a/guava-tests/test/com/google/common/collect/SetOperationsTest.java
+++ b/guava-tests/test/com/google/common/collect/SetOperationsTest.java
@@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.SetTestSuiteBuilder;
import com.google.common.collect.testing.TestStringSetGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
@@ -38,8 +39,9 @@ import java.util.Set;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class SetOperationsTest extends TestCase {
+ @GwtIncompatible("suite")
public static Test suite() {
TestSuite suite = new TestSuite();
diff --git a/guava-tests/test/com/google/common/collect/SetsTest.java b/guava-tests/test/com/google/common/collect/SetsTest.java
index 4dc847b..d99129d 100644
--- a/guava-tests/test/com/google/common/collect/SetsTest.java
+++ b/guava-tests/test/com/google/common/collect/SetsTest.java
@@ -20,21 +20,22 @@ import static com.google.common.collect.Iterables.unmodifiableIterable;
import static com.google.common.collect.Sets.newEnumSet;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.collect.Sets.powerSet;
+import static com.google.common.collect.Sets.unmodifiableNavigableSet;
import static com.google.common.collect.testing.IteratorFeature.UNMODIFIABLE;
import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod;
import static java.io.ObjectStreamConstants.TC_REFERENCE;
import static java.io.ObjectStreamConstants.baseWireHandle;
import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
import com.google.common.collect.testing.AnEnum;
import com.google.common.collect.testing.IteratorTester;
import com.google.common.collect.testing.MinimalIterable;
+import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
+import com.google.common.collect.testing.SafeTreeSet;
import com.google.common.collect.testing.SetTestSuiteBuilder;
import com.google.common.collect.testing.TestEnumSetGenerator;
import com.google.common.collect.testing.TestStringSetGenerator;
@@ -69,10 +70,12 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.NavigableSet;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.concurrent.CopyOnWriteArraySet;
import javax.annotation.Nullable;
@@ -171,6 +174,36 @@ public class SetsTest extends TestCase {
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
+ suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ SafeTreeSet<String> set = new SafeTreeSet<String>(Arrays.asList(elements));
+ return Sets.unmodifiableNavigableSet(set);
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ })
+ .named("Sets.unmodifiableNavigableSet[TreeSet]")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+
+ suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override protected Set<String> create(String[] elements) {
+ SafeTreeSet<String> set = new SafeTreeSet<String>(Arrays.asList(elements));
+ return SerializableTester.reserialize(Sets.unmodifiableNavigableSet(set));
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ })
+ .named("Sets.unmodifiableNavigableSet[TreeSet], reserialized")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+
suite.addTest(testsForFilter());
suite.addTest(testsForFilterNoNulls());
suite.addTest(testsForFilterFiltered());
@@ -201,7 +234,8 @@ public class SetsTest extends TestCase {
@GwtIncompatible("suite")
private static Test testsForFilterNoNulls() {
- return SetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
@Override public Set<String> create(String[] elements) {
Set<String> unfiltered = Sets.newLinkedHashSet();
unfiltered.add("yyy");
@@ -217,7 +251,30 @@ public class SetsTest extends TestCase {
CollectionSize.ANY,
CollectionFeature.ALLOWS_NULL_QUERIES)
.suppressing(getIteratorKnownOrderRemoveSupportedMethod())
- .createTestSuite();
+ .createTestSuite());
+ suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override public NavigableSet<String> create(String[] elements) {
+ NavigableSet<String> unfiltered = Sets.newTreeSet();
+ unfiltered.add("yyy");
+ unfiltered.addAll(ImmutableList.copyOf(elements));
+ unfiltered.add("zzz");
+ return Sets.filter(unfiltered, Collections2Test.LENGTH_1);
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ })
+ .named("Sets.filter[NavigableSet]")
+ .withFeatures(
+ SetFeature.GENERAL_PURPOSE,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionSize.ANY,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .suppressing(getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ return suite;
}
@GwtIncompatible("suite")
@@ -249,7 +306,7 @@ public class SetsTest extends TestCase {
public void testImmutableEnumSet() {
Set<SomeEnum> units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B);
- ASSERT.that(units).hasContentsInOrder(SomeEnum.B, SomeEnum.D);
+ ASSERT.that(units).has().allOf(SomeEnum.B, SomeEnum.D).inOrder();
try {
units.remove(SomeEnum.B);
fail("ImmutableEnumSet should throw an exception on remove()");
@@ -264,7 +321,7 @@ public class SetsTest extends TestCase {
public void testImmutableEnumSet_serialized() {
Set<SomeEnum> units = Sets.immutableEnumSet(SomeEnum.D, SomeEnum.B);
- ASSERT.that(units).hasContentsInOrder(SomeEnum.B, SomeEnum.D);
+ ASSERT.that(units).has().allOf(SomeEnum.B, SomeEnum.D).inOrder();
Set<SomeEnum> copy = SerializableTester.reserializeAndAssert(units);
assertTrue(copy instanceof ImmutableEnumSet);
@@ -273,15 +330,15 @@ public class SetsTest extends TestCase {
public void testImmutableEnumSet_fromIterable() {
ImmutableSet<SomeEnum> none
= Sets.immutableEnumSet(MinimalIterable.<SomeEnum>of());
- ASSERT.that(none).hasContentsInOrder();
+ ASSERT.that(none).isEmpty();
ImmutableSet<SomeEnum> one
= Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.B));
- ASSERT.that(one).hasContentsInOrder(SomeEnum.B);
+ ASSERT.that(one).has().item(SomeEnum.B);
ImmutableSet<SomeEnum> two
= Sets.immutableEnumSet(MinimalIterable.of(SomeEnum.D, SomeEnum.B));
- ASSERT.that(two).hasContentsInOrder(SomeEnum.B, SomeEnum.D);
+ ASSERT.that(two).has().allOf(SomeEnum.B, SomeEnum.D).inOrder();
}
@GwtIncompatible("java serialization not supported in GWT.")
@@ -426,7 +483,7 @@ public class SetsTest extends TestCase {
assertTrue(set.isEmpty());
set.add(new Derived("foo"));
set.add(new Derived("bar"));
- ASSERT.that(set).hasContentsInOrder(new Derived("bar"), new Derived("foo"));
+ ASSERT.that(set).has().allOf(new Derived("bar"), new Derived("foo")).inOrder();
}
public void testNewTreeSetEmptyNonGeneric() {
@@ -434,7 +491,8 @@ public class SetsTest extends TestCase {
assertTrue(set.isEmpty());
set.add(new LegacyComparable("foo"));
set.add(new LegacyComparable("bar"));
- ASSERT.that(set).hasContentsInOrder(new LegacyComparable("bar"), new LegacyComparable("foo"));
+ ASSERT.that(set).has()
+ .allOf(new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
}
public void testNewTreeSetFromCollection() {
@@ -451,16 +509,16 @@ public class SetsTest extends TestCase {
Iterable<Derived> iterable =
Arrays.asList(new Derived("foo"), new Derived("bar"));
TreeSet<Derived> set = Sets.newTreeSet(iterable);
- ASSERT.that(set).hasContentsInOrder(
- new Derived("bar"), new Derived("foo"));
+ ASSERT.that(set).has().allOf(
+ new Derived("bar"), new Derived("foo")).inOrder();
}
public void testNewTreeSetFromIterableNonGeneric() {
Iterable<LegacyComparable> iterable =
Arrays.asList(new LegacyComparable("foo"), new LegacyComparable("bar"));
TreeSet<LegacyComparable> set = Sets.newTreeSet(iterable);
- ASSERT.that(set).hasContentsInOrder(
- new LegacyComparable("bar"), new LegacyComparable("foo"));
+ ASSERT.that(set).has().allOf(
+ new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
}
public void testNewTreeSetEmptyWithComparator() {
@@ -479,6 +537,18 @@ public class SetsTest extends TestCase {
assertEquals(2, set.size());
}
+ @GwtIncompatible("CopyOnWriteArraySet")
+ public void testNewCOWASEmpty() {
+ CopyOnWriteArraySet<Integer> set = Sets.newCopyOnWriteArraySet();
+ verifySetContents(set, EMPTY_COLLECTION);
+ }
+
+ @GwtIncompatible("CopyOnWriteArraySet")
+ public void testNewCOWASFromIterable() {
+ CopyOnWriteArraySet<Integer> set = Sets.newCopyOnWriteArraySet(SOME_ITERABLE);
+ verifySetContents(set, SOME_COLLECTION);
+ }
+
public void testComplementOfEnumSet() {
Set<SomeEnum> units = EnumSet.of(SomeEnum.B, SomeEnum.D);
EnumSet<SomeEnum> otherUnits = Sets.complementOf(units);
@@ -530,15 +600,11 @@ public class SetsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNullPointerExceptions() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Enum.class, SomeEnum.A);
-
- // TODO: make NPT create empty arrays for defaults automatically
- tester.setDefault(Collection[].class, new Collection[0]);
- tester.setDefault(Enum[].class, new Enum[0]);
- tester.setDefault(Set[].class, new Set[0]);
- tester.testAllPublicStaticMethods(Sets.class);
+ public void testNullPointerExceptions() {
+ new NullPointerTester()
+ .setDefault(Enum.class, SomeEnum.A)
+ .setDefault(Class.class, SomeEnum.class) // for newEnumSet
+ .testAllPublicStaticMethods(Sets.class);
}
public void testNewSetFromMap() {
@@ -553,7 +619,7 @@ public class SetsTest extends TestCase {
Sets.newSetFromMap(new LinkedHashMap<Integer, Boolean>());
set.addAll(SOME_COLLECTION);
Set<Integer> copy = SerializableTester.reserializeAndAssert(set);
- ASSERT.that(copy).hasContentsInOrder(0, 1);
+ ASSERT.that(copy).has().allOf(0, 1).inOrder();
}
public void testNewSetFromMapIllegal() {
@@ -573,7 +639,7 @@ public class SetsTest extends TestCase {
*/
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_zeroary() {
- ASSERT.that(Sets.cartesianProduct()).hasContentsAnyOrder(list());
+ ASSERT.that(Sets.cartesianProduct()).has().allOf(list());
}
/**
@@ -582,7 +648,7 @@ public class SetsTest extends TestCase {
*/
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_unary() {
- ASSERT.that(Sets.cartesianProduct(set(1, 2))).hasContentsAnyOrder(list(1), list(2));
+ ASSERT.that(Sets.cartesianProduct(set(1, 2))).has().allOf(list(1), list(2));
}
@SuppressWarnings("unchecked") // varargs!
@@ -611,26 +677,26 @@ public class SetsTest extends TestCase {
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_binary1x1() {
- ASSERT.that(Sets.cartesianProduct(set(1), set(2))).hasContentsAnyOrder(list(1, 2));
+ ASSERT.that(Sets.cartesianProduct(set(1), set(2))).has().item(list(1, 2));
}
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_binary1x2() {
- ASSERT.that(Sets.cartesianProduct(set(1), set(2, 3))).hasContentsAnyOrder(
- list(1, 2), list(1, 3));
+ ASSERT.that(Sets.cartesianProduct(set(1), set(2, 3)))
+ .has().allOf(list(1, 2), list(1, 3)).inOrder();
}
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_binary2x2() {
- ASSERT.that(Sets.cartesianProduct(set(1, 2), set(3, 4))).hasContentsAnyOrder(
- list(1, 3), list(1, 4), list(2, 3), list(2, 4));
+ ASSERT.that(Sets.cartesianProduct(set(1, 2), set(3, 4)))
+ .has().allOf(list(1, 3), list(1, 4), list(2, 3), list(2, 4)).inOrder();
}
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProduct_2x2x2() {
- ASSERT.that(Sets.cartesianProduct(set(0, 1), set(0, 1), set(0, 1))).hasContentsAnyOrder(
+ ASSERT.that(Sets.cartesianProduct(set(0, 1), set(0, 1), set(0, 1))).has().allOf(
list(0, 0, 0), list(0, 0, 1), list(0, 1, 0), list(0, 1, 1),
- list(1, 0, 0), list(1, 0, 1), list(1, 1, 0), list(1, 1, 1));
+ list(1, 0, 0), list(1, 0, 1), list(1, 1, 0), list(1, 1, 1)).inOrder();
}
@SuppressWarnings("unchecked") // varargs!
@@ -653,14 +719,14 @@ public class SetsTest extends TestCase {
List<Object> exp3 = list((Object) 2, "3");
List<Object> exp4 = list((Object) 2, "4");
- ASSERT.that(Sets.<Object>cartesianProduct(x, y)).hasContentsAnyOrder(exp1, exp2, exp3, exp4);
+ ASSERT.that(Sets.<Object>cartesianProduct(x, y)).has().allOf(exp1, exp2, exp3, exp4).inOrder();
}
@SuppressWarnings("unchecked") // varargs!
public void testCartesianProductTooBig() {
- Set<Integer> set = Ranges.closed(0, 10000).asSet(DiscreteDomains.integers());
+ Set<Integer> set = Range.closed(0, 10000).asSet(DiscreteDomain.integers());
try {
- Set<List<Integer>> productSet = Sets.cartesianProduct(set, set, set, set, set);
+ Sets.cartesianProduct(set, set, set, set, set);
fail("Expected IAE");
} catch (IllegalArgumentException expected) {}
}
@@ -997,105 +1063,113 @@ public class SetsTest extends TestCase {
private static final long serialVersionUID = 0;
}
- public void testFilterFiltered() {
- Set<String> unfiltered = Sets.newHashSet();
- Set<String> filtered = Sets.filter(
- Sets.filter(unfiltered, Collections2Test.LENGTH_1),
- Collections2Test.STARTS_WITH_VOWEL);
- unfiltered.add("a");
- unfiltered.add("b");
- unfiltered.add("apple");
- unfiltered.add("banana");
- unfiltered.add("e");
- assertEquals(ImmutableSet.of("a", "e"), filtered);
- assertEquals(ImmutableSet.of("a", "b", "apple", "banana", "e"), unfiltered);
+ @GwtIncompatible("NavigableSet")
+ public void testUnmodifiableNavigableSet() {
+ TreeSet<Integer> mod = Sets.newTreeSet();
+ mod.add(1);
+ mod.add(2);
+ mod.add(3);
- try {
- filtered.add("d");
- fail();
- } catch (IllegalArgumentException expected) {}
- try {
- filtered.add("egg");
- fail();
- } catch (IllegalArgumentException expected) {}
- assertEquals(ImmutableSet.of("a", "e"), filtered);
- assertEquals(ImmutableSet.of("a", "b", "apple", "banana", "e"), unfiltered);
-
- filtered.clear();
- assertTrue(filtered.isEmpty());
- assertEquals(ImmutableSet.of("b", "apple", "banana"), unfiltered);
- }
-
- public void testFilterSorted() {
- SortedSet<Long> sorted = Sets.newTreeSet();
- for (long i = 1; i < 11; i++) {
- sorted.add(i);
- }
- SortedSet<Long> filteredEven = Sets.filter(sorted, new Predicate<Long>() {
- @Override
- public boolean apply(Long input) {
- return input % 2 == 0;
- }
- });
+ NavigableSet<Integer> unmod = unmodifiableNavigableSet(mod);
- assertEquals("filteredSortedSet", ImmutableSet.of(2L, 4L, 6L, 8L, 10L), filteredEven);
- assertEquals("First", 2L, filteredEven.first().longValue());
- assertEquals("Last", 10L, filteredEven.last().longValue());
- assertEquals("subSet", ImmutableSet.of(4L, 6L), filteredEven.subSet(4L, 8L));
- assertEquals("headSet", ImmutableSet.of(2L, 4L), filteredEven.headSet(5L));
- assertEquals("tailSet", ImmutableSet.of(8L, 10L), filteredEven.tailSet(7L));
- assertEquals("comparator", sorted.comparator(), filteredEven.comparator());
+ /* Unmodifiable is a view. */
+ mod.add(4);
+ assertTrue(unmod.contains(4));
+ assertTrue(unmod.descendingSet().contains(4));
- sorted.add(12L);
- sorted.add(0L);
- assertEquals("addingElementsToSet", ImmutableSet.of(0L, 2L, 4L, 6L, 8L, 10L, 12L),
- filteredEven);
- assertEquals("FirstOnModifiedSortedSet", 0L, filteredEven.first().longValue());
- assertEquals("LastOnModifiedSortedSet", 12L, filteredEven.last().longValue());
- }
-
- static SortedSet<Long> filteredEmpty = Sets.filter(new TreeSet<Long>(), Predicates.alwaysTrue());
- public void testFilteredSortedEmpty_size() {
- assertEquals("filterEmptySize", 0, filteredEmpty.size());
- }
+ ensureNotDirectlyModifiable(unmod);
+ ensureNotDirectlyModifiable(unmod.descendingSet());
+ ensureNotDirectlyModifiable(unmod.headSet(2));
+ ensureNotDirectlyModifiable(unmod.headSet(2, true));
+ ensureNotDirectlyModifiable(unmod.tailSet(2));
+ ensureNotDirectlyModifiable(unmod.tailSet(2, true));
+ ensureNotDirectlyModifiable(unmod.subSet(1, 3));
+ ensureNotDirectlyModifiable(unmod.subSet(1, true, 3, true));
- public void testFilteredSortedEmpty_first() {
+ /* UnsupportedOperationException on indirect modifications. */
+ NavigableSet<Integer> reverse = unmod.descendingSet();
try {
- filteredEmpty.first();
- fail("CallFirstOnEmptySetThrowsException");
- } catch (NoSuchElementException expected) {}
- }
-
- public void testFilteredSortedEmpty_last() {
+ reverse.add(4);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
try {
- filteredEmpty.last();
- fail("CallLastOnEmptySetThrowsException");
- } catch (NoSuchElementException expected) {}
- }
-
- static SortedSet<Long> sorted = Sets.newTreeSet();
- static {
- for (long i = 1; i < 11; i++) {
- sorted.add(i);
+ reverse.addAll(Collections.singleton(4));
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ reverse.remove(4);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
}
- }
- static SortedSet<Long> filterAllElements = Sets.filter(sorted, Predicates.alwaysFalse());
-
- public void testFilteredSortedAllFiltered_size() {
- assertEquals("filterAllElementsSize", 0, filterAllElements.size());
}
- public void testFilteredSortedAllFiltered_first() {
+ void ensureNotDirectlyModifiable(SortedSet<Integer> unmod) {
+ try {
+ unmod.add(4);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
try {
- filterAllElements.first();
- fail("CallFirstOnSetWithAllElementsFilteredThrowsException");
- } catch (NoSuchElementException expected) {}
+ unmod.remove(4);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ unmod.addAll(Collections.singleton(4));
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ Iterator<Integer> iterator = unmod.iterator();
+ iterator.next();
+ iterator.remove();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
}
- public void testFilteredSortedAllFiltered_last() {
+ @GwtIncompatible("NavigableSet")
+ void ensureNotDirectlyModifiable(NavigableSet<Integer> unmod) {
try {
- filterAllElements.last();
- fail("CallLastOnSetWithAllElementsFilteredThrowsException");
- } catch (NoSuchElementException expected) {}
+ unmod.add(4);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ unmod.remove(4);
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ unmod.addAll(Collections.singleton(4));
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ unmod.pollFirst();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ unmod.pollLast();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ Iterator<Integer> iterator = unmod.iterator();
+ iterator.next();
+ iterator.remove();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
+ try {
+ Iterator<Integer> iterator = unmod.descendingIterator();
+ iterator.next();
+ iterator.remove();
+ fail("UnsupportedOperationException expected");
+ } catch (UnsupportedOperationException expected) {
+ }
}
}
diff --git a/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java b/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java
index 608fbae..60eaec8 100644
--- a/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/SimpleAbstractMultisetTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2007 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
@@ -17,13 +17,14 @@ package com.google.common.collect;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.annotations.GwtCompatible;
-import com.google.common.collect.Multiset.Entry;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
+import javax.annotation.Nullable;
+
/**
* Unit test for {@link AbstractMultiset}.
*
@@ -67,7 +68,7 @@ public class SimpleAbstractMultisetTest extends AbstractMultisetTest {
implements Serializable {
final Map<E, Integer> backingMap = Maps.newHashMap();
- @Override public int add(E element, int occurrences) {
+ @Override public int add(@Nullable E element, int occurrences) {
checkArgument(occurrences >= 0);
Integer frequency = backingMap.get(element);
if (frequency == null) {
@@ -122,7 +123,7 @@ public class SimpleAbstractMultisetTest extends AbstractMultisetTest {
private static class SimpleAbstractMultiset<E> extends NoRemoveMultiset<E> {
@SuppressWarnings("unchecked")
- @Override public int remove(Object element, int occurrences) {
+ @Override public int remove(@Nullable Object element, int occurrences) {
checkArgument(occurrences >= 0);
Integer count = backingMap.get(element);
if (count == null) {
diff --git a/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java b/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java
index 36b8159..395be9c 100644
--- a/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java
+++ b/guava-tests/test/com/google/common/collect/SingletonImmutableTableTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Google Inc.
+ * Copyright (C) 2009 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,19 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.base.Objects;
import com.google.common.testing.EqualsTester;
/**
* Tests {@link SingletonImmutableTable}.
*
- * @author gak@google.com (Gregory Kick)
+ * @author Gregory Kick
*/
+@GwtCompatible(emulated = true)
public class SingletonImmutableTableTest extends AbstractImmutableTableTest {
private final ImmutableTable<Character, Integer, String> testTable =
new SingletonImmutableTable<Character, Integer, String>('a', 1, "blah");
@@ -35,8 +38,7 @@ public class SingletonImmutableTableTest extends AbstractImmutableTableTest {
}
public void testCellSet() {
- assertEquals(ImmutableSet.of(Tables.immutableCell('a', 1, "blah")),
- testTable.cellSet());
+ assertEquals(ImmutableSet.of(Tables.immutableCell('a', 1, "blah")), testTable.cellSet());
}
public void testColumn() {
@@ -49,8 +51,7 @@ public class SingletonImmutableTableTest extends AbstractImmutableTableTest {
}
public void testColumnMap() {
- assertEquals(ImmutableMap.of(1, ImmutableMap.of('a', "blah")),
- testTable.columnMap());
+ assertEquals(ImmutableMap.of(1, ImmutableMap.of('a', "blah")), testTable.columnMap());
}
public void testRow() {
@@ -69,14 +70,20 @@ public class SingletonImmutableTableTest extends AbstractImmutableTableTest {
public void testEqualsObject() {
new EqualsTester()
- .addEqualityGroup(testTable, ArrayTable.create(testTable),
- HashBasedTable.create(testTable))
- .addEqualityGroup(EmptyImmutableTable.INSTANCE,
- HashBasedTable.create())
+ .addEqualityGroup(testTable, HashBasedTable.create(testTable))
+ .addEqualityGroup(EmptyImmutableTable.INSTANCE, HashBasedTable.create())
.addEqualityGroup(HashBasedTable.create(ImmutableTable.of('A', 2, "")))
.testEquals();
}
+ @GwtIncompatible("ArrayTable")
+ public void testEqualsObjectNullValues() {
+ new EqualsTester()
+ .addEqualityGroup(testTable)
+ .addEqualityGroup(ArrayTable.create(ImmutableSet.of('A'), ImmutableSet.of(1)))
+ .testEquals();
+ }
+
public void testToString() {
assertEquals("{a={1=blah}}", testTable.toString());
}
@@ -119,11 +126,10 @@ public class SingletonImmutableTableTest extends AbstractImmutableTableTest {
}
public void testValues() {
- ASSERT.that(testTable.values()).hasContentsInOrder("blah");
+ ASSERT.that(testTable.values()).has().item("blah");
}
- @Override Iterable<ImmutableTable<Character, Integer, String>>
- getTestInstances() {
+ @Override Iterable<ImmutableTable<Character, Integer, String>> getTestInstances() {
return ImmutableSet.of(testTable);
}
}
diff --git a/guava-tests/test/com/google/common/collect/SortedIterablesTest.java b/guava-tests/test/com/google/common/collect/SortedIterablesTest.java
index e16a75a..d3a50f8 100644
--- a/guava-tests/test/com/google/common/collect/SortedIterablesTest.java
+++ b/guava-tests/test/com/google/common/collect/SortedIterablesTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
@@ -14,43 +14,19 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
-
import com.google.common.annotations.GwtCompatible;
import junit.framework.TestCase;
-import java.util.Arrays;
-import java.util.List;
import java.util.SortedSet;
/**
* Unit tests for {@code SortedIterables}.
- *
+ *
* @author Louis Wasserman
*/
@GwtCompatible
public class SortedIterablesTest extends TestCase {
- @SuppressWarnings("unchecked")
- public void testSortedCounts() {
- List<Integer> list = Arrays.asList(3, 9, 8, 4, 5, 2, 2, 8);
- ASSERT.that(SortedIterables.sortedCounts(Ordering.natural(), list))
- .hasContentsInOrder(
- Multisets.immutableEntry(2, 2), Multisets.immutableEntry(3, 1),
- Multisets.immutableEntry(4, 1), Multisets.immutableEntry(5, 1),
- Multisets.immutableEntry(8, 2), Multisets.immutableEntry(9, 1));
- }
-
- @SuppressWarnings("unchecked")
- public void testSortedCountsIterator() {
- List<Integer> list = Arrays.asList(3, 9, 8, 4, 5, 2, 2, 8);
- ASSERT.that(SortedIterables.sortedCounts(Ordering.natural(), list.iterator()))
- .hasContentsInOrder(
- Multisets.immutableEntry(2, 2), Multisets.immutableEntry(3, 1),
- Multisets.immutableEntry(4, 1), Multisets.immutableEntry(5, 1),
- Multisets.immutableEntry(8, 2), Multisets.immutableEntry(9, 1));
- }
-
public void testSameComparator() {
assertTrue(SortedIterables.hasSameComparator(Ordering.natural(), Sets.newTreeSet()));
// Before JDK6 (including under GWT), the TreeMap keySet is a plain Set.
@@ -61,4 +37,8 @@ public class SortedIterablesTest extends TestCase {
assertTrue(SortedIterables.hasSameComparator(Ordering.natural().reverse(),
Sets.newTreeSet(Ordering.natural().reverse())));
}
+
+ public void testComparator() {
+ assertEquals(Ordering.natural(), SortedIterables.comparator(Sets.newTreeSet()));
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/SortedListsTest.java b/guava-tests/test/com/google/common/collect/SortedListsTest.java
index 884f5f9..02b259a 100644
--- a/guava-tests/test/com/google/common/collect/SortedListsTest.java
+++ b/guava-tests/test/com/google/common/collect/SortedListsTest.java
@@ -16,8 +16,6 @@ package com.google.common.collect;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
import com.google.common.collect.SortedLists.KeyAbsentBehavior;
import com.google.common.collect.SortedLists.KeyPresentBehavior;
import com.google.common.testing.NullPointerTester;
@@ -119,13 +117,7 @@ public class SortedListsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Function.class, Functions.identity());
- tester.setDefault(List.class, LIST_WITH_DUPS);
- tester.setDefault(Comparable.class, 2);
- tester.setDefault(KeyPresentBehavior.class, KeyPresentBehavior.ANY_PRESENT);
- tester.setDefault(KeyAbsentBehavior.class, KeyAbsentBehavior.NEXT_HIGHER);
- tester.testAllPublicStaticMethods(SortedLists.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(SortedLists.class);
}
}
diff --git a/guava-tests/test/com/google/common/collect/SortedMapsTest.java b/guava-tests/test/com/google/common/collect/SortedMapsTest.java
deleted file mode 100644
index 5529521..0000000
--- a/guava-tests/test/com/google/common/collect/SortedMapsTest.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import static org.junit.contrib.truth.Truth.ASSERT;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Maps.EntryTransformer;
-import com.google.common.collect.testing.SortedMapInterfaceTest;
-import com.google.common.testing.NullPointerTester;
-
-import junit.framework.TestCase;
-
-import java.util.Comparator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.SortedMap;
-
-/**
- * Tests for SortedMaps.
- *
- * @author Louis Wasserman
- */
-@GwtCompatible(emulated = true)
-@SuppressWarnings("deprecation")
-public class SortedMapsTest extends TestCase {
-
- private static final EntryTransformer<Object, Object, Object> ALWAYS_NULL =
- new EntryTransformer<Object, Object, Object>() {
- @Override
- public Object transformEntry(Object k, Object v1) {
- return null;
- }
- };
-
- @GwtIncompatible("NullPointerTester")
- public void testNullPointer() throws Exception {
- NullPointerTester nullPointerTester = new NullPointerTester();
- nullPointerTester.setDefault(EntryTransformer.class, ALWAYS_NULL);
- nullPointerTester.setDefault(
- SortedMap.class, Maps.<String, String>newTreeMap());
- nullPointerTester.testAllPublicStaticMethods(SortedMaps.class);
- }
-
- public void testTransformSortedValues() {
- SortedMap<String, Integer> map = ImmutableSortedMap.of("a", 4, "b", 9);
- Function<Integer, Double> sqrt = new Function<Integer, Double>() {
- @Override
- public Double apply(Integer in) {
- return Math.sqrt(in);
- }
- };
- SortedMap<String, Double> transformed =
- SortedMaps.transformValues(map, sqrt);
-
- assertEquals(ImmutableSortedMap.of("a", 2.0, "b", 3.0), transformed);
- }
-
- public void testTransformSortedEntries() {
- SortedMap<String, String> map = ImmutableSortedMap.of("a", "4", "b", "9");
- EntryTransformer<String, String, String> concat =
- new EntryTransformer<String, String, String>() {
- @Override
- public String transformEntry(String key, String value) {
- return key + value;
- }
- };
- SortedMap<String, String> transformed =
- SortedMaps.transformEntries(map, concat);
-
- assertEquals(ImmutableSortedMap.of("a", "a4", "b", "b9"), transformed);
- }
-
- // Not testing Map methods of SortedMaps.filter*, since the implementation
- // doesn't override Maps.FilteredEntryMap, which is already tested.
-
- private static final Predicate<Integer> EVEN =
- new Predicate<Integer>() {
- @Override
- public boolean apply(Integer input) {
- return input % 2 == 0;
- }
- };
-
- public void testFilterKeys() {
- Comparator<Integer> comparator = Ordering.natural();
- SortedMap<Integer, String> unfiltered = Maps.newTreeMap(comparator);
- unfiltered.put(1, "one");
- unfiltered.put(2, "two");
- unfiltered.put(3, "three");
- unfiltered.put(4, "four");
- unfiltered.put(5, "five");
- unfiltered.put(6, "six");
- unfiltered.put(7, "seven");
- SortedMap<Integer, String> filtered
- = SortedMaps.filterKeys(unfiltered, EVEN);
- ASSERT.that(filtered.keySet()).hasContentsInOrder(2, 4, 6);
- assertSame(comparator, filtered.comparator());
- assertEquals((Integer) 2, filtered.firstKey());
- assertEquals((Integer) 6, filtered.lastKey());
- ASSERT.that(filtered.headMap(5).keySet()).hasContentsInOrder(2, 4);
- ASSERT.that(filtered.tailMap(3).keySet()).hasContentsInOrder(4, 6);
- ASSERT.that(filtered.subMap(3, 5).keySet()).hasContentsInOrder(4);
- }
-
- private static final Predicate<String> NOT_LENGTH_3 =
- new Predicate<String>() {
- @Override
- public boolean apply(String input) {
- return input == null || input.length() != 3;
- }
- };
-
- public void testFilterValues() {
- Comparator<Integer> comparator = Ordering.natural();
- SortedMap<Integer, String> unfiltered = Maps.newTreeMap(comparator);
- unfiltered.put(1, "one");
- unfiltered.put(2, "two");
- unfiltered.put(3, "three");
- unfiltered.put(4, "four");
- unfiltered.put(5, "five");
- unfiltered.put(6, "six");
- unfiltered.put(7, "seven");
- SortedMap<Integer, String> filtered
- = SortedMaps.filterValues(unfiltered, NOT_LENGTH_3);
- ASSERT.that(filtered.keySet()).hasContentsInOrder(3, 4, 5, 7);
- assertSame(comparator, filtered.comparator());
- assertEquals((Integer) 3, filtered.firstKey());
- assertEquals((Integer) 7, filtered.lastKey());
- ASSERT.that(filtered.headMap(5).keySet()).hasContentsInOrder(3, 4);
- ASSERT.that(filtered.tailMap(4).keySet()).hasContentsInOrder(4, 5, 7);
- ASSERT.that(filtered.subMap(4, 6).keySet()).hasContentsInOrder(4, 5);
- }
-
- private static final Predicate<Map.Entry<Integer, String>>
- EVEN_AND_LENGTH_3 = new Predicate<Map.Entry<Integer, String>>() {
- @Override public boolean apply(Entry<Integer, String> entry) {
- return (entry.getKey() == null || entry.getKey() % 2 == 0)
- && (entry.getValue() == null || entry.getValue().length() == 3);
- }
- };
-
- private static class ContainsKeySafeSortedMap
- extends ForwardingSortedMap<Integer, String> {
- SortedMap<Integer, String> delegate
- = Maps.newTreeMap(Ordering.natural().nullsFirst());
-
- @Override protected SortedMap<Integer, String> delegate() {
- return delegate;
- }
-
- // Needed by MapInterfaceTest.testContainsKey()
- @Override public boolean containsKey(Object key) {
- try {
- return super.containsKey(key);
- } catch (ClassCastException e) {
- return false;
- }
- }
- }
-
- public static class FilteredEntriesSortedMapInterfaceTest
- extends SortedMapInterfaceTest<Integer, String> {
- public FilteredEntriesSortedMapInterfaceTest() {
- super(true, true, true, true, true);
- }
-
- @Override protected SortedMap<Integer, String> makeEmptyMap() {
- SortedMap<Integer, String> unfiltered = new ContainsKeySafeSortedMap();
- unfiltered.put(1, "one");
- unfiltered.put(3, "three");
- unfiltered.put(4, "four");
- unfiltered.put(5, "five");
- return SortedMaps.filterEntries(unfiltered, EVEN_AND_LENGTH_3);
- }
-
- @Override protected SortedMap<Integer, String> makePopulatedMap() {
- SortedMap<Integer, String> unfiltered = new ContainsKeySafeSortedMap();
- unfiltered.put(1, "one");
- unfiltered.put(2, "two");
- unfiltered.put(3, "three");
- unfiltered.put(4, "four");
- unfiltered.put(5, "five");
- unfiltered.put(6, "six");
- return SortedMaps.filterEntries(unfiltered, EVEN_AND_LENGTH_3);
- }
-
- @Override protected Integer getKeyNotInPopulatedMap() {
- return 10;
- }
-
- @Override protected String getValueNotInPopulatedMap() {
- return "ten";
- }
-
- // Iterators don't support remove.
- @Override public void testEntrySetIteratorRemove() {}
- @Override public void testValuesIteratorRemove() {}
-
- // These tests fail on GWT.
- // TODO: Investigate why.
- @Override public void testEntrySetRemoveAll() {}
- @Override public void testEntrySetRetainAll() {}
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/SpecialRandom.java b/guava-tests/test/com/google/common/collect/SpecialRandom.java
new file mode 100644
index 0000000..4b6d827
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/SpecialRandom.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import java.util.Random;
+
+/**
+ * Utility class for being able to seed a {@link Random} value with a passed
+ * in seed from a benchmark parameter.
+ *
+ * TODO: Remove this class once Caliper has a better way.
+ *
+ * @author Nicholaus Shupe
+ */
+public final class SpecialRandom extends Random {
+ public static SpecialRandom valueOf(String s) {
+ return (s.length() == 0)
+ ? new SpecialRandom()
+ : new SpecialRandom(Long.parseLong(s));
+ }
+
+ private final boolean hasSeed;
+ private final long seed;
+
+ public SpecialRandom() {
+ this.hasSeed = false;
+ this.seed = 0;
+ }
+
+ public SpecialRandom(long seed) {
+ super(seed);
+ this.hasSeed = true;
+ this.seed = seed;
+ }
+
+ @Override public String toString() {
+ return hasSeed ? "(seed:" + seed : "(default seed)";
+ }
+
+ private static final long serialVersionUID = 0;
+}
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java b/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java
index 7e99f71..b0efcf0 100644
--- a/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java
+++ b/guava-tests/test/com/google/common/collect/SynchronizedBiMapTest.java
@@ -16,11 +16,20 @@
package com.google.common.collect;
+import static com.google.common.base.Preconditions.checkArgument;
+
import com.google.common.collect.Synchronized.SynchronizedBiMap;
import com.google.common.collect.Synchronized.SynchronizedSet;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.BiMapInverseTester;
+import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringBiMapGenerator;
import junit.framework.TestSuite;
+import java.util.Map.Entry;
import java.util.Set;
/**
@@ -32,7 +41,24 @@ public class SynchronizedBiMapTest extends SynchronizedMapTest {
public static TestSuite suite() {
TestSuite suite = new TestSuite(SynchronizedBiMapTest.class);
- suite.addTestSuite(AbstractBiMapTests.class);
+ suite.addTest(BiMapTestSuiteBuilder.using(new SynchTestingBiMapGenerator())
+ .named("Synchronized.biMap[TestBiMap]")
+ .withFeatures(CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.REJECTS_DUPLICATES_AT_CREATION)
+ .createTestSuite());
+ suite.addTest(BiMapTestSuiteBuilder.using(new SynchronizedHashBiMapGenerator())
+ .named("synchronizedBiMap[HashBiMap]")
+ .withFeatures(CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.SERIALIZABLE)
+ .suppressing(BiMapInverseTester.getInverseSameAfterSerializingMethods())
+ .createTestSuite());
return suite;
}
@@ -43,6 +69,34 @@ public class SynchronizedBiMapTest extends SynchronizedMapTest {
return outer;
}
+ public static final class SynchronizedHashBiMapGenerator extends TestStringBiMapGenerator {
+ @Override
+ protected BiMap<String, String> create(Entry<String, String>[] entries) {
+ Object mutex = new Object();
+ BiMap<String, String> result = HashBiMap.create();
+ for (Entry<String, String> entry : entries) {
+ checkArgument(!result.containsKey(entry.getKey()));
+ result.put(entry.getKey(), entry.getValue());
+ }
+ return Maps.synchronizedBiMap(result);
+ }
+ }
+
+ public static final class SynchTestingBiMapGenerator extends TestStringBiMapGenerator {
+ @Override
+ protected BiMap<String, String> create(Entry<String, String>[] entries) {
+ Object mutex = new Object();
+ BiMap<String, String> backing =
+ new TestBiMap<String, String>(HashBiMap.<String, String>create(), mutex);
+ BiMap<String, String> result = Synchronized.biMap(backing, mutex);
+ for (Entry<String, String> entry : entries) {
+ checkArgument(!result.containsKey(entry.getKey()));
+ result.put(entry.getKey(), entry.getValue());
+ }
+ return result;
+ }
+ }
+
static class TestBiMap<K, V> extends TestMap<K, V> implements BiMap<K, V> {
private final BiMap<K, V> delegate;
@@ -89,26 +143,4 @@ public class SynchronizedBiMapTest extends SynchronizedMapTest {
assertTrue(values instanceof SynchronizedSet);
assertSame(mutex, ((SynchronizedSet<?>) values).mutex);
}
-
- public static class AbstractBiMapTests extends AbstractBiMapTest {
- public final Object mutex = new Integer(1); // something Serializable
-
- @Override protected BiMap<Integer, String> create() {
- TestBiMap<Integer, String> inner = new TestBiMap<Integer, String>(
- HashBiMap.<Integer, String>create(), mutex);
- BiMap<Integer, String> outer = Synchronized.biMap(inner, mutex);
- return outer;
- }
-
- /**
- * If you serialize a synchronized bimap and its inverse together, the
- * reserialized bimaps will have backing maps that stay in sync, as shown
- * by the {@code testSerializationWithInverseEqual()} test. However, the
- * inverse of one won't be the same as the other.
- *
- * To make them the same, the inverse synchronized bimap would need a custom
- * serialized form, similar to what {@code AbstractBiMap.Inverse} does.
- */
- @Override public void testSerializationWithInverseSame() {}
- }
}
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java b/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java
index 9e8ee22..75559be 100644
--- a/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java
+++ b/guava-tests/test/com/google/common/collect/SynchronizedMultimapTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import java.io.Serializable;
import java.util.Arrays;
@@ -173,11 +173,11 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest {
ArrayListMultimap.<String, Integer>create());
multimap.putAll("foo", Arrays.asList(3, -1, 2, 4, 1));
multimap.putAll("bar", Arrays.asList(1, 2, 3, 1));
- ASSERT.that(multimap.removeAll("foo")).hasContentsInOrder(3, -1, 2, 4, 1);
+ ASSERT.that(multimap.removeAll("foo")).has().allOf(3, -1, 2, 4, 1).inOrder();
assertFalse(multimap.containsKey("foo"));
ASSERT.that(multimap.replaceValues("bar", Arrays.asList(6, 5)))
- .hasContentsInOrder(1, 2, 3, 1);
- ASSERT.that(multimap.get("bar")).hasContentsInOrder(6, 5);
+ .has().allOf(1, 2, 3, 1).inOrder();
+ ASSERT.that(multimap.get("bar")).has().allOf(6, 5).inOrder();
}
public void testSynchronizedSortedSetMultimap() {
@@ -186,11 +186,11 @@ public class SynchronizedMultimapTest extends AbstractSetMultimapTest {
TreeMultimap.<String, Integer>create());
multimap.putAll("foo", Arrays.asList(3, -1, 2, 4, 1));
multimap.putAll("bar", Arrays.asList(1, 2, 3, 1));
- ASSERT.that(multimap.removeAll("foo")).hasContentsInOrder(-1, 1, 2, 3, 4);
+ ASSERT.that(multimap.removeAll("foo")).has().allOf(-1, 1, 2, 3, 4).inOrder();
assertFalse(multimap.containsKey("foo"));
ASSERT.that(multimap.replaceValues("bar", Arrays.asList(6, 5)))
- .hasContentsInOrder(1, 2, 3);
- ASSERT.that(multimap.get("bar")).hasContentsInOrder(5, 6);
+ .has().allOf(1, 2, 3).inOrder();
+ ASSERT.that(multimap.get("bar")).has().allOf(5, 6).inOrder();
}
public void testSynchronizedArrayListMultimapRandomAccess() {
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedNavigableMapTest.java b/guava-tests/test/com/google/common/collect/SynchronizedNavigableMapTest.java
new file mode 100644
index 0000000..99370dd
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/SynchronizedNavigableMapTest.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.collect.Synchronized.SynchronizedNavigableMap;
+import com.google.common.collect.Synchronized.SynchronizedNavigableSet;
+import com.google.common.collect.Synchronized.SynchronizedSortedMap;
+import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
+import com.google.common.collect.testing.SafeTreeMap;
+import com.google.common.collect.testing.TestStringSortedMapGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.testing.SerializableTester;
+
+import junit.framework.TestSuite;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.Map.Entry;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.SortedMap;
+
+/**
+ * Tests for {@link Maps#synchronizedNavigableMap(NavigableMap)}.
+ *
+ * @author Louis Wasserman
+ */
+public class SynchronizedNavigableMapTest extends SynchronizedMapTest {
+ @Override protected <K, V> NavigableMap<K, V> create() {
+ @SuppressWarnings("unchecked")
+ NavigableMap<K, V> innermost = new SafeTreeMap<K, V>(
+ (Comparator<? super K>) Ordering.natural().nullsFirst());
+ TestMap<K, V> inner = new TestMap<K, V>(innermost, mutex);
+ NavigableMap<K, V> outer = Synchronized.navigableMap(inner, mutex);
+ return outer;
+ }
+
+ static class TestEntry<K, V> extends ForwardingMapEntry<K, V>
+ implements Serializable {
+ private final Entry<K, V> delegate;
+ private final Object mutex;
+
+ TestEntry(Entry<K, V> delegate, Object mutex) {
+ this.delegate = delegate;
+ this.mutex = mutex;
+ }
+
+ @Override protected Entry<K, V> delegate() {
+ return delegate;
+ }
+
+ @Override public boolean equals(Object object) {
+ assertTrue(Thread.holdsLock(mutex));
+ return super.equals(object);
+ }
+
+ @Override public K getKey() {
+ assertTrue(Thread.holdsLock(mutex));
+ return super.getKey();
+ }
+
+ @Override public V getValue() {
+ assertTrue(Thread.holdsLock(mutex));
+ return super.getValue();
+ }
+
+ @Override public int hashCode() {
+ assertTrue(Thread.holdsLock(mutex));
+ return super.hashCode();
+ }
+
+ @Override public V setValue(V value) {
+ assertTrue(Thread.holdsLock(mutex));
+ return super.setValue(value);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ static class TestMap<K, V> extends SynchronizedMapTest.TestMap<K, V>
+ implements NavigableMap<K, V> {
+
+ public TestMap(NavigableMap<K, V> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @Override protected NavigableMap<K, V> delegate() {
+ return (NavigableMap<K, V>) super.delegate();
+ }
+
+ @Override public Entry<K, V> ceilingEntry(K key) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().ceilingEntry(key);
+ }
+
+ @Override public K ceilingKey(K key) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().ceilingKey(key);
+ }
+
+ @Override public NavigableSet<K> descendingKeySet() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().descendingKeySet();
+ }
+
+ @Override public NavigableMap<K, V> descendingMap() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().descendingMap();
+ }
+
+ @Override public Entry<K, V> firstEntry() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().firstEntry();
+ }
+
+ @Override public Entry<K, V> floorEntry(K key) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().floorEntry(key);
+ }
+
+ @Override public K floorKey(K key) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().floorKey(key);
+ }
+
+ @Override public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().headMap(toKey, inclusive);
+ }
+
+ @Override public SortedMap<K, V> headMap(K toKey) {
+ return headMap(toKey, false);
+ }
+
+ @Override public Entry<K, V> higherEntry(K key) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().higherEntry(key);
+ }
+
+ @Override public K higherKey(K key) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().higherKey(key);
+ }
+
+ @Override public Entry<K, V> lastEntry() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().lastEntry();
+ }
+
+ @Override public Entry<K, V> lowerEntry(K key) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().lowerEntry(key);
+ }
+
+ @Override public K lowerKey(K key) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().lowerKey(key);
+ }
+
+ @Override public NavigableSet<K> navigableKeySet() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().navigableKeySet();
+ }
+
+ @Override public Entry<K, V> pollFirstEntry() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().pollFirstEntry();
+ }
+
+ @Override public Entry<K, V> pollLastEntry() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().pollLastEntry();
+ }
+
+ @Override public NavigableMap<K, V> subMap(
+ K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().subMap(fromKey, fromInclusive, toKey, toInclusive);
+ }
+
+ @Override public SortedMap<K, V> subMap(K fromKey, K toKey) {
+ return delegate().subMap(fromKey, true, toKey, false);
+ }
+
+ @Override public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().tailMap(fromKey, inclusive);
+ }
+
+ @Override public SortedMap<K, V> tailMap(K fromKey) {
+ return tailMap(fromKey, true);
+ }
+
+ @Override public Comparator<? super K> comparator() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().comparator();
+ }
+
+ @Override public K firstKey() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().firstKey();
+ }
+
+ @Override public K lastKey() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().lastKey();
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ public static TestSuite suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(SynchronizedNavigableMapTest.class);
+ suite.addTest(
+ NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
+ private final Object mutex = new Integer(1);
+
+ @Override protected SortedMap<String, String> create(
+ Entry<String, String>[] entries) {
+ NavigableMap<String, String> innermost =
+ new SafeTreeMap<String, String>();
+ for (Entry<String, String> entry : entries) {
+ innermost.put(entry.getKey(), entry.getValue());
+ }
+ TestMap<String, String> inner =
+ new TestMap<String, String>(innermost, mutex);
+ NavigableMap<String, String> outer =
+ Synchronized.navigableMap(inner, mutex);
+ return outer;
+ }
+ }).named("Maps.synchronizedNavigableMap[SafeTreeMap]")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ MapFeature.GENERAL_PURPOSE, MapFeature.ALLOWS_NULL_VALUES)
+ .createTestSuite());
+
+ return suite;
+ }
+
+ public void testComparator() {
+ create().comparator();
+ }
+
+ public void testCeilingEntry() {
+ create().ceilingEntry("a");
+ }
+
+ public void testCeilingKey() {
+ create().ceilingKey("a");
+ }
+
+ public void testDescendingKeySet() {
+ NavigableMap<String, Integer> map = create();
+ NavigableSet<String> descendingKeySet = map.descendingKeySet();
+ assertTrue(descendingKeySet instanceof SynchronizedNavigableSet);
+ assertSame(
+ mutex, ((SynchronizedNavigableSet<String>) descendingKeySet).mutex);
+ }
+
+ public void testDescendingMap() {
+ NavigableMap<String, Integer> map = create();
+ NavigableMap<String, Integer> descendingMap = map.descendingMap();
+ assertTrue(descendingMap instanceof SynchronizedNavigableMap);
+ assertSame(mutex,
+ ((SynchronizedNavigableMap<String, Integer>) descendingMap).mutex);
+ }
+
+ public void testFirstEntry() {
+ create().firstEntry();
+ }
+
+ public void testFirstKey() {
+ NavigableMap<String, Integer> map = create();
+ map.put("a", 1);
+ map.firstKey();
+ }
+
+ public void testFloorEntry() {
+ create().floorEntry("a");
+ }
+
+ public void testFloorKey() {
+ create().floorKey("a");
+ }
+
+ public void testHeadMap_K() {
+ NavigableMap<String, Integer> map = create();
+ SortedMap<String, Integer> headMap = map.headMap("a");
+ assertTrue(headMap instanceof SynchronizedSortedMap);
+ assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) headMap).mutex);
+ }
+
+ public void testHeadMap_K_B() {
+ NavigableMap<String, Integer> map = create();
+ NavigableMap<String, Integer> headMap = map.headMap("a", true);
+ assertTrue(headMap instanceof SynchronizedNavigableMap);
+ assertSame(
+ mutex, ((SynchronizedNavigableMap<String, Integer>) headMap).mutex);
+ }
+
+ public void testHigherEntry() {
+ create().higherEntry("a");
+ }
+
+ public void testHigherKey() {
+ create().higherKey("a");
+ }
+
+ public void testLastEntry() {
+ create().lastEntry();
+ }
+
+ public void testLastKey() {
+ NavigableMap<String, Integer> map = create();
+ map.put("a", 1);
+ map.lastKey();
+ }
+
+ public void testLowerEntry() {
+ create().lowerEntry("a");
+ }
+
+ public void testLowerKey() {
+ create().lowerKey("a");
+ }
+
+ public void testNavigableKeySet() {
+ NavigableMap<String, Integer> map = create();
+ NavigableSet<String> navigableKeySet = map.navigableKeySet();
+ assertTrue(navigableKeySet instanceof SynchronizedNavigableSet);
+ assertSame(
+ mutex, ((SynchronizedNavigableSet<String>) navigableKeySet).mutex);
+ }
+
+ public void testPollFirstEntry() {
+ create().pollFirstEntry();
+ }
+
+ public void testPollLastEntry() {
+ create().pollLastEntry();
+ }
+
+ public void testSubMap_K_K() {
+ NavigableMap<String, Integer> map = create();
+ SortedMap<String, Integer> subMap = map.subMap("a", "b");
+ assertTrue(subMap instanceof SynchronizedSortedMap);
+ assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) subMap).mutex);
+ }
+
+ public void testSubMap_K_B_K_B() {
+ NavigableMap<String, Integer> map = create();
+ NavigableMap<String, Integer> subMap = map.subMap("a", true, "b", false);
+ assertTrue(subMap instanceof SynchronizedNavigableMap);
+ assertSame(
+ mutex, ((SynchronizedNavigableMap<String, Integer>) subMap).mutex);
+ }
+
+ public void testTailMap_K() {
+ NavigableMap<String, Integer> map = create();
+ SortedMap<String, Integer> subMap = map.tailMap("a");
+ assertTrue(subMap instanceof SynchronizedSortedMap);
+ assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) subMap).mutex);
+ }
+
+ public void testTailMap_K_B() {
+ NavigableMap<String, Integer> map = create();
+ NavigableMap<String, Integer> subMap = map.tailMap("a", true);
+ assertTrue(subMap instanceof SynchronizedNavigableMap);
+ assertSame(
+ mutex, ((SynchronizedNavigableMap<String, Integer>) subMap).mutex);
+ }
+
+ @Override public void testSerialization() {
+ SerializableTester.reserializeAndAssert(create());
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedNavigableSetTest.java b/guava-tests/test/com/google/common/collect/SynchronizedNavigableSetTest.java
new file mode 100644
index 0000000..9350f62
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/SynchronizedNavigableSetTest.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2010 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import com.google.common.collect.Synchronized.SynchronizedNavigableSet;
+import com.google.common.collect.Synchronized.SynchronizedSortedSet;
+import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
+import com.google.common.collect.testing.SafeTreeSet;
+import com.google.common.collect.testing.TestStringSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.testing.SerializableTester;
+
+import junit.framework.TestSuite;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Tests for {@link Sets#synchronizedNavigableSet(NavigableSet)}.
+ *
+ * @author Louis Wasserman
+ */
+public class SynchronizedNavigableSetTest extends SynchronizedSetTest {
+ @SuppressWarnings("unchecked")
+ @Override protected <E> NavigableSet<E> create() {
+ TestSet<E> inner = new TestSet<E>(
+ new TreeSet<E>((Comparator<E>) Ordering.natural().nullsFirst()), mutex);
+ NavigableSet<E> outer =
+ Synchronized.navigableSet(inner, mutex);
+ return outer;
+ }
+
+ static class TestSet<E> extends SynchronizedSetTest.TestSet<E>
+ implements NavigableSet<E> {
+
+ TestSet(NavigableSet<E> delegate, Object mutex) {
+ super(delegate, mutex);
+ }
+
+ @Override protected NavigableSet<E> delegate() {
+ return (NavigableSet<E>) super.delegate();
+ }
+
+ @Override public E ceiling(E e) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().ceiling(e);
+ }
+
+ @Override public Iterator<E> descendingIterator() {
+ return delegate().descendingIterator();
+ }
+
+ @Override public NavigableSet<E> descendingSet() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().descendingSet();
+ }
+
+ @Override public E floor(E e) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().floor(e);
+ }
+
+ @Override public NavigableSet<E> headSet(E toElement, boolean inclusive) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().headSet(toElement, inclusive);
+ }
+
+ @Override public SortedSet<E> headSet(E toElement) {
+ return headSet(toElement, false);
+ }
+
+ @Override public E higher(E e) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().higher(e);
+ }
+
+ @Override public E lower(E e) {
+ return delegate().lower(e);
+ }
+
+ @Override public E pollFirst() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().pollFirst();
+ }
+
+ @Override public E pollLast() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().pollLast();
+ }
+
+ @Override public NavigableSet<E> subSet(E fromElement,
+ boolean fromInclusive, E toElement, boolean toInclusive) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().subSet(
+ fromElement, fromInclusive, toElement, toInclusive);
+ }
+
+ @Override public SortedSet<E> subSet(E fromElement, E toElement) {
+ return subSet(fromElement, true, toElement, false);
+ }
+
+ @Override public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().tailSet(fromElement, inclusive);
+ }
+
+ @Override public SortedSet<E> tailSet(E fromElement) {
+ return tailSet(fromElement, true);
+ }
+
+ @Override public Comparator<? super E> comparator() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().comparator();
+ }
+
+ @Override public E first() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().first();
+ }
+
+ @Override public E last() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate().last();
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ public static TestSuite suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(SynchronizedNavigableSetTest.class);
+ suite.addTest(
+ NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ private final Object mutex = new Integer(1);
+
+ @Override protected Set<String> create(String[] elements) {
+ NavigableSet<String> innermost = new SafeTreeSet<String>();
+ innermost.addAll(Arrays.asList(elements));
+ TestSet<String> inner = new TestSet<String>(innermost, mutex);
+ NavigableSet<String> outer =
+ Synchronized.navigableSet(inner, mutex);
+ return outer;
+ }
+
+ @Override public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ }).named("Sets.synchronizedNavigableSet[SafeTreeSet]")
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE).createTestSuite());
+
+ return suite;
+ }
+
+ public void testComparator() {
+ create().comparator();
+ }
+
+ public void testCeiling() {
+ create().ceiling("a");
+ }
+
+ public void testFloor() {
+ create().floor("a");
+ }
+
+ public void testHigher() {
+ create().higher("a");
+ }
+
+ public void testLower() {
+ create().lower("a");
+ }
+
+ public void testDescendingSet() {
+ NavigableSet<String> map = create();
+ NavigableSet<String> descendingSet = map.descendingSet();
+ assertTrue(descendingSet instanceof SynchronizedNavigableSet);
+ assertSame(mutex, ((SynchronizedNavigableSet<String>) descendingSet).mutex);
+ }
+
+ public void testFirst() {
+ NavigableSet<String> set = create();
+ set.add("a");
+ set.first();
+ }
+
+ public void testPollFirst() {
+ create().pollFirst();
+ }
+
+ public void testLast() {
+ NavigableSet<String> set = create();
+ set.add("a");
+ set.last();
+ }
+
+ public void testPollLast() {
+ create().pollLast();
+ }
+
+ public void testHeadSet_E() {
+ NavigableSet<String> map = create();
+ SortedSet<String> headSet = map.headSet("a");
+ assertTrue(headSet instanceof SynchronizedSortedSet);
+ assertSame(mutex, ((SynchronizedSortedSet<String>) headSet).mutex);
+ }
+
+ public void testHeadSet_E_B() {
+ NavigableSet<String> map = create();
+ NavigableSet<String> headSet = map.headSet("a", true);
+ assertTrue(headSet instanceof SynchronizedNavigableSet);
+ assertSame(mutex, ((SynchronizedNavigableSet<String>) headSet).mutex);
+ }
+
+ public void testSubSet_E_E() {
+ NavigableSet<String> map = create();
+ SortedSet<String> subSet = map.subSet("a", "b");
+ assertTrue(subSet instanceof SynchronizedSortedSet);
+ assertSame(mutex, ((SynchronizedSortedSet<String>) subSet).mutex);
+ }
+
+ public void testSubSet_E_B_E_B() {
+ NavigableSet<String> map = create();
+ NavigableSet<String> subSet = map.subSet("a", false, "b", true);
+ assertTrue(subSet instanceof SynchronizedNavigableSet);
+ assertSame(mutex, ((SynchronizedNavigableSet<String>) subSet).mutex);
+ }
+
+ public void testTailSet_E() {
+ NavigableSet<String> map = create();
+ SortedSet<String> tailSet = map.tailSet("a");
+ assertTrue(tailSet instanceof SynchronizedSortedSet);
+ assertSame(mutex, ((SynchronizedSortedSet<String>) tailSet).mutex);
+ }
+
+ public void testTailSet_E_B() {
+ NavigableSet<String> map = create();
+ NavigableSet<String> tailSet = map.tailSet("a", true);
+ assertTrue(tailSet instanceof SynchronizedNavigableSet);
+ assertSame(mutex, ((SynchronizedNavigableSet<String>) tailSet).mutex);
+ }
+
+ @Override public void testSerialization() {
+ SerializableTester.reserializeAndAssert(create());
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java b/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java
new file mode 100644
index 0000000..4cce708
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/SynchronizedQueueTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.collect;
+
+import junit.framework.TestCase;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Queue;
+
+/**
+ * Tests for {@link Synchronized#queue} and {@link Queues#synchronizedQueue}.
+ *
+ * @author Kurt Alfred Kluever
+ */
+public class SynchronizedQueueTest extends TestCase {
+
+ protected Queue<String> create() {
+ TestQueue<String> inner = new TestQueue<String>();
+ Queue<String> outer = Synchronized.queue(inner, inner.mutex);
+ outer.add("foo"); // necessary because we try to remove elements later on
+ return outer;
+ }
+
+ private static final class TestQueue<E> implements Queue<E> {
+ private final Queue<E> delegate = Lists.newLinkedList();
+ public final Object mutex = new Integer(1); // something Serializable
+
+ @Override
+ public boolean offer(E o) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.offer(o);
+ }
+
+ @Override
+ public E poll() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.poll();
+ }
+
+ @Override
+ public E remove() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.remove();
+ }
+
+ @Override
+ public E peek() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.peek();
+ }
+
+ @Override
+ public E element() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.element();
+ }
+
+ @Override
+ public Iterator<E> iterator() {
+ // We explicitly don't lock for iterator()
+ assertFalse(Thread.holdsLock(mutex));
+ return delegate.iterator();
+ }
+
+ @Override
+ public int size() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.size();
+ }
+
+ @Override
+ public boolean removeAll(Collection<?> collection) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.removeAll(collection);
+ }
+
+ @Override
+ public boolean isEmpty() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object object) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.contains(object);
+ }
+
+ @Override
+ public boolean add(E element) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.add(element);
+ }
+
+ @Override
+ public boolean remove(Object object) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.remove(object);
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> collection) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.containsAll(collection);
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends E> collection) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.addAll(collection);
+ }
+
+ @Override
+ public boolean retainAll(Collection<?> collection) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.retainAll(collection);
+ }
+
+ @Override
+ public void clear() {
+ assertTrue(Thread.holdsLock(mutex));
+ delegate.clear();
+ }
+
+ @Override
+ public Object[] toArray() {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.toArray();
+ }
+
+ @Override
+ public <T> T[] toArray(T[] array) {
+ assertTrue(Thread.holdsLock(mutex));
+ return delegate.toArray(array);
+ }
+
+ private static final long serialVersionUID = 0;
+ }
+
+ public void testHoldsLockOnAllOperations() {
+ create().element();
+ create().offer("foo");
+ create().peek();
+ create().poll();
+ create().remove();
+ create().add("foo");
+ create().addAll(ImmutableList.of("foo"));
+ create().clear();
+ create().contains("foo");
+ create().containsAll(ImmutableList.of("foo"));
+ create().equals(ImmutableList.of("foo"));
+ create().hashCode();
+ create().isEmpty();
+ create().iterator();
+ create().remove("foo");
+ create().removeAll(ImmutableList.of("foo"));
+ create().retainAll(ImmutableList.of("foo"));
+ create().size();
+ create().toArray();
+ create().toArray(new String[] { "foo" });
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java b/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java
index a33d0b7..b14da0a 100644
--- a/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java
+++ b/guava-tests/test/com/google/common/collect/SynchronizedSetTest.java
@@ -41,7 +41,7 @@ public class SynchronizedSetTest extends AbstractCollectionTest {
return outer;
}
- @Override public void testNullPointerExceptions() throws Exception {
+ @Override public void testNullPointerExceptions() {
/* Skip this test, as SynchronizedSet is not a public class. */
}
diff --git a/guava-tests/test/com/google/common/collect/TableCollectionTest.java b/guava-tests/test/com/google/common/collect/TableCollectionTest.java
index 9eed028..2e85311 100644
--- a/guava-tests/test/com/google/common/collect/TableCollectionTest.java
+++ b/guava-tests/test/com/google/common/collect/TableCollectionTest.java
@@ -70,14 +70,14 @@ public class TableCollectionTest extends TestCase {
private static final Feature<?>[] COLLECTION_FEATURES_REMOVE = {
CollectionSize.ANY,
- CollectionFeature.REMOVE_OPERATIONS,
+ CollectionFeature.SUPPORTS_REMOVE,
CollectionFeature.ALLOWS_NULL_QUERIES
};
private static final Feature<?>[] COLLECTION_FEATURES_REMOVE_ORDER = {
CollectionSize.ANY,
CollectionFeature.KNOWN_ORDER,
- CollectionFeature.REMOVE_OPERATIONS,
+ CollectionFeature.SUPPORTS_REMOVE,
CollectionFeature.ALLOWS_NULL_QUERIES
};
@@ -214,7 +214,7 @@ public class TableCollectionTest extends TestCase {
.named("TreeBasedTable.rowKeySet.subSet")
.withFeatures(COLLECTION_FEATURES_REMOVE_ORDER)
.createTestSuite());
-
+
suite.addTest(SetTestSuiteBuilder.using(new TestStringSetGenerator() {
@Override protected Set<String> create(String[] elements) {
Table<String, Integer, Character> table = HashBasedTable.create();
@@ -458,7 +458,7 @@ public class TableCollectionTest extends TestCase {
}
})
.named("HashBasedTable.cellSet")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
+ .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -468,7 +468,7 @@ public class TableCollectionTest extends TestCase {
}
})
.named("TreeBasedTable.cellSet")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
+ .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -480,7 +480,7 @@ public class TableCollectionTest extends TestCase {
}
})
.named("TransposedTable.cellSet")
- .withFeatures(CollectionSize.ANY, CollectionFeature.REMOVE_OPERATIONS,
+ .withFeatures(CollectionSize.ANY, CollectionFeature.SUPPORTS_REMOVE,
CollectionFeature.ALLOWS_NULL_QUERIES)
.createTestSuite());
@@ -502,7 +502,8 @@ public class TableCollectionTest extends TestCase {
}
})
.named("TransformValues.cellSet")
- .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES)
+ .withFeatures(CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_QUERIES,
+ CollectionFeature.SUPPORTS_REMOVE)
.createTestSuite());
suite.addTest(SetTestSuiteBuilder.using(new TestCellSetGenerator() {
diff --git a/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java b/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java
index 99787a9..1ea040c 100644
--- a/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java
+++ b/guava-tests/test/com/google/common/collect/TablesTransformValuesTest.java
@@ -50,7 +50,7 @@ public class TablesTransformValuesTest extends AbstractTableTest {
// Null support depends on the underlying table and function.
@GwtIncompatible("NullPointerTester")
- @Override public void testNullPointerInstance() throws Exception {}
+ @Override public void testNullPointerInstance() {}
// put() and putAll() aren't supported.
@Override public void testPut() {
diff --git a/guava-tests/test/com/google/common/collect/TransformedImmutableListTest.java b/guava-tests/test/com/google/common/collect/TransformedImmutableListTest.java
deleted file mode 100644
index 03c2f6e..0000000
--- a/guava-tests/test/com/google/common/collect/TransformedImmutableListTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2010 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.ListTestSuiteBuilder;
-import com.google.common.collect.testing.TestStringListGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-
-import java.util.List;
-
-@GwtCompatible
-public class TransformedImmutableListTest extends TestCase {
- @GwtIncompatible("suite")
- public static Test suite() {
- return ListTestSuiteBuilder.using(new TestStringListGenerator() {
-
- @SuppressWarnings("serial")
- @Override protected List<String> create(String[] elements) {
- return new TransformedImmutableList<String, String>(
- ImmutableList.copyOf(elements)) {
-
- @Override String transform(String str) {
- return str;
- }
- };
- }
- }).named("TransformedImmutableList identity").withFeatures(
- CollectionSize.ANY,
- CollectionFeature.ALLOWS_NULL_QUERIES).createTestSuite();
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/TransformedSetTest.java b/guava-tests/test/com/google/common/collect/TransformedSetTest.java
deleted file mode 100644
index 8a26ed8..0000000
--- a/guava-tests/test/com/google/common/collect/TransformedSetTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.collect;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.SampleElements;
-import com.google.common.collect.testing.SetTestSuiteBuilder;
-import com.google.common.collect.testing.TestSetGenerator;
-import com.google.common.collect.testing.features.CollectionFeature;
-import com.google.common.collect.testing.features.CollectionSize;
-import com.google.common.collect.testing.features.SetFeature;
-
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Tests for {@link Sets#transform(Set, Sets.InvertibleFunction)}.
- *
- * @author Dimitris Andreou
- */
-@GwtCompatible(emulated = true)
-public class TransformedSetTest extends TestCase {
- // Negates each integer. This is a true bijection, even considering MIN_VALUE
- private static final Sets.InvertibleFunction<Integer, Integer> integerBijection =
- new Sets.InvertibleFunction<Integer, Integer>() {
- @Override public Integer apply(Integer integer) {
- return integer != null ? -integer : null;
- }
-
- @Override
- public Integer invert(Integer integer) {
- return integer != null ? -integer : null;
- }
- };
-
- @GwtIncompatible("suite")
- public static TestSuite suite() {
- TestSuite suite = new TestSuite();
- suite.addTest(SetTestSuiteBuilder
- .using(new TransformedIntegerSetGenerator())
- .named("TransformedSet")
- .withFeatures(
- SetFeature.GENERAL_PURPOSE,
- CollectionFeature.ALLOWS_NULL_VALUES,
- CollectionSize.SEVERAL)
- .createTestSuite());
- return suite;
- }
-
- public void testSimpleCases() {
- Set<Integer> original = Sets.newHashSet(0, 1, 2, 3);
- Set<Integer> transformed = Sets.transform(original, integerBijection);
-
- assertEquals(ImmutableSet.of(0, -1, -2, -3), transformed);
-
- // adding/removing to the original, see if transformed is affected
- assertTrue(original.remove(2));
- assertTrue(original.add(4));
- assertEquals(ImmutableSet.of(0, 1, 3, 4), original);
- assertEquals(ImmutableSet.of(0, -1, -3, -4), transformed);
-
- // adding/removing to the transformed, see if original is affected
- assertTrue(transformed.remove(-1));
- assertTrue(transformed.add(-5));
- assertEquals(ImmutableSet.of(0, -3, -4, -5), transformed);
- assertEquals(ImmutableSet.of(0, 3, 4, 5), original);
-
- // redoing the same actions as above; no effect
- assertFalse(transformed.remove(-1));
- assertFalse(transformed.add(-5));
-
- // they should always have the same size
- assertEquals(original.size(), transformed.size());
-
- transformed.clear();
- assertTrue(original.isEmpty());
- assertTrue(transformed.isEmpty());
- }
-
- public static class TransformedIntegerSetGenerator implements TestSetGenerator<Integer> {
- @Override public Set<Integer> create(Object... elements) {
- // Would use Collections#checkedCollection, but I get:
- // [ERROR] The method checkedCollection(Collection, Class<Integer>)
- // is undefined for the type Collections
- @SuppressWarnings("unchecked")
- Iterable<Integer> integers = (Iterable) Arrays.asList(elements);
-
- // I invert these before adding, so that the transformed set will have
- // the expected elements themselves, not their image under the bijection
- Set<Integer> invertedIntegers = Sets.newHashSet(Iterables.transform(integers,
- integerBijection.inverse()));
- return Sets.transform(invertedIntegers, integerBijection);
- }
-
- @Override public Integer[] createArray(int length) {
- return new Integer[length];
- }
-
- @Override public SampleElements<Integer> samples() {
- return new SampleElements<Integer>(-1, 0, 1, 2, 3);
- }
-
- @Override public Iterable<Integer> order(List<Integer> insertionOrder) {
- throw new AssertionError();
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java b/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java
index f4469ca..81550f8 100644
--- a/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java
+++ b/guava-tests/test/com/google/common/collect/TreeBasedTableTest.java
@@ -16,13 +16,13 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.MapTestSuiteBuilder;
import com.google.common.collect.testing.SortedMapInterfaceTest;
-import com.google.common.collect.testing.TestStringMapGenerator;
+import com.google.common.collect.testing.SortedMapTestSuiteBuilder;
+import com.google.common.collect.testing.TestStringSortedMapGenerator;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
import com.google.common.testing.SerializableTester;
@@ -39,19 +39,20 @@ import java.util.SortedMap;
/**
* Test cases for {@link TreeBasedTable}.
- *
+ *
* @author Jared Levy
* @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
public class TreeBasedTableTest extends AbstractTableTest {
- public static Test suite(){
+ @GwtIncompatible("suite")
+ public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite(TreeBasedTableTest.class);
suite.addTestSuite(TreeRowTest.class);
- suite.addTest(MapTestSuiteBuilder
- .using(new TestStringMapGenerator() {
- @Override protected Map<String, String> create(
+ suite.addTest(SortedMapTestSuiteBuilder
+ .using(new TestStringSortedMapGenerator() {
+ @Override protected SortedMap<String, String> create(
Entry<String, String>[] entries) {
TreeBasedTable<String, String, String> table =
TreeBasedTable.create();
@@ -67,7 +68,7 @@ public class TreeBasedTableTest extends AbstractTableTest {
.named("RowMapTestSuite").createTestSuite());
return suite;
}
-
+
public static class TreeRowTest extends
SortedMapInterfaceTest<String, String> {
public TreeRowTest() {
@@ -118,7 +119,7 @@ public class TreeBasedTableTest extends AbstractTableTest {
}
private TreeBasedTable<String, Integer, Character> sortedTable;
-
+
protected TreeBasedTable<String, Integer, Character> create(
Comparator<? super String> rowComparator,
Comparator<? super Integer> columnComparator,
@@ -131,7 +132,7 @@ public class TreeBasedTableTest extends AbstractTableTest {
populate(table, data);
return table;
}
-
+
@Override protected TreeBasedTable<String, Integer, Character> create(
Object... data) {
TreeBasedTable<String, Integer, Character> table = TreeBasedTable.create();
@@ -140,8 +141,8 @@ public class TreeBasedTableTest extends AbstractTableTest {
table.clear();
populate(table, data);
return table;
- }
-
+ }
+
public void testCreateExplicitComparators() {
table = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
@@ -149,10 +150,10 @@ public class TreeBasedTableTest extends AbstractTableTest {
table.put("foo", 12, 'b');
table.put("bar", 5, 'c');
table.put("cat", 8, 'd');
- ASSERT.that(table.rowKeySet()).hasContentsInOrder("foo", "cat", "bar");
- ASSERT.that(table.row("foo").keySet()).hasContentsInOrder(12, 3);
+ ASSERT.that(table.rowKeySet()).has().allOf("foo", "cat", "bar").inOrder();
+ ASSERT.that(table.row("foo").keySet()).has().allOf(12, 3).inOrder();
}
-
+
public void testCreateCopy() {
TreeBasedTable<String, Integer, Character> original = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
@@ -161,127 +162,127 @@ public class TreeBasedTableTest extends AbstractTableTest {
original.put("bar", 5, 'c');
original.put("cat", 8, 'd');
table = TreeBasedTable.create(original);
- ASSERT.that(table.rowKeySet()).hasContentsInOrder("foo", "cat", "bar");
- ASSERT.that(table.row("foo").keySet()).hasContentsInOrder(12, 3);
+ ASSERT.that(table.rowKeySet()).has().allOf("foo", "cat", "bar").inOrder();
+ ASSERT.that(table.row("foo").keySet()).has().allOf(12, 3).inOrder();
assertEquals(original, table);
}
-
+
@GwtIncompatible("SerializableTester")
public void testSerialization() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
SerializableTester.reserializeAndAssert(table);
}
-
+
public void testToString_ordered() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
assertEquals("{bar={1=b}, foo={1=a, 3=c}}", table.toString());
assertEquals("{bar={1=b}, foo={1=a, 3=c}}", table.rowMap().toString());
}
-
+
public void testCellSetToString_ordered() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
assertEquals("[(bar,1)=b, (foo,1)=a, (foo,3)=c]",
- table.cellSet().toString());
+ table.cellSet().toString());
}
-
+
public void testRowKeySetToString_ordered() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertEquals("[bar, foo]", table.rowKeySet().toString());
+ assertEquals("[bar, foo]", table.rowKeySet().toString());
}
-
+
public void testValuesToString_ordered() {
table = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertEquals("[b, a, c]", table.values().toString());
+ assertEquals("[b, a, c]", table.values().toString());
}
-
+
public void testRowComparator() {
sortedTable = TreeBasedTable.create();
assertSame(Ordering.natural(), sortedTable.rowComparator());
-
+
sortedTable = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
assertSame(Collections.reverseOrder(), sortedTable.rowComparator());
}
-
+
public void testColumnComparator() {
sortedTable = TreeBasedTable.create();
assertSame(Ordering.natural(), sortedTable.columnComparator());
-
+
sortedTable = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
assertSame(Ordering.usingToString(), sortedTable.columnComparator());
}
-
+
public void testRowKeySetComparator() {
sortedTable = TreeBasedTable.create();
assertSame(Ordering.natural(),
sortedTable.rowKeySet().comparator());
-
+
sortedTable = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
assertSame(Collections.reverseOrder(),
sortedTable.rowKeySet().comparator());
}
-
+
public void testRowKeySetFirst() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertSame("bar", sortedTable.rowKeySet().first());
- }
-
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ assertSame("bar", sortedTable.rowKeySet().first());
+ }
+
public void testRowKeySetLast() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertSame("foo", sortedTable.rowKeySet().last());
- }
-
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ assertSame("foo", sortedTable.rowKeySet().last());
+ }
+
public void testRowKeySetHeadSet() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Set<String> set = sortedTable.rowKeySet().headSet("cat");
assertEquals(Collections.singleton("bar"), set);
set.clear();
assertTrue(set.isEmpty());
assertEquals(Collections.singleton("foo"), sortedTable.rowKeySet());
- }
-
+ }
+
public void testRowKeySetTailSet() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Set<String> set = sortedTable.rowKeySet().tailSet("cat");
assertEquals(Collections.singleton("foo"), set);
set.clear();
assertTrue(set.isEmpty());
assertEquals(Collections.singleton("bar"), sortedTable.rowKeySet());
}
-
+
public void testRowKeySetSubSet() {
sortedTable = create(
- "foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
+ "foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
Set<String> set = sortedTable.rowKeySet().subSet("cat", "egg");
assertEquals(Collections.singleton("dog"), set);
set.clear();
assertTrue(set.isEmpty());
assertEquals(ImmutableSet.of("bar", "foo"), sortedTable.rowKeySet());
}
-
+
public void testRowMapComparator() {
sortedTable = TreeBasedTable.create();
assertSame(Ordering.natural(), sortedTable.rowMap().comparator());
-
+
sortedTable = TreeBasedTable.create(
Collections.reverseOrder(), Ordering.usingToString());
assertSame(Collections.reverseOrder(), sortedTable.rowMap().comparator());
- }
-
+ }
+
public void testRowMapFirstKey() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertSame("bar", sortedTable.rowMap().firstKey());
- }
-
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ assertSame("bar", sortedTable.rowMap().firstKey());
+ }
+
public void testRowMapLastKey() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
- assertSame("foo", sortedTable.rowMap().lastKey());
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ assertSame("foo", sortedTable.rowMap().lastKey());
}
-
+
public void testRowKeyMapHeadMap() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Map<String, Map<Integer, Character>> map
= sortedTable.rowMap().headMap("cat");
assertEquals(1, map.size());
@@ -289,10 +290,10 @@ public class TreeBasedTableTest extends AbstractTableTest {
map.clear();
assertTrue(map.isEmpty());
assertEquals(Collections.singleton("foo"), sortedTable.rowKeySet());
- }
-
+ }
+
public void testRowKeyMapTailMap() {
- sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
+ sortedTable = create("foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c');
Map<String, Map<Integer, Character>> map
= sortedTable.rowMap().tailMap("cat");
assertEquals(1, map.size());
@@ -301,10 +302,10 @@ public class TreeBasedTableTest extends AbstractTableTest {
assertTrue(map.isEmpty());
assertEquals(Collections.singleton("bar"), sortedTable.rowKeySet());
}
-
+
public void testRowKeyMapSubMap() {
sortedTable = create(
- "foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
+ "foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
Map<String, Map<Integer, Character>> map
= sortedTable.rowMap().subMap("cat", "egg");
assertEquals(ImmutableMap.of(2, 'd'), map.get("dog"));
@@ -312,13 +313,13 @@ public class TreeBasedTableTest extends AbstractTableTest {
assertTrue(map.isEmpty());
assertEquals(ImmutableSet.of("bar", "foo"), sortedTable.rowKeySet());
}
-
- public void testRowMapValuesAreSorted(){
+
+ public void testRowMapValuesAreSorted() {
sortedTable = create(
"foo", 1, 'a', "bar", 1, 'b', "foo", 3, 'c', "dog", 2, 'd');
assertTrue(sortedTable.rowMap().get("foo") instanceof SortedMap);
}
-
+
public void testColumnKeySet_isSorted() {
table = create("a", 2, 'X',
"a", 2, 'X',
@@ -334,7 +335,7 @@ public class TreeBasedTableTest extends AbstractTableTest {
);
assertEquals("[1, 2, 3, 5, 10, 15, 20]", table.columnKeySet().toString());
}
-
+
public void testColumnKeySet_isSortedWithRealComparator() {
table = create(String.CASE_INSENSITIVE_ORDER,
Ordering.natural().reverse(),
@@ -351,33 +352,33 @@ public class TreeBasedTableTest extends AbstractTableTest {
"e", 5, 'X'
);
assertEquals("[20, 15, 10, 5, 3, 2, 1]", table.columnKeySet().toString());
- }
-
+ }
+
public void testColumnKeySet_empty() {
table = create();
assertEquals("[]", table.columnKeySet().toString());
}
-
+
public void testColumnKeySet_oneRow() {
table = create("a", 2, 'X',
"a", 1, 'X'
);
assertEquals("[1, 2]", table.columnKeySet().toString());
}
-
+
public void testColumnKeySet_oneColumn() {
table = create("a", 1, 'X',
"b", 1, 'X'
);
assertEquals("[1]", table.columnKeySet().toString());
}
-
+
public void testColumnKeySet_oneEntry() {
table = create("a", 1, 'X');
assertEquals("[1]", table.columnKeySet().toString());
}
- public void testRowEntrySetContains(){
+ public void testRowEntrySetContains() {
table =
sortedTable =
create("a", 2, 'X', "a", 2, 'X', "b", 3, 'X', "b", 2, 'X', "c", 10,
@@ -394,7 +395,7 @@ public class TreeBasedTableTest extends AbstractTableTest {
assertFalse(entrySet.contains(Maps.immutableEntry(15, 'X')));
}
- public void testRowEntrySetRemove(){
+ public void testRowEntrySetRemove() {
table =
sortedTable =
create("a", 2, 'X', "a", 2, 'X', "b", 3, 'X', "b", 2, 'X', "c", 10,
@@ -410,8 +411,8 @@ public class TreeBasedTableTest extends AbstractTableTest {
assertFalse(entrySet.remove(Maps.immutableEntry(20, 'X')));
assertFalse(entrySet.remove(Maps.immutableEntry(15, 'X')));
}
-
- public void testRowSize(){
+
+ public void testRowSize() {
table =
sortedTable =
create("a", 2, 'X', "a", 2, 'X', "b", 3, 'X', "b", 2, 'X', "c", 10,
diff --git a/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java b/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java
index bc9b68f..3269397 100644
--- a/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java
+++ b/guava-tests/test/com/google/common/collect/TreeMultimapExplicitTest.java
@@ -16,7 +16,7 @@
package com.google.common.collect;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
@@ -96,13 +96,13 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest {
tree.put("google", 6);
tree.put("tree", 0);
tree.put("tree", 3);
- ASSERT.that(tree.keySet()).hasContentsInOrder("tree", "google");
- ASSERT.that(tree.get("google")).hasContentsInOrder(6, 2);
+ ASSERT.that(tree.keySet()).has().allOf("tree", "google").inOrder();
+ ASSERT.that(tree.get("google")).has().allOf(6, 2).inOrder();
TreeMultimap<String, Integer> copy = TreeMultimap.create(tree);
assertEquals(tree, copy);
- ASSERT.that(copy.keySet()).hasContentsInOrder("google", "tree");
- ASSERT.that(copy.get("google")).hasContentsInOrder(2, 6);
+ ASSERT.that(copy.keySet()).has().allOf("google", "tree").inOrder();
+ ASSERT.that(copy.get("google")).has().allOf(2, 6).inOrder();
assertEquals(Ordering.natural(), copy.keyComparator());
assertEquals(Ordering.natural(), copy.valueComparator());
assertEquals(Ordering.natural(), copy.get("google").comparator());
@@ -121,14 +121,14 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest {
public void testOrderedGet() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.get(null)).hasContentsInOrder(7, 3, 1);
- ASSERT.that(multimap.get("google")).hasContentsInOrder(6, 2);
- ASSERT.that(multimap.get("tree")).hasContentsInOrder(null, 0);
+ ASSERT.that(multimap.get(null)).has().allOf(7, 3, 1).inOrder();
+ ASSERT.that(multimap.get("google")).has().allOf(6, 2).inOrder();
+ ASSERT.that(multimap.get("tree")).has().allOf(null, 0).inOrder();
}
public void testOrderedKeySet() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.keySet()).hasContentsInOrder(null, "tree", "google");
+ ASSERT.that(multimap.keySet()).has().allOf(null, "tree", "google").inOrder();
}
public void testOrderedAsMapEntries() {
@@ -137,29 +137,30 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest {
multimap.asMap().entrySet().iterator();
Map.Entry<String, Collection<Integer>> entry = iterator.next();
assertEquals(null, entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsAnyOrder(7, 3, 1);
+ ASSERT.that(entry.getValue()).has().allOf(7, 3, 1);
entry = iterator.next();
assertEquals("tree", entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsAnyOrder(null, 0);
+ ASSERT.that(entry.getValue()).has().allOf(null, 0);
entry = iterator.next();
assertEquals("google", entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsAnyOrder(6, 2);
+ ASSERT.that(entry.getValue()).has().allOf(6, 2);
}
public void testOrderedEntries() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.entries()).hasContentsInOrder(
+ ASSERT.that(multimap.entries()).has().allOf(
Maps.immutableEntry((String) null, 7),
Maps.immutableEntry((String) null, 3),
Maps.immutableEntry((String) null, 1),
Maps.immutableEntry("tree", (Integer) null),
Maps.immutableEntry("tree", 0),
- Maps.immutableEntry("google", 6), Maps.immutableEntry("google", 2));
+ Maps.immutableEntry("google", 6),
+ Maps.immutableEntry("google", 2)).inOrder();
}
public void testOrderedValues() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.values()).hasContentsInOrder(7, 3, 1, null, 0, 6, 2);
+ ASSERT.that(multimap.values()).has().allOf(7, 3, 1, null, 0, 6, 2).inOrder();
}
public void testComparator() {
@@ -196,8 +197,8 @@ public class TreeMultimapExplicitTest extends AbstractSetMultimapTest {
TreeMultimap<String, Integer> multimap = createPopulate();
TreeMultimap<String, Integer> copy
= SerializableTester.reserializeAndAssert(multimap);
- ASSERT.that(copy.values()).hasContentsInOrder(7, 3, 1, null, 0, 6, 2);
- ASSERT.that(copy.keySet()).hasContentsInOrder(null, "tree", "google");
+ ASSERT.that(copy.values()).has().allOf(7, 3, 1, null, 0, 6, 2).inOrder();
+ ASSERT.that(copy.keySet()).has().allOf(null, "tree", "google").inOrder();
assertEquals(multimap.keyComparator(), copy.keyComparator());
assertEquals(multimap.valueComparator(), copy.valueComparator());
}
diff --git a/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java b/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java
index 5416a1d..1ee1320 100644
--- a/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java
+++ b/guava-tests/test/com/google/common/collect/TreeMultimapNaturalTest.java
@@ -16,26 +16,39 @@
package com.google.common.collect;
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Sets.newHashSet;
-import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
-import static java.util.Arrays.asList;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.DerivedComparable;
-import com.google.common.collect.testing.IteratorTester;
+import com.google.common.collect.testing.Helpers;
+import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
+import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.TestSortedMapGenerator;
+import com.google.common.collect.testing.TestStringSetGenerator;
+import com.google.common.collect.testing.TestStringSortedSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.google.SortedSetMultimapTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringSetMultimapGenerator;
import com.google.common.testing.SerializableTester;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.NoSuchElementException;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
@@ -46,7 +59,196 @@ import java.util.SortedSet;
* @author Jared Levy
*/
@GwtCompatible(emulated = true)
-public class TreeMultimapNaturalTest<E> extends AbstractSetMultimapTest {
+public class TreeMultimapNaturalTest extends AbstractSetMultimapTest {
+
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ // TODO(user): should we force TreeMultimap to be more thorough about checking nulls?
+ suite.addTest(SortedSetMultimapTestSuiteBuilder.using(new TestStringSetMultimapGenerator() {
+ @Override
+ protected SetMultimap<String, String> create(Entry<String, String>[] entries) {
+ SetMultimap<String, String> multimap = TreeMultimap.create(
+ Ordering.natural().nullsFirst(), Ordering.natural().nullsFirst());
+ for (Entry<String, String> entry : entries) {
+ multimap.put(entry.getKey(), entry.getValue());
+ }
+ return multimap;
+ }
+
+ @Override
+ public Iterable<Entry<String, String>> order(List<Entry<String, String>> insertionOrder) {
+ return new Ordering<Entry<String, String>>() {
+ @Override
+ public int compare(Entry<String, String> left, Entry<String, String> right) {
+ return ComparisonChain.start()
+ .compare(left.getKey(), right.getKey(), Ordering.natural().nullsFirst())
+ .compare(left.getValue(), right.getValue(), Ordering.natural().nullsFirst())
+ .result();
+ }
+ }.sortedCopy(insertionOrder);
+ }
+ })
+ .named("TreeMultimap nullsFirst")
+ .withFeatures(
+ MapFeature.ALLOWS_NULL_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ MapFeature.GENERAL_PURPOSE,
+ MapFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.SERIALIZABLE,
+ CollectionSize.ANY)
+ .createTestSuite());
+ suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSortedSetGenerator() {
+ @Override
+ protected NavigableSet<String> create(String[] elements) {
+ TreeMultimap<String, Integer> multimap = TreeMultimap.create(
+ Ordering.natural().nullsFirst(), Ordering.natural());
+ for (int i = 0; i < elements.length; i++) {
+ multimap.put(elements[i], i);
+ }
+ return multimap.keySet();
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().nullsFirst().sortedCopy(insertionOrder);
+ }
+ })
+ .named("TreeMultimap.keySet")
+ .withFeatures(
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.SUPPORTS_REMOVE,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionSize.ANY)
+ .createTestSuite());
+ suite.addTest(NavigableMapTestSuiteBuilder.using(
+ new TestSortedMapGenerator<String, Collection<String>>() {
+
+ @Override
+ public String[] createKeyArray(int length) {
+ return new String[length];
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Collection<String>[] createValueArray(int length) {
+ return new Collection[length];
+ }
+
+ @Override
+ public SampleElements<Entry<String, Collection<String>>> samples() {
+ return new SampleElements<Entry<String, Collection<String>>>(
+ Helpers.mapEntry("a", (Collection<String>) ImmutableSortedSet.of("alex")),
+ Helpers.mapEntry("b", (Collection<String>) ImmutableSortedSet.of("bob", "bagel")),
+ Helpers.mapEntry("c", (Collection<String>) ImmutableSortedSet.of("carl", "carol")),
+ Helpers.mapEntry("d", (Collection<String>) ImmutableSortedSet.of("david", "dead")),
+ Helpers.mapEntry("e", (Collection<String>) ImmutableSortedSet.of("eric", "elaine")));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Entry<String, Collection<String>>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<String, Collection<String>>> order(
+ List<Entry<String, Collection<String>>> insertionOrder) {
+ return new Ordering<Entry<String, ?>>() {
+ @Override
+ public int compare(Entry<String, ?> left, Entry<String, ?> right) {
+ return left.getKey().compareTo(right.getKey());
+ }
+ }.sortedCopy(insertionOrder);
+ }
+
+ @Override
+ public NavigableMap<String, Collection<String>> create(Object... elements) {
+ TreeMultimap<String, String> multimap = TreeMultimap.create();
+ for (Object o : elements) {
+ @SuppressWarnings("unchecked")
+ Entry<String, Collection<String>> entry = (Entry<String, Collection<String>>) o;
+ checkArgument(!multimap.containsKey(entry.getKey()));
+ multimap.putAll(entry.getKey(), entry.getValue());
+ }
+ return multimap.asMap();
+ }
+
+ @Override
+ public Entry<String, Collection<String>> belowSamplesLesser() {
+ return Helpers.mapEntry("-- a", (Collection<String>) ImmutableSortedSet.of("--below"));
+ }
+
+ @Override
+ public Entry<String, Collection<String>> belowSamplesGreater() {
+ return Helpers.mapEntry("-- b", (Collection<String>) ImmutableSortedSet.of("--below"));
+ }
+
+ @Override
+ public Entry<String, Collection<String>> aboveSamplesLesser() {
+ return Helpers.mapEntry("~~ b", (Collection<String>) ImmutableSortedSet.of("~above"));
+ }
+
+ @Override
+ public Entry<String, Collection<String>> aboveSamplesGreater() {
+ return Helpers.mapEntry("~~ c", (Collection<String>) ImmutableSortedSet.of("~above"));
+ }
+ })
+ .named("TreeMultimap.asMap")
+ .withFeatures(
+ MapFeature.SUPPORTS_REMOVE,
+ MapFeature.REJECTS_DUPLICATES_AT_CREATION,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionSize.ANY)
+ .createTestSuite());
+ suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override
+ protected Set<String> create(String[] elements) {
+ TreeMultimap<Integer, String> multimap = TreeMultimap.create(
+ Ordering.natural(), Ordering.natural().nullsFirst());
+ multimap.putAll(1, Arrays.asList(elements));
+ return multimap.get(1);
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().nullsFirst().sortedCopy(insertionOrder);
+ }
+ })
+ .named("TreeMultimap.get")
+ .withFeatures(
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.GENERAL_PURPOSE,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionSize.ANY)
+ .createTestSuite());
+ suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override
+ protected Set<String> create(String[] elements) {
+ TreeMultimap<Integer, String> multimap = TreeMultimap.create(
+ Ordering.natural(), Ordering.natural().nullsFirst());
+ multimap.putAll(1, Arrays.asList(elements));
+ return (Set<String>) multimap.asMap().entrySet().iterator().next().getValue();
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().nullsFirst().sortedCopy(insertionOrder);
+ }
+ })
+ .named("TreeMultimap.asMap.entrySet collection")
+ .withFeatures(
+ CollectionFeature.ALLOWS_NULL_VALUES,
+ CollectionFeature.GENERAL_PURPOSE,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionSize.ONE,
+ CollectionSize.SEVERAL)
+ .createTestSuite());
+ suite.addTestSuite(TreeMultimapNaturalTest.class);
+ return suite;
+ }
+
@Override protected Multimap<String, Integer> create() {
return TreeMultimap.create();
}
@@ -83,14 +285,14 @@ public class TreeMultimapNaturalTest<E> extends AbstractSetMultimapTest {
public void testOrderedGet() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.get("foo")).hasContentsInOrder(1, 3, 7);
- ASSERT.that(multimap.get("google")).hasContentsInOrder(2, 6);
- ASSERT.that(multimap.get("tree")).hasContentsInOrder(0, 4);
+ ASSERT.that(multimap.get("foo")).has().allOf(1, 3, 7).inOrder();
+ ASSERT.that(multimap.get("google")).has().allOf(2, 6).inOrder();
+ ASSERT.that(multimap.get("tree")).has().allOf(0, 4).inOrder();
}
public void testOrderedKeySet() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.keySet()).hasContentsInOrder("foo", "google", "tree");
+ ASSERT.that(multimap.keySet()).has().allOf("foo", "google", "tree").inOrder();
}
public void testOrderedAsMapEntries() {
@@ -99,95 +301,31 @@ public class TreeMultimapNaturalTest<E> extends AbstractSetMultimapTest {
multimap.asMap().entrySet().iterator();
Map.Entry<String, Collection<Integer>> entry = iterator.next();
assertEquals("foo", entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsAnyOrder(1, 3, 7);
+ ASSERT.that(entry.getValue()).has().allOf(1, 3, 7);
entry = iterator.next();
assertEquals("google", entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsAnyOrder(2, 6);
+ ASSERT.that(entry.getValue()).has().allOf(2, 6);
entry = iterator.next();
assertEquals("tree", entry.getKey());
- ASSERT.that(entry.getValue()).hasContentsAnyOrder(0, 4);
+ ASSERT.that(entry.getValue()).has().allOf(0, 4);
}
public void testOrderedEntries() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.entries()).hasContentsInOrder(
+ ASSERT.that(multimap.entries()).has().allOf(
Maps.immutableEntry("foo", 1),
Maps.immutableEntry("foo", 3),
Maps.immutableEntry("foo", 7),
Maps.immutableEntry("google", 2),
Maps.immutableEntry("google", 6),
Maps.immutableEntry("tree", 0),
- Maps.immutableEntry("tree", 4));
+ Maps.immutableEntry("tree", 4)).inOrder();
}
public void testOrderedValues() {
TreeMultimap<String, Integer> multimap = createPopulate();
- ASSERT.that(multimap.values()).hasContentsInOrder(
- 1, 3, 7, 2, 6, 0, 4);
- }
-
- public void testFirst() {
- TreeMultimap<String, Integer> multimap = createPopulate();
- assertEquals(Integer.valueOf(1), multimap.get("foo").first());
- try {
- multimap.get("missing").first();
- fail("Expected NoSuchElementException");
- } catch (NoSuchElementException expected) {}
- }
-
- public void testLast() {
- TreeMultimap<String, Integer> multimap = createPopulate();
- assertEquals(Integer.valueOf(7), multimap.get("foo").last());
- try {
- multimap.get("missing").last();
- fail("Expected NoSuchElementException");
- } catch (NoSuchElementException expected) {}
- }
-
- public void testComparatorFromGet() {
- TreeMultimap<String, Integer> multimap = createPopulate();
- assertSame(Ordering.natural(), multimap.get("foo").comparator());
- assertSame(Ordering.natural(), multimap.get("missing").comparator());
- }
-
- public void testHeadSet() {
- TreeMultimap<String, Integer> multimap = createPopulate();
- Set<Integer> fooSet = multimap.get("foo").headSet(4);
- assertEquals(Sets.newHashSet(1, 3), fooSet);
- Set<Integer> missingSet = multimap.get("missing").headSet(4);
- assertEquals(Sets.newHashSet(), missingSet);
-
- multimap.put("foo", 0);
- assertEquals(Sets.newHashSet(0, 1, 3), fooSet);
-
- missingSet.add(2);
- assertEquals(Sets.newHashSet(2), multimap.get("missing"));
- }
-
- public void testTailSet() {
- TreeMultimap<String, Integer> multimap = createPopulate();
- Set<Integer> fooSet = multimap.get("foo").tailSet(2);
- assertEquals(Sets.newHashSet(3, 7), fooSet);
- Set<Integer> missingSet = multimap.get("missing").tailSet(4);
- assertEquals(Sets.newHashSet(), missingSet);
-
- multimap.put("foo", 6);
- assertEquals(Sets.newHashSet(3, 6, 7), fooSet);
-
- missingSet.add(9);
- assertEquals(Sets.newHashSet(9), multimap.get("missing"));
- }
-
- public void testSubSet() {
- TreeMultimap<String, Integer> multimap = createPopulate();
- Set<Integer> fooSet = multimap.get("foo").subSet(2, 6);
- assertEquals(Sets.newHashSet(3), fooSet);
-
- multimap.put("foo", 5);
- assertEquals(Sets.newHashSet(3, 5), fooSet);
-
- fooSet.add(4);
- assertEquals(Sets.newHashSet(1, 3, 4, 5, 7), multimap.get("foo"));
+ ASSERT.that(multimap.values()).has().allOf(
+ 1, 3, 7, 2, 6, 0, 4).inOrder();
}
public void testMultimapConstructor() {
@@ -196,7 +334,7 @@ public class TreeMultimapNaturalTest<E> extends AbstractSetMultimapTest {
assertEquals(multimap, copy);
}
- private static final Comparator<Double> KEY_COMPARATOR =
+ private static final Comparator<Double> KEY_COMPARATOR =
Ordering.natural();
private static final Comparator<Double> VALUE_COMPARATOR =
@@ -262,209 +400,13 @@ public class TreeMultimapNaturalTest<E> extends AbstractSetMultimapTest {
assertEquals(Ordering.natural(), multimap.valueComparator());
}
- public void testSortedKeySet() {
- TreeMultimap<String, Integer> multimap = createPopulate();
- SortedSet<String> keySet = multimap.keySet();
-
- assertEquals("foo", keySet.first());
- assertEquals("tree", keySet.last());
- assertEquals(Ordering.natural(), keySet.comparator());
- assertEquals(ImmutableSet.of("foo", "google"), keySet.headSet("hi"));
- assertEquals(ImmutableSet.of("tree"), keySet.tailSet("hi"));
- assertEquals(ImmutableSet.of("google"), keySet.subSet("gap", "hi"));
- }
-
- public void testKeySetSubSet() {
- TreeMultimap<String, Integer> multimap = createPopulate();
- SortedSet<String> keySet = multimap.keySet();
- SortedSet<String> subSet = keySet.subSet("gap", "hi");
-
- assertEquals(1, subSet.size());
- assertTrue(subSet.contains("google"));
- assertFalse(subSet.contains("foo"));
- assertTrue(subSet.containsAll(Collections.singleton("google")));
- assertFalse(subSet.containsAll(Collections.singleton("foo")));
-
- Iterator<String> iterator = subSet.iterator();
- assertTrue(iterator.hasNext());
- assertEquals("google", iterator.next());
- assertFalse(iterator.hasNext());
-
- assertFalse(subSet.remove("foo"));
- assertTrue(multimap.containsKey("foo"));
- assertEquals(7, multimap.size());
- assertTrue(subSet.remove("google"));
- assertFalse(multimap.containsKey("google"));
- assertEquals(5, multimap.size());
- }
-
- @GwtIncompatible("unreasonable slow")
- public void testGetIteration() {
- new IteratorTester<Integer>(6, MODIFIABLE,
- Sets.newTreeSet(asList(2, 3, 4, 7, 8)),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- private Multimap<String, Integer> multimap;
-
- @Override protected Iterator<Integer> newTargetIterator() {
- multimap = create();
- multimap.putAll("foo", asList(3, 8, 4));
- multimap.putAll("bar", asList(5, 6));
- multimap.putAll("foo", asList(7, 2));
- return multimap.get("foo").iterator();
- }
-
- @Override protected void verify(List<Integer> elements) {
- assertEquals(newHashSet(elements), multimap.get("foo"));
- }
- }.test();
- }
-
- @SuppressWarnings("unchecked")
- @GwtIncompatible("unreasonable slow")
- public void testEntriesIteration() {
- Set<Entry<String, Integer>> set = Sets.newLinkedHashSet(asList(
- Maps.immutableEntry("bar", 4),
- Maps.immutableEntry("bar", 5),
- Maps.immutableEntry("foo", 2),
- Maps.immutableEntry("foo", 3),
- Maps.immutableEntry("foo", 6)));
- new IteratorTester<Entry<String, Integer>>(6, MODIFIABLE, set,
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- private Multimap<String, Integer> multimap;
-
- @Override protected Iterator<Entry<String, Integer>> newTargetIterator() {
- multimap = create();
- multimap.putAll("foo", asList(6, 3));
- multimap.putAll("bar", asList(4, 5));
- multimap.putAll("foo", asList(2));
- return multimap.entries().iterator();
- }
-
- @Override protected void verify(List<Entry<String, Integer>> elements) {
- assertEquals(newHashSet(elements), multimap.entries());
- }
- }.test();
- }
-
- @GwtIncompatible("unreasonable slow")
- public void testKeysIteration() {
- new IteratorTester<String>(6, MODIFIABLE, Lists.newArrayList("bar", "bar",
- "foo", "foo", "foo"), IteratorTester.KnownOrder.KNOWN_ORDER) {
- private Multimap<String, Integer> multimap;
-
- @Override protected Iterator<String> newTargetIterator() {
- multimap = create();
- multimap.putAll("foo", asList(2, 3));
- multimap.putAll("bar", asList(4, 5));
- multimap.putAll("foo", asList(6));
- return multimap.keys().iterator();
- }
-
- @Override protected void verify(List<String> elements) {
- assertEquals(elements, Lists.newArrayList(multimap.keys()));
- }
- }.test();
- }
-
- @GwtIncompatible("unreasonable slow")
- public void testValuesIteration() {
- new IteratorTester<Integer>(6, MODIFIABLE, newArrayList(4, 5, 2, 3, 6),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- private Multimap<String, Integer> multimap;
-
- @Override protected Iterator<Integer> newTargetIterator() {
- multimap = create();
- multimap.putAll("foo", asList(2, 3));
- multimap.putAll("bar", asList(4, 5));
- multimap.putAll("foo", asList(6));
- return multimap.values().iterator();
- }
-
- @Override protected void verify(List<Integer> elements) {
- assertEquals(elements, Lists.newArrayList(multimap.values()));
- }
- }.test();
- }
-
- @GwtIncompatible("unreasonable slow")
- public void testKeySetIteration() {
- new IteratorTester<String>(6, MODIFIABLE,
- Sets.newTreeSet(asList("bar", "baz", "cat", "dog", "foo")),
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- private Multimap<String, Integer> multimap;
-
- @Override protected Iterator<String> newTargetIterator() {
- multimap = create();
- multimap.putAll("foo", asList(2, 3));
- multimap.putAll("bar", asList(4, 5));
- multimap.putAll("foo", asList(6));
- multimap.putAll("baz", asList(7, 8));
- multimap.putAll("dog", asList(9));
- multimap.putAll("bar", asList(10, 11));
- multimap.putAll("cat", asList(12, 13, 14));
- return multimap.keySet().iterator();
- }
-
- @Override protected void verify(List<String> elements) {
- assertEquals(newHashSet(elements), multimap.keySet());
- }
- }.test();
- }
-
- @SuppressWarnings("unchecked")
- @GwtIncompatible("unreasonable slow")
- public void testAsSetIteration() {
- Set<Entry<String, Collection<Integer>>> set = Sets.newTreeSet(
- new Comparator<Entry<String, ?>>() {
- @Override
- public int compare(Entry<String, ?> o1, Entry<String, ?> o2) {
- return o1.getKey().compareTo(o2.getKey());
- }
- });
- Collections.addAll(set,
- Maps.immutableEntry("bar",
- (Collection<Integer>) Sets.newHashSet(4, 5, 10, 11)),
- Maps.immutableEntry("baz",
- (Collection<Integer>) Sets.newHashSet(7, 8)),
- Maps.immutableEntry("cat",
- (Collection<Integer>) Sets.newHashSet(12, 13, 14)),
- Maps.immutableEntry("dog",
- (Collection<Integer>) Sets.newHashSet(9)),
- Maps.immutableEntry("foo",
- (Collection<Integer>) Sets.newHashSet(2, 3, 6))
- );
-
- new IteratorTester<Entry<String, Collection<Integer>>>(6, MODIFIABLE, set,
- IteratorTester.KnownOrder.KNOWN_ORDER) {
- private Multimap<String, Integer> multimap;
-
- @Override protected Iterator<Entry<String, Collection<Integer>>>
- newTargetIterator() {
- multimap = create();
- multimap.putAll("foo", asList(2, 3));
- multimap.putAll("bar", asList(4, 5));
- multimap.putAll("foo", asList(6));
- multimap.putAll("baz", asList(7, 8));
- multimap.putAll("dog", asList(9));
- multimap.putAll("bar", asList(10, 11));
- multimap.putAll("cat", asList(12, 13, 14));
- return multimap.asMap().entrySet().iterator();
- }
-
- @Override protected void verify(
- List<Entry<String, Collection<Integer>>> elements) {
- assertEquals(newHashSet(elements), multimap.asMap().entrySet());
- }
- }.test();
- }
-
@GwtIncompatible("SerializableTester")
public void testExplicitComparatorSerialization() {
TreeMultimap<String, Integer> multimap = createPopulate();
TreeMultimap<String, Integer> copy
= SerializableTester.reserializeAndAssert(multimap);
- ASSERT.that(copy.values()).hasContentsInOrder(1, 3, 7, 2, 6, 0, 4);
- ASSERT.that(copy.keySet()).hasContentsInOrder("foo", "google", "tree");
+ ASSERT.that(copy.values()).has().allOf(1, 3, 7, 2, 6, 0, 4).inOrder();
+ ASSERT.that(copy.keySet()).has().allOf("foo", "google", "tree").inOrder();
assertEquals(multimap.keyComparator(), copy.keyComparator());
assertEquals(multimap.valueComparator(), copy.valueComparator());
}
@@ -479,11 +421,11 @@ public class TreeMultimapNaturalTest<E> extends AbstractSetMultimapTest {
multimap.put(new DerivedComparable("bar"), new DerivedComparable("b"));
multimap.put(new DerivedComparable("bar"), new DerivedComparable("a"));
multimap.put(new DerivedComparable("bar"), new DerivedComparable("r"));
- ASSERT.that(multimap.keySet()).hasContentsInOrder(
- new DerivedComparable("bar"), new DerivedComparable("foo"));
- ASSERT.that(multimap.values()).hasContentsInOrder(
+ ASSERT.that(multimap.keySet()).has().allOf(
+ new DerivedComparable("bar"), new DerivedComparable("foo")).inOrder();
+ ASSERT.that(multimap.values()).has().allOf(
new DerivedComparable("a"), new DerivedComparable("b"), new DerivedComparable("r"),
- new DerivedComparable("f"), new DerivedComparable("o"));
+ new DerivedComparable("f"), new DerivedComparable("o")).inOrder();
assertEquals(Ordering.natural(), multimap.keyComparator());
assertEquals(Ordering.natural(), multimap.valueComparator());
SerializableTester.reserializeAndAssert(multimap);
@@ -500,14 +442,14 @@ public class TreeMultimapNaturalTest<E> extends AbstractSetMultimapTest {
multimap.put(new LegacyComparable("bar"), new LegacyComparable("b"));
multimap.put(new LegacyComparable("bar"), new LegacyComparable("a"));
multimap.put(new LegacyComparable("bar"), new LegacyComparable("r"));
- ASSERT.that(multimap.keySet()).hasContentsInOrder(
- new LegacyComparable("bar"), new LegacyComparable("foo"));
- ASSERT.that(multimap.values()).hasContentsInOrder(
+ ASSERT.that(multimap.keySet()).has().allOf(
+ new LegacyComparable("bar"), new LegacyComparable("foo")).inOrder();
+ ASSERT.that(multimap.values()).has().allOf(
new LegacyComparable("a"),
new LegacyComparable("b"),
new LegacyComparable("r"),
new LegacyComparable("f"),
- new LegacyComparable("o"));
+ new LegacyComparable("o")).inOrder();
assertEquals(Ordering.natural(), multimap.keyComparator());
assertEquals(Ordering.natural(), multimap.valueComparator());
SerializableTester.reserializeAndAssert(multimap);
@@ -546,4 +488,33 @@ public class TreeMultimapNaturalTest<E> extends AbstractSetMultimapTest {
assertEquals(4, multimap.values().size());
assertEquals(4, multimap.keys().size());
}
+
+ @GwtIncompatible("reflection")
+ public void testKeySetBridgeMethods() {
+ for (Method m : TreeMultimap.class.getMethods()) {
+ if (m.getName().equals("keySet") && m.getReturnType().equals(SortedSet.class)) {
+ return;
+ }
+ }
+ fail("No bridge method found");
+ }
+
+ @GwtIncompatible("reflection")
+ public void testAsMapBridgeMethods() {
+ for (Method m : TreeMultimap.class.getMethods()) {
+ if (m.getName().equals("asMap") && m.getReturnType().equals(SortedMap.class)) {
+ return;
+ }
+ }
+ }
+
+ @GwtIncompatible("reflection")
+ public void testGetBridgeMethods() {
+ for (Method m : TreeMultimap.class.getMethods()) {
+ if (m.getName().equals("get") && m.getReturnType().equals(SortedSet.class)) {
+ return;
+ }
+ }
+ fail("No bridge method found");
+ }
}
diff --git a/guava-tests/test/com/google/common/collect/TreeMultisetTest.java b/guava-tests/test/com/google/common/collect/TreeMultisetTest.java
index 2d70307..ef92e3e 100644
--- a/guava-tests/test/com/google/common/collect/TreeMultisetTest.java
+++ b/guava-tests/test/com/google/common/collect/TreeMultisetTest.java
@@ -19,8 +19,24 @@ package com.google.common.collect;
import static com.google.common.collect.BoundType.CLOSED;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.testing.IteratorFeature.MODIFIABLE;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static java.util.Collections.sort;
+import static org.truth0.Truth.ASSERT;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.Helpers.NullsBeforeB;
+import com.google.common.collect.testing.IteratorTester;
+import com.google.common.collect.testing.NavigableSetTestSuiteBuilder;
+import com.google.common.collect.testing.TestStringSetGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.google.SortedMultisetTestSuiteBuilder;
+import com.google.common.collect.testing.google.TestStringMultisetGenerator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
@@ -29,10 +45,6 @@ import java.util.List;
import java.util.Set;
import java.util.SortedSet;
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-import com.google.common.collect.testing.IteratorTester;
-
/**
* Unit test for {@link TreeMultiset}.
*
@@ -40,6 +52,70 @@ import com.google.common.collect.testing.IteratorTester;
*/
@GwtCompatible(emulated = true)
public class TreeMultisetTest extends AbstractMultisetTest {
+
+ @GwtIncompatible("suite")
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(SortedMultisetTestSuiteBuilder
+ .using(new TestStringMultisetGenerator() {
+ @Override
+ protected Multiset<String> create(String[] elements) {
+ return TreeMultiset.create(Arrays.asList(elements));
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Ordering.natural().sortedCopy(insertionOrder);
+ }
+ })
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .named("TreeMultiset, Ordering.natural")
+ .createTestSuite());
+ suite.addTest(SortedMultisetTestSuiteBuilder
+ .using(new TestStringMultisetGenerator() {
+ @Override
+ protected Multiset<String> create(String[] elements) {
+ Multiset<String> result = TreeMultiset.create(NullsBeforeB.INSTANCE);
+ result.addAll(Arrays.asList(elements));
+ return result;
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ sort(insertionOrder, NullsBeforeB.INSTANCE);
+ return insertionOrder;
+ }
+ })
+ .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER,
+ CollectionFeature.GENERAL_PURPOSE,
+ CollectionFeature.SERIALIZABLE,
+ CollectionFeature.ALLOWS_NULL_VALUES)
+ .named("TreeMultiset, NullsBeforeB")
+ .createTestSuite());
+ suite.addTest(NavigableSetTestSuiteBuilder.using(new TestStringSetGenerator() {
+ @Override
+ protected Set<String> create(String[] elements) {
+ return TreeMultiset.create(Arrays.asList(elements)).elementSet();
+ }
+
+ @Override
+ public List<String> order(List<String> insertionOrder) {
+ return Lists.newArrayList(Sets.newTreeSet(insertionOrder));
+ }
+ })
+ .named("TreeMultiset[Ordering.natural].elementSet")
+ .withFeatures(
+ CollectionSize.ANY,
+ CollectionFeature.SUPPORTS_REMOVE,
+ CollectionFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+ suite.addTestSuite(TreeMultisetTest.class);
+ return suite;
+ }
+
@SuppressWarnings("unchecked")
@Override protected <E> Multiset<E> create() {
return (Multiset) TreeMultiset.create();
@@ -139,9 +215,9 @@ public class TreeMultisetTest extends AbstractMultisetTest {
assertEquals("c", elementSet.last());
assertEquals(Ordering.natural(), elementSet.comparator());
- ASSERT.that(elementSet.headSet("b")).hasContentsInOrder("a");
- ASSERT.that(elementSet.tailSet("b")).hasContentsInOrder("b", "c");
- ASSERT.that(elementSet.subSet("a", "c")).hasContentsInOrder("a", "b");
+ ASSERT.that(elementSet.headSet("b")).has().allOf("a").inOrder();
+ ASSERT.that(elementSet.tailSet("b")).has().allOf("b", "c").inOrder();
+ ASSERT.that(elementSet.subSet("a", "c")).has().allOf("a", "b").inOrder();
}
public void testElementSetSubsetRemove() {
@@ -154,18 +230,18 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("f", 2);
SortedSet<String> elementSet = ms.elementSet();
- ASSERT.that(elementSet).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
SortedSet<String> subset = elementSet.subSet("b", "f");
- ASSERT.that(subset).hasContentsInOrder("b", "c", "d", "e");
+ ASSERT.that(subset).has().allOf("b", "c", "d", "e").inOrder();
assertTrue(subset.remove("c"));
- ASSERT.that(elementSet).hasContentsInOrder("a", "b", "d", "e", "f");
- ASSERT.that(subset).hasContentsInOrder("b", "d", "e");
+ ASSERT.that(elementSet).has().allOf("a", "b", "d", "e", "f").inOrder();
+ ASSERT.that(subset).has().allOf("b", "d", "e").inOrder();
assertEquals(10, ms.size());
assertFalse(subset.remove("a"));
- ASSERT.that(elementSet).hasContentsInOrder("a", "b", "d", "e", "f");
- ASSERT.that(subset).hasContentsInOrder("b", "d", "e");
+ ASSERT.that(elementSet).has().allOf("a", "b", "d", "e", "f").inOrder();
+ ASSERT.that(subset).has().allOf("b", "d", "e").inOrder();
assertEquals(10, ms.size());
}
@@ -179,13 +255,13 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("f", 2);
SortedSet<String> elementSet = ms.elementSet();
- ASSERT.that(elementSet).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
SortedSet<String> subset = elementSet.subSet("b", "f");
- ASSERT.that(subset).hasContentsInOrder("b", "c", "d", "e");
+ ASSERT.that(subset).has().allOf("b", "c", "d", "e").inOrder();
assertTrue(subset.removeAll(Arrays.asList("a", "c")));
- ASSERT.that(elementSet).hasContentsInOrder("a", "b", "d", "e", "f");
- ASSERT.that(subset).hasContentsInOrder("b", "d", "e");
+ ASSERT.that(elementSet).has().allOf("a", "b", "d", "e", "f").inOrder();
+ ASSERT.that(subset).has().allOf("b", "d", "e").inOrder();
assertEquals(10, ms.size());
}
@@ -199,13 +275,13 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("f", 2);
SortedSet<String> elementSet = ms.elementSet();
- ASSERT.that(elementSet).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
SortedSet<String> subset = elementSet.subSet("b", "f");
- ASSERT.that(subset).hasContentsInOrder("b", "c", "d", "e");
+ ASSERT.that(subset).has().allOf("b", "c", "d", "e").inOrder();
assertTrue(subset.retainAll(Arrays.asList("a", "c")));
- ASSERT.that(elementSet).hasContentsInOrder("a", "c", "f");
- ASSERT.that(subset).hasContentsInOrder("c");
+ ASSERT.that(elementSet).has().allOf("a", "c", "f").inOrder();
+ ASSERT.that(subset).has().allOf("c").inOrder();
assertEquals(5, ms.size());
}
@@ -219,13 +295,13 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("f", 2);
SortedSet<String> elementSet = ms.elementSet();
- ASSERT.that(elementSet).hasContentsInOrder("a", "b", "c", "d", "e", "f");
+ ASSERT.that(elementSet).has().allOf("a", "b", "c", "d", "e", "f").inOrder();
SortedSet<String> subset = elementSet.subSet("b", "f");
- ASSERT.that(subset).hasContentsInOrder("b", "c", "d", "e");
+ ASSERT.that(subset).has().allOf("b", "c", "d", "e").inOrder();
subset.clear();
- ASSERT.that(elementSet).hasContentsInOrder("a", "f");
- ASSERT.that(subset).hasContentsInOrder();
+ ASSERT.that(elementSet).has().allOf("a", "f").inOrder();
+ ASSERT.that(subset).isEmpty();
assertEquals(3, ms.size());
}
@@ -244,7 +320,7 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("b");
ms.add("d");
- ASSERT.that(ms).hasContentsInOrder("d", "c", "b", "b", "a");
+ ASSERT.that(ms).has().allOf("d", "c", "b", "b", "a").inOrder();
SortedSet<String> elementSet = ms.elementSet();
assertEquals("d", elementSet.first());
@@ -262,7 +338,7 @@ public class TreeMultisetTest extends AbstractMultisetTest {
ms.add("b");
ms.add(null, 2);
- ASSERT.that(ms).hasContentsInOrder(null, null, null, "a", "b", "b");
+ ASSERT.that(ms).has().allOf(null, null, null, "a", "b", "b").inOrder();
assertEquals(3, ms.count(null));
SortedSet<String> elementSet = ms.elementSet();
@@ -332,5 +408,14 @@ public class TreeMultisetTest extends AbstractMultisetTest {
c = ms = TreeMultiset.create(Ordering.natural().nullsFirst());
super.testToStringNull();
}
-}
+ @GwtIncompatible("reflection")
+ public void testElementSetBridgeMethods() {
+ for (Method m : TreeMultiset.class.getMethods()) {
+ if (m.getName().equals("elementSet") && m.getReturnType().equals(SortedSet.class)) {
+ return;
+ }
+ }
+ fail("No bridge method found");
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java b/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java
new file mode 100644
index 0000000..c914065
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/TreeRangeMapTest.java
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.BoundType.OPEN;
+import static com.google.common.collect.testing.Helpers.mapEntry;
+
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.MapTestSuiteBuilder;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.TestMapGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.testers.CollectionIteratorTester;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+
+/**
+ * Tests for {@code TreeRangeMap}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtIncompatible("NavigableMap")
+public class TreeRangeMapTest extends TestCase {
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(TreeRangeMapTest.class);
+ suite.addTest(MapTestSuiteBuilder.using(new TestMapGenerator<Range<Integer>, String>() {
+ @Override
+ public SampleElements<Entry<Range<Integer>, String>> samples() {
+ return new SampleElements<Entry<Range<Integer>, String>>(
+ mapEntry(Range.singleton(0), "banana"),
+ mapEntry(Range.closedOpen(3, 5), "frisbee"),
+ mapEntry(Range.atMost(-1), "fruitcake"),
+ mapEntry(Range.open(10, 15), "elephant"),
+ mapEntry(Range.closed(20, 22), "umbrella"));
+ }
+
+ @Override
+ public Map<Range<Integer>, String> create(Object... elements) {
+ RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
+ for (Object o : elements) {
+ @SuppressWarnings("unchecked")
+ Entry<Range<Integer>, String> entry = (Entry<Range<Integer>, String>) o;
+ rangeMap.put(entry.getKey(), entry.getValue());
+ }
+ return rangeMap.asMapOfRanges();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Entry<Range<Integer>, String>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<Range<Integer>, String>> order(
+ List<Entry<Range<Integer>, String>> insertionOrder) {
+ return Range.RANGE_LEX_ORDERING.onResultOf(Maps.<Range<Integer>>keyFunction())
+ .sortedCopy(insertionOrder);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Range<Integer>[] createKeyArray(int length) {
+ return new Range[length];
+ }
+
+ @Override
+ public String[] createValueArray(int length) {
+ return new String[length];
+ }
+ })
+ .named("TreeRangeMap.asMapOfRanges")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.SUPPORTS_REMOVE,
+ MapFeature.ALLOWS_NULL_QUERIES,
+ CollectionFeature.KNOWN_ORDER)
+ .createTestSuite());
+
+ suite.addTest(MapTestSuiteBuilder.using(new TestMapGenerator<Range<Integer>, String>() {
+ @Override
+ public SampleElements<Entry<Range<Integer>, String>> samples() {
+ return new SampleElements<Entry<Range<Integer>, String>>(
+ mapEntry(Range.singleton(0), "banana"),
+ mapEntry(Range.closedOpen(3, 5), "frisbee"),
+ mapEntry(Range.atMost(-1), "fruitcake"),
+ mapEntry(Range.open(10, 15), "elephant"),
+ mapEntry(Range.closed(20, 22), "umbrella"));
+ }
+
+ @Override
+ public Map<Range<Integer>, String> create(Object... elements) {
+ RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
+ for (Object o : elements) {
+ @SuppressWarnings("unchecked")
+ Entry<Range<Integer>, String> entry = (Entry<Range<Integer>, String>) o;
+ rangeMap.put(entry.getKey(), entry.getValue());
+ }
+ return rangeMap.subRangeMap(Range.atMost(22)).asMapOfRanges();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Entry<Range<Integer>, String>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<Range<Integer>, String>> order(
+ List<Entry<Range<Integer>, String>> insertionOrder) {
+ return Range.RANGE_LEX_ORDERING.onResultOf(Maps.<Range<Integer>>keyFunction())
+ .sortedCopy(insertionOrder);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Range<Integer>[] createKeyArray(int length) {
+ return new Range[length];
+ }
+
+ @Override
+ public String[] createValueArray(int length) {
+ return new String[length];
+ }
+ })
+ .named("TreeRangeMap.subRangeMap.asMapOfRanges")
+ .withFeatures(
+ CollectionSize.ANY,
+ MapFeature.SUPPORTS_REMOVE,
+ MapFeature.ALLOWS_NULL_QUERIES,
+ CollectionFeature.KNOWN_ORDER)
+ .suppressing(CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod())
+ .createTestSuite());
+ return suite;
+ }
+
+ private static final ImmutableList<Range<Integer>> RANGES;
+ private static final int MIN_BOUND = -2;
+ private static final int MAX_BOUND = 2;
+ static {
+ ImmutableList.Builder<Range<Integer>> builder = ImmutableList.builder();
+
+ builder.add(Range.<Integer>all());
+
+ // Add one-ended ranges
+ for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
+ for (BoundType type : BoundType.values()) {
+ builder.add(Range.upTo(i, type));
+ builder.add(Range.downTo(i, type));
+ }
+ }
+
+ // Add two-ended ranges
+ for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
+ for (int j = i; j <= MAX_BOUND; j++) {
+ for (BoundType lowerType : BoundType.values()) {
+ for (BoundType upperType : BoundType.values()) {
+ if (i == j & lowerType == OPEN & upperType == OPEN) {
+ continue;
+ }
+ builder.add(Range.range(i, lowerType, j, upperType));
+ }
+ }
+ }
+ }
+ RANGES = builder.build();
+ }
+
+ public void testSpanSingleRange() {
+ for (Range<Integer> range : RANGES) {
+ RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
+ rangeMap.put(range, 1);
+
+ try {
+ assertEquals(range, rangeMap.span());
+ assertFalse(range.isEmpty());
+ } catch (NoSuchElementException e) {
+ assertTrue(range.isEmpty());
+ }
+ }
+ }
+
+ public void testSpanTwoRanges() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
+ rangeMap.put(range1, 1);
+ rangeMap.put(range2, 2);
+
+ Range<Integer> expected;
+ if (range1.isEmpty()) {
+ if (range2.isEmpty()) {
+ expected = null;
+ } else {
+ expected = range2;
+ }
+ } else {
+ if (range2.isEmpty()) {
+ expected = range1;
+ } else {
+ expected = range1.span(range2);
+ }
+ }
+
+ try {
+ assertEquals(expected, rangeMap.span());
+ assertNotNull(expected);
+ } catch (NoSuchElementException e) {
+ assertNull(expected);
+ }
+ }
+ }
+ }
+
+ public void testAllRangesAlone() {
+ for (Range<Integer> range : RANGES) {
+ Map<Integer, Integer> model = Maps.newHashMap();
+ putModel(model, range, 1);
+ RangeMap<Integer, Integer> test = TreeRangeMap.create();
+ test.put(range, 1);
+ verify(model, test);
+ }
+ }
+
+ public void testAllRangePairs() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ Map<Integer, Integer> model = Maps.newHashMap();
+ putModel(model, range1, 1);
+ putModel(model, range2, 2);
+ RangeMap<Integer, Integer> test = TreeRangeMap.create();
+ test.put(range1, 1);
+ test.put(range2, 2);
+ verify(model, test);
+ }
+ }
+ }
+
+ public void testAllRangeTriples() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ for (Range<Integer> range3 : RANGES) {
+ Map<Integer, Integer> model = Maps.newHashMap();
+ putModel(model, range1, 1);
+ putModel(model, range2, 2);
+ putModel(model, range3, 3);
+ RangeMap<Integer, Integer> test = TreeRangeMap.create();
+ test.put(range1, 1);
+ test.put(range2, 2);
+ test.put(range3, 3);
+ verify(model, test);
+ }
+ }
+ }
+ }
+
+ public void testPutAll() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ for (Range<Integer> range3 : RANGES) {
+ Map<Integer, Integer> model = Maps.newHashMap();
+ putModel(model, range1, 1);
+ putModel(model, range2, 2);
+ putModel(model, range3, 3);
+ RangeMap<Integer, Integer> test = TreeRangeMap.create();
+ RangeMap<Integer, Integer> test2 = TreeRangeMap.create();
+ // put range2 and range3 into test2, and then put test2 into test
+ test.put(range1, 1);
+ test2.put(range2, 2);
+ test2.put(range3, 3);
+ test.putAll(test2);
+ verify(model, test);
+ }
+ }
+ }
+ }
+
+ public void testPutAndRemove() {
+ for (Range<Integer> rangeToPut : RANGES) {
+ for (Range<Integer> rangeToRemove : RANGES) {
+ Map<Integer, Integer> model = Maps.newHashMap();
+ putModel(model, rangeToPut, 1);
+ removeModel(model, rangeToRemove);
+ RangeMap<Integer, Integer> test = TreeRangeMap.create();
+ test.put(rangeToPut, 1);
+ test.remove(rangeToRemove);
+ verify(model, test);
+ }
+ }
+ }
+
+ public void testPutTwoAndRemove() {
+ for (Range<Integer> rangeToPut1 : RANGES) {
+ for (Range<Integer> rangeToPut2 : RANGES) {
+ for (Range<Integer> rangeToRemove : RANGES) {
+ Map<Integer, Integer> model = Maps.newHashMap();
+ putModel(model, rangeToPut1, 1);
+ putModel(model, rangeToPut2, 2);
+ removeModel(model, rangeToRemove);
+ RangeMap<Integer, Integer> test = TreeRangeMap.create();
+ test.put(rangeToPut1, 1);
+ test.put(rangeToPut2, 2);
+ test.remove(rangeToRemove);
+ verify(model, test);
+ }
+ }
+ }
+ }
+
+ public void testSubRangeMapExhaustive() {
+ for (Range<Integer> range1 : RANGES) {
+ for (Range<Integer> range2 : RANGES) {
+ RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
+ rangeMap.put(range1, 1);
+ rangeMap.put(range2, 2);
+
+ for (Range<Integer> subRange : RANGES) {
+ RangeMap<Integer, Integer> expected = TreeRangeMap.create();
+ for (Map.Entry<Range<Integer>, Integer> entry : rangeMap.asMapOfRanges().entrySet()) {
+ if (entry.getKey().isConnected(subRange)) {
+ expected.put(entry.getKey().intersection(subRange), entry.getValue());
+ }
+ }
+ RangeMap<Integer, Integer> subRangeMap = rangeMap.subRangeMap(subRange);
+ assertEquals(expected, subRangeMap);
+ assertEquals(expected.asMapOfRanges(), subRangeMap.asMapOfRanges());
+
+ if (!expected.asMapOfRanges().isEmpty()) {
+ assertEquals(expected.span(), subRangeMap.span());
+ }
+
+ for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
+ assertEquals(expected.get(i), subRangeMap.get(i));
+ }
+
+ for (Range<Integer> query : RANGES) {
+ assertEquals(
+ expected.asMapOfRanges().get(query),
+ subRangeMap.asMapOfRanges().get(query));
+ }
+ }
+ }
+ }
+ }
+
+ public void testSubSubRangeMap() {
+ RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
+ rangeMap.put(Range.open(3, 7), 1);
+ rangeMap.put(Range.closed(9, 10), 2);
+ rangeMap.put(Range.closed(12, 16), 3);
+ RangeMap<Integer, Integer> sub1 = rangeMap.subRangeMap(Range.closed(5, 11));
+ assertEquals(ImmutableMap.of(Range.closedOpen(5, 7), 1, Range.closed(9, 10), 2),
+ sub1.asMapOfRanges());
+ RangeMap<Integer, Integer> sub2 = sub1.subRangeMap(Range.open(6, 15));
+ assertEquals(ImmutableMap.of(Range.open(6, 7), 1, Range.closed(9, 10), 2),
+ sub2.asMapOfRanges());
+ }
+
+ public void testSubRangeMapPut() {
+ RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
+ rangeMap.put(Range.open(3, 7), 1);
+ rangeMap.put(Range.closed(9, 10), 2);
+ rangeMap.put(Range.closed(12, 16), 3);
+ RangeMap<Integer, Integer> sub = rangeMap.subRangeMap(Range.closed(5, 11));
+ assertEquals(ImmutableMap.of(Range.closedOpen(5, 7), 1, Range.closed(9, 10), 2),
+ sub.asMapOfRanges());
+ sub.put(Range.closed(7, 9), 4);
+ assertEquals(
+ ImmutableMap.of(
+ Range.closedOpen(5, 7), 1, Range.closed(7, 9), 4, Range.openClosed(9, 10), 2),
+ sub.asMapOfRanges());
+ assertEquals(
+ ImmutableMap.of(Range.open(3, 7), 1, Range.closed(7, 9), 4, Range.openClosed(9, 10), 2,
+ Range.closed(12, 16), 3),
+ rangeMap.asMapOfRanges());
+
+ try {
+ sub.put(Range.open(9, 12), 5);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ sub = sub.subRangeMap(Range.closedOpen(5, 5));
+ sub.put(Range.closedOpen(5, 5), 6); // should be a no-op
+ assertEquals(
+ ImmutableMap.of(Range.open(3, 7), 1, Range.closed(7, 9), 4, Range.openClosed(9, 10), 2,
+ Range.closed(12, 16), 3),
+ rangeMap.asMapOfRanges());
+ }
+
+ public void testSubRangeMapRemove() {
+ RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
+ rangeMap.put(Range.open(3, 7), 1);
+ rangeMap.put(Range.closed(9, 10), 2);
+ rangeMap.put(Range.closed(12, 16), 3);
+ RangeMap<Integer, Integer> sub = rangeMap.subRangeMap(Range.closed(5, 11));
+ assertEquals(ImmutableMap.of(Range.closedOpen(5, 7), 1, Range.closed(9, 10), 2),
+ sub.asMapOfRanges());
+ sub.remove(Range.closed(7, 9));
+ assertEquals(
+ ImmutableMap.of(Range.closedOpen(5, 7), 1, Range.openClosed(9, 10), 2),
+ sub.asMapOfRanges());
+ assertEquals(
+ ImmutableMap.of(Range.open(3, 7), 1, Range.openClosed(9, 10), 2, Range.closed(12, 16), 3),
+ rangeMap.asMapOfRanges());
+
+ sub.remove(Range.closed(3, 9));
+ assertEquals(
+ ImmutableMap.of(Range.openClosed(9, 10), 2),
+ sub.asMapOfRanges());
+ assertEquals(
+ ImmutableMap.of(Range.open(3, 5), 1, Range.openClosed(9, 10), 2, Range.closed(12, 16), 3),
+ rangeMap.asMapOfRanges());
+ }
+
+ public void testSubRangeMapClear() {
+ RangeMap<Integer, Integer> rangeMap = TreeRangeMap.create();
+ rangeMap.put(Range.open(3, 7), 1);
+ rangeMap.put(Range.closed(9, 10), 2);
+ rangeMap.put(Range.closed(12, 16), 3);
+ RangeMap<Integer, Integer> sub = rangeMap.subRangeMap(Range.closed(5, 11));
+ sub.clear();
+ assertEquals(
+ ImmutableMap.of(Range.open(3, 5), 1, Range.closed(12, 16), 3),
+ rangeMap.asMapOfRanges());
+ }
+
+ private void verify(Map<Integer, Integer> model, RangeMap<Integer, Integer> test) {
+ for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
+ assertEquals(model.get(i), test.get(i));
+
+ Map.Entry<Range<Integer>, Integer> entry = test.getEntry(i);
+ assertEquals(model.containsKey(i), entry != null);
+ if (entry != null) {
+ assertTrue(test.asMapOfRanges().entrySet().contains(entry));
+ }
+ }
+ for (Range<Integer> range : test.asMapOfRanges().keySet()) {
+ assertFalse(range.isEmpty());
+ }
+ }
+
+ private void putModel(Map<Integer, Integer> model, Range<Integer> range, int value) {
+ for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
+ if (range.contains(i)) {
+ model.put(i, value);
+ }
+ }
+ }
+
+ private void removeModel(Map<Integer, Integer> model, Range<Integer> range) {
+ for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
+ if (range.contains(i)) {
+ model.remove(i);
+ }
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/collect/TreeRangeSetTest.java b/guava-tests/test/com/google/common/collect/TreeRangeSetTest.java
new file mode 100644
index 0000000..e67508d
--- /dev/null
+++ b/guava-tests/test/com/google/common/collect/TreeRangeSetTest.java
@@ -0,0 +1,570 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.collect;
+
+import static com.google.common.collect.BoundType.OPEN;
+import static com.google.common.collect.Range.range;
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.annotations.GwtIncompatible;
+
+import java.util.List;
+import java.util.NavigableMap;
+
+/**
+ * Tests for {@link TreeRangeSet}.
+ *
+ * @author Louis Wasserman
+ * @author Chris Povirk
+ */
+@GwtIncompatible("TreeRangeSet")
+public class TreeRangeSetTest extends AbstractRangeSetTest {
+ // TODO(cpovirk): test all of these with the ranges added in the reverse order
+
+ private static final ImmutableList<Range<Integer>> QUERY_RANGES;
+
+ private static final int MIN_BOUND = -1;
+ private static final int MAX_BOUND = 1;
+
+ static {
+ ImmutableList.Builder<Range<Integer>> queryBuilder = ImmutableList.builder();
+
+ queryBuilder.add(Range.<Integer>all());
+
+ for (int i = MIN_BOUND; i <= MAX_BOUND; i++) {
+ for (BoundType boundType : BoundType.values()) {
+ queryBuilder.add(Range.upTo(i, boundType));
+ queryBuilder.add(Range.downTo(i, boundType));
+ }
+ queryBuilder.add(Range.singleton(i));
+ queryBuilder.add(Range.openClosed(i, i));
+ queryBuilder.add(Range.closedOpen(i, i));
+
+ for (BoundType lowerBoundType : BoundType.values()) {
+ for (int j = i + 1; j <= MAX_BOUND; j++) {
+ for (BoundType upperBoundType : BoundType.values()) {
+ queryBuilder.add(Range.range(i, lowerBoundType, j, upperBoundType));
+ }
+ }
+ }
+ }
+ QUERY_RANGES = queryBuilder.build();
+ }
+
+ void testViewAgainstExpected(RangeSet<Integer> expected, RangeSet<Integer> view) {
+ assertEquals(expected, view);
+ assertEquals(expected.asRanges(), view.asRanges());
+ assertEquals(expected.isEmpty(), view.isEmpty());
+
+ if (!expected.isEmpty()) {
+ assertEquals(expected.span(), view.span());
+ }
+
+ for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
+ assertEquals(expected.contains(i), view.contains(i));
+ assertEquals(expected.rangeContaining(i), view.rangeContaining(i));
+ }
+ testEnclosing(view);
+ if (view instanceof TreeRangeSet) {
+ testRangesByLowerBounds((TreeRangeSet<Integer>) view, expected.asRanges());
+ }
+ }
+
+ private static final ImmutableList<Cut<Integer>> CUTS_TO_TEST;
+
+ static {
+ List<Cut<Integer>> cutsToTest = Lists.newArrayList();
+ for (int i = MIN_BOUND - 1; i <= MAX_BOUND + 1; i++) {
+ cutsToTest.add(Cut.belowValue(i));
+ cutsToTest.add(Cut.aboveValue(i));
+ }
+ cutsToTest.add(Cut.<Integer>aboveAll());
+ cutsToTest.add(Cut.<Integer>belowAll());
+ CUTS_TO_TEST = ImmutableList.copyOf(cutsToTest);
+ }
+
+ private void testRangesByLowerBounds(
+ TreeRangeSet<Integer> rangeSet, Iterable<Range<Integer>> expectedRanges) {
+ NavigableMap<Cut<Integer>, Range<Integer>> expectedRangesByLowerBound = Maps.newTreeMap();
+ for (Range<Integer> range : expectedRanges) {
+ expectedRangesByLowerBound.put(range.lowerBound, range);
+ }
+
+ NavigableMap<Cut<Integer>, Range<Integer>> rangesByLowerBound = rangeSet.rangesByLowerBound;
+ testNavigationAgainstExpected(expectedRangesByLowerBound, rangesByLowerBound, CUTS_TO_TEST);
+ }
+
+ <K, V> void testNavigationAgainstExpected(
+ NavigableMap<K, V> expected, NavigableMap<K, V> navigableMap, Iterable<K> keysToTest) {
+ for (K key : keysToTest) {
+ assertEquals(expected.lowerEntry(key), navigableMap.lowerEntry(key));
+ assertEquals(expected.floorEntry(key), navigableMap.floorEntry(key));
+ assertEquals(expected.ceilingEntry(key), navigableMap.ceilingEntry(key));
+ assertEquals(expected.higherEntry(key), navigableMap.higherEntry(key));
+ for (boolean inclusive : new boolean[] {false, true}) {
+ ASSERT.that(navigableMap.headMap(key, inclusive).entrySet())
+ .has().allFrom(expected.headMap(key, inclusive).entrySet()).inOrder();
+ ASSERT.that(navigableMap.tailMap(key, inclusive).entrySet())
+ .has().allFrom(expected.tailMap(key, inclusive).entrySet()).inOrder();
+ ASSERT.that(navigableMap.headMap(key, inclusive).descendingMap().entrySet())
+ .has().allFrom(expected.headMap(key, inclusive).descendingMap().entrySet()).inOrder();
+ ASSERT.that(navigableMap.tailMap(key, inclusive).descendingMap().entrySet())
+ .has().allFrom(expected.tailMap(key, inclusive).descendingMap().entrySet()).inOrder();
+ }
+ }
+ }
+
+ public void testEnclosing(RangeSet<Integer> rangeSet) {
+ for (Range<Integer> query : QUERY_RANGES) {
+ boolean expectEnclose = false;
+ for (Range<Integer> expectedRange : rangeSet.asRanges()) {
+ if (expectedRange.encloses(query)) {
+ expectEnclose = true;
+ break;
+ }
+ }
+
+ assertEquals(rangeSet + " was incorrect on encloses(" + query + ")", expectEnclose,
+ rangeSet.encloses(query));
+ }
+ }
+
+ public void testAllSingleRangesComplementAgainstRemove() {
+ for (Range<Integer> range : QUERY_RANGES) {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(range);
+
+ TreeRangeSet<Integer> complement = TreeRangeSet.create();
+ complement.add(Range.<Integer>all());
+ complement.remove(range);
+
+ assertEquals(complement, rangeSet.complement());
+ ASSERT.that(rangeSet.complement().asRanges()).has().allFrom(complement.asRanges()).inOrder();
+ }
+ }
+
+ public void testInvariantsEmpty() {
+ testInvariants(TreeRangeSet.create());
+ }
+
+ public void testAllSingleRangesEnclosing() {
+ for (Range<Integer> range : QUERY_RANGES) {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(range);
+ testEnclosing(rangeSet);
+ testEnclosing(rangeSet.complement());
+ }
+ }
+
+ public void testAllTwoRangesEnclosing() {
+ for (Range<Integer> range1 : QUERY_RANGES) {
+ for (Range<Integer> range2 : QUERY_RANGES) {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(range1);
+ rangeSet.add(range2);
+ testEnclosing(rangeSet);
+ testEnclosing(rangeSet.complement());
+ }
+ }
+ }
+
+ public void testCreateCopy() {
+ for (Range<Integer> range1 : QUERY_RANGES) {
+ for (Range<Integer> range2 : QUERY_RANGES) {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(range1);
+ rangeSet.add(range2);
+
+ assertEquals(rangeSet, TreeRangeSet.create(rangeSet));
+ }
+ }
+ }
+
+ private RangeSet<Integer> expectedSubRangeSet(
+ RangeSet<Integer> rangeSet, Range<Integer> subRange) {
+ RangeSet<Integer> expected = TreeRangeSet.create();
+ for (Range<Integer> range : rangeSet.asRanges()) {
+ if (range.isConnected(subRange)) {
+ expected.add(range.intersection(subRange));
+ }
+ }
+ return expected;
+ }
+
+ private RangeSet<Integer> expectedComplement(RangeSet<Integer> rangeSet) {
+ RangeSet<Integer> expected = TreeRangeSet.create();
+ expected.add(Range.<Integer>all());
+ expected.removeAll(rangeSet);
+ return expected;
+ }
+
+ public void testSubRangeSet() {
+ for (Range<Integer> range1 : QUERY_RANGES) {
+ for (Range<Integer> range2 : QUERY_RANGES) {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(range1);
+ rangeSet.add(range2);
+ for (Range<Integer> subRange : QUERY_RANGES) {
+ testViewAgainstExpected(
+ expectedSubRangeSet(rangeSet, subRange), rangeSet.subRangeSet(subRange));
+ }
+ }
+ }
+ }
+
+ public void testComplement() {
+ for (Range<Integer> range1 : QUERY_RANGES) {
+ for (Range<Integer> range2 : QUERY_RANGES) {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(range1);
+ rangeSet.add(range2);
+ testViewAgainstExpected(expectedComplement(rangeSet), rangeSet.complement());
+ }
+ }
+ }
+
+ public void testSubRangeSetOfComplement() {
+ for (Range<Integer> range1 : QUERY_RANGES) {
+ for (Range<Integer> range2 : QUERY_RANGES) {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(range1);
+ rangeSet.add(range2);
+ for (Range<Integer> subRange : QUERY_RANGES) {
+ testViewAgainstExpected(
+ expectedSubRangeSet(expectedComplement(rangeSet), subRange),
+ rangeSet.complement().subRangeSet(subRange));
+ }
+ }
+ }
+ }
+
+ public void testComplementOfSubRangeSet() {
+ for (Range<Integer> range1 : QUERY_RANGES) {
+ for (Range<Integer> range2 : QUERY_RANGES) {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(range1);
+ rangeSet.add(range2);
+ for (Range<Integer> subRange : QUERY_RANGES) {
+ testViewAgainstExpected(
+ expectedComplement(expectedSubRangeSet(rangeSet, subRange)),
+ rangeSet.subRangeSet(subRange).complement());
+ }
+ }
+ }
+ }
+
+ public void testRangesByUpperBound() {
+ for (Range<Integer> range1 : QUERY_RANGES) {
+ for (Range<Integer> range2 : QUERY_RANGES) {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(range1);
+ rangeSet.add(range2);
+
+ NavigableMap<Cut<Integer>, Range<Integer>> expectedRangesByUpperBound = Maps.newTreeMap();
+ for (Range<Integer> range : rangeSet.asRanges()) {
+ expectedRangesByUpperBound.put(range.upperBound, range);
+ }
+ testNavigationAgainstExpected(expectedRangesByUpperBound,
+ new TreeRangeSet.RangesByUpperBound<Integer>(rangeSet.rangesByLowerBound),
+ CUTS_TO_TEST);
+ }
+ }
+ }
+
+ public void testMergesConnectedWithOverlap() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(1, 4));
+ rangeSet.add(Range.open(2, 6));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.atLeast(6)).inOrder();
+ }
+
+ public void testMergesConnectedDisjoint() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(1, 4));
+ rangeSet.add(Range.open(4, 6));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.atLeast(6)).inOrder();
+ }
+
+ public void testIgnoresSmallerSharingNoBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(1, 6));
+ rangeSet.add(Range.open(2, 4));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
+ }
+
+ public void testIgnoresSmallerSharingLowerBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(1, 6));
+ rangeSet.add(Range.closed(1, 4));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
+ }
+
+ public void testIgnoresSmallerSharingUpperBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(1, 6));
+ rangeSet.add(Range.closed(3, 6));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
+ }
+
+ public void testIgnoresEqual() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(1, 6));
+ rangeSet.add(Range.closed(1, 6));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
+ }
+
+ public void testExtendSameLowerBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(1, 4));
+ rangeSet.add(Range.closed(1, 6));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
+ }
+
+ public void testExtendSameUpperBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 6));
+ rangeSet.add(Range.closed(1, 6));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
+ }
+
+ public void testExtendBothDirections() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 4));
+ rangeSet.add(Range.closed(1, 6));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
+ }
+
+ public void testAddEmpty() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closedOpen(3, 3));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).isEmpty();
+ ASSERT.that(rangeSet.complement().asRanges()).has().allOf(Range.<Integer>all()).inOrder();
+ }
+
+ public void testFillHoleExactly() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closedOpen(1, 3));
+ rangeSet.add(Range.closedOpen(4, 6));
+ rangeSet.add(Range.closedOpen(3, 4));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.atLeast(6)).inOrder();
+ }
+
+ public void testFillHoleWithOverlap() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closedOpen(1, 3));
+ rangeSet.add(Range.closedOpen(4, 6));
+ rangeSet.add(Range.closedOpen(2, 5));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closedOpen(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.atLeast(6)).inOrder();
+ }
+
+ public void testAddManyPairs() {
+ for (int aLow = 0; aLow < 6; aLow++) {
+ for (int aHigh = 0; aHigh < 6; aHigh++) {
+ for (BoundType aLowType : BoundType.values()) {
+ for (BoundType aHighType : BoundType.values()) {
+ if ((aLow == aHigh && aLowType == OPEN && aHighType == OPEN) || aLow > aHigh) {
+ continue;
+ }
+ for (int bLow = 0; bLow < 6; bLow++) {
+ for (int bHigh = 0; bHigh < 6; bHigh++) {
+ for (BoundType bLowType : BoundType.values()) {
+ for (BoundType bHighType : BoundType.values()) {
+ if ((bLow == bHigh && bLowType == OPEN && bHighType == OPEN) || bLow > bHigh) {
+ continue;
+ }
+ doPairTest(range(aLow, aLowType, aHigh, aHighType),
+ range(bLow, bLowType, bHigh, bHighType));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private static void doPairTest(Range<Integer> a, Range<Integer> b) {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(a);
+ rangeSet.add(b);
+ if (a.isEmpty() && b.isEmpty()) {
+ ASSERT.that(rangeSet.asRanges()).isEmpty();
+ } else if (a.isEmpty()) {
+ ASSERT.that(rangeSet.asRanges()).has().item(b);
+ } else if (b.isEmpty()) {
+ ASSERT.that(rangeSet.asRanges()).has().item(a);
+ } else if (a.isConnected(b)) {
+ ASSERT.that(rangeSet.asRanges()).has().allOf(a.span(b)).inOrder();
+ } else {
+ if (a.lowerEndpoint() < b.lowerEndpoint()) {
+ ASSERT.that(rangeSet.asRanges()).has().allOf(a, b).inOrder();
+ } else {
+ ASSERT.that(rangeSet.asRanges()).has().allOf(b, a).inOrder();
+ }
+ }
+ }
+
+ public void testRemoveEmpty() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(1, 6));
+ rangeSet.remove(Range.closedOpen(3, 3));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.closed(1, 6));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(1), Range.greaterThan(6)).inOrder();
+ }
+
+ public void testRemovePartSharingLowerBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 5));
+ rangeSet.remove(Range.closedOpen(3, 5));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.singleton(5));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(5), Range.greaterThan(5)).inOrder();
+ }
+
+ public void testRemovePartSharingUpperBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 5));
+ rangeSet.remove(Range.openClosed(3, 5));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().item(Range.singleton(3));
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.lessThan(3), Range.greaterThan(3)).inOrder();
+ }
+
+ public void testRemoveMiddle() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.atMost(6));
+ rangeSet.remove(Range.closedOpen(3, 4));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().allOf(Range.lessThan(3), Range.closed(4, 6)).inOrder();
+ ASSERT.that(rangeSet.complement().asRanges())
+ .has().allOf(Range.closedOpen(3, 4), Range.greaterThan(6)).inOrder();
+ }
+
+ public void testRemoveNoOverlap() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 6));
+ rangeSet.remove(Range.closedOpen(1, 3));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().allOf(Range.closed(3, 6)).inOrder();
+ }
+
+ public void testRemovePartFromBelowLowerBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 6));
+ rangeSet.remove(Range.closed(1, 3));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().allOf(Range.openClosed(3, 6)).inOrder();
+ }
+
+ public void testRemovePartFromAboveUpperBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 6));
+ rangeSet.remove(Range.closed(6, 9));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).has().allOf(Range.closedOpen(3, 6)).inOrder();
+ }
+
+ public void testRemoveExact() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 6));
+ rangeSet.remove(Range.closed(3, 6));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).isEmpty();
+ }
+
+ public void testRemoveAllFromBelowLowerBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 6));
+ rangeSet.remove(Range.closed(2, 6));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).isEmpty();
+ }
+
+ public void testRemoveAllFromAboveUpperBound() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 6));
+ rangeSet.remove(Range.closed(3, 7));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).isEmpty();
+ }
+
+ public void testRemoveAllExtendingBothDirections() {
+ TreeRangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 6));
+ rangeSet.remove(Range.closed(2, 7));
+ testInvariants(rangeSet);
+ ASSERT.that(rangeSet.asRanges()).isEmpty();
+ }
+
+ public void testRangeContaining1() {
+ RangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 10));
+ assertEquals(Range.closed(3, 10), rangeSet.rangeContaining(5));
+ assertTrue(rangeSet.contains(5));
+ assertNull(rangeSet.rangeContaining(1));
+ assertFalse(rangeSet.contains(1));
+ }
+
+ public void testRangeContaining2() {
+ RangeSet<Integer> rangeSet = TreeRangeSet.create();
+ rangeSet.add(Range.closed(3, 10));
+ rangeSet.remove(Range.open(5, 7));
+ assertEquals(Range.closed(3, 5), rangeSet.rangeContaining(5));
+ assertTrue(rangeSet.contains(5));
+ assertEquals(Range.closed(7, 10), rangeSet.rangeContaining(8));
+ assertTrue(rangeSet.contains(8));
+ assertNull(rangeSet.rangeContaining(6));
+ assertFalse(rangeSet.contains(6));
+ }
+}
diff --git a/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java b/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java
index 79862c7..1a0d555 100644
--- a/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java
+++ b/guava-tests/test/com/google/common/eventbus/AsyncEventBusTest.java
@@ -17,9 +17,11 @@
package com.google.common.eventbus;
import com.google.common.collect.Lists;
+
+import junit.framework.TestCase;
+
import java.util.List;
import java.util.concurrent.Executor;
-import junit.framework.TestCase;
/**
* Test case for {@link AsyncEventBus}.
diff --git a/guava-tests/test/com/google/common/eventbus/EventBusTest.java b/guava-tests/test/com/google/common/eventbus/EventBusTest.java
index 2a11784..0180557 100644
--- a/guava-tests/test/com/google/common/eventbus/EventBusTest.java
+++ b/guava-tests/test/com/google/common/eventbus/EventBusTest.java
@@ -16,11 +16,17 @@
package com.google.common.eventbus;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
+
+import junit.framework.TestCase;
+
import java.util.Collection;
import java.util.List;
import java.util.Set;
-import junit.framework.TestCase;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
/**
* Test case for {@link EventBus}.
@@ -41,11 +47,6 @@ public class EventBusTest extends TestCase {
public void testBasicCatcherDistribution() {
StringCatcher catcher = new StringCatcher();
bus.register(catcher);
-
- Set<EventHandler> wrappers = bus.getHandlersForEventType(String.class);
- assertNotNull("Should have at least one method registered.", wrappers);
- assertEquals("One method should be registered.", 1, wrappers.size());
-
bus.post(EVENT);
List<String> events = catcher.getEvents();
@@ -209,12 +210,57 @@ public class EventBusTest extends TestCase {
expectedEvents, catcher2.getEvents());
}
+ // NOTE: This test will always pass if register() is thread-safe but may also
+ // pass if it isn't, though this is unlikely.
+
+ public void testRegisterThreadSafety() throws Exception {
+ List<StringCatcher> catchers = Lists.newCopyOnWriteArrayList();
+ List<Future<?>> futures = Lists.newArrayList();
+ ExecutorService executor = Executors.newFixedThreadPool(10);
+ int numberOfCatchers = 10000;
+ for (int i = 0; i < numberOfCatchers; i++) {
+ futures.add(executor.submit(new Registrator(bus, catchers)));
+ }
+ for (int i = 0; i < numberOfCatchers; i++) {
+ futures.get(i).get();
+ }
+ assertEquals("Unexpected number of catchers in the list",
+ numberOfCatchers, catchers.size());
+ bus.post(EVENT);
+ List<String> expectedEvents = ImmutableList.of(EVENT);
+ for (StringCatcher catcher : catchers) {
+ assertEquals("One of the registered catchers did not receive an event.",
+ expectedEvents, catcher.getEvents());
+ }
+ }
+
private <T> void assertContains(T element, Collection<T> collection) {
assertTrue("Collection must contain " + element,
collection.contains(element));
}
/**
+ * Runnable which registers a StringCatcher on an event bus and adds it to a
+ * list.
+ */
+ private static class Registrator implements Runnable {
+ private final EventBus bus;
+ private final List<StringCatcher> catchers;
+
+ Registrator(EventBus bus, List<StringCatcher> catchers) {
+ this.bus = bus;
+ this.catchers = catchers;
+ }
+
+ @Override
+ public void run() {
+ StringCatcher catcher = new StringCatcher();
+ bus.register(catcher);
+ catchers.add(catcher);
+ }
+ }
+
+ /**
* A collector for DeadEvents.
*
* @author cbiffle
diff --git a/guava-tests/test/com/google/common/eventbus/EventHandlerTest.java b/guava-tests/test/com/google/common/eventbus/EventHandlerTest.java
index 00a189a..bdbc332 100644
--- a/guava-tests/test/com/google/common/eventbus/EventHandlerTest.java
+++ b/guava-tests/test/com/google/common/eventbus/EventHandlerTest.java
@@ -16,9 +16,12 @@
package com.google.common.eventbus;
+import com.google.common.testing.EqualsTester;
+
+import junit.framework.TestCase;
+
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import junit.framework.TestCase;
/**
* Test case for {@link EventHandler}.
@@ -56,31 +59,6 @@ public class EventHandlerTest extends TestCase {
methodArgument == FIXTURE_ARGUMENT);
}
- /**
- * Checks that EventHandler's constructor disallows null methods.
- */
- public void testRejectionOfNullMethods() {
- try {
- new EventHandler(this, null);
- fail("EventHandler must immediately reject null methods.");
- } catch (NullPointerException e) {
- // Hooray!
- }
- }
-
- /**
- * Checks that EventHandler's constructor disallows null targets.
- */
- public void testRejectionOfNullTargets() {
- Method method = getRecordingMethod();
- try {
- new EventHandler(null, method);
- fail("EventHandler must immediately reject null targets.");
- } catch (NullPointerException e) {
- // Huzzah!
- }
- }
-
public void testExceptionWrapping() {
Method method = getExceptionThrowingMethod();
EventHandler handler = new EventHandler(this, method);
@@ -106,6 +84,17 @@ public class EventHandlerTest extends TestCase {
}
}
+ public void testEquals() throws Exception {
+ Method charAt = String.class.getMethod("charAt", int.class);
+ Method concat = String.class.getMethod("concat", String.class);
+ new EqualsTester()
+ .addEqualityGroup(
+ new EventHandler("foo", charAt), new EventHandler("foo", charAt))
+ .addEqualityGroup(new EventHandler("bar", charAt))
+ .addEqualityGroup(new EventHandler("foo", concat))
+ .testEquals();
+ }
+
/**
* Gets a reference to {@link #recordingMethod(Object)}.
*
diff --git a/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java b/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java
new file mode 100644
index 0000000..5024370
--- /dev/null
+++ b/guava-tests/test/com/google/common/eventbus/PackageSanityTests.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.eventbus;
+
+import com.google.common.testing.AbstractPackageSanityTests;
+
+import java.lang.reflect.Method;
+
+import javax.annotation.Nullable;
+
+/**
+ * Basic sanity tests for the entire package.
+ *
+ * @author Ben Yu
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {
+
+ public PackageSanityTests() throws Exception {
+ setDefault(EventHandler.class, new DummyHandler().toEventHandler());
+ setDefault(Method.class, DummyHandler.handlerMethod());
+ }
+
+ private static class DummyHandler {
+
+ @SuppressWarnings("unused") // Used by reflection
+ public void handle(@Nullable Object anything) {}
+
+ EventHandler toEventHandler() throws Exception {
+ return new EventHandler(this, handlerMethod());
+ }
+
+ private static Method handlerMethod() throws NoSuchMethodException {
+ return DummyHandler.class.getMethod("handle", Object.class);
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java b/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java
index 3f23050..f39f5f8 100644
--- a/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java
+++ b/guava-tests/test/com/google/common/eventbus/ReentrantEventsTest.java
@@ -17,9 +17,11 @@
package com.google.common.eventbus;
import com.google.common.collect.Lists;
-import java.util.List;
+
import junit.framework.TestCase;
+import java.util.List;
+
/**
* Validate that {@link EventBus} behaves carefully when listeners publish
* their own events.
diff --git a/guava-tests/test/com/google/common/eventbus/StringCatcher.java b/guava-tests/test/com/google/common/eventbus/StringCatcher.java
index fa2e446..d4bfdbd 100644
--- a/guava-tests/test/com/google/common/eventbus/StringCatcher.java
+++ b/guava-tests/test/com/google/common/eventbus/StringCatcher.java
@@ -17,9 +17,13 @@
package com.google.common.eventbus;
import com.google.common.collect.Lists;
-import java.util.List;
+
import junit.framework.Assert;
+import java.util.List;
+
+import javax.annotation.Nullable;
+
/**
* A simple EventHandler mock that records Strings.
*
@@ -32,11 +36,11 @@ public class StringCatcher {
private List<String> events = Lists.newArrayList();
@Subscribe
- public void hereHaveAString(String string) {
+ public void hereHaveAString(@Nullable String string) {
events.add(string);
}
- public void methodWithoutAnnotation(String string) {
+ public void methodWithoutAnnotation(@Nullable String string) {
Assert.fail("Event bus must not call methods without @Subscribe!");
}
diff --git a/guava-tests/test/com/google/common/eventbus/outside/AnnotatedHandlerFinderTests.java b/guava-tests/test/com/google/common/eventbus/outside/AnnotatedHandlerFinderTests.java
new file mode 100644
index 0000000..a28ba00
--- /dev/null
+++ b/guava-tests/test/com/google/common/eventbus/outside/AnnotatedHandlerFinderTests.java
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.eventbus.outside;
+
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.collect.Lists;
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+
+import junit.framework.TestCase;
+
+import java.util.List;
+
+/**
+ * Test that EventBus finds the correct handlers.
+ *
+ * This test must be outside the c.g.c.eventbus package to test correctly.
+ * @author Louis Wasserman
+ */
+public class AnnotatedHandlerFinderTests {
+
+ private static final Object EVENT = new Object();
+
+ abstract static class AbstractEventBusTest<H> extends TestCase {
+ abstract H createHandler();
+
+ private H handler;
+
+ H getHandler() {
+ return handler;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ handler = createHandler();
+ EventBus bus = new EventBus();
+ bus.register(handler);
+ bus.post(EVENT);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ handler = null;
+ }
+ }
+
+ /*
+ * We break the tests up based on whether they are annotated or abstract in the superclass.
+ */
+ public static class BaseHandlerFinderTest extends
+ AbstractEventBusTest<BaseHandlerFinderTest.Handler> {
+ static class Handler {
+ final List<Object> nonSubscriberEvents = Lists.newArrayList();
+ final List<Object> subscriberEvents = Lists.newArrayList();
+
+ public void notASubscriber(Object o) {
+ nonSubscriberEvents.add(o);
+ }
+
+ @Subscribe
+ public void subscriber(Object o) {
+ subscriberEvents.add(o);
+ }
+ }
+
+ public void testNonSubscriber() {
+ ASSERT.that(getHandler().nonSubscriberEvents).isEmpty();
+ }
+
+ public void testSubscriber() {
+ ASSERT.that(getHandler().subscriberEvents).has().item(EVENT);
+ }
+
+ @Override
+ Handler createHandler() {
+ return new Handler();
+ }
+ }
+
+ public static class AnnotatedAndAbstractInSuperclassTest extends
+ AbstractEventBusTest<AnnotatedAndAbstractInSuperclassTest.SubClass> {
+ abstract static class SuperClass {
+ @Subscribe
+ public abstract void overriddenAndAnnotatedInSubclass(Object o);
+
+ @Subscribe
+ public abstract void overriddenInSubclass(Object o);
+ }
+
+ static class SubClass extends SuperClass {
+ final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
+ final List<Object> overriddenInSubclassEvents = Lists.newArrayList();
+
+ @Subscribe
+ @Override
+ public void overriddenAndAnnotatedInSubclass(Object o) {
+ overriddenAndAnnotatedInSubclassEvents.add(o);
+ }
+
+ @Override
+ public void overriddenInSubclass(Object o) {
+ overriddenInSubclassEvents.add(o);
+ }
+ }
+
+ public void testOverriddenAndAnnotatedInSubclass() {
+ ASSERT.that(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
+ }
+
+ public void testOverriddenNotAnnotatedInSubclass() {
+ ASSERT.that(getHandler().overriddenInSubclassEvents).has().item(EVENT);
+ }
+
+ @Override
+ SubClass createHandler() {
+ return new SubClass();
+ }
+ }
+
+ public static class AnnotatedNotAbstractInSuperclassTest extends
+ AbstractEventBusTest<AnnotatedNotAbstractInSuperclassTest.SubClass> {
+ static class SuperClass {
+ final List<Object> notOverriddenInSubclassEvents = Lists.newArrayList();
+ final List<Object> overriddenNotAnnotatedInSubclassEvents = Lists.newArrayList();
+ final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
+ final List<Object> differentlyOverriddenNotAnnotatedInSubclassBadEvents = Lists
+ .newArrayList();
+ final List<Object> differentlyOverriddenAnnotatedInSubclassBadEvents = Lists.newArrayList();
+
+ @Subscribe
+ public void notOverriddenInSubclass(Object o) {
+ notOverriddenInSubclassEvents.add(o);
+ }
+
+ @Subscribe
+ public void overriddenNotAnnotatedInSubclass(Object o) {
+ overriddenNotAnnotatedInSubclassEvents.add(o);
+ }
+
+ @Subscribe
+ public void overriddenAndAnnotatedInSubclass(Object o) {
+ overriddenAndAnnotatedInSubclassEvents.add(o);
+ }
+
+ @Subscribe
+ public void differentlyOverriddenNotAnnotatedInSubclass(Object o) {
+ // the subclass overrides this and does *not* call super.dONAIS(o)
+ differentlyOverriddenNotAnnotatedInSubclassBadEvents.add(o);
+ }
+
+ @Subscribe
+ public void differentlyOverriddenAnnotatedInSubclass(Object o) {
+ // the subclass overrides this and does *not* call super.dOAIS(o)
+ differentlyOverriddenAnnotatedInSubclassBadEvents.add(o);
+ }
+ }
+
+ static class SubClass extends SuperClass {
+ final List<Object> differentlyOverriddenNotAnnotatedInSubclassGoodEvents = Lists
+ .newArrayList();
+ final List<Object> differentlyOverriddenAnnotatedInSubclassGoodEvents = Lists.newArrayList();
+
+ @Override
+ public void overriddenNotAnnotatedInSubclass(Object o) {
+ super.overriddenNotAnnotatedInSubclass(o);
+ }
+
+ @Subscribe
+ @Override
+ public void overriddenAndAnnotatedInSubclass(Object o) {
+ super.overriddenAndAnnotatedInSubclass(o);
+ }
+
+ @Override
+ public void differentlyOverriddenNotAnnotatedInSubclass(Object o) {
+ differentlyOverriddenNotAnnotatedInSubclassGoodEvents.add(o);
+ }
+
+ @Subscribe
+ @Override
+ public void differentlyOverriddenAnnotatedInSubclass(Object o) {
+ differentlyOverriddenAnnotatedInSubclassGoodEvents.add(o);
+ }
+ }
+
+ public void testNotOverriddenInSubclass() {
+ ASSERT.that(getHandler().notOverriddenInSubclassEvents).has().item(EVENT);
+ }
+
+ public void testOverriddenNotAnnotatedInSubclass() {
+ ASSERT.that(getHandler().overriddenNotAnnotatedInSubclassEvents).has().item(EVENT);
+ }
+
+ public void testDifferentlyOverriddenNotAnnotatedInSubclass() {
+ ASSERT
+ .that(getHandler().differentlyOverriddenNotAnnotatedInSubclassGoodEvents)
+ .has().item(EVENT);
+ ASSERT.that(getHandler().differentlyOverriddenNotAnnotatedInSubclassBadEvents).isEmpty();
+ }
+
+ public void testOverriddenAndAnnotatedInSubclass() {
+ ASSERT.that(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
+ }
+
+ public void testDifferentlyOverriddenAndAnnotatedInSubclass() {
+ ASSERT
+ .that(getHandler().differentlyOverriddenAnnotatedInSubclassGoodEvents)
+ .has().item(EVENT);
+ ASSERT.that(getHandler().differentlyOverriddenAnnotatedInSubclassBadEvents).isEmpty();
+ }
+
+ @Override
+ SubClass createHandler() {
+ return new SubClass();
+ }
+ }
+
+ public static class AbstractNotAnnotatedInSuperclassTest extends
+ AbstractEventBusTest<AbstractNotAnnotatedInSuperclassTest.SubClass> {
+ abstract static class SuperClass {
+ public abstract void overriddenInSubclassNowhereAnnotated(Object o);
+
+ public abstract void overriddenAndAnnotatedInSubclass(Object o);
+ }
+
+ static class SubClass extends SuperClass {
+ final List<Object> overriddenInSubclassNowhereAnnotatedEvents = Lists.newArrayList();
+ final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
+
+ @Override
+ public void overriddenInSubclassNowhereAnnotated(Object o) {
+ overriddenInSubclassNowhereAnnotatedEvents.add(o);
+ }
+
+ @Subscribe
+ @Override
+ public void overriddenAndAnnotatedInSubclass(Object o) {
+ overriddenAndAnnotatedInSubclassEvents.add(o);
+ }
+ }
+
+ public void testOverriddenAndAnnotatedInSubclass() {
+ ASSERT.that(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
+ }
+
+ public void testOverriddenInSubclassNowhereAnnotated() {
+ ASSERT.that(getHandler().overriddenInSubclassNowhereAnnotatedEvents).isEmpty();
+ }
+
+ @Override
+ SubClass createHandler() {
+ return new SubClass();
+ }
+ }
+
+ public static class NeitherAbstractNorAnnotatedInSuperclassTest extends
+ AbstractEventBusTest<NeitherAbstractNorAnnotatedInSuperclassTest.SubClass> {
+ static class SuperClass {
+ final List<Object> neitherOverriddenNorAnnotatedEvents = Lists.newArrayList();
+ final List<Object> overriddenInSubclassNowhereAnnotatedEvents = Lists.newArrayList();
+ final List<Object> overriddenAndAnnotatedInSubclassEvents = Lists.newArrayList();
+
+ public void neitherOverriddenNorAnnotated(Object o) {
+ neitherOverriddenNorAnnotatedEvents.add(o);
+ }
+
+ public void overriddenInSubclassNowhereAnnotated(Object o) {
+ overriddenInSubclassNowhereAnnotatedEvents.add(o);
+ }
+
+ public void overriddenAndAnnotatedInSubclass(Object o) {
+ overriddenAndAnnotatedInSubclassEvents.add(o);
+ }
+ }
+
+ static class SubClass extends SuperClass {
+ @Override
+ public void overriddenInSubclassNowhereAnnotated(Object o) {
+ super.overriddenInSubclassNowhereAnnotated(o);
+ }
+
+ @Subscribe
+ @Override
+ public void overriddenAndAnnotatedInSubclass(Object o) {
+ super.overriddenAndAnnotatedInSubclass(o);
+ }
+ }
+
+ public void testNeitherOverriddenNorAnnotated() {
+ ASSERT.that(getHandler().neitherOverriddenNorAnnotatedEvents).isEmpty();
+ }
+
+ public void testOverriddenInSubclassNowhereAnnotated() {
+ ASSERT.that(getHandler().overriddenInSubclassNowhereAnnotatedEvents).isEmpty();
+ }
+
+ public void testOverriddenAndAnnotatedInSubclass() {
+ ASSERT.that(getHandler().overriddenAndAnnotatedInSubclassEvents).has().item(EVENT);
+ }
+
+ @Override
+ SubClass createHandler() {
+ return new SubClass();
+ }
+ }
+
+ public static class DeepInterfaceTest extends
+ AbstractEventBusTest<DeepInterfaceTest.HandlerClass> {
+ interface Interface1 {
+ @Subscribe
+ void annotatedIn1(Object o);
+
+ @Subscribe
+ void annotatedIn1And2(Object o);
+
+ @Subscribe
+ void annotatedIn1And2AndClass(Object o);
+
+ void declaredIn1AnnotatedIn2(Object o);
+
+ void declaredIn1AnnotatedInClass(Object o);
+
+ void nowhereAnnotated(Object o);
+ }
+
+ interface Interface2 extends Interface1 {
+ @Override
+ @Subscribe
+ void declaredIn1AnnotatedIn2(Object o);
+
+ @Override
+ @Subscribe
+ void annotatedIn1And2(Object o);
+
+ @Override
+ @Subscribe
+ void annotatedIn1And2AndClass(Object o);
+
+ void declaredIn2AnnotatedInClass(Object o);
+
+ @Subscribe
+ void annotatedIn2(Object o);
+ }
+
+ static class HandlerClass implements Interface2 {
+ final List<Object> annotatedIn1Events = Lists.newArrayList();
+ final List<Object> annotatedIn1And2Events = Lists.newArrayList();
+ final List<Object> annotatedIn1And2AndClassEvents = Lists.newArrayList();
+ final List<Object> declaredIn1AnnotatedIn2Events = Lists.newArrayList();
+ final List<Object> declaredIn1AnnotatedInClassEvents = Lists.newArrayList();
+ final List<Object> declaredIn2AnnotatedInClassEvents = Lists.newArrayList();
+ final List<Object> annotatedIn2Events = Lists.newArrayList();
+ final List<Object> nowhereAnnotatedEvents = Lists.newArrayList();
+
+ @Override
+ public void annotatedIn1(Object o) {
+ annotatedIn1Events.add(o);
+ }
+
+ @Subscribe
+ @Override
+ public void declaredIn1AnnotatedInClass(Object o) {
+ declaredIn1AnnotatedInClassEvents.add(o);
+ }
+
+ @Override
+ public void declaredIn1AnnotatedIn2(Object o) {
+ declaredIn1AnnotatedIn2Events.add(o);
+ }
+
+ @Override
+ public void annotatedIn1And2(Object o) {
+ annotatedIn1And2Events.add(o);
+ }
+
+ @Subscribe
+ @Override
+ public void annotatedIn1And2AndClass(Object o) {
+ annotatedIn1And2AndClassEvents.add(o);
+ }
+
+ @Subscribe
+ @Override
+ public void declaredIn2AnnotatedInClass(Object o) {
+ declaredIn2AnnotatedInClassEvents.add(o);
+ }
+
+ @Override
+ public void annotatedIn2(Object o) {
+ annotatedIn2Events.add(o);
+ }
+
+ @Override
+ public void nowhereAnnotated(Object o) {
+ nowhereAnnotatedEvents.add(o);
+ }
+ }
+
+ public void testAnnotatedIn1() {
+ ASSERT.that(getHandler().annotatedIn1Events).has().item(EVENT);
+ }
+
+ public void testAnnotatedIn2() {
+ ASSERT.that(getHandler().annotatedIn2Events).has().item(EVENT);
+ }
+
+ public void testAnnotatedIn1And2() {
+ ASSERT.that(getHandler().annotatedIn1And2Events).has().item(EVENT);
+ }
+
+ public void testAnnotatedIn1And2AndClass() {
+ ASSERT.that(getHandler().annotatedIn1And2AndClassEvents).has().item(EVENT);
+ }
+
+ public void testDeclaredIn1AnnotatedIn2() {
+ ASSERT.that(getHandler().declaredIn1AnnotatedIn2Events).has().item(EVENT);
+ }
+
+ public void testDeclaredIn1AnnotatedInClass() {
+ ASSERT.that(getHandler().declaredIn1AnnotatedInClassEvents).has().item(EVENT);
+ }
+
+ public void testDeclaredIn2AnnotatedInClass() {
+ ASSERT.that(getHandler().declaredIn2AnnotatedInClassEvents).has().item(EVENT);
+ }
+
+ public void testNowhereAnnotated() {
+ ASSERT.that(getHandler().nowhereAnnotatedEvents).isEmpty();
+ }
+
+ @Override
+ HandlerClass createHandler() {
+ return new HandlerClass();
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java b/guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java
new file mode 100644
index 0000000..d23e021
--- /dev/null
+++ b/guava-tests/test/com/google/common/eventbus/outside/OutsideEventBusTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.eventbus.outside;
+
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+
+import junit.framework.TestCase;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Test cases for {@code EventBus} that must not be in the same package.
+ *
+ * @author Louis Wasserman
+ */
+public class OutsideEventBusTest extends TestCase {
+
+ /*
+ * If you do this test from common.eventbus.EventBusTest, it doesn't actually test the behavior.
+ * That is, even if exactly the same method works from inside the common.eventbus package tests,
+ * it can fail here.
+ */
+ public void testAnonymous() {
+ final AtomicReference<String> holder = new AtomicReference<String>();
+ final AtomicInteger deliveries = new AtomicInteger();
+ EventBus bus = new EventBus();
+ bus.register(new Object() {
+ @Subscribe
+ public void accept(String str) {
+ holder.set(str);
+ deliveries.incrementAndGet();
+ }
+ });
+
+ String EVENT = "Hello!";
+ bus.post(EVENT);
+
+ assertEquals("Only one event should be delivered.", 1, deliveries.get());
+ assertEquals("Correct string should be delivered.", EVENT, holder.get());
+ }
+}
diff --git a/guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java b/guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java
new file mode 100644
index 0000000..53a55a5
--- /dev/null
+++ b/guava-tests/test/com/google/common/hash/AbstractByteHasherTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.hash;
+
+import static com.google.common.base.Charsets.UTF_16LE;
+import static org.junit.Assert.assertArrayEquals;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Random;
+
+/**
+ * Tests for AbstractByteHasher.
+ *
+ * @author Colin Decker
+ */
+public class AbstractByteHasherTest extends TestCase {
+
+ public void testBytes() {
+ TestHasher hasher = new TestHasher(); // byte order insignificant here
+ byte[] expected = {1, 2, 3, 4, 5, 6, 7, 8};
+ hasher.putByte((byte) 1);
+ hasher.putBytes(new byte[]{2, 3, 4, 5, 6});
+ hasher.putByte((byte) 7);
+ hasher.putBytes(new byte[]{});
+ hasher.putBytes(new byte[]{8});
+ hasher.assertBytes(expected);
+ }
+
+ public void testShort() {
+ TestHasher hasher = new TestHasher();
+ hasher.putShort((short) 0x0201);
+ hasher.assertBytes(new byte[]{1, 2});
+ }
+
+ public void testInt() {
+ TestHasher hasher = new TestHasher();
+ hasher.putInt(0x04030201);
+ hasher.assertBytes(new byte[]{1, 2, 3, 4});
+ }
+
+ public void testLong() {
+ TestHasher hasher = new TestHasher();
+ hasher.putLong(0x0807060504030201L);
+ hasher.assertBytes(new byte[]{1, 2, 3, 4, 5, 6, 7, 8});
+ }
+
+ public void testChar() {
+ TestHasher hasher = new TestHasher();
+ hasher.putChar((char) 0x0201);
+ hasher.assertBytes(new byte[]{1, 2});
+ }
+
+ public void testString() {
+ Random random = new Random();
+ for (int i = 0; i < 100; i++) {
+ byte[] bytes = new byte[64];
+ random.nextBytes(bytes);
+ String s = new String(bytes, UTF_16LE); // so all random strings are valid
+ assertEquals(
+ new TestHasher().putString(s).hash(),
+ new TestHasher().putBytes(s.getBytes(UTF_16LE)).hash());
+ assertEquals(
+ new TestHasher().putString(s).hash(),
+ new TestHasher().putString(s, UTF_16LE).hash());
+ }
+ }
+
+ public void testFloat() {
+ TestHasher hasher = new TestHasher();
+ hasher.putFloat(Float.intBitsToFloat(0x04030201));
+ hasher.assertBytes(new byte[]{1, 2, 3, 4});
+ }
+
+ public void testDouble() {
+ TestHasher hasher = new TestHasher();
+ hasher.putDouble(Double.longBitsToDouble(0x0807060504030201L));
+ hasher.assertBytes(new byte[]{1, 2, 3, 4, 5, 6, 7, 8});
+ }
+
+ public void testCorrectExceptions() {
+ TestHasher hasher = new TestHasher();
+ try {
+ hasher.putBytes(new byte[8], -1, 4);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ hasher.putBytes(new byte[8], 0, 16);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ try {
+ hasher.putBytes(new byte[8], 0, -1);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
+ }
+
+ private class TestHasher extends AbstractByteHasher {
+
+ private final ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ @Override
+ protected void update(byte b) {
+ out.write(b);
+ }
+
+ @Override
+ protected void update(byte[] b, int off, int len) {
+ out.write(b, off, len);
+ }
+
+ byte[] bytes() {
+ return out.toByteArray();
+ }
+
+ void assertBytes(byte[] expected) {
+ assertArrayEquals(expected, bytes());
+ }
+
+ @Override
+ public HashCode hash() {
+ return HashCodes.fromBytesNoCopy(bytes());
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java b/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java
index b4edf42..2cec063 100644
--- a/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java
+++ b/guava-tests/test/com/google/common/hash/AbstractNonStreamingHashFunctionTest.java
@@ -1,4 +1,18 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.google.common.hash;
@@ -22,8 +36,8 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase {
* Constructs two trivial HashFunctions (output := input), one streaming and one non-streaming,
* and checks that their results are identical, no matter which newHasher version we used.
*/
- public void test() {
- List<Hasher> hashers = ImmutableList.of(
+ public void testExhaustive() {
+ List<Hasher> hashers = ImmutableList.of(
new StreamingVersion().newHasher(),
new StreamingVersion().newHasher(52),
new NonStreamingVersion().newHasher(),
@@ -40,7 +54,43 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase {
assertEquals(codes[i - 1], codes[i]);
}
}
-
+
+ public void testPutStringWithLowSurrogate() {
+ // we pad because the dummy hash function we use to test this, merely copies the input into
+ // the output, so the input must be at least 32 bits, since the output has to be that long
+ assertPutString(new char[] { 'p', HashTestUtils.randomLowSurrogate(new Random()) });
+ }
+
+ public void testPutStringWithHighSurrogate() {
+ // we pad because the dummy hash function we use to test this, merely copies the input into
+ // the output, so the input must be at least 32 bits, since the output has to be that long
+ assertPutString(new char[] { 'p', HashTestUtils.randomHighSurrogate(new Random()) });
+ }
+
+ public void testPutStringWithLowHighSurrogate() {
+ assertPutString(new char[] {
+ HashTestUtils.randomLowSurrogate(new Random()),
+ HashTestUtils.randomHighSurrogate(new Random()) });
+ }
+
+ public void testPutStringWithHighLowSurrogate() {
+ assertPutString(new char[] {
+ HashTestUtils.randomHighSurrogate(new Random()),
+ HashTestUtils.randomLowSurrogate(new Random()) });
+ }
+
+ private static void assertPutString(char[] chars) {
+ Hasher h1 = new NonStreamingVersion().newHasher();
+ Hasher h2 = new NonStreamingVersion().newHasher();
+ String s = new String(chars);
+ // this is the correct implementation of the spec
+ for (int i = 0; i < s.length(); i++) {
+ h1.putChar(s.charAt(i));
+ }
+ h2.putString(s);
+ assertEquals(h1.hash(), h2.hash());
+ }
+
static class StreamingVersion extends AbstractStreamingHashFunction {
@Override
public int bits() {
@@ -72,7 +122,7 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase {
};
}
}
-
+
static class NonStreamingVersion extends AbstractNonStreamingHashFunction {
@Override
public int bits() {
@@ -88,12 +138,12 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase {
public HashCode hashBytes(byte[] input, int off, int len) {
return HashCodes.fromBytes(Arrays.copyOfRange(input, off, off + len));
}
-
+
@Override
public HashCode hashString(CharSequence input) {
throw new UnsupportedOperationException();
}
-
+
@Override
public HashCode hashString(CharSequence input, Charset charset) {
throw new UnsupportedOperationException();
@@ -103,5 +153,10 @@ public class AbstractNonStreamingHashFunctionTest extends TestCase {
public HashCode hashLong(long input) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public HashCode hashInt(int input) {
+ throw new UnsupportedOperationException();
+ }
}
}
diff --git a/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java b/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java
index 8f1cbb4..7324e6f 100644
--- a/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java
+++ b/guava-tests/test/com/google/common/hash/AbstractStreamingHasherTest.java
@@ -1,7 +1,23 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.google.common.hash;
+import static com.google.common.base.Charsets.UTF_16LE;
+
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.hash.AbstractStreamingHashFunction.AbstractStreamingHasher;
@@ -19,30 +35,24 @@ import java.util.List;
import java.util.Random;
/**
- * Tests for AbstractHashSink.
- *
- * @author andreou@google.com (Dimitris Andreou)
+ * Tests for AbstractStreamingHasher.
+ *
+ * @author Dimitris Andreou
*/
public class AbstractStreamingHasherTest extends TestCase {
- /** Test we get the HashCode that is created by the sink. Later we ignore the result */
- public void testSanity() {
- Sink sink = new Sink(4);
- assertEquals(0xDeadBeef, sink.makeHash().asInt());
- }
-
public void testBytes() {
Sink sink = new Sink(4); // byte order insignificant here
byte[] expected = { 1, 2, 3, 4, 5, 6, 7, 8 };
sink.putByte((byte) 1);
sink.putBytes(new byte[] { 2, 3, 4, 5, 6 });
sink.putByte((byte) 7);
- sink.putBytes(new byte[] { });
+ sink.putBytes(new byte[] {});
sink.putBytes(new byte[] { 8 });
sink.hash();
sink.assertInvariants(8);
sink.assertBytes(expected);
}
-
+
public void testShort() {
Sink sink = new Sink(4);
sink.putShort((short) 0x0201);
@@ -50,7 +60,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(2);
sink.assertBytes(new byte[] { 1, 2, 0, 0 }); // padded with zeros
}
-
+
public void testInt() {
Sink sink = new Sink(4);
sink.putInt(0x04030201);
@@ -58,7 +68,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(4);
sink.assertBytes(new byte[] { 1, 2, 3, 4 });
}
-
+
public void testLong() {
Sink sink = new Sink(8);
sink.putLong(0x0807060504030201L);
@@ -66,7 +76,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(8);
sink.assertBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
}
-
+
public void testChar() {
Sink sink = new Sink(4);
sink.putChar((char) 0x0201);
@@ -74,7 +84,22 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(2);
sink.assertBytes(new byte[] { 1, 2, 0, 0 }); // padded with zeros
}
-
+
+ public void testString() {
+ Random random = new Random();
+ for (int i = 0; i < 100; i++) {
+ byte[] bytes = new byte[64];
+ random.nextBytes(bytes);
+ String s = new String(bytes, UTF_16LE); // so all random strings are valid
+ assertEquals(
+ new Sink(4).putString(s).hash(),
+ new Sink(4).putBytes(s.getBytes(UTF_16LE)).hash());
+ assertEquals(
+ new Sink(4).putString(s).hash(),
+ new Sink(4).putString(s, UTF_16LE).hash());
+ }
+ }
+
public void testFloat() {
Sink sink = new Sink(4);
sink.putFloat(Float.intBitsToFloat(0x04030201));
@@ -82,7 +107,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(4);
sink.assertBytes(new byte[] { 1, 2, 3, 4 });
}
-
+
public void testDouble() {
Sink sink = new Sink(8);
sink.putDouble(Double.longBitsToDouble(0x0807060504030201L));
@@ -90,7 +115,7 @@ public class AbstractStreamingHasherTest extends TestCase {
sink.assertInvariants(8);
sink.assertBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
}
-
+
public void testCorrectExceptions() {
Sink sink = new Sink(4);
try {
@@ -106,16 +131,16 @@ public class AbstractStreamingHasherTest extends TestCase {
fail();
} catch (IndexOutOfBoundsException ok) {}
}
-
+
/**
* This test creates a long random sequence of inputs, then a lot of differently configured
* sinks process it; all should produce the same answer, the only difference should be the
- * number of process()/processRemaining() invocations, due to alignment.
+ * number of process()/processRemaining() invocations, due to alignment.
*/
public void testExhaustive() throws Exception {
Random random = new Random(0); // will iteratively make more debuggable, each time it breaks
for (int totalInsertions = 0; totalInsertions < 200; totalInsertions++) {
-
+
List<Sink> sinks = Lists.newArrayList();
for (int chunkSize = 4; chunkSize <= 32; chunkSize++) {
for (int bufferSize = chunkSize; bufferSize <= chunkSize * 4; bufferSize += chunkSize) {
@@ -123,22 +148,28 @@ public class AbstractStreamingHasherTest extends TestCase {
sinks.add(new Sink(chunkSize, bufferSize));
// For convenience, testing only with big endianness, to match DataOutputStream.
// I regard highly unlikely that both the little endianness tests above and this one
- // passes, and there is still a little endianness bug lurking around.
+ // passes, and there is still a little endianness bug lurking around.
}
}
-
+
Control control = new Control();
Hasher controlSink = control.newHasher(1024);
-
- Iterable<Hasher> sinksAndControl = Iterables.concat(
- sinks, Collections.singleton(controlSink));
+
+ Iterable<Hasher> sinksAndControl =
+ Iterables.concat(sinks, Collections.singleton(controlSink));
for (int insertion = 0; insertion < totalInsertions; insertion++) {
- RandomHasherAction.pickAtRandom(random).performAction(random, sinksAndControl);
+ RandomHasherAction.pickAtRandom(random).performAction(random, sinksAndControl);
+ }
+ // We need to ensure that at least 4 bytes have been put into the hasher or else
+ // Hasher#hash will throw an ISE.
+ int intToPut = random.nextInt();
+ for (Hasher hasher : sinksAndControl) {
+ hasher.putInt(intToPut);
}
for (Sink sink : sinks) {
sink.hash();
}
-
+
byte[] expected = controlSink.hash().asBytes();
for (Sink sink : sinks) {
sink.assertInvariants(expected.length);
@@ -146,15 +177,15 @@ public class AbstractStreamingHasherTest extends TestCase {
}
}
}
-
+
private static class Sink extends AbstractStreamingHasher {
final int chunkSize;
final int bufferSize;
final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
+
int processCalled = 0;
boolean remainingCalled = false;
-
+
Sink(int chunkSize, int bufferSize) {
super(chunkSize, bufferSize);
this.chunkSize = chunkSize;
@@ -168,7 +199,7 @@ public class AbstractStreamingHasherTest extends TestCase {
}
@Override HashCode makeHash() {
- return HashCodes.fromInt(0xDeadBeef);
+ return HashCodes.fromBytes(out.toByteArray());
}
@Override protected void process(ByteBuffer bb) {
@@ -179,7 +210,7 @@ public class AbstractStreamingHasherTest extends TestCase {
out.write(bb.get());
}
}
-
+
@Override protected void processRemaining(ByteBuffer bb) {
assertFalse(remainingCalled);
remainingCalled = true;
@@ -192,21 +223,21 @@ public class AbstractStreamingHasherTest extends TestCase {
assertEquals(before + 1, after); // default implementation pads and calls process()
processCalled--; // don't count the tail invocation (makes tests a bit more understandable)
}
-
+
// ensures that the number of invocations looks sane
void assertInvariants(int expectedBytes) {
- // we should have seen as many bytes as the next multiple of chunk after expectedBytes - 1
+ // we should have seen as many bytes as the next multiple of chunk after expectedBytes - 1
assertEquals(out.toByteArray().length, ceilToMultiple(expectedBytes, chunkSize));
assertEquals(expectedBytes / chunkSize, processCalled);
assertEquals(expectedBytes % chunkSize != 0, remainingCalled);
}
-
+
// returns the minimum x such as x >= a && (x % b) == 0
private static int ceilToMultiple(int a, int b) {
int remainder = a % b;
return remainder == 0 ? a : a + b - remainder;
}
-
+
void assertBytes(byte[] expected) {
byte[] got = out.toByteArray();
for (int i = 0; i < expected.length; i++) {
@@ -214,13 +245,14 @@ public class AbstractStreamingHasherTest extends TestCase {
}
}
}
-
+
+ // Assumes that AbstractNonStreamingHashFunction works properly (must be tested elsewhere!)
private static class Control extends AbstractNonStreamingHashFunction {
@Override
public HashCode hashBytes(byte[] input) {
return HashCodes.fromBytes(input);
}
-
+
@Override
public HashCode hashBytes(byte[] input, int off, int len) {
return hashBytes(Arrays.copyOfRange(input, off, off + len));
@@ -245,5 +277,10 @@ public class AbstractStreamingHasherTest extends TestCase {
public HashCode hashLong(long input) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public HashCode hashInt(int input) {
+ throw new UnsupportedOperationException();
+ }
}
}
diff --git a/guava-tests/test/com/google/common/hash/BloomFilterTest.java b/guava-tests/test/com/google/common/hash/BloomFilterTest.java
index 26b7641..d9056f6 100644
--- a/guava-tests/test/com/google/common/hash/BloomFilterTest.java
+++ b/guava-tests/test/com/google/common/hash/BloomFilterTest.java
@@ -1,20 +1,79 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.google.common.hash;
+import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
import junit.framework.TestCase;
import java.util.Random;
+import javax.annotation.Nullable;
+
/**
* Tests for SimpleGenericBloomFilter and derived BloomFilter views.
- *
- * @author andreou@google.com (Dimitris Andreou)
+ *
+ * @author Dimitris Andreou
*/
public class BloomFilterTest extends TestCase {
+
+ public void testCreateAndCheckBloomFilterWithKnownFalsePositives() {
+ int numInsertions = 1000000;
+ BloomFilter<CharSequence> bf = BloomFilter.create(Funnels.stringFunnel(), numInsertions);
+
+ // Insert "numInsertions" even numbers into the BF.
+ for (int i = 0; i < numInsertions * 2; i += 2) {
+ bf.put(Integer.toString(i));
+ }
+
+ // Assert that the BF "might" have all of the even numbers.
+ for (int i = 0; i < numInsertions * 2; i += 2) {
+ assertTrue(bf.mightContain(Integer.toString(i)));
+ }
+
+ // Now we check for known false positives using a set of known false positives.
+ // (These are all of the false positives under 900.)
+ ImmutableSet<Integer> falsePositives = ImmutableSet.of(
+ 49, 51, 59, 163, 199, 321, 325, 363, 367, 469, 545, 561, 727, 769, 773, 781);
+ for (int i = 1; i < 900; i += 2) {
+ if (!falsePositives.contains(i)) {
+ assertFalse("BF should not contain " + i, bf.mightContain(Integer.toString(i)));
+ }
+ }
+
+ // Check that there are exactly 29824 false positives for this BF.
+ int knownNumberOfFalsePositives = 29824;
+ int numFpp = 0;
+ for (int i = 1; i < numInsertions * 2; i += 2) {
+ if (bf.mightContain(Integer.toString(i))) {
+ numFpp++;
+ }
+ }
+ assertEquals(knownNumberOfFalsePositives, numFpp);
+ double actualFpp = (double) knownNumberOfFalsePositives / numInsertions;
+ double expectedFpp = bf.expectedFpp();
+ // The normal order of (expected, actual) is reversed here on purpose.
+ assertEquals(actualFpp, expectedFpp, 0.00015);
+ }
+
/**
* Sanity checking with many combinations of false positive rates and expected insertions
*/
@@ -25,9 +84,43 @@ public class BloomFilterTest extends TestCase {
}
}
}
-
+
+ public void testPreconditions() {
+ try {
+ BloomFilter.create(Funnels.stringFunnel(), -1);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ BloomFilter.create(Funnels.stringFunnel(), -1, 0.03);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ BloomFilter.create(Funnels.stringFunnel(), 1, 0.0);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ BloomFilter.create(Funnels.stringFunnel(), 1, 1.0);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testFailureWhenMoreThan255HashFunctionsAreNeeded() {
+ try {
+ int n = 1000;
+ double p = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000001;
+ BloomFilter.create(Funnels.stringFunnel(), n, p);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testNullPointers() {
+ NullPointerTester tester = new NullPointerTester();
+ tester.testAllPublicInstanceMethods(BloomFilter.create(Funnels.stringFunnel(), 100));
+ tester.testAllPublicStaticMethods(BloomFilter.class);
+ }
+
/**
- * Tests that we never get an optimal hashes number of zero.
+ * Tests that we never get an optimal hashes number of zero.
*/
public void testOptimalHashes() {
for (int n = 1; n < 1000; n++) {
@@ -36,9 +129,9 @@ public class BloomFilterTest extends TestCase {
}
}
}
-
+
/**
- * Tests that we always get a non-negative optimal size.
+ * Tests that we always get a non-negative optimal size.
*/
public void testOptimalSize() {
for (int n = 1; n < 1000; n++) {
@@ -46,36 +139,148 @@ public class BloomFilterTest extends TestCase {
assertTrue(BloomFilter.optimalNumOfBits(n, fpp) >= 0);
}
}
-
+
// some random values
- Random random = new Random(0);
+ Random random = new Random(0);
for (int repeats = 0; repeats < 10000; repeats++) {
assertTrue(BloomFilter.optimalNumOfBits(random.nextInt(1 << 16), random.nextDouble()) >= 0);
}
-
- // and some crazy values
- assertEquals(Integer.MAX_VALUE, BloomFilter.optimalNumOfBits(
+
+ // and some crazy values (this used to be capped to Integer.MAX_VALUE, now it can go bigger
+ assertEquals(3327428144502L, BloomFilter.optimalNumOfBits(
Integer.MAX_VALUE, Double.MIN_VALUE));
+ try {
+ BloomFilter.create(HashTestUtils.BAD_FUNNEL, Integer.MAX_VALUE, Double.MIN_VALUE);
+ fail("we can't represent such a large BF!");
+ } catch (IllegalArgumentException expected) {
+ assertEquals("Could not create BloomFilter of 3327428144502 bits", expected.getMessage());
+ }
}
-
+
private void checkSanity(BloomFilter<Object> bf) {
assertFalse(bf.mightContain(new Object()));
+ assertFalse(bf.apply(new Object()));
for (int i = 0; i < 100; i++) {
Object o = new Object();
bf.put(o);
assertTrue(bf.mightContain(o));
+ assertTrue(bf.apply(o));
}
}
-
- public void testSerialization() {
+
+ public void testCopy() {
+ BloomFilter<CharSequence> original = BloomFilter.create(Funnels.stringFunnel(), 100);
+ BloomFilter<CharSequence> copy = original.copy();
+ assertNotSame(original, copy);
+ assertEquals(original, copy);
+ }
+
+ public void testExpectedFpp() {
+ BloomFilter<Object> bf = BloomFilter.create(HashTestUtils.BAD_FUNNEL, 10, 0.03);
+ double fpp = bf.expectedFpp();
+ assertEquals(0.0, fpp);
+ // usually completed in less than 200 iterations
+ while (fpp != 1.0) {
+ boolean changed = bf.put(new Object());
+ double newFpp = bf.expectedFpp();
+ // if changed, the new fpp is strictly higher, otherwise it is the same
+ assertTrue(changed ? newFpp > fpp : newFpp == fpp);
+ fpp = newFpp;
+ }
+ }
+
+ public void testEquals_empty() {
+ new EqualsTester()
+ .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 100, 0.01))
+ .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 100, 0.02))
+ .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 200, 0.01))
+ .addEqualityGroup(BloomFilter.create(Funnels.byteArrayFunnel(), 200, 0.02))
+ .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 100, 0.01))
+ .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 100, 0.02))
+ .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 200, 0.01))
+ .addEqualityGroup(BloomFilter.create(Funnels.stringFunnel(), 200, 0.02))
+ .testEquals();
+ }
+
+ public void testEquals() {
+ BloomFilter<CharSequence> bf1 = BloomFilter.create(Funnels.stringFunnel(), 100);
+ bf1.put("1");
+ bf1.put("2");
+
+ BloomFilter<CharSequence> bf2 = BloomFilter.create(Funnels.stringFunnel(), 100);
+ bf2.put("1");
+ bf2.put("2");
+
+ new EqualsTester()
+ .addEqualityGroup(bf1, bf2)
+ .testEquals();
+
+ bf2.put("3");
+
+ new EqualsTester()
+ .addEqualityGroup(bf1)
+ .addEqualityGroup(bf2)
+ .testEquals();
+ }
+
+ public void testEqualsWithCustomFunnel() {
+ BloomFilter<Long> bf1 = BloomFilter.create(new CustomFunnel(), 100);
+ BloomFilter<Long> bf2 = BloomFilter.create(new CustomFunnel(), 100);
+ assertEquals(bf1, bf2);
+ }
+
+ public void testSerializationWithCustomFunnel() {
+ SerializableTester.reserializeAndAssert(BloomFilter.create(new CustomFunnel(), 100));
+ }
+
+ private static final class CustomFunnel implements Funnel<Long> {
+ @Override
+ public void funnel(Long value, PrimitiveSink into) {
+ into.putLong(value);
+ }
+ @Override
+ public boolean equals(@Nullable Object object) {
+ return (object instanceof CustomFunnel);
+ }
+ @Override
+ public int hashCode() {
+ return 42;
+ }
+ }
+
+ public void testPutReturnValue() {
+ for (int i = 0; i < 10; i++) {
+ BloomFilter<CharSequence> bf = BloomFilter.create(Funnels.stringFunnel(), 100);
+ for (int j = 0; j < 10; j++) {
+ String value = new Object().toString();
+ boolean mightContain = bf.mightContain(value);
+ boolean put = bf.put(value);
+ assertTrue(mightContain != put);
+ }
+ }
+ }
+
+ public void testJavaSerialization() {
BloomFilter<byte[]> bf = BloomFilter.create(Funnels.byteArrayFunnel(), 100);
for (int i = 0; i < 10; i++) {
bf.put(Ints.toByteArray(i));
}
-
- bf = SerializableTester.reserialize(bf);
+
+ BloomFilter<byte[]> copy = SerializableTester.reserialize(bf);
for (int i = 0; i < 10; i++) {
- assertTrue(bf.mightContain(Ints.toByteArray(i)));
+ assertTrue(copy.mightContain(Ints.toByteArray(i)));
}
+ assertEquals(bf.expectedFpp(), copy.expectedFpp());
+
+ SerializableTester.reserializeAndAssert(bf);
+ }
+
+ /**
+ * This test will fail whenever someone updates/reorders the BloomFilterStrategies constants.
+ * Only appending a new constant is allowed.
+ */
+ public void testBloomFilterStrategies() {
+ assertEquals(1, BloomFilterStrategies.values().length);
+ assertEquals(BloomFilterStrategies.MURMUR128_MITZ_32, BloomFilterStrategies.values()[0]);
}
}
diff --git a/guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java b/guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java
new file mode 100644
index 0000000..5b29c46
--- /dev/null
+++ b/guava-tests/test/com/google/common/hash/ChecksumHashFunctionTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.hash;
+
+import static com.google.common.hash.Hashing.ChecksumType.ADLER_32;
+import static com.google.common.hash.Hashing.ChecksumType.CRC_32;
+
+import com.google.common.base.Supplier;
+
+import junit.framework.TestCase;
+
+import java.util.zip.Checksum;
+
+/**
+ * Tests for ChecksumHashFunction.
+ *
+ * @author Colin Decker
+ */
+public class ChecksumHashFunctionTest extends TestCase {
+
+ public void testCrc32_equalsChecksumValue() throws Exception {
+ assertChecksum(CRC_32, "");
+ assertChecksum(CRC_32, "Z");
+ assertChecksum(CRC_32, "foobar");
+ }
+
+ public void testAdler32_equalsChecksumValue() throws Exception {
+ assertChecksum(ADLER_32, "");
+ assertChecksum(ADLER_32, "Z");
+ assertChecksum(ADLER_32, "foobar");
+ }
+
+ public void testCrc32_knownValues() throws Exception {
+ assertHash32(0x1C8600E3, CRC_32, "hell");
+ assertHash32(0x3610A686, CRC_32, "hello");
+ assertHash32(0xED81F9F6, CRC_32, "hello ");
+ assertHash32(0x4850DDC2, CRC_32, "hello w");
+ assertHash32(0x7A2D6005, CRC_32, "hello wo");
+ assertHash32(0x1C192672, CRC_32, "hello wor");
+ assertHash32(0x414FA339, CRC_32, "The quick brown fox jumps over the lazy dog");
+ assertHash32(0x4400B5BC, CRC_32, "The quick brown fox jumps over the lazy cog");
+ }
+
+ public void testAdler32_knownValues() throws Exception {
+ assertHash32(0x041701A6, ADLER_32, "hell");
+ assertHash32(0x062C0215, ADLER_32, "hello");
+ assertHash32(0x08610235, ADLER_32, "hello ");
+ assertHash32(0x0B0D02AC, ADLER_32, "hello w");
+ assertHash32(0x0E28031B, ADLER_32, "hello wo");
+ assertHash32(0x11B5038D, ADLER_32, "hello wor");
+ assertHash32(0x5BDC0FDA, ADLER_32, "The quick brown fox jumps over the lazy dog");
+ assertHash32(0x5BD90FD9, ADLER_32, "The quick brown fox jumps over the lazy cog");
+ }
+
+ private static void assertChecksum(Supplier<Checksum> supplier, String input) {
+ byte[] bytes = HashTestUtils.ascii(input);
+
+ Checksum checksum = supplier.get();
+ checksum.update(bytes, 0, bytes.length);
+ long value = checksum.getValue();
+
+ String toString = "name";
+ HashFunction func = new ChecksumHashFunction(supplier, 32, toString);
+ assertEquals(toString, func.toString());
+ assertEquals(value, func.hashBytes(bytes).padToLong());
+ }
+
+ private static void assertHash32(int expected, Supplier<Checksum> supplier, String input) {
+ byte[] bytes = HashTestUtils.ascii(input);
+ String toString = "name";
+ HashFunction func = new ChecksumHashFunction(supplier, 32, toString);
+ assertEquals(expected, func.hashBytes(bytes).asInt());
+ assertEquals(toString, func.toString());
+ }
+}
diff --git a/guava-tests/test/com/google/common/hash/FunnelsTest.java b/guava-tests/test/com/google/common/hash/FunnelsTest.java
index 698549a..368f7b5 100644
--- a/guava-tests/test/com/google/common/hash/FunnelsTest.java
+++ b/guava-tests/test/com/google/common/hash/FunnelsTest.java
@@ -1,31 +1,41 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.google.common.hash;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
import com.google.common.hash.AbstractStreamingHashFunction.AbstractStreamingHasher;
import junit.framework.TestCase;
-import org.easymock.EasyMock;
-
+import java.io.OutputStream;
import java.nio.ByteBuffer;
/**
* Tests for HashExtractors.
- *
- * @author andreou@google.com (Dimitris Andreou)
+ *
+ * @author Dimitris Andreou
*/
public class FunnelsTest extends TestCase {
public void testForBytes() {
- Sink byteSink = EasyMock.createMock(Sink.class);
-
- EasyMock.expect(byteSink.putBytes(EasyMock.aryEq(new byte[] { 4, 3, 2, 1})))
- .andReturn(byteSink).once();
- EasyMock.replay(byteSink);
-
- Funnels.byteArrayFunnel().funnel(new byte[]{4, 3, 2, 1}, byteSink);
-
- EasyMock.verify(byteSink);
+ PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class);
+ Funnels.byteArrayFunnel().funnel(new byte[] { 4, 3, 2, 1 }, bytePrimitiveSink);
+ verify(bytePrimitiveSink).putBytes(new byte[] { 4, 3, 2, 1 });
}
public void testForBytes_null() {
@@ -33,23 +43,39 @@ public class FunnelsTest extends TestCase {
}
public void testForStrings() {
-
- Sink byteSink = EasyMock.createMock(Sink.class);
-
- EasyMock.expect(byteSink.putString("test")).andReturn(byteSink).once();
- EasyMock.replay(byteSink);
-
- Funnels.stringFunnel().funnel("test", byteSink);
-
- EasyMock.verify(byteSink);
+ PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class);
+ Funnels.stringFunnel().funnel("test", bytePrimitiveSink);
+ verify(bytePrimitiveSink).putString("test");
}
-
+
public void testForStrings_null() {
assertNullsThrowException(Funnels.stringFunnel());
}
-
+
+ public void testForInts() {
+ Integer value = 1234;
+ PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class);
+ Funnels.integerFunnel().funnel(value, bytePrimitiveSink);
+ verify(bytePrimitiveSink).putInt(1234);
+ }
+
+ public void testForInts_null() {
+ assertNullsThrowException(Funnels.integerFunnel());
+ }
+
+ public void testForLongs() {
+ Long value = 1234L;
+ PrimitiveSink bytePrimitiveSink = mock(PrimitiveSink.class);
+ Funnels.longFunnel().funnel(value, bytePrimitiveSink);
+ verify(bytePrimitiveSink).putLong(1234);
+ }
+
+ public void testForLongs_null() {
+ assertNullsThrowException(Funnels.longFunnel());
+ }
+
private static void assertNullsThrowException(Funnel<?> funnel) {
- Sink byteSink = new AbstractStreamingHasher(4, 4) {
+ PrimitiveSink bytePrimitiveSink = new AbstractStreamingHasher(4, 4) {
@Override HashCode makeHash() { throw new UnsupportedOperationException(); }
@Override protected void process(ByteBuffer bb) {
@@ -59,8 +85,20 @@ public class FunnelsTest extends TestCase {
}
};
try {
- funnel.funnel(null, byteSink);
+ funnel.funnel(null, bytePrimitiveSink);
fail();
} catch (NullPointerException ok) {}
}
+
+ public void testAsOutputStream() throws Exception {
+ PrimitiveSink sink = mock(PrimitiveSink.class);
+ OutputStream out = Funnels.asOutputStream(sink);
+ byte[] bytes = { 1, 2, 3, 4 };
+ out.write(255);
+ out.write(bytes);
+ out.write(bytes, 1, 2);
+ verify(sink).putByte((byte) 255);
+ verify(sink).putBytes(bytes);
+ verify(sink).putBytes(bytes, 1, 2);
+ }
}
diff --git a/guava-tests/test/com/google/common/hash/HashCodesTest.java b/guava-tests/test/com/google/common/hash/HashCodesTest.java
index 2b483ac..70fb7ec 100644
--- a/guava-tests/test/com/google/common/hash/HashCodesTest.java
+++ b/guava-tests/test/com/google/common/hash/HashCodesTest.java
@@ -1,8 +1,23 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.google.common.hash;
import com.google.common.collect.ImmutableList;
+import com.google.common.testing.ClassSanityTester;
import junit.framework.TestCase;
@@ -10,67 +25,124 @@ import java.util.Arrays;
/**
* Tests for HashCodes, especially making sure that their endianness promises (big-endian)
- * are upheld.
- *
- * @author andreou@google.com (Dimitris Andreou)
+ * are upheld.
+ *
+ * @author Dimitris Andreou
*/
public class HashCodesTest extends TestCase {
// note: asInt(), asLong() are in little endian
private static final ImmutableList<ExpectedHashCode> expectedHashCodes = ImmutableList.of(
- new ExpectedHashCode(new byte[] {
+ new ExpectedHashCode(new byte[] {
(byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x89,
(byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01},
0x89abcdef, 0x0123456789abcdefL, "efcdab8967452301"),
-
- new ExpectedHashCode(new byte[] {
+
+ new ExpectedHashCode(new byte[] {
(byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x89,
(byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01, // up to here, same bytes as above
(byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x04,
(byte) 0x05, (byte) 0x06, (byte) 0x07, (byte) 0x08},
0x89abcdef, 0x0123456789abcdefL, // asInt/asLong as above, due to equal eight first bytes
- "efcdab89674523010102030405060708"),
-
+ "efcdab89674523010102030405060708"),
+
new ExpectedHashCode(new byte[] { (byte) 0xdf, (byte) 0x9b, (byte) 0x57, (byte) 0x13 },
0x13579bdf, null, "df9b5713"),
-
- new ExpectedHashCode(new byte[] {
+
+ new ExpectedHashCode(new byte[] {
(byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00},
0x0000abcd, null, "cdab0000"),
-
- new ExpectedHashCode(new byte[] {
+
+ new ExpectedHashCode(new byte[] {
(byte) 0xef, (byte) 0xcd, (byte) 0xab, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00},
0x00abcdef, 0x0000000000abcdefL, "efcdab0000000000")
);
-
+
// expectedHashCodes must contain at least one hash code with 4 bytes
public void testFromInt() {
for (ExpectedHashCode expected : expectedHashCodes) {
- if (expected.bytes.length == 4) {
+ if (expected.bytes.length == 4) {
HashCode fromInt = HashCodes.fromInt(expected.asInt);
assertExpectedHashCode(expected, fromInt);
}
}
}
-
+
// expectedHashCodes must contain at least one hash code with 8 bytes
public void testFromLong() {
for (ExpectedHashCode expected : expectedHashCodes) {
- if (expected.bytes.length == 8) {
+ if (expected.bytes.length == 8) {
HashCode fromLong = HashCodes.fromLong(expected.asLong);
assertExpectedHashCode(expected, fromLong);
}
}
}
-
+
public void testFromBytes() {
for (ExpectedHashCode expected : expectedHashCodes) {
HashCode fromBytes = HashCodes.fromBytes(expected.bytes);
assertExpectedHashCode(expected, fromBytes);
}
}
-
- private void assertExpectedHashCode(ExpectedHashCode expected, HashCode hash) {
+
+ public void testFromBytes_copyOccurs() {
+ byte[] bytes = new byte[] { (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00 };
+ HashCode hashCode = HashCodes.fromBytes(bytes);
+ int expectedInt = 0x0000abcd;
+ String expectedToString = "cdab0000";
+
+ assertEquals(expectedInt, hashCode.asInt());
+ assertEquals(expectedToString, hashCode.toString());
+
+ bytes[0] = (byte) 0x00;
+
+ assertEquals(expectedInt, hashCode.asInt());
+ assertEquals(expectedToString, hashCode.toString());
+ }
+
+ public void testFromBytesNoCopy_noCopyOccurs() {
+ byte[] bytes = new byte[] { (byte) 0xcd, (byte) 0xab, (byte) 0x00, (byte) 0x00 };
+ HashCode hashCode = HashCodes.fromBytesNoCopy(bytes);
+
+ assertEquals(0x0000abcd, hashCode.asInt());
+ assertEquals("cdab0000", hashCode.toString());
+
+ bytes[0] = (byte) 0x00;
+
+ assertEquals(0x0000ab00, hashCode.asInt());
+ assertEquals("00ab0000", hashCode.toString());
+ }
+
+ public void testPadToLong() {
+ assertEquals(0x1111111111111111L, HashCodes.fromLong(0x1111111111111111L).padToLong());
+ assertEquals(0x9999999999999999L, HashCodes.fromLong(0x9999999999999999L).padToLong());
+ assertEquals(0x0000000011111111L, HashCodes.fromInt(0x11111111).padToLong());
+ assertEquals(0x0000000099999999L, HashCodes.fromInt(0x99999999).padToLong());
+
+ byte[] longBytes = {(byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99,
+ (byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99};
+ byte[] intBytes = {(byte) 0x99, (byte) 0x99, (byte) 0x99, (byte) 0x99};
+ assertEquals(0x9999999999999999L, HashCodes.fromBytesNoCopy(longBytes).padToLong());
+ assertEquals(0x0000000099999999L, HashCodes.fromBytesNoCopy(intBytes).padToLong());
+ }
+
+ public void testHashCodes_nulls() throws Exception {
+ sanityTester().testNulls();
+ }
+
+ public void testHashCodes_equalsAndSerializable() throws Exception {
+ sanityTester().testEqualsAndSerializable();
+ }
+
+ private static ClassSanityTester.FactoryMethodReturnValueTester sanityTester() {
+ return new ClassSanityTester()
+ .setDefault(byte[].class, new byte[] {1, 2, 3, 4})
+ .setSampleInstances(byte[].class,
+ ImmutableList.of(new byte[] {1, 2, 3, 4}, new byte[] {5, 6, 7, 8}))
+ .forAllPublicStaticMethods(HashCodes.class);
+ }
+
+ private static void assertExpectedHashCode(ExpectedHashCode expected, HashCode hash) {
assertTrue(Arrays.equals(expected.bytes, hash.asBytes()));
byte[] bb = new byte[hash.bits() / 8];
hash.writeBytesTo(bb, 0, bb.length);
@@ -88,27 +160,27 @@ public class HashCodesTest extends TestCase {
assertSideEffectFree(hash);
assertReadableBytes(hash);
}
-
- private void assertSideEffectFree(HashCode hash) {
+
+ private static void assertSideEffectFree(HashCode hash) {
byte[] original = hash.asBytes();
byte[] mutated = hash.asBytes();
mutated[0]++;
assertTrue(Arrays.equals(original, hash.asBytes()));
}
-
- private void assertReadableBytes(HashCode hashCode) {
+
+ private static void assertReadableBytes(HashCode hashCode) {
assertTrue(hashCode.bits() >= 32); // sanity
byte[] hashBytes = hashCode.asBytes();
int totalBytes = hashCode.bits() / 8;
-
+
for (int bytes = 0; bytes < totalBytes; bytes++) {
byte[] bb = new byte[bytes];
hashCode.writeBytesTo(bb, 0, bb.length);
-
+
assertTrue(Arrays.equals(Arrays.copyOf(hashBytes, bytes), bb));
}
}
-
+
private static class ExpectedHashCode {
final byte[] bytes;
final int asInt;
diff --git a/guava-tests/test/com/google/common/hash/HashFunctionsTest.java b/guava-tests/test/com/google/common/hash/HashFunctionsTest.java
deleted file mode 100644
index f9fd6c4..0000000
--- a/guava-tests/test/com/google/common/hash/HashFunctionsTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-
-package com.google.common.hash;
-
-import com.google.common.collect.Sets;
-
-import junit.framework.TestCase;
-
-import java.util.Set;
-
-/**
- * Tests for HashFunctions.
- *
- * @author andreou@google.com (Dimitris Andreou)
- */
-public class HashFunctionsTest extends TestCase {
- public void testMd5() {
- assertInvariants(Hashing.md5());
- }
-
- public void testMurmur3_138() {
- assertInvariants(Hashing.murmur3_128());
- }
-
- public void testMurmur3_32() {
- assertInvariants(Hashing.murmur3_32());
- }
-
- public void testGoodFastHash() {
- for (int i = 1; i < 500; i++) {
- HashFunction hasher = Hashing.goodFastHash(i);
- assertTrue(hasher.bits() >= i);
- assertInvariants(hasher);
- }
- }
-
- /**
- * Checks that a Hasher returns the same HashCode when given the same input, and also
- * that the collision rate looks sane.
- */
- private static void assertInvariants(HashFunction hashFunction) {
- int objects = 100;
- Set<HashCode> hashcodes = Sets.newHashSetWithExpectedSize(objects);
- for (int i = 0; i < objects; i++) {
- Object o = new Object();
- HashCode hashcode1 = hashFunction.newHasher().putObject(o, HashTestUtils.BAD_FUNNEL).hash();
- HashCode hashcode2 = hashFunction.newHasher().putObject(o, HashTestUtils.BAD_FUNNEL).hash();
- assertEquals(hashcode1, hashcode2); // idempotent
- assertEquals(hashFunction.bits(), hashcode1.bits());
- assertEquals(hashFunction.bits(), hashcode1.asBytes().length * 8);
- hashcodes.add(hashcode1);
- }
- assertTrue(hashcodes.size() > objects * 0.95); // quite relaxed test
-
- assertHashBytesThrowsCorrectExceptions(hashFunction);
- }
-
- private static void assertHashBytesThrowsCorrectExceptions(HashFunction hashFunction) {
- hashFunction.hashBytes(new byte[64], 0, 0);
-
- try {
- hashFunction.hashBytes(new byte[128], -1, 128);
- fail();
- } catch (IndexOutOfBoundsException ok) {}
- try {
- hashFunction.hashBytes(new byte[128], 64, 256 /* too long len */);
- fail();
- } catch (IndexOutOfBoundsException ok) {}
- try {
- hashFunction.hashBytes(new byte[64], 0, -1);
- fail();
- } catch (IndexOutOfBoundsException ok) {}
- }
-}
diff --git a/guava-tests/test/com/google/common/hash/HashTestUtils.java b/guava-tests/test/com/google/common/hash/HashTestUtils.java
index a857a79..8a894f7 100644
--- a/guava-tests/test/com/google/common/hash/HashTestUtils.java
+++ b/guava-tests/test/com/google/common/hash/HashTestUtils.java
@@ -1,20 +1,44 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.google.common.hash;
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
import com.google.common.primitives.Ints;
+import com.google.common.testing.EqualsTester;
import org.junit.Assert;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
+import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Random;
+import java.util.Set;
/**
- * @author andreou@google.com (Dimitris Andreou)
+ * Various utilities for testing {@link HashFunction}s.
+ *
+ * @author Dimitris Andreou
+ * @author Kurt Alfred Kluever
*/
-class HashTestUtils {
+final class HashTestUtils {
private HashTestUtils() {}
/**
@@ -28,17 +52,6 @@ class HashTestUtils {
return bytes;
}
- /**
- * Returns a byte array representation for a sequence of longs, in big-endian order.
- */
- static byte[] toBytes(ByteOrder bo, long... longs) {
- ByteBuffer bb = ByteBuffer.wrap(new byte[longs.length * 8]).order(bo);
- for (long x : longs) {
- bb.putLong(x);
- }
- return bb.array();
- }
-
interface HashFn {
byte[] hash(byte[] input, int seed);
}
@@ -56,123 +69,510 @@ class HashTestUtils {
byte[] hash = hashFunction.hash(Arrays.copyOf(key, i), seed);
System.arraycopy(hash, 0, hashes, i * hashBytes, hash.length);
}
-
+
// Then hash the result array
byte[] result = hashFunction.hash(hashes, 0);
-
+
// interpreted in little-endian order.
- int verification = Integer.reverseBytes(Ints.fromByteArray(result));
+ int verification = Integer.reverseBytes(Ints.fromByteArray(result));
if (expected != verification) {
throw new AssertionError("Expected: " + Integer.toHexString(expected)
+ " got: " + Integer.toHexString(verification));
}
}
-
- static void assertEqualHashes(byte[] expectedHash, byte[] actualHash) {
- if (!Arrays.equals(expectedHash, actualHash)) {
- Assert.fail(String.format("Should be: %x, was %x", expectedHash, actualHash));
- }
- }
-
+
static final Funnel<Object> BAD_FUNNEL = new Funnel<Object>() {
- @Override public void funnel(Object object, Sink byteSink) {
- byteSink.putInt(object.hashCode());
+ @Override public void funnel(Object object, PrimitiveSink bytePrimitiveSink) {
+ bytePrimitiveSink.putInt(object.hashCode());
}
};
-
+
static enum RandomHasherAction {
PUT_BOOLEAN() {
- @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
boolean value = random.nextBoolean();
- for (Sink sink : sinks) {
+ for (PrimitiveSink sink : sinks) {
sink.putBoolean(value);
}
}
},
PUT_BYTE() {
- @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
int value = random.nextInt();
- for (Sink sink : sinks) {
+ for (PrimitiveSink sink : sinks) {
sink.putByte((byte) value);
}
}
},
PUT_SHORT() {
- @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
short value = (short) random.nextInt();
- for (Sink sink : sinks) {
+ for (PrimitiveSink sink : sinks) {
sink.putShort(value);
}
}
},
PUT_CHAR() {
- @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
char value = (char) random.nextInt();
- for (Sink sink : sinks) {
+ for (PrimitiveSink sink : sinks) {
sink.putChar(value);
}
}
},
PUT_INT() {
- @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
int value = random.nextInt();
- for (Sink sink : sinks) {
+ for (PrimitiveSink sink : sinks) {
sink.putInt(value);
}
}
},
PUT_LONG() {
- @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
long value = random.nextLong();
- for (Sink sink : sinks) {
+ for (PrimitiveSink sink : sinks) {
sink.putLong(value);
}
}
},
PUT_FLOAT() {
- @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
float value = random.nextFloat();
- for (Sink sink : sinks) {
+ for (PrimitiveSink sink : sinks) {
sink.putFloat(value);
}
}
},
PUT_DOUBLE() {
- @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
double value = random.nextDouble();
- for (Sink sink : sinks) {
+ for (PrimitiveSink sink : sinks) {
sink.putDouble(value);
}
}
},
PUT_BYTES() {
- @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
byte[] value = new byte[random.nextInt(128)];
random.nextBytes(value);
- for (Sink sink : sinks) {
+ for (PrimitiveSink sink : sinks) {
sink.putBytes(value);
}
}
},
PUT_BYTES_INT_INT() {
- @Override void performAction(Random random, Iterable<? extends Sink> sinks) {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
byte[] value = new byte[random.nextInt(128)];
random.nextBytes(value);
int off = random.nextInt(value.length + 1);
int len = random.nextInt(value.length - off + 1);
- for (Sink sink : sinks) {
+ for (PrimitiveSink sink : sinks) {
sink.putBytes(value);
}
}
+ },
+ PUT_STRING() {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ char[] value = new char[random.nextInt(128)];
+ for (int i = 0; i < value.length; i++) {
+ value[i] = (char) random.nextInt();
+ }
+ String s = new String(value);
+ for (PrimitiveSink sink : sinks) {
+ sink.putString(s);
+ }
+ }
+ },
+ PUT_STRING_LOW_SURROGATE() {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ String s = new String(new char[] { randomLowSurrogate(random) });
+ for (PrimitiveSink sink : sinks) {
+ sink.putString(s);
+ }
+ }
+ },
+ PUT_STRING_HIGH_SURROGATE() {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ String s = new String(new char[] { randomHighSurrogate(random) });
+ for (PrimitiveSink sink : sinks) {
+ sink.putString(s);
+ }
+ }
+ },
+ PUT_STRING_LOW_HIGH_SURROGATE() {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ String s = new String(new char[] {
+ randomLowSurrogate(random), randomHighSurrogate(random)});
+ for (PrimitiveSink sink : sinks) {
+ sink.putString(s);
+ }
+ }
+ },
+ PUT_STRING_HIGH_LOW_SURROGATE() {
+ @Override void performAction(Random random, Iterable<? extends PrimitiveSink> sinks) {
+ String s = new String(new char[] {
+ randomHighSurrogate(random), randomLowSurrogate(random)});
+ for (PrimitiveSink sink : sinks) {
+ sink.putString(s);
+ }
+ }
};
-
- abstract void performAction(Random random, Iterable<? extends Sink> sinks);
-
+
+ abstract void performAction(Random random, Iterable<? extends PrimitiveSink> sinks);
+
private static final RandomHasherAction[] actions = values();
-
+
static RandomHasherAction pickAtRandom(Random random) {
return actions[random.nextInt(actions.length)];
}
}
+
+ /**
+ * Test that the hash function contains no funnels. A funnel is a situation where a set of input
+ * (key) bits 'affects' a strictly smaller set of output bits. Funneling is bad because it can
+ * result in more-than-ideal collisions for a non-uniformly distributed key space. In practice,
+ * most key spaces are ANYTHING BUT uniformly distributed. A bit(i) in the input is said to
+ * 'affect' a bit(j) in the output if two inputs, identical but for bit(i), will differ at output
+ * bit(j) about half the time
+ *
+ * <p>Funneling is pretty simple to detect. The key idea is to find example keys which
+ * unequivocably demonstrate that funneling cannot be occuring. This is done bit-by-bit. For
+ * each input bit(i) and output bit(j), two pairs of keys must be found with all bits identical
+ * except bit(i). One pair must differ in output bit(j), and one pair must not. This proves that
+ * input bit(i) can alter output bit(j).
+ */
+ static void checkNoFunnels(HashFunction function) {
+ Random rand = new Random(0);
+ int keyBits = 32;
+ int hashBits = function.bits();
+
+ // output loop tests input bit
+ for (int i = 0; i < keyBits; i++) {
+ int same = 0x0; // bitset for output bits with same values
+ int diff = 0x0; // bitset for output bits with different values
+ int count = 0;
+ // originally was 2 * Math.log(...), making it try more times to avoid flakiness issues
+ int maxCount = (int) (4 * Math.log(2 * keyBits * hashBits) + 1);
+ while (same != 0xffffffff || diff != 0xffffffff) {
+ int key1 = rand.nextInt();
+ // flip input bit for key2
+ int key2 = key1 ^ (1 << i);
+ // get hashes
+ int hash1 = function.newHasher().putInt(key1).hash().asInt();
+ int hash2 = function.newHasher().putInt(key2).hash().asInt();
+ // test whether the hash values have same output bits
+ same |= ~(hash1 ^ hash2);
+ // test whether the hash values have different output bits
+ diff |= (hash1 ^ hash2);
+
+ count++;
+ // check whether we've exceeded the probabilistically
+ // likely number of trials to have proven no funneling
+ if (count > maxCount) {
+ Assert.fail("input bit(" + i + ") was found not to affect all " +
+ hashBits + " output bits; The unaffected bits are " +
+ "as follows: " + ~(same & diff) + ". This was " +
+ "determined after " + count + " trials.");
+ }
+ }
+ }
+ }
+
+ /**
+ * Test for avalanche. Avalanche means that output bits differ with roughly 1/2 probability on
+ * different input keys. This test verifies that each possible 1-bit key delta achieves avalanche.
+ *
+ * <p>For more information: http://burtleburtle.net/bob/hash/avalanche.html
+ */
+ static void checkAvalanche(HashFunction function, int trials, double epsilon) {
+ Random rand = new Random(0);
+ int keyBits = 32;
+ int hashBits = function.bits();
+ for (int i = 0; i < keyBits; i++) {
+ int[] same = new int[hashBits];
+ int[] diff = new int[hashBits];
+ // go through trials to compute probability
+ for (int j = 0; j < trials; j++) {
+ int key1 = rand.nextInt();
+ // flip input bit for key2
+ int key2 = key1 ^ (1 << i);
+ // compute hash values
+ int hash1 = function.newHasher().putInt(key1).hash().asInt();
+ int hash2 = function.newHasher().putInt(key2).hash().asInt();
+ for (int k = 0; k < hashBits; k++) {
+ if ((hash1 & (1 << k)) == (hash2 & (1 << k))) {
+ same[k] += 1;
+ } else {
+ diff[k] += 1;
+ }
+ }
+ }
+ // measure probability and assert it's within margin of error
+ for (int j = 0; j < hashBits; j++) {
+ double prob = (double) diff[j] / (double) (diff[j] + same[j]);
+ Assert.assertEquals(0.50d, prob, epsilon);
+ }
+ }
+ }
+
+ /**
+ * Test for 2-bit characteristics. A characteristic is a delta in the input which is repeated in
+ * the output. For example, if f() is a block cipher and c is a characteristic, then
+ * f(x^c) = f(x)^c with greater than expected probability. The test for funneling is merely a test
+ * for 1-bit characteristics.
+ *
+ * <p>There is more general code provided by Bob Jenkins to test arbitrarily sized characteristics
+ * using the magic of gaussian elimination: http://burtleburtle.net/bob/crypto/findingc.html.
+ */
+ static void checkNo2BitCharacteristics(HashFunction function) {
+ Random rand = new Random(0);
+ int keyBits = 32;
+
+ // get every one of (keyBits choose 2) deltas:
+ for (int i = 0; i < keyBits; i++) {
+ for (int j = 0; j < keyBits; j++) {
+ if (j <= i) continue;
+ int count = 0;
+ int maxCount = 20; // the probability of error here is miniscule
+ boolean diff = false;
+
+ while (diff == false) {
+ int delta = (1 << i) | (1 << j);
+ int key1 = rand.nextInt();
+ // apply delta
+ int key2 = key1 ^ delta;
+
+ // get hashes
+ int hash1 = function.newHasher().putInt(key1).hash().asInt();
+ int hash2 = function.newHasher().putInt(key2).hash().asInt();
+
+ // this 2-bit candidate delta is not a characteristic
+ // if deltas are different
+ if ((hash1 ^ hash2) != delta) {
+ diff = true;
+ continue;
+ }
+
+ // check if we've exceeded the probabilistically
+ // likely number of trials to have proven 2-bit candidate
+ // is not a characteristic
+ count++;
+ if (count > maxCount) {
+ Assert.fail("2-bit delta (" + i + ", " + j + ") is likely a " +
+ "characteristic for this hash. This was " +
+ "determined after " + count + " trials");
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Test for avalanche with 2-bit deltas. Most probabilities of output bit(j) differing are well
+ * within 50%.
+ */
+ static void check2BitAvalanche(HashFunction function, int trials, double epsilon) {
+ Random rand = new Random(0);
+ int keyBits = 32;
+ int hashBits = function.bits();
+ for (int bit1 = 0; bit1 < keyBits; bit1++) {
+ for (int bit2 = 0; bit2 < keyBits; bit2++) {
+ if (bit2 <= bit1) continue;
+ int delta = (1 << bit1) | (1 << bit2);
+ int[] same = new int[hashBits];
+ int[] diff = new int[hashBits];
+ // go through trials to compute probability
+ for (int j = 0; j < trials; j++) {
+ int key1 = rand.nextInt();
+ // flip input bit for key2
+ int key2 = key1 ^ delta;
+ // compute hash values
+ int hash1 = function.newHasher().putInt(key1).hash().asInt();
+ int hash2 = function.newHasher().putInt(key2).hash().asInt();
+ for (int k = 0; k < hashBits; k++) {
+ if ((hash1 & (1 << k)) == (hash2 & (1 << k))) {
+ same[k] += 1;
+ } else {
+ diff[k] += 1;
+ }
+ }
+ }
+ // measure probability and assert it's within margin of error
+ for (int j = 0; j < hashBits; j++) {
+ double prob = (double) diff[j] / (double) (diff[j] + same[j]);
+ Assert.assertEquals(0.50d, prob, epsilon);
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks that a Hasher returns the same HashCode when given the same input, and also
+ * that the collision rate looks sane.
+ */
+ static void assertInvariants(HashFunction hashFunction) {
+ int objects = 100;
+ Set<HashCode> hashcodes = Sets.newHashSetWithExpectedSize(objects);
+ for (int i = 0; i < objects; i++) {
+ Object o = new Object();
+ HashCode hashcode1 = hashFunction.hashObject(o, HashTestUtils.BAD_FUNNEL);
+ HashCode hashcode2 = hashFunction.hashObject(o, HashTestUtils.BAD_FUNNEL);
+ Assert.assertEquals(hashcode1, hashcode2); // idempotent
+ Assert.assertEquals(hashFunction.bits(), hashcode1.bits());
+ Assert.assertEquals(hashFunction.bits(), hashcode1.asBytes().length * 8);
+ hashcodes.add(hashcode1);
+ }
+ Assert.assertTrue(hashcodes.size() > objects * 0.95); // quite relaxed test
+
+ assertHashBytesThrowsCorrectExceptions(hashFunction);
+ assertIndependentHashers(hashFunction);
+ assertShortcutsAreEquivalent(hashFunction, 512);
+ }
+
+ static void assertHashBytesThrowsCorrectExceptions(HashFunction hashFunction) {
+ hashFunction.hashBytes(new byte[64], 0, 0);
+
+ try {
+ hashFunction.hashBytes(new byte[128], -1, 128);
+ Assert.fail();
+ } catch (IndexOutOfBoundsException expected) {}
+ try {
+ hashFunction.hashBytes(new byte[128], 64, 256 /* too long len */);
+ Assert.fail();
+ } catch (IndexOutOfBoundsException expected) {}
+ try {
+ hashFunction.hashBytes(new byte[64], 0, -1);
+ Assert.fail();
+ } catch (IndexOutOfBoundsException expected) {}
+ }
+
+ static void assertIndependentHashers(HashFunction hashFunction) {
+ int numActions = 100;
+ // hashcodes from non-overlapping hash computations
+ HashCode expected1 = randomHash(hashFunction, new Random(1L), numActions);
+ HashCode expected2 = randomHash(hashFunction, new Random(2L), numActions);
+
+ // equivalent, but overlapping, computations (should produce the same results as above)
+ Random random1 = new Random(1L);
+ Random random2 = new Random(2L);
+ Hasher hasher1 = hashFunction.newHasher();
+ Hasher hasher2 = hashFunction.newHasher();
+ for (int i = 0; i < numActions; i++) {
+ RandomHasherAction.pickAtRandom(random1).performAction(random1, ImmutableSet.of(hasher1));
+ RandomHasherAction.pickAtRandom(random2).performAction(random2, ImmutableSet.of(hasher2));
+ }
+
+ Assert.assertEquals(expected1, hasher1.hash());
+ Assert.assertEquals(expected2, hasher2.hash());
+ }
+
+ static HashCode randomHash(HashFunction hashFunction, Random random, int numActions) {
+ Hasher hasher = hashFunction.newHasher();
+ for (int i = 0; i < numActions; i++) {
+ RandomHasherAction.pickAtRandom(random).performAction(random, ImmutableSet.of(hasher));
+ }
+ return hasher.hash();
+ }
+
+ private static void assertShortcutsAreEquivalent(HashFunction hashFunction, int trials) {
+ Random random = new Random(42085L);
+ for (int i = 0; i < trials; i++) {
+ assertHashBytesEquivalence(hashFunction, random);
+ assertHashIntEquivalence(hashFunction, random);
+ assertHashLongEquivalence(hashFunction, random);
+ assertHashStringEquivalence(hashFunction, random);
+ assertHashStringWithSurrogatesEquivalence(hashFunction, random);
+ }
+ }
+
+ private static void assertHashBytesEquivalence(HashFunction hashFunction, Random random) {
+ int size = random.nextInt(2048);
+ byte[] bytes = new byte[size];
+ random.nextBytes(bytes);
+ assertEquals(hashFunction.hashBytes(bytes),
+ hashFunction.newHasher(size).putBytes(bytes).hash());
+ int off = random.nextInt(size);
+ int len = random.nextInt(size - off);
+ assertEquals(hashFunction.hashBytes(bytes, off, len),
+ hashFunction.newHasher(size).putBytes(bytes, off, len).hash());
+ }
+
+ private static void assertHashIntEquivalence(HashFunction hashFunction, Random random) {
+ int i = random.nextInt();
+ assertEquals(hashFunction.hashInt(i),
+ hashFunction.newHasher().putInt(i).hash());
+ }
+
+ private static void assertHashLongEquivalence(HashFunction hashFunction, Random random) {
+ long l = random.nextLong();
+ assertEquals(hashFunction.hashLong(l),
+ hashFunction.newHasher().putLong(l).hash());
+ }
+
+ private static final ImmutableList<Charset> CHARSETS = ImmutableList.of(
+ Charsets.ISO_8859_1,
+ Charsets.US_ASCII,
+ Charsets.UTF_16,
+ Charsets.UTF_16BE,
+ Charsets.UTF_16LE,
+ Charsets.UTF_8);
+
+ private static void assertHashStringEquivalence(HashFunction hashFunction, Random random) {
+ // Test that only data and data-order is important, not the individual operations.
+ new EqualsTester()
+ .addEqualityGroup(
+ hashFunction.newHasher().putString("abc").hash(),
+ hashFunction.newHasher().putString("ab").putString("c").hash(),
+ hashFunction.newHasher().putString("a").putString("bc").hash(),
+ hashFunction.newHasher().putString("a").putString("b").putString("c").hash(),
+ hashFunction.newHasher().putChar('a').putString("bc").hash(),
+ hashFunction.newHasher().putString("ab").putChar('c').hash(),
+ hashFunction.newHasher().putChar('a').putChar('b').putChar('c').hash())
+ .testEquals();
+
+ int size = random.nextInt(2048);
+ byte[] bytes = new byte[size];
+ random.nextBytes(bytes);
+ String string = new String(bytes);
+ assertEquals(hashFunction.hashString(string),
+ hashFunction.newHasher().putString(string).hash());
+ // These assertions causes failures when testing with mvn. See b/6657789
+ // assertEquals(hashFunction.hashString(string),
+ // hashFunction.hashString(string, Charsets.UTF_16LE));
+ // assertEquals(hashFunction.hashString(string),
+ // hashFunction.newHasher().putString(string, Charsets.UTF_16LE).hash());
+ for (Charset charset : CHARSETS) {
+ assertEquals(hashFunction.hashString(string, charset),
+ hashFunction.newHasher().putString(string, charset).hash());
+ }
+ }
+
+ /**
+ * This verifies that putString(String) and hashString(String) are equivalent, even for
+ * funny strings composed by (possibly unmatched, and mostly illegal) surrogate characters.
+ * (But doesn't test that they do the right thing - just their consistency).
+ */
+ private static void assertHashStringWithSurrogatesEquivalence(
+ HashFunction hashFunction, Random random) {
+ int size = random.nextInt(8) + 1;
+ char[] chars = new char[size];
+ for (int i = 0; i < chars.length; i++) {
+ chars[i] = random.nextBoolean() ? randomLowSurrogate(random) : randomHighSurrogate(random);
+ }
+ String string = new String(chars);
+ assertEquals(hashFunction.hashString(string),
+ hashFunction.newHasher().putString(string).hash());
+ }
+
+ static char randomLowSurrogate(Random random) {
+ return (char) (Character.MIN_LOW_SURROGATE
+ + random.nextInt(Character.MAX_LOW_SURROGATE - Character.MIN_LOW_SURROGATE + 1));
+ }
+
+ static char randomHighSurrogate(Random random) {
+ return (char) (Character.MIN_HIGH_SURROGATE
+ + random.nextInt(Character.MAX_HIGH_SURROGATE - Character.MIN_HIGH_SURROGATE + 1));
+ }
}
diff --git a/guava-tests/test/com/google/common/hash/HashingTest.java b/guava-tests/test/com/google/common/hash/HashingTest.java
index 547d5a3..f5488a1 100644
--- a/guava-tests/test/com/google/common/hash/HashingTest.java
+++ b/guava-tests/test/com/google/common/hash/HashingTest.java
@@ -16,20 +16,125 @@
package com.google.common.hash;
+import static com.google.common.hash.Hashing.ConcatenatedHashFunction;
+
+import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Lists;
+import com.google.common.collect.Table.Cell;
+import com.google.common.testing.NullPointerTester;
import com.google.common.util.concurrent.AtomicLongMap;
import junit.framework.TestCase;
+import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;
import java.util.Random;
/**
- * Unit tests for functions of {@code Hashing} that don't have their own tests.
+ * Unit tests for {@link Hashing}.
+ *
+ * @author Dimitris Andreou
+ * @author Kurt Alfred Kluever
*/
public class HashingTest extends TestCase {
+ public void testMd5() {
+ HashTestUtils.checkAvalanche(Hashing.md5(), 100, 0.4);
+ HashTestUtils.checkNo2BitCharacteristics(Hashing.md5());
+ HashTestUtils.checkNoFunnels(Hashing.md5());
+ HashTestUtils.assertInvariants(Hashing.md5());
+ assertEquals("Hashing.md5()", Hashing.md5().toString());
+ }
+
+ public void testSha1() {
+ HashTestUtils.checkAvalanche(Hashing.sha1(), 100, 0.4);
+ HashTestUtils.checkNo2BitCharacteristics(Hashing.sha1());
+ HashTestUtils.checkNoFunnels(Hashing.sha1());
+ HashTestUtils.assertInvariants(Hashing.sha1());
+ assertEquals("Hashing.sha1()", Hashing.sha1().toString());
+ }
+
+ public void testSha256() {
+ HashTestUtils.checkAvalanche(Hashing.sha256(), 100, 0.4);
+ HashTestUtils.checkNo2BitCharacteristics(Hashing.sha256());
+ HashTestUtils.checkNoFunnels(Hashing.sha256());
+ HashTestUtils.assertInvariants(Hashing.sha256());
+ assertEquals("Hashing.sha256()", Hashing.sha256().toString());
+ }
+
+ public void testSha512() {
+ HashTestUtils.checkAvalanche(Hashing.sha512(), 100, 0.4);
+ HashTestUtils.checkNo2BitCharacteristics(Hashing.sha512());
+ HashTestUtils.checkNoFunnels(Hashing.sha512());
+ HashTestUtils.assertInvariants(Hashing.sha512());
+ assertEquals("Hashing.sha512()", Hashing.sha512().toString());
+ }
+
+ public void testCrc32() {
+ HashTestUtils.assertInvariants(Hashing.crc32());
+ assertEquals("Hashing.crc32()", Hashing.crc32().toString());
+ }
+
+ public void testAdler32() {
+ HashTestUtils.assertInvariants(Hashing.adler32());
+ assertEquals("Hashing.adler32()", Hashing.adler32().toString());
+ }
+
+ public void testMurmur3_128() {
+ HashTestUtils.check2BitAvalanche(Hashing.murmur3_128(), 250, 0.20);
+ HashTestUtils.checkAvalanche(Hashing.murmur3_128(), 250, 0.17);
+ HashTestUtils.checkNo2BitCharacteristics(Hashing.murmur3_128());
+ HashTestUtils.checkNoFunnels(Hashing.murmur3_128());
+ HashTestUtils.assertInvariants(Hashing.murmur3_128());
+ assertEquals("Hashing.murmur3_128(0)", Hashing.murmur3_128().toString());
+ }
+
+ public void testMurmur3_32() {
+ HashTestUtils.check2BitAvalanche(Hashing.murmur3_32(), 250, 0.20);
+ HashTestUtils.checkAvalanche(Hashing.murmur3_32(), 250, 0.17);
+ HashTestUtils.checkNo2BitCharacteristics(Hashing.murmur3_32());
+ HashTestUtils.checkNoFunnels(Hashing.murmur3_32());
+ HashTestUtils.assertInvariants(Hashing.murmur3_32());
+ assertEquals("Hashing.murmur3_32(0)", Hashing.murmur3_32().toString());
+ }
+
+ public void testGoodFastHash() {
+ for (int i = 1; i < 200; i += 17) {
+ HashFunction hasher = Hashing.goodFastHash(i);
+ assertTrue(hasher.bits() >= i);
+ HashTestUtils.assertInvariants(hasher);
+ }
+ }
+
+ // goodFastHash(32) uses Murmur3_32. Use the same epsilon bounds.
+ public void testGoodFastHash32() {
+ HashTestUtils.check2BitAvalanche(Hashing.goodFastHash(32), 250, 0.20);
+ HashTestUtils.checkAvalanche(Hashing.goodFastHash(32), 250, 0.17);
+ HashTestUtils.checkNo2BitCharacteristics(Hashing.goodFastHash(32));
+ HashTestUtils.checkNoFunnels(Hashing.goodFastHash(32));
+ HashTestUtils.assertInvariants(Hashing.goodFastHash(32));
+ }
+
+ // goodFastHash(128) uses Murmur3_128. Use the same epsilon bounds.
+ public void testGoodFastHash128() {
+ HashTestUtils.check2BitAvalanche(Hashing.goodFastHash(128), 250, 0.20);
+ HashTestUtils.checkAvalanche(Hashing.goodFastHash(128), 250, 0.17);
+ HashTestUtils.checkNo2BitCharacteristics(Hashing.goodFastHash(128));
+ HashTestUtils.checkNoFunnels(Hashing.goodFastHash(128));
+ HashTestUtils.assertInvariants(Hashing.goodFastHash(128));
+ }
+
+ // goodFastHash(256) uses Murmur3_128. Use the same epsilon bounds.
+ public void testGoodFastHash256() {
+ HashTestUtils.check2BitAvalanche(Hashing.goodFastHash(256), 250, 0.20);
+ HashTestUtils.checkAvalanche(Hashing.goodFastHash(256), 250, 0.17);
+ HashTestUtils.checkNo2BitCharacteristics(Hashing.goodFastHash(256));
+ HashTestUtils.checkNoFunnels(Hashing.goodFastHash(256));
+ HashTestUtils.assertInvariants(Hashing.goodFastHash(256));
+ }
+
public void testPadToLong() {
assertEquals(0x1111111111111111L, Hashing.padToLong(HashCodes.fromLong(0x1111111111111111L)));
assertEquals(0x9999999999999999L, Hashing.padToLong(HashCodes.fromLong(0x9999999999999999L)));
@@ -103,14 +208,24 @@ public class HashingTest extends TestCase {
assertEquals(Hashing.consistentHash(equivLong, 5555), Hashing.consistentHash(hashCode, 5555));
}
- public void testCombineOrdered_null() {
- try {
- Hashing.combineOrdered(null);
- fail();
- } catch (NullPointerException expected) {
- }
+ /**
+ * Tests that the linear congruential generator is actually compatible with the c++
+ * implementation.
+ *
+ * This test was added to help refactoring, it is not a strict requirement, it can be removed if
+ * functionality changes in the future.
+ */
+ public void testConsistentHash_linearCongruentialGeneratorCompatibility() {
+ assertEquals(55, Hashing.consistentHash(1, 100));
+ assertEquals(62, Hashing.consistentHash(2, 100));
+ assertEquals(8, Hashing.consistentHash(3, 100));
+ assertEquals(45, Hashing.consistentHash(4, 100));
+ assertEquals(59, Hashing.consistentHash(5, 100));
}
+ private static final double MAX_PERCENT_SPREAD = 0.5;
+ private static final long RANDOM_SEED = 177L;
+
public void testCombineOrdered_empty() {
try {
Hashing.combineOrdered(Collections.<HashCode>emptySet());
@@ -153,14 +268,6 @@ public class HashingTest extends TestCase {
assertFalse(hashCode1.equals(hashCode2));
}
- public void testCombineUnordered_null() {
- try {
- Hashing.combineUnordered(null);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
public void testCombineUnordered_empty() {
try {
Hashing.combineUnordered(Collections.<HashCode>emptySet());
@@ -201,4 +308,82 @@ public class HashingTest extends TestCase {
assertEquals(hashCode1, hashCode2);
}
+
+ public void testConcatenatedHashFunction_bits() {
+ assertEquals(Hashing.md5().bits(),
+ new ConcatenatedHashFunction(Hashing.md5()).bits());
+ assertEquals(Hashing.md5().bits() + Hashing.murmur3_32().bits(),
+ new ConcatenatedHashFunction(Hashing.md5(), Hashing.murmur3_32()).bits());
+ assertEquals(Hashing.md5().bits() + Hashing.murmur3_32().bits() + Hashing.murmur3_128().bits(),
+ new ConcatenatedHashFunction(
+ Hashing.md5(), Hashing.murmur3_32(), Hashing.murmur3_128()).bits());
+ }
+
+ public void testConcatenatedHashFunction_makeHash() {
+ byte[] md5Hash = Hashing.md5().hashLong(42L).asBytes();
+ byte[] murmur3Hash = Hashing.murmur3_32().hashLong(42L).asBytes();
+ byte[] combined = new byte[md5Hash.length + murmur3Hash.length];
+ ByteBuffer buffer = ByteBuffer.wrap(combined);
+ buffer.put(md5Hash);
+ buffer.put(murmur3Hash);
+
+ assertEquals(HashCodes.fromBytes(combined),
+ new ConcatenatedHashFunction(Hashing.md5(), Hashing.murmur3_32()).hashLong(42L));
+ }
+
+ private static final String EMPTY_STRING = "";
+ private static final String TQBFJOTLD = "The quick brown fox jumps over the lazy dog";
+ private static final String TQBFJOTLDP = "The quick brown fox jumps over the lazy dog.";
+
+ private static final ImmutableTable<HashFunction, String, String> KNOWN_HASHES =
+ ImmutableTable.<HashFunction, String, String>builder()
+ .put(Hashing.adler32(), EMPTY_STRING, "01000000")
+ .put(Hashing.adler32(), TQBFJOTLD, "da0fdc5b")
+ .put(Hashing.adler32(), TQBFJOTLDP, "0810e46b")
+ .put(Hashing.md5(), EMPTY_STRING, "d41d8cd98f00b204e9800998ecf8427e")
+ .put(Hashing.md5(), TQBFJOTLD, "9e107d9d372bb6826bd81d3542a419d6")
+ .put(Hashing.md5(), TQBFJOTLDP, "e4d909c290d0fb1ca068ffaddf22cbd0")
+ .put(Hashing.murmur3_128(), EMPTY_STRING, "00000000000000000000000000000000")
+ .put(Hashing.murmur3_128(), TQBFJOTLD, "6c1b07bc7bbc4be347939ac4a93c437a")
+ .put(Hashing.murmur3_128(), TQBFJOTLDP, "c902e99e1f4899cde7b68789a3a15d69")
+ .put(Hashing.murmur3_32(), EMPTY_STRING, "00000000")
+ .put(Hashing.murmur3_32(), TQBFJOTLD, "23f74f2e")
+ .put(Hashing.murmur3_32(), TQBFJOTLDP, "fc8bc4d5")
+ .put(Hashing.sha1(), EMPTY_STRING, "da39a3ee5e6b4b0d3255bfef95601890afd80709")
+ .put(Hashing.sha1(), TQBFJOTLD, "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12")
+ .put(Hashing.sha1(), TQBFJOTLDP, "408d94384216f890ff7a0c3528e8bed1e0b01621")
+ .put(Hashing.sha256(), EMPTY_STRING,
+ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
+ .put(Hashing.sha256(), TQBFJOTLD,
+ "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592")
+ .put(Hashing.sha256(), TQBFJOTLDP,
+ "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c")
+ .put(Hashing.sha512(), EMPTY_STRING,
+ "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce" +
+ "47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e")
+ .put(Hashing.sha512(), TQBFJOTLD,
+ "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb64" +
+ "2e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6")
+ .put(Hashing.sha512(), TQBFJOTLDP,
+ "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d12890cea77a1bb" +
+ "c6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3c463d481c7e586c39ac1ed")
+ .build();
+
+ public void testKnownUtf8Hashing() {
+ for (Cell<HashFunction, String, String> cell : KNOWN_HASHES.cellSet()) {
+ HashFunction func = cell.getRowKey();
+ String input = cell.getColumnKey();
+ String expected = cell.getValue();
+ assertEquals(
+ String.format("Known hash for hash(%s, UTF_8) failed", input),
+ expected,
+ func.hashString(input, Charsets.UTF_8).toString());
+ }
+ }
+
+ public void testNullPointers() {
+ NullPointerTester tester = new NullPointerTester()
+ .setDefault(HashCode.class, HashCodes.fromInt(0));
+ tester.testAllPublicStaticMethods(Hashing.class);
+ }
}
diff --git a/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java b/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java
index a70466e..2a9547b 100644
--- a/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java
+++ b/guava-tests/test/com/google/common/hash/MessageDigestHashFunctionTest.java
@@ -1,34 +1,73 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.google.common.hash;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
+import com.google.common.collect.ImmutableSet;
import junit.framework.TestCase;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+
/**
* Tests for the MessageDigestHashFunction.
*
- * @author kak@google.com (Kurt Alfred Kluever)
+ * @author Kurt Alfred Kluever
*/
public class MessageDigestHashFunctionTest extends TestCase {
- public void testMd5Hashing() throws Exception {
- assertMessageDigestHashing(HashTestUtils.ascii(""), "MD5");
- assertMessageDigestHashing(HashTestUtils.ascii("Z"), "MD5");
- assertMessageDigestHashing(HashTestUtils.ascii("foobar"), "MD5");
+ private static final ImmutableSet<String> INPUTS = ImmutableSet.of("", "Z", "foobar");
+ private static final ImmutableSet<String> ALGORITHMS = ImmutableSet.of(
+ "MD5", "SHA1", "SHA-1", "SHA-256", "SHA-512");
+
+ public void testHashing() {
+ for (String stringToTest : INPUTS) {
+ for (String algorithmToTest : ALGORITHMS) {
+ assertMessageDigestHashing(HashTestUtils.ascii(stringToTest), algorithmToTest);
+ }
+ }
}
- public void testSha1Hashing() throws Exception {
- assertMessageDigestHashing(HashTestUtils.ascii(""), "SHA1");
- assertMessageDigestHashing(HashTestUtils.ascii("Z"), "SHA1");
- assertMessageDigestHashing(HashTestUtils.ascii("foobar"), "SHA1");
+ public void testToString() {
+ assertEquals("Hashing.md5()", Hashing.md5().toString());
+ assertEquals("Hashing.sha1()", Hashing.sha1().toString());
+ assertEquals("Hashing.sha256()", Hashing.sha256().toString());
+ assertEquals("Hashing.sha512()", Hashing.sha512().toString());
}
- private static void assertMessageDigestHashing(byte[] input, String algorithmName)
- throws NoSuchAlgorithmException {
- HashTestUtils.assertEqualHashes(
- MessageDigest.getInstance(algorithmName).digest(input),
- new MessageDigestHashFunction(algorithmName).hashBytes(input).asBytes());
+ private static void assertMessageDigestHashing(byte[] input, String algorithmName) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance(algorithmName);
+ assertEquals(
+ HashCodes.fromBytes(digest.digest(input)),
+ new MessageDigestHashFunction(algorithmName, algorithmName).hashBytes(input));
+ for (int bytes = 4; bytes <= digest.getDigestLength(); bytes++) {
+ assertEquals(
+ HashCodes.fromBytes(Arrays.copyOf(digest.digest(input), bytes)),
+ new MessageDigestHashFunction(algorithmName, bytes, algorithmName).hashBytes(input));
+ }
+ try {
+ int maxSize = digest.getDigestLength();
+ new MessageDigestHashFunction(algorithmName, maxSize + 1, algorithmName);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ } catch (NoSuchAlgorithmException nsae) {
+ throw new AssertionError(nsae);
+ }
}
}
diff --git a/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java b/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java
index 4a4eea7..ab319fb 100644
--- a/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java
+++ b/guava-tests/test/com/google/common/hash/Murmur3Hash128Test.java
@@ -16,44 +16,55 @@
package com.google.common.hash;
-import static com.google.common.hash.HashTestUtils.ascii;
-import static com.google.common.hash.HashTestUtils.toBytes;
import static com.google.common.hash.Hashing.murmur3_128;
-import static java.nio.ByteOrder.LITTLE_ENDIAN;
+import com.google.common.base.Charsets;
import com.google.common.hash.Funnels;
import com.google.common.hash.HashTestUtils.HashFn;
import junit.framework.TestCase;
-import java.util.Arrays;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
/**
- * Tests for Murmur3Hash128.
+ * Tests for {@link Murmur3_128HashFunction}.
*/
public class Murmur3Hash128Test extends TestCase {
- public void testCompatibilityWithCPlusPlus() {
- assertHash(0, toBytes(LITTLE_ENDIAN, 0x629942693e10f867L, 0x92db0b82baeb5347L),
- ascii("hell"));
- assertHash(1, toBytes(LITTLE_ENDIAN, 0xa78ddff5adae8d10L, 0x128900ef20900135L),
- ascii("hello"));
- assertHash(2, toBytes(LITTLE_ENDIAN, 0x8a486b23f422e826L, 0xf962a2c58947765fL),
- ascii("hello "));
- assertHash(3, toBytes(LITTLE_ENDIAN, 0x2ea59f466f6bed8cL, 0xc610990acc428a17L),
- ascii("hello w"));
- assertHash(4, toBytes(LITTLE_ENDIAN, 0x79f6305a386c572cL, 0x46305aed3483b94eL),
- ascii("hello wo"));
- assertHash(5, toBytes(LITTLE_ENDIAN, 0xc2219d213ec1f1b5L, 0xa1d8e2e0a52785bdL),
- ascii("hello wor"));
- assertHash(0, toBytes(LITTLE_ENDIAN, 0xe34bbc7bbc071b6cL, 0x7a433ca9c49a9347L),
- ascii("The quick brown fox jumps over the lazy dog"));
- assertHash(0, toBytes(LITTLE_ENDIAN, 0x658ca970ff85269aL, 0x43fee3eaa68e5c3eL),
- ascii("The quick brown fox jumps over the lazy cog"));
+ public void testKnownValues() {
+ assertHash(0, 0x629942693e10f867L, 0x92db0b82baeb5347L, "hell");
+ assertHash(1, 0xa78ddff5adae8d10L, 0x128900ef20900135L, "hello");
+ assertHash(2, 0x8a486b23f422e826L, 0xf962a2c58947765fL, "hello ");
+ assertHash(3, 0x2ea59f466f6bed8cL, 0xc610990acc428a17L, "hello w");
+ assertHash(4, 0x79f6305a386c572cL, 0x46305aed3483b94eL, "hello wo");
+ assertHash(5, 0xc2219d213ec1f1b5L, 0xa1d8e2e0a52785bdL, "hello wor");
+ assertHash(0, 0xe34bbc7bbc071b6cL, 0x7a433ca9c49a9347L,
+ "The quick brown fox jumps over the lazy dog");
+ assertHash(0, 0x658ca970ff85269aL, 0x43fee3eaa68e5c3eL,
+ "The quick brown fox jumps over the lazy cog");
+
+ // Known output from Python smhasher
+ HashCode foxHash =
+ murmur3_128(0).hashString("The quick brown fox jumps over the lazy dog", Charsets.UTF_8);
+ assertEquals("6c1b07bc7bbc4be347939ac4a93c437a", foxHash.toString());
+ }
+
+ private static void assertHash(int seed, long expected1, long expected2, String stringInput) {
+ HashCode expected = toHashCode(expected1, expected2);
+ byte[] input = HashTestUtils.ascii(stringInput);
+ assertEquals(expected, murmur3_128(seed).hashBytes(input));
+ assertEquals(expected, murmur3_128(seed).newHasher().putBytes(input).hash());
}
-
- private static void assertHash(int seed, byte[] expectedHash, byte[] input) {
- byte[] hash = murmur3_128(seed).newHasher().putBytes(input).hash().asBytes();
- assertTrue(Arrays.equals(expectedHash, hash));
+
+ /**
+ * Returns a {@link HashCode} for a sequence of longs, in big-endian order.
+ */
+ private static HashCode toHashCode(long... longs) {
+ ByteBuffer bb = ByteBuffer.wrap(new byte[longs.length * 8]).order(ByteOrder.LITTLE_ENDIAN);
+ for (long x : longs) {
+ bb.putLong(x);
+ }
+ return HashCodes.fromBytes(bb.array());
}
public void testParanoid() {
@@ -64,8 +75,12 @@ public class Murmur3Hash128Test extends TestCase {
return hasher.hash().asBytes();
}
};
- // the magic number comes from:
- // http://code.google.com/p/smhasher/source/browse/trunk/main.cpp, #74
+ // Murmur3F, MurmurHash3 for x64, 128-bit (MurmurHash3_x64_128)
+ // From http://code.google.com/p/smhasher/source/browse/trunk/main.cpp
HashTestUtils.verifyHashFunction(hf, 128, 0x6384BA69);
}
+
+ public void testInvariants() {
+ HashTestUtils.assertInvariants(murmur3_128());
+ }
}
diff --git a/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java b/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java
index 541b53a..dcd57ae 100644
--- a/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java
+++ b/guava-tests/test/com/google/common/hash/Murmur3Hash32Test.java
@@ -24,9 +24,38 @@ import com.google.common.hash.HashTestUtils.HashFn;
import junit.framework.TestCase;
/**
- * Tests for Murmur3Hash32.
+ * Tests for {@link Murmur3_32HashFunction}.
*/
public class Murmur3Hash32Test extends TestCase {
+ public void testKnownIntegerInputs() {
+ assertHash(593689054, murmur3_32().hashInt(0));
+ assertHash(-189366624, murmur3_32().hashInt(-42));
+ assertHash(-1134849565, murmur3_32().hashInt(42));
+ assertHash(-1718298732, murmur3_32().hashInt(Integer.MIN_VALUE));
+ assertHash(-1653689534, murmur3_32().hashInt(Integer.MAX_VALUE));
+ }
+
+ public void testKnownLongInputs() {
+ assertHash(1669671676, murmur3_32().hashLong(0L));
+ assertHash(-846261623, murmur3_32().hashLong(-42L));
+ assertHash(1871679806, murmur3_32().hashLong(42L));
+ assertHash(1366273829, murmur3_32().hashLong(Long.MIN_VALUE));
+ assertHash(-2106506049, murmur3_32().hashLong(Long.MAX_VALUE));
+ }
+
+ public void testKnownStringInputs() {
+ assertHash(0, murmur3_32().hashString(""));
+ assertHash(679745764, murmur3_32().hashString("k"));
+ assertHash(1510782915, murmur3_32().hashString("hell"));
+ assertHash(-675079799, murmur3_32().hashString("hello"));
+ assertHash(1935035788, murmur3_32().hashString("http://www.google.com/"));
+ assertHash(-528633700, murmur3_32().hashString("The quick brown fox jumps over the lazy dog"));
+ }
+
+ private static void assertHash(int expected, HashCode actual) {
+ assertEquals(HashCodes.fromInt(expected), actual);
+ }
+
public void testParanoid() {
HashFn hf = new HashFn() {
@Override public byte[] hash(byte[] input, int seed) {
@@ -35,8 +64,12 @@ public class Murmur3Hash32Test extends TestCase {
return hasher.hash().asBytes();
}
};
- // the magic number comes from:
- // http://code.google.com/p/smhasher/source/browse/trunk/main.cpp, #72
+ // Murmur3A, MurmurHash3 for x86, 32-bit (MurmurHash3_x86_32)
+ // http://code.google.com/p/smhasher/source/browse/trunk/main.cpp
HashTestUtils.verifyHashFunction(hf, 32, 0xB0F57EE3);
}
+
+ public void testInvariants() {
+ HashTestUtils.assertInvariants(murmur3_32());
+ }
}
diff --git a/guava-tests/test/com/google/common/hash/PackageSanityTests.java b/guava-tests/test/com/google/common/hash/PackageSanityTests.java
new file mode 100644
index 0000000..a752a33
--- /dev/null
+++ b/guava-tests/test/com/google/common/hash/PackageSanityTests.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.hash;
+
+import com.google.common.hash.BloomFilterStrategies.BitArray;
+import com.google.common.testing.AbstractPackageSanityTests;
+
+/**
+ * Basic sanity tests for the entire package.
+ *
+ * @author Ben Yu
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {
+ public PackageSanityTests() {
+ setDefault(BitArray.class, new BitArray(1));
+ setDefault(HashCode.class, HashCodes.fromInt(1));
+ setDefault(String.class, "MD5");
+ setDefault(int.class, 32);
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/BaseEncodingTest.java b/guava-tests/test/com/google/common/io/BaseEncodingTest.java
new file mode 100644
index 0000000..fb33841
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/BaseEncodingTest.java
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.io.BaseEncoding.base32;
+import static com.google.common.io.BaseEncoding.base32Hex;
+import static com.google.common.io.BaseEncoding.base64;
+
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Ascii;
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * Tests for {@code BaseEncoding}.
+ *
+ * @author Louis Wasserman
+ */
+@GwtCompatible(emulated = true)
+public class BaseEncodingTest extends TestCase {
+ public void assertEquals(byte[] expected, byte[] actual) {
+ assertEquals(expected.length, actual.length);
+ for (int i = 0; i < expected.length; i++) {
+ assertEquals(expected[i], actual[i]);
+ }
+ }
+
+ public void testSeparatorsExplicitly() {
+ testEncodes(base64().withSeparator("\n", 3), "foobar", "Zm9\nvYm\nFy");
+ testEncodes(base64().withSeparator("$", 4), "foobar", "Zm9v$YmFy");
+ testEncodes(base32().withSeparator("*", 4), "foobar", "MZXW*6YTB*OI==*====");
+ }
+
+ @SuppressWarnings("ReturnValueIgnored")
+ public void testSeparatorSameAsPadChar() {
+ try {
+ base64().withSeparator("=", 3);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
+
+ try {
+ base64().withPadChar('#').withSeparator("!#!", 3);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ @SuppressWarnings("ReturnValueIgnored")
+ public void testAtMostOneSeparator() {
+ BaseEncoding separated = base64().withSeparator("\n", 3);
+ try {
+ separated.withSeparator("$", 4);
+ fail("Expected UnsupportedOperationException");
+ } catch (UnsupportedOperationException expected) {}
+ }
+
+ public void testBase64() {
+ // The following test vectors are specified in RFC 4648 itself
+ testEncodingWithSeparators(base64(), "", "");
+ testEncodingWithSeparators(base64(), "f", "Zg==");
+ testEncodingWithSeparators(base64(), "fo", "Zm8=");
+ testEncodingWithSeparators(base64(), "foo", "Zm9v");
+ testEncodingWithSeparators(base64(), "foob", "Zm9vYg==");
+ testEncodingWithSeparators(base64(), "fooba", "Zm9vYmE=");
+ testEncodingWithSeparators(base64(), "foobar", "Zm9vYmFy");
+ }
+
+ @GwtIncompatible("Reader/Writer")
+ public void testBase64Streaming() throws IOException {
+ // The following test vectors are specified in RFC 4648 itself
+ testStreamingEncodingWithSeparators(base64(), "", "");
+ testStreamingEncodingWithSeparators(base64(), "f", "Zg==");
+ testStreamingEncodingWithSeparators(base64(), "fo", "Zm8=");
+ testStreamingEncodingWithSeparators(base64(), "foo", "Zm9v");
+ testStreamingEncodingWithSeparators(base64(), "foob", "Zm9vYg==");
+ testStreamingEncodingWithSeparators(base64(), "fooba", "Zm9vYmE=");
+ testStreamingEncodingWithSeparators(base64(), "foobar", "Zm9vYmFy");
+ }
+
+ public void testBase64LenientPadding() {
+ testDecodes(base64(), "Zg", "f");
+ testDecodes(base64(), "Zg=", "f");
+ testDecodes(base64(), "Zg==", "f"); // proper padding length
+ testDecodes(base64(), "Zg===", "f");
+ testDecodes(base64(), "Zg====", "f");
+ }
+
+ public void testBase64InvalidDecodings() {
+ // These contain bytes not in the decodabet.
+ assertFailsToDecode(base64(), "\u007f");
+ assertFailsToDecode(base64(), "Wf2!");
+ // This sentence just isn't base64() encoded.
+ assertFailsToDecode(base64(), "let's not talk of love or chains!");
+ // A 4n+1 length string is never legal base64().
+ assertFailsToDecode(base64(), "12345");
+ }
+
+ @SuppressWarnings("ReturnValueIgnored")
+ public void testBase64CannotUpperCase() {
+ try {
+ base64().upperCase();
+ fail();
+ } catch (IllegalStateException expected) {
+ // success
+ }
+ }
+
+ @SuppressWarnings("ReturnValueIgnored")
+ public void testBase64CannotLowerCase() {
+ try {
+ base64().lowerCase();
+ fail();
+ } catch (IllegalStateException expected) {
+ // success
+ }
+ }
+
+ public void testBase64AlternatePadding() {
+ BaseEncoding enc = base64().withPadChar('~');
+ testEncodingWithSeparators(enc, "", "");
+ testEncodingWithSeparators(enc, "f", "Zg~~");
+ testEncodingWithSeparators(enc, "fo", "Zm8~");
+ testEncodingWithSeparators(enc, "foo", "Zm9v");
+ testEncodingWithSeparators(enc, "foob", "Zm9vYg~~");
+ testEncodingWithSeparators(enc, "fooba", "Zm9vYmE~");
+ testEncodingWithSeparators(enc, "foobar", "Zm9vYmFy");
+ }
+
+ @GwtIncompatible("Reader/Writer")
+ public void testBase64StreamingAlternatePadding() throws IOException {
+ BaseEncoding enc = base64().withPadChar('~');
+ testStreamingEncodingWithSeparators(enc, "", "");
+ testStreamingEncodingWithSeparators(enc, "f", "Zg~~");
+ testStreamingEncodingWithSeparators(enc, "fo", "Zm8~");
+ testStreamingEncodingWithSeparators(enc, "foo", "Zm9v");
+ testStreamingEncodingWithSeparators(enc, "foob", "Zm9vYg~~");
+ testStreamingEncodingWithSeparators(enc, "fooba", "Zm9vYmE~");
+ testStreamingEncodingWithSeparators(enc, "foobar", "Zm9vYmFy");
+ }
+
+ public void testBase64OmitPadding() {
+ BaseEncoding enc = base64().omitPadding();
+ testEncodingWithSeparators(enc, "", "");
+ testEncodingWithSeparators(enc, "f", "Zg");
+ testEncodingWithSeparators(enc, "fo", "Zm8");
+ testEncodingWithSeparators(enc, "foo", "Zm9v");
+ testEncodingWithSeparators(enc, "foob", "Zm9vYg");
+ testEncodingWithSeparators(enc, "fooba", "Zm9vYmE");
+ testEncodingWithSeparators(enc, "foobar", "Zm9vYmFy");
+ }
+
+ @GwtIncompatible("Reader/Writer")
+ public void testBase64StreamingOmitPadding() throws IOException {
+ BaseEncoding enc = base64().omitPadding();
+ testStreamingEncodingWithSeparators(enc, "", "");
+ testStreamingEncodingWithSeparators(enc, "f", "Zg");
+ testStreamingEncodingWithSeparators(enc, "fo", "Zm8");
+ testStreamingEncodingWithSeparators(enc, "foo", "Zm9v");
+ testStreamingEncodingWithSeparators(enc, "foob", "Zm9vYg");
+ testStreamingEncodingWithSeparators(enc, "fooba", "Zm9vYmE");
+ testStreamingEncodingWithSeparators(enc, "foobar", "Zm9vYmFy");
+ }
+
+ public void testBase32() {
+ // The following test vectors are specified in RFC 4648 itself
+ testEncodingWithCasing(base32(), "", "");
+ testEncodingWithCasing(base32(), "f", "MY======");
+ testEncodingWithCasing(base32(), "fo", "MZXQ====");
+ testEncodingWithCasing(base32(), "foo", "MZXW6===");
+ testEncodingWithCasing(base32(), "foob", "MZXW6YQ=");
+ testEncodingWithCasing(base32(), "fooba", "MZXW6YTB");
+ testEncodingWithCasing(base32(), "foobar", "MZXW6YTBOI======");
+ }
+
+ @GwtIncompatible("Reader/Writer")
+ public void testBase32Streaming() throws IOException {
+ // The following test vectors are specified in RFC 4648 itself
+ testStreamingEncodingWithCasing(base32(), "", "");
+ testStreamingEncodingWithCasing(base32(), "f", "MY======");
+ testStreamingEncodingWithCasing(base32(), "fo", "MZXQ====");
+ testStreamingEncodingWithCasing(base32(), "foo", "MZXW6===");
+ testStreamingEncodingWithCasing(base32(), "foob", "MZXW6YQ=");
+ testStreamingEncodingWithCasing(base32(), "fooba", "MZXW6YTB");
+ testStreamingEncodingWithCasing(base32(), "foobar", "MZXW6YTBOI======");
+ }
+
+ public void testBase32LenientPadding() {
+ testDecodes(base32(), "MZXW6", "foo");
+ testDecodes(base32(), "MZXW6=", "foo");
+ testDecodes(base32(), "MZXW6==", "foo");
+ testDecodes(base32(), "MZXW6===", "foo"); // proper padding length
+ testDecodes(base32(), "MZXW6====", "foo");
+ testDecodes(base32(), "MZXW6=====", "foo");
+ }
+
+ public void testBase32AlternatePadding() {
+ BaseEncoding enc = base32().withPadChar('~');
+ testEncodingWithCasing(enc, "", "");
+ testEncodingWithCasing(enc, "f", "MY~~~~~~");
+ testEncodingWithCasing(enc, "fo", "MZXQ~~~~");
+ testEncodingWithCasing(enc, "foo", "MZXW6~~~");
+ testEncodingWithCasing(enc, "foob", "MZXW6YQ~");
+ testEncodingWithCasing(enc, "fooba", "MZXW6YTB");
+ testEncodingWithCasing(enc, "foobar", "MZXW6YTBOI~~~~~~");
+ }
+
+ public void testBase32InvalidDecodings() {
+ // These contain bytes not in the decodabet.
+ assertFailsToDecode(base32(), "\u007f");
+ assertFailsToDecode(base32(), "Wf2!");
+ // This sentence just isn't base32() encoded.
+ assertFailsToDecode(base32(), "let's not talk of love or chains!");
+ // An 8n+{1,3,6} length string is never legal base32.
+ assertFailsToDecode(base32(), "A");
+ assertFailsToDecode(base32(), "ABC");
+ assertFailsToDecode(base32(), "ABCDEF");
+ }
+
+ public void testBase32UpperCaseIsNoOp() {
+ assertSame(base32(), base32().upperCase());
+ }
+
+ public void testBase32Hex() {
+ // The following test vectors are specified in RFC 4648 itself
+ testEncodingWithCasing(base32Hex(), "", "");
+ testEncodingWithCasing(base32Hex(), "f", "CO======");
+ testEncodingWithCasing(base32Hex(), "fo", "CPNG====");
+ testEncodingWithCasing(base32Hex(), "foo", "CPNMU===");
+ testEncodingWithCasing(base32Hex(), "foob", "CPNMUOG=");
+ testEncodingWithCasing(base32Hex(), "fooba", "CPNMUOJ1");
+ testEncodingWithCasing(base32Hex(), "foobar", "CPNMUOJ1E8======");
+ }
+
+ @GwtIncompatible("Reader/Writer")
+ public void testBase32HexStreaming() throws IOException {
+ // The following test vectors are specified in RFC 4648 itself
+ testStreamingEncodingWithCasing(base32Hex(), "", "");
+ testStreamingEncodingWithCasing(base32Hex(), "f", "CO======");
+ testStreamingEncodingWithCasing(base32Hex(), "fo", "CPNG====");
+ testStreamingEncodingWithCasing(base32Hex(), "foo", "CPNMU===");
+ testStreamingEncodingWithCasing(base32Hex(), "foob", "CPNMUOG=");
+ testStreamingEncodingWithCasing(base32Hex(), "fooba", "CPNMUOJ1");
+ testStreamingEncodingWithCasing(base32Hex(), "foobar", "CPNMUOJ1E8======");
+ }
+
+ public void testBase32HexLenientPadding() {
+ testDecodes(base32Hex(), "CPNMU", "foo");
+ testDecodes(base32Hex(), "CPNMU=", "foo");
+ testDecodes(base32Hex(), "CPNMU==", "foo");
+ testDecodes(base32Hex(), "CPNMU===", "foo"); // proper padding length
+ testDecodes(base32Hex(), "CPNMU====", "foo");
+ testDecodes(base32Hex(), "CPNMU=====", "foo");
+ }
+
+ public void testBase32HexInvalidDecodings() {
+ // These contain bytes not in the decodabet.
+ assertFailsToDecode(base32Hex(), "\u007f");
+ assertFailsToDecode(base32Hex(), "Wf2!");
+ // This sentence just isn't base32 encoded.
+ assertFailsToDecode(base32Hex(), "let's not talk of love or chains!");
+ // An 8n+{1,3,6} length string is never legal base32.
+ assertFailsToDecode(base32Hex(), "A");
+ assertFailsToDecode(base32Hex(), "ABC");
+ assertFailsToDecode(base32Hex(), "ABCDEF");
+ }
+
+ public void testBase32HexUpperCaseIsNoOp() {
+ assertSame(base32Hex(), base32Hex().upperCase());
+ }
+
+ public void testBase16() {
+ testEncodingWithCasing(base16(), "", "");
+ testEncodingWithCasing(base16(), "f", "66");
+ testEncodingWithCasing(base16(), "fo", "666F");
+ testEncodingWithCasing(base16(), "foo", "666F6F");
+ testEncodingWithCasing(base16(), "foob", "666F6F62");
+ testEncodingWithCasing(base16(), "fooba", "666F6F6261");
+ testEncodingWithCasing(base16(), "foobar", "666F6F626172");
+ }
+
+ public void testBase16UpperCaseIsNoOp() {
+ assertSame(base16().upperCase(), base16().upperCase());
+ }
+
+ private void testEncodingWithCasing(BaseEncoding encoding, String decoded, String encoded) {
+ testEncodingWithSeparators(encoding, decoded, encoded);
+ testEncodingWithSeparators(encoding.upperCase(), decoded, Ascii.toUpperCase(encoded));
+ testEncodingWithSeparators(encoding.lowerCase(), decoded, Ascii.toLowerCase(encoded));
+ }
+
+ private void testEncodingWithSeparators(BaseEncoding encoding, String decoded, String encoded) {
+ testEncoding(encoding, decoded, encoded);
+
+ // test separators work
+ for (int sepLength = 3; sepLength <= 5; sepLength++) {
+ for (String separator : ImmutableList.of(",", "\n", ";;", "")) {
+ testEncoding(encoding.withSeparator(separator, sepLength), decoded,
+ Joiner.on(separator).join(Splitter.fixedLength(sepLength).split(encoded)));
+ }
+ }
+ }
+
+ private void testEncoding(BaseEncoding encoding, String decoded, String encoded) {
+ testEncodes(encoding, decoded, encoded);
+ testDecodes(encoding, encoded, decoded);
+ }
+
+ private void testEncodes(BaseEncoding encoding, String decoded, String encoded) {
+ byte[] bytes;
+ try {
+ bytes = decoded.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError();
+ }
+ assertEquals(encoded, encoding.encode(bytes));
+ }
+
+ private void testDecodes(BaseEncoding encoding, String encoded, String decoded) {
+ byte[] bytes;
+ try {
+ bytes = decoded.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError();
+ }
+ assertEquals(bytes, encoding.decode(encoded));
+ }
+
+ private void assertFailsToDecode(BaseEncoding encoding, String cannotDecode) {
+ try {
+ encoding.decode(cannotDecode);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // success
+ }
+ }
+
+ @GwtIncompatible("Reader/Writer")
+ private void testStreamingEncodingWithCasing(
+ BaseEncoding encoding, String decoded, String encoded) throws IOException {
+ testStreamingEncodingWithSeparators(encoding, decoded, encoded);
+ testStreamingEncodingWithSeparators(encoding.upperCase(), decoded, Ascii.toUpperCase(encoded));
+ testStreamingEncodingWithSeparators(encoding.lowerCase(), decoded, Ascii.toLowerCase(encoded));
+ }
+
+ @GwtIncompatible("Reader/Writer")
+ private void testStreamingEncodingWithSeparators(
+ BaseEncoding encoding, String decoded, String encoded) throws IOException {
+ testStreamingEncoding(encoding, decoded, encoded);
+
+ // test separators work
+ for (int sepLength = 3; sepLength <= 5; sepLength++) {
+ for (String separator : ImmutableList.of(",", "\n", ";;", "")) {
+ testStreamingEncoding(encoding.withSeparator(separator, sepLength), decoded,
+ Joiner.on(separator).join(Splitter.fixedLength(sepLength).split(encoded)));
+ }
+ }
+ }
+
+ @GwtIncompatible("Reader/Writer")
+ private void testStreamingEncoding(BaseEncoding encoding, String decoded, String encoded)
+ throws IOException {
+ testStreamingEncodes(encoding, decoded, encoded);
+ testStreamingDecodes(encoding, encoded, decoded);
+ }
+
+ @GwtIncompatible("Writer")
+ private void testStreamingEncodes(BaseEncoding encoding, String decoded, String encoded)
+ throws IOException {
+ byte[] bytes;
+ try {
+ bytes = decoded.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError();
+ }
+ StringWriter writer = new StringWriter();
+ OutputStream encodingStream = encoding.encodingStream(writer);
+ encodingStream.write(bytes);
+ encodingStream.close();
+ assertEquals(encoded, writer.toString());
+ }
+
+ @GwtIncompatible("Reader")
+ private void testStreamingDecodes(BaseEncoding encoding, String encoded, String decoded)
+ throws IOException {
+ byte[] bytes;
+ try {
+ bytes = decoded.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new AssertionError();
+ }
+ InputStream decodingStream = encoding.decodingStream(new StringReader(encoded));
+ for (int i = 0; i < bytes.length; i++) {
+ assertEquals(bytes[i] & 0xFF, decodingStream.read());
+ }
+ assertEquals(-1, decodingStream.read());
+ decodingStream.close();
+ }
+
+ public void testToString() {
+ assertEquals("BaseEncoding.base64().withPadChar(=)", BaseEncoding.base64().toString());
+ assertEquals("BaseEncoding.base32Hex().omitPadding()",
+ BaseEncoding.base32Hex().omitPadding().toString());
+ assertEquals("BaseEncoding.base32().lowerCase().withPadChar($)",
+ BaseEncoding.base32().lowerCase().withPadChar('$').toString());
+ assertEquals("BaseEncoding.base16().withSeparator(\"\n\", 10)",
+ BaseEncoding.base16().withSeparator("\n", 10).toString());
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/ByteSinkTest.java b/guava-tests/test/com/google/common/io/ByteSinkTest.java
new file mode 100644
index 0000000..adb659c
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/ByteSinkTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.io.TestOption.CLOSE_THROWS;
+import static com.google.common.io.TestOption.OPEN_THROWS;
+import static com.google.common.io.TestOption.READ_THROWS;
+import static com.google.common.io.TestOption.WRITE_THROWS;
+import static org.junit.Assert.assertArrayEquals;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.EnumSet;
+
+/**
+ * Tests for the default implementations of {@code ByteSink} methods.
+ *
+ * @author Colin Decker
+ */
+public class ByteSinkTest extends IoTestCase {
+
+ private final byte[] bytes = newPreFilledByteArray(10000);
+
+ private TestByteSink sink;
+
+ @Override
+ protected void setUp() throws Exception {
+ sink = new TestByteSink();
+ }
+
+ public void testOpenBufferedStream() throws IOException {
+ BufferedOutputStream out = sink.openBufferedStream();
+ assertTrue(sink.wasStreamOpened());
+ assertFalse(sink.wasStreamClosed());
+
+ out.write(new byte[] {1, 2, 3, 4});
+ out.close();
+
+ assertTrue(sink.wasStreamClosed());
+ assertArrayEquals(new byte[] {1, 2, 3, 4}, sink.getBytes());
+ }
+
+ public void testWrite_bytes() throws IOException {
+ assertArrayEquals(new byte[0], sink.getBytes());
+ sink.write(bytes);
+
+ assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
+ assertArrayEquals(bytes, sink.getBytes());
+ }
+
+ public void testWriteFrom_inputStream() throws IOException {
+ ByteArrayInputStream in = new ByteArrayInputStream(bytes);
+ sink.writeFrom(in);
+
+ assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
+ assertArrayEquals(bytes, sink.getBytes());
+ }
+
+ public void testWriteFromStream_doesNotCloseThatStream() throws IOException {
+ TestInputStream in = new TestInputStream(new ByteArrayInputStream(new byte[10]));
+ assertFalse(in.closed());
+ sink.writeFrom(in);
+ assertFalse(in.closed());
+ }
+
+ public void testClosesOnErrors_copyingFromByteSourceThatThrows() {
+ for (TestOption option : EnumSet.of(OPEN_THROWS, READ_THROWS, CLOSE_THROWS)) {
+ TestByteSource failSource = new TestByteSource(new byte[10], option);
+ TestByteSink okSink = new TestByteSink();
+ try {
+ failSource.copyTo(okSink);
+ fail();
+ } catch (IOException expected) {}
+ // ensure stream was closed IF it was opened (depends on implementation whether or not it's
+ // opened at all if source.newInputStream() throws).
+ assertTrue("stream not closed when copying from source with option: " + option,
+ !okSink.wasStreamOpened() || okSink.wasStreamClosed());
+ }
+ }
+
+ public void testClosesOnErrors_whenWriteThrows() {
+ TestByteSink failSink = new TestByteSink(WRITE_THROWS);
+ try {
+ new TestByteSource(new byte[10]).copyTo(failSink);
+ fail();
+ } catch (IOException expected) {
+ }
+ assertTrue(failSink.wasStreamClosed());
+ }
+
+ public void testClosesOnErrors_writingFromInputStreamThatThrows() {
+ TestByteSink okSink = new TestByteSink();
+ try {
+ TestInputStream in = new TestInputStream(
+ new ByteArrayInputStream(new byte[10]), READ_THROWS);
+ okSink.writeFrom(in);
+ fail();
+ } catch (IOException expected) {
+ }
+ assertTrue(okSink.wasStreamClosed());
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/ByteSinkTester.java b/guava-tests/test/com/google/common/io/ByteSinkTester.java
new file mode 100644
index 0000000..69b9d94
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/ByteSinkTester.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.io.SourceSinkFactory.ByteSinkFactory;
+import static com.google.common.io.SourceSinkFactory.CharSinkFactory;
+import static org.junit.Assert.assertArrayEquals;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableList;
+
+import junit.framework.TestSuite;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+/**
+ * A generator of {@code TestSuite} instances for testing {@code ByteSink} implementations.
+ * Generates tests of a all methods on a {@code ByteSink} given various inputs written to it as well
+ * as sub-suites for testing the {@code CharSink} view in the same way.
+ *
+ * @author Colin Decker
+ */
+public class ByteSinkTester extends SourceSinkTester<ByteSink, byte[], ByteSinkFactory> {
+
+ private static final ImmutableList<Method> testMethods
+ = getTestMethods(ByteSinkTester.class);
+
+ static TestSuite tests(String name, ByteSinkFactory factory) {
+ TestSuite suite = new TestSuite(name);
+ for (Map.Entry<String, String> entry : TEST_STRINGS.entrySet()) {
+ String desc = entry.getKey();
+ TestSuite stringSuite = suiteForString(name, factory, entry.getValue(), desc);
+ suite.addTest(stringSuite);
+ }
+ return suite;
+ }
+
+ private static TestSuite suiteForString(String name, ByteSinkFactory factory,
+ String string, String desc) {
+ byte[] bytes = string.getBytes(Charsets.UTF_8);
+ TestSuite suite = suiteForBytes(name, factory, desc, bytes);
+ CharSinkFactory charSinkFactory = SourceSinkFactories.asCharSinkFactory(factory);
+ suite.addTest(CharSinkTester.suiteForString(name + ".asCharSink[Charset]", charSinkFactory,
+ string, desc));
+ return suite;
+ }
+
+ private static TestSuite suiteForBytes(String name, ByteSinkFactory factory,
+ String desc, byte[] bytes) {
+ TestSuite suite = new TestSuite(name + " [" + desc + "]");
+ for (final Method method : testMethods) {
+ suite.addTest(new ByteSinkTester(factory, bytes, name, desc, method));
+ }
+ return suite;
+ }
+
+ private ByteSink sink;
+
+ ByteSinkTester(ByteSinkFactory factory, byte[] data, String suiteName,
+ String caseDesc, Method method) {
+ super(factory, data, suiteName, caseDesc, method);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ sink = factory.createSink();
+ }
+
+ public void testOpenStream() throws IOException {
+ OutputStream out = sink.openStream();
+ try {
+ ByteStreams.copy(new ByteArrayInputStream(data), out);
+ } finally {
+ out.close();
+ }
+
+ assertContainsExpectedBytes();
+ }
+
+ public void testOpenBufferedStream() throws IOException {
+ BufferedOutputStream out = sink.openBufferedStream();
+ try {
+ ByteStreams.copy(new ByteArrayInputStream(data), out);
+ } finally {
+ out.close();
+ }
+
+ assertContainsExpectedBytes();
+ }
+
+ public void testWrite() throws IOException {
+ sink.write(data);
+
+ assertContainsExpectedBytes();
+ }
+
+ public void testWriteFrom_inputStream() throws IOException {
+ sink.writeFrom(new ByteArrayInputStream(data));
+
+ assertContainsExpectedBytes();
+ }
+
+ private void assertContainsExpectedBytes() throws IOException {
+ assertArrayEquals(expected, factory.getSinkContents());
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/ByteSourceTest.java b/guava-tests/test/com/google/common/io/ByteSourceTest.java
new file mode 100644
index 0000000..73919f1
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/ByteSourceTest.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.io.TestOption.CLOSE_THROWS;
+import static com.google.common.io.TestOption.OPEN_THROWS;
+import static com.google.common.io.TestOption.READ_THROWS;
+import static com.google.common.io.TestOption.SKIP_THROWS;
+import static com.google.common.io.TestOption.WRITE_THROWS;
+import static org.junit.Assert.assertArrayEquals;
+
+import com.google.common.base.Charsets;
+import com.google.common.hash.Hashing;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.EnumSet;
+
+/**
+ * Tests for the default implementations of {@code ByteSource} methods.
+ *
+ * @author Colin Decker
+ */
+public class ByteSourceTest extends IoTestCase {
+
+ private static final byte[] bytes = newPreFilledByteArray(10000);
+
+ private TestByteSource source;
+
+ @Override
+ protected void setUp() throws Exception {
+ source = new TestByteSource(bytes);
+ }
+
+ public void testOpenBufferedStream() throws IOException {
+ BufferedInputStream in = source.openBufferedStream();
+ assertTrue(source.wasStreamOpened());
+ assertFalse(source.wasStreamClosed());
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ByteStreams.copy(in, out);
+ in.close();
+ out.close();
+
+ assertTrue(source.wasStreamClosed());
+ assertArrayEquals(bytes, out.toByteArray());
+ }
+
+ public void testSize() throws IOException {
+ assertEquals(bytes.length, source.size());
+ assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
+
+ // test that we can get the size even if skip() isn't supported
+ assertEquals(bytes.length, new TestByteSource(bytes, SKIP_THROWS).size());
+ }
+
+ public void testCopyTo_outputStream() throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ assertEquals(bytes.length, source.copyTo(out));
+ assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
+
+ assertArrayEquals(bytes, out.toByteArray());
+ }
+
+ public void testCopyTo_byteSink() throws IOException {
+ TestByteSink sink = new TestByteSink();
+
+ assertFalse(sink.wasStreamOpened() || sink.wasStreamClosed());
+
+ assertEquals(bytes.length, source.copyTo(sink));
+ assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
+ assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
+
+ assertArrayEquals(bytes, sink.getBytes());
+ }
+
+ public void testRead_toArray() throws IOException {
+ assertArrayEquals(bytes, source.read());
+ assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
+ }
+
+ public void testHash() throws IOException {
+ ByteSource byteSource = new TestByteSource("hamburger\n".getBytes(Charsets.US_ASCII));
+
+ // Pasted this expected string from `echo hamburger | md5sum`
+ assertEquals("cfa0c5002275c90508338a5cdb2a9781", byteSource.hash(Hashing.md5()).toString());
+ }
+
+ public void testContentEquals() throws IOException {
+ assertTrue(source.contentEquals(source));
+ assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
+
+ ByteSource equalSource = new TestByteSource(bytes);
+ assertTrue(source.contentEquals(equalSource));
+ assertTrue(new TestByteSource(bytes).contentEquals(source));
+
+ ByteSource fewerBytes = new TestByteSource(newPreFilledByteArray(bytes.length / 2));
+ assertFalse(source.contentEquals(fewerBytes));
+
+ byte[] copy = bytes.clone();
+ copy[9876] = 1;
+ ByteSource oneByteOff = new TestByteSource(copy);
+ assertFalse(source.contentEquals(oneByteOff));
+ }
+
+ public void testSlice() throws IOException {
+ // Test preconditions
+ try {
+ source.slice(-1, 10);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ source.slice(0, -1);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ assertCorrectSlice(0, 0, 0, 0);
+ assertCorrectSlice(0, 0, 1, 0);
+ assertCorrectSlice(100, 0, 10, 10);
+ assertCorrectSlice(100, 0, 100, 100);
+ assertCorrectSlice(100, 5, 10, 10);
+ assertCorrectSlice(100, 5, 100, 95);
+ assertCorrectSlice(100, 100, 0, 0);
+ assertCorrectSlice(100, 100, 10, 0);
+
+ try {
+ assertCorrectSlice(100, 101, 10, 0);
+ fail();
+ } catch (EOFException expected) {
+ }
+ }
+
+ /**
+ * @param input the size of the input source
+ * @param offset the first argument to {@link ByteStreams#slice}
+ * @param length the second argument to {@link ByteStreams#slice}
+ * @param expectRead the number of bytes we expect to read
+ */
+ private static void assertCorrectSlice(
+ int input, int offset, long length, int expectRead) throws IOException {
+ checkArgument(expectRead == (int) Math.max(0, Math.min(input, offset + length) - offset));
+
+ byte[] expected = newPreFilledByteArray(offset, expectRead);
+
+ ByteSource source = new TestByteSource(newPreFilledByteArray(input));
+ ByteSource slice = source.slice(offset, length);
+
+ assertArrayEquals(expected, slice.read());
+ }
+
+ public void testCopyToStream_doesNotCloseThatStream() throws IOException {
+ TestOutputStream out = new TestOutputStream(ByteStreams.nullOutputStream());
+ assertFalse(out.closed());
+ source.copyTo(out);
+ assertFalse(out.closed());
+ }
+
+ public void testClosesOnErrors_copyingToByteSinkThatThrows() {
+ for (TestOption option : EnumSet.of(OPEN_THROWS, WRITE_THROWS, CLOSE_THROWS)) {
+ TestByteSource okSource = new TestByteSource(bytes);
+ try {
+ okSource.copyTo(new TestByteSink(option));
+ fail();
+ } catch (IOException expected) {
+ }
+ // ensure stream was closed IF it was opened (depends on implementation whether or not it's
+ // opened at all if sink.newOutputStream() throws).
+ assertTrue("stream not closed when copying to sink with option: " + option,
+ !okSource.wasStreamOpened() || okSource.wasStreamClosed());
+ }
+ }
+
+ public void testClosesOnErrors_whenReadThrows() {
+ TestByteSource failSource = new TestByteSource(bytes, READ_THROWS);
+ try {
+ failSource.copyTo(new TestByteSink());
+ fail();
+ } catch (IOException expected) {
+ }
+ assertTrue(failSource.wasStreamClosed());
+ }
+
+ public void testClosesOnErrors_copyingToOutputStreamThatThrows() {
+ TestByteSource okSource = new TestByteSource(bytes);
+ try {
+ OutputStream out = new TestOutputStream(ByteStreams.nullOutputStream(), WRITE_THROWS);
+ okSource.copyTo(out);
+ fail();
+ } catch (IOException expected) {
+ }
+ assertTrue(okSource.wasStreamClosed());
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/ByteSourceTester.java b/guava-tests/test/com/google/common/io/ByteSourceTester.java
new file mode 100644
index 0000000..10cb9a7
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/ByteSourceTester.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.io.SourceSinkFactory.ByteSourceFactory;
+import static com.google.common.io.SourceSinkFactory.CharSourceFactory;
+import static org.junit.Assert.assertArrayEquals;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableList;
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hashing;
+
+import junit.framework.TestSuite;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * A generator of {@code TestSuite} instances for testing {@code ByteSource} implementations.
+ * Generates tests of a all methods on a {@code ByteSource} given various inputs the source is
+ * expected to contain as well as as sub-suites for testing the {@code CharSource} view and
+ * {@code slice()} views in the same way.
+ *
+ * @author Colin Decker
+ */
+public class ByteSourceTester extends SourceSinkTester<ByteSource, byte[], ByteSourceFactory> {
+
+ private static final ImmutableList<Method> testMethods
+ = getTestMethods(ByteSourceTester.class);
+
+ static TestSuite tests(String name, ByteSourceFactory factory, boolean testAsCharSource) {
+ TestSuite suite = new TestSuite(name);
+ for (Map.Entry<String, String> entry : TEST_STRINGS.entrySet()) {
+ if (testAsCharSource) {
+ suite.addTest(suiteForString(factory, entry.getValue(), name, entry.getKey()));
+ } else {
+ suite.addTest(suiteForBytes(
+ factory, entry.getValue().getBytes(Charsets.UTF_8), name, entry.getKey(), true));
+ }
+ }
+ return suite;
+ }
+
+ private static TestSuite suiteForString(ByteSourceFactory factory, String string,
+ String name, String desc) {
+ TestSuite suite = suiteForBytes(factory, string.getBytes(Charsets.UTF_8), name, desc, true);
+ CharSourceFactory charSourceFactory = SourceSinkFactories.asCharSourceFactory(factory);
+ suite.addTest(CharSourceTester.suiteForString(charSourceFactory, string,
+ name + ".asCharSource[Charset]", desc));
+ return suite;
+ }
+
+ private static TestSuite suiteForBytes(ByteSourceFactory factory, byte[] bytes,
+ String name, String desc, boolean slice) {
+ TestSuite suite = new TestSuite(name + " [" + desc + "]");
+ for (Method method : testMethods) {
+ suite.addTest(new ByteSourceTester(factory, bytes, name, desc, method));
+ }
+
+ if (slice && bytes.length > 0) {
+ // test a random slice() of the ByteSource
+ Random random = new Random();
+ byte[] expected = factory.getExpected(bytes);
+ int off = random.nextInt(expected.length);
+ int len = random.nextInt(expected.length - off);
+ ByteSourceFactory sliced = SourceSinkFactories.asSlicedByteSourceFactory(factory, off, len);
+ suite.addTest(suiteForBytes(sliced, bytes, name + ".slice[int, int]",
+ desc, false));
+ }
+
+ return suite;
+ }
+
+ private ByteSource source;
+
+ public ByteSourceTester(ByteSourceFactory factory, byte[] bytes,
+ String suiteName, String caseDesc, Method method) {
+ super(factory, bytes, suiteName, caseDesc, method);
+ }
+
+ @Override
+ public void setUp() throws IOException {
+ source = factory.createSource(data);
+ }
+
+ public void testOpenStream() throws IOException {
+ InputStream in = source.openStream();
+ try {
+ byte[] readBytes = ByteStreams.toByteArray(in);
+ assertExpectedBytes(readBytes);
+ } finally {
+ in.close();
+ }
+ }
+
+ public void testOpenBufferedStream() throws IOException {
+ BufferedInputStream in = source.openBufferedStream();
+ try {
+ byte[] readBytes = ByteStreams.toByteArray(in);
+ assertExpectedBytes(readBytes);
+ } finally {
+ in.close();
+ }
+ }
+
+ public void testRead() throws IOException {
+ byte[] readBytes = source.read();
+ assertExpectedBytes(readBytes);
+ }
+
+ public void testCopyTo_outputStream() throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ source.copyTo(out);
+ assertExpectedBytes(out.toByteArray());
+ }
+
+ public void testCopyTo_byteSink() throws IOException {
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ // HERESY! but it's ok just for this I guess
+ source.copyTo(new ByteSink() {
+ @Override
+ public OutputStream openStream() throws IOException {
+ return out;
+ }
+ });
+ assertExpectedBytes(out.toByteArray());
+ }
+
+ public void testSize() throws IOException {
+ assertEquals(expected.length, source.size());
+ }
+
+ public void testContentEquals() throws IOException {
+ assertTrue(source.contentEquals(new ByteSource() {
+ @Override
+ public InputStream openStream() throws IOException {
+ return new RandomAmountInputStream(
+ new ByteArrayInputStream(expected), new Random());
+ }
+ }));
+ }
+
+ public void testHash() throws IOException {
+ HashCode expectedHash = Hashing.md5().hashBytes(expected);
+ assertEquals(expectedHash, source.hash(Hashing.md5()));
+ }
+
+ public void testSlice_illegalArguments() {
+ try {
+ source.slice(-1, 0);
+ fail("expected IllegalArgumentException for call to slice with offset -1: " + source);
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ source.slice(0, -1);
+ fail("expected IllegalArgumentException for call to slice with length -1: " + source);
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ private void assertExpectedBytes(byte[] readBytes) {
+ assertArrayEquals(expected, readBytes);
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/ByteStreamsTest.java b/guava-tests/test/com/google/common/io/ByteStreamsTest.java
index ff0497a..40349f6 100644
--- a/guava-tests/test/com/google/common/io/ByteStreamsTest.java
+++ b/guava-tests/test/com/google/common/io/ByteStreamsTest.java
@@ -22,9 +22,11 @@ import static com.google.common.io.ByteStreams.newInputStreamSupplier;
import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
-import com.google.common.primitives.Bytes;
+import com.google.common.hash.Hashing;
import com.google.common.testing.TestLogHandler;
+import junit.framework.TestSuite;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
@@ -38,6 +40,8 @@ import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
import java.util.Random;
+import java.util.zip.CRC32;
+import java.util.zip.Checksum;
/**
* Unit test for {@link ByteStreams}.
@@ -46,6 +50,14 @@ import java.util.Random;
*/
public class ByteStreamsTest extends IoTestCase {
+ public static TestSuite suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(ByteSourceTester.tests("ByteStreams.asByteSource[byte[]]",
+ SourceSinkFactories.byteArraySourceFactory(), true));
+ suite.addTestSuite(ByteStreamsTest.class);
+ return suite;
+ }
+
/** Provides an InputStream that throws an IOException on every read. */
static final InputSupplier<InputStream> BROKEN_READ
= new InputSupplier<InputStream>() {
@@ -123,8 +135,8 @@ public class ByteStreamsTest extends IoTestCase {
public void testByteSuppliers() throws IOException {
byte[] range = newPreFilledByteArray(200);
- assertTrue(Arrays.equals(range,
- ByteStreams.toByteArray(ByteStreams.newInputStreamSupplier(range))));
+ assertEquals(range,
+ ByteStreams.toByteArray(ByteStreams.newInputStreamSupplier(range)));
byte[] subRange = ByteStreams.toByteArray(
ByteStreams.newInputStreamSupplier(range, 100, 50));
@@ -159,13 +171,13 @@ public class ByteStreamsTest extends IoTestCase {
}));
}
- private void equalHelper(boolean expect, int size1, int size2)
+ private static void equalHelper(boolean expect, int size1, int size2)
throws IOException {
equalHelper(expect, newPreFilledByteArray(size1),
newPreFilledByteArray(size2));
}
- private void equalHelper(boolean expect, byte[] a, byte[] b)
+ private static void equalHelper(boolean expect, byte[] a, byte[] b)
throws IOException {
assertEquals(expect, ByteStreams.equal(
ByteStreams.newInputStreamSupplier(a),
@@ -302,7 +314,7 @@ public class ByteStreamsTest extends IoTestCase {
in.close();
// toByteArray
- assertTrue(Arrays.equals(range, ByteStreams.toByteArray(okRead)));
+ assertEquals(range, ByteStreams.toByteArray(okRead));
assertTrue(okRead.areClosed());
try {
@@ -340,6 +352,66 @@ public class ByteStreamsTest extends IoTestCase {
assertTrue(brokenWrite.areClosed());
}
+ public void testCopySuppliersExceptions() {
+ if (!Closer.SuppressingSuppressor.isAvailable()) {
+ // test that exceptions are logged
+
+ TestLogHandler logHandler = new TestLogHandler();
+ Closeables.logger.addHandler(logHandler);
+ try {
+ for (InputSupplier<InputStream> in : BROKEN_INPUTS) {
+ runFailureTest(in, newByteArrayOutputStreamSupplier());
+ assertTrue(logHandler.getStoredLogRecords().isEmpty());
+
+ runFailureTest(in, BROKEN_CLOSE_OUTPUT);
+ assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, getAndResetRecords(logHandler));
+ }
+
+ for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) {
+ runFailureTest(newInputStreamSupplier(new byte[10]), out);
+ assertTrue(logHandler.getStoredLogRecords().isEmpty());
+
+ runFailureTest(BROKEN_CLOSE_INPUT, out);
+ assertEquals(1, getAndResetRecords(logHandler));
+ }
+
+ for (InputSupplier<InputStream> in : BROKEN_INPUTS) {
+ for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) {
+ runFailureTest(in, out);
+ assertTrue(getAndResetRecords(logHandler) <= 1);
+ }
+ }
+ } finally {
+ Closeables.logger.removeHandler(logHandler);
+ }
+ } else {
+ // test that exceptions are suppressed
+
+ for (InputSupplier<InputStream> in : BROKEN_INPUTS) {
+ int suppressed = runSuppressionFailureTest(in, newByteArrayOutputStreamSupplier());
+ assertEquals(0, suppressed);
+
+ suppressed = runSuppressionFailureTest(in, BROKEN_CLOSE_OUTPUT);
+ assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, suppressed);
+ }
+
+ for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) {
+ int suppressed = runSuppressionFailureTest(newInputStreamSupplier(new byte[10]), out);
+ assertEquals(0, suppressed);
+
+ suppressed = runSuppressionFailureTest(BROKEN_CLOSE_INPUT, out);
+ assertEquals(1, suppressed);
+ }
+
+ for (InputSupplier<InputStream> in : BROKEN_INPUTS) {
+ for (OutputSupplier<OutputStream> out : BROKEN_OUTPUTS) {
+ int suppressed = runSuppressionFailureTest(in, out);
+ assertTrue(suppressed <= 1);
+ }
+ }
+ }
+ }
+
private static int getAndResetRecords(TestLogHandler logHandler) {
int records = logHandler.getStoredLogRecords().size();
logHandler.clear();
@@ -355,6 +427,20 @@ public class ByteStreamsTest extends IoTestCase {
}
}
+ /**
+ * @return the number of exceptions that were suppressed on the expected thrown exception
+ */
+ private static int runSuppressionFailureTest(
+ InputSupplier<? extends InputStream> in, OutputSupplier<OutputStream> out) {
+ try {
+ copy(in, out);
+ fail();
+ } catch (IOException expected) {
+ return CloserTest.getSuppressed(expected).length;
+ }
+ throw new AssertionError(); // can't happen
+ }
+
private static OutputSupplier<OutputStream> newByteArrayOutputStreamSupplier() {
return new OutputSupplier<OutputStream>() {
@Override public OutputStream getOutput() {
@@ -371,7 +457,7 @@ public class ByteStreamsTest extends IoTestCase {
return out;
}
});
- assertTrue(Arrays.equals(expected, out.toByteArray()));
+ assertEquals(expected, out.toByteArray());
}
public void testCopy() throws Exception {
@@ -379,7 +465,7 @@ public class ByteStreamsTest extends IoTestCase {
byte[] expected = newPreFilledByteArray(100);
long num = ByteStreams.copy(new ByteArrayInputStream(expected), out);
assertEquals(100, num);
- assertTrue(Arrays.equals(expected, out.toByteArray()));
+ assertEquals(expected, out.toByteArray());
}
public void testCopyChannel() throws IOException {
@@ -390,7 +476,7 @@ public class ByteStreamsTest extends IoTestCase {
ReadableByteChannel inChannel =
Channels.newChannel(new ByteArrayInputStream(expected));
ByteStreams.copy(inChannel, outChannel);
- assertTrue(Arrays.equals(expected, out.toByteArray()));
+ assertEquals(expected, out.toByteArray());
}
public void testReadFully() throws IOException {
@@ -440,15 +526,15 @@ public class ByteStreamsTest extends IoTestCase {
Arrays.fill(b, (byte) 0);
ByteStreams.readFully(newTestStream(10), b, 0, 0);
- assertTrue(Arrays.equals(new byte[10], b));
+ assertEquals(new byte[10], b);
Arrays.fill(b, (byte) 0);
ByteStreams.readFully(newTestStream(10), b, 0, 10);
- assertTrue(Arrays.equals(newPreFilledByteArray(10), b));
+ assertEquals(newPreFilledByteArray(10), b);
Arrays.fill(b, (byte) 0);
ByteStreams.readFully(newTestStream(10), b, 0, 5);
- assertTrue(Arrays.equals(new byte[]{0, 1, 2, 3, 4, 0, 0, 0, 0, 0}, b));
+ assertEquals(new byte[]{0, 1, 2, 3, 4, 0, 0, 0, 0, 0}, b);
}
public void testSkipFully() throws IOException {
@@ -465,16 +551,15 @@ public class ByteStreamsTest extends IoTestCase {
}
}
- private void skipHelper(long n, int expect, InputStream in)
+ private static void skipHelper(long n, int expect, InputStream in)
throws IOException {
ByteStreams.skipFully(in, n);
assertEquals(expect, in.read());
in.close();
}
- // TODO(user): rename; violates rule that only immutable things can be all caps
- private static final byte[] BYTES = new byte[] {
- 0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10 };
+ private static final byte[] bytes =
+ new byte[] { 0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10 };
public void testNewDataInput_empty() {
byte[] b = new byte[0];
@@ -487,7 +572,7 @@ public class ByteStreamsTest extends IoTestCase {
}
public void testNewDataInput_normal() {
- ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
+ ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
assertEquals(0x12345678, in.readInt());
assertEquals(0x76543210, in.readInt());
try {
@@ -498,15 +583,15 @@ public class ByteStreamsTest extends IoTestCase {
}
public void testNewDataInput_readFully() {
- ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
- byte[] actual = new byte[BYTES.length];
+ ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
+ byte[] actual = new byte[bytes.length];
in.readFully(actual);
- assertEquals(BYTES, actual);
+ assertEquals(bytes, actual);
}
-
+
public void testNewDataInput_readFullyAndThenSome() {
- ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
- byte[] actual = new byte[BYTES.length * 2];
+ ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
+ byte[] actual = new byte[bytes.length * 2];
try {
in.readFully(actual);
fail();
@@ -514,17 +599,17 @@ public class ByteStreamsTest extends IoTestCase {
assertTrue(ex.getCause() instanceof EOFException);
}
}
-
+
public void testNewDataInput_readFullyWithOffset() {
- ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
+ ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
byte[] actual = new byte[4];
in.readFully(actual, 2, 2);
assertEquals(0, actual[0]);
assertEquals(0, actual[1]);
- assertEquals(BYTES[0], actual[2]);
- assertEquals(BYTES[1], actual[3]);
+ assertEquals(bytes[0], actual[2]);
+ assertEquals(bytes[1], actual[3]);
}
-
+
public void testNewDataInput_readLine() {
ByteArrayDataInput in = ByteStreams.newDataInput(
"This is a line\r\nThis too\rand this\nand also this".getBytes(Charsets.UTF_8));
@@ -540,7 +625,7 @@ public class ByteStreamsTest extends IoTestCase {
assertEquals(Float.intBitsToFloat(0x12345678), in.readFloat(), 0.0);
assertEquals(Float.intBitsToFloat(0x76543210), in.readFloat(), 0.0);
}
-
+
public void testNewDataInput_readDouble() {
byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10};
ByteArrayDataInput in = ByteStreams.newDataInput(data);
@@ -562,7 +647,7 @@ public class ByteStreamsTest extends IoTestCase {
assertEquals('e', in.readChar());
assertEquals('d', in.readChar());
}
-
+
public void testNewDataInput_readUnsignedShort() {
byte[] data = {0, 0, 0, 1, (byte) 0xFF, (byte) 0xFF, 0x12, 0x34};
ByteArrayDataInput in = ByteStreams.newDataInput(data);
@@ -571,7 +656,7 @@ public class ByteStreamsTest extends IoTestCase {
assertEquals(65535, in.readUnsignedShort());
assertEquals(0x1234, in.readUnsignedShort());
}
-
+
public void testNewDataInput_readLong() {
byte[] data = {0x12, 0x34, 0x56, 0x78, 0x76, 0x54, 0x32, 0x10};
ByteArrayDataInput in = ByteStreams.newDataInput(data);
@@ -579,14 +664,14 @@ public class ByteStreamsTest extends IoTestCase {
}
public void testNewDataInput_readBoolean() {
- ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
+ ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
assertTrue(in.readBoolean());
}
-
+
public void testNewDataInput_readByte() {
- ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
- for (int i = 0; i < BYTES.length; i++) {
- assertEquals(BYTES[i], in.readByte());
+ ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
+ for (int i = 0; i < bytes.length; i++) {
+ assertEquals(bytes[i], in.readByte());
}
try {
in.readByte();
@@ -595,11 +680,11 @@ public class ByteStreamsTest extends IoTestCase {
assertTrue(ex.getCause() instanceof EOFException);
}
}
-
+
public void testNewDataInput_readUnsignedByte() {
- ByteArrayDataInput in = ByteStreams.newDataInput(BYTES);
- for (int i = 0; i < BYTES.length; i++) {
- assertEquals(BYTES[i], in.readUnsignedByte());
+ ByteArrayDataInput in = ByteStreams.newDataInput(bytes);
+ for (int i = 0; i < bytes.length; i++) {
+ assertEquals(bytes[i], in.readUnsignedByte());
}
try {
in.readUnsignedByte();
@@ -610,7 +695,7 @@ public class ByteStreamsTest extends IoTestCase {
}
public void testNewDataInput_offset() {
- ByteArrayDataInput in = ByteStreams.newDataInput(BYTES, 2);
+ ByteArrayDataInput in = ByteStreams.newDataInput(bytes, 2);
assertEquals(0x56787654, in.readInt());
try {
in.readInt();
@@ -637,39 +722,39 @@ public class ByteStreamsTest extends IoTestCase {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeInt(0x12345678);
out.writeInt(0x76543210);
- assertTrue(Arrays.equals(BYTES, out.toByteArray()));
+ assertEquals(bytes, out.toByteArray());
}
public void testNewDataOutput_sized() {
ByteArrayDataOutput out = ByteStreams.newDataOutput(4);
out.writeInt(0x12345678);
out.writeInt(0x76543210);
- assertTrue(Arrays.equals(BYTES, out.toByteArray()));
+ assertEquals(bytes, out.toByteArray());
}
public void testNewDataOutput_writeLong() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeLong(0x1234567876543210L);
- assertTrue(Arrays.equals(BYTES, out.toByteArray()));
+ assertEquals(bytes, out.toByteArray());
}
public void testNewDataOutput_writeByteArray() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
- out.write(BYTES);
- assertTrue(Arrays.equals(BYTES, out.toByteArray()));
+ out.write(bytes);
+ assertEquals(bytes, out.toByteArray());
}
public void testNewDataOutput_writeByte() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.write(0x12);
out.writeByte(0x34);
- assertTrue(Arrays.equals(new byte[] {0x12, 0x34}, out.toByteArray()));
+ assertEquals(new byte[] {0x12, 0x34}, out.toByteArray());
}
public void testNewDataOutput_writeByteOffset() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
- out.write(BYTES, 4, 2);
- byte[] expected = {BYTES[4], BYTES[5]};
+ out.write(bytes, 4, 2);
+ byte[] expected = {bytes[4], bytes[5]};
assertEquals(expected, out.toByteArray());
}
@@ -684,7 +769,7 @@ public class ByteStreamsTest extends IoTestCase {
public void testNewDataOutput_writeChar() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeChar('a');
- assertTrue(Arrays.equals(new byte[] {0, 97}, out.toByteArray()));
+ assertEquals(new byte[] {0, 97}, out.toByteArray());
}
public void testNewDataOutput_writeChars() {
@@ -709,20 +794,51 @@ public class ByteStreamsTest extends IoTestCase {
public void testNewDataOutput_writeShort() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeShort(0x1234);
- assertTrue(Arrays.equals(new byte[] {0x12, 0x34}, out.toByteArray()));
+ assertEquals(new byte[] {0x12, 0x34}, out.toByteArray());
}
public void testNewDataOutput_writeDouble() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeDouble(Double.longBitsToDouble(0x1234567876543210L));
- assertEquals(BYTES, out.toByteArray());
+ assertEquals(bytes, out.toByteArray());
}
-
+
public void testNewDataOutput_writeFloat() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeFloat(Float.intBitsToFloat(0x12345678));
out.writeFloat(Float.intBitsToFloat(0x76543210));
- assertEquals(BYTES, out.toByteArray());
+ assertEquals(bytes, out.toByteArray());
+ }
+
+ public void testChecksum() throws IOException {
+ InputSupplier<ByteArrayInputStream> asciiBytes =
+ ByteStreams.newInputStreamSupplier(ASCII.getBytes(Charsets.US_ASCII));
+ InputSupplier<ByteArrayInputStream> i18nBytes =
+ ByteStreams.newInputStreamSupplier(I18N.getBytes(Charsets.UTF_8));
+
+ Checksum checksum = new CRC32();
+ assertEquals(0L, checksum.getValue());
+ assertEquals(3145994718L, ByteStreams.getChecksum(asciiBytes, checksum));
+ assertEquals(0L, checksum.getValue());
+ assertEquals(3145994718L, ByteStreams.getChecksum(asciiBytes, checksum));
+ assertEquals(1138302340L, ByteStreams.getChecksum(i18nBytes, checksum));
+ assertEquals(0L, checksum.getValue());
+ }
+
+ public void testHash() throws IOException {
+ InputSupplier<ByteArrayInputStream> asciiBytes =
+ ByteStreams.newInputStreamSupplier(ASCII.getBytes(Charsets.US_ASCII));
+ InputSupplier<ByteArrayInputStream> i18nBytes =
+ ByteStreams.newInputStreamSupplier(I18N.getBytes(Charsets.UTF_8));
+
+ String init = "d41d8cd98f00b204e9800998ecf8427e";
+ assertEquals(init, Hashing.md5().newHasher().hash().toString());
+
+ String asciiHash = "e5df5a39f2b8cb71b24e1d8038f93131";
+ assertEquals(asciiHash, ByteStreams.hash(asciiBytes, Hashing.md5()).toString());
+
+ String i18nHash = "7fa826962ce2079c8334cd4ebf33aea4";
+ assertEquals(i18nHash, ByteStreams.hash(i18nBytes, Hashing.md5()).toString());
}
public void testLength() throws IOException {
@@ -735,7 +851,7 @@ public class ByteStreamsTest extends IoTestCase {
ByteStreams.newInputStreamSupplier(new byte[0])));
}
- private void lengthHelper(final long skipLimit) throws IOException {
+ private static void lengthHelper(final long skipLimit) throws IOException {
assertEquals(100, ByteStreams.length(new InputSupplier<InputStream>() {
@Override
public InputStream getInput() {
@@ -795,9 +911,9 @@ public class ByteStreamsTest extends IoTestCase {
Math.max(0, Math.min(input, offset + length) - offset));
InputSupplier<? extends InputStream> supplier
= ByteStreams.newInputStreamSupplier(newPreFilledByteArray(input));
- assertTrue(Arrays.equals(
+ assertEquals(
newPreFilledByteArray(offset, expectRead),
- ByteStreams.toByteArray(ByteStreams.slice(supplier, offset, length))));
+ ByteStreams.toByteArray(ByteStreams.slice(supplier, offset, length)));
}
private static InputStream newTestStream(int n) {
@@ -848,6 +964,35 @@ public class ByteStreamsTest extends IoTestCase {
}
}
+ public void testReadBytes() throws IOException {
+ final byte[] array = newPreFilledByteArray(1000);
+ assertEquals(array, ByteStreams.readBytes(
+ new ByteArrayInputStream(array), new TestByteProcessor()));
+ assertEquals(array, ByteStreams.readBytes(
+ new InputSupplier<InputStream>() {
+ @Override
+ public InputStream getInput() {
+ return new ByteArrayInputStream(array);
+ }
+ }, new TestByteProcessor()));
+ }
+
+ private class TestByteProcessor implements ByteProcessor<byte[]> {
+ private final ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ @Override
+ public boolean processBytes(byte[] buf, int off, int len)
+ throws IOException {
+ out.write(buf, off, len);
+ return true;
+ }
+
+ @Override
+ public byte[] getResult() {
+ return out.toByteArray();
+ }
+ }
+
public void testByteProcessorStopEarly() throws IOException {
byte[] array = newPreFilledByteArray(6000);
assertEquals((Integer) 42,
@@ -855,9 +1000,9 @@ public class ByteStreamsTest extends IoTestCase {
new ByteProcessor<Integer>() {
@Override
public boolean processBytes(byte[] buf, int off, int len) {
- assertTrue(Arrays.equals(
+ assertEquals(
copyOfRange(buf, off, off + len),
- newPreFilledByteArray(4096)));
+ newPreFilledByteArray(4096));
return false;
}
@@ -868,6 +1013,123 @@ public class ByteStreamsTest extends IoTestCase {
}));
}
+ public void testNullOutputStream() throws Exception {
+ // create a null output stream
+ OutputStream nos = ByteStreams.nullOutputStream();
+ // write to the output stream
+ nos.write('n');
+ String test = "Test string for NullOutputStream";
+ nos.write(test.getBytes());
+ nos.write(test.getBytes(), 2, 10);
+ // nothing really to assert?
+ assertSame(ByteStreams.nullOutputStream(), ByteStreams.nullOutputStream());
+ }
+
+ public void testLimit() throws Exception {
+ byte[] big = newPreFilledByteArray(5);
+ InputStream bin = new ByteArrayInputStream(big);
+ InputStream lin = ByteStreams.limit(bin, 2);
+
+ // also test available
+ lin.mark(2);
+ assertEquals(2, lin.available());
+ int read = lin.read();
+ assertEquals(big[0], read);
+ assertEquals(1, lin.available());
+ read = lin.read();
+ assertEquals(big[1], read);
+ assertEquals(0, lin.available());
+ read = lin.read();
+ assertEquals(-1, read);
+
+ lin.reset();
+ byte[] small = new byte[5];
+ read = lin.read(small);
+ assertEquals(2, read);
+ assertEquals(big[0], small[0]);
+ assertEquals(big[1], small[1]);
+
+ lin.reset();
+ read = lin.read(small, 2, 3);
+ assertEquals(2, read);
+ assertEquals(big[0], small[2]);
+ assertEquals(big[1], small[3]);
+ }
+
+ public void testLimit_mark() throws Exception {
+ byte[] big = newPreFilledByteArray(5);
+ InputStream bin = new ByteArrayInputStream(big);
+ InputStream lin = ByteStreams.limit(bin, 2);
+
+ int read = lin.read();
+ assertEquals(big[0], read);
+ lin.mark(2);
+
+ read = lin.read();
+ assertEquals(big[1], read);
+ read = lin.read();
+ assertEquals(-1, read);
+
+ lin.reset();
+ read = lin.read();
+ assertEquals(big[1], read);
+ read = lin.read();
+ assertEquals(-1, read);
+ }
+
+ public void testLimit_skip() throws Exception {
+ byte[] big = newPreFilledByteArray(5);
+ InputStream bin = new ByteArrayInputStream(big);
+ InputStream lin = ByteStreams.limit(bin, 2);
+
+ // also test available
+ lin.mark(2);
+ assertEquals(2, lin.available());
+ lin.skip(1);
+ assertEquals(1, lin.available());
+
+ lin.reset();
+ assertEquals(2, lin.available());
+ lin.skip(3);
+ assertEquals(0, lin.available());
+ }
+
+ public void testLimit_markNotSet() {
+ byte[] big = newPreFilledByteArray(5);
+ InputStream bin = new ByteArrayInputStream(big);
+ InputStream lin = ByteStreams.limit(bin, 2);
+
+ try {
+ lin.reset();
+ fail();
+ } catch (IOException expected) {
+ assertEquals("Mark not set", expected.getMessage());
+ }
+ }
+
+ public void testLimit_markNotSupported() {
+ InputStream lin = ByteStreams.limit(new UnmarkableInputStream(), 2);
+
+ try {
+ lin.reset();
+ fail();
+ } catch (IOException expected) {
+ assertEquals("Mark not supported", expected.getMessage());
+ }
+ }
+
+ private static class UnmarkableInputStream extends InputStream {
+ @Override
+ public int read() throws IOException {
+ return 0;
+ }
+
+ @Override
+ public boolean markSupported() {
+ return false;
+ }
+ }
+
private static byte[] copyOfRange(byte[] in, int from, int to) {
byte[] out = new byte[to - from];
for (int i = 0; i < to - from; i++) {
@@ -877,6 +1139,6 @@ public class ByteStreamsTest extends IoTestCase {
}
private static void assertEquals(byte[] expected, byte[] actual) {
- assertEquals(Bytes.asList(expected), Bytes.asList(actual));
+ assertTrue(Arrays.equals(expected, actual));
}
}
diff --git a/guava-tests/test/com/google/common/io/CharSinkTest.java b/guava-tests/test/com/google/common/io/CharSinkTest.java
new file mode 100644
index 0000000..9fd88d3
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/CharSinkTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.io.TestOption.CLOSE_THROWS;
+import static com.google.common.io.TestOption.OPEN_THROWS;
+import static com.google.common.io.TestOption.READ_THROWS;
+import static com.google.common.io.TestOption.WRITE_THROWS;
+
+import com.google.common.collect.ImmutableList;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.EnumSet;
+
+/**
+ * Tests for the default implementations of {@code CharSink} methods.
+ *
+ * @author Colin Decker
+ */
+public class CharSinkTest extends IoTestCase {
+
+ private static final String STRING = ASCII + I18N;
+
+ private TestCharSink sink;
+
+ @Override
+ public void setUp() {
+ sink = new TestCharSink();
+ }
+
+ public void testOpenBufferedStream() throws IOException {
+ BufferedWriter writer = sink.openBufferedStream();
+ assertTrue(sink.wasStreamOpened());
+ assertFalse(sink.wasStreamClosed());
+
+ writer.write(STRING);
+ writer.close();
+
+ assertTrue(sink.wasStreamClosed());
+ assertEquals(STRING, sink.getString());
+ }
+
+ public void testWrite_string() throws IOException {
+ assertEquals("", sink.getString());
+ sink.write(STRING);
+
+ assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
+ assertEquals(STRING, sink.getString());
+ }
+
+ public void testWriteFrom_reader() throws IOException {
+ StringReader reader = new StringReader(STRING);
+ sink.writeFrom(reader);
+
+ assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
+ assertEquals(STRING, sink.getString());
+ }
+
+ public void testWriteFromStream_doesNotCloseThatStream() throws IOException {
+ TestReader in = new TestReader();
+ assertFalse(in.closed());
+ sink.writeFrom(in);
+ assertFalse(in.closed());
+ }
+
+ public void testWriteLines_withSpecificSeparator() throws IOException {
+ sink.writeLines(ImmutableList.of("foo", "bar", "baz"), "\n");
+ assertEquals("foo\nbar\nbaz\n", sink.getString());
+ }
+
+ public void testWriteLines_withDefaultSeparator() throws IOException {
+ sink.writeLines(ImmutableList.of("foo", "bar", "baz"));
+ String separator = System.getProperty("line.separator");
+ assertEquals("foo" + separator + "bar" + separator + "baz" + separator, sink.getString());
+ }
+
+ public void testClosesOnErrors_copyingFromCharSourceThatThrows() {
+ for (TestOption option : EnumSet.of(OPEN_THROWS, READ_THROWS, CLOSE_THROWS)) {
+ TestCharSource failSource = new TestCharSource(STRING, option);
+ TestCharSink okSink = new TestCharSink();
+ try {
+ failSource.copyTo(okSink);
+ fail();
+ } catch (IOException expected) {
+ }
+ // ensure writer was closed IF it was opened (depends on implementation whether or not it's
+ // opened at all if source.newReader() throws).
+ assertTrue("stream not closed when copying from source with option: " + option,
+ !okSink.wasStreamOpened() || okSink.wasStreamClosed());
+ }
+ }
+
+ public void testClosesOnErrors_whenWriteThrows() {
+ TestCharSink failSink = new TestCharSink(WRITE_THROWS);
+ try {
+ new TestCharSource(STRING).copyTo(failSink);
+ fail();
+ } catch (IOException expected) {
+ }
+ assertTrue(failSink.wasStreamClosed());
+ }
+
+ public void testClosesOnErrors_whenWritingFromReaderThatThrows() {
+ TestCharSink okSink = new TestCharSink();
+ try {
+ okSink.writeFrom(new TestReader(READ_THROWS));
+ fail();
+ } catch (IOException expected) {
+ }
+ assertTrue(okSink.wasStreamClosed());
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/CharSinkTester.java b/guava-tests/test/com/google/common/io/CharSinkTester.java
new file mode 100644
index 0000000..08d7e2c
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/CharSinkTester.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.io.SourceSinkFactory.CharSinkFactory;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+
+import junit.framework.TestSuite;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+/**
+ * A generator of {@code TestSuite} instances for testing {@code CharSink} implementations.
+ * Generates tests of a all methods on a {@code CharSink} given various inputs written to it.
+ *
+ * @author Colin Decker
+ */
+public class CharSinkTester extends SourceSinkTester<CharSink, String, CharSinkFactory> {
+
+ private static final ImmutableList<Method> testMethods
+ = getTestMethods(CharSinkTester.class);
+
+ static TestSuite tests(String name, CharSinkFactory factory) {
+ TestSuite suite = new TestSuite(name);
+ for (Map.Entry<String, String> entry : TEST_STRINGS.entrySet()) {
+ String desc = entry.getKey();
+ TestSuite stringSuite = suiteForString(name, factory, entry.getValue(), desc);
+ suite.addTest(stringSuite);
+ }
+ return suite;
+ }
+
+ static TestSuite suiteForString(String name, CharSinkFactory factory,
+ String string, String desc) {
+ TestSuite stringSuite = new TestSuite(name + " [" + desc + "]");
+ for (final Method method : testMethods) {
+ stringSuite.addTest(new CharSinkTester(factory, string, name, desc, method));
+ }
+ return stringSuite;
+ }
+
+ private final ImmutableList<String> lines;
+ private final ImmutableList<String> expectedLines;
+
+ private CharSink sink;
+
+ public CharSinkTester(CharSinkFactory factory, String string,
+ String suiteName, String caseDesc, Method method) {
+ super(factory, string, suiteName, caseDesc, method);
+ this.lines = getLines(string);
+ this.expectedLines = getLines(expected);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ this.sink = factory.createSink();
+ }
+
+ public void testOpenStream() throws IOException {
+ Writer writer = sink.openStream();
+ try {
+ writer.write(data);
+ } finally {
+ writer.close();
+ }
+
+ assertContainsExpectedString();
+ }
+
+ public void testOpenBufferedStream() throws IOException {
+ BufferedWriter writer = sink.openBufferedStream();
+ try {
+ writer.write(data);
+ } finally {
+ writer.close();
+ }
+
+ assertContainsExpectedString();
+ }
+
+ public void testWrite() throws IOException {
+ sink.write(data);
+
+ assertContainsExpectedString();
+ }
+
+ public void testWriteLines_systemDefaultSeparator() throws IOException {
+ String separator = System.getProperty("line.separator");
+ sink.writeLines(lines);
+
+ assertContainsExpectedLines(separator);
+ }
+
+ public void testWriteLines_specificSeparator() throws IOException {
+ String separator = "\r\n";
+ sink.writeLines(lines, separator);
+
+ assertContainsExpectedLines(separator);
+ }
+
+ private void assertContainsExpectedString() throws IOException {
+ assertEquals(expected, factory.getSinkContents());
+ }
+
+ private void assertContainsExpectedLines(String separator) throws IOException {
+ String expected = expectedLines.isEmpty()
+ ? ""
+ : Joiner.on(separator).join(expectedLines);
+ if (!lines.isEmpty()) {
+ // if we wrote any lines in writeLines(), there will be a trailing newline
+ expected += separator;
+ }
+ assertEquals(expected, factory.getSinkContents());
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/CharSourceTest.java b/guava-tests/test/com/google/common/io/CharSourceTest.java
new file mode 100644
index 0000000..6474d5a
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/CharSourceTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.io.TestOption.CLOSE_THROWS;
+import static com.google.common.io.TestOption.OPEN_THROWS;
+import static com.google.common.io.TestOption.READ_THROWS;
+import static com.google.common.io.TestOption.WRITE_THROWS;
+
+import com.google.common.collect.ImmutableList;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.EnumSet;
+
+/**
+ * Tests for the default implementations of {@code CharSource} methods.
+ *
+ * @author Colin Decker
+ */
+public class CharSourceTest extends IoTestCase {
+
+ private static final String STRING = ASCII + I18N;
+ private static final String LINES = "foo\nbar\r\nbaz\rsomething";
+
+ private TestCharSource source;
+
+ @Override
+ public void setUp() {
+ source = new TestCharSource(STRING);
+ }
+
+ public void testOpenBufferedStream() throws IOException {
+ BufferedReader reader = source.openBufferedStream();
+ assertTrue(source.wasStreamOpened());
+ assertFalse(source.wasStreamClosed());
+
+ StringWriter writer = new StringWriter();
+ char[] buf = new char[64];
+ int read;
+ while ((read = reader.read(buf)) != -1) {
+ writer.write(buf, 0, read);
+ }
+ reader.close();
+ writer.close();
+
+ assertTrue(source.wasStreamClosed());
+ assertEquals(STRING, writer.toString());
+ }
+
+ public void testCopyTo_appendable() throws IOException {
+ StringBuilder builder = new StringBuilder();
+
+ assertEquals(STRING.length(), source.copyTo(builder));
+ assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
+
+ assertEquals(STRING, builder.toString());
+ }
+
+ public void testCopyTo_charSink() throws IOException {
+ TestCharSink sink = new TestCharSink();
+
+ assertFalse(sink.wasStreamOpened() || sink.wasStreamClosed());
+
+ assertEquals(STRING.length(), source.copyTo(sink));
+ assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
+ assertTrue(sink.wasStreamOpened() && sink.wasStreamClosed());
+
+ assertEquals(STRING, sink.getString());
+ }
+
+ public void testRead_toString() throws IOException {
+ assertEquals(STRING, source.read());
+ assertTrue(source.wasStreamOpened() && source.wasStreamClosed());
+ }
+
+ public void testReadFirstLine() throws IOException {
+ TestCharSource lines = new TestCharSource(LINES);
+ assertEquals("foo", lines.readFirstLine());
+ assertTrue(lines.wasStreamOpened() && lines.wasStreamClosed());
+ }
+
+ public void testReadLines_toList() throws IOException {
+ TestCharSource lines = new TestCharSource(LINES);
+ assertEquals(ImmutableList.of("foo", "bar", "baz", "something"), lines.readLines());
+ assertTrue(lines.wasStreamOpened() && lines.wasStreamClosed());
+ }
+
+ public void testCopyToAppendable_doesNotCloseIfWriter() throws IOException {
+ TestWriter writer = new TestWriter();
+ assertFalse(writer.closed());
+ source.copyTo(writer);
+ assertFalse(writer.closed());
+ }
+
+ public void testClosesOnErrors_copyingToCharSinkThatThrows() {
+ for (TestOption option : EnumSet.of(OPEN_THROWS, WRITE_THROWS, CLOSE_THROWS)) {
+ TestCharSource okSource = new TestCharSource(STRING);
+ try {
+ okSource.copyTo(new TestCharSink(option));
+ fail();
+ } catch (IOException expected) {
+ }
+ // ensure reader was closed IF it was opened (depends on implementation whether or not it's
+ // opened at all if sink.newWriter() throws).
+ assertTrue("stream not closed when copying to sink with option: " + option,
+ !okSource.wasStreamOpened() || okSource.wasStreamClosed());
+ }
+ }
+
+ public void testClosesOnErrors_whenReadThrows() {
+ TestCharSource failSource = new TestCharSource(STRING, READ_THROWS);
+ try {
+ failSource.copyTo(new TestCharSink());
+ fail();
+ } catch (IOException expected) {
+ }
+ assertTrue(failSource.wasStreamClosed());
+ }
+
+ public void testClosesOnErrors_copyingToWriterThatThrows() {
+ TestCharSource okSource = new TestCharSource(STRING);
+ try {
+ okSource.copyTo(new TestWriter(WRITE_THROWS));
+ fail();
+ } catch (IOException expected) {
+ }
+ assertTrue(okSource.wasStreamClosed());
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/CharSourceTester.java b/guava-tests/test/com/google/common/io/CharSourceTester.java
new file mode 100644
index 0000000..b0d6eed
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/CharSourceTester.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.io.SourceSinkFactory.CharSourceFactory;
+
+import com.google.common.collect.ImmutableList;
+
+import junit.framework.TestSuite;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A generator of {@code TestSuite} instances for testing {@code CharSource} implementations.
+ * Generates tests of a all methods on a {@code CharSource} given various inputs the source is
+ * expected to contain.
+ *
+ * @author Colin Decker
+ */
+public class CharSourceTester extends SourceSinkTester<CharSource, String, CharSourceFactory> {
+
+ private static final ImmutableList<Method> testMethods
+ = getTestMethods(CharSourceTester.class);
+
+ static TestSuite tests(String name, CharSourceFactory factory) {
+ TestSuite suite = new TestSuite(name);
+ for (Map.Entry<String, String> entry : TEST_STRINGS.entrySet()) {
+ suite.addTest(suiteForString(factory, entry.getValue(), name, entry.getKey()));
+ }
+ return suite;
+ }
+
+ static TestSuite suiteForString(CharSourceFactory factory, String string,
+ String name, String desc) {
+ TestSuite suite = new TestSuite(name + " [" + desc + "]");
+ for (Method method : testMethods) {
+ suite.addTest(new CharSourceTester(factory, string, name, desc, method));
+ }
+ return suite;
+ }
+
+ private final ImmutableList<String> expectedLines;
+
+ private CharSource source;
+
+ public CharSourceTester(CharSourceFactory factory, String string,
+ String suiteName, String caseDesc, Method method) {
+ super(factory, string, suiteName, caseDesc, method);
+ this.expectedLines = getLines(expected);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ this.source = factory.createSource(data);
+ }
+
+ public void testOpenStream() throws IOException {
+ Reader reader = source.openStream();
+
+ StringWriter writer = new StringWriter();
+ char[] buf = new char[64];
+ int read;
+ while ((read = reader.read(buf)) != -1) {
+ writer.write(buf, 0, read);
+ }
+ reader.close();
+ writer.close();
+
+ assertExpectedString(writer.toString());
+ }
+
+ public void testOpenBufferedStream() throws IOException {
+ BufferedReader reader = source.openBufferedStream();
+
+ StringWriter writer = new StringWriter();
+ char[] buf = new char[64];
+ int read;
+ while ((read = reader.read(buf)) != -1) {
+ writer.write(buf, 0, read);
+ }
+ reader.close();
+ writer.close();
+
+ assertExpectedString(writer.toString());
+ }
+
+ public void testCopyTo_appendable() throws IOException {
+ StringBuilder builder = new StringBuilder();
+
+ assertEquals(expected.length(), source.copyTo(builder));
+
+ assertExpectedString(builder.toString());
+ }
+
+ public void testCopyTo_charSink() throws IOException {
+ TestCharSink sink = new TestCharSink();
+
+ assertEquals(expected.length(), source.copyTo(sink));
+
+ assertExpectedString(sink.getString());
+ }
+
+ public void testRead_toString() throws IOException {
+ String string = source.read();
+ assertExpectedString(string);
+ }
+
+ public void testReadFirstLine() throws IOException {
+ if (expectedLines.isEmpty()) {
+ assertNull(source.readFirstLine());
+ } else {
+ assertEquals(expectedLines.get(0), source.readFirstLine());
+ }
+ }
+
+ public void testReadLines_toList() throws IOException {
+ assertExpectedLines(source.readLines());
+ }
+
+ private void assertExpectedString(String string) {
+ assertEquals(expected, string);
+ }
+
+ private void assertExpectedLines(List<String> list) {
+ assertEquals(expectedLines, list);
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/CharStreamsTest.java b/guava-tests/test/com/google/common/io/CharStreamsTest.java
index c628afb..f0c84a2 100644
--- a/guava-tests/test/com/google/common/io/CharStreamsTest.java
+++ b/guava-tests/test/com/google/common/io/CharStreamsTest.java
@@ -21,10 +21,13 @@ import static com.google.common.io.CharStreams.copy;
import static com.google.common.io.CharStreams.newReaderSupplier;
import com.google.common.base.Charsets;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.testing.TestLogHandler;
+import junit.framework.TestSuite;
+
import java.io.ByteArrayInputStream;
import java.io.EOFException;
import java.io.FilterReader;
@@ -43,6 +46,15 @@ import java.util.List;
* @author Chris Nokleberg
*/
public class CharStreamsTest extends IoTestCase {
+
+ public static TestSuite suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(CharSourceTester.tests("CharStreams.asCharSource[String]",
+ SourceSinkFactories.stringCharSourceFactory()));
+ suite.addTestSuite(CharStreamsTest.class);
+ return suite;
+ }
+
private static final String TEXT
= "The quick brown fox jumped over the lazy dog.";
@@ -80,18 +92,18 @@ public class CharStreamsTest extends IoTestCase {
CharStreams.skipFully(reader, 6);
assertEquals(-1, reader.read());
}
-
+
private static class NonSkippingReader extends StringReader {
NonSkippingReader(String s) {
super(s);
}
-
+
@Override
public long skip(long n) {
return 0;
}
}
-
+
public void testReadLines_fromReadable() throws IOException {
byte[] bytes = "a\nb\nc".getBytes(Charsets.UTF_8.name());
List<String> lines = CharStreams.readLines(
@@ -218,6 +230,66 @@ public class CharStreamsTest extends IoTestCase {
assertTrue(brokenWrite.areClosed());
}
+ public void testCopySuppliersExceptions() {
+ if (!Closer.SuppressingSuppressor.isAvailable()) {
+ // test that exceptions are logged
+
+ TestLogHandler logHandler = new TestLogHandler();
+ Closeables.logger.addHandler(logHandler);
+ try {
+ for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) {
+ runFailureTest(in, newStringWriterSupplier());
+ assertTrue(logHandler.getStoredLogRecords().isEmpty());
+
+ runFailureTest(in, BROKEN_CLOSE_OUTPUT);
+ assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, getAndResetRecords(logHandler));
+ }
+
+ for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) {
+ runFailureTest(newReaderSupplier("ABC"), out);
+ assertTrue(logHandler.getStoredLogRecords().isEmpty());
+
+ runFailureTest(BROKEN_CLOSE_INPUT, out);
+ assertEquals(1, getAndResetRecords(logHandler));
+ }
+
+ for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) {
+ for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) {
+ runFailureTest(in, out);
+ assertTrue(getAndResetRecords(logHandler) <= 1);
+ }
+ }
+ } finally {
+ Closeables.logger.removeHandler(logHandler);
+ }
+ } else {
+ // test that exceptions are suppressed
+
+ for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) {
+ int suppressed = runSuppressionFailureTest(in, newStringWriterSupplier());
+ assertEquals(0, suppressed);
+
+ suppressed = runSuppressionFailureTest(in, BROKEN_CLOSE_OUTPUT);
+ assertEquals((in == BROKEN_GET_INPUT) ? 0 : 1, suppressed);
+ }
+
+ for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) {
+ int suppressed = runSuppressionFailureTest(newReaderSupplier("ABC"), out);
+ assertEquals(0, suppressed);
+
+ suppressed = runSuppressionFailureTest(BROKEN_CLOSE_INPUT, out);
+ assertEquals(1, suppressed);
+ }
+
+ for (InputSupplier<? extends Reader> in : BROKEN_INPUTS) {
+ for (OutputSupplier<? extends Writer> out : BROKEN_OUTPUTS) {
+ int suppressed = runSuppressionFailureTest(in, out);
+ assertTrue(suppressed <= 1);
+ }
+ }
+ }
+ }
+
private static int getAndResetRecords(TestLogHandler logHandler) {
int records = logHandler.getStoredLogRecords().size();
logHandler.clear();
@@ -233,6 +305,20 @@ public class CharStreamsTest extends IoTestCase {
}
}
+ /**
+ * @return the number of exceptions that were suppressed on the expected thrown exception
+ */
+ private static int runSuppressionFailureTest(
+ InputSupplier<? extends Reader> in, OutputSupplier<? extends Writer> out) {
+ try {
+ copy(in, out);
+ fail();
+ } catch (IOException expected) {
+ return CloserTest.getSuppressed(expected).length;
+ }
+ throw new AssertionError(); // can't happen
+ }
+
private static OutputSupplier<Writer> newStringWriterSupplier() {
return new OutputSupplier<Writer>() {
@Override public Writer getOutput() {
@@ -288,6 +374,38 @@ public class CharStreamsTest extends IoTestCase {
assertEquals(expected, sw.toString());
}
+ public void testCopy() throws IOException {
+ StringBuilder builder = new StringBuilder();
+ long copied = CharStreams.copy(new StringReader(ASCII), builder);
+ assertEquals(ASCII, builder.toString());
+ assertEquals(ASCII.length(), copied);
+
+ StringBuilder builder2 = new StringBuilder();
+ copied = CharStreams.copy(new StringReader(I18N), builder2);
+ assertEquals(I18N, builder2.toString());
+ assertEquals(I18N.length(), copied);
+ }
+
+ /**
+ * Test for Guava issue 1061: http://code.google.com/p/guava-libraries/issues/detail?id=1061
+ *
+ * <p>CharStreams.copy was failing to clear its CharBuffer after each read call, which effectively
+ * reduced the available size of the buffer each time a call to read didn't fill up the available
+ * space in the buffer completely. In general this is a performance problem since the buffer size
+ * is permanently reduced, but with certain Reader implementations it could also cause the buffer
+ * size to reach 0, causing an infinite loop.
+ */
+ public void testCopyWithReaderThatDoesNotFillBuffer() throws IOException {
+ // need a long enough string for the buffer to hit 0 remaining before the copy completes
+ String string = Strings.repeat("0123456789", 100);
+ StringBuilder b = new StringBuilder();
+ // the main assertion of this test is here... the copy will fail if the buffer size goes down
+ // each time it is not filled completely
+ long copied = CharStreams.copy(newNonBufferFillingReader(new StringReader(string)), b);
+ assertEquals(string, b.toString());
+ assertEquals(string.length(), copied);
+ }
+
private static CheckCloseSupplier.Input<Reader> newCheckReader(
InputSupplier<? extends Reader> delegate) {
return new CheckCloseSupplier.Input<Reader>(delegate) {
@@ -315,4 +433,24 @@ public class CharStreamsTest extends IoTestCase {
}
};
}
+
+ /**
+ * Returns a reader wrapping the given reader that only reads half of the maximum number of
+ * characters that it could read in read(char[], int, int).
+ */
+ private static Reader newNonBufferFillingReader(Reader reader) {
+ return new FilterReader(reader) {
+ @Override
+ public int read(char[] cbuf, int off, int len) throws IOException {
+ // if a buffer isn't being cleared correctly, this method will eventually start being called
+ // with a len of 0 forever
+ if (len <= 0) {
+ fail("read called with a len of " + len);
+ }
+ // read fewer than the max number of chars to read
+ // shouldn't be a problem unless the buffer is shrinking each call
+ return in.read(cbuf, off, Math.max(len - 1024, 0));
+ }
+ };
+ }
}
diff --git a/guava-tests/test/com/google/common/io/CloseablesTest.java b/guava-tests/test/com/google/common/io/CloseablesTest.java
index f75d4dc..3717a54 100644
--- a/guava-tests/test/com/google/common/io/CloseablesTest.java
+++ b/guava-tests/test/com/google/common/io/CloseablesTest.java
@@ -25,14 +25,13 @@ import static org.easymock.EasyMock.verify;
import junit.framework.TestCase;
import java.io.Closeable;
-import java.io.Flushable;
import java.io.IOException;
/**
- * Unit tests for {@link Closeables} and {@link Flushables}.
+ * Unit tests for {@link Closeables}.
*
- * <p>Checks proper closing and flushing behavior, and ensures that
- * IOExceptions on Closeable.close() or Flushable.flush() are not
+ * <p>Checks proper closing behavior, and ensures that
+ * IOExceptions on Closeable.close() are not
* propagated out from the {@link Closeables#close} method if {@code
* swallowException} is true.
*
@@ -40,7 +39,6 @@ import java.io.IOException;
*/
public class CloseablesTest extends TestCase {
private Closeable mockCloseable;
- private Flushable mockFlushable;
public void testClose_closeableClean() throws IOException {
// make sure that no exception is thrown regardless of value of
@@ -69,43 +67,11 @@ public class CloseablesTest extends TestCase {
public void testCloseQuietly_closeableWithEatenException()
throws IOException {
// make sure that no exception is thrown by CloseQuietly when the mock does
- // throw an exception, either on close, on flush, or both.
+ // throw an exception on close
setupCloseable(true);
Closeables.closeQuietly(mockCloseable);
}
- public void testFlush_clean() throws IOException {
- // make sure that no exception is thrown regardless of value of
- // 'swallowException' when the mock does not throw an exception.
- setupFlushable(false);
- doFlush(mockFlushable, false, false);
-
- setupFlushable(false);
- doFlush(mockFlushable, true, false);
- }
-
- public void testFlush_flushableWithEatenException() throws IOException {
- // make sure that no exception is thrown if 'swallowException' is true
- // when the mock does throw an exception on flush.
- setupFlushable(true);
- doFlush(mockFlushable, true, false);
- }
-
- public void testFlush_flushableWithThrownException() throws IOException {
- // make sure that the exception is thrown if 'swallowException' is false
- // when the mock does throw an exception on flush.
- setupFlushable(true);
- doFlush(mockFlushable, false, true);
- }
-
- public void testFlushQuietly_flushableWithEatenException()
- throws IOException {
- // make sure that no exception is thrown by CloseQuietly when the mock does
- // throw an exception on flush.
- setupFlushable(true);
- Flushables.flushQuietly(mockFlushable);
- }
-
public void testCloseNull() throws IOException {
Closeables.close(null, true);
Closeables.close(null, false);
@@ -114,7 +80,6 @@ public class CloseablesTest extends TestCase {
@Override protected void setUp() throws Exception {
mockCloseable = createStrictMock(Closeable.class);
- mockFlushable = createStrictMock(Flushable.class);
}
private void expectThrown() {
@@ -133,17 +98,6 @@ public class CloseablesTest extends TestCase {
replay(mockCloseable);
}
- // Set up a flushable to expect to be flushed and closed, and optionally to
- // throw an exception.
- private void setupFlushable(boolean shouldThrowOnFlush) throws IOException {
- reset(mockFlushable);
- mockFlushable.flush();
- if (shouldThrowOnFlush) {
- expectThrown();
- }
- replay(mockFlushable);
- }
-
private void doClose(Closeable closeable, boolean swallowException) {
doClose(closeable, swallowException, !swallowException);
}
@@ -165,22 +119,4 @@ public class CloseablesTest extends TestCase {
}
verify(closeable);
}
-
- // Flush the flushable using the Flushables, passing in the swallowException
- // parameter. expectThrown determines whether we expect an exception to
- // be thrown by Flushables.flush;
- private void doFlush(Flushable flushable, boolean swallowException,
- boolean expectThrown) {
- try {
- Flushables.flush(flushable, swallowException);
- if (expectThrown) {
- fail("Didn't throw exception.");
- }
- } catch (IOException e) {
- if (!expectThrown) {
- fail("Threw exception");
- }
- }
- verify(flushable);
- }
}
diff --git a/guava-tests/test/com/google/common/io/CloserTest.java b/guava-tests/test/com/google/common/io/CloserTest.java
new file mode 100644
index 0000000..e5e8326
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/CloserTest.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Splitter;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.testing.TestLogHandler;
+
+import junit.framework.TestCase;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.logging.LogRecord;
+
+import javax.annotation.Nullable;
+
+/**
+ * Tests for {@link Closer}.
+ *
+ * @author Colin Decker
+ */
+public class CloserTest extends TestCase {
+
+ private TestSuppressor suppressor;
+
+ @Override
+ protected void setUp() throws Exception {
+ suppressor = new TestSuppressor();
+ }
+
+ public void testCreate() {
+ Closer closer = Closer.create();
+ String javaVersion = System.getProperty("java.version");
+ String secondPart = Iterables.get(Splitter.on('.').split(javaVersion), 1);
+ int versionNumber = Integer.parseInt(secondPart);
+ if (versionNumber < 7) {
+ assertTrue(closer.suppressor instanceof Closer.LoggingSuppressor);
+ } else {
+ assertTrue(closer.suppressor instanceof Closer.SuppressingSuppressor);
+ }
+ }
+
+ public void testNoExceptionsThrown() throws IOException {
+ Closer closer = new Closer(suppressor);
+
+ TestCloseable c1 = closer.register(TestCloseable.normal());
+ TestCloseable c2 = closer.register(TestCloseable.normal());
+ TestCloseable c3 = closer.register(TestCloseable.normal());
+
+ assertFalse(c1.isClosed());
+ assertFalse(c2.isClosed());
+ assertFalse(c3.isClosed());
+
+ closer.close();
+
+ assertTrue(c1.isClosed());
+ assertTrue(c2.isClosed());
+ assertTrue(c3.isClosed());
+
+ assertTrue(suppressor.suppressions.isEmpty());
+ }
+
+ public void testExceptionThrown_fromTryBlock() throws IOException {
+ Closer closer = new Closer(suppressor);
+
+ TestCloseable c1 = closer.register(TestCloseable.normal());
+ TestCloseable c2 = closer.register(TestCloseable.normal());
+
+ IOException exception = new IOException();
+
+ try {
+ try {
+ throw exception;
+ } catch (Throwable e) {
+ throw closer.rethrow(e);
+ } finally {
+ closer.close();
+ }
+ } catch (Throwable expected) {
+ assertSame(exception, expected);
+ }
+
+ assertTrue(c1.isClosed());
+ assertTrue(c2.isClosed());
+
+ assertTrue(suppressor.suppressions.isEmpty());
+ }
+
+ public void testExceptionThrown_whenCreatingCloseables() throws IOException {
+ Closer closer = new Closer(suppressor);
+
+ TestCloseable c1 = null;
+ TestCloseable c2 = null;
+ TestCloseable c3 = null;
+ try {
+ try {
+ c1 = closer.register(TestCloseable.normal());
+ c2 = closer.register(TestCloseable.normal());
+ c3 = closer.register(TestCloseable.throwsOnCreate());
+ } catch (Throwable e) {
+ throw closer.rethrow(e);
+ } finally {
+ closer.close();
+ }
+ } catch (Throwable expected) {
+ assertTrue(expected instanceof IOException);
+ }
+
+ assertTrue(c1.isClosed());
+ assertTrue(c2.isClosed());
+ assertNull(c3);
+
+ assertTrue(suppressor.suppressions.isEmpty());
+ }
+
+ public void testExceptionThrown_whileClosingLastCloseable() throws IOException {
+ Closer closer = new Closer(suppressor);
+
+ IOException exception = new IOException();
+
+ // c1 is added first, closed last
+ TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(exception));
+ TestCloseable c2 = closer.register(TestCloseable.normal());
+
+ try {
+ closer.close();
+ } catch (Throwable expected) {
+ assertSame(exception, expected);
+ }
+
+ assertTrue(c1.isClosed());
+ assertTrue(c2.isClosed());
+
+ assertTrue(suppressor.suppressions.isEmpty());
+ }
+
+ public void testExceptionThrown_whileClosingFirstCloseable() throws IOException {
+ Closer closer = new Closer(suppressor);
+
+ IOException exception = new IOException();
+
+ // c2 is added last, closed first
+ TestCloseable c1 = closer.register(TestCloseable.normal());
+ TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(exception));
+
+ try {
+ closer.close();
+ } catch (Throwable expected) {
+ assertSame(exception, expected);
+ }
+
+ assertTrue(c1.isClosed());
+ assertTrue(c2.isClosed());
+
+ assertTrue(suppressor.suppressions.isEmpty());
+ }
+
+ public void testCloseExceptionsSuppressed_whenExceptionThrownFromTryBlock() throws IOException {
+ Closer closer = new Closer(suppressor);
+
+ IOException tryException = new IOException();
+ IOException c1Exception = new IOException();
+ IOException c2Exception = new IOException();
+
+ TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(c1Exception));
+ TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(c2Exception));
+
+ try {
+ try {
+ throw tryException;
+ } catch (Throwable e) {
+ throw closer.rethrow(e);
+ } finally {
+ closer.close();
+ }
+ } catch (Throwable expected) {
+ assertSame(tryException, expected);
+ }
+
+ assertTrue(c1.isClosed());
+ assertTrue(c2.isClosed());
+
+ assertSuppressed(
+ new Suppression(c2, tryException, c2Exception),
+ new Suppression(c1, tryException, c1Exception));
+ }
+
+ public void testCloseExceptionsSuppressed_whenExceptionThrownClosingFirstCloseable()
+ throws IOException {
+ Closer closer = new Closer(suppressor);
+
+ IOException c1Exception = new IOException();
+ IOException c2Exception = new IOException();
+ IOException c3Exception = new IOException();
+
+ TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(c1Exception));
+ TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(c2Exception));
+ TestCloseable c3 = closer.register(TestCloseable.throwsOnClose(c3Exception));
+
+ try {
+ closer.close();
+ } catch (Throwable expected) {
+ assertSame(c3Exception, expected);
+ }
+
+ assertTrue(c1.isClosed());
+ assertTrue(c2.isClosed());
+ assertTrue(c3.isClosed());
+
+ assertSuppressed(
+ new Suppression(c2, c3Exception, c2Exception),
+ new Suppression(c1, c3Exception, c1Exception));
+ }
+
+ public void testRuntimeExceptions() throws IOException {
+ Closer closer = new Closer(suppressor);
+
+ RuntimeException tryException = new RuntimeException();
+ RuntimeException c1Exception = new RuntimeException();
+ RuntimeException c2Exception = new RuntimeException();
+
+ TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(c1Exception));
+ TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(c2Exception));
+
+ try {
+ try {
+ throw tryException;
+ } catch (Throwable e) {
+ throw closer.rethrow(e);
+ } finally {
+ closer.close();
+ }
+ } catch (Throwable expected) {
+ assertSame(tryException, expected);
+ }
+
+ assertTrue(c1.isClosed());
+ assertTrue(c2.isClosed());
+
+ assertSuppressed(
+ new Suppression(c2, tryException, c2Exception),
+ new Suppression(c1, tryException, c1Exception));
+ }
+
+ public void testErrors() throws IOException {
+ Closer closer = new Closer(suppressor);
+
+ Error c1Exception = new Error();
+ Error c2Exception = new Error();
+ Error c3Exception = new Error();
+
+ TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(c1Exception));
+ TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(c2Exception));
+ TestCloseable c3 = closer.register(TestCloseable.throwsOnClose(c3Exception));
+
+ try {
+ closer.close();
+ } catch (Throwable expected) {
+ assertSame(c3Exception, expected);
+ }
+
+ assertTrue(c1.isClosed());
+ assertTrue(c2.isClosed());
+ assertTrue(c3.isClosed());
+
+ assertSuppressed(
+ new Suppression(c2, c3Exception, c2Exception),
+ new Suppression(c1, c3Exception, c1Exception));
+ }
+
+ public static void testLoggingSuppressor() throws IOException {
+ TestLogHandler logHandler = new TestLogHandler();
+
+ Closeables.logger.addHandler(logHandler);
+ try {
+ Closer closer = new Closer(new Closer.LoggingSuppressor());
+
+ TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(new IOException()));
+ TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(new RuntimeException()));
+ try {
+ throw closer.rethrow(new IOException("thrown"), IOException.class);
+ } catch (IOException expected) {}
+
+ assertTrue(logHandler.getStoredLogRecords().isEmpty());
+
+ closer.close();
+
+ assertEquals(2, logHandler.getStoredLogRecords().size());
+
+ LogRecord record = logHandler.getStoredLogRecords().get(0);
+ assertEquals("Suppressing exception thrown when closing " + c2, record.getMessage());
+
+ record = logHandler.getStoredLogRecords().get(1);
+ assertEquals("Suppressing exception thrown when closing " + c1, record.getMessage());
+ } finally {
+ Closeables.logger.removeHandler(logHandler);
+ }
+ }
+
+ public static void testSuppressingSuppressorIfPossible() throws IOException {
+ // can't test the JDK7 suppressor when not running on JDK7
+ if (!Closer.SuppressingSuppressor.isAvailable()) {
+ return;
+ }
+
+ Closer closer = new Closer(new Closer.SuppressingSuppressor());
+
+ IOException thrownException = new IOException();
+ IOException c1Exception = new IOException();
+ RuntimeException c2Exception = new RuntimeException();
+
+ TestCloseable c1 = closer.register(TestCloseable.throwsOnClose(c1Exception));
+ TestCloseable c2 = closer.register(TestCloseable.throwsOnClose(c2Exception));
+ try {
+ try {
+ throw thrownException;
+ } catch (Throwable e) {
+ throw closer.rethrow(thrownException, IOException.class);
+ } finally {
+ assertEquals(0, getSuppressed(thrownException).length);
+ closer.close();
+ }
+ } catch (IOException expected) {
+ assertSame(thrownException, expected);
+ }
+
+ assertTrue(c1.isClosed());
+ assertTrue(c2.isClosed());
+
+ ImmutableSet<Throwable> suppressed = ImmutableSet.copyOf(getSuppressed(thrownException));
+ assertEquals(2, suppressed.size());
+
+ assertEquals(ImmutableSet.of(c1Exception, c2Exception), suppressed);
+ }
+
+ static Throwable[] getSuppressed(Throwable throwable) {
+ try {
+ Method getSuppressed = Throwable.class.getDeclaredMethod("getSuppressed");
+ return (Throwable[]) getSuppressed.invoke(throwable);
+ } catch (Exception e) {
+ throw new AssertionError(e); // only called if running on JDK7
+ }
+ }
+
+ /**
+ * Asserts that an exception was thrown when trying to close each of the given throwables and that
+ * each such exception was suppressed because of the given thrown exception.
+ */
+ private void assertSuppressed(Suppression... expected) {
+ assertEquals(ImmutableList.copyOf(expected), suppressor.suppressions);
+ }
+
+ /**
+ * Suppressor that records suppressions.
+ */
+ private static class TestSuppressor implements Closer.Suppressor {
+
+ private final List<Suppression> suppressions = Lists.newArrayList();
+
+ @Override
+ public void suppress(Closeable closeable, Throwable thrown, Throwable suppressed) {
+ suppressions.add(new Suppression(closeable, thrown, suppressed));
+ }
+ }
+
+ /**
+ * Record of a call to suppress.
+ */
+ private static class Suppression {
+ private final Closeable closeable;
+ private final Throwable thrown;
+ private final Throwable suppressed;
+
+ private Suppression(Closeable closeable, Throwable thrown, Throwable suppressed) {
+ this.closeable = closeable;
+ this.thrown = thrown;
+ this.suppressed = suppressed;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Suppression) {
+ Suppression other = (Suppression) obj;
+ return closeable.equals(other.closeable)
+ && thrown.equals(other.thrown)
+ && suppressed.equals(other.suppressed);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(closeable, thrown, suppressed);
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this)
+ .add("closeable", closeable)
+ .add("thrown", thrown)
+ .add("suppressed", suppressed)
+ .toString();
+ }
+ }
+
+ private static class TestCloseable implements Closeable {
+
+ private final Throwable throwOnClose;
+ private boolean closed;
+
+ static TestCloseable normal() throws IOException {
+ return new TestCloseable(null);
+ }
+
+ static TestCloseable throwsOnClose(Throwable throwOnClose) throws IOException {
+ return new TestCloseable(throwOnClose);
+ }
+
+ static TestCloseable throwsOnCreate() throws IOException {
+ throw new IOException();
+ }
+
+ private TestCloseable(@Nullable Throwable throwOnClose) {
+ this.throwOnClose = throwOnClose;
+ }
+
+ public boolean isClosed() {
+ return closed;
+ }
+
+ @Override
+ public void close() throws IOException {
+ closed = true;
+ if (throwOnClose != null) {
+ Throwables.propagateIfPossible(throwOnClose, IOException.class);
+ throw new AssertionError(throwOnClose);
+ }
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/FlushablesTest.java b/guava-tests/test/com/google/common/io/FlushablesTest.java
new file mode 100644
index 0000000..34a3155
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/FlushablesTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+
+import junit.framework.TestCase;
+
+import java.io.Flushable;
+import java.io.IOException;
+
+/**
+ * Unit tests for {@link Flushables}.
+ *
+ * <p>Checks proper flushing behavior, and ensures that
+ * IOExceptions on Flushable.flush() are not
+ * propagated out from the {@link Flushables#flush} method if {@code
+ * swallowException} is true.
+ *
+ * @author Michael Lancaster
+ */
+public class FlushablesTest extends TestCase {
+ private Flushable mockFlushable;
+
+ public void testFlush_clean() throws IOException {
+ // make sure that no exception is thrown regardless of value of
+ // 'swallowException' when the mock does not throw an exception.
+ setupFlushable(false);
+ doFlush(mockFlushable, false, false);
+
+ setupFlushable(false);
+ doFlush(mockFlushable, true, false);
+ }
+
+ public void testFlush_flushableWithEatenException() throws IOException {
+ // make sure that no exception is thrown if 'swallowException' is true
+ // when the mock does throw an exception on flush.
+ setupFlushable(true);
+ doFlush(mockFlushable, true, false);
+ }
+
+ public void testFlush_flushableWithThrownException() throws IOException {
+ // make sure that the exception is thrown if 'swallowException' is false
+ // when the mock does throw an exception on flush.
+ setupFlushable(true);
+ doFlush(mockFlushable, false, true);
+ }
+
+ public void testFlushQuietly_flushableWithEatenException()
+ throws IOException {
+ // make sure that no exception is thrown by flushQuietly when the mock does
+ // throw an exception on flush.
+ setupFlushable(true);
+ Flushables.flushQuietly(mockFlushable);
+ }
+
+ @Override protected void setUp() throws Exception {
+ mockFlushable = createStrictMock(Flushable.class);
+ }
+
+ private void expectThrown() {
+ expectLastCall().andThrow(new IOException("This should only appear in the "
+ + "logs. It should not be rethrown."));
+ }
+
+ // Set up a flushable to expect to be flushed, and optionally to
+ // throw an exception.
+ private void setupFlushable(boolean shouldThrowOnFlush) throws IOException {
+ reset(mockFlushable);
+ mockFlushable.flush();
+ if (shouldThrowOnFlush) {
+ expectThrown();
+ }
+ replay(mockFlushable);
+ }
+
+ // Flush the flushable using the Flushables, passing in the swallowException
+ // parameter. expectThrown determines whether we expect an exception to
+ // be thrown by Flushables.flush;
+ private void doFlush(Flushable flushable, boolean swallowException,
+ boolean expectThrown) {
+ try {
+ Flushables.flush(flushable, swallowException);
+ if (expectThrown) {
+ fail("Didn't throw exception.");
+ }
+ } catch (IOException e) {
+ if (!expectThrown) {
+ fail("Threw exception");
+ }
+ }
+ verify(flushable);
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/PackageSanityTests.java b/guava-tests/test/com/google/common/io/PackageSanityTests.java
new file mode 100644
index 0000000..a620b30
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/PackageSanityTests.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import com.google.common.testing.AbstractPackageSanityTests;
+
+import java.lang.reflect.Method;
+
+/**
+ * Basic sanity tests for the entire package.
+ *
+ * @author Ben Yu
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {
+ public PackageSanityTests() {
+ setDefault(BaseEncoding.class, BaseEncoding.base64());
+ setDefault(int.class, 32);
+ setDefault(String.class, "abcd");
+ setDefault(Method.class, AbstractPackageSanityTests.class.getDeclaredMethods()[0]);
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/RandomAmountInputStream.java b/guava-tests/test/com/google/common/io/RandomAmountInputStream.java
index 2ffeea7..0e3ee15 100644
--- a/guava-tests/test/com/google/common/io/RandomAmountInputStream.java
+++ b/guava-tests/test/com/google/common/io/RandomAmountInputStream.java
@@ -16,6 +16,8 @@
package com.google.common.io;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -26,8 +28,8 @@ class RandomAmountInputStream extends FilterInputStream {
private final Random random;
public RandomAmountInputStream(InputStream in, Random random) {
- super(in);
- this.random = random;
+ super(checkNotNull(in));
+ this.random = checkNotNull(random);
}
@Override public int read(byte[] b, int off, int len) throws IOException {
diff --git a/guava-tests/test/com/google/common/io/ResourcesTest.java b/guava-tests/test/com/google/common/io/ResourcesTest.java
index 8aedfa3..47779a8 100644
--- a/guava-tests/test/com/google/common/io/ResourcesTest.java
+++ b/guava-tests/test/com/google/common/io/ResourcesTest.java
@@ -17,10 +17,13 @@
package com.google.common.io;
import static com.google.common.base.CharMatcher.WHITESPACE;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestSuite;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -37,17 +40,19 @@ import java.util.List;
*/
public class ResourcesTest extends IoTestCase {
- public void testUrlSupplier() throws IOException {
- try {
- Resources.newInputStreamSupplier(null);
- fail("expected NPE");
- } catch (NullPointerException expected) {
- // expected
- }
+ public static TestSuite suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTest(ByteSourceTester.tests("Resources.asByteSource[URL]",
+ SourceSinkFactories.urlByteSourceFactory(), true));
+ suite.addTest(CharSourceTester.tests("Resources.asCharSource[URL, Charset]",
+ SourceSinkFactories.urlCharSourceFactory()));
+ suite.addTestSuite(ResourcesTest.class);
+ return suite;
+ }
- URL url = getClass().getResource("/com/google/common/io/Resources.class");
+ public void testUrlSupplier() throws IOException {
byte[] data = ByteStreams.toByteArray(
- Resources.newInputStreamSupplier(url));
+ Resources.newInputStreamSupplier(classfile(Resources.class)));
assertEquals(0xCAFEBABE,
new DataInputStream(new ByteArrayInputStream(data)).readInt());
}
@@ -58,10 +63,9 @@ public class ResourcesTest extends IoTestCase {
ASSERT.that(Resources.toString(resource, Charsets.US_ASCII))
.isNotEqualTo(I18N);
}
-
+
public void testToToByteArray() throws IOException {
- URL url = getClass().getResource("/com/google/common/io/Resources.class");
- byte[] data = Resources.toByteArray(url);
+ byte[] data = Resources.toByteArray(classfile(Resources.class));
assertEquals(0xCAFEBABE,
new DataInputStream(new ByteArrayInputStream(data)).readInt());
}
@@ -102,7 +106,7 @@ public class ResourcesTest extends IoTestCase {
Resources.copy(resource, out);
assertEquals(I18N, out.toString("UTF-8"));
}
-
+
public void testGetResource_notFound() {
try {
Resources.getResource("no such resource");
@@ -111,12 +115,12 @@ public class ResourcesTest extends IoTestCase {
assertEquals("resource no such resource not found.", e.getMessage());
}
}
-
+
public void testGetResource() {
assertNotNull(
Resources.getResource("com/google/common/io/testdata/i18n.txt"));
}
-
+
public void testGetResource_relativePath_notFound() {
try {
Resources.getResource(
@@ -128,8 +132,18 @@ public class ResourcesTest extends IoTestCase {
e.getMessage());
}
}
-
+
public void testGetResource_relativePath() {
assertNotNull(Resources.getResource(getClass(), "testdata/i18n.txt"));
}
+
+ public void testNulls() {
+ new NullPointerTester()
+ .setDefault(URL.class, classfile(ResourcesTest.class))
+ .testAllPublicStaticMethods(Resources.class);
+ }
+
+ private static URL classfile(Class<?> c) {
+ return c.getResource(c.getSimpleName() + ".class");
+ }
}
diff --git a/guava-tests/test/com/google/common/io/SourceSinkFactories.java b/guava-tests/test/com/google/common/io/SourceSinkFactories.java
new file mode 100644
index 0000000..0ebfe28
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/SourceSinkFactories.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.io.SourceSinkFactory.ByteSinkFactory;
+import static com.google.common.io.SourceSinkFactory.ByteSourceFactory;
+import static com.google.common.io.SourceSinkFactory.CharSinkFactory;
+import static com.google.common.io.SourceSinkFactory.CharSourceFactory;
+
+import com.google.common.base.Charsets;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.nio.CharBuffer;
+import java.util.Arrays;
+import java.util.logging.Logger;
+
+import javax.annotation.Nullable;
+
+/**
+ * {@link SourceSinkFactory} implementations.
+ *
+ * @author Colin Decker
+ */
+public class SourceSinkFactories {
+
+ private SourceSinkFactories() {}
+
+ public static CharSourceFactory stringCharSourceFactory() {
+ return new StringSourceFactory();
+ }
+
+ public static ByteSourceFactory byteArraySourceFactory() {
+ return new ByteArraySourceFactory();
+ }
+
+ public static ByteSourceFactory fileByteSourceFactory() {
+ return new FileByteSourceFactory();
+ }
+
+ public static ByteSinkFactory fileByteSinkFactory() {
+ return new FileByteSinkFactory(null);
+ }
+
+ public static ByteSinkFactory appendingFileByteSinkFactory() {
+ String initialString = IoTestCase.ASCII + IoTestCase.I18N;
+ return new FileByteSinkFactory(initialString.getBytes(Charsets.UTF_8));
+ }
+
+ public static CharSourceFactory fileCharSourceFactory() {
+ return new FileCharSourceFactory();
+ }
+
+ public static CharSinkFactory fileCharSinkFactory() {
+ return new FileCharSinkFactory(null);
+ }
+
+ public static CharSinkFactory appendingFileCharSinkFactory() {
+ String initialString = IoTestCase.ASCII + IoTestCase.I18N;
+ return new FileCharSinkFactory(initialString);
+ }
+
+ public static ByteSourceFactory urlByteSourceFactory() {
+ return new UrlByteSourceFactory();
+ }
+
+ public static CharSourceFactory urlCharSourceFactory() {
+ return new UrlCharSourceFactory();
+ }
+
+ public static CharSourceFactory asCharSourceFactory(final ByteSourceFactory factory) {
+ checkNotNull(factory);
+ return new CharSourceFactory() {
+ @Override
+ public CharSource createSource(String string) throws IOException {
+ return factory.createSource(string.getBytes(Charsets.UTF_8))
+ .asCharSource(Charsets.UTF_8);
+ }
+
+ @Override
+ public String getExpected(String data) {
+ return checkNotNull(data);
+ }
+
+ @Override
+ public void tearDown() throws IOException {
+ factory.tearDown();
+ }
+ };
+ }
+
+ public static CharSinkFactory asCharSinkFactory(final ByteSinkFactory factory) {
+ checkNotNull(factory);
+ return new CharSinkFactory() {
+ @Override
+ public CharSink createSink() throws IOException {
+ return factory.createSink().asCharSink(Charsets.UTF_8);
+ }
+
+ @Override
+ public String getSinkContents() throws IOException {
+ return new String(factory.getSinkContents(), Charsets.UTF_8);
+ }
+
+ @Override
+ public String getExpected(String data) {
+ /*
+ * Get what the byte sink factory would expect for no written bytes, then append expected
+ * string to that.
+ */
+ byte[] factoryExpectedForNothing = factory.getExpected(new byte[0]);
+ return new String(factoryExpectedForNothing, Charsets.UTF_8) + checkNotNull(data);
+ }
+
+ @Override
+ public void tearDown() throws IOException {
+ factory.tearDown();
+ }
+ };
+ }
+
+ public static ByteSourceFactory asSlicedByteSourceFactory(final ByteSourceFactory factory,
+ final int off, final int len) {
+ checkNotNull(factory);
+ return new ByteSourceFactory() {
+ @Override
+ public ByteSource createSource(byte[] bytes) throws IOException {
+ return factory.createSource(bytes).slice(off, len);
+ }
+
+ @Override
+ public byte[] getExpected(byte[] bytes) {
+ return Arrays.copyOfRange(factory.getExpected(bytes), off, off + len);
+ }
+
+ @Override
+ public void tearDown() throws IOException {
+ factory.tearDown();
+ }
+ };
+ }
+
+ private static class StringSourceFactory implements CharSourceFactory {
+
+ @Override
+ public CharSource createSource(String data) throws IOException {
+ return CharStreams.asCharSource(data);
+ }
+
+ @Override
+ public String getExpected(String data) {
+ return data;
+ }
+
+ @Override
+ public void tearDown() throws IOException {
+ }
+ }
+
+ private static class ByteArraySourceFactory implements ByteSourceFactory {
+
+ @Override
+ public ByteSource createSource(byte[] bytes) throws IOException {
+ return ByteStreams.asByteSource(bytes);
+ }
+
+ @Override
+ public byte[] getExpected(byte[] bytes) {
+ return bytes;
+ }
+
+ @Override
+ public void tearDown() throws IOException {
+ }
+ }
+
+ private abstract static class FileFactory {
+
+ private static final Logger logger = Logger.getLogger(FileFactory.class.getName());
+
+ private final ThreadLocal<File> fileThreadLocal = new ThreadLocal<File>();
+
+ protected File createFile() throws IOException {
+ File file = File.createTempFile("SinkSourceFile", "txt");
+ fileThreadLocal.set(file);
+ return file;
+ }
+
+ protected File getFile() {
+ return fileThreadLocal.get();
+ }
+ public final void tearDown() throws IOException {
+ if (!fileThreadLocal.get().delete()) {
+ logger.warning("Unable to delete file: " + fileThreadLocal.get());
+ }
+ fileThreadLocal.remove();
+ }
+ }
+
+ private static class FileByteSourceFactory extends FileFactory implements ByteSourceFactory {
+
+ @Override
+ public ByteSource createSource(byte[] bytes) throws IOException {
+ checkNotNull(bytes);
+ File file = createFile();
+ OutputStream out = new FileOutputStream(file);
+ try {
+ out.write(bytes);
+ } finally {
+ out.close();
+ }
+ return Files.asByteSource(file);
+ }
+
+ @Override
+ public byte[] getExpected(byte[] bytes) {
+ return checkNotNull(bytes);
+ }
+ }
+
+ private static class FileByteSinkFactory extends FileFactory implements ByteSinkFactory {
+
+ private final byte[] initialBytes;
+
+ private FileByteSinkFactory(@Nullable byte[] initialBytes) {
+ this.initialBytes = initialBytes;
+ }
+
+ @Override
+ public ByteSink createSink() throws IOException {
+ File file = createFile();
+ if (initialBytes != null) {
+ FileOutputStream out = new FileOutputStream(file);
+ try {
+ out.write(initialBytes);
+ } finally {
+ out.close();
+ }
+ return Files.asByteSink(file, FileWriteMode.APPEND);
+ }
+ return Files.asByteSink(file);
+ }
+
+ @Override
+ public byte[] getExpected(byte[] bytes) {
+ if (initialBytes == null) {
+ return checkNotNull(bytes);
+ } else {
+ byte[] result = new byte[initialBytes.length + bytes.length];
+ System.arraycopy(initialBytes, 0, result, 0, initialBytes.length);
+ System.arraycopy(bytes, 0, result, initialBytes.length, bytes.length);
+ return result;
+ }
+ }
+
+ @Override
+ public byte[] getSinkContents() throws IOException {
+ File file = getFile();
+ InputStream in = new FileInputStream(file);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ byte[] buffer = new byte[100];
+ int read;
+ while ((read = in.read(buffer)) != -1) {
+ out.write(buffer, 0, read);
+ }
+ return out.toByteArray();
+ }
+ }
+
+ private static class FileCharSourceFactory extends FileFactory implements CharSourceFactory {
+
+ @Override
+ public CharSource createSource(String string) throws IOException {
+ checkNotNull(string);
+ File file = createFile();
+ Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8);
+ try {
+ writer.write(string);
+ } finally {
+ writer.close();
+ }
+ return Files.asCharSource(file, Charsets.UTF_8);
+ }
+
+ @Override
+ public String getExpected(String string) {
+ return checkNotNull(string);
+ }
+ }
+
+ private static class FileCharSinkFactory extends FileFactory implements CharSinkFactory {
+
+ private final String initialString;
+
+ private FileCharSinkFactory(@Nullable String initialString) {
+ this.initialString = initialString;
+ }
+
+ @Override
+ public CharSink createSink() throws IOException {
+ File file = createFile();
+ if (initialString != null) {
+ Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8);
+ try {
+ writer.write(initialString);
+ } finally {
+ writer.close();
+ }
+ return Files.asCharSink(file, Charsets.UTF_8, FileWriteMode.APPEND);
+ }
+ return Files.asCharSink(file, Charsets.UTF_8);
+ }
+
+ @Override
+ public String getExpected(String string) {
+ checkNotNull(string);
+ return initialString == null
+ ? string
+ : initialString + string;
+ }
+
+ @Override
+ public String getSinkContents() throws IOException {
+ File file = getFile();
+ Reader reader = new InputStreamReader(new FileInputStream(file), Charsets.UTF_8);
+ StringBuilder builder = new StringBuilder();
+ CharBuffer buffer = CharBuffer.allocate(100);
+ while (reader.read(buffer) != -1) {
+ buffer.flip();
+ builder.append(buffer);
+ buffer.clear();
+ }
+ return builder.toString();
+ }
+ }
+
+ private static class UrlByteSourceFactory extends FileByteSourceFactory {
+
+ @Override
+ public ByteSource createSource(byte[] bytes) throws IOException {
+ super.createSource(bytes);
+ return Resources.asByteSource(getFile().toURI().toURL());
+ }
+ }
+
+ private static class UrlCharSourceFactory extends FileCharSourceFactory {
+
+ @Override
+ public CharSource createSource(String string) throws IOException {
+ super.createSource(string); // just ignore returned CharSource
+ return Resources.asCharSource(getFile().toURI().toURL(), Charsets.UTF_8);
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/SourceSinkFactory.java b/guava-tests/test/com/google/common/io/SourceSinkFactory.java
new file mode 100644
index 0000000..0c4fdd8
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/SourceSinkFactory.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * A test factory for byte or char sources or sinks. In addition to creating sources or sinks, the
+ * factory specifies what content should be expected to be read from a source or contained in a sink
+ * given the content data that was used to create the source or that was written to the sink.
+ *
+ * <p>A single {@code SourceSinkFactory} implementation generally corresponds to one specific way of
+ * creating a source or sink, such as {@link Files#asByteSource(File)}. Implementations of
+ * {@code SourceSinkFactory} for common.io are found in {@link SourceSinkFactories}.
+ *
+ * @param <S> the source or sink type
+ * @param <T> the data type (byte[] or String)
+ * @author Colin Decker
+ */
+public interface SourceSinkFactory<S, T> {
+
+ /**
+ * Returns the data to expect the source or sink to contain given the data that was used to create
+ * the source or written to the sink. Typically, this will just return the input directly, but in
+ * some cases it may alter the input. For example, if the factory returns a sliced view of a
+ * source created with some given bytes, this method would return a subsequence of the given
+ * (byte[]) data.
+ */
+ T getExpected(T data);
+
+ /**
+ * Cleans up anything created when creating the source or sink.
+ */
+ public abstract void tearDown() throws IOException;
+
+ /**
+ * Factory for byte or char sources.
+ */
+ public interface SourceFactory<S, T> extends SourceSinkFactory<S, T> {
+
+ /**
+ * Creates a new source containing some or all of the given data.
+ */
+ S createSource(T data) throws IOException;
+ }
+
+ /**
+ * Factory for byte or char sinks.
+ */
+ public interface SinkFactory<S, T> extends SourceSinkFactory<S, T> {
+
+ /**
+ * Creates a new sink.
+ */
+ S createSink() throws IOException;
+
+ /**
+ * Gets the current content of the created sink.
+ */
+ T getSinkContents() throws IOException;
+ }
+
+ /**
+ * Factory for {@link ByteSource} instances.
+ */
+ public interface ByteSourceFactory extends SourceFactory<ByteSource, byte[]> {
+ }
+
+ /**
+ * Factory for {@link ByteSink} instances.
+ */
+ public interface ByteSinkFactory extends SinkFactory<ByteSink, byte[]> {
+ }
+
+ /**
+ * Factory for {@link CharSource} instances.
+ */
+ public interface CharSourceFactory extends SourceFactory<CharSource, String> {
+ }
+
+ /**
+ * Factory for {@link CharSink} instances.
+ */
+ public interface CharSinkFactory extends SinkFactory<CharSink, String> {
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/SourceSinkTester.java b/guava-tests/test/com/google/common/io/SourceSinkTester.java
new file mode 100644
index 0000000..ff3167b
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/SourceSinkTester.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+/**
+ * @param <S> the source or sink type
+ * @param <T> the data type (byte[] or String)
+ * @param <F> the factory type
+ * @author Colin Decker
+ */
+public class SourceSinkTester<S, T, F extends SourceSinkFactory<S, T>> extends TestCase {
+
+ static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing "
+ + "elit. Cras fringilla elit ac ipsum adipiscing vulputate. Maecenas in lorem nulla, ac "
+ + "sollicitudin quam. Praesent neque elit, sodales quis vestibulum vel, pellentesque nec "
+ + "erat. Proin cursus commodo lacus eget congue. Aliquam erat volutpat. Fusce ut leo sed "
+ + "risus tempor vehicula et a odio. Nam aliquet dolor viverra libero rutrum accumsan quis "
+ + "in augue. Suspendisse id dui in lorem tristique placerat eget vel risus. Sed metus neque, "
+ + "scelerisque in molestie ac, mattis quis lectus. Pellentesque viverra justo commodo quam "
+ + "bibendum ut gravida leo accumsan. Nullam malesuada sagittis diam, quis suscipit mauris "
+ + "euismod vulputate. Pellentesque ultrices tellus sed lorem aliquet pulvinar. Nam lorem "
+ + "nunc, ultrices at auctor non, scelerisque eget turpis. Nullam eget varius erat. Sed a "
+ + "lorem id arcu dictum euismod. Fusce lectus odio, elementum ullamcorper mattis viverra, "
+ + "dictum sit amet lacus.\n"
+ + "\n"
+ + "Nunc quis lacus est. Sed aliquam pretium cursus. Sed eu libero eros. In hac habitasse "
+ + "platea dictumst. Pellentesque molestie, nibh nec iaculis luctus, justo sem lobortis enim, "
+ + "at feugiat leo magna nec libero. Mauris quis odio eget nisl rutrum cursus nec eget augue. "
+ + "Sed nec arcu sem. In hac habitasse platea dictumst.";
+
+ static final ImmutableMap<String, String> TEST_STRINGS
+ = ImmutableMap.<String, String>builder()
+ .put("empty", "")
+ .put("1 char", "0")
+ .put("1 word", "hello")
+ .put("2 words", "hello world")
+ .put("\\n line break", "hello\nworld")
+ .put("\\r line break", "hello\rworld")
+ .put("\\r\\n line break", "hello\r\nworld")
+ .put("\\n at EOF", "hello\nworld\n")
+ .put("\\r at EOF", "hello\nworld\r")
+ .put("lorem ipsum", LOREM_IPSUM)
+ .build();
+
+ protected final F factory;
+ protected final T data;
+ protected final T expected;
+
+ private final String suiteName;
+ private final String caseDesc;
+
+ SourceSinkTester(F factory, T data, String suiteName, String caseDesc, Method method) {
+ super(method.getName());
+ this.factory = checkNotNull(factory);
+ this.data = checkNotNull(data);
+ this.expected = checkNotNull(factory.getExpected(data));
+ this.suiteName = checkNotNull(suiteName);
+ this.caseDesc = checkNotNull(caseDesc);
+ }
+
+ @Override
+ public String getName() {
+ return super.getName() + " [" + suiteName + " [" + caseDesc + "]]";
+ }
+
+ protected static ImmutableList<String> getLines(final String string) {
+ try {
+ return new CharSource() {
+ @Override
+ public Reader openStream() throws IOException {
+ return new StringReader(string);
+ }
+ }.readLines();
+ } catch (IOException e) {
+ throw new AssertionError();
+ }
+ }
+
+ @Override
+ public void tearDown() throws IOException {
+ factory.tearDown();
+ }
+
+ static ImmutableList<Method> getTestMethods(Class<?> testClass) {
+ List<Method> result = Lists.newArrayList();
+ for (Method method : testClass.getDeclaredMethods()) {
+ if (Modifier.isPublic(method.getModifiers())
+ && method.getReturnType() == void.class
+ && method.getParameterTypes().length == 0
+ && method.getName().startsWith("test")) {
+ result.add(method);
+ }
+ }
+ return ImmutableList.copyOf(result);
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/TestByteSink.java b/guava-tests/test/com/google/common/io/TestByteSink.java
new file mode 100644
index 0000000..47f34e9
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/TestByteSink.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A byte sink for testing that has configurable behavior.
+ *
+ * @author Colin Decker
+ */
+public class TestByteSink extends ByteSink implements TestStreamSupplier {
+
+ private final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ private final ImmutableSet<TestOption> options;
+
+ private boolean outputStreamOpened;
+ private boolean outputStreamClosed;
+
+ public TestByteSink(TestOption... options) {
+ this.options = ImmutableSet.copyOf(options);
+ }
+
+ byte[] getBytes() {
+ return bytes.toByteArray();
+ }
+
+ @Override
+ public boolean wasStreamOpened() {
+ return outputStreamOpened;
+ }
+
+ @Override
+ public boolean wasStreamClosed() {
+ return outputStreamClosed;
+ }
+
+ @Override
+ public OutputStream openStream() throws IOException {
+ outputStreamOpened = true;
+ bytes.reset(); // truncate
+ return new Out();
+ }
+
+ private final class Out extends TestOutputStream {
+
+ public Out() throws IOException {
+ super(bytes, options);
+ }
+
+ @Override
+ public void close() throws IOException {
+ outputStreamClosed = true;
+ super.close();
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/TestByteSource.java b/guava-tests/test/com/google/common/io/TestByteSource.java
new file mode 100644
index 0000000..08ca554
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/TestByteSource.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Random;
+
+/**
+ * A byte source for testing that has configurable behavior.
+ *
+ * @author Colin Decker
+ */
+public final class TestByteSource extends ByteSource implements TestStreamSupplier {
+
+ private final byte[] bytes;
+ private final ImmutableSet<TestOption> options;
+
+ private boolean inputStreamOpened;
+ private boolean inputStreamClosed;
+
+ TestByteSource(byte[] bytes, TestOption... options) {
+ this.bytes = checkNotNull(bytes);
+ this.options = ImmutableSet.copyOf(options);
+ }
+
+ @Override
+ public boolean wasStreamOpened() {
+ return inputStreamOpened;
+ }
+
+ @Override
+ public boolean wasStreamClosed() {
+ return inputStreamClosed;
+ }
+
+ @Override
+ public InputStream openStream() throws IOException {
+ inputStreamOpened = true;
+ return new RandomAmountInputStream(new In(), new Random());
+ }
+
+ private final class In extends TestInputStream {
+
+ public In() throws IOException {
+ super(new ByteArrayInputStream(bytes), options);
+ }
+
+ @Override
+ public void close() throws IOException {
+ inputStreamClosed = true;
+ super.close();
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/TestCharSink.java b/guava-tests/test/com/google/common/io/TestCharSink.java
new file mode 100644
index 0000000..6f7686f
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/TestCharSink.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.base.Charsets.UTF_8;
+
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+/**
+ * A char sink for testing that has configurable behavior.
+ *
+ * @author Colin Decker
+ */
+public class TestCharSink extends CharSink implements TestStreamSupplier {
+
+ private final TestByteSink byteSink;
+
+ public TestCharSink(TestOption... options) {
+ this.byteSink = new TestByteSink(options);
+ }
+
+ public String getString() {
+ return new String(byteSink.getBytes(), UTF_8);
+ }
+
+ @Override
+ public boolean wasStreamOpened() {
+ return byteSink.wasStreamOpened();
+ }
+
+ @Override
+ public boolean wasStreamClosed() {
+ return byteSink.wasStreamClosed();
+ }
+
+ @Override
+ public Writer openStream() throws IOException {
+ // using TestByteSink's output stream to get option behavior, so flush to it on every write
+ return new FilterWriter(new OutputStreamWriter(byteSink.openStream(), UTF_8)) {
+ @Override
+ public void write(int c) throws IOException {
+ super.write(c);
+ flush();
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ super.write(cbuf, off, len);
+ flush();
+ }
+
+ @Override
+ public void write(String str, int off, int len) throws IOException {
+ super.write(str, off, len);
+ flush();
+ }
+ };
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/TestCharSource.java b/guava-tests/test/com/google/common/io/TestCharSource.java
new file mode 100644
index 0000000..37ee8dc
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/TestCharSource.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.base.Charsets.UTF_8;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+/**
+ * A char source for testing that has configurable options.
+ *
+ * @author Colin Decker
+ */
+public class TestCharSource extends CharSource implements TestStreamSupplier {
+
+ private final TestByteSource byteSource;
+
+ public TestCharSource(String content, TestOption... options) {
+ this.byteSource = new TestByteSource(content.getBytes(UTF_8), options);
+ }
+
+ @Override
+ public boolean wasStreamOpened() {
+ return byteSource.wasStreamOpened();
+ }
+
+ @Override
+ public boolean wasStreamClosed() {
+ return byteSource.wasStreamClosed();
+ }
+
+ @Override
+ public Reader openStream() throws IOException {
+ return new InputStreamReader(byteSource.openStream(), UTF_8);
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/TestInputStream.java b/guava-tests/test/com/google/common/io/TestInputStream.java
new file mode 100644
index 0000000..51aec6d
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/TestInputStream.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.io.TestOption.CLOSE_THROWS;
+import static com.google.common.io.TestOption.OPEN_THROWS;
+import static com.google.common.io.TestOption.READ_THROWS;
+import static com.google.common.io.TestOption.SKIP_THROWS;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+
+/**
+ * @author Colin Decker
+ */
+public class TestInputStream extends FilterInputStream {
+
+ private final ImmutableSet<TestOption> options;
+ private boolean closed;
+
+ public TestInputStream(InputStream in, TestOption... options) throws IOException {
+ this(in, Arrays.asList(options));
+ }
+
+ public TestInputStream(InputStream in, Iterable<TestOption> options) throws IOException {
+ super(checkNotNull(in));
+ this.options = ImmutableSet.copyOf(options);
+ throwIf(OPEN_THROWS);
+ }
+
+ public boolean closed() {
+ return closed;
+ }
+
+ @Override
+ public int read() throws IOException {
+ throwIf(closed);
+ throwIf(READ_THROWS);
+ return in.read();
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ throwIf(closed);
+ throwIf(READ_THROWS);
+ return in.read(b, off, len);
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ throwIf(closed);
+ throwIf(SKIP_THROWS);
+ return in.skip(n);
+ }
+
+ @Override
+ public void close() throws IOException {
+ closed = true;
+ throwIf(CLOSE_THROWS);
+ in.close();
+ }
+
+ private void throwIf(TestOption option) throws IOException {
+ throwIf(options.contains(option));
+ }
+
+ private static void throwIf(boolean condition) throws IOException {
+ if (condition) {
+ throw new IOException();
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/TestOption.java b/guava-tests/test/com/google/common/io/TestOption.java
new file mode 100644
index 0000000..89d7a77
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/TestOption.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+/**
+ * Options controlling the behavior of sources/sinks/streams for testing.
+ *
+ * @author Colin Decker
+ */
+public enum TestOption {
+ OPEN_THROWS,
+ SKIP_THROWS,
+ READ_THROWS,
+ WRITE_THROWS,
+ CLOSE_THROWS
+}
diff --git a/guava-tests/test/com/google/common/io/TestOutputStream.java b/guava-tests/test/com/google/common/io/TestOutputStream.java
new file mode 100644
index 0000000..43fc4dc
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/TestOutputStream.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.io.TestOption.CLOSE_THROWS;
+import static com.google.common.io.TestOption.OPEN_THROWS;
+import static com.google.common.io.TestOption.WRITE_THROWS;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+
+/**
+ * @author Colin Decker
+ */
+public class TestOutputStream extends FilterOutputStream {
+
+ private final ImmutableSet<TestOption> options;
+ private boolean closed;
+
+ public TestOutputStream(OutputStream out, TestOption... options) throws IOException {
+ this(out, Arrays.asList(options));
+ }
+
+ public TestOutputStream(OutputStream out, Iterable<TestOption> options) throws IOException {
+ super(checkNotNull(out));
+ this.options = ImmutableSet.copyOf(options);
+ throwIf(OPEN_THROWS);
+ }
+
+ public boolean closed() {
+ return closed;
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ throwIf(closed);
+ throwIf(WRITE_THROWS);
+ super.write(b, off, len);
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ throwIf(closed);
+ throwIf(WRITE_THROWS);
+ super.write(b);
+ }
+
+ @Override
+ public void close() throws IOException {
+ closed = true;
+ super.close();
+ throwIf(CLOSE_THROWS);
+ }
+
+ private void throwIf(TestOption option) throws IOException {
+ throwIf(options.contains(option));
+ }
+
+ private static void throwIf(boolean condition) throws IOException {
+ if (condition) {
+ throw new IOException();
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/TestReader.java b/guava-tests/test/com/google/common/io/TestReader.java
new file mode 100644
index 0000000..73a7222
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/TestReader.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.base.Charsets.UTF_8;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.ByteArrayInputStream;
+import java.io.FilterReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * @author Colin Decker
+ */
+public class TestReader extends FilterReader {
+
+ private final TestInputStream in;
+
+ public TestReader(TestOption... options) throws IOException {
+ this(new TestInputStream(new ByteArrayInputStream(new byte[10]), options));
+ }
+
+ public TestReader(TestInputStream in) {
+ super(new InputStreamReader(checkNotNull(in), UTF_8));
+ this.in = in;
+ }
+
+ public boolean closed() {
+ return in.closed();
+ }
+}
diff --git a/guava-tests/test/com/google/common/io/TestStreamSupplier.java b/guava-tests/test/com/google/common/io/TestStreamSupplier.java
new file mode 100644
index 0000000..47af47b
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/TestStreamSupplier.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+/**
+ * Interface for a supplier of streams that can report whether a stream was opened and whether that
+ * stream was closed. Intended for use in a test where only a single stream should be opened and
+ * possibly closed.
+ *
+ * @author Colin Decker
+ */
+public interface TestStreamSupplier {
+
+ /**
+ * Returns whether or not a new stream was opened.
+ */
+ boolean wasStreamOpened();
+
+ /**
+ * Returns whether or not an open stream was closed.
+ */
+ boolean wasStreamClosed();
+}
diff --git a/guava-tests/test/com/google/common/io/TestWriter.java b/guava-tests/test/com/google/common/io/TestWriter.java
new file mode 100644
index 0000000..1ffe5af
--- /dev/null
+++ b/guava-tests/test/com/google/common/io/TestWriter.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.io;
+
+import static com.google.common.base.Charsets.UTF_8;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.FilterWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+/**
+ * @author Colin Decker
+ */
+public class TestWriter extends FilterWriter {
+
+ private final TestOutputStream out;
+
+ public TestWriter(TestOption... options) throws IOException {
+ this(new TestOutputStream(ByteStreams.nullOutputStream(), options));
+ }
+
+ public TestWriter(TestOutputStream out) {
+ super(new OutputStreamWriter(checkNotNull(out), UTF_8));
+ this.out = out;
+ }
+
+ @Override
+ public void write(int c) throws IOException {
+ super.write(c);
+ flush(); // flush write to TestOutputStream to get its behavior
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ super.write(cbuf, off, len);
+ flush();
+ }
+
+ @Override
+ public void write(String str, int off, int len) throws IOException {
+ super.write(str, off, len);
+ flush();
+ }
+
+ public boolean closed() {
+ return out.closed();
+ }
+}
diff --git a/guava-tests/test/com/google/common/math/BigIntegerMathTest.java b/guava-tests/test/com/google/common/math/BigIntegerMathTest.java
index 504d8c2..7e1aa77 100644
--- a/guava-tests/test/com/google/common/math/BigIntegerMathTest.java
+++ b/guava-tests/test/com/google/common/math/BigIntegerMathTest.java
@@ -19,8 +19,6 @@ package com.google.common.math;
import static com.google.common.math.MathTesting.ALL_BIGINTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.ALL_ROUNDING_MODES;
import static com.google.common.math.MathTesting.ALL_SAFE_ROUNDING_MODES;
-import static com.google.common.math.MathTesting.NEGATIVE_BIGINTEGER_CANDIDATES;
-import static com.google.common.math.MathTesting.NEGATIVE_INTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.NONZERO_BIGINTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.POSITIVE_BIGINTEGER_CANDIDATES;
import static java.math.BigInteger.ONE;
@@ -36,6 +34,8 @@ import static java.math.RoundingMode.UNNECESSARY;
import static java.math.RoundingMode.UP;
import static java.util.Arrays.asList;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -49,13 +49,15 @@ import java.math.RoundingMode;
*
* @author Louis Wasserman
*/
+@GwtCompatible(emulated = true)
public class BigIntegerMathTest extends TestCase {
+ @GwtIncompatible("TODO")
public void testConstantSqrt2PrecomputedBits() {
assertEquals(BigIntegerMath.sqrt(
BigInteger.ZERO.setBit(2 * BigIntegerMath.SQRT2_PRECOMPUTE_THRESHOLD + 1), FLOOR),
BigIntegerMath.SQRT2_PRECOMPUTED_BITS);
}
-
+
public void testIsPowerOfTwo() {
for (BigInteger x : ALL_BIGINTEGER_CANDIDATES) {
// Checks for a single bit set.
@@ -74,13 +76,11 @@ public class BigIntegerMathTest extends TestCase {
}
public void testLog2NegativeAlwaysThrows() {
- for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
- for (RoundingMode mode : ALL_ROUNDING_MODES) {
- try {
- BigIntegerMath.log2(x.negate(), mode);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
- }
+ for (RoundingMode mode : ALL_ROUNDING_MODES) {
+ try {
+ BigIntegerMath.log2(BigInteger.valueOf(-1), mode);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
}
}
@@ -151,6 +151,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testLog10ZeroAlwaysThrows() {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
try {
@@ -160,17 +161,17 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testLog10NegativeAlwaysThrows() {
- for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
- for (RoundingMode mode : ALL_ROUNDING_MODES) {
- try {
- BigIntegerMath.log10(x.negate(), mode);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
- }
+ for (RoundingMode mode : ALL_ROUNDING_MODES) {
+ try {
+ BigIntegerMath.log10(BigInteger.valueOf(-1), mode);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
}
}
+ @GwtIncompatible("TODO")
public void testLog10Floor() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : asList(FLOOR, DOWN)) {
@@ -181,6 +182,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testLog10Ceiling() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : asList(CEILING, UP)) {
@@ -192,6 +194,7 @@ public class BigIntegerMathTest extends TestCase {
}
// Relies on the correctness of log10(BigInteger, FLOOR).
+ @GwtIncompatible("TODO")
public void testLog10Exact() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
int logFloor = BigIntegerMath.log10(x, FLOOR);
@@ -205,6 +208,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testLog10HalfUp() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
int result = BigIntegerMath.log10(x, HALF_UP);
@@ -216,6 +220,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testLog10HalfDown() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
int result = BigIntegerMath.log10(x, HALF_DOWN);
@@ -228,6 +233,7 @@ public class BigIntegerMathTest extends TestCase {
}
// Relies on the correctness of log10(BigInteger, {HALF_UP,HALF_DOWN}).
+ @GwtIncompatible("TODO")
public void testLog10HalfEven() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
int halfEven = BigIntegerMath.log10(x, HALF_EVEN);
@@ -238,6 +244,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testLog10TrivialOnPowerOf10() {
BigInteger x = BigInteger.TEN.pow(100);
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -245,23 +252,24 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testSqrtZeroAlwaysZero() {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
assertEquals(ZERO, BigIntegerMath.sqrt(ZERO, mode));
}
}
+ @GwtIncompatible("TODO")
public void testSqrtNegativeAlwaysThrows() {
- for (BigInteger x : NEGATIVE_BIGINTEGER_CANDIDATES) {
- for (RoundingMode mode : ALL_ROUNDING_MODES) {
- try {
- BigIntegerMath.sqrt(x, mode);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
- }
+ for (RoundingMode mode : ALL_ROUNDING_MODES) {
+ try {
+ BigIntegerMath.sqrt(BigInteger.valueOf(-1), mode);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
}
}
+ @GwtIncompatible("TODO")
public void testSqrtFloor() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : asList(FLOOR, DOWN)) {
@@ -273,6 +281,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testSqrtCeiling() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : asList(CEILING, UP)) {
@@ -285,6 +294,7 @@ public class BigIntegerMathTest extends TestCase {
}
// Relies on the correctness of sqrt(BigInteger, FLOOR).
+ @GwtIncompatible("TODO")
public void testSqrtExact() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
BigInteger floor = BigIntegerMath.sqrt(x, FLOOR);
@@ -299,6 +309,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testSqrtHalfUp() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
BigInteger result = BigIntegerMath.sqrt(x, HALF_UP);
@@ -314,6 +325,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testSqrtHalfDown() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
BigInteger result = BigIntegerMath.sqrt(x, HALF_DOWN);
@@ -330,6 +342,7 @@ public class BigIntegerMathTest extends TestCase {
}
// Relies on the correctness of sqrt(BigInteger, {HALF_UP,HALF_DOWN}).
+ @GwtIncompatible("TODO")
public void testSqrtHalfEven() {
for (BigInteger x : POSITIVE_BIGINTEGER_CANDIDATES) {
BigInteger halfEven = BigIntegerMath.sqrt(x, HALF_EVEN);
@@ -340,6 +353,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testDivNonZero() {
for (BigInteger p : NONZERO_BIGINTEGER_CANDIDATES) {
for (BigInteger q : NONZERO_BIGINTEGER_CANDIDATES) {
@@ -352,6 +366,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testDivNonZeroExact() {
for (BigInteger p : NONZERO_BIGINTEGER_CANDIDATES) {
for (BigInteger q : NONZERO_BIGINTEGER_CANDIDATES) {
@@ -367,6 +382,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testZeroDivIsAlwaysZero() {
for (BigInteger q : NONZERO_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -375,6 +391,7 @@ public class BigIntegerMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testDivByZeroAlwaysFails() {
for (BigInteger p : ALL_BIGINTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -388,7 +405,7 @@ public class BigIntegerMathTest extends TestCase {
public void testFactorial() {
BigInteger expected = BigInteger.ONE;
- for (int i = 1; i <= 300; i++) {
+ for (int i = 1; i <= 200; i++) {
expected = expected.multiply(BigInteger.valueOf(i));
assertEquals(expected, BigIntegerMath.factorial(i));
}
@@ -399,17 +416,24 @@ public class BigIntegerMathTest extends TestCase {
}
public void testFactorialNegative() {
- for (int n : NEGATIVE_INTEGER_CANDIDATES) {
- try {
- BigIntegerMath.factorial(n);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException expected) {}
- }
+ try {
+ BigIntegerMath.factorial(-1);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testBinomialSmall() {
+ runBinomialTest(0, 30);
}
-
+
+ @GwtIncompatible("too slow")
+ public void testBinomialLarge() {
+ runBinomialTest(31, 100);
+ }
+
// Depends on the correctness of BigIntegerMath.factorial
- public void testBinomial() {
- for (int n = 0; n <= 50; n++) {
+ private static void runBinomialTest(int firstN, int lastN) {
+ for (int n = firstN; n <= lastN; n++) {
for (int k = 0; k <= n; k++) {
BigInteger expected = BigIntegerMath
.factorial(n)
@@ -433,10 +457,10 @@ public class BigIntegerMathTest extends TestCase {
}
}
- public void testNullPointers() throws Exception {
+ @GwtIncompatible("NullPointerTester")
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.setDefault(BigInteger.class, ONE);
- tester.setDefault(RoundingMode.class, FLOOR);
tester.setDefault(int.class, 1);
tester.setDefault(long.class, 1L);
tester.testAllPublicStaticMethods(BigIntegerMath.class);
diff --git a/guava-tests/test/com/google/common/math/DoubleMathTest.java b/guava-tests/test/com/google/common/math/DoubleMathTest.java
index 9fe6d90..b2f9418 100644
--- a/guava-tests/test/com/google/common/math/DoubleMathTest.java
+++ b/guava-tests/test/com/google/common/math/DoubleMathTest.java
@@ -16,9 +16,11 @@
package com.google.common.math;
+import static com.google.common.math.MathTesting.*;
import static com.google.common.math.MathTesting.ALL_DOUBLE_CANDIDATES;
import static com.google.common.math.MathTesting.ALL_ROUNDING_MODES;
import static com.google.common.math.MathTesting.ALL_SAFE_ROUNDING_MODES;
+import static com.google.common.math.MathTesting.FINITE_DOUBLE_CANDIDATES;
import static com.google.common.math.MathTesting.FRACTIONAL_DOUBLE_CANDIDATES;
import static com.google.common.math.MathTesting.INTEGRAL_DOUBLE_CANDIDATES;
import static com.google.common.math.MathTesting.NEGATIVE_INTEGER_CANDIDATES;
@@ -33,6 +35,9 @@ import static java.math.RoundingMode.UNNECESSARY;
import static java.math.RoundingMode.UP;
import static java.util.Arrays.asList;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.primitives.Doubles;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -41,6 +46,7 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.Arrays;
+import java.util.List;
/**
* Tests for {@code DoubleMath}.
@@ -55,7 +61,7 @@ public class DoubleMathTest extends TestCase {
private static final BigDecimal MAX_LONG_AS_BIG_DECIMAL = BigDecimal.valueOf(Long.MAX_VALUE);
private static final BigDecimal MIN_LONG_AS_BIG_DECIMAL = BigDecimal.valueOf(Long.MIN_VALUE);
- public void testConstantsMaxFactorial(){
+ public void testConstantsMaxFactorial() {
BigInteger MAX_DOUBLE_VALUE = BigDecimal.valueOf(Double.MAX_VALUE).toBigInteger();
assertTrue(BigIntegerMath.factorial(DoubleMath.MAX_FACTORIAL).compareTo(MAX_DOUBLE_VALUE) <= 0);
assertTrue(
@@ -65,10 +71,10 @@ public class DoubleMathTest extends TestCase {
public void testConstantsEverySixteenthFactorial() {
for (int i = 0, n = 0; n <= DoubleMath.MAX_FACTORIAL; i++, n += 16) {
assertEquals(
- BigIntegerMath.factorial(n).doubleValue(), DoubleMath.EVERY_SIXTEENTH_FACTORIAL[i]);
+ BigIntegerMath.factorial(n).doubleValue(), DoubleMath.everySixteenthFactorial[i]);
}
}
-
+
public void testRoundIntegralDoubleToInt() {
for (double d : INTEGRAL_DOUBLE_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
@@ -350,6 +356,19 @@ public class DoubleMathTest extends TestCase {
}
}
+ public void testRoundLog2Exact() {
+ for (double x : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
+ boolean isPowerOfTwo = StrictMath.pow(2.0, DoubleMath.log2(x, FLOOR)) == x;
+ try {
+ int log2 = DoubleMath.log2(x, UNNECESSARY);
+ assertEquals(x, Math.scalb(1.0, log2));
+ assertTrue(isPowerOfTwo);
+ } catch (ArithmeticException e) {
+ assertFalse(isPowerOfTwo);
+ }
+ }
+ }
+
public void testRoundLog2ThrowsOnZerosInfinitiesAndNaN() {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
for (double d :
@@ -395,12 +414,12 @@ public class DoubleMathTest extends TestCase {
}
}
- public void testLog2SemiMonotonic(){
+ public void testLog2SemiMonotonic() {
for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
assertTrue(DoubleMath.log2(d + 0.01) >= DoubleMath.log2(d));
}
}
-
+
public void testLog2Negative() {
for (double d : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
assertTrue(Double.isNaN(DoubleMath.log2(-d)));
@@ -475,10 +494,120 @@ public class DoubleMathTest extends TestCase {
} catch (IllegalArgumentException expected) {}
}
}
-
- public void testNullPointers() throws Exception {
+
+ private static final ImmutableList<Double> FINITE_TOLERANCE_CANDIDATES =
+ ImmutableList.of(-0.0, 0.0, 1.0, 100.0, 10000.0, Double.MAX_VALUE);
+
+ private static final Iterable<Double> TOLERANCE_CANDIDATES =
+ Iterables.concat(FINITE_TOLERANCE_CANDIDATES, ImmutableList.of(Double.POSITIVE_INFINITY));
+
+ private static final List<Double> BAD_TOLERANCE_CANDIDATES =
+ Doubles.asList(-Double.MIN_VALUE, -Double.MIN_NORMAL, -1, -20, Double.NaN,
+ Double.NEGATIVE_INFINITY, -0.001);
+
+ public void testFuzzyEqualsFinite() {
+ for (double a : FINITE_DOUBLE_CANDIDATES) {
+ for (double b : FINITE_DOUBLE_CANDIDATES) {
+ for (double tolerance : FINITE_TOLERANCE_CANDIDATES) {
+ assertEquals(
+ Math.abs(a - b) <= tolerance,
+ DoubleMath.fuzzyEquals(a, b, tolerance));
+ }
+ }
+ }
+ }
+
+ public void testFuzzyInfiniteVersusFiniteWithFiniteTolerance() {
+ for (double inf : INFINITIES) {
+ for (double a : FINITE_DOUBLE_CANDIDATES) {
+ for (double tolerance : FINITE_TOLERANCE_CANDIDATES) {
+ assertFalse(DoubleMath.fuzzyEquals(a, inf, tolerance));
+ assertFalse(DoubleMath.fuzzyEquals(inf, a, tolerance));
+ }
+ }
+ }
+ }
+
+ public void testFuzzyInfiniteVersusInfiniteWithFiniteTolerance() {
+ for (double inf : INFINITIES) {
+ for (double tolerance : FINITE_TOLERANCE_CANDIDATES) {
+ assertTrue(DoubleMath.fuzzyEquals(inf, inf, tolerance));
+ assertFalse(DoubleMath.fuzzyEquals(inf, -inf, tolerance));
+ }
+ }
+ }
+
+ public void testFuzzyEqualsInfiniteTolerance() {
+ for (double a : DOUBLE_CANDIDATES_EXCEPT_NAN) {
+ for (double b : DOUBLE_CANDIDATES_EXCEPT_NAN) {
+ assertTrue(DoubleMath.fuzzyEquals(a, b, Double.POSITIVE_INFINITY));
+ }
+ }
+ }
+
+ public void testFuzzyEqualsOneNaN() {
+ for (double a : DOUBLE_CANDIDATES_EXCEPT_NAN) {
+ for (double tolerance : TOLERANCE_CANDIDATES) {
+ assertFalse(DoubleMath.fuzzyEquals(a, Double.NaN, tolerance));
+ assertFalse(DoubleMath.fuzzyEquals(Double.NaN, a, tolerance));
+ }
+ }
+ }
+
+ public void testFuzzyEqualsTwoNaNs() {
+ for (double tolerance : TOLERANCE_CANDIDATES) {
+ assertTrue(DoubleMath.fuzzyEquals(Double.NaN, Double.NaN, tolerance));
+ }
+ }
+
+ public void testFuzzyEqualsZeroTolerance() {
+ // make sure we test -0 tolerance
+ for (double zero : Doubles.asList(0.0, -0.0)) {
+ for (double a : ALL_DOUBLE_CANDIDATES) {
+ for (double b : ALL_DOUBLE_CANDIDATES) {
+ assertEquals(a == b || (Double.isNaN(a) && Double.isNaN(b)),
+ DoubleMath.fuzzyEquals(a, b, zero));
+ }
+ }
+ }
+ }
+
+ public void testFuzzyEqualsBadTolerance() {
+ for (double tolerance : BAD_TOLERANCE_CANDIDATES) {
+ try {
+ DoubleMath.fuzzyEquals(1, 2, tolerance);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // success
+ }
+ }
+ }
+
+ public void testFuzzyCompare() {
+ for (double a : ALL_DOUBLE_CANDIDATES) {
+ for (double b : ALL_DOUBLE_CANDIDATES) {
+ for (double tolerance : TOLERANCE_CANDIDATES) {
+ int expected = DoubleMath.fuzzyEquals(a, b, tolerance) ? 0 : Double.compare(a, b);
+ int actual = DoubleMath.fuzzyCompare(a, b, tolerance);
+ assertEquals(Integer.signum(expected), Integer.signum(actual));
+ }
+ }
+ }
+ }
+
+ public void testFuzzyCompareBadTolerance() {
+ for (double tolerance : BAD_TOLERANCE_CANDIDATES) {
+ try {
+ DoubleMath.fuzzyCompare(1, 2, tolerance);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ // success
+ }
+ }
+ }
+
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
- tester.setDefault(RoundingMode.class, FLOOR);
tester.setDefault(double.class, 3.0);
tester.testAllPublicStaticMethods(DoubleMath.class);
}
diff --git a/guava-tests/test/com/google/common/math/DoubleUtilsTest.java b/guava-tests/test/com/google/common/math/DoubleUtilsTest.java
index f2f99a7..65952aa 100644
--- a/guava-tests/test/com/google/common/math/DoubleUtilsTest.java
+++ b/guava-tests/test/com/google/common/math/DoubleUtilsTest.java
@@ -1,39 +1,40 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.google.common.math;
import static com.google.common.math.MathTesting.ALL_BIGINTEGER_CANDIDATES;
-import static com.google.common.math.MathTesting.ALL_DOUBLE_CANDIDATES;
-import static com.google.common.math.MathTesting.EXPONENTS;
import static com.google.common.math.MathTesting.FINITE_DOUBLE_CANDIDATES;
-
-import java.math.BigInteger;
+import static com.google.common.math.MathTesting.POSITIVE_FINITE_DOUBLE_CANDIDATES;
import junit.framework.TestCase;
-import sun.misc.FpUtils;
-
-public class DoubleUtilsTest extends TestCase {
- public strictfp void testScalbPositiveExponent() {
- for (int k : EXPONENTS) {
- for (double d : ALL_DOUBLE_CANDIDATES) {
- assertEquals(d * StrictMath.pow(2.0, k), DoubleUtils.scalb(d, k));
- }
- }
- }
- public void testGetExponent() {
- for (double d : ALL_DOUBLE_CANDIDATES) {
- assertEquals(FpUtils.getExponent(d), DoubleUtils.getExponent(d));
- }
- }
+import sun.misc.FpUtils;
- public void testNextUp() {
- for (double d : FINITE_DOUBLE_CANDIDATES) {
- assertEquals(FpUtils.nextUp(d), DoubleUtils.next(d, true));
- }
- }
+import java.math.BigInteger;
+/**
+ * Tests for {@link DoubleUtils}.
+ *
+ * @author Louis Wasserman
+ */
+public class DoubleUtilsTest extends TestCase {
public void testNextDown() {
for (double d : FINITE_DOUBLE_CANDIDATES) {
- assertEquals(FpUtils.nextDown(d), DoubleUtils.next(d, false));
+ assertEquals(FpUtils.nextDown(d), DoubleUtils.nextDown(d));
}
}
@@ -42,4 +43,19 @@ public class DoubleUtilsTest extends TestCase {
assertEquals(b.doubleValue(), DoubleUtils.bigToDouble(b));
}
}
+
+ public void testEnsureNonNegative() {
+ assertEquals(0.0, DoubleUtils.ensureNonNegative(0.0));
+ for (double positiveValue : POSITIVE_FINITE_DOUBLE_CANDIDATES) {
+ assertEquals(positiveValue, DoubleUtils.ensureNonNegative(positiveValue));
+ assertEquals(0.0, DoubleUtils.ensureNonNegative(-positiveValue));
+ }
+ assertEquals(Double.POSITIVE_INFINITY, DoubleUtils.ensureNonNegative(Double.POSITIVE_INFINITY));
+ assertEquals(0.0, DoubleUtils.ensureNonNegative(Double.NEGATIVE_INFINITY));
+ try {
+ DoubleUtils.ensureNonNegative(Double.NaN);
+ fail("Expected IllegalArgumentException from ensureNonNegative(Double.NaN)");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
}
diff --git a/guava-tests/test/com/google/common/math/IntMathTest.java b/guava-tests/test/com/google/common/math/IntMathTest.java
index 7f773ea..dcfd8a9 100644
--- a/guava-tests/test/com/google/common/math/IntMathTest.java
+++ b/guava-tests/test/com/google/common/math/IntMathTest.java
@@ -23,6 +23,7 @@ import static com.google.common.math.MathTesting.EXPONENTS;
import static com.google.common.math.MathTesting.NEGATIVE_INTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.NONZERO_INTEGER_CANDIDATES;
import static com.google.common.math.MathTesting.POSITIVE_INTEGER_CANDIDATES;
+import static com.google.common.math.TestPlatform.intsCanGoOutOfRange;
import static java.math.BigInteger.valueOf;
import static java.math.RoundingMode.FLOOR;
import static java.math.RoundingMode.UNNECESSARY;
@@ -53,48 +54,58 @@ public class IntMathTest extends TestCase {
@GwtIncompatible("pow()")
public void testConstantsPowersOf10() {
- for (int i = 0; i < IntMath.POWERS_OF_10.length; i++) {
- assertEquals(IntMath.pow(10, i), IntMath.POWERS_OF_10[i]);
+ for (int i = 0; i < IntMath.powersOf10.length - 1; i++) {
+ assertEquals(IntMath.pow(10, i), IntMath.powersOf10[i]);
+ }
+ }
+
+ @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
+ public void testMaxLog10ForLeadingZeros() {
+ for (int i = 0; i < Integer.SIZE; i++) {
+ assertEquals(
+ BigIntegerMath.log10(BigInteger.ONE.shiftLeft(Integer.SIZE - i), FLOOR),
+ IntMath.maxLog10ForLeadingZeros[i]);
}
}
@GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
public void testConstantsHalfPowersOf10() {
- for (int i = 0; i < IntMath.HALF_POWERS_OF_10.length; i++) {
- assert IntMath.HALF_POWERS_OF_10[i]
+ for (int i = 0; i < IntMath.halfPowersOf10.length; i++) {
+ assert IntMath.halfPowersOf10[i]
== Math.min(Integer.MAX_VALUE,
BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * i + 1), FLOOR).longValue());
}
}
@GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
- public void testConstantsBiggestBinomials(){
- for (int k = 0; k < IntMath.BIGGEST_BINOMIALS.length; k++) {
- assertTrue(fitsInInt(BigIntegerMath.binomial(IntMath.BIGGEST_BINOMIALS[k], k)));
- assertTrue(IntMath.BIGGEST_BINOMIALS[k] == Integer.MAX_VALUE
- || !fitsInInt(BigIntegerMath.binomial(IntMath.BIGGEST_BINOMIALS[k] + 1, k)));
+ public void testConstantsBiggestBinomials() {
+ for (int k = 0; k < IntMath.biggestBinomials.length; k++) {
+ assertTrue(fitsInInt(BigIntegerMath.binomial(IntMath.biggestBinomials[k], k)));
+ assertTrue(IntMath.biggestBinomials[k] == Integer.MAX_VALUE
+ || !fitsInInt(BigIntegerMath.binomial(IntMath.biggestBinomials[k] + 1, k)));
// In the first case, any int is valid; in the second, we want to test that the next-bigger
// int overflows.
}
assertFalse(
fitsInInt(BigIntegerMath.binomial(
- 2 * IntMath.BIGGEST_BINOMIALS.length, IntMath.BIGGEST_BINOMIALS.length)));
+ 2 * IntMath.biggestBinomials.length, IntMath.biggestBinomials.length)));
}
-
+
@GwtIncompatible("sqrt")
public void testPowersSqrtMaxInt() {
assertEquals(IntMath.sqrt(Integer.MAX_VALUE, FLOOR), IntMath.FLOOR_SQRT_MAX_INT);
}
+ @GwtIncompatible("java.math.BigInteger")
public void testIsPowerOfTwo() {
for (int x : ALL_INTEGER_CANDIDATES) {
// Checks for a single bit set.
- boolean expected = x > 0 & (x & (x - 1)) == 0;
+ BigInteger bigX = BigInteger.valueOf(x);
+ boolean expected = (bigX.signum() > 0) && (bigX.bitCount() == 1);
assertEquals(expected, IntMath.isPowerOfTwo(x));
}
}
- @GwtIncompatible("log2")
public void testLog2ZeroAlwaysThrows() {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
try {
@@ -104,7 +115,6 @@ public class IntMathTest extends TestCase {
}
}
- @GwtIncompatible("log2")
public void testLog2NegativeAlwaysThrows() {
for (int x : NEGATIVE_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -117,7 +127,6 @@ public class IntMathTest extends TestCase {
}
// Relies on the correctness of BigIntegrerMath.log2 for all modes except UNNECESSARY.
- @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
public void testLog2MatchesBigInteger() {
for (int x : POSITIVE_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
@@ -127,7 +136,6 @@ public class IntMathTest extends TestCase {
}
// Relies on the correctness of isPowerOfTwo(int).
- @GwtIncompatible("log2")
public void testLog2Exact() {
for (int x : POSITIVE_INTEGER_CANDIDATES) {
// We only expect an exception if x was not a power of 2.
@@ -255,36 +263,41 @@ public class IntMathTest extends TestCase {
}
}
- @GwtIncompatible("-2147483648/1 expected=2147483648")
public void testDivNonZero() {
for (int p : NONZERO_INTEGER_CANDIDATES) {
for (int q : NONZERO_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
+ // Skip some tests that fail due to GWT's non-compliant int implementation.
+ // TODO(cpovirk): does this test fail for only some rounding modes or for all?
+ if (p == -2147483648 && q == -1 && intsCanGoOutOfRange()) {
+ continue;
+ }
int expected =
new BigDecimal(valueOf(p)).divide(new BigDecimal(valueOf(q)), 0, mode).intValue();
- assertEquals(p + "/" + q, expected, IntMath.divide(p, q, mode));
+ assertEquals(p + "/" + q, force32(expected), IntMath.divide(p, q, mode));
}
}
}
}
- @GwtIncompatible("-2147483648/-1 not expected to divide evenly")
public void testDivNonZeroExact() {
for (int p : NONZERO_INTEGER_CANDIDATES) {
for (int q : NONZERO_INTEGER_CANDIDATES) {
+ // Skip some tests that fail due to GWT's non-compliant int implementation.
+ if (p == -2147483648 && q == -1 && intsCanGoOutOfRange()) {
+ continue;
+ }
boolean dividesEvenly = (p % q) == 0;
-
try {
assertEquals(p + "/" + q, p, IntMath.divide(p, q, UNNECESSARY) * q);
- assertTrue(p + "/" + q + " expected to divide evenly", dividesEvenly);
+ assertTrue(p + "/" + q + " not expected to divide evenly", dividesEvenly);
} catch (ArithmeticException e) {
- assertFalse(p + "/" + q + " not expected to divide evenly", dividesEvenly);
+ assertFalse(p + "/" + q + " expected to divide evenly", dividesEvenly);
}
}
}
}
- @GwtIncompatible("pow()")
public void testZeroDivIsAlwaysZero() {
for (int q : NONZERO_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -293,7 +306,6 @@ public class IntMathTest extends TestCase {
}
}
- @GwtIncompatible("pow()")
public void testDivByZeroAlwaysFails() {
for (int p : ALL_INTEGER_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -420,14 +432,13 @@ public class IntMathTest extends TestCase {
}
}
- @GwtIncompatible("-2147483648^1 expected=2147483648")
public void testCheckedPow() {
for (int b : ALL_INTEGER_CANDIDATES) {
for (int k : EXPONENTS) {
BigInteger expectedResult = valueOf(b).pow(k);
boolean expectedSuccess = fitsInInt(expectedResult);
try {
- assertEquals(b + "^" + k, expectedResult.intValue(), IntMath.checkedPow(b, k));
+ assertEquals(b + "^" + k, force32(expectedResult.intValue()), IntMath.checkedPow(b, k));
assertTrue(b + "^" + k + " should have succeeded", expectedSuccess);
} catch (ArithmeticException e) {
assertFalse(b + "^" + k + " should have failed", expectedSuccess);
@@ -437,7 +448,6 @@ public class IntMathTest extends TestCase {
}
// Depends on the correctness of BigIntegerMath.factorial.
- @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
public void testFactorial() {
for (int n = 0; n <= 50; n++) {
BigInteger expectedBig = BigIntegerMath.factorial(n);
@@ -446,7 +456,6 @@ public class IntMathTest extends TestCase {
}
}
- @GwtIncompatible("factorial")
public void testFactorialNegative() {
for (int n : NEGATIVE_INTEGER_CANDIDATES) {
try {
@@ -492,15 +501,87 @@ public class IntMathTest extends TestCase {
}
}
- private boolean fitsInInt(BigInteger big) {
+ @GwtIncompatible("java.math.BigInteger")
+ public void testMean() {
+ // Odd-sized ranges have an obvious mean
+ assertMean(2, 1, 3);
+
+ assertMean(-2, -3, -1);
+ assertMean(0, -1, 1);
+ assertMean(1, -1, 3);
+ assertMean((1 << 30) - 1, -1, Integer.MAX_VALUE);
+
+ // Even-sized ranges should prefer the lower mean
+ assertMean(2, 1, 4);
+ assertMean(-3, -4, -1);
+ assertMean(0, -1, 2);
+ assertMean(0, Integer.MIN_VALUE + 2, Integer.MAX_VALUE);
+ assertMean(0, 0, 1);
+ assertMean(-1, -1, 0);
+ assertMean(-1, Integer.MIN_VALUE, Integer.MAX_VALUE);
+
+ // x == y == mean
+ assertMean(1, 1, 1);
+ assertMean(0, 0, 0);
+ assertMean(-1, -1, -1);
+ assertMean(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
+ assertMean(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
+
+ // Exhaustive checks
+ for (int x : ALL_INTEGER_CANDIDATES) {
+ for (int y : ALL_INTEGER_CANDIDATES) {
+ assertMean(x, y);
+ }
+ }
+ }
+
+ /**
+ * Helper method that asserts the arithmetic mean of x and y is equal
+ * to the expectedMean.
+ */
+ private static void assertMean(int expectedMean, int x, int y) {
+ assertEquals("The expectedMean should be the same as computeMeanSafely",
+ expectedMean, computeMeanSafely(x, y));
+ assertMean(x, y);
+ }
+
+ /**
+ * Helper method that asserts the arithmetic mean of x and y is equal
+ * to the result of computeMeanSafely.
+ */
+ private static void assertMean(int x, int y) {
+ int expectedMean = computeMeanSafely(x, y);
+ assertEquals(expectedMean, IntMath.mean(x, y));
+ assertEquals("The mean of x and y should equal the mean of y and x",
+ expectedMean, IntMath.mean(y, x));
+ }
+
+ /**
+ * Computes the mean in a way that is obvious and resilient to
+ * overflow by using BigInteger arithmetic.
+ */
+ private static int computeMeanSafely(int x, int y) {
+ BigInteger bigX = BigInteger.valueOf(x);
+ BigInteger bigY = BigInteger.valueOf(y);
+ BigDecimal bigMean = new BigDecimal(bigX.add(bigY))
+ .divide(BigDecimal.valueOf(2), BigDecimal.ROUND_FLOOR);
+ // parseInt blows up on overflow as opposed to intValue() which does not.
+ return Integer.parseInt(bigMean.toString());
+ }
+
+ private static boolean fitsInInt(BigInteger big) {
return big.bitLength() <= 31;
}
-
+
@GwtIncompatible("NullPointerTester")
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.setDefault(int.class, 1);
- tester.setDefault(RoundingMode.class, FLOOR);
tester.testAllPublicStaticMethods(IntMath.class);
}
+
+ private static int force32(int value) {
+ // GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
+ return value & 0xffffffff;
+ }
}
diff --git a/guava-tests/test/com/google/common/math/LongMathTest.java b/guava-tests/test/com/google/common/math/LongMathTest.java
index 3ab0a8e..089bf03 100644
--- a/guava-tests/test/com/google/common/math/LongMathTest.java
+++ b/guava-tests/test/com/google/common/math/LongMathTest.java
@@ -30,6 +30,8 @@ import static java.math.BigInteger.valueOf;
import static java.math.RoundingMode.FLOOR;
import static java.math.RoundingMode.UNNECESSARY;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.testing.NullPointerTester;
import junit.framework.TestCase;
@@ -43,75 +45,92 @@ import java.math.RoundingMode;
*
* @author Louis Wasserman
*/
+@GwtCompatible(emulated = true)
public class LongMathTest extends TestCase {
+ @GwtIncompatible("TODO")
public void testConstantMaxPowerOfSqrt2Unsigned() {
assertEquals(BigIntegerMath.sqrt(BigInteger.ZERO.setBit(2 * Long.SIZE - 1), FLOOR).longValue(),
LongMath.MAX_POWER_OF_SQRT2_UNSIGNED);
}
+ @GwtIncompatible("BigIntegerMath") // TODO(cpovirk): GWT-enable BigIntegerMath
+ public void testMaxLog10ForLeadingZeros() {
+ for (int i = 0; i < Long.SIZE; i++) {
+ assertEquals(
+ BigIntegerMath.log10(BigInteger.ONE.shiftLeft(Long.SIZE - i), FLOOR),
+ LongMath.maxLog10ForLeadingZeros[i]);
+ }
+ }
+
+ @GwtIncompatible("TODO")
public void testConstantsPowersOf10() {
- for (int i = 0; i < LongMath.POWERS_OF_10.length; i++) {
- assertEquals(LongMath.checkedPow(10, i), LongMath.POWERS_OF_10[i]);
+ for (int i = 0; i < LongMath.powersOf10.length; i++) {
+ assertEquals(LongMath.checkedPow(10, i), LongMath.powersOf10[i]);
}
try {
- LongMath.checkedPow(10, LongMath.POWERS_OF_10.length);
+ LongMath.checkedPow(10, LongMath.powersOf10.length);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
+ @GwtIncompatible("TODO")
public void testConstantsHalfPowersOf10() {
- for (int i = 0; i < LongMath.HALF_POWERS_OF_10.length; i++) {
+ for (int i = 0; i < LongMath.halfPowersOf10.length; i++) {
assertEquals(BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * i + 1), FLOOR),
- BigInteger.valueOf(LongMath.HALF_POWERS_OF_10[i]));
+ BigInteger.valueOf(LongMath.halfPowersOf10[i]));
}
BigInteger nextBigger =
- BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * LongMath.HALF_POWERS_OF_10.length + 1), FLOOR);
+ BigIntegerMath.sqrt(BigInteger.TEN.pow(2 * LongMath.halfPowersOf10.length + 1), FLOOR);
assertTrue(nextBigger.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0);
}
+ @GwtIncompatible("TODO")
public void testConstantsSqrtMaxLong() {
assertEquals(LongMath.sqrt(Long.MAX_VALUE, FLOOR), LongMath.FLOOR_SQRT_MAX_LONG);
}
+ @GwtIncompatible("TODO")
public void testConstantsFactorials() {
long expected = 1;
- for (int i = 0; i < LongMath.FACTORIALS.length; i++, expected *= i) {
- assertEquals(expected, LongMath.FACTORIALS[i]);
+ for (int i = 0; i < LongMath.factorials.length; i++, expected *= i) {
+ assertEquals(expected, LongMath.factorials[i]);
}
try {
LongMath.checkedMultiply(
- LongMath.FACTORIALS[LongMath.FACTORIALS.length - 1], LongMath.FACTORIALS.length);
+ LongMath.factorials[LongMath.factorials.length - 1], LongMath.factorials.length);
fail("Expected ArithmeticException");
} catch (ArithmeticException expect) {}
}
+ @GwtIncompatible("TODO")
public void testConstantsBiggestBinomials() {
- for (int k = 0; k < LongMath.BIGGEST_BINOMIALS.length; k++) {
- assertTrue(fitsInLong(BigIntegerMath.binomial(LongMath.BIGGEST_BINOMIALS[k], k)));
- assertTrue(LongMath.BIGGEST_BINOMIALS[k] == Integer.MAX_VALUE
- || !fitsInLong(BigIntegerMath.binomial(LongMath.BIGGEST_BINOMIALS[k] + 1, k)));
+ for (int k = 0; k < LongMath.biggestBinomials.length; k++) {
+ assertTrue(fitsInLong(BigIntegerMath.binomial(LongMath.biggestBinomials[k], k)));
+ assertTrue(LongMath.biggestBinomials[k] == Integer.MAX_VALUE
+ || !fitsInLong(BigIntegerMath.binomial(LongMath.biggestBinomials[k] + 1, k)));
// In the first case, any long is valid; in the second, we want to test that the next-bigger
// long overflows.
}
- int k = LongMath.BIGGEST_BINOMIALS.length;
+ int k = LongMath.biggestBinomials.length;
assertFalse(fitsInLong(BigIntegerMath.binomial(2 * k, k)));
// 2 * k is the smallest value for which we don't replace k with (n-k).
}
+ @GwtIncompatible("TODO")
public void testConstantsBiggestSimpleBinomials() {
- for (int k = 0; k < LongMath.BIGGEST_SIMPLE_BINOMIALS.length; k++) {
- assertTrue(LongMath.BIGGEST_SIMPLE_BINOMIALS[k] <= LongMath.BIGGEST_BINOMIALS[k]);
- simpleBinomial(LongMath.BIGGEST_SIMPLE_BINOMIALS[k], k); // mustn't throw
- if (LongMath.BIGGEST_SIMPLE_BINOMIALS[k] < Integer.MAX_VALUE) {
+ for (int k = 0; k < LongMath.biggestSimpleBinomials.length; k++) {
+ assertTrue(LongMath.biggestSimpleBinomials[k] <= LongMath.biggestBinomials[k]);
+ simpleBinomial(LongMath.biggestSimpleBinomials[k], k); // mustn't throw
+ if (LongMath.biggestSimpleBinomials[k] < Integer.MAX_VALUE) {
// unless all n are fair game with this k
try {
- simpleBinomial(LongMath.BIGGEST_SIMPLE_BINOMIALS[k] + 1, k);
+ simpleBinomial(LongMath.biggestSimpleBinomials[k] + 1, k);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
}
try {
- int k = LongMath.BIGGEST_SIMPLE_BINOMIALS.length;
+ int k = LongMath.biggestSimpleBinomials.length;
simpleBinomial(2 * k, k);
// 2 * k is the smallest value for which we don't replace k with (n-k).
fail("Expected ArithmeticException");
@@ -119,6 +138,7 @@ public class LongMathTest extends TestCase {
}
// Throws an ArithmeticException if "the simple implementation" of binomial coefficients overflows
+ @GwtIncompatible("TODO")
private long simpleBinomial(int n, int k) {
long accum = 1;
for (int i = 0; i < k; i++) {
@@ -128,10 +148,12 @@ public class LongMathTest extends TestCase {
return accum;
}
+ @GwtIncompatible("java.math.BigInteger")
public void testIsPowerOfTwo() {
for (long x : ALL_LONG_CANDIDATES) {
// Checks for a single bit set.
- boolean expected = x > 0 & (x & (x - 1)) == 0L;
+ BigInteger bigX = BigInteger.valueOf(x);
+ boolean expected = (bigX.signum() > 0) && (bigX.bitCount() == 1);
assertEquals(expected, LongMath.isPowerOfTwo(x));
}
}
@@ -180,6 +202,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testLog10ZeroAlwaysThrows() {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
try {
@@ -189,6 +212,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testLog10NegativeAlwaysThrows() {
for (long x : NEGATIVE_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -201,6 +225,7 @@ public class LongMathTest extends TestCase {
}
// Relies on the correctness of BigIntegerMath.log10 for all modes except UNNECESSARY.
+ @GwtIncompatible("TODO")
public void testLog10MatchesBigInteger() {
for (long x : POSITIVE_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
@@ -210,6 +235,7 @@ public class LongMathTest extends TestCase {
}
// Relies on the correctness of log10(long, FLOOR) and of pow(long, int).
+ @GwtIncompatible("TODO")
public void testLog10Exact() {
for (long x : POSITIVE_LONG_CANDIDATES) {
int floor = LongMath.log10(x, FLOOR);
@@ -223,6 +249,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testLog10TrivialOnPowerOf10() {
long x = 1000000000000L;
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -230,6 +257,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testSqrtNegativeAlwaysThrows() {
for (long x : NEGATIVE_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -242,6 +270,7 @@ public class LongMathTest extends TestCase {
}
// Relies on the correctness of BigIntegerMath.sqrt for all modes except UNNECESSARY.
+ @GwtIncompatible("TODO")
public void testSqrtMatchesBigInteger() {
for (long x : POSITIVE_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_SAFE_ROUNDING_MODES) {
@@ -253,6 +282,7 @@ public class LongMathTest extends TestCase {
}
/* Relies on the correctness of sqrt(long, FLOOR). */
+ @GwtIncompatible("TODO")
public void testSqrtExactMatchesFloorOrThrows() {
for (long x : POSITIVE_LONG_CANDIDATES) {
long logFloor = LongMath.sqrt(x, FLOOR);
@@ -267,6 +297,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testPow() {
for (long i : ALL_LONG_CANDIDATES) {
for (int exp : EXPONENTS) {
@@ -277,6 +308,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testDivNonZero() {
for (long p : NONZERO_LONG_CANDIDATES) {
for (long q : NONZERO_LONG_CANDIDATES) {
@@ -289,6 +321,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testDivNonZeroExact() {
for (long p : NONZERO_LONG_CANDIDATES) {
for (long q : NONZERO_LONG_CANDIDATES) {
@@ -304,6 +337,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testZeroDivIsAlwaysZero() {
for (long q : NONZERO_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -312,6 +346,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testDivByZeroAlwaysFails() {
for (long p : ALL_LONG_CANDIDATES) {
for (RoundingMode mode : ALL_ROUNDING_MODES) {
@@ -323,6 +358,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testIntMod() {
for (long x : ALL_LONG_CANDIDATES) {
for (int m : POSITIVE_INTEGER_CANDIDATES) {
@@ -333,6 +369,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testIntModNegativeModulusFails() {
for (long x : ALL_LONG_CANDIDATES) {
for (int m : NEGATIVE_INTEGER_CANDIDATES) {
@@ -344,6 +381,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testIntModZeroModulusFails() {
for (long x : ALL_LONG_CANDIDATES) {
try {
@@ -353,6 +391,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testMod() {
for (long x : ALL_LONG_CANDIDATES) {
for (long m : POSITIVE_LONG_CANDIDATES) {
@@ -363,6 +402,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testModNegativeModulusFails() {
for (long x : ALL_LONG_CANDIDATES) {
for (long m : NEGATIVE_LONG_CANDIDATES) {
@@ -374,7 +414,7 @@ public class LongMathTest extends TestCase {
}
}
- public void testGCD() {
+ public void testGCDExhaustive() {
for (long a : POSITIVE_LONG_CANDIDATES) {
for (long b : POSITIVE_LONG_CANDIDATES) {
assertEquals(valueOf(a).gcd(valueOf(b)), valueOf(LongMath.gcd(a, b)));
@@ -382,6 +422,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testGCDZero() {
for (long a : POSITIVE_LONG_CANDIDATES) {
assertEquals(a, LongMath.gcd(a, 0));
@@ -390,6 +431,7 @@ public class LongMathTest extends TestCase {
assertEquals(0, LongMath.gcd(0, 0));
}
+ @GwtIncompatible("TODO")
public void testGCDNegativePositiveThrows() {
for (long a : NEGATIVE_LONG_CANDIDATES) {
try {
@@ -403,6 +445,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testGCDNegativeZeroThrows() {
for (long a : NEGATIVE_LONG_CANDIDATES) {
try {
@@ -416,6 +459,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testCheckedAdd() {
for (long a : ALL_INTEGER_CANDIDATES) {
for (long b : ALL_INTEGER_CANDIDATES) {
@@ -431,6 +475,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testCheckedSubtract() {
for (long a : ALL_INTEGER_CANDIDATES) {
for (long b : ALL_INTEGER_CANDIDATES) {
@@ -446,6 +491,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testCheckedMultiply() {
for (long a : ALL_INTEGER_CANDIDATES) {
for (long b : ALL_INTEGER_CANDIDATES) {
@@ -461,6 +507,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testCheckedPow() {
for (long b : ALL_INTEGER_CANDIDATES) {
for (int exp : EXPONENTS) {
@@ -477,6 +524,7 @@ public class LongMathTest extends TestCase {
}
// Depends on the correctness of BigIntegerMath.factorial.
+ @GwtIncompatible("TODO")
public void testFactorial() {
for (int n = 0; n <= 50; n++) {
BigInteger expectedBig = BigIntegerMath.factorial(n);
@@ -485,6 +533,7 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("TODO")
public void testFactorialNegative() {
for (int n : NEGATIVE_INTEGER_CANDIDATES) {
try {
@@ -505,6 +554,17 @@ public class LongMathTest extends TestCase {
}
}
+ @GwtIncompatible("Slow")
+ public void testBinomial_exhaustiveNotOverflowing() {
+ // Tests all of the inputs to LongMath.binomial that won't cause it to overflow, that weren't
+ // tested in the previous method, for k >= 3.
+ for (int k = 3; k < LongMath.biggestBinomials.length; k++) {
+ for (int n = 70; n <= LongMath.biggestBinomials[k]; n++) {
+ assertEquals(BigIntegerMath.binomial(n, k).longValue(), LongMath.binomial(n, k));
+ }
+ }
+ }
+
public void testBinomialOutside() {
for (int n = 0; n <= 50; n++) {
try {
@@ -527,13 +587,81 @@ public class LongMathTest extends TestCase {
}
}
- private boolean fitsInLong(BigInteger big) {
+ @GwtIncompatible("java.math.BigInteger")
+ public void testMean() {
+ // Odd-sized ranges have an obvious mean
+ assertMean(2, 1, 3);
+
+ assertMean(-2, -3, -1);
+ assertMean(0, -1, 1);
+ assertMean(1, -1, 3);
+ assertMean((1L << 62) - 1, -1, Long.MAX_VALUE);
+
+ // Even-sized ranges should prefer the lower mean
+ assertMean(2, 1, 4);
+ assertMean(-3, -4, -1);
+ assertMean(0, -1, 2);
+ assertMean(0, Long.MIN_VALUE + 2, Long.MAX_VALUE);
+ assertMean(0, 0, 1);
+ assertMean(-1, -1, 0);
+ assertMean(-1, Long.MIN_VALUE, Long.MAX_VALUE);
+
+ // x == y == mean
+ assertMean(1, 1, 1);
+ assertMean(0, 0, 0);
+ assertMean(-1, -1, -1);
+ assertMean(Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE);
+ assertMean(Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE);
+
+ // Exhaustive checks
+ for (long x : ALL_LONG_CANDIDATES) {
+ for (long y : ALL_LONG_CANDIDATES) {
+ assertMean(x, y);
+ }
+ }
+ }
+
+ /**
+ * Helper method that asserts the arithmetic mean of x and y is equal
+ * to the expectedMean.
+ */
+ private static void assertMean(long expectedMean, long x, long y) {
+ assertEquals("The expectedMean should be the same as computeMeanSafely",
+ expectedMean, computeMeanSafely(x, y));
+ assertMean(x, y);
+ }
+
+ /**
+ * Helper method that asserts the arithmetic mean of x and y is equal
+ *to the result of computeMeanSafely.
+ */
+ private static void assertMean(long x, long y) {
+ long expectedMean = computeMeanSafely(x, y);
+ assertEquals(expectedMean, LongMath.mean(x, y));
+ assertEquals("The mean of x and y should equal the mean of y and x",
+ expectedMean, LongMath.mean(y, x));
+ }
+
+ /**
+ * Computes the mean in a way that is obvious and resilient to
+ * overflow by using BigInteger arithmetic.
+ */
+ private static long computeMeanSafely(long x, long y) {
+ BigInteger bigX = BigInteger.valueOf(x);
+ BigInteger bigY = BigInteger.valueOf(y);
+ BigDecimal bigMean = new BigDecimal(bigX.add(bigY))
+ .divide(BigDecimal.valueOf(2), BigDecimal.ROUND_FLOOR);
+ // parseInt blows up on overflow as opposed to intValue() which does not.
+ return Long.parseLong(bigMean.toString());
+ }
+
+ private static boolean fitsInLong(BigInteger big) {
return big.bitLength() <= 63;
}
- public void testNullPointers() throws Exception {
+ @GwtIncompatible("NullPointerTester")
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
- tester.setDefault(RoundingMode.class, FLOOR);
tester.setDefault(int.class, 1);
tester.setDefault(long.class, 1L);
tester.testAllPublicStaticMethods(LongMath.class);
diff --git a/guava-tests/test/com/google/common/math/MathBenchmarking.java b/guava-tests/test/com/google/common/math/MathBenchmarking.java
new file mode 100644
index 0000000..856f995
--- /dev/null
+++ b/guava-tests/test/com/google/common/math/MathBenchmarking.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.math;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+/**
+ * Utilities for benchmarks.
+ *
+ * @author Louis Wasserman
+ */
+final class MathBenchmarking {
+ static final int ARRAY_SIZE = 0x10000;
+ static final int ARRAY_MASK = 0x0ffff;
+ static final Random RANDOM_SOURCE = new Random(314159265358979L);
+ static final int MAX_EXPONENT = 100;
+
+ /*
+ * Duplicated from LongMath.
+ * binomial(biggestBinomials[k], k) fits in a long, but not
+ * binomial(biggestBinomials[k] + 1, k).
+ */
+ static final int[] biggestBinomials =
+ {Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 3810779, 121977, 16175, 4337, 1733,
+ 887, 534, 361, 265, 206, 169, 143, 125, 111, 101, 94, 88, 83, 79, 76, 74, 72, 70, 69, 68,
+ 67, 67, 66, 66, 66, 66};
+
+ static BigInteger randomPositiveBigInteger(int numBits) {
+ int digits = RANDOM_SOURCE.nextInt(numBits) + 1;
+ return new BigInteger(digits, RANDOM_SOURCE).add(BigInteger.ONE);
+ }
+
+ static BigInteger randomNonNegativeBigInteger(int numBits) {
+ int digits = RANDOM_SOURCE.nextInt(numBits) + 1;
+ return new BigInteger(digits, RANDOM_SOURCE);
+ }
+
+ static BigInteger randomNonZeroBigInteger(int numBits) {
+ BigInteger result = randomPositiveBigInteger(numBits);
+ return RANDOM_SOURCE.nextBoolean() ? result : result.negate();
+ }
+
+ static BigInteger randomBigInteger(int numBits) {
+ BigInteger result = randomNonNegativeBigInteger(numBits);
+ return RANDOM_SOURCE.nextBoolean() ? result : result.negate();
+ }
+
+ static double randomDouble(int maxExponent) {
+ double result = RANDOM_SOURCE.nextDouble();
+ result = Math.scalb(result, RANDOM_SOURCE.nextInt(maxExponent + 1));
+ return RANDOM_SOURCE.nextBoolean() ? result : -result;
+ }
+
+ /**
+ * Returns a random integer between zero and {@code MAX_EXPONENT}.
+ */
+ static int randomExponent() {
+ return RANDOM_SOURCE.nextInt(MAX_EXPONENT + 1);
+ }
+
+ static double randomPositiveDouble() {
+ return Math.exp(randomDouble(6));
+ }
+}
diff --git a/guava-tests/test/com/google/common/math/MathPreconditionsTest.java b/guava-tests/test/com/google/common/math/MathPreconditionsTest.java
new file mode 100644
index 0000000..b776ee1
--- /dev/null
+++ b/guava-tests/test/com/google/common/math/MathPreconditionsTest.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.math;
+
+import com.google.common.annotations.GwtCompatible;
+
+import junit.framework.TestCase;
+
+import java.math.BigInteger;
+
+/**
+ * Unit tests for {@link MathPreconditions}.
+ *
+ * @author Ben Yu
+ */
+@GwtCompatible
+public class MathPreconditionsTest extends TestCase {
+
+ public void testCheckPositive_zeroInt() {
+ try {
+ MathPreconditions.checkPositive("int", 0);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckPositive_maxInt() {
+ MathPreconditions.checkPositive("int", Integer.MAX_VALUE);
+ }
+
+ public void testCheckPositive_minInt() {
+ try {
+ MathPreconditions.checkPositive("int", Integer.MIN_VALUE);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckPositive_positiveInt() {
+ MathPreconditions.checkPositive("int", 1);
+ }
+
+ public void testCheckPositive_negativeInt() {
+ try {
+ MathPreconditions.checkPositive("int", -1);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckPositive_zeroLong() {
+ try {
+ MathPreconditions.checkPositive("long", 0L);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckPositive_maxLong() {
+ MathPreconditions.checkPositive("long", Long.MAX_VALUE);
+ }
+
+ public void testCheckPositive_minLong() {
+ try {
+ MathPreconditions.checkPositive("long", Long.MIN_VALUE);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckPositive_positiveLong() {
+ MathPreconditions.checkPositive("long", 1);
+ }
+
+ public void testCheckPositive_negativeLong() {
+ try {
+ MathPreconditions.checkPositive("long", -1L);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckPositive_zeroBigInteger() {
+ try {
+ MathPreconditions.checkPositive("BigInteger", BigInteger.ZERO);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckPositive_postiveBigInteger() {
+ MathPreconditions.checkPositive("BigInteger", BigInteger.ONE);
+ }
+
+ public void testCheckPositive_negativeBigInteger() {
+ try {
+ MathPreconditions.checkPositive("BigInteger", BigInteger.ZERO.negate());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckNonNegative_zeroInt() {
+ MathPreconditions.checkNonNegative("int", 0);
+ }
+
+ public void testCheckNonNegative_maxInt() {
+ MathPreconditions.checkNonNegative("int", Integer.MAX_VALUE);
+ }
+
+ public void testCheckNonNegative_minInt() {
+ try {
+ MathPreconditions.checkNonNegative("int", Integer.MIN_VALUE);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckNonNegative_positiveInt() {
+ MathPreconditions.checkNonNegative("int", 1);
+ }
+
+ public void testCheckNonNegative_negativeInt() {
+ try {
+ MathPreconditions.checkNonNegative("int", -1);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckNonNegative_zeroLong() {
+ MathPreconditions.checkNonNegative("long", 0L);
+ }
+
+ public void testCheckNonNegative_maxLong() {
+ MathPreconditions.checkNonNegative("long", Long.MAX_VALUE);
+ }
+
+ public void testCheckNonNegative_minLong() {
+ try {
+ MathPreconditions.checkNonNegative("long", Long.MIN_VALUE);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckNonNegative_positiveLong() {
+ MathPreconditions.checkNonNegative("long", 1L);
+ }
+
+ public void testCheckNonNegative_negativeLong() {
+ try {
+ MathPreconditions.checkNonNegative("int", -1L);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckNonNegative_zeroBigInteger() {
+ MathPreconditions.checkNonNegative("BigInteger", BigInteger.ZERO);
+ }
+
+ public void testCheckNonNegative_positiveBigInteger() {
+ MathPreconditions.checkNonNegative("BigInteger", BigInteger.ONE);
+ }
+
+ public void testCheckNonNegative_negativeBigInteger() {
+ try {
+ MathPreconditions.checkNonNegative("int", BigInteger.ONE.negate());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckNonNegative_zeroFloat() {
+ MathPreconditions.checkNonNegative("float", 0f);
+ }
+
+ public void testCheckNonNegative_maxFloat() {
+ MathPreconditions.checkNonNegative("float", Float.MAX_VALUE);
+ }
+
+ public void testCheckNonNegative_minFloat() {
+ MathPreconditions.checkNonNegative("float", Float.MIN_VALUE);
+ }
+
+ public void testCheckNonNegative_positiveFloat() {
+ MathPreconditions.checkNonNegative("float", 1f);
+ }
+
+ public void testCheckNonNegative_negativeFloat() {
+ try {
+ MathPreconditions.checkNonNegative("float", -1f);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckNonNegative_nanFloat() {
+ try {
+ MathPreconditions.checkNonNegative("float", Float.NaN);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckNonNegative_zeroDouble() {
+ MathPreconditions.checkNonNegative("double", 0d);
+ }
+
+ public void testCheckNonNegative_maxDouble() {
+ MathPreconditions.checkNonNegative("double", Double.MAX_VALUE);
+ }
+
+ public void testCheckNonNegative_minDouble() {
+ MathPreconditions.checkNonNegative("double", Double.MIN_VALUE);
+ }
+
+ public void testCheckNonNegative_positiveDouble() {
+ MathPreconditions.checkNonNegative("double", 1d);
+ }
+
+ public void testCheckNonNegative_negativeDouble() {
+ try {
+ MathPreconditions.checkNonNegative("double", -1d);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckNonNegative_nanDouble() {
+ try {
+ MathPreconditions.checkNonNegative("double", Double.NaN);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCheckRoundingUnnnecessary_success() {
+ MathPreconditions.checkRoundingUnnecessary(true);
+ }
+
+ public void testCheckRoundingUnnecessary_failure() {
+ try {
+ MathPreconditions.checkRoundingUnnecessary(false);
+ fail();
+ } catch (ArithmeticException expected) {}
+ }
+
+ public void testCheckInRange_success() {
+ MathPreconditions.checkInRange(true);
+ }
+
+ public void testCheckInRange_failure() {
+ try {
+ MathPreconditions.checkInRange(false);
+ fail();
+ } catch (ArithmeticException expected) {}
+ }
+
+ public void testCheckNoOverflow_success() {
+ MathPreconditions.checkNoOverflow(true);
+ }
+
+ public void testCheckNoOverflow_failure() {
+ try {
+ MathPreconditions.checkNoOverflow(false);
+ fail();
+ } catch (ArithmeticException expected) {}
+ }
+}
diff --git a/guava-tests/test/com/google/common/math/MathTesting.java b/guava-tests/test/com/google/common/math/MathTesting.java
index df4c5c4..eee4a47 100644
--- a/guava-tests/test/com/google/common/math/MathTesting.java
+++ b/guava-tests/test/com/google/common/math/MathTesting.java
@@ -40,8 +40,8 @@ import java.math.RoundingMode;
/**
* Exhaustive input sets for every integral type.
- *
- * @author lowasser@google.com (Louis Wasserman)
+ *
+ * @author Louis Wasserman
*/
@GwtCompatible
public class MathTesting {
@@ -52,8 +52,8 @@ public class MathTesting {
FLOOR, CEILING, HALF_EVEN, HALF_UP, HALF_DOWN);
// Exponents to test for the pow() function.
- static final ImmutableList<Integer> EXPONENTS = ImmutableList.of(0, 1, 2, 3, 4, 5, 6, 7, 10, 15,
- 20, 25, 30, 40, 70);
+ static final ImmutableList<Integer> EXPONENTS = ImmutableList.of(0, 1, 2, 3, 4, 7, 10, 15,
+ 20, 25, 40, 70);
/* Helper function to make a Long value from an Integer. */
private static final Function<Integer, Long> TO_LONG = new Function<Integer, Long>() {
@@ -110,23 +110,23 @@ public class MathTesting {
ImmutableSet.Builder<Integer> intValues = ImmutableSet.builder();
// Add boundary values manually to avoid over/under flow (this covers 2^N for 0 and 31).
intValues.add(Integer.MAX_VALUE - 1, Integer.MAX_VALUE);
- // Add values up to 64. This covers cases like "square of a prime" and such.
- for (int i = 1; i <= 64; i++) {
+ // Add values up to 40. This covers cases like "square of a prime" and such.
+ for (int i = 1; i <= 40; i++) {
intValues.add(i);
}
// Now add values near 2^N for lots of values of N.
- for (int exponent : asList(2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 23, 24, 25)) {
+ for (int exponent : asList(2, 3, 4, 9, 15, 16, 17, 24, 25, 30)) {
int x = 1 << exponent;
intValues.add(x, x + 1, x - 1);
}
intValues.add(9999).add(10000).add(10001).add(1000000); // near powers of 10
intValues.add(5792).add(5793); // sqrt(2^25) rounded up and down
POSITIVE_INTEGER_CANDIDATES = intValues.build();
- NEGATIVE_INTEGER_CANDIDATES =
- Iterables.concat(Iterables.transform(POSITIVE_INTEGER_CANDIDATES, NEGATE_INT),
- ImmutableList.of(Integer.MIN_VALUE));
- NONZERO_INTEGER_CANDIDATES =
- Iterables.concat(POSITIVE_INTEGER_CANDIDATES, NEGATIVE_INTEGER_CANDIDATES);
+ NEGATIVE_INTEGER_CANDIDATES = ImmutableList.copyOf(Iterables.concat(
+ Iterables.transform(POSITIVE_INTEGER_CANDIDATES, NEGATE_INT),
+ ImmutableList.of(Integer.MIN_VALUE)));
+ NONZERO_INTEGER_CANDIDATES = ImmutableList.copyOf(
+ Iterables.concat(POSITIVE_INTEGER_CANDIDATES, NEGATIVE_INTEGER_CANDIDATES));
ALL_INTEGER_CANDIDATES = Iterables.concat(NONZERO_INTEGER_CANDIDATES, ImmutableList.of(0));
}
@@ -202,9 +202,13 @@ public class MathTesting {
static final ImmutableSet<Double> INTEGRAL_DOUBLE_CANDIDATES;
static final ImmutableSet<Double> FRACTIONAL_DOUBLE_CANDIDATES;
+ static final Iterable<Double> INFINITIES = Doubles.asList(
+ Double.POSITIVE_INFINITY,
+ Double.NEGATIVE_INFINITY);
static final Iterable<Double> FINITE_DOUBLE_CANDIDATES;
static final Iterable<Double> POSITIVE_FINITE_DOUBLE_CANDIDATES;
static final Iterable<Double> ALL_DOUBLE_CANDIDATES;
+ static final Iterable<Double> DOUBLE_CANDIDATES_EXCEPT_NAN;
static {
ImmutableSet.Builder<Double> integralBuilder = ImmutableSet.builder();
ImmutableSet.Builder<Double> fractionalBuilder = ImmutableSet.builder();
@@ -246,8 +250,8 @@ public class MathTesting {
return input.doubleValue() > 0.0;
}
});
+ DOUBLE_CANDIDATES_EXCEPT_NAN = Iterables.concat(FINITE_DOUBLE_CANDIDATES, INFINITIES);
ALL_DOUBLE_CANDIDATES =
- Iterables.concat(FINITE_DOUBLE_CANDIDATES,
- asList(Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NaN));
+ Iterables.concat(DOUBLE_CANDIDATES_EXCEPT_NAN, asList(Double.NaN));
}
}
diff --git a/guava-tests/test/com/google/common/math/PackageSanityTests.java b/guava-tests/test/com/google/common/math/PackageSanityTests.java
new file mode 100644
index 0000000..4914af1
--- /dev/null
+++ b/guava-tests/test/com/google/common/math/PackageSanityTests.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.math;
+
+import com.google.common.testing.AbstractPackageSanityTests;
+
+/**
+ * Basic sanity tests for the entire package.
+ *
+ * @author Ben Yu
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {}
diff --git a/guava-tests/test/com/google/common/collect/InverseBiMapTest.java b/guava-tests/test/com/google/common/math/TestPlatform.java
index 637b629..63604b5 100644
--- a/guava-tests/test/com/google/common/collect/InverseBiMapTest.java
+++ b/guava-tests/test/com/google/common/math/TestPlatform.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 The Guava Authors
+ * Copyright (C) 2011 The Guava Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,19 +14,16 @@
* limitations under the License.
*/
-package com.google.common.collect;
+package com.google.common.math;
import com.google.common.annotations.GwtCompatible;
/**
- * Unit test covering the inverse view of a {@code BiMap}.
- *
- * @author Kevin Bourrillion
+ * @author Chris Povirk
*/
-@GwtCompatible
-public class InverseBiMapTest extends AbstractBiMapTest {
- @Override protected BiMap<Integer, String> create() {
- BiMap<String, Integer> inverse = HashBiMap.create();
- return inverse.inverse();
+@GwtCompatible(emulated = true)
+class TestPlatform {
+ static boolean intsCanGoOutOfRange() {
+ return false;
}
}
diff --git a/guava-tests/test/com/google/common/net/HostAndPortTest.java b/guava-tests/test/com/google/common/net/HostAndPortTest.java
new file mode 100644
index 0000000..476a63b
--- /dev/null
+++ b/guava-tests/test/com/google/common/net/HostAndPortTest.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.net;
+
+import com.google.common.testing.SerializableTester;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link HostAndPort}
+ *
+ * @author Paul Marks
+ */
+public class HostAndPortTest extends TestCase {
+
+ public void testFromStringWellFormed() {
+ // Well-formed inputs.
+ checkFromStringCase("google.com", 80, "google.com", 80, false);
+ checkFromStringCase("google.com", 80, "google.com", 80, false);
+ checkFromStringCase("192.0.2.1", 82, "192.0.2.1", 82, false);
+ checkFromStringCase("[2001::1]", 84, "2001::1", 84, false);
+ checkFromStringCase("2001::3", 86, "2001::3", 86, false);
+ checkFromStringCase("host:", 80, "host", 80, false);
+ }
+
+ public void testFromStringBadDefaultPort() {
+ // Well-formed strings with bad default ports.
+ checkFromStringCase("gmail.com:81", -1, "gmail.com", 81, true);
+ checkFromStringCase("192.0.2.2:83", -1, "192.0.2.2", 83, true);
+ checkFromStringCase("[2001::2]:85", -1, "2001::2", 85, true);
+ checkFromStringCase("goo.gl:65535", 65536, "goo.gl", 65535, true);
+ // No port, bad default.
+ checkFromStringCase("google.com", -1, "google.com", -1, false);
+ checkFromStringCase("192.0.2.1", 65536, "192.0.2.1", -1, false);
+ checkFromStringCase("[2001::1]", -1, "2001::1", -1, false);
+ checkFromStringCase("2001::3", 65536, "2001::3", -1, false);
+ }
+
+ public void testFromStringUnusedDefaultPort() {
+ // Default port, but unused.
+ checkFromStringCase("gmail.com:81", 77, "gmail.com", 81, true);
+ checkFromStringCase("192.0.2.2:83", 77, "192.0.2.2", 83, true);
+ checkFromStringCase("[2001::2]:85", 77, "2001::2", 85, true);
+ }
+
+ public void testFromStringBadPort() {
+ // Out-of-range ports.
+ checkFromStringCase("google.com:65536", 1, null, 99, false);
+ checkFromStringCase("google.com:9999999999", 1, null, 99, false);
+ // Invalid port parts.
+ checkFromStringCase("google.com:port", 1, null, 99, false);
+ checkFromStringCase("google.com:-25", 1, null, 99, false);
+ checkFromStringCase("google.com:+25", 1, null, 99, false);
+ checkFromStringCase("google.com:25 ", 1, null, 99, false);
+ checkFromStringCase("google.com:25\t", 1, null, 99, false);
+ checkFromStringCase("google.com:0x25 ", 1, null, 99, false);
+ }
+
+ public void testFromStringUnparseableNonsense() {
+ // Some nonsense that causes parse failures.
+ checkFromStringCase("[goo.gl]", 1, null, 99, false);
+ checkFromStringCase("[goo.gl]:80", 1, null, 99, false);
+ checkFromStringCase("[", 1, null, 99, false);
+ checkFromStringCase("[]:", 1, null, 99, false);
+ checkFromStringCase("[]:80", 1, null, 99, false);
+ checkFromStringCase("[]bad", 1, null, 99, false);
+ }
+
+ public void testFromStringParseableNonsense() {
+ // Examples of nonsense that gets through.
+ checkFromStringCase("[[:]]", 86, "[:]", 86, false);
+ checkFromStringCase("x:y:z", 87, "x:y:z", 87, false);
+ checkFromStringCase("", 88, "", 88, false);
+ checkFromStringCase(":", 99, "", 99, false);
+ checkFromStringCase(":123", -1, "", 123, true);
+ checkFromStringCase("\nOMG\t", 89, "\nOMG\t", 89, false);
+ }
+
+ private static void checkFromStringCase(
+ String hpString,
+ int defaultPort,
+ String expectHost,
+ int expectPort,
+ boolean expectHasExplicitPort) {
+ HostAndPort hp;
+ try {
+ hp = HostAndPort.fromString(hpString);
+ } catch (IllegalArgumentException e) {
+ // Make sure we expected this.
+ assertNull(expectHost);
+ return;
+ }
+ assertNotNull(expectHost);
+
+ // Apply withDefaultPort(), yielding hp2.
+ final boolean badDefaultPort = (defaultPort < 0 || defaultPort > 65535);
+ HostAndPort hp2 = null;
+ try {
+ hp2 = hp.withDefaultPort(defaultPort);
+ assertFalse(badDefaultPort);
+ } catch (IllegalArgumentException e) {
+ assertTrue(badDefaultPort);
+ }
+
+ // Check the pre-withDefaultPort() instance.
+ if (expectHasExplicitPort) {
+ assertTrue(hp.hasPort());
+ assertEquals(expectPort, hp.getPort());
+ } else {
+ assertFalse(hp.hasPort());
+ try {
+ hp.getPort();
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+ }
+ assertEquals(expectHost, hp.getHostText());
+
+ // Check the post-withDefaultPort() instance (if any).
+ if (!badDefaultPort) {
+ try {
+ int port = hp2.getPort();
+ assertTrue(expectPort != -1);
+ assertEquals(expectPort, port);
+ } catch (IllegalStateException e) {
+ // Make sure we expected this to fail.
+ assertEquals(-1, expectPort);
+ }
+ assertEquals(expectHost, hp2.getHostText());
+ }
+ }
+
+ public void testFromParts() {
+ HostAndPort hp = HostAndPort.fromParts("gmail.com", 81);
+ assertEquals("gmail.com", hp.getHostText());
+ assertTrue(hp.hasPort());
+ assertEquals(81, hp.getPort());
+
+ try {
+ HostAndPort.fromParts("gmail.com:80", 81);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ HostAndPort.fromParts("gmail.com", -1);
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testGetPortOrDefault() {
+ assertEquals(80, HostAndPort.fromString("host:80").getPortOrDefault(123));
+ assertEquals(123, HostAndPort.fromString("host").getPortOrDefault(123));
+ }
+
+ public void testHashCodeAndEquals() {
+ HostAndPort hp1 = HostAndPort.fromString("foo::123");
+ HostAndPort hp2 = HostAndPort.fromString("foo::123");
+ HostAndPort hp3 = HostAndPort.fromString("[foo::123]");
+ HostAndPort hp4 = HostAndPort.fromParts("[foo::123]", 80);
+ HostAndPort hp5 = HostAndPort.fromString("[foo::123]:80");
+ assertEquals(hp1.hashCode(), hp1.hashCode());
+ assertEquals(hp1.hashCode(), hp2.hashCode());
+ assertFalse(hp1.hashCode() == hp3.hashCode());
+ assertFalse(hp3.hashCode() == hp4.hashCode());
+ assertEquals(hp4.hashCode(), hp5.hashCode());
+
+ assertTrue(hp1.equals(hp1));
+ assertTrue(hp1.equals(hp2));
+ assertFalse(hp1.equals(hp3));
+ assertFalse(hp3.equals(hp4));
+ assertTrue(hp4.equals(hp5));
+ assertFalse(hp1.equals(null));
+ }
+
+ public void testRequireBracketsForIPv6() {
+ // Bracketed IPv6 works fine.
+ assertEquals("::1", HostAndPort.fromString("[::1]").requireBracketsForIPv6().getHostText());
+ assertEquals("::1", HostAndPort.fromString("[::1]:80").requireBracketsForIPv6().getHostText());
+ // Non-bracketed non-IPv6 works fine.
+ assertEquals("x", HostAndPort.fromString("x").requireBracketsForIPv6().getHostText());
+ assertEquals("x", HostAndPort.fromString("x:80").requireBracketsForIPv6().getHostText());
+
+ // Non-bracketed IPv6 fails.
+ try {
+ HostAndPort.fromString("::1").requireBracketsForIPv6();
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testToString() {
+ // With ports.
+ assertEquals("foo:101", "" + HostAndPort.fromString("foo:101"));
+ assertEquals(":102", HostAndPort.fromString(":102").toString());
+ assertEquals("[1::2]:103", HostAndPort.fromParts("1::2", 103).toString());
+ assertEquals("[::1]:104", HostAndPort.fromString("[::1]:104").toString());
+
+ // Without ports.
+ assertEquals("foo", "" + HostAndPort.fromString("foo"));
+ assertEquals("", HostAndPort.fromString("").toString());
+ assertEquals("[1::2]", HostAndPort.fromString("1::2").toString());
+ assertEquals("[::1]", HostAndPort.fromString("[::1]").toString());
+
+ // Garbage in, garbage out.
+ assertEquals("[::]]:107", HostAndPort.fromParts("::]", 107).toString());
+ assertEquals("[[:]]:108", HostAndPort.fromString("[[:]]:108").toString());
+ }
+
+ public void testSerialization() {
+ SerializableTester.reserializeAndAssert(HostAndPort.fromParts("host", 80));
+ SerializableTester.reserializeAndAssert(HostAndPort.fromString("host"));
+ SerializableTester.reserializeAndAssert(HostAndPort.fromString("host:80"));
+ SerializableTester.reserializeAndAssert(HostAndPort.fromString("[::1]:104"));
+ SerializableTester.reserializeAndAssert(HostAndPort.fromParts("1::2", 103));
+ }
+}
diff --git a/guava-tests/test/com/google/common/net/HostSpecifierTest.java b/guava-tests/test/com/google/common/net/HostSpecifierTest.java
index f66c128..12c7631 100644
--- a/guava-tests/test/com/google/common/net/HostSpecifierTest.java
+++ b/guava-tests/test/com/google/common/net/HostSpecifierTest.java
@@ -87,7 +87,7 @@ public final class HostSpecifierTest extends TestCase {
return HostSpecifier.fromValid(specifier);
}
- public void testNulls() throws Exception {
+ public void testNulls() {
final NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(HostSpecifier.class);
diff --git a/guava-tests/test/com/google/common/net/HttpHeadersTest.java b/guava-tests/test/com/google/common/net/HttpHeadersTest.java
index 513767c..4bcf3ff 100644
--- a/guava-tests/test/com/google/common/net/HttpHeadersTest.java
+++ b/guava-tests/test/com/google/common/net/HttpHeadersTest.java
@@ -30,7 +30,7 @@ import java.util.List;
/**
* Tests for the HttpHeaders class.
*
- * @author Kurt Aflred Kluever
+ * @author Kurt Alfred Kluever
*/
public class HttpHeadersTest extends TestCase {
public void testConstantNameMatchesString() throws Exception {
@@ -47,7 +47,8 @@ public class HttpHeadersTest extends TestCase {
}
private static final ImmutableSet<String> UPPERCASE_ACRONYMS = ImmutableSet.of(
- "ID", "DNT", "GFE", "IP", "MD5", "P3P", "TE", "UID", "URL", "WWW", "XSS");
+ "ID", "DNT", "GFE", "GSE", "IP", "MD5", "P3P", "TE", "UID", "URL",
+ "WWW", "XSS");
private static final Splitter SPLITTER = Splitter.on('_');
private static final Joiner JOINER = Joiner.on('-');
diff --git a/guava-tests/test/com/google/common/net/InetAddressesTest.java b/guava-tests/test/com/google/common/net/InetAddressesTest.java
index 41564eb..90d3285 100644
--- a/guava-tests/test/com/google/common/net/InetAddressesTest.java
+++ b/guava-tests/test/com/google/common/net/InetAddressesTest.java
@@ -32,7 +32,7 @@ import java.net.UnknownHostException;
*/
public class InetAddressesTest extends TestCase {
- public void testNulls() throws Exception {
+ public void testNulls() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(InetAddresses.class);
@@ -241,9 +241,15 @@ public class InetAddressesTest extends TestCase {
assertEquals(expected, InetAddresses.forUriString("[3ffe:0:0:0:0:0:0:1]"));
}
+ public void testForUriStringIPv4Mapped() {
+ Inet4Address expected = (Inet4Address) InetAddresses.forString("192.0.2.1");
+ assertEquals(expected, InetAddresses.forUriString("[::ffff:192.0.2.1]"));
+ }
+
public void testIsUriInetAddress() {
assertTrue(InetAddresses.isUriInetAddress("192.168.1.1"));
assertTrue(InetAddresses.isUriInetAddress("[3ffe:0:0:0:0:0:0:1]"));
+ assertTrue(InetAddresses.isUriInetAddress("[::ffff:192.0.2.1]"));
assertFalse(InetAddresses.isUriInetAddress("[192.168.1.1"));
assertFalse(InetAddresses.isUriInetAddress("192.168.1.1]"));
@@ -253,6 +259,8 @@ public class InetAddressesTest extends TestCase {
assertFalse(InetAddresses.isUriInetAddress("1:2e"));
assertFalse(InetAddresses.isUriInetAddress("[3ffe:0:0:0:0:0:0:1"));
assertFalse(InetAddresses.isUriInetAddress("3ffe:0:0:0:0:0:0:1]"));
+ assertFalse(InetAddresses.isUriInetAddress("3ffe:0:0:0:0:0:0:1"));
+ assertFalse(InetAddresses.isUriInetAddress("::ffff:192.0.2.1"));
}
public void testForUriStringBad() {
@@ -318,6 +326,20 @@ public class InetAddressesTest extends TestCase {
} catch (IllegalArgumentException e) {
// expected
}
+
+ try {
+ InetAddresses.forUriString("3ffe:0:0:0:0:0:0:1");
+ fail("expected IllegalArgumentException"); // COV_NF_LINE
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ InetAddresses.forUriString("::ffff:192.0.2.1");
+ fail("expected IllegalArgumentException"); // COV_NF_LINE
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
}
public void testCompatIPv4Addresses() {
@@ -467,6 +489,14 @@ public class InetAddressesTest extends TestCase {
assertEquals(flags, teredo.getFlags());
}
+ public void testTeredoAddress_nullServer() {
+ InetAddresses.TeredoInfo info = new InetAddresses.TeredoInfo(null, null, 80, 1000);
+ assertEquals(InetAddresses.forString("0.0.0.0"), info.getServer());
+ assertEquals(InetAddresses.forString("0.0.0.0"), info.getClient());
+ assertEquals(80, info.getPort());
+ assertEquals(1000, info.getFlags());
+ }
+
public void testIsatapAddresses() {
InetAddress ipv4 = InetAddresses.forString("1.2.3.4");
String[] validIsatapAddresses = {
@@ -607,14 +637,6 @@ public class InetAddressesTest extends TestCase {
assertTrue(InetAddresses.coerceToInteger(coerced) <= 0xfffffffe);
}
- public void testHash64To32() {
- // Make sure the output looks reasonably sane.
- assertEquals(532412650, InetAddresses.hash64To32(-1));
- assertEquals(720020139, InetAddresses.hash64To32(0));
- assertEquals(357654460, InetAddresses.hash64To32(1));
- assertEquals(-1977349188, InetAddresses.hash64To32(0x7fffffffffffffffL));
- }
-
public void testToInteger() {
InetAddress ipv4Addr = InetAddresses.forString("127.0.0.1");
assertEquals(0x7f000001, InetAddresses.coerceToInteger(ipv4Addr));
@@ -677,7 +699,7 @@ public class InetAddressesTest extends TestCase {
try {
address = InetAddresses.increment(address);
fail();
- } catch (IllegalArgumentException expected) { }
+ } catch (IllegalArgumentException expected) {}
}
public void testIncrementIPv6() throws UnknownHostException {
@@ -700,6 +722,6 @@ public class InetAddressesTest extends TestCase {
try {
address = InetAddresses.increment(address);
fail();
- } catch (IllegalArgumentException expected) { }
+ } catch (IllegalArgumentException expected) {}
}
}
diff --git a/guava-tests/test/com/google/common/net/InternetDomainNameTest.java b/guava-tests/test/com/google/common/net/InternetDomainNameTest.java
index 1fb869f..7291286 100644
--- a/guava-tests/test/com/google/common/net/InternetDomainNameTest.java
+++ b/guava-tests/test/com/google/common/net/InternetDomainNameTest.java
@@ -370,7 +370,7 @@ public final class InternetDomainNameTest extends TestCase {
}
public void testExclusion() {
- InternetDomainName domain = InternetDomainName.from("foo.nhs.uk");
+ InternetDomainName domain = InternetDomainName.from("foo.nic.uk");
assertTrue(domain.hasPublicSuffix());
assertEquals("uk", domain.publicSuffix().name());
@@ -378,6 +378,16 @@ public final class InternetDomainNameTest extends TestCase {
assertFalse(domain.publicSuffix().isPublicSuffix());
}
+ public void testMultipleUnders() {
+ // PSL has both *.uk and *.police.uk; the latter should win.
+ // See http://code.google.com/p/guava-libraries/issues/detail?id=1176
+
+ InternetDomainName domain = InternetDomainName.from("www.essex.police.uk");
+ assertTrue(domain.hasPublicSuffix());
+ assertEquals("essex.police.uk", domain.publicSuffix().name());
+ assertEquals("www.essex.police.uk", domain.topPrivateDomain().name());
+ }
+
public void testEquality() {
new EqualsTester()
.addEqualityGroup(
@@ -393,11 +403,10 @@ public final class InternetDomainNameTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
+ public void testNulls() {
final NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(InternetDomainName.class);
tester.testAllPublicInstanceMethods(InternetDomainName.from("google.com"));
}
-
}
diff --git a/guava-tests/test/com/google/common/net/MediaTypeTest.java b/guava-tests/test/com/google/common/net/MediaTypeTest.java
new file mode 100644
index 0000000..12efed6
--- /dev/null
+++ b/guava-tests/test/com/google/common/net/MediaTypeTest.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.net;
+
+import static com.google.common.base.Charsets.UTF_16;
+import static com.google.common.base.Charsets.UTF_8;
+import static com.google.common.net.MediaType.ANY_APPLICATION_TYPE;
+import static com.google.common.net.MediaType.ANY_AUDIO_TYPE;
+import static com.google.common.net.MediaType.ANY_IMAGE_TYPE;
+import static com.google.common.net.MediaType.ANY_TEXT_TYPE;
+import static com.google.common.net.MediaType.ANY_TYPE;
+import static com.google.common.net.MediaType.ANY_VIDEO_TYPE;
+import static com.google.common.net.MediaType.HTML_UTF_8;
+import static com.google.common.net.MediaType.JPEG;
+import static com.google.common.net.MediaType.PLAIN_TEXT_UTF_8;
+import static java.lang.reflect.Modifier.isFinal;
+import static java.lang.reflect.Modifier.isPublic;
+import static java.lang.reflect.Modifier.isStatic;
+import static java.util.Arrays.asList;
+
+import com.google.common.annotations.Beta;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Throwables;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Field;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
+
+/**
+ * Tests for {@link MediaType}.
+ *
+ * @author Gregory Kick
+ */
+@Beta
+@GwtCompatible(emulated = true)
+public class MediaTypeTest extends TestCase {
+ @GwtIncompatible("reflection") public void testParse_useConstants() throws Exception {
+ for (MediaType constant : getConstants()) {
+ assertSame(constant, MediaType.parse(constant.toString()));
+ }
+ }
+
+ @GwtIncompatible("reflection") public void testCreate_useConstants() throws Exception {
+ for (MediaType constant : getConstants()) {
+ assertSame(constant, MediaType.create(constant.type(), constant.subtype())
+ .withParameters(constant.parameters()));
+ }
+ }
+
+ @GwtIncompatible("reflection") public void testConstants_charset() throws Exception {
+ for (Field field : getConstantFields()) {
+ Optional<Charset> charset = ((MediaType) field.get(null)).charset();
+ if (field.getName().endsWith("_UTF_8")) {
+ assertEquals(Optional.of(UTF_8), charset);
+ } else {
+ assertEquals(Optional.absent(), charset);
+ }
+ }
+ }
+
+ @GwtIncompatible("reflection") private static FluentIterable<Field> getConstantFields() {
+ return FluentIterable.from(asList(MediaType.class.getDeclaredFields()))
+ .filter(new Predicate<Field>() {
+ @Override public boolean apply(Field input) {
+ int modifiers = input.getModifiers();
+ return isPublic(modifiers) && isStatic(modifiers) && isFinal(modifiers)
+ && MediaType.class.equals(input.getType());
+ }
+ });
+ }
+
+ @GwtIncompatible("reflection") private static FluentIterable<MediaType> getConstants() {
+ return getConstantFields()
+ .transform(new Function<Field, MediaType>() {
+ @Override public MediaType apply(Field input) {
+ try {
+ return (MediaType) input.get(null);
+ } catch (Exception e) {
+ throw Throwables.propagate(e);
+ }
+ }
+ });
+ }
+
+ public void testCreate_invalidType() {
+ try {
+ MediaType.create("te><t", "plaintext");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCreate_invalidSubtype() {
+ try {
+ MediaType.create("text", "pl@intext");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCreate_wildcardTypeDeclaredSubtype() {
+ try {
+ MediaType.create("*", "text");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testCreateApplicationType() {
+ MediaType newType = MediaType.createApplicationType("yams");
+ assertEquals("application", newType.type());
+ assertEquals("yams", newType.subtype());
+ }
+
+ public void testCreateAudioType() {
+ MediaType newType = MediaType.createAudioType("yams");
+ assertEquals("audio", newType.type());
+ assertEquals("yams", newType.subtype());
+ }
+
+ public void testCreateImageType() {
+ MediaType newType = MediaType.createImageType("yams");
+ assertEquals("image", newType.type());
+ assertEquals("yams", newType.subtype());
+ }
+
+ public void testCreateTextType() {
+ MediaType newType = MediaType.createTextType("yams");
+ assertEquals("text", newType.type());
+ assertEquals("yams", newType.subtype());
+ }
+
+ public void testCreateVideoType() {
+ MediaType newType = MediaType.createVideoType("yams");
+ assertEquals("video", newType.type());
+ assertEquals("yams", newType.subtype());
+ }
+
+ public void testGetType() {
+ assertEquals("text", MediaType.parse("text/plain").type());
+ assertEquals("application",
+ MediaType.parse("application/atom+xml; charset=utf-8").type());
+ }
+
+ public void testGetSubtype() {
+ assertEquals("plain", MediaType.parse("text/plain").subtype());
+ assertEquals("atom+xml",
+ MediaType.parse("application/atom+xml; charset=utf-8").subtype());
+ }
+
+ private static final ImmutableListMultimap<String, String> PARAMETERS =
+ ImmutableListMultimap.of("a", "1", "a", "2", "b", "3");
+
+ public void testGetParameters() {
+ assertEquals(ImmutableListMultimap.of(), MediaType.parse("text/plain").parameters());
+ assertEquals(ImmutableListMultimap.of("charset", "utf-8"),
+ MediaType.parse("application/atom+xml; charset=utf-8").parameters());
+ assertEquals(PARAMETERS,
+ MediaType.parse("application/atom+xml; a=1; a=2; b=3").parameters());
+ }
+
+ public void testWithoutParameters() {
+ assertSame(MediaType.parse("image/gif"),
+ MediaType.parse("image/gif").withoutParameters());
+ assertEquals(MediaType.parse("image/gif"),
+ MediaType.parse("image/gif; foo=bar").withoutParameters());
+ }
+
+ public void testWithParameters() {
+ assertEquals(MediaType.parse("text/plain; a=1; a=2; b=3"),
+ MediaType.parse("text/plain").withParameters(PARAMETERS));
+ assertEquals(MediaType.parse("text/plain; a=1; a=2; b=3"),
+ MediaType.parse("text/plain; a=1; a=2; b=3").withParameters(PARAMETERS));
+ }
+
+ public void testWithParameters_invalidAttribute() {
+ MediaType mediaType = MediaType.parse("text/plain");
+ ImmutableListMultimap<String, String> parameters =
+ ImmutableListMultimap.of("a", "1", "@", "2", "b", "3");
+ try {
+ mediaType.withParameters(parameters);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testWithParameter() {
+ assertEquals(MediaType.parse("text/plain; a=1"),
+ MediaType.parse("text/plain").withParameter("a", "1"));
+ assertEquals(MediaType.parse("text/plain; a=1"),
+ MediaType.parse("text/plain; a=1; a=2").withParameter("a", "1"));
+ assertEquals(MediaType.parse("text/plain; a=3"),
+ MediaType.parse("text/plain; a=1; a=2").withParameter("a", "3"));
+ assertEquals(MediaType.parse("text/plain; a=1; a=2; b=3"),
+ MediaType.parse("text/plain; a=1; a=2").withParameter("b", "3"));
+ }
+
+ public void testWithParameter_invalidAttribute() {
+ MediaType mediaType = MediaType.parse("text/plain");
+ try {
+ mediaType.withParameter("@", "2");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testWithCharset() {
+ assertEquals(MediaType.parse("text/plain; charset=utf-8"),
+ MediaType.parse("text/plain").withCharset(UTF_8));
+ assertEquals(MediaType.parse("text/plain; charset=utf-8"),
+ MediaType.parse("text/plain; charset=utf-16").withCharset(UTF_8));
+ }
+
+ public void testHasWildcard() {
+ assertFalse(PLAIN_TEXT_UTF_8.hasWildcard());
+ assertFalse(JPEG.hasWildcard());
+ assertTrue(ANY_TYPE.hasWildcard());
+ assertTrue(ANY_APPLICATION_TYPE.hasWildcard());
+ assertTrue(ANY_AUDIO_TYPE.hasWildcard());
+ assertTrue(ANY_IMAGE_TYPE.hasWildcard());
+ assertTrue(ANY_TEXT_TYPE.hasWildcard());
+ assertTrue(ANY_VIDEO_TYPE.hasWildcard());
+ }
+
+ public void testIs() {
+ assertTrue(PLAIN_TEXT_UTF_8.is(ANY_TYPE));
+ assertTrue(JPEG.is(ANY_TYPE));
+ assertTrue(ANY_TEXT_TYPE.is(ANY_TYPE));
+ assertTrue(PLAIN_TEXT_UTF_8.is(ANY_TEXT_TYPE));
+ assertTrue(PLAIN_TEXT_UTF_8.withoutParameters().is(ANY_TEXT_TYPE));
+ assertFalse(JPEG.is(ANY_TEXT_TYPE));
+ assertTrue(PLAIN_TEXT_UTF_8.is(PLAIN_TEXT_UTF_8));
+ assertTrue(PLAIN_TEXT_UTF_8.is(PLAIN_TEXT_UTF_8.withoutParameters()));
+ assertFalse(PLAIN_TEXT_UTF_8.withoutParameters().is(PLAIN_TEXT_UTF_8));
+ assertFalse(PLAIN_TEXT_UTF_8.is(HTML_UTF_8));
+ assertFalse(PLAIN_TEXT_UTF_8.withParameter("charset", "UTF-16").is(PLAIN_TEXT_UTF_8));
+ assertFalse(PLAIN_TEXT_UTF_8.is(PLAIN_TEXT_UTF_8.withParameter("charset", "UTF-16")));
+ }
+
+ public void testParse_empty() {
+ try {
+ MediaType.parse("");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testParse_badInput() {
+ try {
+ MediaType.parse("/");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("te<t/plain");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/pl@in");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain;");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain; ");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain; a");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain; a=");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain; a=@");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain; a=\"@");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain; a=1;");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain; a=1; ");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain; a=1; b");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain; a=1; b=");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ try {
+ MediaType.parse("text/plain; a=\u2025");
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testGetCharset() {
+ assertEquals(Optional.absent(), MediaType.parse("text/plain").charset());
+ assertEquals(Optional.of(UTF_8),
+ MediaType.parse("text/plain; charset=utf-8").charset());
+ }
+
+ @GwtIncompatible("Non-UTF-8 Charset") public void testGetCharset_utf16() {
+ assertEquals(Optional.of(UTF_16),
+ MediaType.parse("text/plain; charset=utf-16").charset());
+ }
+
+ public void testGetCharset_tooMany() {
+ MediaType mediaType = MediaType.parse("text/plain; charset=utf-8; charset=utf-16");
+ try {
+ mediaType.charset();
+ fail();
+ } catch (IllegalStateException expected) {}
+ }
+
+ public void testGetCharset_illegalCharset() {
+ MediaType mediaType = MediaType.parse(
+ "text/plain; charset=\"!@#$%^&*()\"");
+ try {
+ mediaType.charset();
+ fail();
+ } catch (IllegalCharsetNameException expected) {}
+ }
+
+ public void testGetCharset_unsupportedCharset() {
+ MediaType mediaType = MediaType.parse(
+ "text/plain; charset=utf-wtf");
+ try {
+ mediaType.charset();
+ fail();
+ } catch (UnsupportedCharsetException expected) {}
+ }
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(MediaType.create("text", "plain"),
+ MediaType.create("TEXT", "PLAIN"),
+ MediaType.parse("text/plain"),
+ MediaType.parse("TEXT/PLAIN"),
+ MediaType.create("text", "plain").withParameter("a", "1").withoutParameters())
+ .addEqualityGroup(
+ MediaType.create("text", "plain").withCharset(UTF_8),
+ MediaType.create("text", "plain").withParameter("CHARSET", "UTF-8"),
+ MediaType.create("text", "plain").withParameters(
+ ImmutableMultimap.of("charset", "utf-8")),
+ MediaType.parse("text/plain;charset=utf-8"),
+ MediaType.parse("text/plain; charset=utf-8"),
+ MediaType.parse("text/plain; charset=utf-8"),
+ MediaType.parse("text/plain; \tcharset=utf-8"),
+ MediaType.parse("text/plain; \r\n\tcharset=utf-8"),
+ MediaType.parse("text/plain; CHARSET=utf-8"),
+ MediaType.parse("text/plain; charset=\"utf-8\""),
+ MediaType.parse("text/plain; charset=\"\\u\\tf-\\8\""),
+ MediaType.parse("text/plain; charset=UTF-8"))
+ .addEqualityGroup(MediaType.parse("text/plain; charset=utf-8; charset=utf-8"))
+ .addEqualityGroup(MediaType.create("text", "plain").withParameter("a", "value"),
+ MediaType.create("text", "plain").withParameter("A", "value"))
+ .addEqualityGroup(MediaType.create("text", "plain").withParameter("a", "VALUE"),
+ MediaType.create("text", "plain").withParameter("A", "VALUE"))
+ .addEqualityGroup(
+ MediaType.create("text", "plain")
+ .withParameters(ImmutableListMultimap.of("a", "1", "a", "2")),
+ MediaType.create("text", "plain")
+ .withParameters(ImmutableListMultimap.of("a", "2", "a", "1")))
+ .addEqualityGroup(MediaType.create("text", "csv"))
+ .addEqualityGroup(MediaType.create("application", "atom+xml"))
+ .testEquals();
+ }
+
+ @GwtIncompatible("Non-UTF-8 Charset") public void testEquals_nonUtf8Charsets() {
+ new EqualsTester()
+ .addEqualityGroup(MediaType.create("text", "plain"))
+ .addEqualityGroup(MediaType.create("text", "plain").withCharset(UTF_8))
+ .addEqualityGroup(MediaType.create("text", "plain").withCharset(UTF_16))
+ .testEquals();
+ }
+
+ @GwtIncompatible("com.google.common.testing.NullPointerTester")
+ public void testNullPointer() {
+ NullPointerTester tester = new NullPointerTester();
+ tester.testAllPublicConstructors(MediaType.class);
+ tester.testAllPublicStaticMethods(MediaType.class);
+ tester.testAllPublicInstanceMethods(MediaType.parse("text/plain"));
+ }
+
+ public void testToString() {
+ assertEquals("text/plain", MediaType.create("text", "plain").toString());
+ assertEquals("text/plain; something=\"cr@zy\"; something-else=\"crazy with spaces\"",
+ MediaType.create("text", "plain")
+ .withParameter("something", "cr@zy")
+ .withParameter("something-else", "crazy with spaces")
+ .toString());
+ }
+}
diff --git a/guava-tests/test/com/google/common/net/PackageSanityTests.java b/guava-tests/test/com/google/common/net/PackageSanityTests.java
new file mode 100644
index 0000000..3d18ad6
--- /dev/null
+++ b/guava-tests/test/com/google/common/net/PackageSanityTests.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.net;
+
+import com.google.common.testing.AbstractPackageSanityTests;
+
+/**
+ * Basic sanity tests for the entire package.
+ *
+ * @author Ben Yu
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {
+ public PackageSanityTests() {
+ setDefault(InternetDomainName.class, InternetDomainName.from("google.com"));
+ }
+}
diff --git a/guava-tests/test/com/google/common/net/TestPlatform.java b/guava-tests/test/com/google/common/net/TestPlatform.java
new file mode 100644
index 0000000..39301d5
--- /dev/null
+++ b/guava-tests/test/com/google/common/net/TestPlatform.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.net;
+
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * @author Hayward Chan
+ */
+@GwtCompatible(emulated = true)
+class TestPlatform {
+}
diff --git a/guava-tests/test/com/google/common/primitives/BooleansTest.java b/guava-tests/test/com/google/common/primitives/BooleansTest.java
index b20a01c..f6c5d99 100644
--- a/guava-tests/test/com/google/common/primitives/BooleansTest.java
+++ b/guava-tests/test/com/google/common/primitives/BooleansTest.java
@@ -39,6 +39,7 @@ import java.util.List;
public class BooleansTest extends TestCase {
private static final boolean[] EMPTY = {};
private static final boolean[] ARRAY_FALSE = {false};
+ private static final boolean[] ARRAY_TRUE = {true};
private static final boolean[] ARRAY_FALSE_FALSE = {false, false};
private static final boolean[] ARRAY_FALSE_TRUE = {false, true};
@@ -69,6 +70,16 @@ public class BooleansTest extends TestCase {
}
public void testIndexOf() {
+ assertEquals(-1, Booleans.indexOf(EMPTY, ARRAY_FALSE));
+ assertEquals(-1, Booleans.indexOf(ARRAY_FALSE, ARRAY_FALSE_TRUE));
+ assertEquals(0, Booleans.indexOf(ARRAY_FALSE_FALSE, ARRAY_FALSE));
+ assertEquals(0, Booleans.indexOf(ARRAY_FALSE, ARRAY_FALSE));
+ assertEquals(0, Booleans.indexOf(ARRAY_FALSE_TRUE, ARRAY_FALSE));
+ assertEquals(1, Booleans.indexOf(ARRAY_FALSE_TRUE, ARRAY_TRUE));
+ assertEquals(0, Booleans.indexOf(ARRAY_TRUE, new boolean[0]));
+ }
+
+ public void testIndexOf_arrays() {
assertEquals(-1, Booleans.indexOf(EMPTY, false));
assertEquals(-1, Booleans.indexOf(ARRAY_FALSE, true));
assertEquals(-1, Booleans.indexOf(ARRAY_FALSE_FALSE, true));
@@ -200,14 +211,85 @@ public class BooleansTest extends TestCase {
}
}
- public void testAsListEmpty() {
- assertSame(Collections.emptyList(), Booleans.asList(EMPTY));
+ public void testAsListIsEmpty() {
+ assertTrue(Booleans.asList(EMPTY).isEmpty());
+ assertFalse(Booleans.asList(ARRAY_FALSE).isEmpty());
+ }
+
+ public void testAsListSize() {
+ assertEquals(0, Booleans.asList(EMPTY).size());
+ assertEquals(1, Booleans.asList(ARRAY_FALSE).size());
+ assertEquals(2, Booleans.asList(ARRAY_FALSE_TRUE).size());
+ }
+
+ public void testAsListIndexOf() {
+ assertEquals(-1, Booleans.asList(EMPTY).indexOf("wrong type"));
+ assertEquals(-1, Booleans.asList(EMPTY).indexOf(true));
+ assertEquals(-1, Booleans.asList(ARRAY_FALSE).indexOf(true));
+ assertEquals(0, Booleans.asList(ARRAY_FALSE).indexOf(false));
+ assertEquals(1, Booleans.asList(ARRAY_FALSE_TRUE).indexOf(true));
+ }
+
+ public void testAsListLastIndexOf() {
+ assertEquals(-1, Booleans.asList(EMPTY).indexOf("wrong type"));
+ assertEquals(-1, Booleans.asList(EMPTY).indexOf(true));
+ assertEquals(-1, Booleans.asList(ARRAY_FALSE).lastIndexOf(true));
+ assertEquals(1, Booleans.asList(ARRAY_FALSE_TRUE).lastIndexOf(true));
+ assertEquals(1, Booleans.asList(ARRAY_FALSE_FALSE).lastIndexOf(false));
+ }
+
+ public void testAsListContains() {
+ assertFalse(Booleans.asList(EMPTY).contains("wrong type"));
+ assertFalse(Booleans.asList(EMPTY).contains(true));
+ assertFalse(Booleans.asList(ARRAY_FALSE).contains(true));
+ assertTrue(Booleans.asList(ARRAY_TRUE).contains(true));
+ assertTrue(Booleans.asList(ARRAY_FALSE_TRUE).contains(false));
+ assertTrue(Booleans.asList(ARRAY_FALSE_TRUE).contains(true));
+ }
+
+ public void testAsListEquals() {
+ assertEquals(Booleans.asList(EMPTY), Collections.emptyList());
+ assertEquals(Booleans.asList(ARRAY_FALSE), Booleans.asList(ARRAY_FALSE));
+ assertFalse(Booleans.asList(ARRAY_FALSE).equals(ARRAY_FALSE));
+ assertFalse(Booleans.asList(ARRAY_FALSE).equals(null));
+ assertFalse(Booleans.asList(ARRAY_FALSE).equals(Booleans.asList(ARRAY_FALSE_TRUE)));
+ assertFalse(Booleans.asList(ARRAY_FALSE_FALSE).equals(Booleans.asList(ARRAY_FALSE_TRUE)));
+ assertEquals(1, Booleans.asList(ARRAY_FALSE_TRUE).lastIndexOf(true));
+ List<Boolean> reference = Booleans.asList(ARRAY_FALSE);
+ assertEquals(Booleans.asList(ARRAY_FALSE), reference);
+ assertEquals(reference, reference);
+ }
+
+ public void testAsListHashcode() {
+ assertEquals(1, Booleans.asList(EMPTY).hashCode());
+ assertEquals(Booleans.asList(ARRAY_FALSE).hashCode(), Booleans.asList(ARRAY_FALSE).hashCode());
+ List<Boolean> reference = Booleans.asList(ARRAY_FALSE);
+ assertEquals(Booleans.asList(ARRAY_FALSE).hashCode(), reference.hashCode());
+ }
+
+ public void testAsListToString() {
+ assertEquals("[false]", Booleans.asList(ARRAY_FALSE).toString());
+ assertEquals("[false, true]", Booleans.asList(ARRAY_FALSE_TRUE).toString());
+ }
+
+ public void testAsListSet() {
+ List<Boolean> list = Booleans.asList(ARRAY_FALSE);
+ assertFalse(list.set(0, true));
+ assertTrue(list.set(0, false));
+ try {
+ list.set(0, null);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ try {
+ list.set(1, true);
+ fail();
+ } catch (IndexOutOfBoundsException expected) {
+ }
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(boolean[].class, new boolean[0]);
- tester.testAllPublicStaticMethods(Booleans.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(Booleans.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java
index 49ffa74..585c4c8 100644
--- a/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/ByteArrayAsListTest.java
@@ -19,6 +19,7 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -38,7 +39,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class ByteArrayAsListTest extends TestCase {
private static List<Byte> asList(Byte[] values) {
@@ -49,6 +50,7 @@ public class ByteArrayAsListTest extends TestCase {
return Bytes.asList(temp);
}
+ @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Byte>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/BytesTest.java b/guava-tests/test/com/google/common/primitives/BytesTest.java
index a30061c..e268427 100644
--- a/guava-tests/test/com/google/common/primitives/BytesTest.java
+++ b/guava-tests/test/com/google/common/primitives/BytesTest.java
@@ -200,6 +200,24 @@ public class BytesTest extends TestCase {
}
}
+ public void testToArray_withConversion() {
+ byte[] array = {(byte) 0, (byte) 1, (byte) 2};
+
+ List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
+ List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
+ List<Integer> ints = Arrays.asList(0, 1, 2);
+ List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
+ List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
+ List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
+
+ assertTrue(Arrays.equals(array, Bytes.toArray(bytes)));
+ assertTrue(Arrays.equals(array, Bytes.toArray(shorts)));
+ assertTrue(Arrays.equals(array, Bytes.toArray(ints)));
+ assertTrue(Arrays.equals(array, Bytes.toArray(floats)));
+ assertTrue(Arrays.equals(array, Bytes.toArray(longs)));
+ assertTrue(Arrays.equals(array, Bytes.toArray(doubles)));
+ }
+
public void testAsList_isAView() {
byte[] array = {(byte) 0, (byte) 1};
List<Byte> list = Bytes.asList(array);
@@ -237,9 +255,7 @@ public class BytesTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(byte[].class, new byte[0]);
- tester.testAllPublicStaticMethods(Bytes.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(Bytes.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java
index 23b88b1..c2eae49 100644
--- a/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/CharArrayAsListTest.java
@@ -19,6 +19,7 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -38,7 +39,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class CharArrayAsListTest extends TestCase {
private static List<Character> asList(Character[] values) {
@@ -49,6 +50,7 @@ public class CharArrayAsListTest extends TestCase {
return Chars.asList(temp);
}
+ @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Character>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/CharsTest.java b/guava-tests/test/com/google/common/primitives/CharsTest.java
index adc1898..e6d7439 100644
--- a/guava-tests/test/com/google/common/primitives/CharsTest.java
+++ b/guava-tests/test/com/google/common/primitives/CharsTest.java
@@ -390,9 +390,7 @@ public class CharsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(char[].class, new char[0]);
- tester.testAllPublicStaticMethods(Chars.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(Chars.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java
index 1fa39d7..a20f7f5 100644
--- a/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/DoubleArrayAsListTest.java
@@ -19,6 +19,7 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -38,7 +39,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class DoubleArrayAsListTest extends TestCase {
private static List<Double> asList(Double[] values) {
@@ -49,6 +50,7 @@ public class DoubleArrayAsListTest extends TestCase {
return Doubles.asList(temp);
}
+ @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Double>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/DoublesTest.java b/guava-tests/test/com/google/common/primitives/DoublesTest.java
index 68fdc59..5e1e4c8 100644
--- a/guava-tests/test/com/google/common/primitives/DoublesTest.java
+++ b/guava-tests/test/com/google/common/primitives/DoublesTest.java
@@ -17,10 +17,11 @@
package com.google.common.primitives;
import static java.lang.Double.NaN;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.Helpers;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -50,9 +51,10 @@ public class DoublesTest extends TestCase {
private static final double GREATEST = Double.POSITIVE_INFINITY;
private static final double[] NUMBERS = new double[] {
- LEAST, -Double.MAX_VALUE, -1.0, -0.0, 0.0, 1.0, Double.MAX_VALUE, GREATEST,
- Double.MIN_NORMAL, -Double.MIN_NORMAL, Double.MIN_VALUE, -Double.MIN_VALUE,
- Integer.MIN_VALUE, Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE
+ LEAST, -Double.MAX_VALUE, -1.0, -0.5, -0.1, -0.0, 0.0, 0.1, 0.5, 1.0,
+ Double.MAX_VALUE, GREATEST, Double.MIN_NORMAL, -Double.MIN_NORMAL,
+ Double.MIN_VALUE, -Double.MIN_VALUE, Integer.MIN_VALUE,
+ Integer.MAX_VALUE, Long.MIN_VALUE, Long.MAX_VALUE
};
private static final double[] VALUES
@@ -337,13 +339,31 @@ public class DoublesTest extends TestCase {
}
}
+ public void testToArray_withConversion() {
+ double[] array = {(double) 0, (double) 1, (double) 2};
+
+ List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
+ List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
+ List<Integer> ints = Arrays.asList(0, 1, 2);
+ List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
+ List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
+ List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
+
+ assertTrue(Arrays.equals(array, Doubles.toArray(bytes)));
+ assertTrue(Arrays.equals(array, Doubles.toArray(shorts)));
+ assertTrue(Arrays.equals(array, Doubles.toArray(ints)));
+ assertTrue(Arrays.equals(array, Doubles.toArray(floats)));
+ assertTrue(Arrays.equals(array, Doubles.toArray(longs)));
+ assertTrue(Arrays.equals(array, Doubles.toArray(doubles)));
+ }
+
public void testAsList_isAView() {
double[] array = {(double) 0, (double) 1};
List<Double> list = Doubles.asList(array);
list.set(0, (double) 2);
assertTrue(Arrays.equals(new double[] {(double) 2, (double) 1}, array));
array[1] = (double) 3;
- ASSERT.that(list).hasContentsInOrder((double) 2, (double) 3);
+ ASSERT.that(list).has().allOf((double) 2, (double) 3).inOrder();
}
public void testAsList_toArray_roundTrip() {
@@ -373,10 +393,108 @@ public class DoublesTest extends TestCase {
assertSame(Collections.emptyList(), Doubles.asList(EMPTY));
}
+ /**
+ * A reference implementation for {@code tryParse} that just catches the exception from
+ * {@link Double#valueOf}.
+ */
+ private static Double referenceTryParse(String input) {
+ if (input.trim().length() < input.length()) {
+ return null;
+ }
+ try {
+ return Double.valueOf(input);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ @GwtIncompatible("Doubles.tryParse")
+ private static void checkTryParse(String input) {
+ Double expected = referenceTryParse(input);
+ assertEquals(expected, Doubles.tryParse(input));
+ assertEquals(expected != null,
+ Doubles.FLOATING_POINT_PATTERN.matcher(input).matches());
+ }
+
+ @GwtIncompatible("Doubles.tryParse")
+ private static void checkTryParse(double expected, String input) {
+ assertEquals(Double.valueOf(expected), Doubles.tryParse(input));
+ assertTrue(Doubles.FLOATING_POINT_PATTERN.matcher(input).matches());
+ }
+
+ @GwtIncompatible("Doubles.tryParse")
+ public void testTryParseHex() {
+ for (String signChar : ImmutableList.of("", "+", "-")) {
+ for (String hexPrefix : ImmutableList.of("0x", "0X")) {
+ for (String iPart : ImmutableList.of("", "0", "1", "F", "f", "c4", "CE")) {
+ for (String fPart : ImmutableList.of("", ".", ".F", ".52", ".a")) {
+ for (String expMarker : ImmutableList.of("p", "P")) {
+ for (String exponent : ImmutableList.of("0", "-5", "+20", "52")) {
+ for (String typePart : ImmutableList.of("", "D", "F", "d", "f")) {
+ checkTryParse(
+ signChar + hexPrefix + iPart + fPart + expMarker + exponent + typePart);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @GwtIncompatible("Doubles.tryParse")
+ public void testTryParseAllCodePoints() {
+ // Exercise non-ASCII digit test cases and the like.
+ char[] tmp = new char[2];
+ for (int i = Character.MIN_CODE_POINT; i < Character.MAX_CODE_POINT; i++) {
+ Character.toChars(i, tmp, 0);
+ checkTryParse(String.copyValueOf(tmp, 0, Character.charCount(i)));
+ }
+ }
+
+ @GwtIncompatible("Doubles.tryParse")
+ public void testTryParseOfToStringIsOriginal() {
+ for (double d : NUMBERS) {
+ checkTryParse(d, Double.toString(d));
+ }
+ }
+
+ @GwtIncompatible("Doubles.tryParse")
+ public void testTryParseOfToHexStringIsOriginal() {
+ for (double d : NUMBERS) {
+ checkTryParse(d, Double.toHexString(d));
+ }
+ }
+
+ @GwtIncompatible("Doubles.tryParse")
+ public void testTryParseNaN() {
+ checkTryParse("NaN");
+ checkTryParse("+NaN");
+ checkTryParse("-NaN");
+ }
+
+ @GwtIncompatible("Doubles.tryParse")
+ public void testTryParseInfinity() {
+ checkTryParse(Double.POSITIVE_INFINITY, "Infinity");
+ checkTryParse(Double.POSITIVE_INFINITY, "+Infinity");
+ checkTryParse(Double.NEGATIVE_INFINITY, "-Infinity");
+ }
+
+ private static final String[] BAD_TRY_PARSE_INPUTS =
+ { "", "+-", "+-0", " 5", "32 ", " 55 ", "infinity", "POSITIVE_INFINITY", "0x9A", "0x9A.bE-5",
+ ".", ".e5", "NaNd", "InfinityF" };
+
+ @GwtIncompatible("Doubles.tryParse")
+ public void testTryParseFailures() {
+ for (String badInput : BAD_TRY_PARSE_INPUTS) {
+ assertFalse(Doubles.FLOATING_POINT_PATTERN.matcher(badInput).matches());
+ assertEquals(referenceTryParse(badInput), Doubles.tryParse(badInput));
+ assertNull(Doubles.tryParse(badInput));
+ }
+ }
+
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(double[].class, new double[0]);
- tester.testAllPublicStaticMethods(Doubles.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(Doubles.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java
index ded5a77..06dd93b 100644
--- a/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/FloatArrayAsListTest.java
@@ -19,6 +19,7 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -38,7 +39,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class FloatArrayAsListTest extends TestCase {
private static List<Float> asList(Float[] values) {
@@ -49,6 +50,7 @@ public class FloatArrayAsListTest extends TestCase {
return Floats.asList(temp);
}
+ @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Float>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/FloatsTest.java b/guava-tests/test/com/google/common/primitives/FloatsTest.java
index 55f5bbc..e4d99ab 100644
--- a/guava-tests/test/com/google/common/primitives/FloatsTest.java
+++ b/guava-tests/test/com/google/common/primitives/FloatsTest.java
@@ -17,10 +17,11 @@
package com.google.common.primitives;
import static java.lang.Float.NaN;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.Helpers;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
@@ -329,13 +330,31 @@ public class FloatsTest extends TestCase {
}
}
+ public void testToArray_withConversion() {
+ float[] array = {(float) 0, (float) 1, (float) 2};
+
+ List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
+ List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
+ List<Integer> ints = Arrays.asList(0, 1, 2);
+ List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
+ List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
+ List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
+
+ assertTrue(Arrays.equals(array, Floats.toArray(bytes)));
+ assertTrue(Arrays.equals(array, Floats.toArray(shorts)));
+ assertTrue(Arrays.equals(array, Floats.toArray(ints)));
+ assertTrue(Arrays.equals(array, Floats.toArray(floats)));
+ assertTrue(Arrays.equals(array, Floats.toArray(longs)));
+ assertTrue(Arrays.equals(array, Floats.toArray(doubles)));
+ }
+
public void testAsList_isAView() {
float[] array = {(float) 0, (float) 1};
List<Float> list = Floats.asList(array);
list.set(0, (float) 2);
assertTrue(Arrays.equals(new float[] {(float) 2, (float) 1}, array));
array[1] = (float) 3;
- ASSERT.that(list).hasContentsInOrder((float) 2, (float) 3);
+ ASSERT.that(list).has().allOf((float) 2, (float) 3).inOrder();
}
public void testAsList_toArray_roundTrip() {
@@ -365,10 +384,103 @@ public class FloatsTest extends TestCase {
assertSame(Collections.emptyList(), Floats.asList(EMPTY));
}
+ /**
+ * A reference implementation for {@code tryParse} that just catches the exception from
+ * {@link Float#valueOf}.
+ */
+ private static Float referenceTryParse(String input) {
+ if (input.trim().length() < input.length()) {
+ return null;
+ }
+ try {
+ return Float.valueOf(input);
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ }
+
+ @GwtIncompatible("Floats.tryParse")
+ private static void checkTryParse(String input) {
+ assertEquals(referenceTryParse(input), Floats.tryParse(input));
+ }
+
+ @GwtIncompatible("Floats.tryParse")
+ private static void checkTryParse(float expected, String input) {
+ assertEquals(Float.valueOf(expected), Floats.tryParse(input));
+ }
+
+ @GwtIncompatible("Floats.tryParse")
+ public void testTryParseHex() {
+ for (String signChar : ImmutableList.of("", "+", "-")) {
+ for (String hexPrefix : ImmutableList.of("0x", "0X")) {
+ for (String iPart : ImmutableList.of("", "0", "1", "F", "f", "c4", "CE")) {
+ for (String fPart : ImmutableList.of("", ".", ".F", ".52", ".a")) {
+ for (String expMarker : ImmutableList.of("p", "P")) {
+ for (String exponent : ImmutableList.of("0", "-5", "+20", "52")) {
+ for (String typePart : ImmutableList.of("", "D", "F", "d", "f")) {
+ checkTryParse(
+ signChar + hexPrefix + iPart + fPart + expMarker + exponent + typePart);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @GwtIncompatible("Floats.tryParse")
+ public void testTryParseAllCodePoints() {
+ // Exercise non-ASCII digit test cases and the like.
+ char[] tmp = new char[2];
+ for (int i = Character.MIN_CODE_POINT; i < Character.MAX_CODE_POINT; i++) {
+ Character.toChars(i, tmp, 0);
+ checkTryParse(String.copyValueOf(tmp, 0, Character.charCount(i)));
+ }
+ }
+
+ @GwtIncompatible("Floats.tryParse")
+ public void testTryParseOfToStringIsOriginal() {
+ for (float f : NUMBERS) {
+ checkTryParse(f, Float.toString(f));
+ }
+ }
+
+ @GwtIncompatible("Floats.tryParse")
+ public void testTryParseOfToHexStringIsOriginal() {
+ for (float f : NUMBERS) {
+ checkTryParse(f, Float.toHexString(f));
+ }
+ }
+
+ @GwtIncompatible("Floats.tryParse")
+ public void testTryParseNaN() {
+ checkTryParse("NaN");
+ checkTryParse("+NaN");
+ checkTryParse("-NaN");
+ }
+
+ @GwtIncompatible("Floats.tryParse")
+ public void testTryParseInfinity() {
+ checkTryParse(Float.POSITIVE_INFINITY, "Infinity");
+ checkTryParse(Float.POSITIVE_INFINITY, "+Infinity");
+ checkTryParse(Float.NEGATIVE_INFINITY, "-Infinity");
+ }
+
+ private static final String[] BAD_TRY_PARSE_INPUTS =
+ { "", "+-", "+-0", " 5", "32 ", " 55 ", "infinity", "POSITIVE_INFINITY", "0x9A", "0x9A.bE-5",
+ ".", ".e5", "NaNd", "InfinityF" };
+
+ @GwtIncompatible("Floats.tryParse")
+ public void testTryParseFailures() {
+ for (String badInput : BAD_TRY_PARSE_INPUTS) {
+ assertEquals(referenceTryParse(badInput), Floats.tryParse(badInput));
+ assertNull(Floats.tryParse(badInput));
+ }
+ }
+
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(float[].class, new float[0]);
- tester.testAllPublicStaticMethods(Floats.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(Floats.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java
index d384149..efdbbb2 100644
--- a/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/IntArrayAsListTest.java
@@ -19,6 +19,7 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -38,7 +39,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
@SuppressWarnings("cast") // redundant casts are intentional and harmless
public class IntArrayAsListTest extends TestCase {
@@ -50,6 +51,7 @@ public class IntArrayAsListTest extends TestCase {
return Ints.asList(temp);
}
+ @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Integer>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/IntsTest.java b/guava-tests/test/com/google/common/primitives/IntsTest.java
index 8265b80..6ac5185 100644
--- a/guava-tests/test/com/google/common/primitives/IntsTest.java
+++ b/guava-tests/test/com/google/common/primitives/IntsTest.java
@@ -76,7 +76,7 @@ public class IntsTest extends TestCase {
assertEquals(LEAST, Ints.saturatedCast(Long.MIN_VALUE));
}
- private void assertCastFails(long value) {
+ private static void assertCastFails(long value) {
try {
Ints.checkedCast(value);
fail("Cast to int should have failed: " + value);
@@ -356,6 +356,24 @@ public class IntsTest extends TestCase {
}
}
+ public void testToArray_withConversion() {
+ int[] array = {0, 1, 2};
+
+ List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
+ List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
+ List<Integer> ints = Arrays.asList(0, 1, 2);
+ List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
+ List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
+ List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
+
+ assertTrue(Arrays.equals(array, Ints.toArray(bytes)));
+ assertTrue(Arrays.equals(array, Ints.toArray(shorts)));
+ assertTrue(Arrays.equals(array, Ints.toArray(ints)));
+ assertTrue(Arrays.equals(array, Ints.toArray(floats)));
+ assertTrue(Arrays.equals(array, Ints.toArray(longs)));
+ assertTrue(Arrays.equals(array, Ints.toArray(doubles)));
+ }
+
public void testAsList_isAView() {
int[] array = {(int) 0, (int) 1};
List<Integer> list = Ints.asList(array);
@@ -393,10 +411,8 @@ public class IntsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(int[].class, new int[0]);
- tester.testAllPublicStaticMethods(Ints.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(Ints.class);
}
@GwtIncompatible("AndroidInteger")
diff --git a/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java
index 1fa140f..c5049c4 100644
--- a/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/LongArrayAsListTest.java
@@ -19,6 +19,7 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -38,7 +39,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class LongArrayAsListTest extends TestCase {
private static List<Long> asList(Long[] values) {
@@ -49,6 +50,7 @@ public class LongArrayAsListTest extends TestCase {
return Longs.asList(temp);
}
+ @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Long>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/LongsTest.java b/guava-tests/test/com/google/common/primitives/LongsTest.java
index b92dd67..c5098c4 100644
--- a/guava-tests/test/com/google/common/primitives/LongsTest.java
+++ b/guava-tests/test/com/google/common/primitives/LongsTest.java
@@ -16,6 +16,9 @@
package com.google.common.primitives;
+import static java.lang.Long.MAX_VALUE;
+import static java.lang.Long.MIN_VALUE;
+
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.testing.Helpers;
@@ -24,6 +27,7 @@ import com.google.common.testing.SerializableTester;
import junit.framework.TestCase;
+import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -44,11 +48,8 @@ public class LongsTest extends TestCase {
private static final long[] ARRAY234
= {(long) 2, (long) 3, (long) 4};
- private static final long LEAST = Long.MIN_VALUE;
- private static final long GREATEST = Long.MAX_VALUE;
-
private static final long[] VALUES =
- { LEAST, (long) -1, (long) 0, (long) 1, GREATEST };
+ { MIN_VALUE, (long) -1, (long) 0, (long) 1, MAX_VALUE };
@GwtIncompatible("Long.hashCode returns different values in GWT.")
public void testHashCode() {
@@ -150,8 +151,8 @@ public class LongsTest extends TestCase {
}
public void testMax() {
- assertEquals(LEAST, Longs.max(LEAST));
- assertEquals(GREATEST, Longs.max(GREATEST));
+ assertEquals(MIN_VALUE, Longs.max(MIN_VALUE));
+ assertEquals(MAX_VALUE, Longs.max(MAX_VALUE));
assertEquals((long) 9, Longs.max(
(long) 8, (long) 6, (long) 7,
(long) 5, (long) 3, (long) 0, (long) 9));
@@ -166,8 +167,8 @@ public class LongsTest extends TestCase {
}
public void testMin() {
- assertEquals(LEAST, Longs.min(LEAST));
- assertEquals(GREATEST, Longs.min(GREATEST));
+ assertEquals(MIN_VALUE, Longs.min(MIN_VALUE));
+ assertEquals(MAX_VALUE, Longs.min(MAX_VALUE));
assertEquals((long) 0, Longs.min(
(long) 8, (long) 6, (long) 7,
(long) 5, (long) 3, (long) 0, (long) 9));
@@ -188,19 +189,23 @@ public class LongsTest extends TestCase {
Longs.concat(ARRAY1, ARRAY234)));
}
- @GwtIncompatible("Longs.toByteArray")
+ private static void assertByteArrayEquals(byte[] expected, byte[] actual) {
+ assertTrue(
+ "Expected: " + Arrays.toString(expected) + ", but got: " + Arrays.toString(actual),
+ Arrays.equals(expected, actual));
+ }
+
public void testToByteArray() {
- assertTrue(Arrays.equals(
+ assertByteArrayEquals(
new byte[] {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19},
- Longs.toByteArray(0x1213141516171819L)));
- assertTrue(Arrays.equals(
+ Longs.toByteArray(0x1213141516171819L));
+ assertByteArrayEquals(
new byte[] {
(byte) 0xFF, (byte) 0xEE, (byte) 0xDD, (byte) 0xCC,
(byte) 0xBB, (byte) 0xAA, (byte) 0x99, (byte) 0x88},
- Longs.toByteArray(0xFFEEDDCCBBAA9988L)));
+ Longs.toByteArray(0xFFEEDDCCBBAA9988L));
}
- @GwtIncompatible("Longs.fromByteArray")
public void testFromByteArray() {
assertEquals(0x1213141516171819L, Longs.fromByteArray(
new byte[] {0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x33}));
@@ -216,7 +221,6 @@ public class LongsTest extends TestCase {
}
}
- @GwtIncompatible("Longs.fromBytes")
public void testFromBytes() {
assertEquals(0x1213141516171819L, Longs.fromBytes(
(byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15,
@@ -226,7 +230,6 @@ public class LongsTest extends TestCase {
(byte) 0xBB, (byte) 0xAA, (byte) 0x99, (byte) 0x88));
}
- @GwtIncompatible("Longs.fromByteArray, Longs.toByteArray")
public void testByteArrayRoundTrips() {
Random r = new Random(5);
byte[] b = new byte[Longs.BYTES];
@@ -276,14 +279,14 @@ public class LongsTest extends TestCase {
public void testLexicographicalComparator() {
List<long[]> ordered = Arrays.asList(
new long[] {},
- new long[] {LEAST},
- new long[] {LEAST, LEAST},
- new long[] {LEAST, (long) 1},
+ new long[] {MIN_VALUE},
+ new long[] {MIN_VALUE, MIN_VALUE},
+ new long[] {MIN_VALUE, (long) 1},
new long[] {(long) 1},
- new long[] {(long) 1, LEAST},
- new long[] {GREATEST, GREATEST - (long) 1},
- new long[] {GREATEST, GREATEST},
- new long[] {GREATEST, GREATEST, GREATEST});
+ new long[] {(long) 1, MIN_VALUE},
+ new long[] {MAX_VALUE, MAX_VALUE - (long) 1},
+ new long[] {MAX_VALUE, MAX_VALUE},
+ new long[] {MAX_VALUE, MAX_VALUE, MAX_VALUE});
Comparator<long[]> comparator = Longs.lexicographicalComparator();
Helpers.testComparator(comparator, ordered);
@@ -336,6 +339,24 @@ public class LongsTest extends TestCase {
}
}
+ public void testToArray_withConversion() {
+ long[] array = {(long) 0, (long) 1, (long) 2};
+
+ List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
+ List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
+ List<Integer> ints = Arrays.asList(0, 1, 2);
+ List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
+ List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
+ List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
+
+ assertTrue(Arrays.equals(array, Longs.toArray(bytes)));
+ assertTrue(Arrays.equals(array, Longs.toArray(shorts)));
+ assertTrue(Arrays.equals(array, Longs.toArray(ints)));
+ assertTrue(Arrays.equals(array, Longs.toArray(floats)));
+ assertTrue(Arrays.equals(array, Longs.toArray(longs)));
+ assertTrue(Arrays.equals(array, Longs.toArray(doubles)));
+ }
+
public void testAsList_isAView() {
long[] array = {(long) 0, (long) 1};
List<Long> list = Longs.asList(array);
@@ -373,9 +394,35 @@ public class LongsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(long[].class, new long[0]);
- tester.testAllPublicStaticMethods(Longs.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(Longs.class);
+ }
+
+ @GwtIncompatible("AndroidInteger")
+ public void testTryParse() {
+ tryParseAndAssertEquals(0L, "0");
+ tryParseAndAssertEquals(0L, "-0");
+ tryParseAndAssertEquals(1L, "1");
+ tryParseAndAssertEquals(-1L, "-1");
+ tryParseAndAssertEquals(8900L, "8900");
+ tryParseAndAssertEquals(-8900L, "-8900");
+ tryParseAndAssertEquals(MAX_VALUE, Long.toString(MAX_VALUE));
+ tryParseAndAssertEquals(MIN_VALUE, Long.toString(MIN_VALUE));
+ assertNull(Longs.tryParse(""));
+ assertNull(Longs.tryParse("-"));
+ assertNull(Longs.tryParse("+1"));
+ assertNull(Longs.tryParse("999999999999999999999999"));
+ assertNull("Max integer + 1",
+ Longs.tryParse(BigInteger.valueOf(MAX_VALUE).add(BigInteger.ONE).toString()));
+ assertNull("Min integer - 1",
+ Longs.tryParse(BigInteger.valueOf(MIN_VALUE).subtract(BigInteger.ONE).toString()));
+ }
+
+ /**
+ * Applies {@link Longs#tryParse(String)} to the given string and asserts that
+ * the result is as expected.
+ */
+ private static void tryParseAndAssertEquals(Long expected, String value) {
+ assertEquals(expected, Longs.tryParse(value));
}
}
diff --git a/guava-tests/test/com/google/common/primitives/PackageSanityTests.java b/guava-tests/test/com/google/common/primitives/PackageSanityTests.java
new file mode 100644
index 0000000..3f3e745
--- /dev/null
+++ b/guava-tests/test/com/google/common/primitives/PackageSanityTests.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.primitives;
+
+import com.google.common.testing.AbstractPackageSanityTests;
+
+/**
+ * Tests basic sanity for each class in the package.
+ *
+ * @author Ben Yu
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {
+ public PackageSanityTests() {
+ setDefault(String.class, "string");
+ }
+}
diff --git a/guava-tests/test/com/google/common/primitives/PrimitivesTest.java b/guava-tests/test/com/google/common/primitives/PrimitivesTest.java
index 9fba2aa..b3ef33c 100644
--- a/guava-tests/test/com/google/common/primitives/PrimitivesTest.java
+++ b/guava-tests/test/com/google/common/primitives/PrimitivesTest.java
@@ -76,7 +76,7 @@ public class PrimitivesTest extends TestCase {
}
}
- public void testNullPointerExceptions() throws Exception {
+ public void testNullPointerExceptions() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicStaticMethods(Primitives.class);
}
diff --git a/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java b/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java
index 3fb6a4d..78086e4 100644
--- a/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java
+++ b/guava-tests/test/com/google/common/primitives/ShortArrayAsListTest.java
@@ -19,6 +19,7 @@ package com.google.common.primitives;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.testing.ListTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
@@ -38,7 +39,7 @@ import java.util.List;
*
* @author Kevin Bourrillion
*/
-@GwtCompatible
+@GwtCompatible(emulated = true)
public class ShortArrayAsListTest extends TestCase {
private static List<Short> asList(Short[] values) {
@@ -49,6 +50,7 @@ public class ShortArrayAsListTest extends TestCase {
return Shorts.asList(temp);
}
+ @GwtIncompatible("suite")
public static Test suite() {
List<ListTestSuiteBuilder<Short>> builders =
ImmutableList.of(
diff --git a/guava-tests/test/com/google/common/primitives/ShortsTest.java b/guava-tests/test/com/google/common/primitives/ShortsTest.java
index e98510a..3cc7b61 100644
--- a/guava-tests/test/com/google/common/primitives/ShortsTest.java
+++ b/guava-tests/test/com/google/common/primitives/ShortsTest.java
@@ -76,7 +76,7 @@ public class ShortsTest extends TestCase {
assertEquals(LEAST, Shorts.saturatedCast(Long.MIN_VALUE));
}
- private void assertCastFails(long value) {
+ private static void assertCastFails(long value) {
try {
Shorts.checkedCast(value);
fail("Cast to short should have failed: " + value);
@@ -363,6 +363,24 @@ public class ShortsTest extends TestCase {
}
}
+ public void testToArray_withConversion() {
+ short[] array = {(short) 0, (short) 1, (short) 2};
+
+ List<Byte> bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
+ List<Short> shorts = Arrays.asList((short) 0, (short) 1, (short) 2);
+ List<Integer> ints = Arrays.asList(0, 1, 2);
+ List<Float> floats = Arrays.asList((float) 0, (float) 1, (float) 2);
+ List<Long> longs = Arrays.asList((long) 0, (long) 1, (long) 2);
+ List<Double> doubles = Arrays.asList((double) 0, (double) 1, (double) 2);
+
+ assertTrue(Arrays.equals(array, Shorts.toArray(bytes)));
+ assertTrue(Arrays.equals(array, Shorts.toArray(shorts)));
+ assertTrue(Arrays.equals(array, Shorts.toArray(ints)));
+ assertTrue(Arrays.equals(array, Shorts.toArray(floats)));
+ assertTrue(Arrays.equals(array, Shorts.toArray(longs)));
+ assertTrue(Arrays.equals(array, Shorts.toArray(doubles)));
+ }
+
public void testAsList_isAView() {
short[] array = {(short) 0, (short) 1};
List<Short> list = Shorts.asList(array);
@@ -400,9 +418,7 @@ public class ShortsTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(short[].class, new short[0]);
- tester.testAllPublicStaticMethods(Shorts.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(Shorts.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/SignedBytesTest.java b/guava-tests/test/com/google/common/primitives/SignedBytesTest.java
index 18863a5..8e205fe 100644
--- a/guava-tests/test/com/google/common/primitives/SignedBytesTest.java
+++ b/guava-tests/test/com/google/common/primitives/SignedBytesTest.java
@@ -65,7 +65,7 @@ public class SignedBytesTest extends TestCase {
assertEquals(LEAST, SignedBytes.saturatedCast(Long.MIN_VALUE));
}
- private void assertCastFails(long value) {
+ private static void assertCastFails(long value) {
try {
SignedBytes.checkedCast(value);
fail("Cast to byte should have failed: " + value);
@@ -155,9 +155,7 @@ public class SignedBytesTest extends TestCase {
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(byte[].class, new byte[0]);
- tester.testAllPublicStaticMethods(SignedBytes.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(SignedBytes.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java b/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java
index 88ef454..916db9e 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java
@@ -30,6 +30,7 @@ import java.util.List;
* Unit test for {@link UnsignedBytes}.
*
* @author Kevin Bourrillion
+ * @author Louis Wasserman
*/
public class UnsignedBytesTest extends TestCase {
private static final byte LEAST = 0;
@@ -70,7 +71,7 @@ public class UnsignedBytesTest extends TestCase {
assertEquals(LEAST, UnsignedBytes.saturatedCast(Long.MIN_VALUE));
}
- private void assertCastFails(long value) {
+ private static void assertCastFails(long value) {
try {
UnsignedBytes.checkedCast(value);
fail("Cast to byte should have failed: " + value);
@@ -123,6 +124,95 @@ public class UnsignedBytesTest extends TestCase {
assertEquals(GREATEST, UnsignedBytes.min(GREATEST));
assertEquals((byte) 0, UnsignedBytes.min(
(byte) 0, (byte) -128, (byte) -1, (byte) 127, (byte) 1));
+ assertEquals((byte) 0, UnsignedBytes.min(
+ (byte) -1, (byte) 127, (byte) 1, (byte) -128, (byte) 0));
+ }
+
+ private static void assertParseFails(String value) {
+ try {
+ UnsignedBytes.parseUnsignedByte(value);
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+ }
+
+ public void testParseUnsignedByte() {
+ // We can easily afford to test this exhaustively.
+ for (int i = 0; i <= 0xff; i++) {
+ assertEquals((byte) i, UnsignedBytes.parseUnsignedByte(Integer.toString(i)));
+ }
+ assertParseFails("1000");
+ assertParseFails("-1");
+ assertParseFails("-128");
+ assertParseFails("256");
+ }
+
+ public void testMaxValue() {
+ assertTrue(UnsignedBytes
+ .compare(UnsignedBytes.MAX_VALUE, (byte) (UnsignedBytes.MAX_VALUE + 1)) > 0);
+ }
+
+ private static void assertParseFails(String value, int radix) {
+ try {
+ UnsignedBytes.parseUnsignedByte(value, radix);
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+ }
+
+ public void testParseUnsignedByteWithRadix() throws NumberFormatException {
+ // We can easily afford to test this exhaustively.
+ for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
+ for (int i = 0; i <= 0xff; i++) {
+ assertEquals((byte) i, UnsignedBytes.parseUnsignedByte(Integer.toString(i, radix), radix));
+ }
+ assertParseFails(Integer.toString(1000, radix), radix);
+ assertParseFails(Integer.toString(-1, radix), radix);
+ assertParseFails(Integer.toString(-128, radix), radix);
+ assertParseFails(Integer.toString(256, radix), radix);
+ }
+ }
+
+ public void testParseUnsignedByteThrowsExceptionForInvalidRadix() {
+ // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX,
+ // inclusive.
+ try {
+ UnsignedBytes.parseUnsignedByte("0", Character.MIN_RADIX - 1);
+ fail();
+ } catch (NumberFormatException nfe) {
+ // expected
+ }
+
+ try {
+ UnsignedBytes.parseUnsignedByte("0", Character.MAX_RADIX + 1);
+ fail();
+ } catch (NumberFormatException nfe) {
+ // expected
+ }
+
+ // The radix is used as an array index, so try a negative value.
+ try {
+ UnsignedBytes.parseUnsignedByte("0", -1);
+ fail();
+ } catch (NumberFormatException nfe) {
+ // expected
+ }
+ }
+
+ public void testToString() {
+ // We can easily afford to test this exhaustively.
+ for (int i = 0; i <= 0xff; i++) {
+ assertEquals(Integer.toString(i), UnsignedBytes.toString((byte) i));
+ }
+ }
+
+ public void testToStringWithRadix() {
+ // We can easily afford to test this exhaustively.
+ for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
+ for (int i = 0; i <= 0xff; i++) {
+ assertEquals(Integer.toString(i, radix), UnsignedBytes.toString((byte) i, radix));
+ }
+ }
}
public void testJoin() {
@@ -164,9 +254,7 @@ public class UnsignedBytesTest extends TestCase {
assertSame(javaImpl, SerializableTester.reserialize(javaImpl));
}
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(byte[].class, new byte[0]);
- tester.testAllPublicStaticMethods(UnsignedBytes.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(UnsignedBytes.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java b/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java
index fece9c9..6297261 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedIntegerTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -14,8 +14,6 @@
package com.google.common.primitives;
-import junit.framework.TestCase;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableSet;
@@ -23,47 +21,90 @@ import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
+import junit.framework.TestCase;
+
+import java.math.BigInteger;
+
/**
* Tests for {@code UnsignedInteger}.
- *
+ *
* @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
public class UnsignedIntegerTest extends TestCase {
private static final ImmutableSet<Integer> TEST_INTS;
+ private static final ImmutableSet<Long> TEST_LONGS;
private static int force32(int value) {
- // GWT doesn't overflow values to make them 32-bit, so we need to force it.
+ // GWT doesn't consistently overflow values to make them 32-bit, so we need to force it.
return value & 0xffffffff;
}
static {
ImmutableSet.Builder<Integer> testIntsBuilder = ImmutableSet.builder();
+ ImmutableSet.Builder<Long> testLongsBuilder = ImmutableSet.builder();
for (int i = -3; i <= 3; i++) {
- testIntsBuilder.add(i).add(-i).add(force32(Integer.MIN_VALUE + i))
- .add(force32(Integer.MAX_VALUE + i));
+ testIntsBuilder
+ .add(i)
+ .add(force32(Integer.MIN_VALUE + i))
+ .add(force32(Integer.MAX_VALUE + i));
+ testLongsBuilder
+ .add((long) i)
+ .add((long) Integer.MIN_VALUE + i)
+ .add((long) Integer.MAX_VALUE + i)
+ .add((1L << 32) + i);
}
TEST_INTS = testIntsBuilder.build();
+ TEST_LONGS = testLongsBuilder.build();
}
- public void testAsUnsignedAndIntValueAreInverses() {
+ public void testFromIntBitsAndIntValueAreInverses() {
for (int value : TEST_INTS) {
- assertEquals(UnsignedInts.toString(value), value, UnsignedInteger.asUnsigned(value)
+ assertEquals(UnsignedInts.toString(value), value, UnsignedInteger.fromIntBits(value)
.intValue());
}
}
- public void testAsUnsignedLongValue() {
+ public void testFromIntBitsLongValue() {
for (int value : TEST_INTS) {
long expected = value & 0xffffffffL;
- assertEquals(UnsignedInts.toString(value), expected, UnsignedInteger.asUnsigned(value)
+ assertEquals(UnsignedInts.toString(value), expected, UnsignedInteger.fromIntBits(value)
.longValue());
}
}
+
+ public void testValueOfLong() {
+ long min = 0;
+ long max = (1L << 32) - 1;
+ for (long value : TEST_LONGS) {
+ boolean expectSuccess = value >= min && value <= max;
+ try {
+ assertEquals(value, UnsignedInteger.valueOf(value).longValue());
+ assertTrue(expectSuccess);
+ } catch (IllegalArgumentException e) {
+ assertFalse(expectSuccess);
+ }
+ }
+ }
+
+ public void testValueOfBigInteger() {
+ long min = 0;
+ long max = (1L << 32) - 1;
+ for (long value : TEST_LONGS) {
+ boolean expectSuccess = value >= min && value <= max;
+ try {
+ assertEquals(value, UnsignedInteger.valueOf(BigInteger.valueOf(value))
+ .longValue());
+ assertTrue(expectSuccess);
+ } catch (IllegalArgumentException e) {
+ assertFalse(expectSuccess);
+ }
+ }
+ }
public void testToString() {
for (int value : TEST_INTS) {
- UnsignedInteger unsignedValue = UnsignedInteger.asUnsigned(value);
+ UnsignedInteger unsignedValue = UnsignedInteger.fromIntBits(value);
assertEquals(unsignedValue.bigIntegerValue().toString(), unsignedValue.toString());
}
}
@@ -72,7 +113,7 @@ public class UnsignedIntegerTest extends TestCase {
public void testToStringRadix() {
for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
for (int l : TEST_INTS) {
- UnsignedInteger value = UnsignedInteger.asUnsigned(l);
+ UnsignedInteger value = UnsignedInteger.fromIntBits(l);
assertEquals(value.bigIntegerValue().toString(radix), value.toString(radix));
}
}
@@ -82,7 +123,7 @@ public class UnsignedIntegerTest extends TestCase {
int[] radices = {2, 3, 5, 7, 10, 12, 16, 21, 31, 36};
for (int radix : radices) {
for (int l : TEST_INTS) {
- UnsignedInteger value = UnsignedInteger.asUnsigned(l);
+ UnsignedInteger value = UnsignedInteger.fromIntBits(l);
assertEquals(value.bigIntegerValue().toString(radix), value.toString(radix));
}
}
@@ -90,66 +131,66 @@ public class UnsignedIntegerTest extends TestCase {
public void testFloatValue() {
for (int value : TEST_INTS) {
- UnsignedInteger unsignedValue = UnsignedInteger.asUnsigned(value);
+ UnsignedInteger unsignedValue = UnsignedInteger.fromIntBits(value);
assertEquals(unsignedValue.bigIntegerValue().floatValue(), unsignedValue.floatValue());
}
}
public void testDoubleValue() {
for (int value : TEST_INTS) {
- UnsignedInteger unsignedValue = UnsignedInteger.asUnsigned(value);
+ UnsignedInteger unsignedValue = UnsignedInteger.fromIntBits(value);
assertEquals(unsignedValue.bigIntegerValue().doubleValue(), unsignedValue.doubleValue());
}
}
- public void testAdd() {
+ public void testPlus() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
- UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
- UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
int expected = aUnsigned.bigIntegerValue().add(bUnsigned.bigIntegerValue()).intValue();
- UnsignedInteger unsignedSum = aUnsigned.add(bUnsigned);
+ UnsignedInteger unsignedSum = aUnsigned.plus(bUnsigned);
assertEquals(expected, unsignedSum.intValue());
}
}
}
- public void testSubtract() {
+ public void testMinus() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
- UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
- UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
int expected =
force32(aUnsigned.bigIntegerValue().subtract(bUnsigned.bigIntegerValue()).intValue());
- UnsignedInteger unsignedSub = aUnsigned.subtract(bUnsigned);
+ UnsignedInteger unsignedSub = aUnsigned.minus(bUnsigned);
assertEquals(expected, unsignedSub.intValue());
}
}
}
@GwtIncompatible("multiply")
- public void testMultiply() {
+ public void testTimes() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
- UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
- UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
int expected =
force32(aUnsigned.bigIntegerValue().multiply(bUnsigned.bigIntegerValue()).intValue());
- UnsignedInteger unsignedMul = aUnsigned.multiply(bUnsigned);
+ UnsignedInteger unsignedMul = aUnsigned.times(bUnsigned);
assertEquals(aUnsigned + " * " + bUnsigned, expected, unsignedMul.intValue());
}
}
}
- public void testDivide() {
+ public void testDividedBy() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
if (b != 0) {
- UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
- UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
int expected =
aUnsigned.bigIntegerValue().divide(bUnsigned.bigIntegerValue()).intValue();
- UnsignedInteger unsignedDiv = aUnsigned.divide(bUnsigned);
+ UnsignedInteger unsignedDiv = aUnsigned.dividedBy(bUnsigned);
assertEquals(expected, unsignedDiv.intValue());
}
}
@@ -159,31 +200,32 @@ public class UnsignedIntegerTest extends TestCase {
public void testDivideByZeroThrows() {
for (int a : TEST_INTS) {
try {
- UnsignedInteger.asUnsigned(a).divide(UnsignedInteger.ZERO);
+ UnsignedInteger.fromIntBits(a).divide(UnsignedInteger.ZERO);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
}
- public void testRemainder() {
+ public void testMod() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
if (b != 0) {
- UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
- UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
int expected =
- aUnsigned.bigIntegerValue().remainder(bUnsigned.bigIntegerValue()).intValue();
- UnsignedInteger unsignedRem = aUnsigned.remainder(bUnsigned);
+ aUnsigned.bigIntegerValue().mod(bUnsigned.bigIntegerValue()).intValue();
+ UnsignedInteger unsignedRem = aUnsigned.mod(bUnsigned);
assertEquals(expected, unsignedRem.intValue());
}
}
}
}
- public void testRemainderByZero() {
+ @SuppressWarnings("ReturnValueIgnored")
+ public void testModByZero() {
for (int a : TEST_INTS) {
try {
- UnsignedInteger.asUnsigned(a).remainder(UnsignedInteger.ZERO);
+ UnsignedInteger.fromIntBits(a).mod(UnsignedInteger.ZERO);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
@@ -192,8 +234,8 @@ public class UnsignedIntegerTest extends TestCase {
public void testCompare() {
for (int a : TEST_INTS) {
for (int b : TEST_INTS) {
- UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
- UnsignedInteger bUnsigned = UnsignedInteger.asUnsigned(b);
+ UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
+ UnsignedInteger bUnsigned = UnsignedInteger.fromIntBits(b);
assertEquals(aUnsigned.bigIntegerValue().compareTo(bUnsigned.bigIntegerValue()),
aUnsigned.compareTo(bUnsigned));
}
@@ -201,11 +243,11 @@ public class UnsignedIntegerTest extends TestCase {
}
@GwtIncompatible("too slow")
- public void testEqualsAndValueOf() {
+ public void testEquals() {
EqualsTester equalsTester = new EqualsTester();
for (int a : TEST_INTS) {
long value = a & 0xffffffffL;
- equalsTester.addEqualityGroup(UnsignedInteger.asUnsigned(a), UnsignedInteger.valueOf(value),
+ equalsTester.addEqualityGroup(UnsignedInteger.fromIntBits(a), UnsignedInteger.valueOf(value),
UnsignedInteger.valueOf(Long.toString(value)),
UnsignedInteger.valueOf(Long.toString(value, 16), 16));
}
@@ -214,7 +256,7 @@ public class UnsignedIntegerTest extends TestCase {
public void testIntValue() {
for (int a : TEST_INTS) {
- UnsignedInteger aUnsigned = UnsignedInteger.asUnsigned(a);
+ UnsignedInteger aUnsigned = UnsignedInteger.fromIntBits(a);
int intValue = aUnsigned.bigIntegerValue().intValue();
assertEquals(intValue, aUnsigned.intValue());
}
@@ -223,14 +265,12 @@ public class UnsignedIntegerTest extends TestCase {
@GwtIncompatible("serialization")
public void testSerialization() {
for (int a : TEST_INTS) {
- SerializableTester.reserializeAndAssert(UnsignedInteger.asUnsigned(a));
+ SerializableTester.reserializeAndAssert(UnsignedInteger.fromIntBits(a));
}
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(UnsignedInteger.class, UnsignedInteger.ONE);
- tester.testAllPublicStaticMethods(UnsignedInteger.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(UnsignedInteger.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java b/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java
index 4ab36de..d1fd13c 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedIntsTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -14,17 +14,21 @@
package com.google.common.primitives;
-import java.util.Random;
-
-import junit.framework.TestCase;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.Helpers;
import com.google.common.testing.NullPointerTester;
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Random;
+
/**
* Tests for UnsignedInts
- *
+ *
* @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
@@ -41,6 +45,9 @@ public class UnsignedIntsTest extends TestCase {
0xfffffffdL,
0xfffffffeL,
0xffffffffL};
+
+ private static final int LEAST = (int) 0L;
+ private static final int GREATEST = (int) 0xffffffffL;
public void testToLong() {
for (long a : UNSIGNED_INTS) {
@@ -57,6 +64,57 @@ public class UnsignedIntsTest extends TestCase {
}
}
}
+
+ public void testMax_noArgs() {
+ try {
+ UnsignedInts.max();
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testMax() {
+ assertEquals(LEAST, UnsignedInts.max(LEAST));
+ assertEquals(GREATEST, UnsignedInts.max(GREATEST));
+ assertEquals((int) 0xff1a618bL, UnsignedInts.max(
+ (int) 8L, (int) 6L, (int) 7L,
+ (int) 0x12345678L, (int) 0x5a4316b8L,
+ (int) 0xff1a618bL, (int) 0L));
+ }
+
+ public void testMin_noArgs() {
+ try {
+ UnsignedInts.min();
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testMin() {
+ assertEquals(LEAST, UnsignedInts.min(LEAST));
+ assertEquals(GREATEST, UnsignedInts.min(GREATEST));
+ assertEquals((int) 0L, UnsignedInts.min(
+ (int) 8L, (int) 6L, (int) 7L,
+ (int) 0x12345678L, (int) 0x5a4316b8L,
+ (int) 0xff1a618bL, (int) 0L));
+ }
+
+ public void testLexicographicalComparator() {
+ List<int[]> ordered = Arrays.asList(
+ new int[] {},
+ new int[] {LEAST},
+ new int[] {LEAST, LEAST},
+ new int[] {LEAST, (int) 1L},
+ new int[] {(int) 1L},
+ new int[] {(int) 1L, LEAST},
+ new int[] {GREATEST, (GREATEST - (int) 1L)},
+ new int[] {GREATEST, GREATEST},
+ new int[] {GREATEST, GREATEST, GREATEST}
+ );
+
+ Comparator<int[]> comparator = UnsignedInts.lexicographicalComparator();
+ Helpers.testComparator(comparator, ordered);
+ }
public void testDivide() {
for (long a : UNSIGNED_INTS) {
@@ -113,7 +171,7 @@ public class UnsignedIntsTest extends TestCase {
} catch (NumberFormatException expected) {}
}
- public void testParseLongWithRadix() throws NumberFormatException {
+ public void testParseIntWithRadix() throws NumberFormatException {
for (long a : UNSIGNED_INTS) {
for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
assertEquals((int) a, UnsignedInts.parseUnsignedInt(Long.toString(a, radix), radix));
@@ -136,7 +194,7 @@ public class UnsignedIntsTest extends TestCase {
}
}
- public void testParseLongThrowsExceptionForInvalidRadix() {
+ public void testParseIntThrowsExceptionForInvalidRadix() {
// Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX,
// inclusive.
try {
@@ -156,6 +214,43 @@ public class UnsignedIntsTest extends TestCase {
} catch (NumberFormatException expected) {}
}
+ public void testDecodeInt() {
+ assertEquals(0xffffffff, UnsignedInts.decode("0xffffffff"));
+ assertEquals(01234567, UnsignedInts.decode("01234567")); // octal
+ assertEquals(0x12345678, UnsignedInts.decode("#12345678"));
+ assertEquals(76543210, UnsignedInts.decode("76543210"));
+ assertEquals(0x13579135, UnsignedInts.decode("0x13579135"));
+ assertEquals(0x13579135, UnsignedInts.decode("0X13579135"));
+ assertEquals(0, UnsignedInts.decode("0"));
+ }
+
+ public void testDecodeIntFails() {
+ try {
+ // One more than maximum value
+ UnsignedInts.decode("0xfffffffff");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+
+ try {
+ UnsignedInts.decode("-5");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+
+ try {
+ UnsignedInts.decode("-0x5");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+
+ try {
+ UnsignedInts.decode("-05");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+ }
+
public void testToString() {
int[] bases = {2, 5, 7, 8, 10, 16};
for (long a : UNSIGNED_INTS) {
@@ -165,10 +260,21 @@ public class UnsignedIntsTest extends TestCase {
}
}
+ public void testJoin() {
+ assertEquals("", join());
+ assertEquals("1", join(1));
+ assertEquals("1,2", join(1, 2));
+ assertEquals("4294967295,2147483648", join(-1, Integer.MIN_VALUE));
+
+ assertEquals("123", UnsignedInts.join("", 1, 2, 3));
+ }
+
+ private static String join(int... values) {
+ return UnsignedInts.join(",", values);
+ }
+
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(int[].class, new int[0]);
- tester.testAllPublicStaticMethods(UnsignedInts.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(UnsignedInts.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java b/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java
index 81f1644..1df86cb 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedLongTest.java
@@ -14,10 +14,6 @@
package com.google.common.primitives;
-import java.math.BigInteger;
-
-import junit.framework.TestCase;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableSet;
@@ -25,6 +21,10 @@ import com.google.common.testing.EqualsTester;
import com.google.common.testing.NullPointerTester;
import com.google.common.testing.SerializableTester;
+import junit.framework.TestCase;
+
+import java.math.BigInteger;
+
/**
* Tests for {@code UnsignedLong}.
*
@@ -33,9 +33,11 @@ import com.google.common.testing.SerializableTester;
@GwtCompatible(emulated = true)
public class UnsignedLongTest extends TestCase {
private static final ImmutableSet<Long> TEST_LONGS;
+ private static final ImmutableSet<BigInteger> TEST_BIG_INTEGERS;
static {
ImmutableSet.Builder<Long> testLongsBuilder = ImmutableSet.builder();
+ ImmutableSet.Builder<BigInteger> testBigIntegersBuilder = ImmutableSet.builder();
for (long i = -3; i <= 3; i++) {
testLongsBuilder
.add(i)
@@ -43,14 +45,24 @@ public class UnsignedLongTest extends TestCase {
.add(Long.MIN_VALUE + i)
.add(Integer.MIN_VALUE + i)
.add(Integer.MAX_VALUE + i);
+ BigInteger bigI = BigInteger.valueOf(i);
+ testBigIntegersBuilder
+ .add(bigI)
+ .add(BigInteger.valueOf(Long.MAX_VALUE).add(bigI))
+ .add(BigInteger.valueOf(Long.MIN_VALUE).add(bigI))
+ .add(BigInteger.valueOf(Integer.MAX_VALUE).add(bigI))
+ .add(BigInteger.valueOf(Integer.MIN_VALUE).add(bigI))
+ .add(BigInteger.ONE.shiftLeft(63).add(bigI))
+ .add(BigInteger.ONE.shiftLeft(64).add(bigI));
}
TEST_LONGS = testLongsBuilder.build();
+ TEST_BIG_INTEGERS = testBigIntegersBuilder.build();
}
public void testAsUnsignedAndLongValueAreInverses() {
for (long value : TEST_LONGS) {
assertEquals(
- UnsignedLongs.toString(value), value, UnsignedLong.asUnsigned(value).longValue());
+ UnsignedLongs.toString(value), value, UnsignedLong.fromLongBits(value).longValue());
}
}
@@ -60,13 +72,40 @@ public class UnsignedLongTest extends TestCase {
? BigInteger.valueOf(value)
: BigInteger.valueOf(value).add(BigInteger.ZERO.setBit(64));
assertEquals(UnsignedLongs.toString(value), expected,
- UnsignedLong.asUnsigned(value).bigIntegerValue());
+ UnsignedLong.fromLongBits(value).bigIntegerValue());
+ }
+ }
+
+ public void testValueOfLong() {
+ for (long value : TEST_LONGS) {
+ boolean expectSuccess = value >= 0;
+ try {
+ assertEquals(value, UnsignedLong.valueOf(value).longValue());
+ assertTrue(expectSuccess);
+ } catch (IllegalArgumentException e) {
+ assertFalse(expectSuccess);
+ }
+ }
+ }
+
+ public void testValueOfBigInteger() {
+ BigInteger min = BigInteger.ZERO;
+ BigInteger max = UnsignedLong.MAX_VALUE.bigIntegerValue();
+ for (BigInteger big : TEST_BIG_INTEGERS) {
+ boolean expectSuccess =
+ big.compareTo(min) >= 0 && big.compareTo(max) <= 0;
+ try {
+ assertEquals(big, UnsignedLong.valueOf(big).bigIntegerValue());
+ assertTrue(expectSuccess);
+ } catch (IllegalArgumentException e) {
+ assertFalse(expectSuccess);
+ }
}
}
public void testToString() {
for (long value : TEST_LONGS) {
- UnsignedLong unsignedValue = UnsignedLong.asUnsigned(value);
+ UnsignedLong unsignedValue = UnsignedLong.fromLongBits(value);
assertEquals(unsignedValue.bigIntegerValue().toString(), unsignedValue.toString());
}
}
@@ -75,7 +114,7 @@ public class UnsignedLongTest extends TestCase {
public void testToStringRadix() {
for (int radix = Character.MIN_RADIX; radix <= Character.MAX_RADIX; radix++) {
for (long l : TEST_LONGS) {
- UnsignedLong value = UnsignedLong.asUnsigned(l);
+ UnsignedLong value = UnsignedLong.fromLongBits(l);
assertEquals(value.bigIntegerValue().toString(radix), value.toString(radix));
}
}
@@ -85,7 +124,7 @@ public class UnsignedLongTest extends TestCase {
int[] radices = {2, 3, 5, 7, 10, 12, 16, 21, 31, 36};
for (int radix : radices) {
for (long l : TEST_LONGS) {
- UnsignedLong value = UnsignedLong.asUnsigned(l);
+ UnsignedLong value = UnsignedLong.fromLongBits(l);
assertEquals(value.bigIntegerValue().toString(radix), value.toString(radix));
}
}
@@ -93,110 +132,112 @@ public class UnsignedLongTest extends TestCase {
public void testFloatValue() {
for (long value : TEST_LONGS) {
- UnsignedLong unsignedValue = UnsignedLong.asUnsigned(value);
+ UnsignedLong unsignedValue = UnsignedLong.fromLongBits(value);
assertEquals(unsignedValue.bigIntegerValue().floatValue(), unsignedValue.floatValue());
}
}
public void testDoubleValue() {
for (long value : TEST_LONGS) {
- UnsignedLong unsignedValue = UnsignedLong.asUnsigned(value);
+ UnsignedLong unsignedValue = UnsignedLong.fromLongBits(value);
assertEquals(unsignedValue.bigIntegerValue().doubleValue(), unsignedValue.doubleValue());
}
}
- public void testAdd() {
+ public void testPlus() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
- UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
- UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
+ UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
+ UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
long expected = aUnsigned
.bigIntegerValue()
.add(bUnsigned.bigIntegerValue())
.longValue();
- UnsignedLong unsignedSum = aUnsigned.add(bUnsigned);
+ UnsignedLong unsignedSum = aUnsigned.plus(bUnsigned);
assertEquals(expected, unsignedSum.longValue());
}
}
}
- public void testSubtract() {
+ public void testMinus() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
- UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
- UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
+ UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
+ UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
long expected = aUnsigned
.bigIntegerValue()
.subtract(bUnsigned.bigIntegerValue())
.longValue();
- UnsignedLong unsignedSub = aUnsigned.subtract(bUnsigned);
+ UnsignedLong unsignedSub = aUnsigned.minus(bUnsigned);
assertEquals(expected, unsignedSub.longValue());
}
}
}
- public void testMultiply() {
+ public void testTimes() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
- UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
- UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
+ UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
+ UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
long expected = aUnsigned
.bigIntegerValue()
.multiply(bUnsigned.bigIntegerValue())
.longValue();
- UnsignedLong unsignedMul = aUnsigned.multiply(bUnsigned);
+ UnsignedLong unsignedMul = aUnsigned.times(bUnsigned);
assertEquals(expected, unsignedMul.longValue());
}
}
}
- public void testDivide() {
+ public void testDividedBy() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
if (b != 0) {
- UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
- UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
+ UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
+ UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
long expected = aUnsigned
.bigIntegerValue()
.divide(bUnsigned.bigIntegerValue())
.longValue();
- UnsignedLong unsignedDiv = aUnsigned.divide(bUnsigned);
+ UnsignedLong unsignedDiv = aUnsigned.dividedBy(bUnsigned);
assertEquals(expected, unsignedDiv.longValue());
}
}
}
}
+ @SuppressWarnings("ReturnValueIgnored")
public void testDivideByZeroThrows() {
for (long a : TEST_LONGS) {
try {
- UnsignedLong.asUnsigned(a).divide(UnsignedLong.ZERO);
+ UnsignedLong.fromLongBits(a).dividedBy(UnsignedLong.ZERO);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
}
- public void testRemainder() {
+ public void testMod() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
if (b != 0) {
- UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
- UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
+ UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
+ UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
long expected = aUnsigned
.bigIntegerValue()
.remainder(bUnsigned.bigIntegerValue())
.longValue();
- UnsignedLong unsignedRem = aUnsigned.remainder(bUnsigned);
+ UnsignedLong unsignedRem = aUnsigned.mod(bUnsigned);
assertEquals(expected, unsignedRem.longValue());
}
}
}
}
- public void testRemainderByZero() {
+ @SuppressWarnings("ReturnValueIgnored")
+ public void testModByZero() {
for (long a : TEST_LONGS) {
try {
- UnsignedLong.asUnsigned(a).remainder(UnsignedLong.ZERO);
+ UnsignedLong.fromLongBits(a).mod(UnsignedLong.ZERO);
fail("Expected ArithmeticException");
} catch (ArithmeticException expected) {}
}
@@ -205,8 +246,8 @@ public class UnsignedLongTest extends TestCase {
public void testCompare() {
for (long a : TEST_LONGS) {
for (long b : TEST_LONGS) {
- UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
- UnsignedLong bUnsigned = UnsignedLong.asUnsigned(b);
+ UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
+ UnsignedLong bUnsigned = UnsignedLong.fromLongBits(b);
assertEquals(aUnsigned.bigIntegerValue().compareTo(bUnsigned.bigIntegerValue()),
aUnsigned.compareTo(bUnsigned));
}
@@ -214,12 +255,12 @@ public class UnsignedLongTest extends TestCase {
}
@GwtIncompatible("too slow")
- public void testEqualsAndValueOf() {
+ public void testEquals() {
EqualsTester equalsTester = new EqualsTester();
for (long a : TEST_LONGS) {
BigInteger big =
(a >= 0) ? BigInteger.valueOf(a) : BigInteger.valueOf(a).add(BigInteger.ZERO.setBit(64));
- equalsTester.addEqualityGroup(UnsignedLong.asUnsigned(a), UnsignedLong.valueOf(big),
+ equalsTester.addEqualityGroup(UnsignedLong.fromLongBits(a), UnsignedLong.valueOf(big),
UnsignedLong.valueOf(big.toString()), UnsignedLong.valueOf(big.toString(16), 16));
}
equalsTester.testEquals();
@@ -227,7 +268,7 @@ public class UnsignedLongTest extends TestCase {
public void testIntValue() {
for (long a : TEST_LONGS) {
- UnsignedLong aUnsigned = UnsignedLong.asUnsigned(a);
+ UnsignedLong aUnsigned = UnsignedLong.fromLongBits(a);
int intValue = aUnsigned.bigIntegerValue().intValue();
assertEquals(intValue, aUnsigned.intValue());
}
@@ -236,14 +277,12 @@ public class UnsignedLongTest extends TestCase {
@GwtIncompatible("serialization")
public void testSerialization() {
for (long a : TEST_LONGS) {
- SerializableTester.reserializeAndAssert(UnsignedLong.asUnsigned(a));
+ SerializableTester.reserializeAndAssert(UnsignedLong.fromLongBits(a));
}
}
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(UnsignedLong.class, UnsignedLong.ONE);
- tester.testAllPublicStaticMethods(UnsignedLong.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(UnsignedLong.class);
}
}
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java b/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java
index 5928f7e..7abee87 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedLongsTest.java
@@ -1,11 +1,11 @@
/*
* Copyright (C) 2011 The Guava Authors
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
@@ -16,43 +16,97 @@ package com.google.common.primitives;
import static java.math.BigInteger.ONE;
-import java.math.BigInteger;
-import java.util.Random;
-
-import junit.framework.TestCase;
-
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
+import com.google.common.collect.testing.Helpers;
import com.google.common.testing.NullPointerTester;
+import junit.framework.TestCase;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Random;
+
/**
* Tests for UnsignedLongs
- *
+ *
* @author Brian Milch
* @author Louis Wasserman
*/
@GwtCompatible(emulated = true)
public class UnsignedLongsTest extends TestCase {
-
+ private static final long LEAST = 0L;
+ private static final long GREATEST = 0xffffffffffffffffL;
+
public void testCompare() {
// max value
- assertTrue((UnsignedLongs.compare(0, 0xffffffffffffffffL) < 0));
- assertTrue((UnsignedLongs.compare(0xffffffffffffffffL, 0) > 0));
+ assertTrue(UnsignedLongs.compare(0, 0xffffffffffffffffL) < 0);
+ assertTrue(UnsignedLongs.compare(0xffffffffffffffffL, 0) > 0);
// both with high bit set
- assertTrue((UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xffffffffffffffffL) < 0));
- assertTrue((UnsignedLongs.compare(0xffffffffffffffffL, 0xff1a618b7f65ea12L) > 0));
+ assertTrue(UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xffffffffffffffffL) < 0);
+ assertTrue(UnsignedLongs.compare(0xffffffffffffffffL, 0xff1a618b7f65ea12L) > 0);
// one with high bit set
- assertTrue((UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0xff1a618b7f65ea12L) < 0));
- assertTrue((UnsignedLongs.compare(0xff1a618b7f65ea12L, 0x5a4316b8c153ac4dL) > 0));
+ assertTrue(UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0xff1a618b7f65ea12L) < 0);
+ assertTrue(UnsignedLongs.compare(0xff1a618b7f65ea12L, 0x5a4316b8c153ac4dL) > 0);
// neither with high bit set
- assertTrue((UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0x6cf78a4b139a4e2aL) < 0));
- assertTrue((UnsignedLongs.compare(0x6cf78a4b139a4e2aL, 0x5a4316b8c153ac4dL) > 0));
+ assertTrue(UnsignedLongs.compare(0x5a4316b8c153ac4dL, 0x6cf78a4b139a4e2aL) < 0);
+ assertTrue(UnsignedLongs.compare(0x6cf78a4b139a4e2aL, 0x5a4316b8c153ac4dL) > 0);
// same value
- assertTrue((UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xff1a618b7f65ea12L) == 0));
+ assertTrue(UnsignedLongs.compare(0xff1a618b7f65ea12L, 0xff1a618b7f65ea12L) == 0);
+ }
+
+ public void testMax_noArgs() {
+ try {
+ UnsignedLongs.max();
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testMax() {
+ assertEquals(LEAST, UnsignedLongs.max(LEAST));
+ assertEquals(GREATEST, UnsignedLongs.max(GREATEST));
+ assertEquals(0xff1a618b7f65ea12L, UnsignedLongs.max(
+ 0x5a4316b8c153ac4dL, 8L, 100L,
+ 0L, 0x6cf78a4b139a4e2aL, 0xff1a618b7f65ea12L));
+ }
+
+ public void testMin_noArgs() {
+ try {
+ UnsignedLongs.min();
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testMin() {
+ assertEquals(LEAST, UnsignedLongs.min(LEAST));
+ assertEquals(GREATEST, UnsignedLongs.min(GREATEST));
+ assertEquals(0L, UnsignedLongs.min(
+ 0x5a4316b8c153ac4dL, 8L, 100L,
+ 0L, 0x6cf78a4b139a4e2aL, 0xff1a618b7f65ea12L));
+ }
+
+ public void testLexicographicalComparator() {
+ List<long[]> ordered = Arrays.asList(
+ new long[] {},
+ new long[] {LEAST},
+ new long[] {LEAST, LEAST},
+ new long[] {LEAST, (long) 1},
+ new long[] {(long) 1},
+ new long[] {(long) 1, LEAST},
+ new long[] {GREATEST, GREATEST - (long) 1},
+ new long[] {GREATEST, GREATEST},
+ new long[] {GREATEST, GREATEST, GREATEST});
+
+ Comparator<long[]> comparator = UnsignedLongs.lexicographicalComparator();
+ Helpers.testComparator(comparator, ordered);
}
public void testDivide() {
@@ -84,33 +138,65 @@ public class UnsignedLongsTest extends TestCase {
long dividend = r.nextLong();
long divisor = r.nextLong();
// Test that the Euclidean property is preserved:
- assertTrue(dividend - (divisor * UnsignedLongs.divide(dividend, divisor)
- + UnsignedLongs.remainder(dividend, divisor)) == 0);
+ assertEquals(0,
+ dividend - (divisor * UnsignedLongs.divide(dividend, divisor)
+ + UnsignedLongs.remainder(dividend, divisor)));
}
}
public void testParseLong() {
+ assertEquals(0xffffffffffffffffL, UnsignedLongs.parseUnsignedLong("18446744073709551615"));
+ assertEquals(0x7fffffffffffffffL, UnsignedLongs.parseUnsignedLong("9223372036854775807"));
+ assertEquals(0xff1a618b7f65ea12L, UnsignedLongs.parseUnsignedLong("18382112080831834642"));
+ assertEquals(0x5a4316b8c153ac4dL, UnsignedLongs.parseUnsignedLong("6504067269626408013"));
+ assertEquals(0x6cf78a4b139a4e2aL, UnsignedLongs.parseUnsignedLong("7851896530399809066"));
+
try {
- assertEquals(0xffffffffffffffffL, UnsignedLongs.parseUnsignedLong("18446744073709551615"));
- assertEquals(0x7fffffffffffffffL, UnsignedLongs.parseUnsignedLong("9223372036854775807"));
- assertEquals(0xff1a618b7f65ea12L, UnsignedLongs.parseUnsignedLong("18382112080831834642"));
- assertEquals(0x5a4316b8c153ac4dL, UnsignedLongs.parseUnsignedLong("6504067269626408013"));
- assertEquals(0x6cf78a4b139a4e2aL, UnsignedLongs.parseUnsignedLong("7851896530399809066"));
- } catch (NumberFormatException e) {
- fail(e.getMessage());
+ // One more than maximum value
+ UnsignedLongs.parseUnsignedLong("18446744073709551616");
+ fail();
+ } catch (NumberFormatException expected) {
}
+ }
- boolean overflowCaught = false;
+ public void testDecodeLong() {
+ assertEquals(0xffffffffffffffffL, UnsignedLongs.decode("0xffffffffffffffff"));
+ assertEquals(01234567, UnsignedLongs.decode("01234567")); // octal
+ assertEquals(0x1234567890abcdefL, UnsignedLongs.decode("#1234567890abcdef"));
+ assertEquals(987654321012345678L, UnsignedLongs.decode("987654321012345678"));
+ assertEquals(0x135791357913579L, UnsignedLongs.decode("0x135791357913579"));
+ assertEquals(0x135791357913579L, UnsignedLongs.decode("0X135791357913579"));
+ assertEquals(0L, UnsignedLongs.decode("0"));
+ }
+
+ public void testDecodeLongFails() {
try {
// One more than maximum value
- UnsignedLongs.parseUnsignedLong("18446744073709551616");
- } catch (NumberFormatException e) {
- overflowCaught = true;
+ UnsignedLongs.decode("0xfffffffffffffffff");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+
+ try {
+ UnsignedLongs.decode("-5");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+
+ try {
+ UnsignedLongs.decode("-0x5");
+ fail();
+ } catch (NumberFormatException expected) {
+ }
+
+ try {
+ UnsignedLongs.decode("-05");
+ fail();
+ } catch (NumberFormatException expected) {
}
- assertTrue(overflowCaught);
}
- public void testParseLongWithRadix() throws NumberFormatException {
+ public void testParseLongWithRadix() {
assertEquals(0xffffffffffffffffL, UnsignedLongs.parseUnsignedLong("ffffffffffffffff", 16));
assertEquals(0x1234567890abcdefL, UnsignedLongs.parseUnsignedLong("1234567890abcdef", 16));
@@ -127,35 +213,36 @@ public class UnsignedLongsTest extends TestCase {
String overflowAsString = overflow.toString(radix);
UnsignedLongs.parseUnsignedLong(overflowAsString, radix);
fail();
- } catch (NumberFormatException nfe) {
- // expected
+ } catch (NumberFormatException expected) {
}
}
+
+ try {
+ UnsignedLongs.parseUnsignedLong("1234567890abcdef1", 16);
+ fail();
+ } catch (NumberFormatException expected) {
+ }
}
public void testParseLongThrowsExceptionForInvalidRadix() {
- // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX,
- // inclusive.
+ // Valid radix values are Character.MIN_RADIX to Character.MAX_RADIX, inclusive.
try {
UnsignedLongs.parseUnsignedLong("0", Character.MIN_RADIX - 1);
fail();
- } catch (NumberFormatException nfe) {
- // expected
+ } catch (NumberFormatException expected) {
}
try {
UnsignedLongs.parseUnsignedLong("0", Character.MAX_RADIX + 1);
fail();
- } catch (NumberFormatException nfe) {
- // expected
+ } catch (NumberFormatException expected) {
}
// The radix is used as an array index, so try a negative value.
try {
UnsignedLongs.parseUnsignedLong("0", -1);
fail();
- } catch (NumberFormatException nfe) {
- // expected
+ } catch (NumberFormatException expected) {
}
}
@@ -165,8 +252,9 @@ public class UnsignedLongsTest extends TestCase {
"7fffffffffffffff",
"ff1a618b7f65ea12",
"5a4316b8c153ac4d",
- "6cf78a4b139a4e2a"};
- int[] bases = {2, 5, 7, 8, 10, 16};
+ "6cf78a4b139a4e2a"
+ };
+ int[] bases = { 2, 5, 7, 8, 10, 16 };
for (int base : bases) {
for (String x : tests) {
BigInteger xValue = new BigInteger(x, 16);
@@ -176,11 +264,19 @@ public class UnsignedLongsTest extends TestCase {
}
}
+ public void testJoin() {
+ assertEquals("", UnsignedLongs.join(","));
+ assertEquals("1", UnsignedLongs.join(",", 1));
+ assertEquals("1,2", UnsignedLongs.join(",", 1, 2));
+ assertEquals("18446744073709551615,9223372036854775808",
+ UnsignedLongs.join(",", -1, Long.MIN_VALUE));
+ assertEquals("123", UnsignedLongs.join("", 1, 2, 3));
+ assertEquals("184467440737095516159223372036854775808",
+ UnsignedLongs.join("", -1, Long.MIN_VALUE));
+ }
+
@GwtIncompatible("NullPointerTester")
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(long[].class, new long[0]);
- tester.setDefault(BigInteger.class, BigInteger.ZERO);
- tester.testAllPublicStaticMethods(UnsignedLongs.class);
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(UnsignedLongs.class);
}
}
diff --git a/guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java b/guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java
new file mode 100644
index 0000000..5c3f5fd
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/AbstractInvocationHandlerTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.testing.EqualsTester;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.List;
+
+/**
+ * Tests for {@link AbstractInvocationHandler}.
+ *
+ * @author Ben Yu
+ */
+public class AbstractInvocationHandlerTest extends TestCase {
+
+ private static final ImmutableList<String> LIST1 = ImmutableList.of("one", "two");
+ private static final ImmutableList<String> LIST2 = ImmutableList.of("three");
+
+ public void testDelegate() {
+ assertEquals(LIST1, ImmutableList.copyOf(newDelegatingList(LIST1)));
+ assertEquals(LIST1, ImmutableList.copyOf(newDelegatingListWithEquals(LIST1)));
+ }
+
+ public void testToString() {
+ List<String> proxy = newDelegatingList(LIST1);
+ assertEquals(Proxy.getInvocationHandler(proxy).toString(), proxy.toString());
+ }
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(newDelegatingList(LIST1))
+ // Actually, this violates List#equals contract.
+ // But whatever, no one is going to proxy List (hopefully).
+ .addEqualityGroup(newDelegatingList(LIST1))
+ .addEqualityGroup(newDelegatingList(LIST2))
+ .addEqualityGroup(newDelegatingListWithEquals(LIST1), newDelegatingListWithEquals(LIST1))
+ .addEqualityGroup(
+ newDelegatingListWithEquals(LIST2),
+ newProxyWithSubHandler1(LIST2), // Makes sure type of handler doesn't affect equality
+ newProxyWithSubHandler2(LIST2))
+ .addEqualityGroup(newDelegatingIterableWithEquals(LIST2)) // different interface
+ .testEquals();
+ }
+
+ @SuppressWarnings("unchecked") // proxy of List<String>
+ private static List<String> newDelegatingList(List<String> delegate) {
+ return Reflection.newProxy(List.class, new DelegatingInvocationHandler(delegate));
+ }
+
+ @SuppressWarnings("unchecked") // proxy of List<String>
+ private static List<String> newDelegatingListWithEquals(List<String> delegate) {
+ return Reflection.newProxy(List.class, new DelegatingInvocationHandlerWithEquals(delegate));
+ }
+
+ @SuppressWarnings("unchecked") // proxy of Iterable<String>
+ private static Iterable<String> newDelegatingIterableWithEquals(Iterable<String> delegate) {
+ return Reflection.newProxy(Iterable.class, new DelegatingInvocationHandlerWithEquals(delegate));
+ }
+
+ @SuppressWarnings("unchecked") // proxy of List<String>
+ private static List<String> newProxyWithSubHandler1(List<String> delegate) {
+ return Reflection.newProxy(List.class, new SubHandler1(delegate));
+ }
+
+ @SuppressWarnings("unchecked") // proxy of List<String>
+ private static List<String> newProxyWithSubHandler2(List<String> delegate) {
+ return Reflection.newProxy(List.class, new SubHandler2(delegate));
+ }
+
+ private static class DelegatingInvocationHandler extends AbstractInvocationHandler {
+ final Object delegate;
+
+ DelegatingInvocationHandler(Object delegate) {
+ this.delegate = checkNotNull(delegate);
+ }
+
+ @Override protected Object handleInvocation(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ return method.invoke(delegate, args);
+ }
+
+ @Override public String toString() {
+ return "some arbitrary string";
+ }
+ }
+
+ private static class DelegatingInvocationHandlerWithEquals extends DelegatingInvocationHandler {
+
+ DelegatingInvocationHandlerWithEquals(Object delegate) {
+ super(delegate);
+ }
+
+ @Override public boolean equals(Object obj) {
+ if (obj instanceof DelegatingInvocationHandlerWithEquals) {
+ DelegatingInvocationHandlerWithEquals that = (DelegatingInvocationHandlerWithEquals) obj;
+ return delegate.equals(that.delegate);
+ } else {
+ return false;
+ }
+ }
+
+ @Override public int hashCode() {
+ return delegate.hashCode();
+ }
+ }
+
+ private static class SubHandler1 extends DelegatingInvocationHandlerWithEquals {
+ SubHandler1(Object delegate) {
+ super(delegate);
+ }
+ }
+
+ private static class SubHandler2 extends DelegatingInvocationHandlerWithEquals {
+ SubHandler2(Object delegate) {
+ super(delegate);
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/ClassPathTest.java b/guava-tests/test/com/google/common/reflect/ClassPathTest.java
new file mode 100644
index 0000000..b1bf897
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/ClassPathTest.java
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.reflect.ClassPath.ClassInfo;
+import com.google.common.reflect.ClassPath.ResourceInfo;
+import com.google.common.reflect.subpackage.ClassInSubPackage;
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestCase;
+
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Manifest;
+
+/**
+ * Functional tests of {@link ClassPath}.
+ */
+public class ClassPathTest extends TestCase {
+
+ public void testGetResources() throws Exception {
+ Map<String, ResourceInfo> byName = Maps.newHashMap();
+ Map<String, ResourceInfo> byToString = Maps.newHashMap();
+ ClassPath classpath = ClassPath.from(getClass().getClassLoader());
+ for (ResourceInfo resource : classpath.getResources()) {
+ byName.put(resource.getResourceName(), resource);
+ byToString.put(resource.toString(), resource);
+ assertNotNull(resource.url());
+ }
+ String testResourceName = "com/google/common/reflect/test.txt";
+ ASSERT.that(byName.keySet()).has().allOf(
+ "com/google/common/reflect/ClassPath.class",
+ "com/google/common/reflect/ClassPathTest.class",
+ "com/google/common/reflect/ClassPathTest$Nested.class",
+ testResourceName);
+ assertFalse(byName.keySet().contains("META-INF/MANIFEST.MF"));
+ ASSERT.that(byToString.keySet()).has().allOf(
+ "com.google.common.reflect.ClassPath",
+ "com.google.common.reflect.ClassPathTest",
+ "com/google/common/reflect/ClassPathTest$Nested.class",
+ testResourceName);
+ assertFalse(byToString.keySet().contains("META-INF/MANIFEST.MF"));
+ assertEquals(getClass().getClassLoader().getResource(testResourceName),
+ byName.get("com/google/common/reflect/test.txt").url());
+ }
+
+ public void testGetClasses() throws Exception {
+ Set<String> names = Sets.newHashSet();
+ Set<String> strings = Sets.newHashSet();
+ Set<Class<?>> classes = Sets.newHashSet();
+ Set<String> packageNames = Sets.newHashSet();
+ Set<String> simpleNames = Sets.newHashSet();
+ ClassPath classpath = ClassPath.from(getClass().getClassLoader());
+ for (ClassInfo classInfo
+ : classpath.getTopLevelClasses(ClassPathTest.class.getPackage().getName())) {
+ names.add(classInfo.getName());
+ strings.add(classInfo.toString());
+ classes.add(classInfo.load());
+ packageNames.add(classInfo.getPackageName());
+ simpleNames.add(classInfo.getSimpleName());
+ }
+ ASSERT.that(names).has().allOf(ClassPath.class.getName(), ClassPathTest.class.getName());
+ ASSERT.that(strings).has().allOf(ClassPath.class.getName(), ClassPathTest.class.getName());
+ ASSERT.that(classes).has().allOf(ClassPath.class, ClassPathTest.class);
+ ASSERT.that(packageNames).has().item(ClassPath.class.getPackage().getName());
+ ASSERT.that(simpleNames).has().allOf("ClassPath", "ClassPathTest");
+ assertFalse(classes.contains(ClassInSubPackage.class));
+ }
+
+ public void testGetClassesRecursive() throws Exception {
+ Set<Class<?>> classes = Sets.newHashSet();
+ ClassPath classpath = ClassPath.from(ClassPathTest.class.getClassLoader());
+ for (ClassInfo classInfo
+ : classpath.getTopLevelClassesRecursive(ClassPathTest.class.getPackage().getName())) {
+ classes.add(classInfo.load());
+ }
+ ASSERT.that(classes).has().allOf(ClassPathTest.class, ClassInSubPackage.class);
+ }
+
+ public void testGetClasses_diamond() throws Exception {
+ ClassLoader parent = ClassPathTest.class.getClassLoader();
+ ClassLoader sub1 = new ClassLoader(parent) {};
+ ClassLoader sub2 = new ClassLoader(parent) {};
+ assertEquals(findClass(ClassPath.from(sub1).getTopLevelClasses(), ClassPathTest.class),
+ findClass(ClassPath.from(sub2).getTopLevelClasses(), ClassPathTest.class));
+ }
+
+ public void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(classInfo(ClassPathTest.class), classInfo(ClassPathTest.class))
+ .addEqualityGroup(classInfo(Test.class), classInfo(Test.class, getClass().getClassLoader()))
+ .addEqualityGroup(
+ new ResourceInfo("a/b/c.txt", getClass().getClassLoader()),
+ new ResourceInfo("a/b/c.txt", getClass().getClassLoader()))
+ .addEqualityGroup(
+ new ResourceInfo("x.txt", getClass().getClassLoader()))
+ .testEquals();
+ }
+
+ public void testClassPathEntries_emptyURLClassLoader_noParent() {
+ ASSERT.that(ClassPath.getClassPathEntries(new URLClassLoader(new URL[0], null)).keySet())
+ .isEmpty();
+ }
+
+ public void testClassPathEntries_URLClassLoader_noParent() throws Exception {
+ URL url1 = new URL("file:/a");
+ URL url2 = new URL("file:/b");
+ URLClassLoader classloader = new URLClassLoader(new URL[] {url1, url2}, null);
+ assertEquals(
+ ImmutableMap.of(url1.toURI(), classloader, url2.toURI(), classloader),
+ ClassPath.getClassPathEntries(classloader));
+ }
+
+ public void testClassPathEntries_URLClassLoader_withParent() throws Exception {
+ URL url1 = new URL("file:/a");
+ URL url2 = new URL("file:/b");
+ URLClassLoader parent = new URLClassLoader(new URL[] {url1}, null);
+ URLClassLoader child = new URLClassLoader(new URL[] {url2}, parent) {};
+ ImmutableMap<URI, ClassLoader> classPathEntries = ClassPath.getClassPathEntries(child);
+ assertEquals(ImmutableMap.of(url1.toURI(), parent, url2.toURI(), child), classPathEntries);
+ ASSERT.that(classPathEntries.keySet()).has().allOf(url1.toURI(), url2.toURI()).inOrder();
+ }
+
+ public void testClassPathEntries_duplicateUri_parentWins() throws Exception {
+ URL url = new URL("file:/a");
+ URLClassLoader parent = new URLClassLoader(new URL[] {url}, null);
+ URLClassLoader child = new URLClassLoader(new URL[] {url}, parent) {};
+ assertEquals(ImmutableMap.of(url.toURI(), parent), ClassPath.getClassPathEntries(child));
+ }
+
+ public void testClassPathEntries_notURLClassLoader_noParent() {
+ ASSERT.that(ClassPath.getClassPathEntries(new ClassLoader(null) {}).keySet()).isEmpty();
+ }
+
+ public void testClassPathEntries_notURLClassLoader_withParent() throws Exception {
+ URL url = new URL("file:/a");
+ URLClassLoader parent = new URLClassLoader(new URL[] {url}, null);
+ assertEquals(
+ ImmutableMap.of(url.toURI(), parent),
+ ClassPath.getClassPathEntries(new ClassLoader(parent) {}));
+ }
+
+ public void testClassPathEntries_notURLClassLoader_withParentAndGrandParent() throws Exception {
+ URL url1 = new URL("file:/a");
+ URL url2 = new URL("file:/b");
+ URLClassLoader grandParent = new URLClassLoader(new URL[] {url1}, null);
+ URLClassLoader parent = new URLClassLoader(new URL[] {url2}, grandParent);
+ assertEquals(
+ ImmutableMap.of(url1.toURI(), grandParent, url2.toURI(), parent),
+ ClassPath.getClassPathEntries(new ClassLoader(parent) {}));
+ }
+
+ public void testClassPathEntries_notURLClassLoader_withGrandParent() throws Exception {
+ URL url = new URL("file:/a");
+ URLClassLoader grandParent = new URLClassLoader(new URL[] {url}, null);
+ ClassLoader parent = new ClassLoader(grandParent) {};
+ assertEquals(
+ ImmutableMap.of(url.toURI(), grandParent),
+ ClassPath.getClassPathEntries(new ClassLoader(parent) {}));
+ }
+
+ public void testBrowseFromFile_fileNotExists() throws IOException {
+ ClassLoader classLoader = ClassPathTest.class.getClassLoader();
+ ImmutableSet.Builder<ResourceInfo> resources = ImmutableSet.builder();
+ ClassPath.browseFrom(new File("no/such/file/anywhere"), classLoader, resources);
+ ASSERT.that(resources.build()).isEmpty();
+ }
+
+ public void testBrowseFromFile_notJarFile() throws IOException {
+ ClassLoader classLoader = ClassPathTest.class.getClassLoader();
+ ImmutableSet.Builder<ResourceInfo> resources = ImmutableSet.builder();
+ File notJar = File.createTempFile("not_a_jar", "txt");
+ try {
+ ClassPath.browseFrom(notJar, classLoader, resources);
+ } finally {
+ notJar.delete();
+ }
+ ASSERT.that(resources.build()).isEmpty();
+ }
+
+ public void testGetClassPathEntry() throws URISyntaxException {
+ assertEquals(URI.create("file:/usr/test/dep.jar"),
+ ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "file:/usr/test/dep.jar"));
+ assertEquals(URI.create("file:/home/build/a.jar"),
+ ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "a.jar"));
+ assertEquals(URI.create("file:/home/build/x/y/z"),
+ ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z"));
+ assertEquals(URI.create("file:/home/build/x/y/z.jar"),
+ ClassPath.getClassPathEntry(new File("/home/build/outer.jar"), "x/y/z.jar"));
+ }
+
+ public void testGetClassPathFromManifest_nullManifest() {
+ ASSERT.that(ClassPath.getClassPathFromManifest(new File("some.jar"), null)).isEmpty();
+ }
+
+ public void testGetClassPathFromManifest_noClassPath() throws IOException {
+ File jarFile = new File("base.jar");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest("")))
+ .isEmpty();
+ }
+
+ public void testGetClassPathFromManifest_emptyClassPath() throws IOException {
+ File jarFile = new File("base.jar");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifestClasspath("")))
+ .isEmpty();
+ }
+
+ public void testGetClassPathFromManifest_badClassPath() throws IOException {
+ File jarFile = new File("base.jar");
+ Manifest manifest = manifestClasspath("an_invalid^path");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
+ .isEmpty();
+ }
+
+ public void testGetClassPathFromManifest_relativeDirectory() throws IOException {
+ File jarFile = new File("base/some.jar");
+ // with/relative/directory is the Class-Path value in the mf file.
+ Manifest manifest = manifestClasspath("with/relative/dir");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
+ .has().allOf(new File("base/with/relative/dir").toURI()).inOrder();
+ }
+
+ public void testGetClassPathFromManifest_relativeJar() throws IOException {
+ File jarFile = new File("base/some.jar");
+ // with/relative/directory is the Class-Path value in the mf file.
+ Manifest manifest = manifestClasspath("with/relative.jar");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
+ .has().allOf(new File("base/with/relative.jar").toURI()).inOrder();
+ }
+
+ public void testGetClassPathFromManifest_jarInCurrentDirectory() throws IOException {
+ File jarFile = new File("base/some.jar");
+ // with/relative/directory is the Class-Path value in the mf file.
+ Manifest manifest = manifestClasspath("current.jar");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
+ .has().allOf(new File("base/current.jar").toURI()).inOrder();
+ }
+
+ public void testGetClassPathFromManifest_absoluteDirectory() throws IOException {
+ File jarFile = new File("base/some.jar");
+ Manifest manifest = manifestClasspath("file:/with/absolute/dir");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
+ .has().allOf(new File("/with/absolute/dir").toURI()).inOrder();
+ }
+
+ public void testGetClassPathFromManifest_absoluteJar() throws IOException {
+ File jarFile = new File("base/some.jar");
+ Manifest manifest = manifestClasspath("file:/with/absolute.jar");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
+ .has().allOf(new File("/with/absolute.jar").toURI()).inOrder();
+ }
+
+ public void testGetClassPathFromManifest_multiplePaths() throws IOException {
+ File jarFile = new File("base/some.jar");
+ Manifest manifest = manifestClasspath("file:/with/absolute.jar relative.jar relative/dir");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
+ .has().allOf(
+ new File("/with/absolute.jar").toURI(),
+ new File("base/relative.jar").toURI(),
+ new File("base/relative/dir").toURI())
+ .inOrder();
+ }
+
+ public void testGetClassPathFromManifest_leadingBlanks() throws IOException {
+ File jarFile = new File("base/some.jar");
+ Manifest manifest = manifestClasspath(" relative.jar");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
+ .has().allOf(new File("base/relative.jar").toURI()).inOrder();
+ }
+
+ public void testGetClassPathFromManifest_trailingBlanks() throws IOException {
+ File jarFile = new File("base/some.jar");
+ Manifest manifest = manifestClasspath("relative.jar ");
+ ASSERT.that(ClassPath.getClassPathFromManifest(jarFile, manifest))
+ .has().allOf(new File("base/relative.jar").toURI()).inOrder();
+ }
+
+ public void testGetClassName() {
+ assertEquals("abc.d.Abc", ClassPath.getClassName("abc/d/Abc.class"));
+ }
+
+ public void testResourceInfo_of() {
+ assertEquals(ClassInfo.class, resourceInfo(ClassPathTest.class).getClass());
+ assertEquals(ClassInfo.class, resourceInfo(ClassPath.class).getClass());
+ assertEquals(ResourceInfo.class, resourceInfo(Nested.class).getClass());
+ }
+
+ public void testGetSimpleName() {
+ assertEquals("Foo",
+ new ClassInfo("Foo.class", getClass().getClassLoader()).getSimpleName());
+ assertEquals("Foo",
+ new ClassInfo("a/b/Foo.class", getClass().getClassLoader()).getSimpleName());
+ }
+
+ public void testGetPackageName() {
+ assertEquals("",
+ new ClassInfo("Foo.class", getClass().getClassLoader()).getPackageName());
+ assertEquals("a.b",
+ new ClassInfo("a/b/Foo.class", getClass().getClassLoader()).getPackageName());
+ }
+
+ private static class Nested {}
+
+ public void testNulls() throws IOException {
+ new NullPointerTester().testAllPublicStaticMethods(ClassPath.class);
+ new NullPointerTester()
+ .testAllPublicInstanceMethods(ClassPath.from(getClass().getClassLoader()));
+ }
+
+ private static ClassPath.ClassInfo findClass(
+ Iterable<ClassPath.ClassInfo> classes, Class<?> cls) {
+ for (ClassPath.ClassInfo classInfo : classes) {
+ if (classInfo.getName().equals(cls.getName())) {
+ return classInfo;
+ }
+ }
+ throw new AssertionError("failed to find " + cls);
+ }
+
+ private static ResourceInfo resourceInfo(Class<?> cls) {
+ return ResourceInfo.of(cls.getName().replace('.', '/') + ".class", cls.getClassLoader());
+ }
+
+ private static ClassInfo classInfo(Class<?> cls) {
+ return classInfo(cls, cls.getClassLoader());
+ }
+
+ private static ClassInfo classInfo(Class<?> cls, ClassLoader classLoader) {
+ return new ClassInfo(cls.getName().replace('.', '/') + ".class", classLoader);
+ }
+
+ private static Manifest manifestClasspath(String classpath) throws IOException {
+ return manifest("Class-Path: " + classpath + "\n");
+ }
+
+ private static Manifest manifest(String content) throws IOException {
+ InputStream in = new ByteArrayInputStream(content.getBytes(Charsets.US_ASCII));
+ Manifest manifest = new Manifest();
+ manifest.read(in);
+ return manifest;
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/ElementTest.java b/guava-tests/test/com/google/common/reflect/ElementTest.java
new file mode 100644
index 0000000..a34693a
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/ElementTest.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestCase;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Constructor;
+
+/**
+ * Unit tests of {@link Element}.
+ *
+ * @author Ben Yu
+ */
+public class ElementTest extends TestCase {
+
+ public void testPrivateField() throws Exception {
+ Element element = A.field("privateField");
+ assertTrue(element.isPrivate());
+ assertFalse(element.isAbstract());
+ assertFalse(element.isPackagePrivate());
+ assertFalse(element.isProtected());
+ assertFalse(element.isPublic());
+ assertFalse(element.isFinal());
+ assertFalse(element.isStatic());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testPackagePrivateField() throws Exception {
+ Element element = A.field("packagePrivateField");
+ assertFalse(element.isPrivate());
+ assertTrue(element.isPackagePrivate());
+ assertFalse(element.isProtected());
+ assertFalse(element.isPublic());
+ assertFalse(element.isFinal());
+ assertFalse(element.isStatic());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testProtectedField() throws Exception {
+ Element element = A.field("protectedField");
+ assertFalse(element.isPrivate());
+ assertFalse(element.isPackagePrivate());
+ assertTrue(element.isProtected());
+ assertFalse(element.isPublic());
+ assertFalse(element.isFinal());
+ assertFalse(element.isStatic());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testPublicField() throws Exception {
+ Element element = A.field("publicField");
+ assertFalse(element.isPrivate());
+ assertFalse(element.isPackagePrivate());
+ assertFalse(element.isProtected());
+ assertTrue(element.isPublic());
+ assertFalse(element.isFinal());
+ assertFalse(element.isStatic());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testFinalField() throws Exception {
+ Element element = A.field("finalField");
+ assertTrue(element.isFinal());
+ assertFalse(element.isStatic());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testStaticField() throws Exception {
+ Element element = A.field("staticField");
+ assertTrue(element.isStatic());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testVolatileField() throws Exception {
+ Element element = A.field("volatileField");
+ assertTrue(element.isVolatile());
+ }
+
+ public void testTransientField() throws Exception {
+ Element element = A.field("transientField");
+ assertTrue(element.isTransient());
+ }
+
+ public void testConstructor() throws Exception {
+ Element element = A.constructor();
+ assertTrue(element.isPublic());
+ assertFalse(element.isPackagePrivate());
+ assertFalse(element.isAbstract());
+ assertFalse(element.isStatic());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testAbstractMethod() throws Exception {
+ Element element = A.method("abstractMethod");
+ assertTrue(element.isPackagePrivate());
+ assertTrue(element.isAbstract());
+ assertFalse(element.isFinal());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testOverridableMethod() throws Exception {
+ Element element = A.method("overridableMethod");
+ assertTrue(element.isPackagePrivate());
+ assertFalse(element.isAbstract());
+ assertFalse(element.isFinal());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testPrivateMethod() throws Exception {
+ Element element = A.method("privateMethod");
+ assertFalse(element.isAbstract());
+ assertTrue(element.isPrivate());
+ assertFalse(element.isPackagePrivate());
+ assertFalse(element.isPublic());
+ assertFalse(element.isProtected());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testProtectedMethod() throws Exception {
+ Element element = A.method("protectedMethod");
+ assertFalse(element.isAbstract());
+ assertFalse(element.isPrivate());
+ assertFalse(element.isPackagePrivate());
+ assertFalse(element.isFinal());
+ assertFalse(element.isPublic());
+ assertTrue(element.isProtected());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testFinalMethod() throws Exception {
+ Element element = A.method("publicFinalMethod");
+ assertFalse(element.isAbstract());
+ assertFalse(element.isPrivate());
+ assertTrue(element.isFinal());
+ assertTrue(element.isPublic());
+ assertTrue(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testNativeMethod() throws Exception {
+ Element element = A.method("nativeMethod");
+ assertTrue(element.isNative());
+ assertTrue(element.isPackagePrivate());
+ }
+
+ public void testSynchronizedMethod() throws Exception {
+ Element element = A.method("synchronizedMethod");
+ assertTrue(element.isSynchronized());
+ }
+
+ public void testUnannotatedMethod() throws Exception {
+ Element element = A.method("notAnnotatedMethod");
+ assertFalse(element.isAnnotationPresent(Tested.class));
+ }
+
+ public void testEquals() throws Exception {
+ new EqualsTester()
+ .addEqualityGroup(A.field("privateField"), A.field("privateField"))
+ .addEqualityGroup(A.field("publicField"))
+ .addEqualityGroup(A.constructor(), A.constructor())
+ .addEqualityGroup(A.method("privateMethod"), A.method("privateMethod"))
+ .addEqualityGroup(A.method("publicFinalMethod"))
+ .testEquals();
+ }
+
+ public void testNulls() {
+ new NullPointerTester()
+ .testAllPublicStaticMethods(Element.class);
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ private @interface Tested {}
+
+ private static abstract class A {
+ @Tested private boolean privateField;
+ @Tested int packagePrivateField;
+ @Tested protected int protectedField;
+ @Tested public String publicField;
+ @Tested private static Iterable<String> staticField;
+ @Tested private final Object finalField;
+ private volatile char volatileField;
+ private transient long transientField;
+
+ @Tested public A(Object finalField) {
+ this.finalField = finalField;
+ }
+
+ @Tested abstract void abstractMethod();
+
+ @Tested void overridableMethod() {}
+
+ @Tested protected void protectedMethod() {}
+
+ @Tested private void privateMethod() {}
+
+ @Tested public final void publicFinalMethod() {}
+
+ void notAnnotatedMethod() {}
+
+ static Element field(String name) throws Exception {
+ Element element = new Element(A.class.getDeclaredField(name));
+ assertEquals(name, element.getName());
+ assertEquals(A.class, element.getDeclaringClass());
+ return element;
+ }
+
+ static Element constructor() throws Exception {
+ Constructor<?> constructor = A.class.getDeclaredConstructor(Object.class);
+ Element element = new Element(constructor);
+ assertEquals(constructor.getName(), element.getName());
+ assertEquals(A.class, element.getDeclaringClass());
+ return element;
+ }
+
+ static Element method(String name, Class<?>... parameterTypes) throws Exception {
+ Element element = new Element(A.class.getDeclaredMethod(name, parameterTypes));
+ assertEquals(name, element.getName());
+ assertEquals(A.class, element.getDeclaringClass());
+ return element;
+ }
+
+ native void nativeMethod();
+
+ synchronized void synchronizedMethod() {}
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java b/guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java
new file mode 100644
index 0000000..7422fba
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/ImmutableTypeToInstanceMapTest.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+import com.google.common.collect.testing.MapTestSuiteBuilder;
+import com.google.common.collect.testing.SampleElements;
+import com.google.common.collect.testing.TestMapGenerator;
+import com.google.common.collect.testing.features.CollectionFeature;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Unit test for {@link ImmutableTypeToInstanceMap}.
+ *
+ * @author Ben Yu
+ */
+public class ImmutableTypeToInstanceMapTest extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(ImmutableTypeToInstanceMapTest.class);
+
+ suite.addTest(MapTestSuiteBuilder
+ .using(new TestTypeToInstanceMapGenerator() {
+ // Other tests will verify what real, warning-free usage looks like
+ // but here we have to do some serious fudging
+ @Override
+ @SuppressWarnings("unchecked")
+ public Map<TypeToken, Object> create(Object... elements) {
+ ImmutableTypeToInstanceMap.Builder<Object> builder
+ = ImmutableTypeToInstanceMap.builder();
+ for (Object object : elements) {
+ Entry<TypeToken, Object> entry = (Entry<TypeToken, Object>) object;
+ builder.put(entry.getKey(), entry.getValue());
+ }
+ return (Map) builder.build();
+ }
+ })
+ .named("ImmutableTypeToInstanceMap")
+ .withFeatures(
+ MapFeature.REJECTS_DUPLICATES_AT_CREATION,
+ MapFeature.RESTRICTS_KEYS,
+ CollectionFeature.KNOWN_ORDER,
+ CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_QUERIES)
+ .createTestSuite());
+
+ return suite;
+ }
+
+ public void testEmpty() {
+ assertEquals(0, ImmutableTypeToInstanceMap.of().size());
+ }
+
+ public void testPrimitiveAndWrapper() {
+ ImmutableTypeToInstanceMap<Number> map = ImmutableTypeToInstanceMap.<Number>builder()
+ .put(Integer.class, 0)
+ .put(int.class, 1)
+ .build();
+ assertEquals(2, map.size());
+
+ assertEquals(0, (int) map.getInstance(Integer.class));
+ assertEquals(0, (int) map.getInstance(TypeToken.of(Integer.class)));
+ assertEquals(1, (int) map.getInstance(int.class));
+ assertEquals(1, (int) map.getInstance(TypeToken.of(int.class)));
+ }
+
+ public void testParameterizedType() {
+ TypeToken<ImmutableList<Integer>> type = new TypeToken<ImmutableList<Integer>>() {};
+ ImmutableTypeToInstanceMap<Iterable<?>> map = ImmutableTypeToInstanceMap.<Iterable<?>>builder()
+ .put(type, ImmutableList.of(1))
+ .build();
+ assertEquals(1, map.size());
+ assertEquals(ImmutableList.of(1), map.getInstance(type));
+ }
+
+ public void testGeneriArrayType() {
+ @SuppressWarnings("unchecked") // Trying to test generic array
+ ImmutableList<Integer>[] array = new ImmutableList[] {ImmutableList.of(1)};
+ TypeToken<ImmutableList<Integer>[]> type = new TypeToken<ImmutableList<Integer>[]>() {};
+ ImmutableTypeToInstanceMap<Iterable<?>[]> map =
+ ImmutableTypeToInstanceMap.<Iterable<?>[]>builder()
+ .put(type, array)
+ .build();
+ assertEquals(1, map.size());
+ ASSERT.that(map.getInstance(type)).has().allOf(array[0]).inOrder();
+ }
+
+ public void testWildcardType() {
+ TypeToken<ImmutableList<?>> type = new TypeToken<ImmutableList<?>>() {};
+ ImmutableTypeToInstanceMap<Iterable<?>> map = ImmutableTypeToInstanceMap.<Iterable<?>>builder()
+ .put(type, ImmutableList.of(1))
+ .build();
+ assertEquals(1, map.size());
+ assertEquals(ImmutableList.of(1), map.getInstance(type));
+ }
+
+ public void testGetInstance_containsTypeVariable() {
+ ImmutableTypeToInstanceMap<Iterable<Number>> map = ImmutableTypeToInstanceMap.of();
+ try {
+ map.getInstance(this.<Number>anyIterableType());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testPut_containsTypeVariable() {
+ ImmutableTypeToInstanceMap.Builder<Iterable<Integer>> builder =
+ ImmutableTypeToInstanceMap.builder();
+ try {
+ builder.put(this.<Integer>anyIterableType(), ImmutableList.of(1));
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ private <T> TypeToken<Iterable<T>> anyIterableType() {
+ return new TypeToken<Iterable<T>>() {};
+ }
+
+ abstract static class TestTypeToInstanceMapGenerator
+ implements TestMapGenerator<TypeToken, Object> {
+
+ @Override public TypeToken[] createKeyArray(int length) {
+ return new TypeToken[length];
+ }
+
+ @Override public Object[] createValueArray(int length) {
+ return new Object[length];
+ }
+
+ @Override
+ public SampleElements<Entry<TypeToken, Object>> samples() {
+ Entry<TypeToken, Object> entry1 =
+ Maps.immutableEntry((TypeToken) TypeToken.of(Integer.class), (Object) 0);
+ Entry<TypeToken, Object> entry2 =
+ Maps.immutableEntry((TypeToken) TypeToken.of(Number.class), (Object) 1);
+ Entry<TypeToken, Object> entry3 =
+ Maps.immutableEntry((TypeToken) new TypeToken<ImmutableList<Integer>>() {},
+ (Object) ImmutableList.of(2));
+ Entry<TypeToken, Object> entry4 =
+ Maps.immutableEntry((TypeToken) new TypeToken<int[]>() {}, (Object) new int[] {3});
+ Entry<TypeToken, Object> entry5 =
+ Maps.immutableEntry((TypeToken) new TypeToken<Iterable<?>>() {},
+ (Object) ImmutableList.of("4"));
+ return new SampleElements<Entry<TypeToken, Object>>(
+ entry1, entry2, entry3, entry4, entry5
+ );
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Entry<TypeToken, Object>[] createArray(int length) {
+ return new Entry[length];
+ }
+
+ @Override
+ public Iterable<Entry<TypeToken, Object>> order(List<Entry<TypeToken, Object>> insertionOrder) {
+ return insertionOrder;
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/InvokableTest.java b/guava-tests/test/com/google/common/reflect/InvokableTest.java
new file mode 100644
index 0000000..cad4616
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/InvokableTest.java
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.reflect.TypeToken;
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestCase;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.TypeVariable;
+import java.util.Collections;
+
+import javax.annotation.Nullable;
+
+/**
+ * Unit tests for {@link Invokable}.
+ *
+ * @author Ben Yu
+ */
+public class InvokableTest extends TestCase {
+
+ public void testConstructor_returnType() throws Exception {
+ assertEquals(Prepender.class,
+ Prepender.constructor().getReturnType().getType());
+ }
+
+ public void testConstructor_exceptionTypes() throws Exception {
+ assertEquals(ImmutableList.of(TypeToken.of(NullPointerException.class)),
+ Prepender.constructor(String.class, int.class).getExceptionTypes());
+ }
+
+ public void testConstructor_typeParameters() throws Exception {
+ TypeVariable<?>[] variables =
+ Prepender.constructor().getTypeParameters();
+ assertEquals(1, variables.length);
+ assertEquals("A", variables[0].getName());
+ }
+
+ public void testConstructor_parameters() throws Exception {
+ Invokable<?, Prepender> delegate = Prepender.constructor(String.class, int.class);
+ ImmutableList<Parameter> parameters = delegate.getParameters();
+ assertEquals(2, parameters.size());
+ assertEquals(String.class, parameters.get(0).getType().getType());
+ assertTrue(parameters.get(0).isAnnotationPresent(NotBlank.class));
+ assertEquals(int.class, parameters.get(1).getType().getType());
+ assertFalse(parameters.get(1).isAnnotationPresent(NotBlank.class));
+ new EqualsTester()
+ .addEqualityGroup(parameters.get(0))
+ .addEqualityGroup(parameters.get(1))
+ .testEquals();
+ }
+
+ public void testConstructor_call() throws Exception {
+ Invokable<?, Prepender> delegate = Prepender.constructor(String.class, int.class);
+ Prepender prepender = delegate.invoke(null, "a", 1);
+ assertEquals("a", prepender.prefix);
+ assertEquals(1, prepender.times);
+ }
+
+ public void testConstructor_returning() throws Exception {
+ Invokable<?, Prepender> delegate = Prepender.constructor(String.class, int.class)
+ .returning(Prepender.class);
+ Prepender prepender = delegate.invoke(null, "a", 1);
+ assertEquals("a", prepender.prefix);
+ assertEquals(1, prepender.times);
+ }
+
+ public void testConstructor_invalidReturning() throws Exception {
+ Invokable<?, Prepender> delegate = Prepender.constructor(String.class, int.class);
+ try {
+ delegate.returning(SubPrepender.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testStaticMethod_returnType() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("prepend", String.class, Iterable.class);
+ assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
+ }
+
+ public void testStaticMethod_exceptionTypes() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("prepend", String.class, Iterable.class);
+ assertEquals(ImmutableList.of(), delegate.getExceptionTypes());
+ }
+
+ public void testStaticMethod_typeParameters() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("prepend", String.class, Iterable.class);
+ TypeVariable<?>[] variables = delegate.getTypeParameters();
+ assertEquals(1, variables.length);
+ assertEquals("T", variables[0].getName());
+ }
+
+ public void testStaticMethod_parameters() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("prepend", String.class, Iterable.class);
+ ImmutableList<Parameter> parameters = delegate.getParameters();
+ assertEquals(2, parameters.size());
+ assertEquals(String.class, parameters.get(0).getType().getType());
+ assertTrue(parameters.get(0).isAnnotationPresent(NotBlank.class));
+ assertEquals(new TypeToken<Iterable<String>>() {}, parameters.get(1).getType());
+ assertFalse(parameters.get(1).isAnnotationPresent(NotBlank.class));
+ new EqualsTester()
+ .addEqualityGroup(parameters.get(0))
+ .addEqualityGroup(parameters.get(1))
+ .testEquals();
+ }
+
+ public void testStaticMethod_call() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("prepend", String.class, Iterable.class);
+ @SuppressWarnings("unchecked") // prepend() returns Iterable<String>
+ Iterable<String> result = (Iterable<String>)
+ delegate.invoke(null, "a", ImmutableList.of("b", "c"));
+ assertEquals(ImmutableList.of("a", "b", "c"), ImmutableList.copyOf(result));
+ }
+
+ public void testStaticMethod_returning() throws Exception {
+ Invokable<?, Iterable<String>> delegate = Prepender.method(
+ "prepend", String.class, Iterable.class)
+ .returning(new TypeToken<Iterable<String>>() {});
+ assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
+ Iterable<String> result = delegate.invoke(null, "a", ImmutableList.of("b", "c"));
+ assertEquals(ImmutableList.of("a", "b", "c"), ImmutableList.copyOf(result));
+ }
+
+ public void testStaticMethod_returningRawType() throws Exception {
+ @SuppressWarnings("rawtypes") // the purpose is to test raw type
+ Invokable<?, Iterable> delegate = Prepender.method(
+ "prepend", String.class, Iterable.class)
+ .returning(Iterable.class);
+ assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
+ @SuppressWarnings("unchecked") // prepend() returns Iterable<String>
+ Iterable<String> result = delegate.invoke(null, "a", ImmutableList.of("b", "c"));
+ assertEquals(ImmutableList.of("a", "b", "c"), ImmutableList.copyOf(result));
+ }
+
+ public void testStaticMethod_invalidReturning() throws Exception {
+ Invokable<?, Object> delegate = Prepender.method("prepend", String.class, Iterable.class);
+ try {
+ delegate.returning(new TypeToken<Iterable<Integer>>() {});
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testInstanceMethod_returnType() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("prepend", Iterable.class);
+ assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
+ }
+
+ public void testInstanceMethod_exceptionTypes() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("prepend", Iterable.class);
+ assertEquals(
+ ImmutableList.of(
+ TypeToken.of(IllegalArgumentException.class),
+ TypeToken.of(NullPointerException.class)),
+ delegate.getExceptionTypes());
+ }
+
+ public void testInstanceMethod_typeParameters() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("prepend", Iterable.class);
+ assertEquals(0, delegate.getTypeParameters().length);
+ }
+
+ public void testInstanceMethod_parameters() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("prepend", Iterable.class);
+ ImmutableList<Parameter> parameters = delegate.getParameters();
+ assertEquals(1, parameters.size());
+ assertEquals(new TypeToken<Iterable<String>>() {}, parameters.get(0).getType());
+ assertEquals(0, parameters.get(0).getAnnotations().length);
+ new EqualsTester()
+ .addEqualityGroup(parameters.get(0))
+ .testEquals();
+ }
+
+ public void testInstanceMethod_call() throws Exception {
+ Invokable<Prepender, ?> delegate = Prepender.method("prepend", Iterable.class);
+ @SuppressWarnings("unchecked") // prepend() returns Iterable<String>
+ Iterable<String> result = (Iterable<String>)
+ delegate.invoke(new Prepender("a", 2), ImmutableList.of("b", "c"));
+ assertEquals(ImmutableList.of("a", "a", "b", "c"), ImmutableList.copyOf(result));
+ }
+
+ public void testInstanceMethod_returning() throws Exception {
+ Invokable<Prepender, Iterable<String>> delegate = Prepender.method(
+ "prepend", Iterable.class)
+ .returning(new TypeToken<Iterable<String>>() {});
+ assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
+ Iterable<String> result = delegate.invoke(new Prepender("a", 2), ImmutableList.of("b", "c"));
+ assertEquals(ImmutableList.of("a", "a", "b", "c"), ImmutableList.copyOf(result));
+ }
+
+ public void testInstanceMethod_returningRawType() throws Exception {
+ @SuppressWarnings("rawtypes") // the purpose is to test raw type
+ Invokable<Prepender, Iterable> delegate = Prepender.method("prepend", Iterable.class)
+ .returning(Iterable.class);
+ assertEquals(new TypeToken<Iterable<String>>() {}, delegate.getReturnType());
+ @SuppressWarnings("unchecked") // prepend() returns Iterable<String>
+ Iterable<String> result = delegate.invoke(
+ new Prepender("a", 2), ImmutableList.of("b", "c"));
+ assertEquals(ImmutableList.of("a", "a", "b", "c"), ImmutableList.copyOf(result));
+ }
+
+ public void testInstanceMethod_invalidReturning() throws Exception {
+ Invokable<?, Object> delegate = Prepender.method("prepend", Iterable.class);
+ try {
+ delegate.returning(new TypeToken<Iterable<Integer>>() {});
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testPrivateInstanceMethod_isOverridable() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("privateMethod");
+ assertTrue(delegate.isPrivate());
+ assertFalse(delegate.isOverridable());
+ assertFalse(delegate.isVarArgs());
+ }
+
+ public void testPrivateFinalInstanceMethod_isOverridable() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("privateFinalMethod");
+ assertTrue(delegate.isPrivate());
+ assertTrue(delegate.isFinal());
+ assertFalse(delegate.isOverridable());
+ assertFalse(delegate.isVarArgs());
+ }
+
+ public void testStaticMethod_isOverridable() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("staticMethod");
+ assertTrue(delegate.isStatic());
+ assertFalse(delegate.isOverridable());
+ assertFalse(delegate.isVarArgs());
+ }
+
+ public void testStaticFinalMethod_isFinal() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("staticFinalMethod");
+ assertTrue(delegate.isStatic());
+ assertTrue(delegate.isFinal());
+ assertFalse(delegate.isOverridable());
+ assertFalse(delegate.isVarArgs());
+ }
+
+ static class Foo {}
+
+ public void testConstructor_isOverridablel() throws Exception {
+ Invokable<?, ?> delegate = Invokable.from(Foo.class.getDeclaredConstructor());
+ assertFalse(delegate.isOverridable());
+ assertFalse(delegate.isVarArgs());
+ }
+
+ public void testMethod_isVarArgs() throws Exception {
+ Invokable<?, ?> delegate = Prepender.method("privateVarArgsMethod", String[].class);
+ assertTrue(delegate.isVarArgs());
+ }
+
+ public void testConstructor_isVarArgs() throws Exception {
+ Invokable<?, ?> delegate = Prepender.constructor(String[].class);
+ assertTrue(delegate.isVarArgs());
+ }
+
+ public void testGetOwnerType_constructor() throws Exception {
+ Invokable<String, String> invokable = Invokable.from(String.class.getConstructor());
+ assertEquals(TypeToken.of(String.class), invokable.getOwnerType());
+ }
+
+ public void testGetOwnerType_method() throws Exception {
+ Invokable<?, ?> invokable = Invokable.from(String.class.getMethod("length"));
+ assertEquals(TypeToken.of(String.class), invokable.getOwnerType());
+ }
+
+ private static final class FinalClass {
+ @SuppressWarnings("unused") // used by reflection
+ void notFinalMethod() {}
+ }
+
+ public void testNonFinalMethodInFinalClass_isOverridable() throws Exception {
+ Invokable<?, ?> delegate = Invokable.from(
+ FinalClass.class.getDeclaredMethod("notFinalMethod"));
+ assertFalse(delegate.isOverridable());
+ assertFalse(delegate.isVarArgs());
+ }
+
+ private class InnerWithDefaultConstructor {
+ class NestedInner {}
+ }
+
+ public void testInnerClassDefaultConstructor() throws Exception {
+ Constructor<?> constructor =
+ InnerWithDefaultConstructor.class.getDeclaredConstructors() [0];
+ assertEquals(0, Invokable.from(constructor).getParameters().size());
+ }
+
+ public void testNestedInnerClassDefaultConstructor() throws Exception {
+ Constructor<?> constructor =
+ InnerWithDefaultConstructor.NestedInner.class.getDeclaredConstructors() [0];
+ assertEquals(0, Invokable.from(constructor).getParameters().size());
+ }
+
+ private class InnerWithOneParameterConstructor {
+ @SuppressWarnings("unused") // called by reflection
+ public InnerWithOneParameterConstructor(String s) {}
+ }
+
+ public void testInnerClassWithOneParameterConstructor() throws Exception {
+ Constructor<?> constructor =
+ InnerWithOneParameterConstructor.class.getDeclaredConstructors()[0];
+ Invokable<?, ?> invokable = Invokable.from(constructor);
+ assertEquals(1, invokable.getParameters().size());
+ assertEquals(TypeToken.of(String.class), invokable.getParameters().get(0).getType());
+ }
+
+ private class InnerWithAnnotatedConstructorParameter {
+ @SuppressWarnings("unused") // called by reflection
+ InnerWithAnnotatedConstructorParameter(@Nullable String s) {}
+ }
+
+ public void testInnerClassWithAnnotatedConstructorParameter() throws Exception {
+ Constructor<?> constructor =
+ InnerWithAnnotatedConstructorParameter.class.getDeclaredConstructors() [0];
+ Invokable<?, ?> invokable = Invokable.from(constructor);
+ assertEquals(1, invokable.getParameters().size());
+ assertEquals(TypeToken.of(String.class), invokable.getParameters().get(0).getType());
+ }
+
+ private class InnerWithGenericConstructorParameter {
+ @SuppressWarnings("unused") // called by reflection
+ InnerWithGenericConstructorParameter(Iterable<String> it, String s) {}
+ }
+
+ public void testInnerClassWithGenericConstructorParameter() throws Exception {
+ Constructor<?> constructor =
+ InnerWithGenericConstructorParameter.class.getDeclaredConstructors() [0];
+ Invokable<?, ?> invokable = Invokable.from(constructor);
+ assertEquals(2, invokable.getParameters().size());
+ assertEquals(new TypeToken<Iterable<String>>() {},
+ invokable.getParameters().get(0).getType());
+ assertEquals(TypeToken.of(String.class),
+ invokable.getParameters().get(1).getType());
+ }
+
+ public void testAnonymousClassDefaultConstructor() throws Exception {
+ final int i = 1;
+ final String s = "hello world";
+ Class<?> anonymous = new Runnable() {
+ @Override public void run() {
+ System.out.println(s + i);
+ }
+ }.getClass();
+ Constructor<?> constructor =
+ anonymous.getDeclaredConstructors() [0];
+ assertEquals(0, Invokable.from(constructor).getParameters().size());
+ }
+
+ public void testAnonymousClassWithTwoParametersConstructor() throws Exception {
+ abstract class Base {
+ @SuppressWarnings("unused") // called by reflection
+ Base(String s, int i) {}
+ }
+ Class<?> anonymous = new Base("test", 0) {}.getClass();
+ Constructor<?> constructor =
+ anonymous.getDeclaredConstructors() [0];
+ assertEquals(2, Invokable.from(constructor).getParameters().size());
+ }
+
+ public void testLocalClassDefaultConstructor() throws Exception {
+ final int i = 1;
+ final String s = "hello world";
+ class LocalWithDefaultConstructor implements Runnable {
+ @Override public void run() {
+ System.out.println(s + i);
+ }
+ }
+ Constructor<?> constructor =
+ LocalWithDefaultConstructor.class.getDeclaredConstructors() [0];
+ assertEquals(0, Invokable.from(constructor).getParameters().size());
+ }
+
+ public void testStaticAnonymousClassDefaultConstructor() throws Exception {
+ doTestStaticAnonymousClassDefaultConstructor();
+ }
+
+ private static void doTestStaticAnonymousClassDefaultConstructor() throws Exception {
+ final int i = 1;
+ final String s = "hello world";
+ Class<?> anonymous = new Runnable() {
+ @Override public void run() {
+ System.out.println(s + i);
+ }
+ }.getClass();
+ Constructor<?> constructor =
+ anonymous.getDeclaredConstructors() [0];
+ assertEquals(0, Invokable.from(constructor).getParameters().size());
+ }
+
+ public void testLocalClassWithOneParameterConstructor() throws Exception {
+ final int i = 1;
+ final String s = "hello world";
+ class LocalWithOneParameterConstructor {
+ @SuppressWarnings("unused") // called by reflection
+ public LocalWithOneParameterConstructor(String x) {
+ System.out.println(s + i);
+ }
+ }
+ Constructor<?> constructor =
+ LocalWithOneParameterConstructor.class.getDeclaredConstructors()[0];
+ Invokable<?, ?> invokable = Invokable.from(constructor);
+ assertEquals(1, invokable.getParameters().size());
+ assertEquals(TypeToken.of(String.class), invokable.getParameters().get(0).getType());
+ }
+
+ public void testLocalClassWithAnnotatedConstructorParameter() throws Exception {
+ class LocalWithAnnotatedConstructorParameter {
+ @SuppressWarnings("unused") // called by reflection
+ LocalWithAnnotatedConstructorParameter(@Nullable String s) {}
+ }
+ Constructor<?> constructor =
+ LocalWithAnnotatedConstructorParameter.class.getDeclaredConstructors() [0];
+ Invokable<?, ?> invokable = Invokable.from(constructor);
+ assertEquals(1, invokable.getParameters().size());
+ assertEquals(TypeToken.of(String.class), invokable.getParameters().get(0).getType());
+ }
+
+ public void testLocalClassWithGenericConstructorParameter() throws Exception {
+ class LocalWithGenericConstructorParameter {
+ @SuppressWarnings("unused") // called by reflection
+ LocalWithGenericConstructorParameter(Iterable<String> it, String s) {}
+ }
+ Constructor<?> constructor =
+ LocalWithGenericConstructorParameter.class.getDeclaredConstructors() [0];
+ Invokable<?, ?> invokable = Invokable.from(constructor);
+ assertEquals(2, invokable.getParameters().size());
+ assertEquals(new TypeToken<Iterable<String>>() {},
+ invokable.getParameters().get(0).getType());
+ assertEquals(TypeToken.of(String.class),
+ invokable.getParameters().get(1).getType());
+ }
+
+ public void testEquals() throws Exception {
+ new EqualsTester()
+ .addEqualityGroup(Prepender.constructor(), Prepender.constructor())
+ .addEqualityGroup(Prepender.constructor(String.class, int.class))
+ .addEqualityGroup(Prepender.method("privateMethod"), Prepender.method("privateMethod"))
+ .addEqualityGroup(Prepender.method("privateFinalMethod"))
+ .testEquals();
+ }
+
+ public void testNulls() {
+ new NullPointerTester().testAllPublicStaticMethods(Invokable.class);
+ new NullPointerTester().testAllPublicInstanceMethods(Prepender.method("staticMethod"));
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ private @interface NotBlank {}
+
+ /** Class for testing constructor, static method and instance method. */
+ @SuppressWarnings("unused") // most are called by reflection
+ private static class Prepender {
+
+ private final String prefix;
+ private final int times;
+
+ Prepender(@NotBlank String prefix, int times) throws NullPointerException {
+ this.prefix = prefix;
+ this.times = times;
+ }
+
+ Prepender(String... varargs) {
+ this(null, 0);
+ }
+
+ // just for testing
+ private <A> Prepender() {
+ this(null, 0);
+ }
+
+ static <T> Iterable<String> prepend(@NotBlank String first, Iterable<String> tail) {
+ return Iterables.concat(ImmutableList.of(first), tail);
+ }
+
+ Iterable<String> prepend(Iterable<String> tail)
+ throws IllegalArgumentException, NullPointerException {
+ return Iterables.concat(Collections.nCopies(times, prefix), tail);
+ }
+
+ static Invokable<?, Prepender> constructor(Class<?>... parameterTypes) throws Exception {
+ Constructor<Prepender> constructor = Prepender.class.getDeclaredConstructor(parameterTypes);
+ return Invokable.from(constructor);
+ }
+
+ static Invokable<Prepender, Object> method(String name, Class<?>... parameterTypes) {
+ try {
+ Method method = Prepender.class.getDeclaredMethod(name, parameterTypes);
+ @SuppressWarnings("unchecked") // The method is from Prepender.
+ Invokable<Prepender, Object> invokable = (Invokable<Prepender, Object>)
+ Invokable.from(method);
+ return invokable;
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ private void privateMethod() {}
+
+ private final void privateFinalMethod() {}
+
+ static void staticMethod() {}
+
+ static final void staticFinalMethod() {}
+
+ private void privateVarArgsMethod(String... varargs) {}
+ }
+
+ private static class SubPrepender extends Prepender {
+ @SuppressWarnings("unused") // needed to satisfy compiler, never called
+ public SubPrepender() throws NullPointerException {
+ throw new AssertionError();
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java b/guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java
new file mode 100644
index 0000000..18e0058
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/MutableTypeToInstanceMapTest.java
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.testing.MapTestSuiteBuilder;
+import com.google.common.collect.testing.features.CollectionSize;
+import com.google.common.collect.testing.features.MapFeature;
+import com.google.common.collect.testing.testers.MapPutTester;
+import com.google.common.reflect.ImmutableTypeToInstanceMapTest.TestTypeToInstanceMapGenerator;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Unit test of {@link MutableTypeToInstanceMap}.
+ *
+ * @author Ben Yu
+ */
+public class MutableTypeToInstanceMapTest extends TestCase {
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite();
+ suite.addTestSuite(MutableTypeToInstanceMapTest.class);
+
+ // Suppress this one because the tester framework doesn't understand that
+ // *some* remappings will be allowed and others not.
+ Method remapTest = null;
+ try {
+ remapTest = MapPutTester.class.getMethod(
+ "testPut_replaceNullValueWithNonNullSupported");
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError();
+ }
+
+ suite.addTest(MapTestSuiteBuilder
+ .using(new TestTypeToInstanceMapGenerator() {
+ // Other tests will verify what real, warning-free usage looks like
+ // but here we have to do some serious fudging
+ @Override
+ @SuppressWarnings("unchecked")
+ public Map<TypeToken, Object> create(Object... elements) {
+ MutableTypeToInstanceMap<Object> map
+ = new MutableTypeToInstanceMap<Object>();
+ for (Object object : elements) {
+ Entry<TypeToken, Object> entry = (Entry<TypeToken, Object>) object;
+ map.putInstance(entry.getKey(), entry.getValue());
+ }
+ return (Map) map;
+ }
+ })
+ .named("MutableTypeToInstanceMap")
+ .withFeatures(
+ MapFeature.SUPPORTS_REMOVE,
+ MapFeature.RESTRICTS_KEYS,
+ MapFeature.ALLOWS_NULL_VALUES,
+ CollectionSize.ANY,
+ MapFeature.ALLOWS_NULL_QUERIES)
+ .suppressing(remapTest)
+ .createTestSuite());
+
+ return suite;
+ }
+
+ private TypeToInstanceMap<Object> map;
+
+ @Override protected void setUp() throws Exception {
+ map = new MutableTypeToInstanceMap<Object>();
+ }
+
+ public void testPutThrows() {
+ try {
+ map.put(TypeToken.of(Integer.class), new Integer(5));
+ fail();
+ } catch (UnsupportedOperationException expected) {}
+ }
+
+ public void testPutAllThrows() {
+ try {
+ map.putAll(ImmutableMap.of(TypeToken.of(Integer.class), new Integer(5)));
+ fail();
+ } catch (UnsupportedOperationException expected) {}
+ }
+
+ public void testPutAndGetInstance() {
+ assertNull(map.putInstance(Integer.class, new Integer(5)));
+
+ Integer oldValue = map.putInstance(Integer.class, new Integer(7));
+ assertEquals(5, (int) oldValue);
+
+ Integer newValue = map.getInstance(Integer.class);
+ assertEquals(7, (int) newValue);
+ assertEquals(7, (int) map.getInstance(TypeToken.of(Integer.class)));
+
+ // Won't compile: map.putInstance(Double.class, new Long(42));
+ }
+
+ public void testNull() {
+ try {
+ map.putInstance((TypeToken) null, new Integer(1));
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ map.putInstance(Integer.class, null);
+ assertNull(map.get(Integer.class));
+ assertNull(map.getInstance(Integer.class));
+
+ map.putInstance(Long.class, null);
+ assertNull(map.get(Long.class));
+ assertNull(map.getInstance(Long.class));
+ }
+
+ public void testPrimitiveAndWrapper() {
+ assertNull(map.getInstance(int.class));
+ assertNull(map.getInstance(Integer.class));
+
+ assertNull(map.putInstance(int.class, 0));
+ assertNull(map.putInstance(Integer.class, 1));
+ assertEquals(2, map.size());
+
+ assertEquals(0, (int) map.getInstance(int.class));
+ assertEquals(1, (int) map.getInstance(Integer.class));
+
+ assertEquals(0, (int) map.putInstance(int.class, null));
+ assertEquals(1, (int) map.putInstance(Integer.class, null));
+
+ assertNull(map.getInstance(int.class));
+ assertNull(map.getInstance(Integer.class));
+ assertEquals(2, map.size());
+ }
+
+ public void testParameterizedType() {
+ TypeToken<ImmutableList<Integer>> type = new TypeToken<ImmutableList<Integer>>() {};
+ map.putInstance(type, ImmutableList.of(1));
+ assertEquals(1, map.size());
+ assertEquals(ImmutableList.of(1), map.getInstance(type));
+ }
+
+ public void testGeneriArrayType() {
+ @SuppressWarnings("unchecked") // Trying to test generic array
+ ImmutableList<Integer>[] array = new ImmutableList[] {ImmutableList.of(1)};
+ TypeToken<ImmutableList<Integer>[]> type = new TypeToken<ImmutableList<Integer>[]>() {};
+ map.putInstance(type, array);
+ assertEquals(1, map.size());
+ ASSERT.that(map.getInstance(type)).has().allOf(array[0]).inOrder();
+ }
+
+ public void testWildcardType() {
+ TypeToken<ImmutableList<?>> type = new TypeToken<ImmutableList<?>>() {};
+ map.putInstance(type, ImmutableList.of(1));
+ assertEquals(1, map.size());
+ assertEquals(ImmutableList.of(1), map.getInstance(type));
+ }
+
+ public void testGetInstance_withTypeVariable() {
+ try {
+ map.getInstance(this.<Number>anyIterableType());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testPutInstance_withTypeVariable() {
+ try {
+ map.putInstance(this.<Integer>anyIterableType(), ImmutableList.of(1));
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ private <T> TypeToken<Iterable<T>> anyIterableType() {
+ return new TypeToken<Iterable<T>>() {};
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/PackageSanityTests.java b/guava-tests/test/com/google/common/reflect/PackageSanityTests.java
new file mode 100644
index 0000000..8398be5
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/PackageSanityTests.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import com.google.common.testing.AbstractPackageSanityTests;
+
+/**
+ * Tests nulls for the entire package.
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {}
diff --git a/guava-tests/test/com/google/common/reflect/ParameterTest.java b/guava-tests/test/com/google/common/reflect/ParameterTest.java
new file mode 100644
index 0000000..88d04b7
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/ParameterTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Method;
+
+/**
+ * Tests for {@link Parameter}.
+ *
+ * @author Ben Yu
+ */
+public class ParameterTest extends TestCase {
+
+ public void testNulls() {
+ for (Method method : ParameterTest.class.getDeclaredMethods()) {
+ for (Parameter param : Invokable.from(method).getParameters()) {
+ new NullPointerTester().testAllPublicInstanceMethods(param);
+ }
+ }
+ }
+
+ public void testEquals() {
+ EqualsTester tester = new EqualsTester();
+ for (Method method : ParameterTest.class.getDeclaredMethods()) {
+ for (Parameter param : Invokable.from(method).getParameters()) {
+ tester.addEqualityGroup(param);
+ }
+ }
+ tester.testEquals();
+ }
+
+ @SuppressWarnings("unused")
+ private void someMethod(int i, int j) {}
+
+ @SuppressWarnings("unused")
+ private void anotherMethod(int i, String s) {}
+}
diff --git a/guava-tests/test/com/google/common/reflect/ReflectionTest.java b/guava-tests/test/com/google/common/reflect/ReflectionTest.java
new file mode 100644
index 0000000..2923b47
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/ReflectionTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2006 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+/** Tests for {@link Reflection} */
+public class ReflectionTest extends TestCase {
+
+ public void testGetPackageName() throws Exception {
+ assertEquals("java.lang", Reflection.getPackageName(Iterable.class));
+ assertEquals("java", Reflection.getPackageName("java.MyType"));
+ assertEquals("java.lang", Reflection.getPackageName(Iterable.class.getName()));
+ assertEquals("", Reflection.getPackageName("NoPackage"));
+ assertEquals("java.util", Reflection.getPackageName(Map.Entry.class));
+ }
+
+ public void testNewProxy() throws Exception {
+ Runnable runnable = Reflection.newProxy(Runnable.class, X_RETURNER);
+ assertEquals("x", runnable.toString());
+ }
+
+ public void testNewProxyCantWorkOnAClass() throws Exception {
+ try {
+ Reflection.newProxy(Object.class, X_RETURNER);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ private static final InvocationHandler X_RETURNER = new InvocationHandler() {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable {
+ return "x";
+ }
+ };
+
+ private static int classesInitialized = 0;
+ private static class A {
+ static {
+ ++classesInitialized;
+ }
+ }
+ private static class B {
+ static {
+ ++classesInitialized;
+ }
+ }
+ private static class C {
+ static {
+ ++classesInitialized;
+ }
+ }
+
+ public void testInitialize() {
+ assertEquals("This test can't be included twice in the same suite.", 0, classesInitialized);
+
+ Reflection.initialize(A.class);
+ assertEquals(1, classesInitialized);
+
+ Reflection.initialize(
+ A.class, // Already initialized (above)
+ B.class,
+ C.class);
+ assertEquals(3, classesInitialized);
+ }
+
+ public void testNullPointers() {
+ new NullPointerTester().testAllPublicStaticMethods(Reflection.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/TypeParameterTest.java b/guava-tests/test/com/google/common/reflect/TypeParameterTest.java
new file mode 100644
index 0000000..9ac8a4a
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/TypeParameterTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.TypeVariable;
+
+/**
+ * Unit test for {@link TypeParameter}.
+ *
+ * @author Ben Yu
+ */
+public class TypeParameterTest extends TestCase {
+
+ public <T> void testCaptureTypeParameter() throws Exception {
+ TypeVariable<?> variable = new TypeParameter<T>() {}.typeVariable;
+ TypeVariable<?> expected = TypeParameterTest.class
+ .getDeclaredMethod("testCaptureTypeParameter")
+ .getTypeParameters()[0];
+ assertEquals(expected, variable);
+ }
+
+ public void testConcreteTypeRejected() {
+ try {
+ new TypeParameter<String>() {};
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <A, B> void testEquals() throws Exception {
+ Method method = TypeParameterTest.class.getDeclaredMethod("testEquals");
+ new EqualsTester()
+ .addEqualityGroup(
+ new TypeParameter<A>() {}, new TypeParameter<A>() {})
+ .addEqualityGroup(new TypeParameter<B>() {})
+ .testEquals();
+ }
+
+ public void testNullPointers() {
+ new NullPointerTester().testAllPublicStaticMethods(TypeParameter.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/TypeResolverTest.java b/guava-tests/test/com/google/common/reflect/TypeResolverTest.java
new file mode 100644
index 0000000..84b1b5e
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/TypeResolverTest.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Unit tests of {@link TypeResolver}.
+ *
+ * @author Ben Yu
+ */
+public class TypeResolverTest extends TestCase {
+
+ public void testWhere_noMapping() {
+ Type t = aTypeVariable();
+ assertEquals(t, new TypeResolver().resolveType(t));
+ }
+
+ public void testWhere_typeVariableMapping() {
+ Type t = aTypeVariable();
+ assertEquals(String.class, new TypeResolver().where(t, String.class).resolveType(t));
+ }
+
+ public <T> void testWhere_indirectMapping() {
+ Type t1 = new TypeCapture<T>() {}.capture();
+ Type t2 = aTypeVariable();
+ assertEquals(String.class,
+ new TypeResolver().where(t1, t2).where(t2, String.class).resolveType(t1));
+ }
+
+ public void testWhere_typeVariableSelfMapping() {
+ TypeResolver resolver = new TypeResolver();
+ Type t = aTypeVariable();
+ assertEquals(t, resolver.where(t, t).resolveType(t));
+ }
+
+ public <T> void testWhere_parameterizedSelfMapping() {
+ TypeResolver resolver = new TypeResolver();
+ Type t = new TypeCapture<List<T>>() {}.capture();
+ assertEquals(t, resolver.where(t, t).resolveType(t));
+ }
+
+ public <T> void testWhere_genericArraySelfMapping() {
+ TypeResolver resolver = new TypeResolver();
+ Type t = new TypeCapture<T[]>() {}.capture();
+ assertEquals(t, resolver.where(t, t).resolveType(t));
+ }
+
+ public <T> void testWhere_rawClassSelfMapping() {
+ TypeResolver resolver = new TypeResolver();
+ assertEquals(String.class,
+ resolver.where(String.class, String.class).resolveType(String.class));
+ }
+
+ public <T> void testWhere_wildcardSelfMapping() {
+ TypeResolver resolver = new TypeResolver();
+ Type t = aWildcardType();
+ assertEquals(t, resolver.where(t, t).resolveType(t));
+ }
+
+ public <T> void testWhere_duplicateMapping() {
+ Type t = aTypeVariable();
+ TypeResolver resolver = new TypeResolver().where(t, String.class);
+ try {
+ resolver.where(t, String.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <T1, T2 extends List<T1>> void testWhere_recursiveMapping() {
+ Type t1 = new TypeCapture<T1>() {}.capture();
+ Type t2 = new TypeCapture<T2>() {}.capture();
+ assertEquals(t2, new TypeResolver().where(t1, t2).resolveType(t1));
+ }
+
+ public <T> void testWhere_genericArrayMapping() {
+ Type t = new TypeCapture<T>() {}.capture();
+ assertEquals(String.class, new TypeResolver()
+ .where(new TypeCapture<T[]>() {}.capture(), String[].class)
+ .resolveType(t));
+ }
+
+ public <T> void testWhere_primitiveArrayMapping() {
+ Type t = new TypeCapture<T>() {}.capture();
+ assertEquals(int.class,
+ new TypeResolver().where(new TypeCapture<T[]>() {}.capture(), int[].class).resolveType(t));
+ }
+
+ public <T> void testWhere_parameterizedTypeMapping() {
+ Type t = new TypeCapture<T>() {}.capture();
+ assertEquals(String.class, new TypeResolver()
+ .where(new TypeCapture<List<T>>() {}.capture(),
+ new TypeCapture<List<String>>() {}.capture())
+ .resolveType(t));
+ assertEquals(Types.subtypeOf(String.class), new TypeResolver()
+ .where(new TypeCapture<List<T>>() {}.capture(),
+ new TypeCapture<List<? extends String>>() {}.capture())
+ .resolveType(t));
+ assertEquals(Types.supertypeOf(String.class), new TypeResolver()
+ .where(new TypeCapture<List<T>>() {}.capture(),
+ new TypeCapture<List<? super String>>() {}.capture())
+ .resolveType(t));
+ }
+
+ public <T> void testWhere_wildcardTypeMapping() {
+ Type t = new TypeCapture<T>() {}.capture();
+ assertEquals(String.class, new TypeResolver()
+ .where(new TypeCapture<List<? extends T>>() {}.capture(),
+ new TypeCapture<List<? extends String>>() {}.capture())
+ .resolveType(t));
+ assertEquals(String.class, new TypeResolver()
+ .where(new TypeCapture<List<? super T>>() {}.capture(),
+ new TypeCapture<List<? super String>>() {}.capture())
+ .resolveType(t));
+ }
+
+ public <T> void testWhere_incompatibleGenericArrayMapping() {
+ try {
+ new TypeResolver().where(new TypeCapture<T[]>() {}.capture(), String.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <T> void testWhere_incompatibleParameterizedTypeMapping() {
+ try {
+ new TypeResolver().where(new TypeCapture<Iterable<T>>() {}.capture(), List.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <T> void testWhere_impossibleParameterizedTypeMapping() {
+ try {
+ new TypeResolver().where(
+ new TypeCapture<List<T>>() {}.capture(),
+ new TypeCapture<Map<String, Integer>>() {}.capture());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <T> void testWhere_incompatibleWildcardUpperBound() {
+ try {
+ new TypeResolver().where(
+ new TypeCapture<List<? extends String>>() {}.capture(),
+ new TypeCapture<List<? extends Integer>>() {}.capture());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <T> void testWhere_incompatibleWildcardLowerBound() {
+ try {
+ new TypeResolver().where(
+ new TypeCapture<List<? super String>>() {}.capture(),
+ new TypeCapture<List<? super Integer>>() {}.capture());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <T> void testWhere_incompatibleWildcardBounds() {
+ try {
+ new TypeResolver().where(
+ new TypeCapture<List<? extends T>>() {}.capture(),
+ new TypeCapture<List<? super String>>() {}.capture());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <T> void testWhere_wrongOrder() {
+ try {
+ new TypeResolver().where(String.class, aTypeVariable());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <T> void testWhere_mapFromConcreteParameterizedType() {
+ try {
+ new TypeResolver().where(new TypeCapture<List<String>>() {}.capture(), aTypeVariable());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <T> void testWhere_mapFromConcreteGenericArrayType() {
+ try {
+ new TypeResolver().where(new TypeCapture<List<String>>() {}.capture(), aTypeVariable());
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ private static <T> Type aTypeVariable() {
+ return new TypeCapture<T>() {}.capture();
+ }
+
+ private static <T> Type aWildcardType() {
+ ParameterizedType parameterizedType = (ParameterizedType)
+ new TypeCapture<List<? extends T>>() {}.capture();
+ return parameterizedType.getActualTypeArguments()[0];
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java b/guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java
new file mode 100644
index 0000000..6d51494
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/TypeTokenResolutionTest.java
@@ -0,0 +1,547 @@
+/*
+ * Copyright (C) 2009 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Unit test for {@link TypeToken} and {@link TypeResolver}.
+ *
+ * @author Ben Yu
+ */
+public class TypeTokenResolutionTest extends TestCase {
+
+ private static class Foo<A, B> {
+
+ Class<? super A> getClassA() {
+ return new TypeToken<A>(getClass()) {}.getRawType();
+ }
+
+ Class<? super B> getClassB() {
+ return new TypeToken<B>(getClass()) {}.getRawType();
+ }
+
+ Class<? super A[]> getArrayClassA() {
+ return new TypeToken<A[]>(getClass()) {}.getRawType();
+ }
+
+ Type getArrayTypeA() {
+ return new TypeToken<A[]>(getClass()) {}.getType();
+ }
+
+ Class<? super B[]> getArrayClassB() {
+ return new TypeToken<B[]>(getClass()) {}.getRawType();
+ }
+ }
+
+ public void testSimpleTypeToken() {
+ Foo<String, Integer> foo = new Foo<String, Integer>() {};
+ assertEquals(String.class, foo.getClassA());
+ assertEquals(Integer.class, foo.getClassB());
+ assertEquals(String[].class, foo.getArrayClassA());
+ assertEquals(Integer[].class, foo.getArrayClassB());
+ }
+
+ public void testCompositeTypeToken() {
+ Foo<String[], List<int[]>> foo = new Foo<String[], List<int[]>>() {};
+ assertEquals(String[].class, foo.getClassA());
+ assertEquals(List.class, foo.getClassB());
+ assertEquals(String[][].class, foo.getArrayClassA());
+ assertEquals(List[].class, foo.getArrayClassB());
+ }
+
+ private static class StringFoo<T> extends Foo<String, T> {}
+
+ public void testPartialSpecialization() {
+ StringFoo<Integer> foo = new StringFoo<Integer>() {};
+ assertEquals(String.class, foo.getClassA());
+ assertEquals(Integer.class, foo.getClassB());
+ assertEquals(String[].class, foo.getArrayClassA());
+ assertEquals(Integer[].class, foo.getArrayClassB());
+ assertEquals(new TypeToken<String[]>() {}.getType(), foo.getArrayTypeA());
+ }
+
+ public void testTypeArgNotFound() {
+ StringFoo<Integer> foo = new StringFoo<Integer>();
+ assertEquals(String.class, foo.getClassA());
+ assertEquals(String[].class, foo.getArrayClassA());
+ assertEquals(Object.class, foo.getClassB());
+ assertEquals(Object[].class, foo.getArrayClassB());
+ }
+
+ private static abstract class Bar<T> {}
+
+ private abstract static class Parameterized<O, T, P> {
+ ParameterizedType parameterizedType() {
+ return new ParameterizedType() {
+ @Override public Type[] getActualTypeArguments() {
+ return new Type[]{new TypeCapture<P>() {}.capture()};
+ }
+ @Override public Type getOwnerType() {
+ return new TypeCapture<O>() {}.capture();
+ }
+ @Override public Type getRawType() {
+ return new TypeCapture<T>() {}.capture();
+ }
+ };
+ }
+ }
+
+ public void testResolveType_parameterizedType() {
+ @SuppressWarnings("rawtypes") // trying to test raw type
+ Parameterized<?, ?, ?> parameterized =
+ new Parameterized<TypeTokenResolutionTest, Bar, String>() {};
+ TypeResolver typeResolver = TypeResolver.accordingTo(parameterized.getClass());
+ ParameterizedType resolved = (ParameterizedType) typeResolver.resolveType(
+ parameterized.parameterizedType());
+ assertEquals(TypeTokenResolutionTest.class, resolved.getOwnerType());
+ assertEquals(Bar.class, resolved.getRawType());
+ ASSERT.that(resolved.getActualTypeArguments()).has().item(String.class);
+ }
+
+ private interface StringListPredicate extends Predicate<List<String>> {}
+
+ private interface IntegerSupplier extends Supplier<Integer> {}
+
+ // Intentionally duplicate the Predicate interface to test that it won't cause
+ // exceptions
+ private interface IntegerStringFunction extends IntegerSupplier,
+ Predicate<List<String>>, StringListPredicate {}
+
+ public void testGenericInterface() {
+ // test the 1st generic interface on the class
+ Type fType = Supplier.class.getTypeParameters()[0];
+ assertEquals(Integer.class,
+ TypeToken.of(IntegerStringFunction.class).resolveType(fType)
+ .getRawType());
+
+ // test the 2nd generic interface on the class
+ Type predicateParameterType = Predicate.class.getTypeParameters()[0];
+ assertEquals(new TypeToken<List<String>>() {}.getType(),
+ TypeToken.of(IntegerStringFunction.class).resolveType(predicateParameterType)
+ .getType());
+ }
+
+ private static abstract class StringIntegerFoo extends Foo<String, Integer> {}
+
+ public void testConstructor_typeArgsResolvedFromAncestorClass() {
+ assertEquals(String.class, new StringIntegerFoo() {}.getClassA());
+ assertEquals(Integer.class, new StringIntegerFoo() {}.getClassB());
+ }
+
+ private static class Owner<T> {
+ private static abstract class Nested<X> {
+ Class<? super X> getTypeArgument() {
+ return new TypeToken<X>(getClass()) {}.getRawType();
+ }
+ }
+
+ private abstract class Inner<Y> extends Nested<Y> {
+ Class<? super T> getOwnerType() {
+ return new TypeToken<T>(getClass()) {}.getRawType();
+ }
+ }
+ }
+
+ public void testResolveNestedClass() {
+ assertEquals(String.class, new Owner.Nested<String>() {}.getTypeArgument());
+ }
+
+ public void testResolveInnerClass() {
+ assertEquals(String.class,
+ new Owner<Integer>().new Inner<String>() {}.getTypeArgument());
+ }
+
+ public void testResolveOwnerClass() {
+ assertEquals(Integer.class,
+ new Owner<Integer>().new Inner<String>() {}.getOwnerType());
+ }
+
+ private static class Mapping<F, T> {
+
+ final Type f = new TypeToken<F>(getClass()) {}.getType();
+ final Type t = new TypeToken<T>(getClass()) {}.getType();
+
+ Type getFromType() {
+ return new TypeToken<F>(getClass()) {}.getType();
+ }
+
+ Type getToType() {
+ return new TypeToken<T>(getClass()) {}.getType();
+ }
+
+ Mapping<T, F> flip() {
+ return new Mapping<T, F>() {};
+ }
+
+ Mapping<F, T> selfMapping() {
+ return new Mapping<F, T>() {};
+ }
+ }
+
+ public void testCyclicMapping() {
+ Mapping<Integer, String> mapping = new Mapping<Integer, String>();
+ assertEquals(mapping.f, mapping.getFromType());
+ assertEquals(mapping.t, mapping.getToType());
+ assertEquals(mapping.f, mapping.flip().getFromType());
+ assertEquals(mapping.t, mapping.flip().getToType());
+ assertEquals(mapping.f, mapping.selfMapping().getFromType());
+ assertEquals(mapping.t, mapping.selfMapping().getToType());
+ }
+
+ private static class ParameterizedOuter<T> {
+
+ @SuppressWarnings("unused") // used by reflection
+ public Inner field;
+
+ class Inner {}
+ }
+
+ public void testInnerClassWithParameterizedOwner() throws Exception {
+ Type fieldType = ParameterizedOuter.class.getField("field")
+ .getGenericType();
+ assertEquals(fieldType,
+ TypeToken.of(ParameterizedOuter.class).resolveType(fieldType).getType());
+ }
+
+ private interface StringIterable extends Iterable<String> {}
+
+ public void testResolveType() {
+ assertEquals(String.class, TypeToken.of(this.getClass()).resolveType(String.class).getType());
+ assertEquals(String.class,
+ TypeToken.of(StringIterable.class)
+ .resolveType(Iterable.class.getTypeParameters()[0]).getType());
+ assertEquals(String.class,
+ TypeToken.of(StringIterable.class)
+ .resolveType(Iterable.class.getTypeParameters()[0]).getType());
+ try {
+ TypeToken.of(this.getClass()).resolveType(null);
+ fail();
+ } catch (NullPointerException expected) {}
+ }
+
+ public void testConextIsParameterizedType() throws Exception {
+ class Context {
+ @SuppressWarnings("unused") // used by reflection
+ Map<String, Integer> returningMap() {
+ throw new AssertionError();
+ }
+ }
+ Type context = Context.class.getDeclaredMethod("returningMap")
+ .getGenericReturnType();
+ Type keyType = Map.class.getTypeParameters()[0];
+ Type valueType = Map.class.getTypeParameters()[1];
+
+ // context is parameterized type
+ assertEquals(String.class, TypeToken.of(context).resolveType(keyType).getType());
+ assertEquals(Integer.class,
+ TypeToken.of(context).resolveType(valueType).getType());
+
+ // context is type variable
+ assertEquals(keyType, TypeToken.of(keyType).resolveType(keyType).getType());
+ assertEquals(valueType, TypeToken.of(valueType).resolveType(valueType).getType());
+ }
+
+ private static final class GenericArray<T> {
+ final Type t = new TypeToken<T>(getClass()) {}.getType();
+ final Type array = new TypeToken<T[]>(getClass()) {}.getType();
+ }
+
+ public void testGenericArrayType() {
+ GenericArray<?> genericArray = new GenericArray<Integer>();
+ assertEquals(GenericArray.class.getTypeParameters()[0], genericArray.t);
+ assertEquals(Types.newArrayType(genericArray.t),
+ genericArray.array);
+ }
+
+ public void testClassWrapper() {
+ TypeToken<String> typeExpression = TypeToken.of(String.class);
+ assertEquals(String.class, typeExpression.getType());
+ assertEquals(String.class, typeExpression.getRawType());
+ }
+
+ private static class Red<A> {
+ private class Orange {
+ Class<?> getClassA() {
+ return new TypeToken<A>(getClass()) {}.getRawType();
+ }
+
+ Red<A> getSelfB() {
+ return Red.this;
+ }
+ }
+
+ Red<A> getSelfA() {
+ return this;
+ }
+
+ private class Yellow<B> extends Red<B>.Orange {
+ Yellow(Red<B> red) {
+ red.super();
+ }
+
+ Class<?> getClassB() {
+ return new TypeToken<B>(getClass()) {}.getRawType();
+ }
+
+ Red<A> getA() {
+ return getSelfA();
+ }
+
+ Red<B> getB() {
+ return getSelfB();
+ }
+ }
+
+ Class<?> getClassDirect() {
+ return new TypeToken<A>(getClass()) {}.getRawType();
+ }
+ }
+
+ public void test1() {
+ Red<String> redString = new Red<String>() {};
+ Red<Integer> redInteger = new Red<Integer>() {};
+ assertEquals(String.class, redString.getClassDirect());
+ assertEquals(Integer.class, redInteger.getClassDirect());
+
+ Red<String>.Yellow<Integer> yellowInteger =
+ redString.new Yellow<Integer>(redInteger) {};
+ assertEquals(Integer.class, yellowInteger.getClassA());
+ assertEquals(Integer.class, yellowInteger.getClassB());
+ assertEquals(String.class, yellowInteger.getA().getClassDirect());
+ assertEquals(Integer.class, yellowInteger.getB().getClassDirect());
+ }
+
+ public void test2() {
+ Red<String> redString = new Red<String>();
+ Red<Integer> redInteger = new Red<Integer>();
+ Red<String>.Yellow<Integer> yellowInteger =
+ redString.new Yellow<Integer>(redInteger) {};
+ assertEquals(Integer.class, yellowInteger.getClassA());
+ assertEquals(Integer.class, yellowInteger.getClassB());
+ }
+
+ private static <T> Type staticMethodWithLocalClass() {
+ class MyLocalClass {
+ Type getType() {
+ return new TypeToken<T>(getClass()) {}.getType();
+ }
+ }
+ return new MyLocalClass().getType();
+ }
+
+ public void testLocalClassInsideStaticMethod() {
+ assertNotNull(staticMethodWithLocalClass());
+ }
+
+ public void testLocalClassInsideNonStaticMethod() {
+ class MyLocalClass<T> {
+ Type getType() {
+ return new TypeToken<T>(getClass()) {}.getType();
+ }
+ }
+ assertNotNull(new MyLocalClass<String>().getType());
+ }
+
+ private static <T> Type staticMethodWithAnonymousClass() {
+ return new Object() {
+ Type getType() {
+ return new TypeToken<T>(getClass()) {}.getType();
+ }
+ }.getType();
+ }
+
+ public void testAnonymousClassInsideStaticMethod() {
+ assertNotNull(staticMethodWithAnonymousClass());
+ }
+
+ public void testAnonymousClassInsideNonStaticMethod() {
+ assertNotNull(new Object() {
+ Type getType() {
+ return new TypeToken<Object>() {}.getType();
+ }
+ }.getType());
+ }
+
+ public void testStaticContext() {
+ assertEquals(Map.class, mapType().getRawType());
+ }
+
+ private abstract static class Holder<T> {
+ Type getContentType() {
+ return new TypeToken<T>(getClass()) {}.getType();
+ }
+ }
+
+ public void testResolvePrimitiveArrayType() {
+ assertEquals(new TypeToken<int[]>() {}.getType(),
+ new Holder<int[]>() {}.getContentType());
+ assertEquals(new TypeToken<int[][]> () {}.getType(),
+ new Holder<int[][]>() {}.getContentType());
+ }
+
+ public void testResolveToGenericArrayType() {
+ GenericArrayType arrayType = (GenericArrayType)
+ new Holder<List<int[][]>[]>() {}.getContentType();
+ ParameterizedType listType = (ParameterizedType)
+ arrayType.getGenericComponentType();
+ assertEquals(List.class, listType.getRawType());
+ assertEquals(Types.newArrayType(int[].class),
+ listType.getActualTypeArguments()[0]);
+ }
+
+ private abstract class WithGenericBound<A> {
+
+ @SuppressWarnings("unused")
+ public <B extends A> void withTypeVariable(List<B> list) {}
+
+ @SuppressWarnings("unused")
+ public <E extends Enum<E>> void withRecursiveBound(List<E> list) {}
+
+ @SuppressWarnings("unused")
+ public <K extends List<V>, V extends List<K>> void withMutualRecursiveBound(
+ List<Map<K, V>> list) {}
+
+ @SuppressWarnings("unused")
+ void withWildcardLowerBound(List<? super A> list) {}
+
+ @SuppressWarnings("unused")
+ void withWildcardUpperBound(List<? extends A> list) {}
+
+ Type getTargetType(String methodName) throws Exception {
+ ParameterizedType parameterType = (ParameterizedType)
+ WithGenericBound.class.getDeclaredMethod(methodName, List.class)
+ .getGenericParameterTypes()[0];
+ parameterType = (ParameterizedType)
+ TypeToken.of(this.getClass()).resolveType(parameterType).getType();
+ return parameterType.getActualTypeArguments()[0];
+ }
+ }
+
+ public void testWithGenericBoundInTypeVariable() throws Exception {
+ TypeVariable<?> typeVariable = (TypeVariable<?>)
+ new WithGenericBound<String>() {}.getTargetType("withTypeVariable");
+ assertEquals(String.class, typeVariable.getBounds()[0]);
+ }
+
+ public void testWithRecursiveBoundInTypeVariable() throws Exception {
+ TypeVariable<?> typeVariable = (TypeVariable<?>)
+ new WithGenericBound<String>() {}.getTargetType("withRecursiveBound");
+ assertEquals(Types.newParameterizedType(Enum.class, typeVariable),
+ typeVariable.getBounds()[0]);
+ }
+
+ public void testWithMutualRecursiveBoundInTypeVariable() throws Exception {
+ ParameterizedType paramType = (ParameterizedType)
+ new WithGenericBound<String>() {}
+ .getTargetType("withMutualRecursiveBound");
+ TypeVariable<?> k = (TypeVariable<?>) paramType.getActualTypeArguments()[0];
+ TypeVariable<?> v = (TypeVariable<?>) paramType.getActualTypeArguments()[1];
+ assertEquals(Types.newParameterizedType(List.class, v), k.getBounds()[0]);
+ assertEquals(Types.newParameterizedType(List.class, k), v.getBounds()[0]);
+ }
+
+ public void testWithGenericLowerBoundInWildcard() throws Exception {
+ WildcardType wildcardType = (WildcardType)
+ new WithGenericBound<String>() {}
+ .getTargetType("withWildcardLowerBound");
+ assertEquals(String.class, wildcardType.getLowerBounds()[0]);
+ }
+
+ public void testWithGenericUpperBoundInWildcard() throws Exception {
+ WildcardType wildcardType = (WildcardType)
+ new WithGenericBound<String>() {}
+ .getTargetType("withWildcardUpperBound");
+ assertEquals(String.class, wildcardType.getUpperBounds()[0]);
+ }
+
+ public void testInterfaceTypeParameterResolution() throws Exception {
+ assertEquals(String.class,
+ TypeToken.of(new TypeToken<ArrayList<String>>() {}.getType())
+ .resolveType(List.class.getTypeParameters()[0]).getType());
+ }
+
+ private static TypeToken<Map<Object, Object>> mapType() {
+ return new TypeToken<Map<Object, Object>>() {};
+ }
+
+ // Looks like recursive, but legit.
+ private interface WithFalseRecursiveType<K, V> {
+ WithFalseRecursiveType<List<V>, String> keyShouldNotResolveToStringList();
+ WithFalseRecursiveType<List<K>, List<V>> shouldNotCauseInfiniteLoop();
+ SubTypeOfWithFalseRecursiveType<List<V>, List<K>> evenSubTypeWorks();
+ }
+
+ private interface SubTypeOfWithFalseRecursiveType<K1, V1>
+ extends WithFalseRecursiveType<List<K1>, List<V1>> {
+ SubTypeOfWithFalseRecursiveType<V1, K1> revertKeyAndValueTypes();
+ }
+
+ public void testFalseRecursiveType_mappingOnTheSameDeclarationNotUsed() {
+ Type returnType = genericReturnType(
+ WithFalseRecursiveType.class, "keyShouldNotResolveToStringList");
+ TypeToken<?> keyType = TypeToken.of(returnType)
+ .resolveType(WithFalseRecursiveType.class.getTypeParameters()[0]);
+ assertEquals("java.util.List<V>", keyType.getType().toString());
+ }
+
+ public void testFalseRecursiveType_notRealRecursiveMapping() {
+ Type returnType = genericReturnType(
+ WithFalseRecursiveType.class, "shouldNotCauseInfiniteLoop");
+ TypeToken<?> keyType = TypeToken.of(returnType)
+ .resolveType(WithFalseRecursiveType.class.getTypeParameters()[0]);
+ assertEquals("java.util.List<K>", keyType.getType().toString());
+ }
+
+ public void testFalseRecursiveType_referenceOfSubtypeDoesNotConfuseMe() {
+ Type returnType = genericReturnType(
+ WithFalseRecursiveType.class, "evenSubTypeWorks");
+ TypeToken<?> keyType = TypeToken.of(returnType)
+ .resolveType(WithFalseRecursiveType.class.getTypeParameters()[0]);
+ assertEquals("java.util.List<java.util.List<V>>", keyType.getType().toString());
+ }
+
+ public void testFalseRecursiveType_intermediaryTypeMappingDoesNotConfuseMe() {
+ Type returnType = genericReturnType(
+ SubTypeOfWithFalseRecursiveType.class, "revertKeyAndValueTypes");
+ TypeToken<?> keyType = TypeToken.of(returnType)
+ .resolveType(WithFalseRecursiveType.class.getTypeParameters()[0]);
+ assertEquals("java.util.List<K1>", keyType.getType().toString());
+ }
+
+ private static Type genericReturnType(Class<?> cls, String methodName) {
+ try {
+ return cls.getMethod(methodName).getGenericReturnType();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/TypeTokenTest.java b/guava-tests/test/com/google/common/reflect/TypeTokenTest.java
new file mode 100644
index 0000000..1f8ceea
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/TypeTokenTest.java
@@ -0,0 +1,1517 @@
+/*
+ * Copyright (C) 2007 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
+import com.google.common.testing.SerializableTester;
+
+import junit.framework.TestCase;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Test cases for {@link TypeToken}.
+ *
+ * @author Sven Mawson
+ * @author Ben Yu
+ */
+public class TypeTokenTest extends TestCase {
+
+ private abstract static class StringList implements List<String> {}
+
+ private abstract static class IntegerList implements List<Integer> {}
+
+ public void testValueEqualityNotInstanceEquality() {
+ TypeToken<List<String>> a = new TypeToken<List<String>>() {};
+ TypeToken<List<String>> b = new TypeToken<List<String>>() {};
+ assertEquals(a, b);
+ }
+
+ public <T> void testVariableTypeTokenNotAllowed() {
+ try {
+ new TypeToken<T>() {};
+ fail();
+ } catch (IllegalStateException expected) {}
+ }
+
+ public void testRawTypeIsCorrect() {
+ TypeToken<List<String>> token = new TypeToken<List<String>>() {};
+ assertEquals(List.class, token.getRawType());
+ }
+
+ public void testTypeIsCorrect() {
+ TypeToken<List<String>> token = new TypeToken<List<String>>() {};
+ assertEquals(StringList.class.getGenericInterfaces()[0], token.getType());
+ }
+
+ public void testGetClass() {
+ TypeToken<List> token = TypeToken.of(List.class);
+ assertEquals(new TypeToken<List>() {}, token);
+ }
+
+ public void testGetType() {
+ TypeToken<?> t = TypeToken.of(StringList.class.getGenericInterfaces()[0]);
+ assertEquals(new TypeToken<List<String>>() {}, t);
+ }
+
+ public void testNonStaticLocalClass() {
+ class Local<T> {}
+ TypeToken<Local<String>> type = new TypeToken<Local<String>>() {};
+ assertEquals(Types.newParameterizedType(Local.class, String.class),
+ type.getType());
+ assertEquals(new Local<String>() {}.getClass().getGenericSuperclass(), type.getType());
+ }
+
+ public void testStaticLocalClass() {
+ doTestStaticLocalClass();
+ }
+
+ private static void doTestStaticLocalClass() {
+ class Local<T> {}
+ TypeToken<Local<String>> type = new TypeToken<Local<String>>() {};
+ assertEquals(Types.newParameterizedType(Local.class, String.class),
+ type.getType());
+ assertEquals(new Local<String>() {}.getClass().getGenericSuperclass(), type.getType());
+ }
+
+ public void testGenericArrayType() throws Exception {
+ TypeToken<List<String>[]> token = new TypeToken<List<String>[]>() {};
+ assertEquals(List[].class, token.getRawType());
+ assertTrue(token.getType() instanceof GenericArrayType);
+ }
+
+ public void testMultiDimensionalGenericArrayType() throws Exception {
+ TypeToken<List<Long>[][][]> token = new TypeToken<List<Long>[][][]>() {};
+ assertEquals(List[][][].class, token.getRawType());
+ assertTrue(token.getType() instanceof GenericArrayType);
+ }
+
+ public <T> void testGenericVariableTypeArrays() throws Exception {
+ assertEquals("T[]", new TypeToken<T[]>() {}.toString());
+ }
+
+ public void testResolveType() throws Exception {
+ Method getFromList = List.class.getMethod("get", int.class);
+ TypeToken<?> returnType = new TypeToken<List<String>>() {}
+ .resolveType(getFromList.getGenericReturnType());
+ assertEquals(String.class, returnType.getType());
+ }
+
+ public <F extends Enum<F> & Function<String, Integer> & Iterable<Long>>
+ void testResolveType_fromTypeVariable() throws Exception {
+ TypeToken<?> f = TypeToken.of(new TypeCapture<F>() {}.capture());
+ assertEquals(String.class,
+ f.resolveType(Function.class.getTypeParameters()[0]).getType());
+ assertEquals(Integer.class,
+ f.resolveType(Function.class.getTypeParameters()[1]).getType());
+ assertEquals(Long.class,
+ f.resolveType(Iterable.class.getTypeParameters()[0]).getType());
+ }
+
+ public <E extends Comparable<Iterable<String>> & Iterable<Integer>>
+ void testResolveType_fromTypeVariable_onlyDirectBoundsAreUsed() throws Exception {
+ TypeToken<?> e = TypeToken.of(new TypeCapture<E>() {}.capture());
+ assertEquals(Integer.class,
+ e.resolveType(Iterable.class.getTypeParameters()[0]).getType());
+ }
+
+ public void testResolveType_fromWildcard() throws Exception {
+ ParameterizedType withWildcardType = (ParameterizedType)
+ new TypeCapture<Comparable<? extends Iterable<String>>>() {}.capture();
+ TypeToken<?> wildcardType = TypeToken.of(withWildcardType.getActualTypeArguments()[0]);
+ assertEquals(String.class,
+ wildcardType.resolveType(Iterable.class.getTypeParameters()[0]).getType());
+ }
+
+ public void testGetTypes_noSuperclass() {
+ TypeToken<Object>.TypeSet types = new TypeToken<Object>() {}.getTypes();
+ ASSERT.that(types).has().item(TypeToken.of(Object.class));
+ ASSERT.that(types.rawTypes()).has().item(Object.class);
+ ASSERT.that(types.interfaces()).isEmpty();
+ ASSERT.that(types.interfaces().rawTypes()).isEmpty();
+ ASSERT.that(types.classes()).has().item(TypeToken.of(Object.class));
+ ASSERT.that(types.classes().rawTypes()).has().item(Object.class);
+ }
+
+ public void testGetTypes_fromInterface() {
+ TypeToken<Interface1>.TypeSet types = new TypeToken<Interface1>() {}.getTypes();
+ ASSERT.that(types).has().item(TypeToken.of(Interface1.class));
+ ASSERT.that(types.rawTypes()).has().item(Interface1.class);
+ ASSERT.that(types.interfaces()).has().item(TypeToken.of(Interface1.class));
+ ASSERT.that(types.interfaces().rawTypes()).has().item(Interface1.class);
+ ASSERT.that(types.classes()).isEmpty();
+ ASSERT.that(types.classes().rawTypes()).isEmpty();
+ }
+
+ public void testGetTypes_fromPrimitive() {
+ TypeToken<Integer>.TypeSet types = TypeToken.of(int.class).getTypes();
+ ASSERT.that(types).has().item(TypeToken.of(int.class));
+ ASSERT.that(types.rawTypes()).has().item(int.class);
+ ASSERT.that(types.interfaces()).isEmpty();
+ ASSERT.that(types.interfaces().rawTypes()).isEmpty();
+ ASSERT.that(types.classes()).has().item(TypeToken.of(int.class));
+ ASSERT.that(types.classes().rawTypes()).has().item(int.class);
+ }
+
+ public void testGetTypes_withInterfacesAndSuperclasses() {
+ abstract class Class2 extends Class1 implements Interface12 {}
+ abstract class Class3<T> extends Class2 implements Interface3<T> {}
+ TypeToken<Class3<String>>.TypeSet types = new TypeToken<Class3<String>>() {}.getTypes();
+ ASSERT.that(types).has().allOf(
+ new TypeToken<Class3<String>>() {},
+ new TypeToken<Interface3<String>>() {},
+ new TypeToken<Iterable<String>>() {},
+ TypeToken.of(Class2.class),
+ TypeToken.of(Interface12.class),
+ TypeToken.of(Interface1.class),
+ TypeToken.of(Interface2.class),
+ TypeToken.of(Class1.class),
+ TypeToken.of(Object.class));
+ ASSERT.that(types.interfaces()).has().allOf(
+ new TypeToken<Interface3<String>>() {},
+ TypeToken.of(Interface12.class),
+ TypeToken.of(Interface1.class),
+ TypeToken.of(Interface2.class),
+ new TypeToken<Iterable<String>>() {});
+ ASSERT.that(types.classes()).has().allOf(
+ new TypeToken<Class3<String>>() {},
+ TypeToken.of(Class2.class),
+ TypeToken.of(Class1.class),
+ TypeToken.of(Object.class));
+ assertSubtypeFirst(types);
+ }
+
+ public void testGetTypes_rawTypes_withInterfacesAndSuperclasses() {
+ abstract class Class2 extends Class1 implements Interface12 {}
+ abstract class Class3<T> extends Class2 implements Interface3<T> {}
+ TypeToken<Class3<String>>.TypeSet types = new TypeToken<Class3<String>>() {}.getTypes();
+ ASSERT.that(types.rawTypes()).has().allOf(
+ Class3.class, Interface3.class,
+ Iterable.class,
+ Class2.class,
+ Interface12.class,
+ Interface1.class,
+ Interface2.class,
+ Class1.class,
+ Object.class);
+ ASSERT.that(types.interfaces().rawTypes()).has().allOf(
+ Interface3.class,
+ Interface12.class,
+ Interface1.class,
+ Interface2.class,
+ Iterable.class);
+ ASSERT.that(types.classes().rawTypes()).has().allOf(
+ Class3.class,
+ Class2.class,
+ Class1.class,
+ Object.class);
+ assertSubtypeFirst(types);
+ }
+
+ public <A extends Class1 & Interface1, B extends A>
+ void testGetTypes_ignoresTypeVariablesByDefault() {
+ TypeToken.TypeSet types = TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes();
+ ASSERT.that(types).has().allOf(
+ TypeToken.of(Interface1.class), TypeToken.of(Class1.class),
+ TypeToken.of(Object.class));
+ assertSubtypeFirst(types);
+ ASSERT.that(types.interfaces()).has().allOf(
+ TypeToken.of(Interface1.class)).inOrder();
+ ASSERT.that(types.classes()).has().allOf(
+ TypeToken.of(Class1.class), TypeToken.of(Object.class)).inOrder();
+ }
+
+ public <A extends Class1 & Interface1, B extends A>
+ void testGetTypes_rawTypes_ignoresTypeVariablesByDefault() {
+ TypeToken.TypeSet types = TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes();
+ ASSERT.that(types.rawTypes()).has().allOf(
+ Interface1.class, Class1.class,
+ Object.class);
+ ASSERT.that(types.interfaces().rawTypes()).has().allOf(
+ Interface1.class).inOrder();
+ ASSERT.that(types.classes().rawTypes()).has().allOf(
+ Class1.class, Object.class).inOrder();
+ }
+
+ public <A extends Interface1 & Interface2 & Interface3<String>>
+ void testGetTypes_manyBounds() {
+ TypeToken.TypeSet types = TypeToken.of(new TypeCapture<A>() {}.capture()).getTypes();
+ ASSERT.that(types.rawTypes()).has().allOf(
+ Interface1.class, Interface2.class, Interface3.class, Iterable.class);
+ }
+
+ private static void assertSubtypeFirst(TypeToken<?>.TypeSet types) {
+ assertSubtypeTokenBeforeSupertypeToken(types);
+ assertSubtypeTokenBeforeSupertypeToken(types.interfaces());
+ assertSubtypeTokenBeforeSupertypeToken(types.classes());
+ assertSubtypeBeforeSupertype(types.rawTypes());
+ assertSubtypeBeforeSupertype(types.interfaces().rawTypes());
+ assertSubtypeBeforeSupertype(types.classes().rawTypes());
+ }
+
+ private static void assertSubtypeTokenBeforeSupertypeToken(
+ Iterable<? extends TypeToken<?>> types) {
+ int i = 0;
+ for (TypeToken<?> left : types) {
+ int j = 0;
+ for (TypeToken<?> right : types) {
+ if (left.isAssignableFrom(right)) {
+ assertTrue(left + " should be after " + right, i >= j);
+ }
+ j++;
+ }
+ i++;
+ }
+ }
+
+ private static void assertSubtypeBeforeSupertype(Iterable<? extends Class<?>> types) {
+ int i = 0;
+ for (Class<?> left : types) {
+ int j = 0;
+ for (Class<?> right : types) {
+ if (left.isAssignableFrom(right)) {
+ assertTrue(left + " should be after " + right, i >= j);
+ }
+ j++;
+ }
+ i++;
+ }
+ }
+
+ // Tests to make sure assertSubtypeBeforeSupertype() works.
+
+ public void testAssertSubtypeTokenBeforeSupertypeToken_empty() {
+ assertSubtypeTokenBeforeSupertypeToken(ImmutableList.<TypeToken<?>>of());
+ }
+
+ public void testAssertSubtypeTokenBeforeSupertypeToken_oneType() {
+ assertSubtypeTokenBeforeSupertypeToken(ImmutableList.of(TypeToken.of(String.class)));
+ }
+
+ public void testAssertSubtypeTokenBeforeSupertypeToken_subtypeFirst() {
+ assertSubtypeTokenBeforeSupertypeToken(
+ ImmutableList.of(TypeToken.of(String.class), TypeToken.of(CharSequence.class)));
+ }
+
+ public void testAssertSubtypeTokenBeforeSupertypeToken_supertypeFirst() {
+ try {
+ assertSubtypeTokenBeforeSupertypeToken(
+ ImmutableList.of(TypeToken.of(CharSequence.class), TypeToken.of(String.class)));
+ } catch (AssertionError expected) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertSubtypeTokenBeforeSupertypeToken_duplicate() {
+ try {
+ assertSubtypeTokenBeforeSupertypeToken(
+ ImmutableList.of(TypeToken.of(String.class), TypeToken.of(String.class)));
+ } catch (AssertionError expected) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertSubtypeBeforeSupertype_empty() {
+ assertSubtypeBeforeSupertype(ImmutableList.<Class<?>>of());
+ }
+
+ public void testAssertSubtypeBeforeSupertype_oneType() {
+ assertSubtypeBeforeSupertype(ImmutableList.of(String.class));
+ }
+
+ public void testAssertSubtypeBeforeSupertype_subtypeFirst() {
+ assertSubtypeBeforeSupertype(
+ ImmutableList.of(String.class, CharSequence.class));
+ }
+
+ public void testAssertSubtypeBeforeSupertype_supertypeFirst() {
+ try {
+ assertSubtypeBeforeSupertype(
+ ImmutableList.of(CharSequence.class, String.class));
+ } catch (AssertionError expected) {
+ return;
+ }
+ fail();
+ }
+
+ public void testAssertSubtypeBeforeSupertype_duplicate() {
+ try {
+ assertSubtypeBeforeSupertype(
+ ImmutableList.of(String.class, String.class));
+ } catch (AssertionError expected) {
+ return;
+ }
+ fail();
+ }
+
+ public void testGetGenericSuperclass_noSuperclass() {
+ assertNull(new TypeToken<Object>() {}.getGenericSuperclass());
+ assertEquals(TypeToken.of(Object.class),
+ new TypeToken<Object[]>() {}.getGenericSuperclass());
+ assertNull(new TypeToken<List<String>>() {}.getGenericSuperclass());
+ assertEquals(TypeToken.of(Object.class),
+ new TypeToken<List<String>[]>() {}.getGenericSuperclass());
+ }
+
+ public void testGetGenericSuperclass_withSuperclass() {
+ TypeToken<? super ArrayList<String>> superToken =
+ new TypeToken<ArrayList<String>>() {}.getGenericSuperclass();
+ assertEquals(ArrayList.class.getSuperclass(), superToken.getRawType());
+ assertEquals(String.class,
+ ((ParameterizedType) superToken.getType()).getActualTypeArguments()[0]);
+ assertEquals(TypeToken.of(Base.class), TypeToken.of(Sub.class).getGenericSuperclass());
+ assertEquals(TypeToken.of(Object.class), TypeToken.of(Sub[].class).getGenericSuperclass());
+ }
+
+ public <T> void testGetGenericSuperclass_typeVariable_unbounded() {
+ assertEquals(TypeToken.of(Object.class),
+ TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
+ assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
+ }
+
+ public <T extends ArrayList<String> & CharSequence>
+ void testGetGenericSuperclass_typeVariable_boundIsClass() {
+ assertEquals(new TypeToken<ArrayList<String>>() {},
+ TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
+ assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
+ }
+
+ public <T extends Enum<T> & CharSequence>
+ void testGetGenericSuperclass_typeVariable_boundIsFBoundedClass() {
+ assertEquals(new TypeToken<Enum<T>>() {},
+ TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
+ assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
+ }
+
+ public <T extends List<String> & CharSequence>
+ void testGetGenericSuperclass_typeVariable_boundIsInterface() {
+ assertNull(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericSuperclass());
+ assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
+ }
+
+ public <T extends ArrayList<String> & CharSequence, T1 extends T>
+ void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndClass() {
+ assertEquals(TypeToken.of(new TypeCapture<T>() {}.capture()),
+ TypeToken.of(new TypeCapture<T1>() {}.capture()).getGenericSuperclass());
+ assertEquals(TypeToken.of(Object.class), new TypeToken<T[]>() {}.getGenericSuperclass());
+ }
+
+ public <T extends List<String> & CharSequence, T1 extends T>
+ void testGetGenericSuperclass_typeVariable_boundIsTypeVariableAndInterface() {
+ assertNull(TypeToken.of(new TypeCapture<T1>() {}.capture()).getGenericSuperclass());
+ assertEquals(TypeToken.of(Object.class), new TypeToken<T1[]>() {}.getGenericSuperclass());
+ }
+
+ public void testGetGenericSuperclass_wildcard_lowerBounded() {
+ assertEquals(TypeToken.of(Object.class),
+ TypeToken.of(Types.supertypeOf(String.class)).getGenericSuperclass());
+ assertEquals(new TypeToken<Object>() {},
+ TypeToken.of(Types.supertypeOf(String[].class)).getGenericSuperclass());
+ assertEquals(new TypeToken<Object>() {},
+ TypeToken.of(Types.supertypeOf(CharSequence.class)).getGenericSuperclass());
+ }
+
+ public void testGetGenericSuperclass_wildcard_boundIsClass() {
+ assertEquals(TypeToken.of(Object.class),
+ TypeToken.of(Types.subtypeOf(Object.class)).getGenericSuperclass());
+ assertEquals(new TypeToken<Object[]>() {},
+ TypeToken.of(Types.subtypeOf(Object[].class)).getGenericSuperclass());
+ }
+
+ public void testGetGenericSuperclass_wildcard_boundIsInterface() {
+ assertNull(TypeToken.of(Types.subtypeOf(CharSequence.class)).getGenericSuperclass());
+ assertEquals(new TypeToken<CharSequence[]>() {},
+ TypeToken.of(Types.subtypeOf(CharSequence[].class)).getGenericSuperclass());
+ }
+
+ public <T> void testGetGenericInterfaces_typeVariable_unbounded() {
+ ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
+ .isEmpty();
+ assertHasArrayInterfaces(new TypeToken<T[]>() {});
+ }
+
+ public <T extends NoInterface> void testGetGenericInterfaces_typeVariable_boundIsClass() {
+ ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
+ .isEmpty();
+ assertHasArrayInterfaces(new TypeToken<T[]>() {});
+ }
+
+ public <T extends NoInterface&Iterable<String>>
+ void testGetGenericInterfaces_typeVariable_boundsAreClassWithInterface() {
+ ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
+ .iteratesOverSequence(new TypeToken<Iterable<String>>() {});
+ assertHasArrayInterfaces(new TypeToken<T[]>() {});
+ }
+
+ public <T extends CharSequence&Iterable<String>>
+ void testGetGenericInterfaces_typeVariable_boundsAreInterfaces() {
+ ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
+ .iteratesOverSequence(
+ TypeToken.of(CharSequence.class), new TypeToken<Iterable<String>>() {});
+ assertHasArrayInterfaces(new TypeToken<T[]>() {});
+ }
+
+ public <T extends CharSequence&Iterable<T>>
+ void testGetGenericInterfaces_typeVariable_boundsAreFBoundedInterfaces() {
+ ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
+ .iteratesOverSequence(TypeToken.of(CharSequence.class), new TypeToken<Iterable<T>>() {});
+ assertHasArrayInterfaces(new TypeToken<T[]>() {});
+ }
+
+ public <T extends Base&Iterable<T>>
+ void testGetGenericInterfaces_typeVariable_boundsAreClassWithFBoundedInterface() {
+ ASSERT.that(TypeToken.of(new TypeCapture<T>() {}.capture()).getGenericInterfaces())
+ .iteratesOverSequence(new TypeToken<Iterable<T>>() {});
+ assertHasArrayInterfaces(new TypeToken<T[]>() {});
+ }
+
+ public <T extends NoInterface, T1 extends T, T2 extends T1>
+ void testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndClass() {
+ ASSERT.that(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces())
+ .isEmpty();
+ assertHasArrayInterfaces(new TypeToken<T2[]>() {});
+ }
+
+ public <T extends Iterable<T>, T1 extends T, T2 extends T1>
+ void testGetGenericInterfaces_typeVariable_boundIsTypeVariableAndInterface() {
+ ASSERT.that(TypeToken.of(new TypeCapture<T2>() {}.capture()).getGenericInterfaces())
+ .iteratesOverSequence(TypeToken.of(new TypeCapture<T1>() {}.capture()));
+ assertHasArrayInterfaces(new TypeToken<T2[]>() {});
+ }
+
+ public void testGetGenericInterfaces_wildcard_lowerBounded() {
+ ASSERT.that(TypeToken.of(Types.supertypeOf(String.class)).getGenericInterfaces())
+ .isEmpty();
+ ASSERT.that(TypeToken.of(Types.supertypeOf(String[].class)).getGenericInterfaces())
+ .isEmpty();
+ }
+
+ public void testGetGenericInterfaces_wildcard_boundIsClass() {
+ ASSERT.that(TypeToken.of(Types.subtypeOf(Object.class)).getGenericInterfaces())
+ .isEmpty();
+ ASSERT.that(TypeToken.of(Types.subtypeOf(Object[].class)).getGenericInterfaces())
+ .isEmpty();
+ }
+
+ public void testGetGenericInterfaces_wildcard_boundIsInterface() {
+ TypeToken<Iterable<String>> interfaceType = new TypeToken<Iterable<String>>() {};
+ ASSERT.that(TypeToken.of(Types.subtypeOf(interfaceType.getType())).getGenericInterfaces())
+ .iteratesOverSequence(interfaceType);
+ assertHasArrayInterfaces(new TypeToken<Iterable<String>[]>() {});
+ }
+
+ public void testGetGenericInterfaces_noInterface() {
+ ASSERT.that(new TypeToken<NoInterface>() {}.getGenericInterfaces())
+ .isEmpty();
+ assertHasArrayInterfaces(new TypeToken<NoInterface[]>() {});
+ }
+
+ public void testGetGenericInterfaces_withInterfaces() {
+ Map<Class<?>, Type> interfaceMap = Maps.newHashMap();
+ for (TypeToken<?> interfaceType:
+ new TypeToken<Implementation<Integer, String>>() {}.getGenericInterfaces()) {
+ interfaceMap.put(interfaceType.getRawType(), interfaceType.getType());
+ }
+ assertEquals(ImmutableMap.of(
+ Iterable.class, new TypeToken<Iterable<String>>() {}.getType(),
+ Map.class, new TypeToken<Map<Integer, String>>() {}.getType()),
+ interfaceMap);
+ }
+
+ private interface Interface1 {}
+ private interface Interface2 {}
+ private interface Interface3<T> extends Iterable<T> {}
+ private interface Interface12 extends Interface1, Interface2 {}
+ private static class Class1 implements Interface1 {}
+
+ private static final class NoInterface {}
+
+ private abstract static class Implementation<K, V>
+ implements Iterable<V>, Map<K, V> {}
+
+ private abstract static class First<T> {}
+
+ private abstract static class Second<D> extends First<D> {}
+
+ private abstract static class Third<T, D> extends Second<T> {}
+
+ private abstract static class Fourth<T, D> extends Third<D, T> {}
+
+ private static class ConcreteIS extends Fourth<Integer, String> {}
+
+ private static class ConcreteSI extends Fourth<String, Integer> {}
+
+ public void testAssignableClassToClass() {
+ TypeToken<List> tokL = new TypeToken<List>() {};
+ assertTrue(tokL.isAssignableFrom(List.class));
+ assertTrue(tokL.isAssignableFrom(ArrayList.class));
+ assertFalse(tokL.isAssignableFrom(List[].class));
+
+ TypeToken<Number> tokN = new TypeToken<Number>() {};
+ assertTrue(tokN.isAssignableFrom(Number.class));
+ assertTrue(tokN.isAssignableFrom(Integer.class));
+ }
+
+ public <T> void testAssignableParameterizedTypeToObject() {
+ assertTrue(TypeToken.of(Object.class).isAssignableFrom(
+ TypeToken.of(new TypeCapture<T>() {}.capture())));
+ assertFalse(TypeToken.of(int.class).isAssignableFrom(
+ TypeToken.of(new TypeCapture<T>() {}.capture())));
+ }
+
+ public <T, T1 extends T> void testAssignableGenericArrayToGenericArray() {
+ assertTrue(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T[]>() {}));
+ assertTrue(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T1[]>() {}));
+ assertFalse(new TypeToken<T[]>() {}.isAssignableFrom(new TypeToken<T[][]>() {}));
+ }
+
+ public void testAssignableWildcardBoundedByArrayToArrayClass() throws Exception {
+ Type wildcardType = Types.subtypeOf(Object[].class);
+ assertTrue(TypeToken.of(Object[].class).isAssignableFrom(wildcardType));
+ assertTrue(TypeToken.of(Object.class).isAssignableFrom(wildcardType));
+ assertTrue(TypeToken.of(wildcardType).isAssignableFrom(wildcardType));
+ assertFalse(TypeToken.of(int[].class).isAssignableFrom(wildcardType));
+ }
+
+ public void testAssignableArrayClassToBoundedWildcard() throws Exception {
+ TypeToken<?> upperBounded = TypeToken.of(Types.subtypeOf(Object[].class));
+ TypeToken<?> lowerBounded = TypeToken.of(Types.supertypeOf(Object[].class));
+ assertTrue(upperBounded.isAssignableFrom(Object[].class));
+ assertTrue(upperBounded.isAssignableFrom(Object[][].class));
+ assertTrue(upperBounded.isAssignableFrom(String[].class));
+ assertTrue(lowerBounded.isAssignableFrom(Object[].class));
+ assertTrue(lowerBounded.isAssignableFrom(Object.class));
+ assertFalse(lowerBounded.isAssignableFrom(Object[][].class));
+ assertFalse(lowerBounded.isAssignableFrom(String[].class));
+ }
+
+ public void testAssignableWildcardBoundedByIntArrayToArrayClass() throws Exception {
+ Type wildcardType = Types.subtypeOf(int[].class);
+ assertTrue(TypeToken.of(int[].class).isAssignableFrom(wildcardType));
+ assertTrue(TypeToken.of(Object.class).isAssignableFrom(wildcardType));
+ assertTrue(TypeToken.of(wildcardType).isAssignableFrom(wildcardType));
+ assertFalse(TypeToken.of(Object[].class).isAssignableFrom(wildcardType));
+ }
+
+ public void testAssignableWildcardToWildcard() throws Exception {
+ TypeToken<?> upperBounded = TypeToken.of(Types.subtypeOf(Object[].class));
+ TypeToken<?> lowerBounded = TypeToken.of(Types.supertypeOf(Object[].class));
+ assertFalse(lowerBounded.isAssignableFrom(upperBounded));
+ assertTrue(lowerBounded.isAssignableFrom(lowerBounded));
+ assertTrue(upperBounded.isAssignableFrom(upperBounded));
+ assertFalse(upperBounded.isAssignableFrom(lowerBounded));
+ }
+
+ public <T> void testAssignableGenericArrayToArrayClass() {
+ assertTrue(TypeToken.of(Object[].class).isAssignableFrom(new TypeToken<T[]>() {}));
+ assertTrue(TypeToken.of(Object[].class).isAssignableFrom(new TypeToken<T[][]>() {}));
+ assertTrue(TypeToken.of(Object[][].class).isAssignableFrom(new TypeToken<T[][]>() {}));
+ }
+
+ public void testAssignableParameterizedTypeToClass() {
+ TypeToken<List> tokL = new TypeToken<List>() {};
+ assertTrue(tokL.isAssignableFrom(StringList.class));
+ assertTrue(tokL.isAssignableFrom(
+ StringList.class.getGenericInterfaces()[0]));
+
+ TypeToken<Second> tokS = new TypeToken<Second>() {};
+ assertTrue(tokS.isAssignableFrom(Second.class));
+ assertTrue(tokS.isAssignableFrom(Third.class.getGenericSuperclass()));
+ }
+
+ public void testAssignableArrayToClass() throws Exception {
+ TypeToken<List[]> tokL = new TypeToken<List[]>() {};
+ assertTrue(tokL.isAssignableFrom(List[].class));
+ assertFalse(tokL.isAssignableFrom(List.class));
+
+ TypeToken<Second[]> tokS = new TypeToken<Second[]>() {};
+ assertTrue(tokS.isAssignableFrom(Second[].class));
+ assertTrue(tokS.isAssignableFrom(Third[].class));
+ }
+
+ public void testAssignableTokenToClass() {
+ TypeToken<List> tokL = new TypeToken<List>() {};
+ assertTrue(tokL.isAssignableFrom(new TypeToken<List>() {}));
+ assertTrue(tokL.isAssignableFrom(new TypeToken<List<String>>() {}));
+ assertTrue(tokL.isAssignableFrom(new TypeToken<List<?>>() {}));
+
+ TypeToken<Second> tokS = new TypeToken<Second>() {};
+ assertTrue(tokS.isAssignableFrom(new TypeToken<Second>() {}));
+ assertTrue(tokS.isAssignableFrom(new TypeToken<Third>() {}));
+ assertTrue(tokS.isAssignableFrom(
+ new TypeToken<Third<String, Integer>>() {}));
+
+ TypeToken<List[]> tokA = new TypeToken<List[]>() {};
+ assertTrue(tokA.isAssignableFrom(new TypeToken<List[]>() {}));
+ assertTrue(tokA.isAssignableFrom(new TypeToken<List<String>[]>() {}));
+ assertTrue(tokA.isAssignableFrom(new TypeToken<List<?>[]>() {}));
+ }
+
+ public void testAssignableClassToType() {
+ TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
+ assertTrue(tokenL.isAssignableFrom(StringList.class));
+ assertFalse(tokenL.isAssignableFrom(List.class));
+
+ TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
+ assertTrue(tokenF.isAssignableFrom(ConcreteIS.class));
+ assertFalse(tokenF.isAssignableFrom(ConcreteSI.class));
+ }
+
+ public void testAssignableClassToArrayType() {
+ TypeToken<List<String>[]> tokenL = new TypeToken<List<String>[]>() {};
+ assertTrue(tokenL.isAssignableFrom(StringList[].class));
+ assertFalse(tokenL.isAssignableFrom(List[].class));
+ }
+
+ public void testAssignableParameterizedTypeToType() {
+ TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
+ assertTrue(tokenL.isAssignableFrom(
+ StringList.class.getGenericInterfaces()[0]));
+ assertFalse(tokenL.isAssignableFrom(
+ IntegerList.class.getGenericInterfaces()[0]));
+
+ TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
+ assertTrue(tokenF.isAssignableFrom(
+ ConcreteIS.class.getGenericSuperclass()));
+ assertFalse(tokenF.isAssignableFrom(
+ ConcreteSI.class.getGenericSuperclass()));
+ }
+
+ public void testGenericArrayTypeToArrayType() throws Exception {
+ TypeToken<List<String>[]> tokL = new TypeToken<List<String>[]>() {};
+ TypeToken<ArrayList<String>[]> token =
+ new TypeToken<ArrayList<String>[]>() {};
+ assertTrue(tokL.isAssignableFrom(tokL.getType()));
+ assertTrue(tokL.isAssignableFrom(token.getType()));
+ }
+
+ public void testAssignableTokenToType() {
+ TypeToken<List<String>> tokenL = new TypeToken<List<String>>() {};
+ assertTrue(tokenL.isAssignableFrom(new TypeToken<List<String>>() {}));
+ assertTrue(tokenL.isAssignableFrom(new TypeToken<ArrayList<String>>() {}));
+ assertTrue(tokenL.isAssignableFrom(new TypeToken<StringList>() {}));
+
+ TypeToken<First<String>> tokenF = new TypeToken<First<String>>() {};
+ assertTrue(tokenF.isAssignableFrom(new TypeToken<Second<String>>() {}));
+ assertTrue(tokenF.isAssignableFrom(
+ new TypeToken<Third<String, Integer>>() {}));
+ assertFalse(tokenF.isAssignableFrom(
+ new TypeToken<Third<Integer, String>>() {}));
+ assertTrue(tokenF.isAssignableFrom(
+ new TypeToken<Fourth<Integer, String>>() {}));
+ assertFalse(tokenF.isAssignableFrom(
+ new TypeToken<Fourth<String, Integer>>() {}));
+ assertTrue(tokenF.isAssignableFrom(new TypeToken<ConcreteIS>() {}));
+ assertFalse(tokenF.isAssignableFrom(new TypeToken<ConcreteSI>() {}));
+ }
+
+ public void testAssignableWithWildcards() {
+ TypeToken<?> unboundedToken = new TypeToken<List<?>>() {};
+ TypeToken<?> upperBoundToken = new TypeToken<List<? extends Number>>() {};
+ TypeToken<?> lowerBoundToken = new TypeToken<List<? super Number>>() {};
+ TypeToken<?> concreteToken = new TypeToken<List<Number>>() {};
+ TypeToken<?> subtypeToken = new TypeToken<List<Integer>>() {};
+ TypeToken<?> supertypeToken = new TypeToken<List<Serializable>>() {};
+ List<TypeToken<?>> allTokens = ImmutableList.of(
+ unboundedToken, upperBoundToken, lowerBoundToken,
+ concreteToken, subtypeToken, supertypeToken);
+
+ for (TypeToken<?> typeToken : allTokens) {
+ assertTrue(typeToken.toString(), unboundedToken.isAssignableFrom(typeToken));
+ }
+
+ assertFalse(upperBoundToken.isAssignableFrom(unboundedToken));
+ assertTrue(upperBoundToken.isAssignableFrom(upperBoundToken));
+ assertFalse(upperBoundToken.isAssignableFrom(lowerBoundToken));
+ assertTrue(upperBoundToken.isAssignableFrom(concreteToken));
+ assertTrue(upperBoundToken.isAssignableFrom(subtypeToken));
+ assertFalse(upperBoundToken.isAssignableFrom(supertypeToken));
+
+ assertFalse(lowerBoundToken.isAssignableFrom(unboundedToken));
+ assertFalse(lowerBoundToken.isAssignableFrom(upperBoundToken));
+ assertTrue(lowerBoundToken.isAssignableFrom(lowerBoundToken));
+ assertTrue(lowerBoundToken.isAssignableFrom(concreteToken));
+ assertFalse(lowerBoundToken.isAssignableFrom(subtypeToken));
+ assertTrue(lowerBoundToken.isAssignableFrom(supertypeToken));
+
+ for (TypeToken<?> typeToken : allTokens) {
+ assertEquals(typeToken.toString(),
+ typeToken == concreteToken, concreteToken.isAssignableFrom(typeToken));
+ }
+
+ for (TypeToken<?> typeToken : allTokens) {
+ assertEquals(typeToken.toString(),
+ typeToken == subtypeToken, subtypeToken.isAssignableFrom(typeToken));
+ }
+
+ for (TypeToken<?> typeToken : allTokens) {
+ assertEquals(typeToken.toString(),
+ typeToken == supertypeToken, supertypeToken.isAssignableFrom(typeToken));
+ }
+ }
+
+ public <N1 extends Number, N2 extends Number, N11 extends N1>
+ void testIsAssignableFrom_typeVariable() {
+ assertAssignable(TypeToken.of(new TypeCapture<N1>() {}.capture()),
+ TypeToken.of(new TypeCapture<N1>() {}.capture()));
+ assertNotAssignable(new TypeToken<List<N11>>() {},
+ new TypeToken<List<N1>>() {});
+ assertNotAssignable(new TypeToken<Number>() {},
+ TypeToken.of(new TypeCapture<N1>() {}.capture()));
+ assertAssignable(TypeToken.of(new TypeCapture<N11>() {}.capture()),
+ TypeToken.of(new TypeCapture<N1>() {}.capture()));
+ assertNotAssignable(TypeToken.of(new TypeCapture<N2>() {}.capture()),
+ TypeToken.of(new TypeCapture<N1>() {}.capture()));
+ }
+
+ public <N1 extends Number, N2 extends Number, N11 extends N1>
+ void testIsAssignableFrom_equalWildcardTypes() {
+ assertAssignable(new TypeToken<List<? extends N1>>() {},
+ new TypeToken<List<? extends N1>>() {});
+ assertAssignable(new TypeToken<List<? super N1>>() {},
+ new TypeToken<List<? super N1>>() {});
+ assertAssignable(new TypeToken<List<? extends Number>>() {},
+ new TypeToken<List<? extends Number>>() {});
+ assertAssignable(new TypeToken<List<? super Number>>() {},
+ new TypeToken<List<? super Number>>() {});
+ }
+
+ public <N> void testIsAssignableFrom_wildcard_noBound() {
+ assertAssignable(new TypeToken<List<? super N>>() {},
+ new TypeToken<List<?>>() {});
+ assertAssignable(new TypeToken<List<N>>() {},
+ new TypeToken<List<?>>() {});
+ }
+
+ public <N1 extends Number, N2 extends Number, N11 extends N1>
+ void testIsAssignableFrom_wildcardType_upperBoundMatch() {
+ // ? extends T
+ assertAssignable(new TypeToken<List<N11>>() {},
+ new TypeToken<List<? extends N1>>() {});
+ assertNotAssignable(new TypeToken<List<N1>>() {},
+ new TypeToken<List<? extends N11>>() {});
+ assertNotAssignable(new TypeToken<List<Number>>() {},
+ new TypeToken<List<? extends N11>>() {});
+
+ // ? extends Number
+ assertAssignable(new TypeToken<List<N1>>() {},
+ new TypeToken<List<? extends Number>>() {});
+ assertAssignable(new TypeToken<ArrayList<N1>>() {},
+ new TypeToken<List<? extends Number>>() {});
+ assertAssignable(new TypeToken<List<? extends N11>>() {},
+ new TypeToken<List<? extends Number>>() {});
+ }
+
+ public <N1 extends Number, N2 extends Number, N11 extends N1>
+ void testIsAssignableFrom_wildcardType_lowerBoundMatch() {
+ // ? super T
+ assertAssignable(new TypeToken<List<N1>>() {},
+ new TypeToken<List<? super N11>>() {});
+ assertAssignable(new TypeToken<ArrayList<Number>>() {},
+ new TypeToken<List<? super N1>>() {});
+ assertNotAssignable(new TypeToken<ArrayList<? super N11>>() {},
+ new TypeToken<List<? super Number>>() {});
+ assertAssignable(new TypeToken<ArrayList<? super N1>>() {},
+ new TypeToken<List<? super N11>>() {});
+ assertAssignable(new TypeToken<ArrayList<? super Number>>() {},
+ new TypeToken<List<? super N11>>() {});
+
+ // ? super Number
+ assertNotAssignable(new TypeToken<ArrayList<N11>>() {},
+ new TypeToken<List<? super Number>>() {});
+ assertAssignable(new TypeToken<ArrayList<Number>>() {},
+ new TypeToken<List<? super Number>>() {});
+ assertAssignable(new TypeToken<ArrayList<Object>>() {},
+ new TypeToken<List<? super Number>>() {});
+ }
+
+ public <L extends List<R>, R extends List<L>>
+ void testIsAssignableFrom_recursiveTypeVariableBounds() {
+ assertAssignable(TypeToken.of(new TypeCapture<L>() {}.capture()),
+ TypeToken.of(new TypeCapture<L>() {}.capture()));
+ assertNotAssignable(TypeToken.of(new TypeCapture<R>() {}.capture()),
+ TypeToken.of(new TypeCapture<L>() {}.capture()));
+ assertAssignable(TypeToken.of(new TypeCapture<L>() {}.capture()),
+ new TypeToken<List<R>>() {});
+ }
+
+ public void testIsAssignableFrom_resolved() {
+ assertFalse(Assignability.of().isAssignable());
+ assertTrue(new Assignability<Integer, Integer>() {}.isAssignable());
+ assertTrue(new Assignability<Integer, Object>() {}.isAssignable());
+ assertFalse(new Assignability<Integer, String>() {}.isAssignable());
+ TypeTokenTest.<Number, Integer>assignabilityTestWithTypeVariables();
+ }
+
+ private static <N1 extends Number, N11 extends N1>
+ void assignabilityTestWithTypeVariables() {
+ assertTrue(new Assignability<N11, N1>() {}.isAssignable());
+ assertTrue(new Assignability<N11, Number>() {}.isAssignable());
+ assertFalse(new Assignability<Number, N11>() {}.isAssignable());
+ }
+
+ public void testIsArray_arrayClasses() {
+ assertTrue(TypeToken.of(Object[].class).isArray());
+ assertTrue(TypeToken.of(Object[][].class).isArray());
+ assertTrue(TypeToken.of(char[].class).isArray());
+ assertTrue(TypeToken.of(char[][].class).isArray());
+ assertTrue(TypeToken.of(byte[].class).isArray());
+ assertTrue(TypeToken.of(short[].class).isArray());
+ assertTrue(TypeToken.of(int[].class).isArray());
+ assertTrue(TypeToken.of(long[].class).isArray());
+ assertTrue(TypeToken.of(float[].class).isArray());
+ assertTrue(TypeToken.of(double[].class).isArray());
+ assertFalse(TypeToken.of(Object.class).isArray());
+ assertFalse(TypeToken.of(void.class).isArray());
+ }
+
+ public <T> void testIsArray_genericArrayClasses() {
+ assertFalse(TypeToken.of(new TypeCapture<T>() {}.capture()).isArray());
+ assertTrue(new TypeToken<T[]>() {}.isArray());
+ assertTrue(new TypeToken<T[][]>() {}.isArray());
+ }
+
+ public void testIsArray_wildcardType() throws Exception {
+ assertTrue(TypeToken.of(Types.subtypeOf(Object[].class)).isArray());
+ assertTrue(TypeToken.of(Types.subtypeOf(int[].class)).isArray());
+ assertFalse(TypeToken.of(Types.subtypeOf(Object.class)).isArray());
+ assertFalse(TypeToken.of(Types.supertypeOf(Object[].class)).isArray());
+ }
+
+ public void testGetComponentType_arrayClasses() {
+ assertEquals(Object.class, TypeToken.of(Object[].class).getComponentType().getType());
+ assertEquals(Object[].class, TypeToken.of(Object[][].class).getComponentType().getType());
+ assertEquals(char.class, TypeToken.of(char[].class).getComponentType().getType());
+ assertEquals(char[].class, TypeToken.of(char[][].class).getComponentType().getType());
+ assertEquals(byte.class, TypeToken.of(byte[].class).getComponentType().getType());
+ assertEquals(short.class, TypeToken.of(short[].class).getComponentType().getType());
+ assertEquals(int.class, TypeToken.of(int[].class).getComponentType().getType());
+ assertEquals(long.class, TypeToken.of(long[].class).getComponentType().getType());
+ assertEquals(float.class, TypeToken.of(float[].class).getComponentType().getType());
+ assertEquals(double.class, TypeToken.of(double[].class).getComponentType().getType());
+ assertNull(TypeToken.of(Object.class).getComponentType());
+ assertNull(TypeToken.of(void.class).getComponentType());
+ }
+
+ public <T> void testGetComponentType_genericArrayClasses() {
+ assertNull(TypeToken.of(new TypeCapture<T>() {}.capture()).getComponentType());
+ assertEquals(TypeToken.of(new TypeCapture<T>() {}.capture()),
+ new TypeToken<T[]>() {}.getComponentType());
+ assertEquals(new TypeToken<T[]>() {}, new TypeToken<T[][]>() {}.getComponentType());
+ }
+
+ public void testGetComponentType_wildcardType() throws Exception {
+ assertEquals(Types.subtypeOf(Object.class),
+ TypeToken.of(Types.subtypeOf(Object[].class)).getComponentType().getType());
+ assertEquals(Types.subtypeOf(Object[].class),
+ Types.newArrayType(
+ TypeToken.of(Types.subtypeOf(Object[].class)).getComponentType().getType()));
+ assertEquals(int.class,
+ TypeToken.of(Types.subtypeOf(int[].class)).getComponentType().getType());
+ assertNull(TypeToken.of(Types.subtypeOf(Object.class)).getComponentType());
+ assertNull(TypeToken.of(Types.supertypeOf(Object[].class)).getComponentType());
+ }
+
+ private interface NumberList<T extends Number> {}
+
+ public void testImplicitUpperBoundForWildcards() {
+ assertAssignable(
+ new TypeToken<NumberList<? extends Number>>() {},
+ new TypeToken<NumberList<?>>() {});
+ assertAssignable(
+ new TypeToken<NumberList<? super Integer>>() {},
+ new TypeToken<NumberList<?>>() {});
+ }
+
+ public <T extends Readable & Appendable> void testMultiBound() {
+ assertAssignable(new TypeToken<List<T>>() {},
+ new TypeToken<List<? extends Readable>>() {});
+ assertAssignable(new TypeToken<List<T>>() {},
+ new TypeToken<List<? extends Appendable>>() {});
+ }
+
+ public void testToGenericType() {
+ assertEquals(TypeToken.of(String.class), TypeToken.toGenericType(String.class));
+ assertEquals(new TypeToken<int[]>() {}, TypeToken.toGenericType(int[].class));
+ TypeToken<? extends Iterable> genericType = TypeToken.toGenericType(Iterable.class);
+ assertEquals(Iterable.class, genericType.getRawType());
+ assertEquals(Types.newParameterizedType(Iterable.class, Iterable.class.getTypeParameters()[0]),
+ genericType.getType());
+ }
+
+ private interface ListIterable<T> extends Iterable<List<T>> {}
+ private interface StringListIterable extends ListIterable<String> {}
+ private interface ListArrayIterable<T> extends Iterable<List<T>[]> {}
+ private interface StringListArrayIterable extends ListIterable<String> {}
+
+ public void testGetSupertype_withTypeVariable() {
+ ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
+ Types.newParameterizedType(List.class, ListIterable.class.getTypeParameters()[0]));
+ assertEquals(expectedType,
+ TypeToken.of(ListIterable.class).getSupertype(Iterable.class).getType());
+ }
+
+ public void testGetSupertype_withoutTypeVariable() {
+ ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
+ Types.newParameterizedType(List.class, String.class));
+ assertEquals(expectedType,
+ TypeToken.of(StringListIterable.class).getSupertype(Iterable.class).getType());
+ }
+
+ public void testGetSupertype_chained() {
+ @SuppressWarnings("unchecked") // StringListIterable extensd ListIterable<String>
+ TypeToken<ListIterable<String>> listIterableType = (TypeToken<ListIterable<String>>)
+ TypeToken.of(StringListIterable.class).getSupertype(ListIterable.class);
+ ParameterizedType expectedType = Types.newParameterizedType(Iterable.class,
+ Types.newParameterizedType(List.class, String.class));
+ assertEquals(expectedType, listIterableType.getSupertype(Iterable.class).getType());
+ }
+
+ public void testGetSupertype_withArray() {
+ assertEquals(new TypeToken<Iterable<List<String>>[]>() {},
+ TypeToken.of(StringListIterable[].class).getSupertype(Iterable[].class));
+ assertEquals(int[].class, TypeToken.of(int[].class).getSupertype(int[].class).getType());
+ assertEquals(Object.class, TypeToken.of(int[].class).getSupertype(Object.class).getType());
+ assertEquals(int[][].class, TypeToken.of(int[][].class).getSupertype(int[][].class).getType());
+ assertEquals(Object[].class,
+ TypeToken.of(String[].class).getSupertype(Object[].class).getType());
+ assertEquals(Object.class, TypeToken.of(String[].class).getSupertype(Object.class).getType());
+ }
+
+ public void testGetSupertype_fromWildcard() {
+ @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
+ TypeToken<? extends List<String>> type = (TypeToken<? extends List<String>>)
+ TypeToken.of(Types.subtypeOf(new TypeToken<List<String>>() {}.getType()));
+ assertEquals(new TypeToken<Iterable<String>>() {}, type.getSupertype(Iterable.class));
+ }
+
+ public <T extends Iterable<String>> void testGetSupertype_fromTypeVariable() {
+ @SuppressWarnings("unchecked") // to construct TypeToken<T> from TypeToken.of()
+ TypeToken<T> typeVariableToken = (TypeToken<T>) TypeToken.of(new TypeCapture<T>() {}.capture());
+ assertEquals(new TypeToken<Iterable<String>>() {},
+ typeVariableToken.getSupertype(Iterable.class));
+ }
+
+ @SuppressWarnings("rawtypes") // purpose is to test raw type
+ public void testGetSupertype_fromRawClass() {
+ assertEquals(Types.newParameterizedType(Iterable.class, List.class.getTypeParameters()[0]),
+ new TypeToken<List>() {}.getSupertype(Iterable.class).getType());
+ }
+
+ @SuppressWarnings("rawtypes") // purpose is to test raw type
+ public void testGetSupertype_notSupertype() {
+ try {
+ new TypeToken<List<String>>() {}.getSupertype((Class) String.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testGetSupertype_fromArray() {
+ assertEquals(new TypeToken<Iterable<String>[]>() {},
+ new TypeToken<List<String>[]>() {}.getSupertype(Iterable[].class));
+ }
+
+ private interface ListMap<K, V> extends Map<K, List<V>> {}
+
+ public void testGetSupertype_fullyGenericType() {
+ ParameterizedType expectedType = Types.newParameterizedType(Map.class,
+ ListMap.class.getTypeParameters()[0],
+ Types.newParameterizedType(List.class, ListMap.class.getTypeParameters()[1]));
+ assertEquals(expectedType,
+ TypeToken.of(ListMap.class).getSupertype(Map.class).getType());
+ }
+
+ public void testGetSupertype_fullySpecializedType() {
+ Type expectedType = new TypeToken<Map<String, List<Object>>>() {}.getType();
+ assertEquals(expectedType,
+ new TypeToken<ListMap<String, Object>>() {}.getSupertype(Map.class).getType());
+ }
+
+ private interface StringListMap<V> extends ListMap<String, V> {}
+
+ public <V> void testGetSupertype_partiallySpecializedType() {
+ Type expectedType = new TypeToken<Map<String, List<V>>>() {}.getType();
+ assertEquals(expectedType,
+ new TypeToken<StringListMap<V>>() {}.getSupertype(Map.class).getType());
+ }
+
+ public void testGetSubtype_withTypeVariable() {
+ assertEquals(new TypeToken<ListIterable<String>>() {},
+ new TypeToken<Iterable<List<String>>>() {}.getSubtype(ListIterable.class));
+ assertEquals(new TypeToken<ListArrayIterable<String>>() {},
+ new TypeToken<Iterable<List<String>[]>>() {}.getSubtype(ListArrayIterable.class));
+ assertEquals(new TypeToken<ListArrayIterable<String>[]>() {},
+ new TypeToken<Iterable<List<String>[]>[]>() {}.getSubtype(ListArrayIterable[].class));
+ }
+
+ public void testGetSubtype_withoutTypeVariable() {
+ assertEquals(StringListIterable.class,
+ TypeToken.of(Iterable.class).getSubtype(StringListIterable.class).getType());
+ assertEquals(StringListIterable[].class,
+ TypeToken.of(Iterable[].class).getSubtype(StringListIterable[].class).getType());
+ assertEquals(TypeToken.of(StringListArrayIterable.class),
+ new TypeToken<Iterable<List<String>>>() {}.getSubtype(StringListArrayIterable.class));
+ assertEquals(TypeToken.of(StringListArrayIterable[].class),
+ new TypeToken<Iterable<List<String>>[]>() {}.getSubtype(StringListArrayIterable[].class));
+ }
+
+ public void testGetSubtype_withArray() {
+ assertEquals(TypeToken.of(StringListIterable[].class),
+ TypeToken.of(Iterable[].class).getSubtype(StringListIterable[].class));
+ assertEquals(TypeToken.of(String[].class),
+ TypeToken.of(Object[].class).getSubtype(String[].class));
+ assertEquals(TypeToken.of(int[].class),
+ TypeToken.of(Object.class).getSubtype(int[].class));
+ }
+
+ public void testGetSubtype_fromWildcard() {
+ @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
+ TypeToken<? super Iterable<String>> type = (TypeToken<? super Iterable<String>>)
+ TypeToken.of(Types.supertypeOf(new TypeToken<Iterable<String>>() {}.getType()));
+ assertEquals(new TypeToken<List<String>>() {}, type.getSubtype(List.class));
+ }
+
+ public void testGetSubtype_fromWildcard_lowerBoundNotSupertype() {
+ @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
+ TypeToken<? super Iterable<String>> type = (TypeToken<? super Iterable<String>>)
+ TypeToken.of(Types.supertypeOf(new TypeToken<ImmutableList<String>>() {}.getType()));
+ try {
+ type.getSubtype(List.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testGetSubtype_fromWildcard_upperBounded() {
+ @SuppressWarnings("unchecked") // can't do new TypeToken<? extends ...>() {}
+ TypeToken<? extends Iterable<String>> type = (TypeToken<? extends Iterable<String>>)
+ TypeToken.of(Types.subtypeOf(new TypeToken<Iterable<String>>() {}.getType()));
+ try {
+ type.getSubtype(Iterable.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public <T extends Iterable<String>> void testGetSubtype_fromTypeVariable() {
+ try {
+ TypeToken.of(new TypeCapture<T>() {}.capture()).getSubtype(List.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ @SuppressWarnings("rawtypes") // purpose is to test raw type
+ public void testGetSubtype_fromRawClass() {
+ assertEquals(List.class, new TypeToken<Iterable>() {}.getSubtype(List.class).getType());
+ }
+
+ public void testGetSubtype_fromArray() {
+ assertEquals(new TypeToken<List<String>[]>() {},
+ new TypeToken<Iterable<String>[]>() {}.getSubtype(List[].class));
+ }
+
+ @SuppressWarnings("unchecked") // To construct TypeToken<T> with TypeToken.of()
+ public <T> void testWhere_circleRejected() {
+ TypeToken<List<T>> type = new TypeToken<List<T>>() {};
+ try {
+ type.where(new TypeParameter<T>() {},
+ (TypeToken<T>) TypeToken.of(new TypeCapture<T>() {}.capture()));
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testWhere() {
+ assertEquals(
+ new TypeToken<Map<String, Integer>>() {},
+ mapOf(String.class, Integer.class));
+ assertEquals(new TypeToken<int[]>() {}, arrayOf(int.class));
+ assertEquals(int[].class, arrayOf(int.class).getRawType());
+ }
+
+ @SuppressWarnings("unused") // used by reflection
+ private static class Holder<T> {
+ T element;
+ List<T> list;
+ List<T>[] matrix;
+
+ void setList(List<T> list) {
+ this.list = list;
+ }
+ }
+
+ public void testWildcardCaptured_methodParameter_upperBound() throws Exception {
+ TypeToken<Holder<?>> type = new TypeToken<Holder<?>>() {};
+ TypeToken<?> parameterType = type.resolveType(
+ Holder.class.getDeclaredMethod("setList", List.class).getGenericParameterTypes()[0]);
+ assertEquals(List.class, parameterType.getRawType());
+ assertFalse(parameterType.getType().toString(),
+ parameterType.isAssignableFrom(new TypeToken<List<Integer>>() {}));
+ }
+
+ public void testWildcardCaptured_field_upperBound() throws Exception {
+ TypeToken<Holder<?>> type = new TypeToken<Holder<?>>() {};
+ TypeToken<?> matrixType = type.resolveType(
+ Holder.class.getDeclaredField("matrix").getGenericType());
+ assertEquals(List[].class, matrixType.getRawType());
+ ASSERT.that(matrixType.getType())
+ .isNotEqualTo(new TypeToken<List<?>[]>() {}.getType());
+ }
+
+ public void testArrayClassPreserved() {
+ assertEquals(int[].class, TypeToken.of(int[].class).getType());
+ assertEquals(int[][].class, TypeToken.of(int[][].class).getType());
+ assertEquals(String[].class, TypeToken.of(String[].class).getType());
+ assertEquals(Integer.class, new TypeToken<Integer>() {}.getType());
+ assertEquals(Integer.class, TypeToken.of(Integer.class).getType());
+ }
+
+ public void testMethod_getOwnerType() throws NoSuchMethodException {
+ Method sizeMethod = List.class.getMethod("size");
+ assertEquals(TypeToken.of(List.class),
+ TypeToken.of(List.class).method(sizeMethod).getOwnerType());
+ assertEquals(new TypeToken<List<String>>() {},
+ new TypeToken<List<String>>() {}.method(sizeMethod).getOwnerType());
+ }
+
+ public void testMethod_notDeclaredByType() throws NoSuchMethodException {
+ Method sizeMethod = Map.class.getMethod("size");
+ try {
+ TypeToken.of(List.class).method(sizeMethod);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testMethod_declaredBySuperclass() throws Exception {
+ Method toStringMethod = Object.class.getMethod("toString");
+ ImmutableList<String> list = ImmutableList.of("foo");
+ assertEquals(list.toString(), TypeToken.of(List.class).method(toStringMethod).invoke(list));
+ }
+
+ public <T extends Number & List<String>> void testMethod_returnType_resolvedAgainstTypeBound()
+ throws NoSuchMethodException {
+ Method getMethod = List.class.getMethod("get", int.class);
+ Invokable<T, String> Invokable = new TypeToken<T>(getClass()) {}
+ .method(getMethod)
+ .returning(String.class);
+ assertEquals(TypeToken.of(String.class), Invokable.getReturnType());
+ }
+
+ public <T extends List<String>> void testMethod_parameterTypes()
+ throws NoSuchMethodException {
+ Method setMethod = List.class.getMethod("set", int.class, Object.class);
+ Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.method(setMethod);
+ ImmutableList<Parameter> params = invokable.getParameters();
+ assertEquals(2, params.size());
+ assertEquals(TypeToken.of(int.class), params.get(0).getType());
+ assertEquals(TypeToken.of(String.class), params.get(1).getType());
+ }
+
+ private interface Loser<E extends Throwable> {
+ void lose() throws E;
+ }
+
+ public <T extends Loser<AssertionError>> void testMethod_exceptionTypes()
+ throws NoSuchMethodException {
+ Method failMethod = Loser.class.getMethod("lose");
+ Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.method(failMethod);
+ ASSERT.that(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class));
+ }
+
+ public void testConstructor_getOwnerType() throws NoSuchMethodException {
+ @SuppressWarnings("rawtypes") // raw class ArrayList.class
+ Constructor<ArrayList> constructor = ArrayList.class.getConstructor();
+ assertEquals(TypeToken.of(ArrayList.class),
+ TypeToken.of(ArrayList.class).constructor(constructor).getOwnerType());
+ assertEquals(new TypeToken<ArrayList<String>>() {},
+ new TypeToken<ArrayList<String>>() {}.constructor(constructor).getOwnerType());
+ }
+
+ public void testConstructor_notDeclaredByType() throws NoSuchMethodException {
+ Constructor<String> constructor = String.class.getConstructor();
+ try {
+ TypeToken.of(Object.class).constructor(constructor);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testConstructor_declaredBySuperclass() throws NoSuchMethodException {
+ Constructor<Object> constructor = Object.class.getConstructor();
+ try {
+ TypeToken.of(String.class).constructor(constructor);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ private static class Container<T> {
+ @SuppressWarnings("unused")
+ public Container(T data) {}
+ }
+
+ public <T extends Container<String>> void testConstructor_parameterTypes()
+ throws NoSuchMethodException {
+ @SuppressWarnings("rawtypes") // Reflection API skew
+ Constructor<Container> constructor = Container.class.getConstructor(Object.class);
+ Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.constructor(constructor);
+ ImmutableList<Parameter> params = invokable.getParameters();
+ assertEquals(1, params.size());
+ assertEquals(TypeToken.of(String.class), params.get(0).getType());
+ }
+
+ private static class CannotConstruct<E extends Throwable> {
+ @SuppressWarnings("unused")
+ public CannotConstruct() throws E {}
+ }
+
+ public <T extends CannotConstruct<AssertionError>> void testConstructor_exceptionTypes()
+ throws NoSuchMethodException {
+ @SuppressWarnings("rawtypes") // Reflection API skew
+ Constructor<CannotConstruct> constructor = CannotConstruct.class.getConstructor();
+ Invokable<T, ?> invokable = new TypeToken<T>(getClass()) {}.constructor(constructor);
+ ASSERT.that(invokable.getExceptionTypes()).has().item(TypeToken.of(AssertionError.class));
+ }
+
+ private abstract static class RawTypeConsistencyTester<T extends Enum<T> & CharSequence> {
+ abstract T returningT();
+ abstract void acceptT(T t);
+ abstract <X extends T> X returningX();
+ abstract <X> void acceptX(X x);
+ abstract <T2 extends Enum<T2> & CharSequence> T2 returningT2();
+ abstract <T2 extends CharSequence&Iterable<T2>> void acceptT2(T2 t2);
+
+ static void verifyConsitentRawType() {
+ for (Method method : RawTypeConsistencyTester.class.getDeclaredMethods()) {
+ assertEquals(method.getReturnType(), TypeToken.getRawType(method.getGenericReturnType()));
+ for (int i = 0; i < method.getParameterTypes().length; i++) {
+ assertEquals(method.getParameterTypes()[i],
+ TypeToken.getRawType(method.getGenericParameterTypes()[i]));
+ }
+ }
+ }
+ }
+
+ public void testRawTypes() throws Exception {
+ RawTypeConsistencyTester.verifyConsitentRawType();
+ assertEquals(Object.class, TypeToken.getRawType(Types.subtypeOf(Object.class)));
+ assertEquals(CharSequence.class, TypeToken.getRawType(Types.subtypeOf(CharSequence.class)));
+ assertEquals(Object.class, TypeToken.getRawType(Types.supertypeOf(CharSequence.class)));
+ }
+
+ private abstract static class IKnowMyType<T> {
+ TypeToken<T> type() {
+ return new TypeToken<T>(getClass()) {};
+ }
+ }
+
+ public void testTypeResolution() {
+ assertEquals(String.class,
+ new IKnowMyType<String>() {}.type().getType());
+ assertEquals(new TypeToken<Map<String, Integer>>() {},
+ new IKnowMyType<Map<String, Integer>>() {}.type());
+ }
+
+ public <A extends Iterable<? extends String>, B extends A> void testSerializable() {
+ reserialize(TypeToken.of(String.class));
+ reserialize(TypeToken.of(String.class).getTypes());
+ reserialize(TypeToken.of(String.class).getTypes().classes());
+ reserialize(TypeToken.of(String.class).getTypes().interfaces());
+ reserialize(TypeToken.of(String.class).getTypes().rawTypes());
+ reserialize(TypeToken.of(String.class).getTypes().classes().rawTypes());
+ reserialize(TypeToken.of(String.class).getTypes().interfaces().rawTypes());
+ reserialize(new TypeToken<int[]>() {});
+ reserialize(new TypeToken<Map<String, Integer>>() {});
+ reserialize(new IKnowMyType<Map<? super String, ? extends int[]>>() {}.type());
+ reserialize(TypeToken.of(new TypeCapture<B>() {}.capture()).getTypes().rawTypes());
+ try {
+ SerializableTester.reserialize(TypeToken.of(new TypeCapture<B>() {}.capture()));
+ fail();
+ } catch (RuntimeException expected) {}
+ }
+
+ public <A> void testSerializable_typeVariableNotSupported() {
+ try {
+ new ITryToSerializeMyTypeVariable<String>().go();
+ fail();
+ } catch (RuntimeException expected) {}
+ }
+
+ private static class ITryToSerializeMyTypeVariable<T> {
+ void go() {
+ SerializableTester.reserialize(TypeToken.of(new TypeCapture<T>() {}.capture()));
+ }
+ }
+
+ private static <T> T reserialize(T object) {
+ T copy = SerializableTester.reserialize(object);
+ new EqualsTester()
+ .addEqualityGroup(object, copy)
+ .testEquals();
+ return copy;
+ }
+
+ public void testTypeResolutionAfterReserialized() {
+ reserialize(new TypeToken<String>() {});
+ reserialize(new TypeToken<Map<String, Integer>>() {});
+ TypeToken<Map<String, Integer>> reserialized = reserialize(
+ new TypeToken<Map<String, Integer>>() {});
+ assertEquals(reserialized, substitute(reserialized, String.class));
+ }
+
+ private static <T, X> TypeToken<T> substitute(TypeToken<T> type, Class<X> arg) {
+ return type.where(new TypeParameter<X>() {}, arg);
+ }
+
+ private abstract static class ToReproduceGenericSignatureFormatError<V> {
+ private abstract class BaseOuter {
+ abstract class BaseInner {}
+ }
+ private abstract class SubOuter extends BaseOuter {
+ private abstract class SubInner extends BaseInner {}
+ }
+
+ }
+
+ // For Guava bug http://code.google.com/p/guava-libraries/issues/detail?id=1025
+ public void testDespiteGenericSignatureFormatError() {
+ ImmutableSet.copyOf(
+ TypeToken.of(ToReproduceGenericSignatureFormatError.SubOuter.SubInner.class)
+ .getTypes()
+ .rawTypes());
+ }
+
+ private abstract static class Entry<K, V> {
+ TypeToken<K> keyType() {
+ return new TypeToken<K>(getClass()) {};
+ }
+ TypeToken<V> valueType() {
+ return new TypeToken<V>(getClass()) {};
+ }
+ }
+
+ // The A and B type parameters are used inside the test to test type variable
+ public <A, B> void testEquals() {
+ new EqualsTester()
+ .addEqualityGroup(
+ TypeToken.of(String.class),
+ TypeToken.of(String.class),
+ new Entry<String, Integer>() {}.keyType(),
+ new Entry<Integer, String>() {}.valueType(),
+ new TypeToken<String>() {},
+ new TypeToken<String>() {})
+ .addEqualityGroup(
+ TypeToken.of(Integer.class),
+ new TypeToken<Integer>() {},
+ new Entry<Integer, String>() {}.keyType(),
+ new Entry<String, Integer>() {}.valueType())
+ .addEqualityGroup(
+ new TypeToken<List<String>>() {},
+ new TypeToken<List<String>>() {})
+ .addEqualityGroup(
+ new TypeToken<List<?>>() {},
+ new TypeToken<List<?>>() {})
+ .addEqualityGroup(
+ new TypeToken<Map<A, ?>>() {},
+ new TypeToken<Map<A, ?>>() {})
+ .addEqualityGroup(
+ new TypeToken<Map<B, ?>>() {})
+ .addEqualityGroup(
+ TypeToken.of(new TypeCapture<A>() {}.capture()),
+ TypeToken.of(new TypeCapture<A>() {}.capture()))
+ .addEqualityGroup(TypeToken.of(new TypeCapture<B>() {}.capture()))
+ .testEquals();
+ }
+
+ // T is used inside to test type variable
+ public <T> void testToString() {
+ assertEquals(String.class.getName(), new TypeToken<String>() {}.toString());
+ assertEquals("T", TypeToken.of(new TypeCapture<T>() {}.capture()).toString());
+ assertEquals("java.lang.String", new Entry<String, Integer>() {}.keyType().toString());
+ }
+
+ private static <K, V> TypeToken<Map<K, V>> mapOf(Class<K> keyType, Class<V> valueType) {
+ return new TypeToken<Map<K, V>>() {}
+ .where(new TypeParameter<K>() {}, keyType)
+ .where(new TypeParameter<V>() {}, valueType);
+ }
+
+ private static <T> TypeToken<T[]> arrayOf(Class<T> componentType) {
+ return new TypeToken<T[]>() {}
+ .where(new TypeParameter<T>() {}, componentType);
+ }
+
+ public <T> void testNulls() {
+ new NullPointerTester()
+ .testAllPublicStaticMethods(TypeToken.class);
+ new NullPointerTester()
+ .setDefault(TypeParameter.class, new TypeParameter<T>() {})
+ .testAllPublicInstanceMethods(TypeToken.of(String.class));
+ }
+
+ private static class Assignability<From, To> {
+
+ boolean isAssignable() {
+ return new TypeToken<To>(getClass()) {}.isAssignableFrom(new TypeToken<From>(getClass()) {});
+ }
+
+ static <From, To> Assignability<From, To> of() {
+ return new Assignability<From, To>();
+ }
+ }
+
+ private static void assertAssignable(TypeToken<?> from, TypeToken<?> to) {
+ assertTrue(
+ from.getType() + " is expected to be assignable to " + to.getType(),
+ to.isAssignableFrom(from));
+ }
+
+ private static void assertNotAssignable(TypeToken<?> from, TypeToken<?> to) {
+ assertFalse(
+ from.getType() + " shouldn't be assignable to " + to.getType(),
+ to.isAssignableFrom(from));
+ }
+
+ private static void assertHasArrayInterfaces(TypeToken<?> arrayType) {
+ assertEquals(arrayInterfaces(), ImmutableSet.copyOf(arrayType.getGenericInterfaces()));
+ }
+
+ private static ImmutableSet<TypeToken<?>> arrayInterfaces() {
+ ImmutableSet.Builder<TypeToken<?>> builder = ImmutableSet.builder();
+ for (Class<?> interfaceType : Object[].class.getInterfaces()) {
+ builder.add(TypeToken.of(interfaceType));
+ }
+ return builder.build();
+ }
+
+ private interface BaseInterface {}
+ private static class Base implements BaseInterface {}
+ private static class Sub extends Base {}
+}
diff --git a/guava-tests/test/com/google/common/reflect/TypesTest.java b/guava-tests/test/com/google/common/reflect/TypesTest.java
new file mode 100644
index 0000000..096951b
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/TypesTest.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect;
+
+import static java.util.Arrays.asList;
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.NullPointerTester;
+import com.google.common.testing.NullPointerTester.Visibility;
+import com.google.common.testing.SerializableTester;
+
+import junit.framework.TestCase;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.GenericDeclaration;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Tests for {@link Types}.
+ *
+ * @author Ben Yu
+ */
+public class TypesTest extends TestCase {
+
+ public void testNewParameterizedType_ownerTypeImplied() throws Exception {
+ ParameterizedType jvmType = (ParameterizedType)
+ new TypeCapture<Map.Entry<String, Integer>>() {}.capture();
+ ParameterizedType ourType = Types.newParameterizedType(
+ Map.Entry.class, String.class, Integer.class);
+ assertEquals(jvmType, ourType);
+ assertEquals(Map.class, ourType.getOwnerType());
+ }
+
+ public void testNewParameterizedType() {
+ ParameterizedType jvmType = (ParameterizedType)
+ new TypeCapture<HashMap<String, int[][]>>() {}.capture();
+ ParameterizedType ourType = Types.newParameterizedType(
+ HashMap.class, String.class, int[][].class);
+
+ new EqualsTester()
+ .addEqualityGroup(jvmType, ourType)
+ .testEquals();
+ assertEquals(jvmType.toString(), ourType.toString());
+ assertEquals(jvmType.hashCode(), ourType.hashCode());
+ assertEquals(HashMap.class, ourType.getRawType());
+ ASSERT.that(ourType.getActualTypeArguments())
+ .iteratesOverSequence(jvmType.getActualTypeArguments());
+ assertEquals(Arrays.asList(
+ String.class,
+ Types.newArrayType(Types.newArrayType(int.class))),
+ Arrays.asList(ourType.getActualTypeArguments()));
+ assertEquals(null, ourType.getOwnerType());
+ }
+
+ public void testNewParameterizedType_nonStaticLocalClass() {
+ class LocalClass<T> {}
+ Type jvmType = new LocalClass<String>() {}.getClass().getGenericSuperclass();
+ Type ourType = Types.newParameterizedType(LocalClass.class, String.class);
+ assertEquals(jvmType, ourType);
+ }
+
+ public void testNewParameterizedType_staticLocalClass() {
+ doTestNewParameterizedType_staticLocalClass();
+ }
+
+ private static void doTestNewParameterizedType_staticLocalClass() {
+ class LocalClass<T> {}
+ Type jvmType = new LocalClass<String>() {}.getClass().getGenericSuperclass();
+ Type ourType = Types.newParameterizedType(LocalClass.class, String.class);
+ assertEquals(jvmType, ourType);
+ }
+
+ public void testNewParameterizedTypeWithOwner() {
+ ParameterizedType jvmType = (ParameterizedType)
+ new TypeCapture<Map.Entry<String, int[][]>>() {}.capture();
+ ParameterizedType ourType = Types.newParameterizedTypeWithOwner(
+ Map.class, Map.Entry.class, String.class, int[][].class);
+
+ new EqualsTester()
+ .addEqualityGroup(jvmType, ourType)
+ .addEqualityGroup(new TypeCapture<Map.Entry<String, String>>() {}.capture())
+ .addEqualityGroup(new TypeCapture<Map<String, Integer>>() {}.capture())
+ .testEquals();
+ assertEquals(jvmType.toString(), ourType.toString());
+ assertEquals(Map.class, ourType.getOwnerType());
+ assertEquals(Map.Entry.class, ourType.getRawType());
+ ASSERT.that(ourType.getActualTypeArguments())
+ .iteratesOverSequence(jvmType.getActualTypeArguments());
+ }
+
+ public void testNewParameterizedType_serializable() {
+ SerializableTester.reserializeAndAssert(Types.newParameterizedType(
+ Map.Entry.class, String.class, Integer.class));
+ }
+
+ public void testNewParameterizedType_ownerMismatch() {
+ try {
+ Types.newParameterizedTypeWithOwner(
+ Number.class, List.class, String.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testNewParameterizedType_ownerMissing() {
+ assertEquals(
+ Types.newParameterizedType(Map.Entry.class, String.class, Integer.class),
+ Types.newParameterizedTypeWithOwner(
+ null, Map.Entry.class, String.class, Integer.class));
+ }
+
+ public void testNewParameterizedType_invalidTypeParameters() {
+ try {
+ Types.newParameterizedTypeWithOwner(
+ Map.class, Map.Entry.class, String.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testNewParameterizedType_primitiveTypeParameters() {
+ try {
+ Types.newParameterizedTypeWithOwner(
+ Map.class, Map.Entry.class, int.class, int.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testNewArrayType() {
+ Type jvmType1 = new TypeCapture<List<String>[]>() {}.capture();
+ GenericArrayType ourType1 = (GenericArrayType) Types.newArrayType(
+ Types.newParameterizedType(List.class, String.class));
+ Type jvmType2 = new TypeCapture<List[]>() {}.capture();
+ Type ourType2 = Types.newArrayType(List.class);
+ new EqualsTester()
+ .addEqualityGroup(jvmType1, ourType1)
+ .addEqualityGroup(jvmType2, ourType2)
+ .testEquals();
+ assertEquals(new TypeCapture<List<String>>() {}.capture(),
+ ourType1.getGenericComponentType());
+ assertEquals(jvmType1.toString(), ourType1.toString());
+ assertEquals(jvmType2.toString(), ourType2.toString());
+ }
+
+ public void testNewArrayTypeOfArray() {
+ Type jvmType = new TypeCapture<int[][]>() {}.capture();
+ Type ourType = Types.newArrayType(int[].class);
+ assertEquals(jvmType.toString(), ourType.toString());
+ new EqualsTester()
+ .addEqualityGroup(jvmType, ourType)
+ .testEquals();
+ }
+
+ public void testNewArrayType_primitive() {
+ Type jvmType = new TypeCapture<int[]>() {}.capture();
+ Type ourType = Types.newArrayType(int.class);
+ assertEquals(jvmType.toString(), ourType.toString());
+ new EqualsTester()
+ .addEqualityGroup(jvmType, ourType)
+ .testEquals();
+ }
+
+ public void testNewArrayType_upperBoundedWildcard() {
+ Type wildcard = Types.subtypeOf(Number.class);
+ assertEquals(Types.subtypeOf(Number[].class), Types.newArrayType(wildcard));
+ }
+
+ public void testNewArrayType_lowerBoundedWildcard() {
+ Type wildcard = Types.supertypeOf(Number.class);
+ assertEquals(Types.supertypeOf(Number[].class), Types.newArrayType(wildcard));
+ }
+
+ public void testNewArrayType_serializable() {
+ SerializableTester.reserializeAndAssert(
+ Types.newArrayType(int[].class));
+ }
+
+ private static class WithWildcardType {
+
+ @SuppressWarnings("unused")
+ void withoutBound(List<?> list) {}
+
+ @SuppressWarnings("unused")
+ void withObjectBound(List<? extends Object> list) {}
+
+ @SuppressWarnings("unused")
+ void withUpperBound(List<? extends int[][]> list) {}
+
+ @SuppressWarnings("unused")
+ void withLowerBound(List<? super String[][]> list) {}
+
+ static WildcardType getWildcardType(String methodName) throws Exception {
+ ParameterizedType parameterType = (ParameterizedType)
+ WithWildcardType.class
+ .getDeclaredMethod(methodName, List.class)
+ .getGenericParameterTypes()[0];
+ return (WildcardType) parameterType.getActualTypeArguments()[0];
+ }
+ }
+
+ public void testNewWildcardType() throws Exception {
+ WildcardType noBoundJvmType =
+ WithWildcardType.getWildcardType("withoutBound");
+ WildcardType objectBoundJvmType =
+ WithWildcardType.getWildcardType("withObjectBound");
+ WildcardType upperBoundJvmType =
+ WithWildcardType.getWildcardType("withUpperBound");
+ WildcardType lowerBoundJvmType =
+ WithWildcardType.getWildcardType("withLowerBound");
+ WildcardType objectBound =
+ Types.subtypeOf(Object.class);
+ WildcardType upperBound =
+ Types.subtypeOf(int[][].class);
+ WildcardType lowerBound =
+ Types.supertypeOf(String[][].class);
+
+ assertEqualWildcardType(noBoundJvmType, objectBound);
+ assertEqualWildcardType(objectBoundJvmType, objectBound);
+ assertEqualWildcardType(upperBoundJvmType, upperBound);
+ assertEqualWildcardType(lowerBoundJvmType, lowerBound);
+
+ new EqualsTester()
+ .addEqualityGroup(
+ noBoundJvmType, objectBoundJvmType, objectBound)
+ .addEqualityGroup(upperBoundJvmType, upperBound)
+ .addEqualityGroup(lowerBoundJvmType, lowerBound)
+ .testEquals();
+ }
+
+ public void testNewWildcardType_primitiveTypeBound() {
+ try {
+ Types.subtypeOf(int.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testNewWildcardType_serializable() {
+ SerializableTester.reserializeAndAssert(
+ Types.supertypeOf(String.class));
+ SerializableTester.reserializeAndAssert(
+ Types.subtypeOf(String.class));
+ SerializableTester.reserializeAndAssert(
+ Types.subtypeOf(Object.class));
+ }
+
+ private static void assertEqualWildcardType(
+ WildcardType expected, WildcardType actual) {
+ assertEquals(expected.toString(), actual.toString());
+ assertEquals(actual.toString(), expected.hashCode(), actual.hashCode());
+ ASSERT.that(actual.getLowerBounds())
+ .has().allFrom(asList(expected.getLowerBounds())).inOrder();
+ ASSERT.that(actual.getUpperBounds())
+ .has().allFrom(asList(expected.getUpperBounds())).inOrder();
+ }
+
+ private static class WithTypeVariable {
+
+ @SuppressWarnings("unused")
+ <T> void withoutBound(List<T> list) {}
+
+ @SuppressWarnings("unused")
+ <T extends Object> void withObjectBound(List<T> list) {}
+
+ @SuppressWarnings("unused")
+ <T extends Number & CharSequence> void withUpperBound(List<T> list) {}
+
+ static TypeVariable<?> getTypeVariable(String methodName) throws Exception {
+ ParameterizedType parameterType = (ParameterizedType)
+ WithTypeVariable.class
+ .getDeclaredMethod(methodName, List.class)
+ .getGenericParameterTypes()[0];
+ return (TypeVariable<?>) parameterType.getActualTypeArguments()[0];
+ }
+ }
+
+ public void testNewTypeVariable() throws Exception {
+ TypeVariable<?> noBoundJvmType =
+ WithTypeVariable.getTypeVariable("withoutBound");
+ TypeVariable<?> objectBoundJvmType =
+ WithTypeVariable.getTypeVariable("withObjectBound");
+ TypeVariable<?> upperBoundJvmType =
+ WithTypeVariable.getTypeVariable("withUpperBound");
+ TypeVariable<?> noBound = withBounds(noBoundJvmType);
+ TypeVariable<?> objectBound = withBounds(objectBoundJvmType, Object.class);
+ TypeVariable<?> upperBound = withBounds(
+ upperBoundJvmType, Number.class, CharSequence.class);
+
+ assertEqualTypeVariable(noBoundJvmType, noBound);
+ assertEqualTypeVariable(noBoundJvmType,
+ withBounds(noBoundJvmType, Object.class));
+ assertEqualTypeVariable(objectBoundJvmType, objectBound);
+ assertEqualTypeVariable(upperBoundJvmType, upperBound);
+
+ new EqualsTester()
+ .addEqualityGroup(noBoundJvmType, noBound)
+ .addEqualityGroup(objectBoundJvmType, objectBound)
+ .addEqualityGroup(
+ upperBoundJvmType, upperBound,
+ withBounds(upperBoundJvmType, CharSequence.class)) // bounds ignored
+ .testEquals();
+ }
+
+ public void testNewTypeVariable_primitiveTypeBound() {
+ try {
+ Types.newTypeVariable(List.class, "E", int.class);
+ fail();
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ public void testNewTypeVariable_serializable() throws Exception {
+ try {
+ SerializableTester.reserialize(Types.newTypeVariable(List.class, "E"));
+ fail();
+ } catch (RuntimeException expected) {}
+ }
+
+ private static <D extends GenericDeclaration> TypeVariable<D> withBounds(
+ TypeVariable<D> typeVariable, Type... bounds) {
+ return Types.newTypeVariable(
+ typeVariable.getGenericDeclaration(), typeVariable.getName(), bounds);
+ }
+
+ private static void assertEqualTypeVariable(
+ TypeVariable<?> expected, TypeVariable<?> actual) {
+ assertEquals(expected.toString(), actual.toString());
+ assertEquals(expected.getName(), actual.getName());
+ assertEquals(
+ expected.getGenericDeclaration(), actual.getGenericDeclaration());
+ assertEquals(actual.toString(), expected.hashCode(), actual.hashCode());
+ ASSERT.that(actual.getBounds()).has().allFrom(asList(expected.getBounds())).inOrder();
+ }
+
+ /**
+ * Working with arrays requires defensive code. Verify that we clone the
+ * type array for both input and output.
+ */
+ public void testNewParameterizedTypeImmutability() {
+ Type[] typesIn = { String.class, Integer.class };
+ ParameterizedType parameterizedType
+ = Types.newParameterizedType(Map.class, typesIn);
+ typesIn[0] = null;
+ typesIn[1] = null;
+
+ Type[] typesOut = parameterizedType.getActualTypeArguments();
+ typesOut[0] = null;
+ typesOut[1] = null;
+
+ assertEquals(String.class, parameterizedType.getActualTypeArguments()[0]);
+ assertEquals(Integer.class, parameterizedType.getActualTypeArguments()[1]);
+ }
+
+ public void testNewParameterizedTypeWithWrongNumberOfTypeArguments() {
+ try {
+ Types.newParameterizedType(
+ Map.class, String.class, Integer.class, Long.class);
+ fail();
+ } catch(IllegalArgumentException expected) {}
+ }
+
+ public void testContainsTypeVariable_class() {
+ assertFalse(Types.containsTypeVariable(String.class));
+ assertFalse(Types.containsTypeVariable(String[].class));
+ assertFalse(Types.containsTypeVariable(int[].class));
+ }
+
+ public void testContainsTypeVariable_parameterizedType() {
+ assertFalse(Types.containsTypeVariable(new TypeCapture<Iterable<String>>() {}.capture()));
+ }
+
+ public void testContainsTypeVariable_wildcardType() {
+ assertFalse(Types.containsTypeVariable(
+ new TypeCapture<Iterable<? extends String>>() {}.capture()));
+ assertFalse(Types.containsTypeVariable(
+ new TypeCapture<Iterable<? super String>>() {}.capture()));
+ }
+
+ public void testContainsTypeVariable_genericArrayType() {
+ assertFalse(Types.containsTypeVariable(
+ new TypeCapture<Iterable<? extends String>[]>() {}.capture()));
+ }
+
+ public <T> void testContainsTypeVariable_withTypeVariable() {
+ assertTrue(Types.containsTypeVariable(new TypeCapture<T>() {}.capture()));
+ assertTrue(Types.containsTypeVariable(new TypeCapture<T[]>() {}.capture()));
+ assertTrue(Types.containsTypeVariable(new TypeCapture<Iterable<T>>() {}.capture()));
+ assertTrue(Types.containsTypeVariable(new TypeCapture<Map<String, T>>() {}.capture()));
+ assertTrue(Types.containsTypeVariable(
+ new TypeCapture<Map<String, ? extends T>>() {}.capture()));
+ assertTrue(Types.containsTypeVariable(
+ new TypeCapture<Map<String, ? super T[]>>() {}.capture()));
+ }
+
+ public void testToString() {
+ assertEquals(int[].class.getName(), Types.toString(int[].class));
+ assertEquals(int[][].class.getName(), Types.toString(int[][].class));
+ assertEquals(String[].class.getName(), Types.toString(String[].class));
+ Type elementType = List.class.getTypeParameters()[0];
+ assertEquals(elementType.toString(), Types.toString(elementType));
+ }
+
+ public void testNullPointers() {
+ new NullPointerTester().testStaticMethods(Types.class, Visibility.PACKAGE);
+ }
+}
diff --git a/guava-tests/test/com/google/common/reflect/subpackage/ClassInSubPackage.java b/guava-tests/test/com/google/common/reflect/subpackage/ClassInSubPackage.java
new file mode 100644
index 0000000..5094193
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/subpackage/ClassInSubPackage.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.reflect.subpackage;
+
+public class ClassInSubPackage {}
diff --git a/guava-tests/test/com/google/common/reflect/test.txt b/guava-tests/test/com/google/common/reflect/test.txt
new file mode 100644
index 0000000..189e613
--- /dev/null
+++ b/guava-tests/test/com/google/common/reflect/test.txt
@@ -0,0 +1 @@
+This is a resource file for testing purpose.
diff --git a/guava-tests/test/com/google/common/testing/EqualsTesterTest.java b/guava-tests/test/com/google/common/testing/EqualsTesterTest.java
deleted file mode 100644
index e2ec18a..0000000
--- a/guava-tests/test/com/google/common/testing/EqualsTesterTest.java
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- * Copyright (C) 2007 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import java.util.Set;
-
-/**
- * Unit tests for {@link EqualsTester}.
- *
- * @author Jim McMaster
- */
-@GwtCompatible
-public class EqualsTesterTest extends TestCase {
- private ValidTestObject reference;
- private EqualsTester equalsTester;
- private ValidTestObject equalObject1;
- private ValidTestObject equalObject2;
- private ValidTestObject notEqualObject1;
- private ValidTestObject notEqualObject2;
-
- @Override
- public void setUp() throws Exception {
- super.setUp();
- reference = new ValidTestObject(1, 2);
- equalsTester = new EqualsTester();
- equalObject1 = new ValidTestObject(1, 2);
- equalObject2 = new ValidTestObject(1, 2);
- notEqualObject1 = new ValidTestObject(0, 2);
- notEqualObject2 = new ValidTestObject(1, 0);
- }
-
- /**
- * Test null reference yields error
- */
- public void testAddNullReference() {
- try {
- equalsTester.addEqualityGroup((Object) null);
- fail("Should fail on null reference");
- } catch (NullPointerException e) {}
- }
-
- /**
- * Test equalObjects after adding multiple instances at once with a null
- */
- public void testAddTwoEqualObjectsAtOnceWithNull() {
- try {
- equalsTester.addEqualityGroup(reference, equalObject1, null);
- fail("Should fail on null equal object");
- } catch (NullPointerException e) {}
- }
-
- /**
- * Test adding null equal object yields error
- */
- public void testAddNullEqualObject() {
- try {
- equalsTester.addEqualityGroup(reference, (Object[]) null);
- fail("Should fail on null equal object");
- } catch (NullPointerException e) {}
- }
-
- /**
- * Test adding objects only by addEqualityGroup, with no reference object
- * specified in the constructor.
- */
- public void testAddEqualObjectWithOArgConstructor() {
- equalsTester.addEqualityGroup(equalObject1, notEqualObject1);
- try {
- equalsTester.testEquals();
- } catch (AssertionFailedError e) {
- assertErrorMessage(
- e,
- equalObject1 + " [group 1, item 1] must be equal to "
- + notEqualObject1 + " [group 1, item 2]");
- return;
- }
- fail("Should get not equal to equal object error");
- }
-
- /**
- * Test EqualsTester with no equals or not equals objects. This checks
- * proper handling of null, incompatible class and reflexive tests
- */
- public void testTestEqualsEmptyLists() {
- equalsTester.addEqualityGroup(reference);
- equalsTester.testEquals();
- }
-
- /**
- * Test EqualsTester after populating equalObjects. This checks proper
- * handling of equality and verifies hashCode for valid objects
- */
- public void testTestEqualsEqualsObjects() {
- equalsTester.addEqualityGroup(reference, equalObject1, equalObject2);
- equalsTester.testEquals();
- }
-
- /**
- * Test proper handling of case where an object is not equal to itself
- */
- public void testNonreflexiveEquals() {
- Object obj = new NonReflexiveObject();
- equalsTester.addEqualityGroup(obj);
- try {
- equalsTester.testEquals();
- } catch (AssertionFailedError e) {
- assertErrorMessage(
- e, obj + " must be equal to itself");
- return;
- }
- fail("Should get non-reflexive error");
- }
-
- /**
- * Test proper handling where an object tests equal to null
- */
- public void testInvalidEqualsNull() {
- Object obj = new InvalidEqualsNullObject();
- equalsTester.addEqualityGroup(obj);
- try {
- equalsTester.testEquals();
- } catch (AssertionFailedError e) {
- assertErrorMessage(
- e, obj + " must be unequal to null");
- return;
- }
- fail("Should get equal to null error");
- }
-
- /**
- * Test proper handling where an object incorrectly tests for an
- * incompatible class
- */
- public void testInvalidEqualsIncompatibleClass() {
- Object obj = new InvalidEqualsIncompatibleClassObject();
- equalsTester.addEqualityGroup(obj);
- try {
- equalsTester.testEquals();
- } catch (AssertionFailedError e) {
- assertErrorMessage(
- e,
- obj
- + " must be unequal to an arbitrary object of another class");
- return;
- }
- fail("Should get equal to incompatible class error");
- }
-
- /**
- * Test proper handling where an object is not equal to one the user has
- * said should be equal
- */
- public void testInvalidNotEqualsEqualObject() {
- equalsTester.addEqualityGroup(reference, notEqualObject1);
- try {
- equalsTester.testEquals();
- } catch (AssertionFailedError e) {
- assertErrorMessage(e, reference.toString() + " [group 1, item 1]");
- assertErrorMessage(e, notEqualObject1.toString() + " [group 1, item 2]");
- return;
- }
- fail("Should get not equal to equal object error");
- }
-
- /**
- * Test for an invalid hashCode method, i.e., one that returns different
- * value for objects that are equal according to the equals method
- */
- public void testInvalidHashCode() {
- Object a = new InvalidHashCodeObject(1, 2);
- Object b = new InvalidHashCodeObject(1, 2);
- equalsTester.addEqualityGroup(a, b);
- try {
- equalsTester.testEquals();
- } catch (AssertionFailedError e) {
- assertErrorMessage(
- e, "the hash (" + a.hashCode() + ") of " + a
- + " [group 1, item 1] must be equal to the hash (" + b.hashCode() + ") of " + b);
- return;
- }
- fail("Should get invalid hashCode error");
- }
-
- public void testNullEqualityGroup() {
- EqualsTester tester = new EqualsTester();
- try {
- tester.addEqualityGroup((Object[]) null);
- fail();
- } catch (NullPointerException e) {}
- }
-
- public void testNullObjectInEqualityGroup() {
- EqualsTester tester = new EqualsTester();
- try {
- tester.addEqualityGroup(1, null, 3);
- fail();
- } catch (NullPointerException e) {
- assertErrorMessage(e, "at index 1");
- }
- }
-
- public void testSymmetryBroken() {
- EqualsTester tester = new EqualsTester()
- .addEqualityGroup(named("foo").addPeers("bar"), named("bar"));
- try {
- tester.testEquals();
- } catch (AssertionFailedError e) {
- assertErrorMessage(
- e,
- "bar [group 1, item 2] must be equal to foo [group 1, item 1]");
- return;
- }
- fail("should failed because symmetry is broken");
- }
-
- public void testTransitivityBrokenInEqualityGroup() {
- EqualsTester tester = new EqualsTester()
- .addEqualityGroup(
- named("foo").addPeers("bar", "baz"),
- named("bar").addPeers("foo"),
- named("baz").addPeers("foo"));
- try {
- tester.testEquals();
- } catch (AssertionFailedError e) {
- assertErrorMessage(
- e,
- "bar [group 1, item 2] must be equal to baz [group 1, item 3]");
- return;
- }
- fail("should failed because transitivity is broken");
- }
-
- public void testUnequalObjectsInEqualityGroup() {
- EqualsTester tester = new EqualsTester()
- .addEqualityGroup(named("foo"), named("bar"));
- try {
- tester.testEquals();
- } catch (AssertionFailedError e) {
- assertErrorMessage(
- e,
- "foo [group 1, item 1] must be equal to bar [group 1, item 2]");
- return;
- }
- fail("should failed because of unequal objects in the same equality group");
- }
-
- public void testTransitivityBrokenAcrossEqualityGroups() {
- EqualsTester tester = new EqualsTester()
- .addEqualityGroup(
- named("foo").addPeers("bar"),
- named("bar").addPeers("foo", "x"))
- .addEqualityGroup(
- named("baz").addPeers("x"),
- named("x").addPeers("baz", "bar"));
- try {
- tester.testEquals();
- } catch (AssertionFailedError e) {
- assertErrorMessage(
- e,
- "bar [group 1, item 2] must be unequal to x [group 2, item 2]");
- return;
- }
- fail("should failed because transitivity is broken");
- }
-
- public void testEqualityGroups() {
- new EqualsTester()
- .addEqualityGroup(
- named("foo").addPeers("bar"), named("bar").addPeers("foo"))
- .addEqualityGroup(named("baz"), named("baz"))
- .testEquals();
- }
-
- private static void assertErrorMessage(Throwable e, String message) {
- // TODO(kevinb): use a Truth assertion here
- if (!e.getMessage().contains(message)) {
- fail("expected <" + e.getMessage() + "> to contain <" + message + ">");
- }
- }
-
- /**
- * Test class with valid equals and hashCode methods. Testers created
- * with instances of this class should always pass.
- */
- private static class ValidTestObject {
- private int aspect1;
- private int aspect2;
-
- ValidTestObject(int aspect1, int aspect2) {
- this.aspect1 = aspect1;
- this.aspect2 = aspect2;
- }
-
- @Override public boolean equals(Object o) {
- if (!(o instanceof ValidTestObject)) {
- return false;
- }
- ValidTestObject other = (ValidTestObject) o;
- if (aspect1 != other.aspect1) {
- return false;
- }
- if (aspect2 != other.aspect2) {
- return false;
- }
- return true;
- }
-
- @Override public int hashCode() {
- int result = 17;
- result = 37 * result + aspect1;
- result = 37 * result + aspect2;
- return result;
- }
- }
-
- /** Test class with invalid hashCode method. */
- private static class InvalidHashCodeObject {
- private int aspect1;
- private int aspect2;
-
- InvalidHashCodeObject(int aspect1, int aspect2) {
- this.aspect1 = aspect1;
- this.aspect2 = aspect2;
- }
-
- @Override public boolean equals(Object o) {
- if (!(o instanceof InvalidHashCodeObject)) {
- return false;
- }
- InvalidHashCodeObject other = (InvalidHashCodeObject) o;
- if (aspect1 != other.aspect1) {
- return false;
- }
- if (aspect2 != other.aspect2) {
- return false;
- }
- return true;
- }
- }
-
- /** Test class that violates reflexitivity. It is not equal to itself */
- private static class NonReflexiveObject{
-
- @Override public boolean equals(Object o) {
- return false;
- }
-
- @Override public int hashCode() {
- return super.hashCode();
- }
- }
-
- /** Test class that returns true if the test object is null */
- private static class InvalidEqualsNullObject{
-
- @Override public boolean equals(Object o) {
- return o == this || o == null;
- }
-
- @Override public int hashCode() {
- return 0;
- }
- }
-
- /**
- * Test class that returns true even if the test object is of the wrong class
- */
- private static class InvalidEqualsIncompatibleClassObject{
-
- @Override public boolean equals(Object o) {
- if (o == null) {
- return false;
- }
- return true;
- }
-
- @Override public int hashCode() {
- return 0;
- }
- }
-
- private static NamedObject named(String name) {
- return new NamedObject(name);
- }
-
- private static class NamedObject {
- private final Set<String> peerNames = Sets.newHashSet();
-
- private final String name;
-
- NamedObject(String name) {
- this.name = Preconditions.checkNotNull(name);
- }
-
- NamedObject addPeers(String... names) {
- peerNames.addAll(ImmutableList.copyOf(names));
- return this;
- }
-
- @Override public boolean equals(Object obj) {
- if (obj instanceof NamedObject) {
- NamedObject that = (NamedObject) obj;
- return name.equals(that.name) || peerNames.contains(that.name);
- }
- return false;
- }
-
- @Override public int hashCode() {
- return 0;
- }
-
- @Override public String toString() {
- return name;
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/testing/EquivalenceTesterTest.java b/guava-tests/test/com/google/common/testing/EquivalenceTesterTest.java
deleted file mode 100644
index 0bfb8f1..0000000
--- a/guava-tests/test/com/google/common/testing/EquivalenceTesterTest.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2011 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static com.google.common.base.Preconditions.checkState;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.base.Equivalence;
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableTable;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-/**
- * Tests for {@link EquivalenceTester}.
- *
- * @author Gregory Kick
- */
-@GwtCompatible
-public class EquivalenceTesterTest extends TestCase {
- private EquivalenceTester<Object> tester;
- private MockEquivalence equivalenceMock;
-
- @Override public void setUp() throws Exception {
- super.setUp();
- this.equivalenceMock = new MockEquivalence();
- this.tester = EquivalenceTester.of(equivalenceMock);
- }
-
- /** Test null reference yields error */
- public void testOf_NullPointerException() {
- try {
- EquivalenceTester.of(null);
- fail("Should fail on null reference");
- } catch (NullPointerException expected) {}
- }
-
- public void testTest_NoData() {
- tester.test();
- }
-
- public void testTest() {
- Object group1Item1 = new TestObject(1, 1);
- Object group1Item2 = new TestObject(1, 2);
- Object group2Item1 = new TestObject(2, 1);
- Object group2Item2 = new TestObject(2, 2);
-
- equivalenceMock.expectEquivalent(group1Item1, group1Item2);
- equivalenceMock.expectDistinct(group1Item1, group2Item1);
- equivalenceMock.expectDistinct(group1Item1, group2Item2);
- equivalenceMock.expectEquivalent(group1Item2, group1Item1);
- equivalenceMock.expectDistinct(group1Item2, group2Item1);
- equivalenceMock.expectDistinct(group1Item2, group2Item2);
- equivalenceMock.expectDistinct(group2Item1, group1Item1);
- equivalenceMock.expectDistinct(group2Item1, group1Item2);
- equivalenceMock.expectEquivalent(group2Item1, group2Item2);
- equivalenceMock.expectDistinct(group2Item2, group1Item1);
- equivalenceMock.expectDistinct(group2Item2, group1Item2);
- equivalenceMock.expectEquivalent(group2Item2, group2Item1);
-
- equivalenceMock.expectHash(group1Item1, 1);
- equivalenceMock.expectHash(group1Item2, 1);
- equivalenceMock.expectHash(group2Item1, 2);
- equivalenceMock.expectHash(group2Item2, 2);
-
- equivalenceMock.replay();
-
- tester.addEquivalenceGroup(group1Item1, group1Item2)
- .addEquivalenceGroup(group2Item1, group2Item2)
- .test();
- }
-
- public void testTest_symmetric() {
- Object group1Item1 = new TestObject(1, 1);
- Object group1Item2 = new TestObject(1, 2);
-
- equivalenceMock.expectEquivalent(group1Item1, group1Item2);
- equivalenceMock.expectDistinct(group1Item2, group1Item1);
-
- equivalenceMock.expectHash(group1Item1, 1);
- equivalenceMock.expectHash(group1Item2, 1);
-
- equivalenceMock.replay();
-
- try {
- tester.addEquivalenceGroup(group1Item1, group1Item2).test();
- } catch (AssertionFailedError expected) {
- assertEquals("TestObject{group=1, item=2} [group 1, item 2] must be equivalent to "
- + "TestObject{group=1, item=1} [group 1, item 1]", expected.getMessage());
- return;
- }
- fail();
- }
-
- public void testTest_trasitive() {
- Object group1Item1 = new TestObject(1, 1);
- Object group1Item2 = new TestObject(1, 2);
- Object group1Item3 = new TestObject(1, 3);
-
- equivalenceMock.expectEquivalent(group1Item1, group1Item2);
- equivalenceMock.expectEquivalent(group1Item1, group1Item3);
- equivalenceMock.expectEquivalent(group1Item2, group1Item1);
- equivalenceMock.expectDistinct(group1Item2, group1Item3);
- equivalenceMock.expectEquivalent(group1Item3, group1Item1);
- equivalenceMock.expectEquivalent(group1Item3, group1Item2);
-
- equivalenceMock.expectHash(group1Item1, 1);
- equivalenceMock.expectHash(group1Item2, 1);
- equivalenceMock.expectHash(group1Item3, 1);
-
- equivalenceMock.replay();
-
- try {
- tester.addEquivalenceGroup(group1Item1, group1Item2, group1Item3).test();
- } catch (AssertionFailedError expected) {
- assertEquals("TestObject{group=1, item=2} [group 1, item 2] must be equivalent to "
- + "TestObject{group=1, item=3} [group 1, item 3]", expected.getMessage());
- return;
- }
- fail();
- }
-
- public void testTest_inequivalence() {
- Object group1Item1 = new TestObject(1, 1);
- Object group2Item1 = new TestObject(2, 1);
-
- equivalenceMock.expectEquivalent(group1Item1, group2Item1);
- equivalenceMock.expectDistinct(group2Item1, group1Item1);
-
- equivalenceMock.expectHash(group1Item1, 1);
- equivalenceMock.expectHash(group2Item1, 2);
-
- equivalenceMock.replay();
-
- try {
- tester.addEquivalenceGroup(group1Item1).addEquivalenceGroup(group2Item1).test();
- } catch (AssertionFailedError expected) {
- assertEquals("TestObject{group=1, item=1} [group 1, item 1] must be inequivalent to "
- + "TestObject{group=2, item=1} [group 2, item 1]", expected.getMessage());
- return;
- }
- fail();
- }
-
- public void testTest_hash() {
- Object group1Item1 = new TestObject(1, 1);
- Object group1Item2 = new TestObject(1, 2);
-
- equivalenceMock.expectEquivalent(group1Item1, group1Item2);
- equivalenceMock.expectEquivalent(group1Item2, group1Item1);
-
- equivalenceMock.expectHash(group1Item1, 1);
- equivalenceMock.expectHash(group1Item2, 2);
-
- equivalenceMock.replay();
-
- try {
- tester.addEquivalenceGroup(group1Item1, group1Item2).test();
- } catch (AssertionFailedError expected) {
- String expectedMessage =
- "the hash (1) of TestObject{group=1, item=1} [group 1, item 1] must be "
- + "equal to the hash (2) of TestObject{group=1, item=2} [group 1, item 2]";
- if (!expected.getMessage().contains(expectedMessage)) {
- fail("<" + expected.getMessage() + "> expected to contain <" + expectedMessage + ">");
- }
- return;
- }
- fail();
- }
-
- /** An object with a friendly {@link #toString()}. */
- private static final class TestObject {
- final int group;
- final int item;
-
- TestObject(int group , int item) {
- this.group = group;
- this.item = item;
- }
-
- @Override public String toString() {
- return Objects.toStringHelper("TestObject")
- .add("group", group)
- .add("item", item)
- .toString();
- }
- }
-
- private static final class MockEquivalence extends Equivalence<Object> {
- final ImmutableTable.Builder<Object, Object, Boolean> equivalentExpectationsBuilder =
- ImmutableTable.builder();
- final ImmutableMap.Builder<Object, Integer> hashExpectationsBuilder =
- ImmutableMap.builder();
- ImmutableTable<Object, Object, Boolean> equivalentExpectations;
- ImmutableMap<Object, Integer> hashExpectations;
-
- void expectEquivalent(Object a, Object b) {
- checkRecording();
- equivalentExpectationsBuilder.put(a, b, true);
- }
-
- void expectDistinct(Object a, Object b) {
- checkRecording();
- equivalentExpectationsBuilder.put(a, b, false);
- }
-
- void expectHash(Object object, int hash) {
- checkRecording();
- hashExpectationsBuilder.put(object, hash);
- }
-
- void replay() {
- checkRecording();
- equivalentExpectations = equivalentExpectationsBuilder.build();
- hashExpectations = hashExpectationsBuilder.build();
- }
-
- @Override protected boolean doEquivalent(Object a, Object b) {
- return equivalentExpectations.get(a, b);
- }
-
- @Override protected int doHash(Object object) {
- return hashExpectations.get(object);
- }
-
- void checkRecording() {
- checkState(equivalentExpectations == null && hashExpectations == null);
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/testing/FakeTickerTest.java b/guava-tests/test/com/google/common/testing/FakeTickerTest.java
deleted file mode 100644
index 10a1886..0000000
--- a/guava-tests/test/com/google/common/testing/FakeTickerTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2008 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import com.google.common.annotations.GwtCompatible;
-import com.google.common.annotations.GwtIncompatible;
-
-import junit.framework.TestCase;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Unit test for {@link FakeTicker}.
- *
- * @author benyu@google.com (Jige Yu)
- */
-@GwtCompatible(emulated = true)
-public class FakeTickerTest extends TestCase {
-
- public void testAdvance() {
- FakeTicker ticker = new FakeTicker();
- assertEquals(0, ticker.read());
- assertSame(ticker, ticker.advance(10));
- assertEquals(10, ticker.read());
- ticker.advance(1, TimeUnit.MILLISECONDS);
- assertEquals(1000010L, ticker.read());
- }
-
- @GwtIncompatible("concurrency")
-
- public void testConcurrentAdvance() throws Exception {
- final FakeTicker ticker = new FakeTicker();
-
- int numberOfThreads = 64;
- ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads);
- final CountDownLatch startLatch = new CountDownLatch(numberOfThreads);
- final CountDownLatch doneLatch = new CountDownLatch(numberOfThreads);
- for (int i = numberOfThreads; i > 0; i--) {
- executorService.submit(new Callable<Void>() {
- @Override
- public Void call() throws Exception {
- // adds two nanoseconds to the ticker
- startLatch.countDown();
- startLatch.await();
- ticker.advance(1L);
- Thread.sleep(10);
- ticker.advance(1L);
- doneLatch.countDown();
- return null;
- }
- });
- }
- doneLatch.await();
- assertEquals(numberOfThreads * 2, ticker.read());
- }
-}
diff --git a/guava-tests/test/com/google/common/testing/GcFinalizationTest.java b/guava-tests/test/com/google/common/testing/GcFinalizationTest.java
deleted file mode 100644
index 35299f5..0000000
--- a/guava-tests/test/com/google/common/testing/GcFinalizationTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-
-package com.google.common.testing;
-
-import com.google.common.testing.GcFinalization.FinalizationPredicate;
-import com.google.common.util.concurrent.SettableFuture;
-
-import junit.framework.TestCase;
-
-import java.lang.ref.WeakReference;
-import java.util.WeakHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Tests for {@link GcFinalization}.
- *
- * @author martinrb@google.com (Martin Buchholz)
- * @author schmoe@google.com (mike nonemacher)
- */
-
-public class GcFinalizationTest extends TestCase {
-
- //----------------------------------------------------------------
- // Ordinary tests of successful method execution
- //----------------------------------------------------------------
-
- public void testAwait_CountDownLatch() {
- final CountDownLatch latch = new CountDownLatch(1);
- Object x = new Object() {
- protected void finalize() { latch.countDown(); }
- };
- x = null; // Hint to the JIT that x is unreachable
- GcFinalization.await(latch);
- assertEquals(0, latch.getCount());
- }
-
- public void testAwaitDone_Future() {
- final SettableFuture<Void> future = SettableFuture.create();
- Object x = new Object() {
- protected void finalize() { future.set(null); }
- };
- x = null; // Hint to the JIT that x is unreachable
- GcFinalization.awaitDone(future);
- assertTrue(future.isDone());
- assertFalse(future.isCancelled());
- }
-
- public void testAwaitDone_Future_Cancel() {
- final SettableFuture<Void> future = SettableFuture.create();
- Object x = new Object() {
- protected void finalize() { future.cancel(false); }
- };
- x = null; // Hint to the JIT that x is unreachable
- GcFinalization.awaitDone(future);
- assertTrue(future.isDone());
- assertTrue(future.isCancelled());
- }
-
- public void testAwaitClear() {
- final WeakReference<Object> ref = new WeakReference<Object>(new Object());
- GcFinalization.awaitClear(ref);
- assertNull(ref.get());
- }
-
- public void testAwaitDone_FinalizationPredicate() {
- final WeakHashMap<Object, Object> map = new WeakHashMap<Object, Object>();
- map.put(new Object(), Boolean.TRUE);
- GcFinalization.awaitDone(new FinalizationPredicate() {
- public boolean isDone() {
- return map.isEmpty();
- }
- });
- assertTrue(map.isEmpty());
- }
-
- //----------------------------------------------------------------
- // Test that interrupts result in RuntimeException, not InterruptedException.
- // Trickier than it looks, because runFinalization swallows interrupts.
- //----------------------------------------------------------------
-
- class Interruptenator extends Thread {
- final AtomicBoolean shutdown;
- Interruptenator(final Thread interruptee) {
- this(interruptee, new AtomicBoolean(false));
- }
- Interruptenator(final Thread interruptee,
- final AtomicBoolean shutdown) {
- super(new Runnable() {
- public void run() {
- while (!shutdown.get()) {
- interruptee.interrupt();
- Thread.yield();
- }}});
- this.shutdown = shutdown;
- start();
- }
- void shutdown() {
- shutdown.set(true);
- while (this.isAlive()) {
- Thread.yield();
- }
- }
- }
-
- void assertWrapsInterruptedException(RuntimeException e) {
- assertTrue(e.getMessage().contains("Unexpected interrupt"));
- assertTrue(e.getCause() instanceof InterruptedException);
- }
-
- public void testAwait_CountDownLatch_Interrupted() {
- Interruptenator interruptenator = new Interruptenator(Thread.currentThread());
- try {
- final CountDownLatch latch = new CountDownLatch(1);
- try {
- GcFinalization.await(latch);
- fail("should throw");
- } catch (RuntimeException expected) {
- assertWrapsInterruptedException(expected);
- }
- } finally {
- interruptenator.shutdown();
- Thread.interrupted();
- }
- }
-
- public void testAwaitDone_Future_Interrupted_Interrupted() {
- Interruptenator interruptenator = new Interruptenator(Thread.currentThread());
- try {
- final SettableFuture<Void> future = SettableFuture.create();
- try {
- GcFinalization.awaitDone(future);
- fail("should throw");
- } catch (RuntimeException expected) {
- assertWrapsInterruptedException(expected);
- }
- } finally {
- interruptenator.shutdown();
- Thread.interrupted();
- }
- }
-
- public void testAwaitClear_Interrupted() {
- Interruptenator interruptenator = new Interruptenator(Thread.currentThread());
- try {
- final WeakReference<Object> ref = new WeakReference<Object>(Boolean.TRUE);
- try {
- GcFinalization.awaitClear(ref);
- fail("should throw");
- } catch (RuntimeException expected) {
- assertWrapsInterruptedException(expected);
- }
- } finally {
- interruptenator.shutdown();
- Thread.interrupted();
- }
- }
-
- public void testAwaitDone_FinalizationPredicate_Interrupted() {
- Interruptenator interruptenator = new Interruptenator(Thread.currentThread());
- try {
- try {
- GcFinalization.awaitDone(new FinalizationPredicate() {
- public boolean isDone() {
- return false;
- }
- });
- fail("should throw");
- } catch (RuntimeException expected) {
- assertWrapsInterruptedException(expected);
- }
- } finally {
- interruptenator.shutdown();
- Thread.interrupted();
- }
- }
-
-}
diff --git a/guava-tests/test/com/google/common/testing/NullPointerTesterTest.java b/guava-tests/test/com/google/common/testing/NullPointerTesterTest.java
deleted file mode 100644
index 7d0ea99..0000000
--- a/guava-tests/test/com/google/common/testing/NullPointerTesterTest.java
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright (C) 2005 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-/**
- * Unit test for {@link NullPointerTester}.
- *
- * @author Kevin Bourrillion
- * @author Mick Killianey
- */
-public class NullPointerTesterTest extends TestCase {
-
- private NullPointerTester tester;
-
- @Override protected void setUp() throws Exception {
- super.setUp();
- tester = new NullPointerTester();
- }
-
- /** Non-NPE RuntimeException. */
- public static class FooException extends RuntimeException {
- private static final long serialVersionUID = 1L;
- }
-
- /**
- * Class for testing all permutations of static/non-static one-argument
- * methods using methodParameter().
- */
- public static class OneArg {
-
- public static void staticOneArgCorrectlyThrowsNpe(String s) {
- checkNotNull(s); // expect NPE here on null
- }
- public static void staticOneArgThrowsOtherThanNpe(String s) {
- throw new FooException(); // should catch as failure
- }
- public static void staticOneArgShouldThrowNpeButDoesnt(String s) {
- // should catch as failure
- }
- public static void
- staticOneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) {
- // null? no problem
- }
- public static void
- staticOneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) {
- throw new FooException(); // ok, as long as it's not NullPointerException
- }
- public static void
- staticOneArgNullableThrowsNPE(@Nullable String s) {
- checkNotNull(s); // doesn't check if you said you'd accept null, but you don't
- }
-
- public void oneArgCorrectlyThrowsNpe(String s) {
- checkNotNull(s); // expect NPE here on null
- }
- public void oneArgThrowsOtherThanNpe(String s) {
- throw new FooException(); // should catch as failure
- }
- public void oneArgShouldThrowNpeButDoesnt(String s) {
- // should catch as failure
- }
- public void oneArgNullableCorrectlyDoesNotThrowNPE(@Nullable String s) {
- // null? no problem
- }
- public void oneArgNullableCorrectlyThrowsOtherThanNPE(@Nullable String s) {
- throw new FooException(); // ok, as long as it's not NullPointerException
- }
- public void oneArgNullableThrowsNPE(@Nullable String s) {
- checkNotNull(s); // doesn't check if you said you'd accept null, but you don't
- }
- }
-
- private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_PASS = {
- "staticOneArgCorrectlyThrowsNpe",
- "staticOneArgNullableCorrectlyDoesNotThrowNPE",
- "staticOneArgNullableCorrectlyThrowsOtherThanNPE",
- "staticOneArgNullableThrowsNPE",
- };
- private static final String[] STATIC_ONE_ARG_METHODS_SHOULD_FAIL = {
- "staticOneArgThrowsOtherThanNpe",
- "staticOneArgShouldThrowNpeButDoesnt",
- };
- private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS = {
- "oneArgCorrectlyThrowsNpe",
- "oneArgNullableCorrectlyDoesNotThrowNPE",
- "oneArgNullableCorrectlyThrowsOtherThanNPE",
- "oneArgNullableThrowsNPE",
- };
- private static final String[] NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL = {
- "oneArgThrowsOtherThanNpe",
- "oneArgShouldThrowNpeButDoesnt",
- };
-
- public void testStaticOneArgMethodsThatShouldPass() throws Exception {
- for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_PASS) {
- Method method = OneArg.class.getMethod(methodName, String.class);
- try {
- tester.testMethodParameter(OneArg.class, method, 0);
- } catch (AssertionFailedError unexpected) {
- fail("Should not have flagged method " + methodName);
- }
- }
- }
-
- public void testStaticOneArgMethodsThatShouldFail() throws Exception {
- for (String methodName : STATIC_ONE_ARG_METHODS_SHOULD_FAIL) {
- Method method = OneArg.class.getMethod(methodName, String.class);
- boolean foundProblem = false;
- try {
- tester.testMethodParameter(OneArg.class, method, 0);
- } catch (AssertionFailedError expected) {
- foundProblem = true;
- }
- assertTrue("Should report error in method " + methodName, foundProblem);
- }
- }
-
- public void testNonStaticOneArgMethodsThatShouldPass() throws Exception {
- OneArg foo = new OneArg();
- for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_PASS) {
- Method method = OneArg.class.getMethod(methodName, String.class);
- try {
- tester.testMethodParameter(foo, method, 0);
- } catch (AssertionFailedError unexpected) {
- fail("Should not have flagged method " + methodName);
- }
- }
- }
-
- public void testNonStaticOneArgMethodsThatShouldFail() throws Exception {
- OneArg foo = new OneArg();
- for (String methodName : NONSTATIC_ONE_ARG_METHODS_SHOULD_FAIL) {
- Method method = OneArg.class.getMethod(methodName, String.class);
- boolean foundProblem = false;
- try {
- tester.testMethodParameter(foo, method, 0);
- } catch (AssertionFailedError expected) {
- foundProblem = true;
- }
- assertTrue("Should report error in method " + methodName, foundProblem);
- }
- }
-
- /**
- * Class for testing all permutations of nullable/non-nullable two-argument
- * methods using testMethod().
- *
- * normalNormal: two params, neither is Nullable
- * nullableNormal: only first param is Nullable
- * normalNullable: only second param is Nullable
- * nullableNullable: both params are Nullable
- */
- public static class TwoArg {
- /** Action to take on a null param. */
- public enum Action {
- THROW_A_NPE {
- @Override public void act() {
- throw new NullPointerException();
- }
- },
- THROW_OTHER {
- @Override public void act() {
- throw new FooException();
- }
- },
- JUST_RETURN {
- @Override public void act() {}
- };
-
- public abstract void act();
- }
- Action actionWhenFirstParamIsNull;
- Action actionWhenSecondParamIsNull;
-
- public TwoArg(
- Action actionWhenFirstParamIsNull,
- Action actionWhenSecondParamIsNull) {
- this.actionWhenFirstParamIsNull = actionWhenFirstParamIsNull;
- this.actionWhenSecondParamIsNull = actionWhenSecondParamIsNull;
- }
-
- /** Method that decides how to react to parameters. */
- public void reactToNullParameters(Object first, Object second) {
- if (first == null) {
- actionWhenFirstParamIsNull.act();
- }
- if (second == null) {
- actionWhenSecondParamIsNull.act();
- }
- }
-
- /** Two-arg method with no Nullable params. */
- public void normalNormal(String first, Integer second) {
- reactToNullParameters(first, second);
- }
-
- /** Two-arg method with the second param Nullable. */
- public void normalNullable(String first, @Nullable Integer second) {
- reactToNullParameters(first, second);
- }
-
- /** Two-arg method with the first param Nullable. */
- public void nullableNormal(@Nullable String first, Integer second) {
- reactToNullParameters(first, second);
- }
-
- /** Two-arg method with the both params Nullable. */
- public void nullableNullable(
- @Nullable String first, @Nullable Integer second) {
- reactToNullParameters(first, second);
- }
-
- /** To provide sanity during debugging. */
- @Override public String toString() {
- return String.format("Bar(%s, %s)",
- actionWhenFirstParamIsNull, actionWhenSecondParamIsNull);
- }
- }
-
- public void verifyBarPass(Method method, TwoArg bar) throws Exception {
- try {
- tester.testMethod(bar, method);
- } catch (AssertionFailedError incorrectError) {
- String errorMessage = String.format(
- "Should not have flagged method %s for %s", method.getName(), bar);
- assertNull(errorMessage, incorrectError);
- }
- }
-
- public void verifyBarFail(Method method, TwoArg bar) throws Exception {
- try {
- tester.testMethod(bar, method);
- } catch (AssertionFailedError expected) {
- return; // good...we wanted a failure
- }
- String errorMessage = String.format(
- "Should have flagged method %s for %s", method.getName(), bar);
- fail(errorMessage);
- }
-
- public void testTwoArgNormalNormal() throws Exception {
- Method method = TwoArg.class.getMethod(
- "normalNormal", String.class, Integer.class);
- for (TwoArg.Action first : TwoArg.Action.values()) {
- for (TwoArg.Action second : TwoArg.Action.values()) {
- TwoArg bar = new TwoArg(first, second);
- if (first.equals(TwoArg.Action.THROW_A_NPE)
- && second.equals(TwoArg.Action.THROW_A_NPE)) {
- verifyBarPass(method, bar); // require both params to throw NPE
- } else {
- verifyBarFail(method, bar);
- }
- }
- }
- }
-
- public void testTwoArgNormalNullable() throws Exception {
- Method method = TwoArg.class.getMethod(
- "normalNullable", String.class, Integer.class);
- for (TwoArg.Action first : TwoArg.Action.values()) {
- for (TwoArg.Action second : TwoArg.Action.values()) {
- TwoArg bar = new TwoArg(first, second);
- if (first.equals(TwoArg.Action.THROW_A_NPE)) {
- verifyBarPass(method, bar); // only pass if 1st param throws NPE
- } else {
- verifyBarFail(method, bar);
- }
- }
- }
- }
-
- public void testTwoArgNullableNormal() throws Exception {
- Method method = TwoArg.class.getMethod(
- "nullableNormal", String.class, Integer.class);
- for (TwoArg.Action first : TwoArg.Action.values()) {
- for (TwoArg.Action second : TwoArg.Action.values()) {
- TwoArg bar = new TwoArg(first, second);
- if (second.equals(TwoArg.Action.THROW_A_NPE)) {
- verifyBarPass(method, bar); // only pass if 2nd param throws NPE
- } else {
- verifyBarFail(method, bar);
- }
- }
- }
- }
-
- public void testTwoArgNullableNullable() throws Exception {
- Method method = TwoArg.class.getMethod(
- "nullableNullable", String.class, Integer.class);
- for (TwoArg.Action first : TwoArg.Action.values()) {
- for (TwoArg.Action second : TwoArg.Action.values()) {
- TwoArg bar = new TwoArg(first, second);
- verifyBarPass(method, bar); // All args nullable: anything goes!
- }
- }
- }
-
- /*
- * This next part consists of several sample classes that provide
- * demonstrations of conditions that cause NullPointerTester
- * to succeed/fail.
- *
- * Add naughty classes to failClasses to verify that NullPointerTest
- * raises an AssertionFailedError.
- *
- * Add acceptable classes to passClasses to verify that NullPointerTest
- * doesn't complain.
- */
-
- /** List of classes that NullPointerTester should pass as acceptable. */
- static List<Class<?>> failClasses = Lists.newArrayList();
-
- /** List of classes that NullPointerTester should flag as problematic. */
- static List<Class<?>> passClasses = Lists.newArrayList();
-
- /** Lots of well-behaved methods. */
- public static class PassObject {
- public static void doThrow(Object arg) {
- if (arg == null) {
- throw new FooException();
- }
- }
- public void noArg() {}
- public void oneArg(String s) { checkNotNull(s); }
- public void oneNullableArg(@Nullable String s) {}
- public void oneNullableArgThrows(@Nullable String s) { doThrow(s); }
-
- public void twoArg(String s, Integer i) { checkNotNull(s); i.intValue(); }
- public void twoMixedArgs(String s, @Nullable Integer i) { checkNotNull(s); }
- public void twoMixedArgsThrows(String s, @Nullable Integer i) {
- checkNotNull(s); doThrow(i);
- }
- public void twoMixedArgs(@Nullable Integer i, String s) { checkNotNull(s); }
- public void twoMixedArgsThrows(@Nullable Integer i, String s) {
- checkNotNull(s); doThrow(i);
- }
- public void twoNullableArgs(@Nullable String s,
- @javax.annotation.Nullable Integer i) { }
- public void twoNullableArgsThrowsFirstArg(
- @Nullable String s, @Nullable Integer i) {
- doThrow(s);
- }
- public void twoNullableArgsThrowsSecondArg(
- @Nullable String s, @Nullable Integer i) {
- doThrow(i);
- }
- public static void staticOneArg(String s) { checkNotNull(s); }
- public static void staticOneNullableArg(@Nullable String s) { }
- public static void staticOneNullableArgThrows(@Nullable String s) {
- doThrow(s);
- }
- }
- static { passClasses.add(PassObject.class); }
-
- static class FailOneArgDoesntThrowNPE extends PassObject {
- @Override public void oneArg(String s) {
- // Fail: missing NPE for s
- }
- }
- static { failClasses.add(FailOneArgDoesntThrowNPE.class); }
-
- static class FailOneArgThrowsWrongType extends PassObject {
- @Override public void oneArg(String s) {
- doThrow(s); // Fail: throwing non-NPE exception for null s
- }
- }
- static { failClasses.add(FailOneArgThrowsWrongType.class); }
-
- static class PassOneNullableArgThrowsNPE extends PassObject {
- @Override public void oneNullableArg(@Nullable String s) {
- checkNotNull(s); // ok to throw NPE
- }
- }
- static { passClasses.add(PassOneNullableArgThrowsNPE.class); }
-
- static class FailTwoArgsFirstArgDoesntThrowNPE extends PassObject {
- @Override public void twoArg(String s, Integer i) {
- // Fail: missing NPE for s
- i.intValue();
- }
- }
- static { failClasses.add(FailTwoArgsFirstArgDoesntThrowNPE.class); }
-
- static class FailTwoArgsFirstArgThrowsWrongType extends PassObject {
- @Override public void twoArg(String s, Integer i) {
- doThrow(s); // Fail: throwing non-NPE exception for null s
- i.intValue();
- }
- }
- static { failClasses.add(FailTwoArgsFirstArgThrowsWrongType.class); }
-
- static class FailTwoArgsSecondArgDoesntThrowNPE extends PassObject {
- @Override public void twoArg(String s, Integer i) {
- checkNotNull(s);
- // Fail: missing NPE for i
- }
- }
- static { failClasses.add(FailTwoArgsSecondArgDoesntThrowNPE.class); }
-
- static class FailTwoArgsSecondArgThrowsWrongType extends PassObject {
- @Override public void twoArg(String s, Integer i) {
- checkNotNull(s);
- doThrow(i); // Fail: throwing non-NPE exception for null i
- }
- }
- static { failClasses.add(FailTwoArgsSecondArgThrowsWrongType.class); }
-
- static class FailTwoMixedArgsFirstArgDoesntThrowNPE extends PassObject {
- @Override public void twoMixedArgs(String s, @Nullable Integer i) {
- // Fail: missing NPE for s
- }
- }
- static { failClasses.add(FailTwoMixedArgsFirstArgDoesntThrowNPE.class); }
-
- static class FailTwoMixedArgsFirstArgThrowsWrongType extends PassObject {
- @Override public void twoMixedArgs(String s, @Nullable Integer i) {
- doThrow(s); // Fail: throwing non-NPE exception for null s
- }
- }
- static { failClasses.add(FailTwoMixedArgsFirstArgThrowsWrongType.class); }
-
- static class PassTwoMixedArgsNullableArgThrowsNPE extends PassObject {
- @Override public void twoMixedArgs(String s, @Nullable Integer i) {
- checkNotNull(s);
- i.intValue(); // ok to throw NPE?
- }
- }
- static { passClasses.add(PassTwoMixedArgsNullableArgThrowsNPE.class); }
-
- static class PassTwoMixedArgSecondNullableArgThrowsOther extends PassObject {
- @Override public void twoMixedArgs(String s, @Nullable Integer i) {
- checkNotNull(s);
- doThrow(i); // ok to throw non-NPE exception for null i
- }
- }
- static { passClasses.add(PassTwoMixedArgSecondNullableArgThrowsOther.class); }
-
- static class FailTwoMixedArgsSecondArgDoesntThrowNPE extends PassObject {
- @Override public void twoMixedArgs(@Nullable Integer i, String s) {
- // Fail: missing NPE for null s
- }
- }
- static { failClasses.add(FailTwoMixedArgsSecondArgDoesntThrowNPE.class); }
-
- static class FailTwoMixedArgsSecondArgThrowsWrongType extends PassObject {
- @Override public void twoMixedArgs(@Nullable Integer i, String s) {
- doThrow(s); // Fail: throwing non-NPE exception for null s
- }
- }
- static { failClasses.add(FailTwoMixedArgsSecondArgThrowsWrongType.class); }
-
- static class PassTwoNullableArgsFirstThrowsNPE extends PassObject {
- @Override public void twoNullableArgs(
- @Nullable String s, @Nullable Integer i) {
- checkNotNull(s); // ok to throw NPE?
- }
- }
- static { passClasses.add(PassTwoNullableArgsFirstThrowsNPE.class); }
-
- static class PassTwoNullableArgsFirstThrowsOther extends PassObject {
- @Override public void twoNullableArgs(
- @Nullable String s, @Nullable Integer i) {
- doThrow(s); // ok to throw non-NPE exception for null s
- }
- }
- static { passClasses.add(PassTwoNullableArgsFirstThrowsOther.class); }
-
- static class PassTwoNullableArgsSecondThrowsNPE extends PassObject {
- @Override public void twoNullableArgs(
- @Nullable String s, @Nullable Integer i) {
- i.intValue(); // ok to throw NPE?
- }
- }
- static { passClasses.add(PassTwoNullableArgsSecondThrowsNPE.class); }
-
- static class PassTwoNullableArgsSecondThrowsOther extends PassObject {
- @Override public void twoNullableArgs(
- @Nullable String s, @Nullable Integer i) {
- doThrow(i); // ok to throw non-NPE exception for null i
- }
- }
- static { passClasses.add(PassTwoNullableArgsSecondThrowsOther.class); }
-
- static class PassTwoNullableArgsNeitherThrowsAnything extends PassObject {
- @Override public void twoNullableArgs(
- @Nullable String s, @Nullable Integer i) {
- // ok to do nothing
- }
- }
- static { passClasses.add(PassTwoNullableArgsNeitherThrowsAnything.class); }
-
- /** Sanity check: it's easy to make typos. */
- private void checkClasses(String message, List<Class<?>> classes) {
- Set<Class<?>> set = Sets.newHashSet(classes);
- for (Class<?> clazz : classes) {
- if (!set.remove(clazz)) {
- fail(String.format("%s: %s appears twice. Typo?",
- message, clazz.getSimpleName()));
- }
- }
- }
-
- public void testDidntMakeTypoInTestCases() {
- checkClasses("passClass", passClasses);
- checkClasses("failClasses", failClasses);
- List<Class<?>> allClasses = Lists.newArrayList(passClasses);
- allClasses.addAll(failClasses);
- checkClasses("allClasses", allClasses);
- }
-
- public void testShouldNotFindProblemInPassClass() throws Exception {
- for (Class<?> passClass : passClasses) {
- Object instance = passClass.newInstance();
- try {
- tester.testAllPublicInstanceMethods(instance);
- } catch (AssertionFailedError e) {
- assertNull("Should not detect problem in " + passClass.getSimpleName(),
- e);
- }
- }
- }
-
- public void testShouldFindProblemInFailClass() throws Exception {
- for (Class<?> failClass : failClasses) {
- Object instance = failClass.newInstance();
- boolean foundProblem = false;
- try {
- tester.testAllPublicInstanceMethods(instance);
- } catch (AssertionFailedError e) {
- foundProblem = true;
- }
- assertTrue("Should detect problem in " + failClass.getSimpleName(),
- foundProblem);
- }
- }
-
- private static class PrivateClassWithPrivateConstructor {
- private PrivateClassWithPrivateConstructor(@Nullable Integer argument) {}
- }
-
- public void testPrivateClass() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- for (Constructor<?> constructor
- : PrivateClassWithPrivateConstructor.class.getDeclaredConstructors()) {
- tester.testConstructor(constructor);
- }
- }
-
- private interface Foo<T> {
- void doSomething(T bar, Integer baz);
- }
-
- private static class StringFoo implements Foo<String> {
-
- @Override public void doSomething(String bar, Integer baz) {
- checkNotNull(bar);
- checkNotNull(baz);
- }
- }
-
- public void testBidgeMethodIgnored() throws Exception {
- new NullPointerTester().testAllPublicInstanceMethods(new StringFoo());
- }
-
- /*
- *
- * TODO(kevinb): This is only a very small start.
- * Must come back and finish.
- *
- */
-
-}
diff --git a/guava-tests/test/com/google/common/testing/SerializableTesterTest.java b/guava-tests/test/com/google/common/testing/SerializableTesterTest.java
deleted file mode 100644
index d62860b..0000000
--- a/guava-tests/test/com/google/common/testing/SerializableTesterTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2009 The Guava Authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import java.io.Serializable;
-
-/**
- * Tests for {@link SerializableTester}.
- *
- * @author Nick Kralevich
- */
-public class SerializableTesterTest extends TestCase {
- public void testStringAssertions() {
- String original = "hello world";
- String copy = SerializableTester.reserializeAndAssert(original);
- assertEquals(original, copy);
- assertNotSame(original, copy);
- }
-
- public void testClassWhichDoesNotImplementEquals() {
- ClassWhichDoesNotImplementEquals orig =
- new ClassWhichDoesNotImplementEquals();
- boolean errorNotThrown = false;
- try {
- SerializableTester.reserializeAndAssert(orig);
- errorNotThrown = true;
- } catch (AssertionFailedError error) {
- // expected
- assertContains("must be equal to", error.getMessage());
- }
- assertFalse(errorNotThrown);
- }
-
- public void testClassWhichIsAlwaysEqualButHasDifferentHashcodes() {
- ClassWhichIsAlwaysEqualButHasDifferentHashcodes orig =
- new ClassWhichIsAlwaysEqualButHasDifferentHashcodes();
- boolean errorNotThrown = false;
- try {
- SerializableTester.reserializeAndAssert(orig);
- errorNotThrown = true;
- } catch (AssertionFailedError error) {
- // expected
- assertContains("must be equal to the hash", error.getMessage());
- }
- assertFalse(errorNotThrown);
- }
-
- public void testObjectWhichIsEqualButChangesClass() {
- ObjectWhichIsEqualButChangesClass orig =
- new ObjectWhichIsEqualButChangesClass();
- boolean errorNotThrown = false;
- try {
- SerializableTester.reserializeAndAssert(orig);
- errorNotThrown = true;
- } catch (AssertionFailedError error) {
- // expected
- assertContains("expected:<class ", error.getMessage());
- }
- assertFalse(errorNotThrown);
- }
-
- private static class ClassWhichDoesNotImplementEquals
- implements Serializable {
- private static final long serialVersionUID = 1L;
- }
-
- private static class ClassWhichIsAlwaysEqualButHasDifferentHashcodes
- implements Serializable {
- private static final long serialVersionUID = 2L;
-
- @Override
- public boolean equals(Object other) {
- return (other instanceof ClassWhichIsAlwaysEqualButHasDifferentHashcodes);
- }
- }
-
- private static class ObjectWhichIsEqualButChangesClass
- implements Serializable {
- private static final long serialVersionUID = 1L;
-
- @Override
- public boolean equals(Object other) {
- return (other instanceof ObjectWhichIsEqualButChangesClass
- || other instanceof OtherForm);
- }
-
- @Override
- public int hashCode() {
- return 1;
- }
-
- private Object writeReplace() {
- return new OtherForm();
- }
-
- private static class OtherForm implements Serializable {
- @Override
- public boolean equals(Object other) {
- return (other instanceof ObjectWhichIsEqualButChangesClass
- || other instanceof OtherForm);
- }
-
- @Override
- public int hashCode() {
- return 1;
- }
- }
- }
-
- private static void assertContains(String expectedSubstring, String actual) {
- // TODO(kevinb): use a Truth assertion here
- if (!actual.contains(expectedSubstring)) {
- fail("expected <" + actual + "> to contain <" + expectedSubstring + ">");
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/testing/TearDownStackTest.java b/guava-tests/test/com/google/common/testing/TearDownStackTest.java
deleted file mode 100644
index ee26536..0000000
--- a/guava-tests/test/com/google/common/testing/TearDownStackTest.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2010 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import com.google.common.annotations.GwtCompatible;
-
-import junit.framework.TestCase;
-
-import org.junit.Test;
-
-/**
- * @author Luiz-Otavio "Z" Zorzella
- */
-@GwtCompatible
-public class TearDownStackTest extends TestCase {
-
- private TearDownStack tearDownStack = new TearDownStack();
-
- @Test
- public void testSingleTearDown() throws Exception {
- final TearDownStack stack = buildTearDownStack();
-
- final SimpleTearDown tearDown = new SimpleTearDown();
- stack.addTearDown(tearDown);
-
- assertEquals(false, tearDown.ran);
-
- stack.runTearDown();
-
- assertEquals("tearDown should have run", true, tearDown.ran);
- }
-
- @Test
- public void testMultipleTearDownsHappenInOrder() throws Exception {
- final TearDownStack stack = buildTearDownStack();
-
- final SimpleTearDown tearDownOne = new SimpleTearDown();
- stack.addTearDown(tearDownOne);
-
- final Callback callback = new Callback() {
- @Override
- public void run() {
- assertEquals("tearDownTwo should have been run before tearDownOne",
- false, tearDownOne.ran);
- }
- };
-
- final SimpleTearDown tearDownTwo = new SimpleTearDown(callback);
- stack.addTearDown(tearDownTwo);
-
- assertEquals(false, tearDownOne.ran);
- assertEquals(false, tearDownTwo.ran);
-
- stack.runTearDown();
-
- assertEquals("tearDownOne should have run", true, tearDownOne.ran);
- assertEquals("tearDownTwo should have run", true, tearDownTwo.ran);
- }
-
- @Test
- public void testThrowingTearDown() throws Exception {
- final TearDownStack stack = buildTearDownStack();
-
- final ThrowingTearDown tearDownOne = new ThrowingTearDown("one");
- stack.addTearDown(tearDownOne);
-
- final ThrowingTearDown tearDownTwo = new ThrowingTearDown("two");
- stack.addTearDown(tearDownTwo);
-
- assertEquals(false, tearDownOne.ran);
- assertEquals(false, tearDownTwo.ran);
-
- try {
- stack.runTearDown();
- fail("runTearDown should have thrown an exception");
- } catch (ClusterException expected) {
- assertEquals("two", expected.getCause().getMessage());
- } catch (RuntimeException e) {
- throw new RuntimeException(
- "A ClusterException should have been thrown, rather than a " + e.getClass().getName(), e);
- }
-
- assertEquals(true, tearDownOne.ran);
- assertEquals(true, tearDownTwo.ran);
- }
-
- @Override public final void runBare() throws Throwable {
- try {
- setUp();
- runTest();
- } finally {
- tearDown();
- }
- }
-
- @Override protected void tearDown() {
- tearDownStack.runTearDown();
- }
-
- /**
- * Builds a {@link TearDownStack} that makes sure it's clear by the end of
- * this test.
- */
- private TearDownStack buildTearDownStack() {
- final TearDownStack result = new TearDownStack();
- tearDownStack.addTearDown(new TearDown() {
-
- @Override
- public void tearDown() throws Exception {
- assertEquals(
- "The test should have cleared the stack (say, by virtue of running runTearDown)",
- 0, result.stack.size());
- }
- });
- return result;
- }
-
- private static final class ThrowingTearDown implements TearDown {
-
- private final String id;
- boolean ran = false;
-
- ThrowingTearDown(String id) {
- this.id = id;
- }
-
- @Override
- public void tearDown() throws Exception {
- ran = true;
- throw new RuntimeException(id);
- }
- }
-
- private static final class SimpleTearDown implements TearDown {
-
- boolean ran = false;
- Callback callback = null;
-
- public SimpleTearDown() {}
-
- public SimpleTearDown(Callback callback) {
- this.callback = callback;
- }
-
- @Override
- public void tearDown() throws Exception {
- if (callback != null) {
- callback.run();
- }
- ran = true;
- }
- }
-
- private interface Callback {
- void run();
- }
-}
diff --git a/guava-tests/test/com/google/common/testing/TestLogHandlerTest.java b/guava-tests/test/com/google/common/testing/TestLogHandlerTest.java
deleted file mode 100644
index 9dd4ad3..0000000
--- a/guava-tests/test/com/google/common/testing/TestLogHandlerTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.common.testing;
-
-import junit.framework.TestCase;
-
-import java.util.logging.Level;
-import java.util.logging.LogRecord;
-import java.util.logging.Logger;
-
-/**
- * Unit test for {@link TestLogHandler}.
- *
- * @author kevinb
- */
-public class TestLogHandlerTest extends TestCase {
-
- private TestLogHandler handler;
- private TearDownStack stack = new TearDownStack();
-
- @Override protected void setUp() throws Exception {
- super.setUp();
-
- handler = new TestLogHandler();
-
- // You could also apply it higher up the Logger hierarchy than this
- ExampleClassUnderTest.logger.addHandler(handler);
-
- ExampleClassUnderTest.logger.setUseParentHandlers(false); // optional
-
- stack.addTearDown(new TearDown() {
- @Override
- public void tearDown() throws Exception {
- ExampleClassUnderTest.logger.setUseParentHandlers(true);
- ExampleClassUnderTest.logger.removeHandler(handler);
- }
- });
- }
-
- public void test() throws Exception {
- assertTrue(handler.getStoredLogRecords().isEmpty());
- ExampleClassUnderTest.foo();
- LogRecord record = handler.getStoredLogRecords().iterator().next();
- assertEquals(Level.INFO, record.getLevel());
- assertEquals("message", record.getMessage());
- assertSame(EXCEPTION, record.getThrown());
- }
-
- public void testConcurrentModification() throws Exception {
- // Tests for the absence of a bug where logging while iterating over the
- // stored log records causes a ConcurrentModificationException
- assertTrue(handler.getStoredLogRecords().isEmpty());
- ExampleClassUnderTest.foo();
- ExampleClassUnderTest.foo();
- for (LogRecord record : handler.getStoredLogRecords()) {
- ExampleClassUnderTest.foo();
- }
- }
-
- @Override public final void runBare() throws Throwable {
- try {
- setUp();
- runTest();
- } finally {
- tearDown();
- }
- }
-
- @Override protected void tearDown() {
- stack.runTearDown();
- }
-
- static final Exception EXCEPTION = new Exception();
-
- static class ExampleClassUnderTest {
- static final Logger logger
- = Logger.getLogger(ExampleClassUnderTest.class.getName());
-
- static void foo() {
- logger.log(Level.INFO, "message", EXCEPTION);
- }
- }
-}
diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java
index d7fd91e..9b14c7d 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AbstractExecutionThreadServiceTest.java
@@ -17,6 +17,8 @@
package com.google.common.util.concurrent;
import com.google.common.base.Throwables;
+import com.google.common.testing.TearDown;
+import com.google.common.testing.TearDownStack;
import junit.framework.TestCase;
@@ -24,6 +26,8 @@ import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -35,6 +39,7 @@ import java.util.concurrent.TimeoutException;
*/
public class AbstractExecutionThreadServiceTest extends TestCase {
+ private final TearDownStack tearDownStack = new TearDownStack(true);
private final CountDownLatch enterRun = new CountDownLatch(1);
private final CountDownLatch exitRun = new CountDownLatch(1);
@@ -54,6 +59,10 @@ public class AbstractExecutionThreadServiceTest extends TestCase {
}
};
+ @Override protected final void tearDown() {
+ tearDownStack.runTearDown();
+ }
+
public void testServiceStartStop() throws Exception {
WaitOnRunService service = new WaitOnRunService();
assertFalse(service.startUpCalled);
@@ -299,4 +308,80 @@ public class AbstractExecutionThreadServiceTest extends TestCase {
}
}
+ public void testStopWhileStarting_runNotCalled() throws Exception {
+ final CountDownLatch started = new CountDownLatch(1);
+ FakeService service = new FakeService() {
+ @Override protected void startUp() throws Exception {
+ super.startUp();
+ started.await();
+ }
+ };
+ service.start();
+ ListenableFuture<Service.State> stopped = service.stop();
+ started.countDown();
+ assertEquals(Service.State.TERMINATED, stopped.get());
+ assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(1, service.startupCalled);
+ assertEquals(0, service.runCalled);
+ assertEquals(1, service.shutdownCalled);
+ }
+
+ public void testStop_noStart() {
+ FakeService service = new FakeService();
+ assertEquals(Service.State.TERMINATED, service.stopAndWait());
+ assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(0, service.startupCalled);
+ assertEquals(0, service.runCalled);
+ assertEquals(0, service.shutdownCalled);
+ }
+
+ public void testDefaultService() {
+ AbstractExecutionThreadService service = new AbstractExecutionThreadService() {
+ @Override protected void run() throws Exception {}
+ };
+ assertEquals(Service.State.RUNNING, service.startAndWait());
+ assertEquals(Service.State.TERMINATED, service.stopAndWait());
+ }
+
+ private class FakeService extends AbstractExecutionThreadService implements TearDown {
+
+ private final ExecutorService executor = Executors.newSingleThreadExecutor();
+
+ FakeService() {
+ tearDownStack.addTearDown(this);
+ }
+
+ volatile int startupCalled = 0;
+ volatile int shutdownCalled = 0;
+ volatile int runCalled = 0;
+
+ @Override protected void startUp() throws Exception {
+ assertEquals(0, startupCalled);
+ assertEquals(0, runCalled);
+ assertEquals(0, shutdownCalled);
+ startupCalled++;
+ }
+
+ @Override protected void run() throws Exception {
+ assertEquals(1, startupCalled);
+ assertEquals(0, runCalled);
+ assertEquals(0, shutdownCalled);
+ runCalled++;
+ }
+
+ @Override protected void shutDown() throws Exception {
+ assertEquals(1, startupCalled);
+ assertEquals(0, shutdownCalled);
+ assertEquals(Service.State.STOPPING, state());
+ shutdownCalled++;
+ }
+
+ @Override protected Executor executor() {
+ return executor;
+ }
+
+ @Override public void tearDown() throws Exception {
+ executor.shutdown();
+ }
+ }
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java
index a7dd412..4024a8e 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AbstractFutureTest.java
@@ -16,11 +16,12 @@
package com.google.common.util.concurrent;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
+import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -63,23 +64,37 @@ public class AbstractFutureTest extends TestCase {
checkStackTrace(ee2);
}
- public void testCancel_notDoneNoInterrupt() {
+ public void testCancel_notDoneNoInterrupt() throws Exception {
InterruptibleFuture future = new InterruptibleFuture();
assertTrue(future.cancel(false));
assertTrue(future.isCancelled());
assertTrue(future.isDone());
- assertFalse(future.wasInterrupted);
+ assertFalse(future.wasInterrupted());
+ assertFalse(future.interruptTaskWasCalled);
+ try {
+ future.get();
+ fail("Expected CancellationException");
+ } catch (CancellationException e) {
+ assertNotNull(e.getCause());
+ }
}
- public void testCancel_notDoneInterrupt() {
+ public void testCancel_notDoneInterrupt() throws Exception {
InterruptibleFuture future = new InterruptibleFuture();
assertTrue(future.cancel(true));
assertTrue(future.isCancelled());
assertTrue(future.isDone());
- assertTrue(future.wasInterrupted);
+ assertTrue(future.wasInterrupted());
+ assertTrue(future.interruptTaskWasCalled);
+ try {
+ future.get();
+ fail("Expected CancellationException");
+ } catch (CancellationException e) {
+ assertNotNull(e.getCause());
+ }
}
- public void testCancel_done() {
+ public void testCancel_done() throws Exception {
AbstractFuture<String> future = new AbstractFuture<String>() {
{
set("foo");
@@ -177,10 +192,11 @@ public class AbstractFutureTest extends TestCase {
private static final class InterruptibleFuture
extends AbstractFuture<String> {
- boolean wasInterrupted;
+ boolean interruptTaskWasCalled;
@Override protected void interruptTask() {
- wasInterrupted = true;
+ assertFalse(interruptTaskWasCalled);
+ interruptTaskWasCalled = true;
}
}
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java
index 8131a37..2939661 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AbstractIdleServiceTest.java
@@ -16,112 +16,200 @@
package com.google.common.util.concurrent;
-import com.google.common.util.concurrent.Service.State;
+import static org.truth0.Truth.ASSERT;
+
+import com.google.common.collect.Lists;
import junit.framework.TestCase;
-import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
- * Unit test for {@link AbstractIdleService}.
+ * Tests for {@link AbstractIdleService}.
*
* @author Chris Nokleberg
+ * @author Ben Yu
*/
public class AbstractIdleServiceTest extends TestCase {
- private Thread executorThread;
- private Throwable thrownByExecutorThread;
- private final Executor executor = new Executor() {
- @Override
- public void execute(Runnable command) {
- executorThread = new Thread(command);
- executorThread.setUncaughtExceptionHandler(
- new UncaughtExceptionHandler() {
- @Override
- public void uncaughtException(Thread thread, Throwable e) {
- thrownByExecutorThread = e;
- }
- });
- executorThread.start();
+
+ // Functional tests using real thread. We only verify publicly visible state.
+ // Interaction assertions are done by the single-threaded unit tests.
+
+ public static class FunctionalTest extends TestCase {
+
+ private static class DefaultService extends AbstractIdleService {
+ @Override protected void startUp() throws Exception {}
+ @Override protected void shutDown() throws Exception {}
}
- };
- public void testServiceStartStop() throws Exception {
- NullService service = new NullService();
- assertFalse(service.startUpCalled);
+ public void testServiceStartStop() throws Exception {
+ AbstractIdleService service = new DefaultService();
+ assertEquals(Service.State.RUNNING, service.startAndWait());
+ assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(Service.State.TERMINATED, service.stopAndWait());
+ assertEquals(Service.State.TERMINATED, service.state());
+ }
+
+ public void testStart_failed() throws Exception {
+ final Exception exception = new Exception("deliberate");
+ AbstractIdleService service = new DefaultService() {
+ @Override protected void startUp() throws Exception {
+ throw exception;
+ }
+ };
+ try {
+ service.startAndWait();
+ fail();
+ } catch (RuntimeException e) {
+ assertSame(exception, e.getCause());
+ }
+ assertEquals(Service.State.FAILED, service.state());
+ }
- service.start().get();
- assertTrue(service.startUpCalled);
+ public void testStop_failed() throws Exception {
+ final Exception exception = new Exception("deliberate");
+ AbstractIdleService service = new DefaultService() {
+ @Override protected void shutDown() throws Exception {
+ throw exception;
+ }
+ };
+ service.startAndWait();
+ try {
+ service.stopAndWait();
+ fail();
+ } catch (RuntimeException e) {
+ assertSame(exception, e.getCause());
+ }
+ assertEquals(Service.State.FAILED, service.state());
+ }
+ }
+
+ public void testStart() {
+ TestService service = new TestService();
+ assertEquals(0, service.startUpCalled);
+ service.startAndWait();
+ assertEquals(1, service.startUpCalled);
assertEquals(Service.State.RUNNING, service.state());
+ ASSERT.that(service.transitionStates).has().allOf(Service.State.STARTING).inOrder();
+ }
+
+ public void testStart_failed() {
+ final Exception exception = new Exception("deliberate");
+ TestService service = new TestService() {
+ @Override protected void startUp() throws Exception {
+ super.startUp();
+ throw exception;
+ }
+ };
+ assertEquals(0, service.startUpCalled);
+ try {
+ service.startAndWait();
+ fail();
+ } catch (RuntimeException e) {
+ assertSame(exception, e.getCause());
+ }
+ assertEquals(1, service.startUpCalled);
+ assertEquals(Service.State.FAILED, service.state());
+ ASSERT.that(service.transitionStates).has().allOf(Service.State.STARTING).inOrder();
+ }
- service.stop().get();
- assertTrue(service.shutDownCalled);
+ public void testStop_withoutStart() {
+ TestService service = new TestService();
+ service.stopAndWait();
+ assertEquals(0, service.startUpCalled);
+ assertEquals(0, service.shutDownCalled);
assertEquals(Service.State.TERMINATED, service.state());
- executorThread.join();
- assertNull(thrownByExecutorThread);
+ ASSERT.that(service.transitionStates).isEmpty();
}
- public void testServiceToString() throws Exception {
- NullService service = new NullService();
- assertEquals("NullService [" + Service.State.NEW + "]", service.toString());
- service.start().get();
- assertEquals("NullService [" + Service.State.RUNNING + "]", service.toString());
- service.stop().get();
- assertEquals("NullService [" + Service.State.TERMINATED + "]", service.toString());
+ public void testStop_afterStart() {
+ TestService service = new TestService();
+ service.startAndWait();
+ assertEquals(1, service.startUpCalled);
+ assertEquals(0, service.shutDownCalled);
+ service.stopAndWait();
+ assertEquals(1, service.startUpCalled);
+ assertEquals(1, service.shutDownCalled);
+ assertEquals(Service.State.TERMINATED, service.state());
+ ASSERT.that(service.transitionStates)
+ .has().allOf(Service.State.STARTING, Service.State.STOPPING).inOrder();
+ }
+
+ public void testStop_failed() {
+ final Exception exception = new Exception("deliberate");
+ TestService service = new TestService() {
+ @Override protected void shutDown() throws Exception {
+ super.shutDown();
+ throw exception;
+ }
+ };
+ service.startAndWait();
+ assertEquals(1, service.startUpCalled);
+ assertEquals(0, service.shutDownCalled);
+ try {
+ service.stopAndWait();
+ fail();
+ } catch (RuntimeException e) {
+ assertSame(exception, e.getCause());
+ }
+ assertEquals(1, service.startUpCalled);
+ assertEquals(1, service.shutDownCalled);
+ assertEquals(Service.State.FAILED, service.state());
+ ASSERT.that(service.transitionStates)
+ .has().allOf(Service.State.STARTING, Service.State.STOPPING).inOrder();
+ }
+
+ public void testServiceToString() {
+ AbstractIdleService service = new TestService();
+ assertEquals("TestService [NEW]", service.toString());
+ service.startAndWait();
+ assertEquals("TestService [RUNNING]", service.toString());
+ service.stopAndWait();
+ assertEquals("TestService [TERMINATED]", service.toString());
}
public void testTimeout() throws Exception {
// Create a service whose executor will never run its commands
- Service service = new NullService() {
- @Override protected Executor executor(Service.State state) {
+ Service service = new TestService() {
+ @Override protected Executor executor() {
return new Executor() {
- @Override public void execute(Runnable command) {
- }
+ @Override public void execute(Runnable command) {}
};
}
};
-
try {
service.start().get(1, TimeUnit.MILLISECONDS);
fail("Expected timeout");
} catch (TimeoutException e) {
- assertTrue(e.getMessage().contains(State.STARTING.toString()));
+ ASSERT.that(e.getMessage()).contains(Service.State.STARTING.toString());
}
}
- private class NullService extends AbstractIdleService {
- boolean startUpCalled = false;
- boolean shutDownCalled = false;
- State expectedShutdownState = State.STOPPING;
+ private static class TestService extends AbstractIdleService {
+ int startUpCalled = 0;
+ int shutDownCalled = 0;
+ final List<State> transitionStates = Lists.newArrayList();
- @Override protected void startUp() {
- assertFalse(startUpCalled);
- assertFalse(shutDownCalled);
- startUpCalled = true;
+ @Override protected void startUp() throws Exception {
+ assertEquals(0, startUpCalled);
+ assertEquals(0, shutDownCalled);
+ startUpCalled++;
assertEquals(State.STARTING, state());
}
- @Override protected void shutDown() {
- assertTrue(startUpCalled);
- assertFalse(shutDownCalled);
- shutDownCalled = true;
- assertEquals(expectedShutdownState, state());
+ @Override protected void shutDown() throws Exception {
+ assertEquals(1, startUpCalled);
+ assertEquals(0, shutDownCalled);
+ shutDownCalled++;
+ assertEquals(State.STOPPING, state());
}
- @Override protected Executor executor(Service.State state) {
- switch (state) {
- case STARTING:
- assertFalse(startUpCalled);
- return executor;
- case STOPPING:
- assertTrue(startUpCalled);
- assertFalse(shutDownCalled);
- return executor;
- default:
- throw new IllegalStateException("unexpected state " + state);
- }
+ @Override protected Executor executor() {
+ transitionStates.add(state());
+ return MoreExecutors.sameThreadExecutor();
}
}
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java
index c839e44..95f9fa8 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AbstractScheduledServiceTest.java
@@ -21,6 +21,7 @@ import com.google.common.util.concurrent.Service.State;
import junit.framework.TestCase;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
@@ -28,7 +29,6 @@ import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
-
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -65,9 +65,7 @@ public class AbstractScheduledServiceTest extends TestCase {
}
private class NullService extends AbstractScheduledService {
- @Override protected void runOneIteration() throws Exception { }
- @Override protected void startUp() throws Exception { }
- @Override protected void shutDown() throws Exception { }
+ @Override protected void runOneIteration() throws Exception {}
@Override protected Scheduler scheduler() { return configuration; }
@Override protected ScheduledExecutorService executor() { return executor; }
}
@@ -150,6 +148,85 @@ public class AbstractScheduledServiceTest extends TestCase {
assertEquals(1, service.numberOfTimesExecutorCalled.get());
}
+ public void testDefaultExecutorIsShutdownWhenServiceIsStopped() throws Exception {
+ final CountDownLatch terminationLatch = new CountDownLatch(1);
+ AbstractScheduledService service = new AbstractScheduledService() {
+ volatile ScheduledExecutorService executorService;
+ @Override protected void runOneIteration() throws Exception {}
+
+ @Override protected ScheduledExecutorService executor() {
+ if (executorService == null) {
+ executorService = super.executor();
+ // Add a listener that will be executed after the listener that shuts down the executor.
+ addListener(new Listener() {
+ @Override public void starting() {}
+ @Override public void running() {}
+ @Override public void stopping(State from) {}
+ @Override public void terminated(State from) {
+ terminationLatch.countDown();
+ }
+ @Override public void failed(State from, Throwable failure) {}
+ }, MoreExecutors.sameThreadExecutor());
+ }
+ return executorService;
+ }
+
+ @Override protected Scheduler scheduler() {
+ return Scheduler.newFixedDelaySchedule(0, 1, TimeUnit.MILLISECONDS);
+ }};
+
+ service.start();
+ assertFalse(service.executor().isShutdown());
+ service.startAndWait();
+ service.stop();
+ terminationLatch.await();
+ assertTrue(service.executor().isShutdown());
+ assertTrue(service.executor().awaitTermination(100, TimeUnit.MILLISECONDS));
+ }
+
+ public void testDefaultExecutorIsShutdownWhenServiceFails() throws Exception {
+ final CountDownLatch failureLatch = new CountDownLatch(1);
+ AbstractScheduledService service = new AbstractScheduledService() {
+ volatile ScheduledExecutorService executorService;
+ @Override protected void runOneIteration() throws Exception {}
+
+ @Override protected void startUp() throws Exception {
+ throw new Exception("Failed");
+ }
+
+ @Override protected ScheduledExecutorService executor() {
+ if (executorService == null) {
+ executorService = super.executor();
+ // Add a listener that will be executed after the listener that shuts down the executor.
+ addListener(new Listener() {
+ @Override public void starting() {}
+ @Override public void running() {}
+ @Override public void stopping(State from) {}
+ @Override public void terminated(State from) {
+ }
+ @Override public void failed(State from, Throwable failure) {
+ failureLatch.countDown();
+ }
+ }, MoreExecutors.sameThreadExecutor());
+ }
+ return executorService;
+ }
+
+ @Override protected Scheduler scheduler() {
+ return Scheduler.newFixedDelaySchedule(0, 1, TimeUnit.MILLISECONDS);
+ }};
+
+ try {
+ service.startAndWait();
+ fail("Expected service to fail during startup");
+ } catch (UncheckedExecutionException e) {
+ // expected
+ }
+ failureLatch.await();
+ assertTrue(service.executor().isShutdown());
+ assertTrue(service.executor().awaitTermination(100, TimeUnit.MILLISECONDS));
+ }
+
public void testSchedulerOnlyCalledOnce() throws Exception {
TestService service = new TestService();
service.startAndWait();
@@ -328,7 +405,7 @@ public class AbstractScheduledServiceTest extends TestCase {
public void testBig() throws Exception {
TestAbstractScheduledCustomService service = new TestAbstractScheduledCustomService() {
@Override protected Scheduler scheduler() {
- return new AbstractScheduledService.CustomScheduler(){
+ return new AbstractScheduledService.CustomScheduler() {
@Override
protected Schedule getNextSchedule() throws Exception {
// Explicitly yield to increase the probability of a pathological scheduling.
@@ -369,9 +446,9 @@ public class AbstractScheduledServiceTest extends TestCase {
return Executors.newScheduledThreadPool(10);
}
- @Override protected void startUp() throws Exception { }
+ @Override protected void startUp() throws Exception {}
- @Override protected void shutDown() throws Exception { }
+ @Override protected void shutDown() throws Exception {}
@Override protected Scheduler scheduler() {
return new CustomScheduler() {
@@ -415,10 +492,6 @@ public class AbstractScheduledServiceTest extends TestCase {
return Executors.newScheduledThreadPool(10);
}
- @Override protected void startUp() throws Exception { }
-
- @Override protected void shutDown() throws Exception { }
-
@Override protected Scheduler scheduler() {
return new CustomScheduler() {
@Override
diff --git a/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java
index c4d4f8e..99e2ffb 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AbstractServiceTest.java
@@ -19,12 +19,21 @@ package com.google.common.util.concurrent;
import static java.lang.Thread.currentThread;
import static java.util.concurrent.TimeUnit.SECONDS;
-import junit.framework.Assert;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Service.Listener;
+import com.google.common.util.concurrent.Service.State;
+
import junit.framework.TestCase;
import java.lang.Thread.UncaughtExceptionHandler;
+import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.concurrent.GuardedBy;
/**
* Unit test for {@link AbstractService}.
@@ -36,43 +45,59 @@ public class AbstractServiceTest extends TestCase {
private Thread executionThread;
private Throwable thrownByExecutionThread;
- public void testNoOpServiceStartStop() {
+ public void testNoOpServiceStartStop() throws Exception {
NoOpService service = new NoOpService();
- Assert.assertEquals(Service.State.NEW, service.state());
+ RecordingListener listener = RecordingListener.record(service);
+
+ assertEquals(State.NEW, service.state());
assertFalse(service.isRunning());
assertFalse(service.running);
service.start();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
assertTrue(service.isRunning());
assertTrue(service.running);
service.stop();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
assertFalse(service.isRunning());
assertFalse(service.running);
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.RUNNING,
+ State.STOPPING,
+ State.TERMINATED),
+ listener.getStateHistory());
}
public void testNoOpServiceStartAndWaitStopAndWait() throws Exception {
NoOpService service = new NoOpService();
service.start().get();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
service.stop().get();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
}
public void testNoOpServiceStartStopIdempotence() throws Exception {
NoOpService service = new NoOpService();
-
+ RecordingListener listener = RecordingListener.record(service);
service.start();
service.start();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
service.stop();
service.stop();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.RUNNING,
+ State.STOPPING,
+ State.TERMINATED),
+ listener.getStateHistory());
}
public void testNoOpServiceStartStopIdempotenceAfterWait() throws Exception {
@@ -80,11 +105,11 @@ public class AbstractServiceTest extends TestCase {
service.start().get();
service.start();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
service.stop().get();
service.stop();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
}
public void testNoOpServiceStartStopIdempotenceDoubleWait() throws Exception {
@@ -92,11 +117,11 @@ public class AbstractServiceTest extends TestCase {
service.start().get();
service.start().get();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
service.stop().get();
service.stop().get();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
}
public void testNoOpServiceStartStopAndWaitUninterruptible()
@@ -106,10 +131,10 @@ public class AbstractServiceTest extends TestCase {
currentThread().interrupt();
try {
service.startAndWait();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
service.stopAndWait();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
assertTrue(currentThread().isInterrupted());
} finally {
@@ -133,49 +158,125 @@ public class AbstractServiceTest extends TestCase {
}
}
- public void testManualServiceStartStop() {
+ public void testManualServiceStartStop() throws Exception {
ManualSwitchedService service = new ManualSwitchedService();
+ RecordingListener listener = RecordingListener.record(service);
service.start();
- assertEquals(Service.State.STARTING, service.state());
+ assertEquals(State.STARTING, service.state());
assertFalse(service.isRunning());
assertTrue(service.doStartCalled);
service.notifyStarted(); // usually this would be invoked by another thread
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
assertTrue(service.isRunning());
service.stop();
- assertEquals(Service.State.STOPPING, service.state());
+ assertEquals(State.STOPPING, service.state());
assertFalse(service.isRunning());
assertTrue(service.doStopCalled);
service.notifyStopped(); // usually this would be invoked by another thread
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
assertFalse(service.isRunning());
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.RUNNING,
+ State.STOPPING,
+ State.TERMINATED),
+ listener.getStateHistory());
+
}
- public void testManualServiceStopWhileStarting() {
+ public void testManualServiceNotifyStoppedWhileRunning() throws Exception {
ManualSwitchedService service = new ManualSwitchedService();
+ RecordingListener listener = RecordingListener.record(service);
service.start();
- assertEquals(Service.State.STARTING, service.state());
+ service.notifyStarted();
+ service.notifyStopped();
+ assertEquals(State.TERMINATED, service.state());
+ assertFalse(service.isRunning());
+ assertFalse(service.doStopCalled);
+
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.RUNNING,
+ State.TERMINATED),
+ listener.getStateHistory());
+ }
+
+ public void testManualServiceStopWhileStarting() throws Exception {
+ ManualSwitchedService service = new ManualSwitchedService();
+ RecordingListener listener = RecordingListener.record(service);
+
+ service.start();
+ assertEquals(State.STARTING, service.state());
assertFalse(service.isRunning());
assertTrue(service.doStartCalled);
service.stop();
- assertEquals(Service.State.STOPPING, service.state());
+ assertEquals(State.STOPPING, service.state());
assertFalse(service.isRunning());
assertFalse(service.doStopCalled);
service.notifyStarted();
- assertEquals(Service.State.STOPPING, service.state());
+ assertEquals(State.STOPPING, service.state());
assertFalse(service.isRunning());
assertTrue(service.doStopCalled);
service.notifyStopped();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
+ assertFalse(service.isRunning());
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.STOPPING,
+ State.TERMINATED),
+ listener.getStateHistory());
+ }
+
+ public void testManualServiceStopWhileNew() throws Exception {
+ ManualSwitchedService service = new ManualSwitchedService();
+ RecordingListener listener = RecordingListener.record(service);
+
+ service.stop();
+ assertEquals(State.TERMINATED, service.state());
assertFalse(service.isRunning());
+ assertFalse(service.doStartCalled);
+ assertFalse(service.doStopCalled);
+ assertEquals(ImmutableList.of(State.TERMINATED), listener.getStateHistory());
+ }
+
+ public void testManualServiceFailWhileStarting() throws Exception {
+ ManualSwitchedService service = new ManualSwitchedService();
+ RecordingListener listener = RecordingListener.record(service);
+ service.start();
+ service.notifyFailed(EXCEPTION);
+ assertEquals(ImmutableList.of(State.STARTING, State.FAILED), listener.getStateHistory());
+ }
+
+ public void testManualServiceFailWhileRunning() throws Exception {
+ ManualSwitchedService service = new ManualSwitchedService();
+ RecordingListener listener = RecordingListener.record(service);
+ service.start();
+ service.notifyStarted();
+ service.notifyFailed(EXCEPTION);
+ assertEquals(ImmutableList.of(State.STARTING, State.RUNNING, State.FAILED),
+ listener.getStateHistory());
+ }
+
+ public void testManualServiceFailWhileStopping() throws Exception {
+ ManualSwitchedService service = new ManualSwitchedService();
+ RecordingListener listener = RecordingListener.record(service);
+ service.start();
+ service.notifyStarted();
+ service.stop();
+ service.notifyFailed(EXCEPTION);
+ assertEquals(ImmutableList.of(State.STARTING, State.RUNNING, State.STOPPING, State.FAILED),
+ listener.getStateHistory());
}
public void testManualServiceUnrequestedStop() {
@@ -184,12 +285,12 @@ public class AbstractServiceTest extends TestCase {
service.start();
service.notifyStarted();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
assertTrue(service.isRunning());
assertFalse(service.doStopCalled);
service.notifyStopped();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
assertFalse(service.isRunning());
assertFalse(service.doStopCalled);
}
@@ -215,16 +316,23 @@ public class AbstractServiceTest extends TestCase {
public void testThreadedServiceStartAndWaitStopAndWait() throws Throwable {
ThreadedService service = new ThreadedService();
-
+ RecordingListener listener = RecordingListener.record(service);
service.start().get();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
service.awaitRunChecks();
- service.stop().get();
- assertEquals(Service.State.TERMINATED, service.state());
+ service.stopAndWait();
+ assertEquals(State.TERMINATED, service.state());
throwIfSet(thrownByExecutionThread);
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.RUNNING,
+ State.STOPPING,
+ State.TERMINATED),
+ listener.getStateHistory());
}
public void testThreadedServiceStartStopIdempotence() throws Throwable {
@@ -232,13 +340,13 @@ public class AbstractServiceTest extends TestCase {
service.start();
service.start().get();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
service.awaitRunChecks();
service.stop();
service.stop().get();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
throwIfSet(thrownByExecutionThread);
}
@@ -249,13 +357,13 @@ public class AbstractServiceTest extends TestCase {
service.start().get();
service.start();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
service.awaitRunChecks();
service.stop().get();
service.stop();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
executionThread.join();
@@ -268,17 +376,31 @@ public class AbstractServiceTest extends TestCase {
service.start().get();
service.start().get();
- assertEquals(Service.State.RUNNING, service.state());
+ assertEquals(State.RUNNING, service.state());
service.awaitRunChecks();
service.stop().get();
service.stop().get();
- assertEquals(Service.State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, service.state());
throwIfSet(thrownByExecutionThread);
}
+ public void testManualServiceFailureIdempotence() {
+ ManualSwitchedService service = new ManualSwitchedService();
+ RecordingListener.record(service);
+ service.start();
+ service.notifyFailed(new Exception("1"));
+ service.notifyFailed(new Exception("2"));
+ try {
+ service.startAndWait();
+ fail();
+ } catch (UncheckedExecutionException e) {
+ assertEquals("1", e.getCause().getMessage());
+ }
+ }
+
private class ThreadedService extends AbstractService {
final CountDownLatch hasConfirmedIsRunning = new CountDownLatch(1);
@@ -339,51 +461,213 @@ public class AbstractServiceTest extends TestCase {
public void testStopUnstartedService() throws Exception {
NoOpService service = new NoOpService();
- Future<Service.State> stopResult = service.stop();
- assertEquals(Service.State.TERMINATED, service.state());
- assertEquals(Service.State.TERMINATED, stopResult.get());
+ RecordingListener listener = RecordingListener.record(service);
+
+ Future<State> stopResult = service.stop();
+ assertEquals(State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, stopResult.get());
- Future<Service.State> startResult = service.start();
- assertEquals(Service.State.TERMINATED, service.state());
- assertEquals(Service.State.TERMINATED, startResult.get());
+ Future<State> startResult = service.start();
+ assertEquals(State.TERMINATED, service.state());
+ assertEquals(State.TERMINATED, startResult.get());
+ assertEquals(State.TERMINATED, Iterables.getOnlyElement(listener.getStateHistory()));
+ }
+
+ public void testFailingServiceStartAndWait() throws Exception {
+ StartFailingService service = new StartFailingService();
+ RecordingListener listener = RecordingListener.record(service);
+
+ try {
+ service.startAndWait();
+ fail();
+ } catch (UncheckedExecutionException e) {
+ assertEquals(EXCEPTION, e.getCause());
+ }
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.FAILED),
+ listener.getStateHistory());
+ }
+
+ public void testFailingServiceStopAndWait_stopFailing() throws Exception {
+ StopFailingService service = new StopFailingService();
+ RecordingListener listener = RecordingListener.record(service);
+
+ service.startAndWait();
+ try {
+ service.stopAndWait();
+ fail();
+ } catch (UncheckedExecutionException e) {
+ assertEquals(EXCEPTION, e.getCause());
+ }
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.RUNNING,
+ State.STOPPING,
+ State.FAILED),
+ listener.getStateHistory());
+ }
+
+ public void testFailingServiceStopAndWait_runFailinging() throws Exception {
+ RunFailingService service = new RunFailingService();
+ RecordingListener listener = RecordingListener.record(service);
+
+ service.startAndWait();
+ try {
+ service.stopAndWait();
+ fail();
+ } catch (UncheckedExecutionException e) {
+ assertEquals(EXCEPTION, e.getCause().getCause());
+ }
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.RUNNING,
+ State.FAILED),
+ listener.getStateHistory());
}
public void testThrowingServiceStartAndWait() throws Exception {
StartThrowingService service = new StartThrowingService();
+ RecordingListener listener = RecordingListener.record(service);
try {
service.startAndWait();
fail();
} catch (UncheckedExecutionException e) {
- assertEquals(EXCEPTION, e.getCause());
+ assertEquals(service.exception, e.getCause());
}
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.FAILED),
+ listener.getStateHistory());
}
public void testThrowingServiceStopAndWait_stopThrowing() throws Exception {
StopThrowingService service = new StopThrowingService();
+ RecordingListener listener = RecordingListener.record(service);
service.startAndWait();
try {
service.stopAndWait();
fail();
} catch (UncheckedExecutionException e) {
- assertEquals(EXCEPTION, e.getCause());
+ assertEquals(service.exception, e.getCause());
}
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.RUNNING,
+ State.STOPPING,
+ State.FAILED),
+ listener.getStateHistory());
}
public void testThrowingServiceStopAndWait_runThrowing() throws Exception {
RunThrowingService service = new RunThrowingService();
+ RecordingListener listener = RecordingListener.record(service);
service.startAndWait();
try {
service.stopAndWait();
fail();
} catch (UncheckedExecutionException e) {
- assertEquals(EXCEPTION, e.getCause().getCause());
+ assertEquals(service.exception, e.getCause().getCause());
}
+ assertEquals(
+ ImmutableList.of(
+ State.STARTING,
+ State.RUNNING,
+ State.FAILED),
+ listener.getStateHistory());
}
- private static class StartThrowingService extends AbstractService {
+ public void testFailureCause_throwsIfNotFailed() {
+ StopFailingService service = new StopFailingService();
+ try {
+ service.failureCause();
+ fail();
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ service.startAndWait();
+ try {
+ service.failureCause();
+ fail();
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ try {
+ service.stopAndWait();
+ fail();
+ } catch (UncheckedExecutionException e) {
+ assertEquals(EXCEPTION, service.failureCause());
+ assertEquals(EXCEPTION, e.getCause());
+ }
+ }
+
+ public void testAddListenerAfterFailureDoesntCauseDeadlock() throws InterruptedException {
+ final StartFailingService service = new StartFailingService();
+ service.start();
+ assertEquals(State.FAILED, service.state());
+ service.addListener(new RecordingListener(service), MoreExecutors.sameThreadExecutor());
+ Thread thread = new Thread() {
+ @Override public void run() {
+ // Internally start() grabs a lock, this could be any such method on AbstractService.
+ service.start();
+ }
+ };
+ thread.start();
+ thread.join(100);
+ assertFalse(thread + " is deadlocked", thread.isAlive());
+ }
+
+ public void testListenerDoesntDeadlockOnStartAndWaitFromRunning() throws Exception {
+ final NoOpThreadedService service = new NoOpThreadedService();
+ service.addListener(new Listener() {
+ @Override public void starting() { }
+ @Override public void running() {
+ service.startAndWait();
+ }
+ @Override public void stopping(State from) { }
+ @Override public void terminated(State from) { }
+ @Override public void failed(State from, Throwable failure) { }
+ }, MoreExecutors.sameThreadExecutor());
+ service.start().get(10, TimeUnit.MILLISECONDS);
+ service.stop();
+ }
+
+ public void testListenerDoesntDeadlockOnStopAndWaitFromTerminated() throws Exception {
+ final NoOpThreadedService service = new NoOpThreadedService();
+ service.addListener(new Listener() {
+ @Override public void starting() { }
+ @Override public void running() { }
+ @Override public void stopping(State from) { }
+ @Override public void terminated(State from) {
+ service.stopAndWait();
+ }
+ @Override public void failed(State from, Throwable failure) { }
+ }, MoreExecutors.sameThreadExecutor());
+ service.startAndWait();
+
+ Thread thread = new Thread() {
+ @Override public void run() {
+ service.stopAndWait();
+ }
+ };
+ thread.start();
+ thread.join(100);
+ assertFalse(thread + " is deadlocked", thread.isAlive());
+ }
+
+ private static class NoOpThreadedService extends AbstractExecutionThreadService {
+ @Override protected void run() throws Exception {}
+ }
+
+ private static class StartFailingService extends AbstractService {
@Override protected void doStart() {
notifyFailed(EXCEPTION);
}
@@ -393,7 +677,7 @@ public class AbstractServiceTest extends TestCase {
}
}
- private static class RunThrowingService extends AbstractService {
+ private static class RunFailingService extends AbstractService {
@Override protected void doStart() {
notifyStarted();
notifyFailed(EXCEPTION);
@@ -404,7 +688,7 @@ public class AbstractServiceTest extends TestCase {
}
}
- private static class StopThrowingService extends AbstractService {
+ private static class StopFailingService extends AbstractService {
@Override protected void doStart() {
notifyStarted();
}
@@ -414,5 +698,171 @@ public class AbstractServiceTest extends TestCase {
}
}
+ private static class StartThrowingService extends AbstractService {
+
+ final RuntimeException exception = new RuntimeException("deliberate");
+
+ @Override protected void doStart() {
+ throw exception;
+ }
+
+ @Override protected void doStop() {
+ fail();
+ }
+ }
+
+ private static class RunThrowingService extends AbstractService {
+
+ final RuntimeException exception = new RuntimeException("deliberate");
+
+ @Override protected void doStart() {
+ notifyStarted();
+ throw exception;
+ }
+
+ @Override protected void doStop() {
+ fail();
+ }
+ }
+
+ private static class StopThrowingService extends AbstractService {
+
+ final RuntimeException exception = new RuntimeException("deliberate");
+
+ @Override protected void doStart() {
+ notifyStarted();
+ }
+
+ @Override protected void doStop() {
+ throw exception;
+ }
+ }
+
+ private static class RecordingListener implements Listener {
+ static RecordingListener record(Service service) {
+ RecordingListener listener = new RecordingListener(service);
+ service.addListener(listener, MoreExecutors.sameThreadExecutor());
+ return listener;
+ }
+
+ final Service service;
+
+ RecordingListener(Service service) {
+ this.service = service;
+ }
+
+ @GuardedBy("this")
+ final List<State> stateHistory = Lists.newArrayList();
+ final CountDownLatch completionLatch = new CountDownLatch(1);
+
+ ImmutableList<State> getStateHistory() throws Exception {
+ completionLatch.await();
+ synchronized (this) {
+ return ImmutableList.copyOf(stateHistory);
+ }
+ }
+
+ @Override public synchronized void starting() {
+ assertTrue(stateHistory.isEmpty());
+ assertNotSame(State.NEW, service.state());
+ stateHistory.add(State.STARTING);
+ }
+
+ @Override public synchronized void running() {
+ assertEquals(State.STARTING, Iterables.getOnlyElement(stateHistory));
+ stateHistory.add(State.RUNNING);
+ assertTrue(service.start().isDone());
+ assertEquals(State.RUNNING, service.startAndWait());
+ assertNotSame(State.STARTING, service.state());
+ }
+
+ @Override public synchronized void stopping(State from) {
+ assertEquals(from, Iterables.getLast(stateHistory));
+ stateHistory.add(State.STOPPING);
+ if (from == State.STARTING) {
+ assertTrue(service.start().isDone());
+ assertEquals(State.STOPPING, service.startAndWait());
+ }
+ assertNotSame(from, service.state());
+ }
+
+ @Override public synchronized void terminated(State from) {
+ assertEquals(from, Iterables.getLast(stateHistory, State.NEW));
+ stateHistory.add(State.TERMINATED);
+ assertEquals(State.TERMINATED, service.state());
+ assertTrue(service.start().isDone());
+ if (from == State.NEW) {
+ assertEquals(State.TERMINATED, service.startAndWait());
+ }
+ assertTrue(service.stop().isDone());
+ assertEquals(State.TERMINATED, service.stopAndWait());
+ completionLatch.countDown();
+ }
+
+ @Override public synchronized void failed(State from, Throwable failure) {
+ assertEquals(from, Iterables.getLast(stateHistory));
+ stateHistory.add(State.FAILED);
+ assertEquals(State.FAILED, service.state());
+ if (from == State.STARTING) {
+ try {
+ service.startAndWait();
+ fail();
+ } catch (UncheckedExecutionException e) {
+ assertEquals(failure, e.getCause());
+ }
+ }
+ try {
+ service.stopAndWait();
+ fail();
+ } catch (UncheckedExecutionException e) {
+ if (from == State.STOPPING) {
+ assertEquals(failure, e.getCause());
+ } else {
+ assertEquals(failure, e.getCause().getCause());
+ }
+ }
+ completionLatch.countDown();
+ }
+ }
+
+ public void testNotifyStartedWhenNotStarting() {
+ AbstractService service = new DefaultService();
+ try {
+ service.notifyStarted();
+ fail();
+ } catch (IllegalStateException expected) {}
+ }
+
+ public void testNotifyStoppedWhenNotRunning() {
+ AbstractService service = new DefaultService();
+ try {
+ service.notifyStopped();
+ fail();
+ } catch (IllegalStateException expected) {}
+ }
+
+ public void testNotifyFailedWhenNotStarted() {
+ AbstractService service = new DefaultService();
+ try {
+ service.notifyFailed(new Exception());
+ fail();
+ } catch (IllegalStateException expected) {}
+ }
+
+ public void testNotifyFailedWhenTerminated() {
+ NoOpService service = new NoOpService();
+ service.startAndWait();
+ service.stopAndWait();
+ try {
+ service.notifyFailed(new Exception());
+ fail();
+ } catch (IllegalStateException expected) {}
+ }
+
+ private static class DefaultService extends AbstractService {
+ @Override protected void doStart() {}
+ @Override protected void doStop() {}
+ }
+
private static final Exception EXCEPTION = new Exception();
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java b/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java
index f3aa63f..7ad3a4a 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AtomicDoubleArrayTest.java
@@ -14,6 +14,7 @@
package com.google.common.util.concurrent;
import junit.framework.*;
+
import java.util.Arrays;
/**
diff --git a/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java b/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java
index 8bffaa1..8746e33 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AtomicLongMapTest.java
@@ -1,7 +1,23 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.google.common.util.concurrent;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.google.common.testing.NullPointerTester;
@@ -19,15 +35,17 @@ import java.util.concurrent.atomic.AtomicLong;
/**
* Tests for {@link AtomicLongMap}.
*
- * @author schmoe@google.com (mike nonemacher)
+ * @author mike nonemacher
*/
+@GwtCompatible(emulated = true)
public class AtomicLongMapTest extends TestCase {
private static final int ITERATIONS = 100;
private static final int MAX_ADDEND = 100;
private Random random = new Random(301);
- public void testNulls() throws Exception {
+ @GwtIncompatible("NullPointerTester")
+ public void testNulls() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicConstructors(AtomicLongMap.class);
tester.testAllPublicStaticMethods(AtomicLongMap.class);
@@ -536,6 +554,7 @@ public class AtomicLongMapTest extends TestCase {
assertFalse(map.replace("a", 1L, 0L));
}
+ @GwtIncompatible("threads")
public void testModify_basher() throws InterruptedException {
int nTasks = 3000;
int nThreads = 100;
diff --git a/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java b/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java
index 66f2b13..5a19625 100644
--- a/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/AtomicsTest.java
@@ -82,7 +82,7 @@ public class AtomicsTest extends TestCase {
}
}
- public void testNullPointers() throws Exception {
+ public void testNullPointers() {
NullPointerTester tester = new NullPointerTester();
tester.testAllPublicConstructors(Atomics.class); // there aren't any
tester.testAllPublicStaticMethods(Atomics.class);
diff --git a/guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java b/guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java
new file mode 100644
index 0000000..b39601f
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/CycleDetectingLockFactoryTest.java
@@ -0,0 +1,581 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import com.google.common.base.Joiner;
+import com.google.common.util.concurrent.CycleDetectingLockFactory.OrderedLockGraphNodesCreator;
+import com.google.common.util.concurrent.CycleDetectingLockFactory.Policies;
+import com.google.common.util.concurrent.CycleDetectingLockFactory.Policy;
+import com.google.common.util.concurrent.CycleDetectingLockFactory.PotentialDeadlockException;
+
+import junit.framework.TestCase;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Unittests for {@link CycleDetectingLockFactory}.
+ *
+ * @author Darick Tong
+ */
+public class CycleDetectingLockFactoryTest extends TestCase {
+
+ private ReentrantLock lockA;
+ private ReentrantLock lockB;
+ private ReentrantLock lockC;
+ private ReentrantReadWriteLock.ReadLock readLockA;
+ private ReentrantReadWriteLock.ReadLock readLockB;
+ private ReentrantReadWriteLock.ReadLock readLockC;
+ private ReentrantReadWriteLock.WriteLock writeLockA;
+ private ReentrantReadWriteLock.WriteLock writeLockB;
+ private ReentrantReadWriteLock.WriteLock writeLockC;
+ private ReentrantLock lock1;
+ private ReentrantLock lock2;
+ private ReentrantLock lock3;
+ private ReentrantLock lock01;
+ private ReentrantLock lock02;
+ private ReentrantLock lock03;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ CycleDetectingLockFactory factory =
+ CycleDetectingLockFactory.newInstance(Policies.THROW);
+ lockA = factory.newReentrantLock("LockA");
+ lockB = factory.newReentrantLock("LockB");
+ lockC = factory.newReentrantLock("LockC");
+ ReentrantReadWriteLock readWriteLockA =
+ factory.newReentrantReadWriteLock("ReadWriteA");
+ ReentrantReadWriteLock readWriteLockB =
+ factory.newReentrantReadWriteLock("ReadWriteB");
+ ReentrantReadWriteLock readWriteLockC =
+ factory.newReentrantReadWriteLock("ReadWriteC");
+ readLockA = readWriteLockA.readLock();
+ readLockB = readWriteLockB.readLock();
+ readLockC = readWriteLockC.readLock();
+ writeLockA = readWriteLockA.writeLock();
+ writeLockB = readWriteLockB.writeLock();
+ writeLockC = readWriteLockC.writeLock();
+
+ CycleDetectingLockFactory.WithExplicitOrdering<MyOrder> factory2 =
+ newInstanceWithExplicitOrdering(MyOrder.class, Policies.THROW);
+ lock1 = factory2.newReentrantLock(MyOrder.FIRST);
+ lock2 = factory2.newReentrantLock(MyOrder.SECOND);
+ lock3 = factory2.newReentrantLock(MyOrder.THIRD);
+
+ CycleDetectingLockFactory.WithExplicitOrdering<OtherOrder> factory3 =
+ newInstanceWithExplicitOrdering(OtherOrder.class, Policies.THROW);
+ lock01 = factory3.newReentrantLock(OtherOrder.FIRST);
+ lock02 = factory3.newReentrantLock(OtherOrder.SECOND);
+ lock03 = factory3.newReentrantLock(OtherOrder.THIRD);
+ }
+
+ // In the unittest, create each ordered factory with its own set of lock
+ // graph nodes (as opposed to using the static per-Enum map) to avoid
+ // conflicts across different test runs.
+ private <E extends Enum<E>> CycleDetectingLockFactory.WithExplicitOrdering<E>
+ newInstanceWithExplicitOrdering(Class<E> enumClass, Policy policy) {
+ OrderedLockGraphNodesCreator nodeCreator =
+ new OrderedLockGraphNodesCreator();
+ return new CycleDetectingLockFactory.WithExplicitOrdering<E>(
+ policy, nodeCreator.createNodesFor(enumClass));
+ }
+
+ public void testDeadlock_twoLocks() {
+ // Establish an acquisition order of lockA -> lockB.
+ lockA.lock();
+ lockB.lock();
+ lockA.unlock();
+ lockB.unlock();
+
+ // The opposite order should fail (Policies.THROW).
+ PotentialDeadlockException firstException = null;
+ lockB.lock();
+ try {
+ lockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(expected, "LockB -> LockA", "LockA -> LockB");
+ firstException = expected;
+ }
+
+ // Second time should also fail, with a cached causal chain.
+ try {
+ lockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(expected, "LockB -> LockA", "LockA -> LockB");
+ // The causal chain should be cached.
+ assertSame(firstException.getCause(), expected.getCause());
+ }
+
+ // lockA should work after lockB is released.
+ lockB.unlock();
+ lockA.lock();
+ }
+
+ // Tests transitive deadlock detection.
+ public void testDeadlock_threeLocks() {
+ // Establish an ordering from lockA -> lockB.
+ lockA.lock();
+ lockB.lock();
+ lockB.unlock();
+ lockA.unlock();
+
+ // Establish an ordering from lockB -> lockC.
+ lockB.lock();
+ lockC.lock();
+ lockB.unlock();
+
+ // lockC -> lockA should fail.
+ try {
+ lockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(
+ expected, "LockC -> LockA", "LockB -> LockC", "LockA -> LockB");
+ }
+ }
+
+ public void testReentrancy_noDeadlock() {
+ lockA.lock();
+ lockB.lock();
+ lockA.lock(); // Should not assert on lockB -> reentrant(lockA)
+ }
+
+ public void testExplicitOrdering_noViolations() {
+ lock1.lock();
+ lock3.lock();
+ lock3.unlock();
+ lock2.lock();
+ lock3.lock();
+ }
+
+ public void testExplicitOrdering_violations() {
+ lock3.lock();
+ try {
+ lock2.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(expected, "MyOrder.THIRD -> MyOrder.SECOND");
+ }
+
+ try {
+ lock1.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(expected, "MyOrder.THIRD -> MyOrder.FIRST");
+ }
+
+ lock3.unlock();
+ lock2.lock();
+
+ try {
+ lock1.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(expected, "MyOrder.SECOND -> MyOrder.FIRST");
+ }
+ }
+
+ public void testDifferentOrderings_noViolations() {
+ lock3.lock(); // MyOrder, ordinal() == 3
+ lock01.lock(); // OtherOrder, ordinal() == 1
+ }
+
+ public void testExplicitOrderings_generalCycleDetection() {
+ lock3.lock(); // MyOrder, ordinal() == 3
+ lock01.lock(); // OtherOrder, ordinal() == 1
+
+ lock3.unlock();
+ try {
+ lock3.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(
+ expected,
+ "OtherOrder.FIRST -> MyOrder.THIRD",
+ "MyOrder.THIRD -> OtherOrder.FIRST");
+ }
+
+ lockA.lock();
+ lock01.unlock();
+ lockB.lock();
+ lockA.unlock();
+
+ try {
+ lock01.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(
+ expected,
+ "LockB -> OtherOrder.FIRST",
+ "LockA -> LockB",
+ "OtherOrder.FIRST -> LockA");
+ }
+ }
+
+ public void testExplicitOrdering_cycleWithUnorderedLock() {
+ Lock myLock = CycleDetectingLockFactory.newInstance(Policies.THROW)
+ .newReentrantLock("MyLock");
+ lock03.lock();
+ myLock.lock();
+ lock03.unlock();
+
+ try {
+ lock01.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(
+ expected,
+ "MyLock -> OtherOrder.FIRST",
+ "OtherOrder.THIRD -> MyLock",
+ "OtherOrder.FIRST -> OtherOrder.THIRD");
+ }
+ }
+
+ public void testExplicitOrdering_reentrantAcquisition() {
+ CycleDetectingLockFactory.WithExplicitOrdering<OtherOrder> factory =
+ newInstanceWithExplicitOrdering(OtherOrder.class, Policies.THROW);
+ Lock lockA = factory.newReentrantReadWriteLock(OtherOrder.FIRST).readLock();
+ Lock lockB = factory.newReentrantLock(OtherOrder.SECOND);
+
+ lockA.lock();
+ lockA.lock();
+ lockB.lock();
+ lockB.lock();
+ lockA.unlock();
+ lockA.unlock();
+ lockB.unlock();
+ lockB.unlock();
+ }
+
+ public void testExplicitOrdering_acquiringMultipleLocksWithSameRank() {
+ CycleDetectingLockFactory.WithExplicitOrdering<OtherOrder> factory =
+ newInstanceWithExplicitOrdering(OtherOrder.class, Policies.THROW);
+ Lock lockA = factory.newReentrantLock(OtherOrder.FIRST);
+ Lock lockB = factory.newReentrantReadWriteLock(OtherOrder.FIRST).readLock();
+
+ lockA.lock();
+ try {
+ lockB.lock();
+ fail("Expected IllegalStateException");
+ } catch (IllegalStateException expected) {
+ }
+
+ lockA.unlock();
+ lockB.lock();
+ }
+
+ public void testReadLock_deadlock() {
+ readLockA.lock(); // Establish an ordering from readLockA -> lockB.
+ lockB.lock();
+ lockB.unlock();
+ readLockA.unlock();
+
+ lockB.lock();
+ try {
+ readLockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(expected, "LockB -> ReadWriteA", "ReadWriteA -> LockB");
+ }
+ }
+
+ public void testReadLock_transitive() {
+ readLockA.lock(); // Establish an ordering from readLockA -> lockB.
+ lockB.lock();
+ lockB.unlock();
+ readLockA.unlock();
+
+ // Establish an ordering from lockB -> readLockC.
+ lockB.lock();
+ readLockC.lock();
+ lockB.unlock();
+ readLockC.unlock();
+
+ // readLockC -> readLockA
+ readLockC.lock();
+ try {
+ readLockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(
+ expected,
+ "ReadWriteC -> ReadWriteA",
+ "LockB -> ReadWriteC",
+ "ReadWriteA -> LockB");
+ }
+ }
+
+ public void testWriteLock_threeLockDeadLock() {
+ // Establish an ordering from writeLockA -> writeLockB.
+ writeLockA.lock();
+ writeLockB.lock();
+ writeLockB.unlock();
+ writeLockA.unlock();
+
+ // Establish an ordering from writeLockB -> writeLockC.
+ writeLockB.lock();
+ writeLockC.lock();
+ writeLockB.unlock();
+
+ // writeLockC -> writeLockA should fail.
+ try {
+ writeLockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(
+ expected,
+ "ReadWriteC -> ReadWriteA",
+ "ReadWriteB -> ReadWriteC",
+ "ReadWriteA -> ReadWriteB");
+ }
+ }
+
+ public void testWriteToReadLockDowngrading() {
+ writeLockA.lock(); // writeLockA downgrades to readLockA
+ readLockA.lock();
+ writeLockA.unlock();
+
+ lockB.lock(); // readLockA -> lockB
+ readLockA.unlock();
+
+ // lockB -> writeLockA should fail
+ try {
+ writeLockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(
+ expected, "LockB -> ReadWriteA", "ReadWriteA -> LockB");
+ }
+ }
+
+ public void testReadWriteLockDeadlock() {
+ writeLockA.lock(); // Establish an ordering from writeLockA -> lockB
+ lockB.lock();
+ writeLockA.unlock();
+ lockB.unlock();
+
+ // lockB -> readLockA should fail.
+ lockB.lock();
+ try {
+ readLockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(
+ expected, "LockB -> ReadWriteA", "ReadWriteA -> LockB");
+ }
+ }
+
+ public void testReadWriteLockDeadlock_transitive() {
+ readLockA.lock(); // Establish an ordering from readLockA -> lockB
+ lockB.lock();
+ readLockA.unlock();
+ lockB.unlock();
+
+ // Establish an ordering from lockB -> lockC
+ lockB.lock();
+ lockC.lock();
+ lockB.unlock();
+ lockC.unlock();
+
+ // lockC -> writeLockA should fail.
+ lockC.lock();
+ try {
+ writeLockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(
+ expected,
+ "LockC -> ReadWriteA",
+ "LockB -> LockC",
+ "ReadWriteA -> LockB");
+ }
+ }
+
+ public void testReadWriteLockDeadlock_treatedEquivalently() {
+ readLockA.lock(); // readLockA -> writeLockB
+ writeLockB.lock();
+ readLockA.unlock();
+ writeLockB.unlock();
+
+ // readLockB -> writeLockA should fail.
+ readLockB.lock();
+ try {
+ writeLockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(
+ expected, "ReadWriteB -> ReadWriteA", "ReadWriteA -> ReadWriteB");
+ }
+ }
+
+ public void testDifferentLockFactories() {
+ CycleDetectingLockFactory otherFactory =
+ CycleDetectingLockFactory.newInstance(Policies.WARN);
+ ReentrantLock lockD = otherFactory.newReentrantLock("LockD");
+
+ // lockA -> lockD
+ lockA.lock();
+ lockD.lock();
+ lockA.unlock();
+ lockD.unlock();
+
+ // lockD -> lockA should fail even though lockD is from a different factory.
+ lockD.lock();
+ try {
+ lockA.lock();
+ fail("Expected PotentialDeadlockException");
+ } catch (PotentialDeadlockException expected) {
+ checkMessage(expected, "LockD -> LockA", "LockA -> LockD");
+ }
+ }
+
+ public void testDifferentLockFactories_policyExecution() {
+ CycleDetectingLockFactory otherFactory =
+ CycleDetectingLockFactory.newInstance(Policies.WARN);
+ ReentrantLock lockD = otherFactory.newReentrantLock("LockD");
+
+ // lockD -> lockA
+ lockD.lock();
+ lockA.lock();
+ lockA.unlock();
+ lockD.unlock();
+
+ // lockA -> lockD should warn but otherwise succeed because lockD was
+ // created by a factory with the WARN policy.
+ lockA.lock();
+ lockD.lock();
+ }
+
+ public void testReentrantLock_tryLock() throws Exception {
+ LockingThread thread = new LockingThread(lockA);
+ thread.start();
+
+ thread.waitUntilHoldingLock();
+ assertFalse(lockA.tryLock());
+
+ thread.releaseLockAndFinish();
+ assertTrue(lockA.tryLock());
+ }
+
+ public void testReentrantWriteLock_tryLock() throws Exception {
+ LockingThread thread = new LockingThread(writeLockA);
+ thread.start();
+
+ thread.waitUntilHoldingLock();
+ assertFalse(writeLockA.tryLock());
+ assertFalse(readLockA.tryLock());
+
+ thread.releaseLockAndFinish();
+ assertTrue(writeLockA.tryLock());
+ assertTrue(readLockA.tryLock());
+ }
+
+ public void testReentrantReadLock_tryLock() throws Exception {
+ LockingThread thread = new LockingThread(readLockA);
+ thread.start();
+
+ thread.waitUntilHoldingLock();
+ assertFalse(writeLockA.tryLock());
+ assertTrue(readLockA.tryLock());
+ readLockA.unlock();
+
+ thread.releaseLockAndFinish();
+ assertTrue(writeLockA.tryLock());
+ assertTrue(readLockA.tryLock());
+ }
+
+ private static class LockingThread extends Thread {
+ final CountDownLatch locked = new CountDownLatch(1);
+ final CountDownLatch finishLatch = new CountDownLatch(1);
+ final Lock lock;
+
+ LockingThread(Lock lock) {
+ this.lock = lock;
+ }
+
+ @Override
+ public void run() {
+ lock.lock();
+ try {
+ locked.countDown();
+ finishLatch.await(1, TimeUnit.MINUTES);
+ } catch (InterruptedException e) {
+ fail(e.toString());
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ void waitUntilHoldingLock() throws InterruptedException {
+ locked.await(1, TimeUnit.MINUTES);
+ }
+
+ void releaseLockAndFinish() throws InterruptedException {
+ finishLatch.countDown();
+ this.join(10000);
+ assertFalse(this.isAlive());
+ }
+ }
+
+ public void testReentrantReadWriteLock_implDoesNotExposeShadowedLocks() {
+ assertEquals(
+ "Unexpected number of public methods in ReentrantReadWriteLock. " +
+ "The correctness of CycleDetectingReentrantReadWriteLock depends on " +
+ "the fact that the shadowed ReadLock and WriteLock are never used or " +
+ "exposed by the superclass implementation. If the implementation has " +
+ "changed, the code must be re-inspected to ensure that the " +
+ "assumption is still valid.",
+ 24, ReentrantReadWriteLock.class.getMethods().length);
+ }
+
+ private enum MyOrder {
+ FIRST, SECOND, THIRD;
+ }
+
+ private enum OtherOrder {
+ FIRST, SECOND, THIRD;
+ }
+
+ // Given a sequence of lock acquisition descriptions
+ // (e.g. "LockA -> LockB", "LockB -> LockC", ...)
+ // Checks that the exception.getMessage() matches a regex of the form:
+ // "LockA -> LockB \b.*\b LockB -> LockC \b.*\b LockC -> LockA"
+ private void checkMessage(
+ IllegalStateException exception, String... expectedLockCycle) {
+ String regex = Joiner.on("\\b.*\\b").join(expectedLockCycle);
+ assertContainsRegex(regex, exception.getMessage());
+ }
+
+ // TODO(cpovirk): consider adding support for regex to Truth
+ private static void assertContainsRegex(String expectedRegex, String actual) {
+ Pattern pattern = Pattern.compile(expectedRegex);
+ Matcher matcher = pattern.matcher(actual);
+ if (!matcher.find()) {
+ String actualDesc = (actual == null) ? "null" : ('<' + actual + '>');
+ fail("expected to contain regex:<" + expectedRegex + "> but was:"
+ + actualDesc);
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java b/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java
index a4a2a8d..92d9768 100644
--- a/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/ExecutionListTest.java
@@ -27,6 +27,7 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* Unit tests for {@link ExecutionList}.
@@ -36,10 +37,10 @@ import java.util.concurrent.TimeUnit;
*/
public class ExecutionListTest extends TestCase {
- protected ExecutionList list = new ExecutionList();
- protected Executor exec = Executors.newCachedThreadPool();
+ private final ExecutionList list = new ExecutionList();
public void testRunOnPopulatedList() throws Exception {
+ Executor exec = Executors.newCachedThreadPool();
CountDownLatch countDownLatch = new CountDownLatch(3);
list.add(new MockRunnable(countDownLatch), exec);
list.add(new MockRunnable(countDownLatch), exec);
@@ -52,13 +53,56 @@ public class ExecutionListTest extends TestCase {
assertTrue(countDownLatch.await(1L, TimeUnit.SECONDS));
}
+ public void testExecute_idempotent() {
+ final AtomicInteger runCalled = new AtomicInteger();
+ list.add(new Runnable() {
+ @Override public void run() {
+ runCalled.getAndIncrement();
+ }
+ }, MoreExecutors.sameThreadExecutor());
+ list.execute();
+ assertEquals(1, runCalled.get());
+ list.execute();
+ assertEquals(1, runCalled.get());
+ }
+
+ public void testExecute_idempotentConcurrently() throws InterruptedException {
+ final CountDownLatch okayToRun = new CountDownLatch(1);
+ final AtomicInteger runCalled = new AtomicInteger();
+ list.add(new Runnable() {
+ @Override public void run() {
+ try {
+ okayToRun.await();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ }
+ runCalled.getAndIncrement();
+ }
+ }, MoreExecutors.sameThreadExecutor());
+ Runnable execute = new Runnable() {
+ @Override public void run() {
+ list.execute();
+ }
+ };
+ Thread thread1 = new Thread(execute);
+ Thread thread2 = new Thread(execute);
+ thread1.start();
+ thread2.start();
+ assertEquals(0, runCalled.get());
+ okayToRun.countDown();
+ thread1.join();
+ thread2.join();
+ assertEquals(1, runCalled.get());
+ }
+
public void testAddAfterRun() throws Exception {
// Run the previous test
testRunOnPopulatedList();
// If it passed, then verify an Add will be executed without calling run
CountDownLatch countDownLatch = new CountDownLatch(1);
- list.add(new MockRunnable(countDownLatch), exec);
+ list.add(new MockRunnable(countDownLatch), Executors.newCachedThreadPool());
assertTrue(countDownLatch.await(1L, TimeUnit.SECONDS));
}
@@ -69,24 +113,19 @@ public class ExecutionListTest extends TestCase {
this.countDownLatch = countDownLatch;
}
- @Override
- public void run() {
+ @Override public void run() {
countDownLatch.countDown();
}
}
public void testExceptionsCaught() {
- ExecutionList list = new ExecutionList();
list.add(THROWING_RUNNABLE, sameThreadExecutor());
list.execute();
list.add(THROWING_RUNNABLE, sameThreadExecutor());
}
- public void testNulls() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Executor.class, sameThreadExecutor());
- tester.setDefault(Runnable.class, DO_NOTHING);
- tester.testAllPublicInstanceMethods(new ExecutionList());
+ public void testNulls() {
+ new NullPointerTester().testAllPublicInstanceMethods(new ExecutionList());
}
private static final Runnable THROWING_RUNNABLE = new Runnable() {
@@ -95,7 +134,6 @@ public class ExecutionListTest extends TestCase {
}
};
private static final Runnable DO_NOTHING = new Runnable() {
- @Override public void run() {
- }
+ @Override public void run() {}
};
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingBlockingQueueTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingBlockingQueueTest.java
new file mode 100644
index 0000000..c32eb3f
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingBlockingQueueTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link ForwardingBlockingQueue}
+ */
+public class ForwardingBlockingQueueTest extends TestCase {
+ public void testForwarding() {
+ ForwardingObjectTester.testForwardingObject(ForwardingBlockingQueue.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingCheckedFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingCheckedFutureTest.java
index b78c287..1a642be 100644
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingCheckedFutureTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingCheckedFutureTest.java
@@ -16,99 +16,15 @@
package com.google.common.util.concurrent;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import com.google.common.util.concurrent.ForwardingCheckedFuture.SimpleForwardingCheckedFuture;
-
import junit.framework.TestCase;
-import java.io.IOException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
/**
* Test for {@link ForwardingCheckedFuture}
*
- * @author Anthony Zana
+ * @author Ben Yu
*/
public class ForwardingCheckedFutureTest extends TestCase {
- private static final String VALUE = "delegated";
- private static final TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS;
-
- @SuppressWarnings("unchecked")
- private CheckedFuture<String, IOException> delegate =
- createMock(CheckedFuture.class);
-
- private TestDelegateFuture forwarded = new TestDelegateFuture();
- private TestSimpleFuture simple = new TestSimpleFuture();
-
- public void testCheckedGet() throws IOException {
- expect(delegate.checkedGet()).andReturn(VALUE).times(2);
- replay(delegate);
- assertEquals(VALUE, forwarded.checkedGet());
- assertEquals(VALUE, simple.checkedGet());
- verify(delegate);
- }
-
- public void testTimedCheckedGet() throws TimeoutException, IOException {
- expect(delegate.checkedGet(100, TIME_UNIT)).andReturn(VALUE).times(2);
- replay(delegate);
- assertEquals(VALUE, forwarded.checkedGet(100, TIME_UNIT));
- assertEquals(VALUE, simple.checkedGet(100, TIME_UNIT));
- verify(delegate);
- }
-
- public void testTimedCheckedGet_timeout()
- throws IOException, TimeoutException {
- expect(delegate.checkedGet(100, TIME_UNIT))
- .andThrow(new TimeoutException()).times(2);
- replay(delegate);
- try {
- forwarded.checkedGet(100, TIME_UNIT);
- fail();
- } catch (TimeoutException expected) {}
- try {
- simple.checkedGet(100, TIME_UNIT);
- fail();
- } catch (TimeoutException expected) {}
- verify(delegate);
- }
-
- public void testCheckedGetException() throws IOException {
- IOException expected = new IOException("expected");
- expect(delegate.checkedGet()).andThrow(expected).times(2);
- replay(delegate);
- try {
- delegate.checkedGet();
- fail();
- } catch (IOException e) {
- assertEquals(expected.getMessage(), e.getMessage());
- }
- try {
- simple.checkedGet();
- fail();
- } catch (IOException e) {
- assertEquals(expected.getMessage(), e.getMessage());
- }
- verify(delegate);
- }
-
- private class TestDelegateFuture
- extends ForwardingCheckedFuture<String, IOException> {
- @Override
- protected CheckedFuture<String, IOException> delegate() {
- return delegate;
- }
- }
-
- private class TestSimpleFuture
- extends SimpleForwardingCheckedFuture<String, IOException> {
- public TestSimpleFuture() {
- super(delegate);
- }
+ public void testForwarding() {
+ ForwardingObjectTester.testForwardingObject(ForwardingCheckedFuture.class);
}
-
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingExecutorServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingExecutorServiceTest.java
new file mode 100644
index 0000000..15f1e0e
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingExecutorServiceTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link ForwardingExecutorService}
+ */
+public class ForwardingExecutorServiceTest extends TestCase {
+ public void testForwarding() {
+ ForwardingObjectTester.testForwardingObject(ForwardingExecutorService.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingFutureTest.java
new file mode 100644
index 0000000..4ce9ebf
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingFutureTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link ForwardingFuture}
+ */
+public class ForwardingFutureTest extends TestCase {
+ public void testForwarding() {
+ ForwardingObjectTester.testForwardingObject(ForwardingFuture.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingListenableFutureTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingListenableFutureTest.java
index 4424e8d..827f50e 100644
--- a/guava-tests/test/com/google/common/util/concurrent/ForwardingListenableFutureTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingListenableFutureTest.java
@@ -21,48 +21,10 @@ import junit.framework.TestCase;
/**
* Tests for {@link ForwardingListenableFuture}.
*
- * @author Shardul Deo
+ * @author Ben Yu
*/
public class ForwardingListenableFutureTest extends TestCase {
-
- private SettableFuture<String> delegate;
- private ListenableFuture<String> forwardingFuture;
-
- private ListenableFutureTester tester;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- delegate = SettableFuture.create();
- forwardingFuture = new ForwardingListenableFuture<String>() {
- @Override
- protected ListenableFuture<String> delegate() {
- return delegate;
- }
- };
- tester = new ListenableFutureTester(forwardingFuture);
- tester.setUp();
- }
-
- @Override
- protected void tearDown() throws Exception {
- tester.tearDown();
- super.tearDown();
- }
-
- public void testCompletedFuture() throws Exception {
- delegate.set("foo");
- tester.testCompletedFuture("foo");
- }
-
- public void testCancelledFuture() throws Exception {
- delegate.cancel(true); // parameter is ignored
- tester.testCancelledFuture();
- }
-
- public void testFailedFuture() throws Exception {
- delegate.setException(new Exception("failed"));
- tester.testFailedFuture("failed");
+ public void testForwarding() {
+ ForwardingObjectTester.testForwardingObject(ForwardingListenableFuture.class);
}
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingListeningExecutorServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingListeningExecutorServiceTest.java
new file mode 100644
index 0000000..d4ebd61
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingListeningExecutorServiceTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link ForwardingListeningExecutorService}
+ */
+public class ForwardingListeningExecutorServiceTest extends TestCase {
+ public void testForwarding() {
+ ForwardingObjectTester.testForwardingObject(ForwardingListeningExecutorService.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java
new file mode 100644
index 0000000..edc48a9
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTester.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import com.google.common.base.Function;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ForwardingObject;
+import com.google.common.collect.Iterables;
+import com.google.common.testing.ForwardingWrapperTester;
+
+import org.easymock.EasyMock;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/**
+ * Tester for typical subclass of {@link ForwardingObject} by using EasyMock partial mocks.
+ *
+ * @author Ben Yu
+ */
+final class ForwardingObjectTester {
+
+ private static final Method DELEGATE_METHOD;
+ static {
+ try {
+ DELEGATE_METHOD = ForwardingObject.class.getDeclaredMethod("delegate");
+ DELEGATE_METHOD.setAccessible(true);
+ } catch (SecurityException e) {
+ throw new RuntimeException(e);
+ } catch (NoSuchMethodException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Ensures that all interface methods of {@code forwarderClass} are forwarded to the
+ * {@link ForwardingObject#delegate}. {@code forwarderClass} is assumed to only implement one
+ * interface.
+ */
+ static <T extends ForwardingObject> void testForwardingObject(final Class<T> forwarderClass) {
+ @SuppressWarnings("unchecked") // super interface type of T
+ Class<? super T> interfaceType = (Class<? super T>)
+ Iterables.getOnlyElement(Arrays.asList(forwarderClass.getInterfaces()));
+ new ForwardingWrapperTester().testForwarding(interfaceType, new Function<Object, T>() {
+ @Override public T apply(Object delegate) {
+ T mock = EasyMock.createMockBuilder(forwarderClass)
+ .addMockedMethod(DELEGATE_METHOD)
+ .createMock();
+ try {
+ DELEGATE_METHOD.invoke(mock);
+ } catch (Exception e) {
+ throw Throwables.propagate(e);
+ }
+ EasyMock.expectLastCall().andStubReturn(delegate);
+ EasyMock.replay(mock);
+ return mock;
+ }
+ });
+ }
+}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTesterTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTesterTest.java
new file mode 100644
index 0000000..eae45bc
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingObjectTesterTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import com.google.common.collect.ForwardingObject;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests for {@link ForwardingObjectTester}.
+ *
+ * @author Ben Yu
+ */
+public class ForwardingObjectTesterTest extends TestCase {
+
+ public void testFailsToForward() {
+ try {
+ ForwardingObjectTester.testForwardingObject(FailToForward.class);
+ } catch (AssertionError expected) {
+ return;
+ }
+ fail("Should have thrown");
+ }
+
+ public void testSuccessfulForwarding() {
+ ForwardingObjectTester.testForwardingObject(ForwardToDelegate.class);
+ }
+
+ private static abstract class FailToForward extends ForwardingObject implements Runnable {
+ @Override public void run() {}
+ }
+
+ private static abstract class ForwardToDelegate extends ForwardingObject implements Runnable {
+ @Override public void run() {
+ delegate().run();
+ }
+ @Override protected abstract Runnable delegate();
+ }
+}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ForwardingServiceTest.java b/guava-tests/test/com/google/common/util/concurrent/ForwardingServiceTest.java
new file mode 100644
index 0000000..e18b00e
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/ForwardingServiceTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link ForwardingService}
+ */
+public class ForwardingServiceTest extends TestCase {
+ public void testForwarding() {
+ ForwardingObjectTester.testForwardingObject(ForwardingService.class);
+ }
+}
diff --git a/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java b/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java
index ea9a3da..44e759b 100644
--- a/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/FuturesTest.java
@@ -23,10 +23,12 @@ import static com.google.common.util.concurrent.Futures.getUnchecked;
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
import static com.google.common.util.concurrent.Futures.immediateFuture;
import static com.google.common.util.concurrent.Futures.successfulAsList;
+import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.easymock.EasyMock.expect;
+import static org.truth0.Truth.ASSERT;
import com.google.common.base.Function;
import com.google.common.base.Functions;
@@ -35,7 +37,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
-import com.google.common.testing.NullPointerTester;
+import com.google.common.testing.ClassSanityTester;
import com.google.common.util.concurrent.ForwardingFuture.SimpleForwardingFuture;
import junit.framework.AssertionFailedError;
@@ -54,9 +56,12 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
import javax.annotation.Nullable;
@@ -122,6 +127,27 @@ public class FuturesTest extends TestCase {
}
}
+ public void testImmediateFailedFuture_cancellationException() throws Exception {
+ CancellationException exception = new CancellationException();
+ ListenableFuture<String> future =
+ Futures.immediateFailedFuture(exception);
+
+ try {
+ future.get(0L, TimeUnit.MILLISECONDS);
+ fail("This call was supposed to throw an ExecutionException");
+ } catch (ExecutionException expected) {
+ // This is good and expected
+ assertSame(exception, expected.getCause());
+ assertFalse(future.isCancelled());
+ }
+ }
+
+ public void testImmediateCancelledFuture() throws Exception {
+ ListenableFuture<String> future =
+ Futures.immediateCancelledFuture();
+ assertTrue(future.isCancelled());
+ }
+
private static class MyException extends Exception {}
public void testImmediateCheckedFuture() throws Exception {
@@ -194,6 +220,61 @@ public class FuturesTest extends TestCase {
assertSame(barChild, bar);
}
+ public void testTransform_ListenableFuture_cancelPropagatesToInput() throws Exception {
+ SettableFuture<Foo> input = SettableFuture.create();
+ AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
+ @Override public ListenableFuture<Bar> apply(Foo unused) {
+ fail("Unexpeted call to apply.");
+ return null;
+ }
+ };
+ assertTrue(Futures.transform(input, function).cancel(false));
+ assertTrue(input.isCancelled());
+ assertFalse(input.wasInterrupted());
+ }
+
+ public void testTransform_ListenableFuture_interruptPropagatesToInput()
+ throws Exception {
+ SettableFuture<Foo> input = SettableFuture.create();
+ AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
+ @Override public ListenableFuture<Bar> apply(Foo unused) {
+ fail("Unexpeted call to apply.");
+ return null;
+ }
+ };
+ assertTrue(Futures.transform(input, function).cancel(true));
+ assertTrue(input.isCancelled());
+ assertTrue(input.wasInterrupted());
+ }
+
+ public void testTransform_ListenableFuture_cancelPropagatesToAsyncOutput()
+ throws Exception {
+ ListenableFuture<Foo> immediate = Futures.immediateFuture(new Foo());
+ final SettableFuture<Bar> secondary = SettableFuture.create();
+ AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
+ @Override public ListenableFuture<Bar> apply(Foo unused) {
+ return secondary;
+ }
+ };
+ assertTrue(Futures.transform(immediate, function).cancel(false));
+ assertTrue(secondary.isCancelled());
+ assertFalse(secondary.wasInterrupted());
+ }
+
+ public void testTransform_ListenableFuture_interruptPropagatesToAsyncOutput()
+ throws Exception {
+ ListenableFuture<Foo> immediate = Futures.immediateFuture(new Foo());
+ final SettableFuture<Bar> secondary = SettableFuture.create();
+ AsyncFunction<Foo, Bar> function = new AsyncFunction<Foo, Bar>() {
+ @Override public ListenableFuture<Bar> apply(Foo unused) {
+ return secondary;
+ }
+ };
+ assertTrue(Futures.transform(immediate, function).cancel(true));
+ assertTrue(secondary.isCancelled());
+ assertTrue(secondary.wasInterrupted());
+ }
+
/**
* {@link ListenableFuture} variant of
* {@link #testTransformValueRemainsMemoized_Future()}.
@@ -382,6 +463,28 @@ public class FuturesTest extends TestCase {
assertEquals(2, spy.getApplyCount());
}
+ public void testLazyTransform_exception() throws Exception {
+ final RuntimeException exception = new RuntimeException("deliberate");
+ Function<Integer, String> function = new Function<Integer, String>() {
+ @Override public String apply(Integer input) {
+ throw exception;
+ }
+ };
+ Future<String> transformed = Futures.lazyTransform(Futures.immediateFuture(1), function);
+ try {
+ transformed.get();
+ fail();
+ } catch (ExecutionException expected) {
+ assertSame(exception, expected.getCause());
+ }
+ try {
+ transformed.get(1, TimeUnit.SECONDS);
+ fail();
+ } catch (ExecutionException expected) {
+ assertSame(exception, expected.getCause());
+ }
+ }
+
private static class FunctionSpy<I, O> implements Function<I, O> {
private int applyCount;
private final Function<I, O> delegate;
@@ -401,6 +504,150 @@ public class FuturesTest extends TestCase {
}
}
+ @SuppressWarnings("unchecked")
+ public void testWithFallback_inputDoesNotRaiseException() throws Exception {
+ FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
+ ListenableFuture<Integer> originalFuture = Futures.immediateFuture(7);
+
+ mocksControl.replay();
+ ListenableFuture<Integer> faultToleranteFuture = Futures.withFallback(originalFuture, fallback);
+ assertEquals(7, faultToleranteFuture.get().intValue());
+ mocksControl.verify();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testWithFallback_inputRaisesException() throws Exception {
+ FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
+ RuntimeException raisedException = new RuntimeException();
+ expect(fallback.create(raisedException)).andReturn(Futures.immediateFuture(20));
+ ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
+
+ mocksControl.replay();
+ ListenableFuture<Integer> faultToleranteFuture = Futures.withFallback(failingFuture, fallback);
+ assertEquals(20, faultToleranteFuture.get().intValue());
+ mocksControl.verify();
+ }
+
+ public void testWithFallback_fallbackGeneratesRuntimeException() throws Exception {
+ RuntimeException expectedException = new RuntimeException();
+ runExpectedExceptionFallbackTest(expectedException, false);
+ }
+
+ public void testWithFallback_fallbackGeneratesCheckedException() throws Exception {
+ Exception expectedException = new Exception() {};
+ runExpectedExceptionFallbackTest(expectedException, false);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testWithFallback_fallbackGeneratesError() throws Exception {
+ Error error = new Error("deliberate");
+ FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
+ RuntimeException raisedException = new RuntimeException();
+ expect(fallback.create(raisedException)).andThrow(error);
+ ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
+ mocksControl.replay();
+ try {
+ Futures.withFallback(failingFuture, fallback);
+ fail("An Exception should have been thrown!");
+ } catch (Error expected) {
+ assertSame(error, expected);
+ }
+ mocksControl.verify();
+ }
+
+ public void testWithFallback_fallbackReturnsRuntimeException() throws Exception {
+ RuntimeException expectedException = new RuntimeException();
+ runExpectedExceptionFallbackTest(expectedException, true);
+ }
+
+ public void testWithFallback_fallbackReturnsCheckedException() throws Exception {
+ Exception expectedException = new Exception() {};
+ runExpectedExceptionFallbackTest(expectedException, true);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void runExpectedExceptionFallbackTest(
+ Throwable expectedException, boolean wrapInFuture) throws Exception {
+ FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
+ RuntimeException raisedException = new RuntimeException();
+ if (!wrapInFuture) {
+ // Exception is thrown in the body of the "fallback" method.
+ expect(fallback.create(raisedException)).andThrow(expectedException);
+ } else {
+ // Exception is wrapped in a future and returned.
+ expect(fallback.create(raisedException)).andReturn(
+ Futures.<Integer>immediateFailedFuture(expectedException));
+ }
+
+ ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
+
+ mocksControl.replay();
+ ListenableFuture<Integer> faultToleranteFuture = Futures.withFallback(failingFuture, fallback);
+ try {
+ faultToleranteFuture.get();
+ fail("An Exception should have been thrown!");
+ } catch (ExecutionException ee) {
+ assertSame(expectedException, ee.getCause());
+ }
+ mocksControl.verify();
+ }
+
+ public void testWithFallback_fallbackNotReady() throws Exception {
+ ListenableFuture<Integer> primary = immediateFailedFuture(new Exception());
+ final SettableFuture<Integer> secondary = SettableFuture.create();
+ FutureFallback<Integer> fallback = new FutureFallback<Integer>() {
+ @Override
+ public ListenableFuture<Integer> create(Throwable t) {
+ return secondary;
+ }
+ };
+ ListenableFuture<Integer> derived = Futures.withFallback(primary, fallback);
+ secondary.set(1);
+ assertEquals(1, (int) derived.get());
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testWithFallback_resultInterruptedBeforeFallback() throws Exception {
+ SettableFuture<Integer> primary = SettableFuture.create();
+ FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
+
+ mocksControl.replay();
+ ListenableFuture<Integer> derived = Futures.withFallback(primary, fallback);
+ derived.cancel(true);
+ assertTrue(primary.isCancelled());
+ assertTrue(primary.wasInterrupted());
+ mocksControl.verify();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testWithFallback_resultCancelledBeforeFallback() throws Exception {
+ SettableFuture<Integer> primary = SettableFuture.create();
+ FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
+
+ mocksControl.replay();
+ ListenableFuture<Integer> derived = Futures.withFallback(primary, fallback);
+ derived.cancel(false);
+ assertTrue(primary.isCancelled());
+ assertFalse(primary.wasInterrupted());
+ mocksControl.verify();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void testWithFallback_resultCancelledAfterFallback() throws Exception {
+ SettableFuture<Integer> secondary = SettableFuture.create();
+ FutureFallback<Integer> fallback = mocksControl.createMock(FutureFallback.class);
+ RuntimeException raisedException = new RuntimeException();
+ expect(fallback.create(raisedException)).andReturn(secondary);
+ ListenableFuture<Integer> failingFuture = Futures.immediateFailedFuture(raisedException);
+
+ mocksControl.replay();
+ ListenableFuture<Integer> derived = Futures.withFallback(failingFuture, fallback);
+ derived.cancel(false);
+ assertTrue(secondary.isCancelled());
+ assertFalse(secondary.wasInterrupted());
+ mocksControl.verify();
+ }
+
public void testTransform_genericsWildcard_AsyncFunction() throws Exception {
ListenableFuture<?> nullFuture = Futures.immediateFuture(null);
ListenableFuture<?> chainedFuture =
@@ -433,74 +680,108 @@ public class FuturesTest extends TestCase {
assertSame(barChild, bar);
}
- public void testTransform_delegatesBlockingGet_AsyncFunction() throws Exception {
- performAsyncFunctionTransformedFutureDelgationTest(0, null);
+ public void testTransform_asyncFunction_timeout()
+ throws InterruptedException, ExecutionException {
+ AsyncFunction<String, Integer> function = constantAsyncFunction(Futures.immediateFuture(1));
+ ListenableFuture<Integer> future = Futures.transform(
+ SettableFuture.<String>create(), function);
+ try {
+ future.get(1, TimeUnit.MILLISECONDS);
+ fail();
+ } catch (TimeoutException expected) {}
}
- public void testTransform_delegatesTimedGet_AsyncFunction() throws Exception {
- performAsyncFunctionTransformedFutureDelgationTest(25, TimeUnit.SECONDS);
+ public void testTransform_asyncFunction_error() {
+ final Error error = new Error("deliberate");
+ AsyncFunction<String, Integer> function = new AsyncFunction<String, Integer>() {
+ @Override public ListenableFuture<Integer> apply(String input) {
+ throw error;
+ }
+ };
+ SettableFuture<String> inputFuture = SettableFuture.create();
+ Futures.transform(inputFuture, function);
+ try {
+ inputFuture.set("value");
+ } catch (Error expected) {
+ assertSame(error, expected);
+ return;
+ }
+ fail("should have thrown error");
+ }
+
+ public void testTransform_asyncFunction_cancelledWhileApplyingFunction()
+ throws InterruptedException, ExecutionException {
+ final CountDownLatch inFunction = new CountDownLatch(1);
+ final CountDownLatch functionDone = new CountDownLatch(1);
+ final SettableFuture<Integer> resultFuture = SettableFuture.create();
+ AsyncFunction<String, Integer> function = new AsyncFunction<String, Integer>() {
+ @Override public ListenableFuture<Integer> apply(String input) throws Exception {
+ inFunction.countDown();
+ functionDone.await();
+ return resultFuture;
+ }
+ };
+ SettableFuture<String> inputFuture = SettableFuture.create();
+ ListenableFuture<Integer> future = Futures.transform(
+ inputFuture, function, Executors.newSingleThreadExecutor());
+ inputFuture.set("value");
+ inFunction.await();
+ future.cancel(false);
+ functionDone.countDown();
+ try {
+ future.get();
+ fail();
+ } catch (CancellationException expected) {}
+ try {
+ resultFuture.get();
+ fail();
+ } catch (CancellationException expected) {}
}
- private void performAsyncFunctionTransformedFutureDelgationTest(
- long timeout, TimeUnit unit)
- throws InterruptedException, ExecutionException, TimeoutException {
- final Foo foo = new Foo();
- MockRequiresGetCallFuture<Foo> fooFuture =
- new MockRequiresGetCallFuture<Foo>(foo);
-
- Bar bar = new Bar();
- final MockRequiresGetCallFuture<Bar> barFuture =
- new MockRequiresGetCallFuture<Bar>(bar);
- AsyncFunction<Foo, Bar> function =
- new AsyncFunction<Foo, Bar>() {
- @Override public ListenableFuture<Bar> apply(Foo from) {
- assertSame(foo, from);
- return barFuture;
- }
- };
-
- ListenableFuture<Bar> chainFuture = Futures.transform(fooFuture, function);
- Bar theBar;
- if (unit != null) {
- theBar = chainFuture.get(timeout, unit);
- } else {
- theBar = chainFuture.get();
- }
- assertSame(bar, theBar);
- assertTrue(fooFuture.getWasGetCalled());
- assertTrue(barFuture.getWasGetCalled());
+ public void testDereference_genericsWildcard() throws Exception {
+ ListenableFuture<?> inner = Futures.immediateFuture(null);
+ ListenableFuture<ListenableFuture<?>> outer =
+ Futures.<ListenableFuture<?>>immediateFuture(inner);
+ ListenableFuture<?> dereferenced = Futures.dereference(outer);
+ assertNull(dereferenced.get());
}
- /**
- * A mock listenable future that requires the caller invoke
- * either form of get() before the future will make its value
- * available or invoke listeners.
- */
- private static class MockRequiresGetCallFuture<T> extends AbstractFuture<T> {
-
- private final T value;
- private boolean getWasCalled;
+ public void testDereference_genericsHierarchy() throws Exception {
+ FooChild fooChild = new FooChild();
+ ListenableFuture<FooChild> inner = Futures.immediateFuture(fooChild);
+ ListenableFuture<ListenableFuture<FooChild>> outer = Futures.immediateFuture(inner);
+ ListenableFuture<Foo> dereferenced = Futures.<Foo>dereference(outer);
+ assertSame(fooChild, dereferenced.get());
+ }
- MockRequiresGetCallFuture(T value) {
- this.value = value;
- }
+ public void testDereference_resultCancelsOuter() throws Exception {
+ ListenableFuture<ListenableFuture<Foo>> outer = SettableFuture.create();
+ ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
+ dereferenced.cancel(true);
+ assertTrue(outer.isCancelled());
+ }
- @Override public T get() throws InterruptedException, ExecutionException {
- set(value);
- getWasCalled = true;
- return super.get();
- }
+ public void testDereference_resultCancelsInner() throws Exception {
+ ListenableFuture<Foo> inner = SettableFuture.create();
+ ListenableFuture<ListenableFuture<Foo>> outer = Futures.immediateFuture(inner);
+ ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
+ dereferenced.cancel(true);
+ assertTrue(inner.isCancelled());
+ }
- @Override public T get(long timeout, TimeUnit unit)
- throws TimeoutException, ExecutionException, InterruptedException {
- set(value);
- getWasCalled = true;
- return super.get(timeout, unit);
- }
+ public void testDereference_outerCancelsResult() throws Exception {
+ ListenableFuture<ListenableFuture<Foo>> outer = SettableFuture.create();
+ ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
+ outer.cancel(true);
+ assertTrue(dereferenced.isCancelled());
+ }
- boolean getWasGetCalled() {
- return getWasCalled;
- }
+ public void testDereference_innerCancelsResult() throws Exception {
+ ListenableFuture<Foo> inner = SettableFuture.create();
+ ListenableFuture<ListenableFuture<Foo>> outer = Futures.immediateFuture(inner);
+ ListenableFuture<Foo> dereferenced = Futures.dereference(outer);
+ inner.cancel(true);
+ assertTrue(dereferenced.isCancelled());
}
/**
@@ -559,7 +840,7 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).hasContentsInOrder(DATA1, DATA2, DATA3);
+ ASSERT.that(results).has().allOf(DATA1, DATA2, DATA3).inOrder();
}
public void testAllAsList_emptyList() throws Exception {
@@ -635,6 +916,27 @@ public class FuturesTest extends TestCase {
}
}
+ public void testAllAsList_error() throws Exception {
+ Error error = new Error("deliberate");
+ SettableFuture<String> future1 = SettableFuture.create();
+ ListenableFuture<String> future2 = Futures.immediateFuture("results");
+ ListenableFuture<List<String>> compound = Futures.allAsList(ImmutableList.of(future1, future2));
+
+ try {
+ future1.setException(error);
+ } catch (Error expected) {
+ assertSame(error, expected);
+ try {
+ compound.get();
+ } catch (ExecutionException ee) {
+ assertSame(error, ee.getCause());
+ return;
+ }
+ fail("Expected error not set in compound future.");
+ }
+ fail("Expected error not thrown");
+ }
+
public void testAllAsList_cancelled() throws Exception {
SingleCallListener listener = new SingleCallListener();
SettableFuture<String> future1 = SettableFuture.create();
@@ -658,22 +960,34 @@ public class FuturesTest extends TestCase {
}
}
- public void testAllAsList_buggyInputFutures() throws Exception {
- final Foo foo1 = new Foo();
- MockRequiresGetCallFuture<Foo> foo1Future =
- new MockRequiresGetCallFuture<Foo>(foo1);
- final Foo foo2 = new Foo();
- MockRequiresGetCallFuture<Foo> foo2Future =
- new MockRequiresGetCallFuture<Foo>(foo2);
+ public void testAllAsList_resultCancelled() throws Exception {
+ SettableFuture<String> future1 = SettableFuture.create();
+ SettableFuture<String> future2 = SettableFuture.create();
+ @SuppressWarnings("unchecked") // array is never modified
+ ListenableFuture<List<String>> compound =
+ Futures.allAsList(future1, future2);
+
+ future2.set(DATA2);
+ assertFalse(compound.isDone());
+ assertTrue(compound.cancel(false));
+ assertTrue(compound.isCancelled());
+ assertTrue(future1.isCancelled());
+ assertFalse(future1.wasInterrupted());
+ }
+ public void testAllAsList_resultInterrupted() throws Exception {
+ SettableFuture<String> future1 = SettableFuture.create();
+ SettableFuture<String> future2 = SettableFuture.create();
@SuppressWarnings("unchecked") // array is never modified
- ListenableFuture<List<Foo>> compound =
- Futures.allAsList(foo1Future, foo2Future);
+ ListenableFuture<List<String>> compound =
+ Futures.allAsList(future1, future2);
+ future2.set(DATA2);
assertFalse(compound.isDone());
- ASSERT.that(compound.get()).hasContentsAnyOrder(foo1, foo2);
- assertTrue(foo1Future.getWasGetCalled());
- assertTrue(foo2Future.getWasGetCalled());
+ assertTrue(compound.cancel(true));
+ assertTrue(compound.isCancelled());
+ assertTrue(future1.isCancelled());
+ assertTrue(future1.wasInterrupted());
}
/**
@@ -707,10 +1021,10 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).hasContentsInOrder(DATA1, DATA2, DATA3);
+ ASSERT.that(results).has().allOf(DATA1, DATA2, DATA3).inOrder();
}
- private String createCombinedResult(Integer i, Boolean b) {
+ private static String createCombinedResult(Integer i, Boolean b) {
return "-" + i + "-" + b;
}
@@ -1127,7 +1441,7 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).hasContentsInOrder(DATA1, DATA2, DATA3);
+ ASSERT.that(results).has().allOf(DATA1, DATA2, DATA3).inOrder();
}
public void testSuccessfulAsList_emptyList() throws Exception {
@@ -1170,7 +1484,7 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).hasContentsInOrder(null, DATA2);
+ ASSERT.that(results).has().allOf(null, DATA2).inOrder();
}
public void testSuccessfulAsList_totalFailure() throws Exception {
@@ -1191,7 +1505,7 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).hasContentsInOrder(null, null);
+ ASSERT.that(results).has().allOf(null, null).inOrder();
}
public void testSuccessfulAsList_cancelled() throws Exception {
@@ -1212,7 +1526,108 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).hasContentsInOrder(null, DATA2);
+ ASSERT.that(results).has().allOf(null, DATA2).inOrder();
+ }
+
+ public void testSuccessfulAsList_resultCancelled() throws Exception {
+ SettableFuture<String> future1 = SettableFuture.create();
+ SettableFuture<String> future2 = SettableFuture.create();
+ @SuppressWarnings("unchecked") // array is never modified
+ ListenableFuture<List<String>> compound =
+ Futures.successfulAsList(future1, future2);
+
+ future2.set(DATA2);
+ assertFalse(compound.isDone());
+ assertTrue(compound.cancel(false));
+ assertTrue(compound.isCancelled());
+ assertTrue(future1.isCancelled());
+ assertFalse(future1.wasInterrupted());
+ }
+
+ public void testSuccessfulAsList_resultCancelledRacingInputDone()
+ throws Exception {
+ /*
+ * The IllegalStateException that we're testing for is caught by
+ * ExecutionList and logged rather than allowed to propagate. We need to
+ * turn that back into a failure.
+ */
+ Handler throwingHandler = new Handler() {
+ @Override public void publish(@Nullable LogRecord record) {
+ AssertionFailedError error = new AssertionFailedError();
+ error.initCause(record.getThrown());
+ throw error;
+ }
+
+ @Override public void flush() {}
+
+ @Override public void close() {}
+ };
+
+ ExecutionList.log.addHandler(throwingHandler);
+ try {
+ doTestSuccessfulAsList_resultCancelledRacingInputDone();
+ } finally {
+ ExecutionList.log.removeHandler(throwingHandler);
+ }
+ }
+
+ private static void doTestSuccessfulAsList_resultCancelledRacingInputDone()
+ throws Exception {
+ // Simple (combined.cancel -> input.cancel -> setOneValue):
+ Futures.successfulAsList(ImmutableList.of(SettableFuture.create()))
+ .cancel(true);
+
+ /*
+ * Complex (combined.cancel -> input.cancel -> other.set -> setOneValue),
+ * to show that this isn't just about problems with the input future we just
+ * cancelled:
+ */
+ final SettableFuture<String> future1 = SettableFuture.create();
+ final SettableFuture<String> future2 = SettableFuture.create();
+ @SuppressWarnings("unchecked") // array is never modified
+ ListenableFuture<List<String>> compound =
+ Futures.successfulAsList(future1, future2);
+
+ future1.addListener(new Runnable() {
+ @Override public void run() {
+ assertTrue(future1.isCancelled());
+ /*
+ * This test relies on behavior that's unspecified but currently
+ * guaranteed by the implementation: Cancellation of inputs is
+ * performed in the order they were provided to the constructor. Verify
+ * that as a sanity check:
+ */
+ assertFalse(future2.isCancelled());
+ // Now attempt to trigger the exception:
+ future2.set(DATA2);
+ }
+ }, sameThreadExecutor());
+ assertTrue(compound.cancel(false));
+ assertTrue(compound.isCancelled());
+ assertTrue(future1.isCancelled());
+ assertFalse(future2.isCancelled());
+
+ try {
+ compound.get();
+ fail("Expected exception not thrown");
+ } catch (CancellationException e) {
+ // Expected
+ }
+ }
+
+ public void testSuccessfulAsList_resultInterrupted() throws Exception {
+ SettableFuture<String> future1 = SettableFuture.create();
+ SettableFuture<String> future2 = SettableFuture.create();
+ @SuppressWarnings("unchecked") // array is never modified
+ ListenableFuture<List<String>> compound =
+ Futures.successfulAsList(future1, future2);
+
+ future2.set(DATA2);
+ assertFalse(compound.isDone());
+ assertTrue(compound.cancel(true));
+ assertTrue(compound.isCancelled());
+ assertTrue(future1.isCancelled());
+ assertTrue(future1.wasInterrupted());
}
public void testSuccessfulAsList_mixed() throws Exception {
@@ -1237,25 +1652,7 @@ public class FuturesTest extends TestCase {
assertTrue(listener.wasCalled());
List<String> results = compound.get();
- ASSERT.that(results).hasContentsInOrder(null, null, DATA3);
- }
-
- public void testSuccessfulAsList_buggyInputFutures() throws Exception {
- final Foo foo1 = new Foo();
- MockRequiresGetCallFuture<Foo> foo1Future =
- new MockRequiresGetCallFuture<Foo>(foo1);
- final Foo foo2 = new Foo();
- MockRequiresGetCallFuture<Foo> foo2Future =
- new MockRequiresGetCallFuture<Foo>(foo2);
-
- @SuppressWarnings("unchecked") // array is never modified
- ListenableFuture<List<Foo>> compound =
- Futures.successfulAsList(foo1Future, foo2Future);
-
- assertFalse(compound.isDone());
- ASSERT.that(compound.get()).hasContentsAnyOrder(foo1, foo2);
- assertTrue(foo1Future.getWasGetCalled());
- assertTrue(foo2Future.getWasGetCalled());
+ ASSERT.that(results).has().allOf(null, null, DATA3).inOrder();
}
private static class TestException extends Exception {
@@ -1485,20 +1882,8 @@ public class FuturesTest extends TestCase {
private static final Future<String> FAILED_FUTURE_OTHER_THROWABLE =
immediateFailedFuture(OTHER_THROWABLE);
private static final Error ERROR = new Error("mymessage");
- private static final Future<String> FAILED_FUTURE_ERROR;
- /*
- * We can't write "= immediateFailedFuture(ERROR)" because setException
- * rethrows the error....
- */
- static {
- SettableFuture<String> f = SettableFuture.create();
- try {
- f.setException(ERROR);
- } catch (Error e) {
- assertEquals(e, ERROR);
- }
- FAILED_FUTURE_ERROR = f;
- }
+ private static final Future<String> FAILED_FUTURE_ERROR =
+ immediateFailedFuture(ERROR);
private static final Future<String> RUNTIME_EXCEPTION_FUTURE =
new SimpleForwardingFuture<String>(FAILED_FUTURE_CHECKED_EXCEPTION) {
@Override public String get() {
@@ -1519,9 +1904,10 @@ public class FuturesTest extends TestCase {
}
public void testGetUntimed_interrupted() {
+ SettableFuture<String> future = SettableFuture.create();
Thread.currentThread().interrupt();
try {
- get(immediateFuture("foo"), TwoArgConstructorException.class);
+ get(future, TwoArgConstructorException.class);
fail();
} catch (TwoArgConstructorException expected) {
assertTrue(expected.getCause() instanceof InterruptedException);
@@ -1590,6 +1976,24 @@ public class FuturesTest extends TestCase {
}
}
+ public void testGetUntimed_badExceptionConstructor_wrapsOriginalChecked() throws Exception {
+ try {
+ get(FAILED_FUTURE_CHECKED_EXCEPTION, ExceptionWithBadConstructor.class);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ assertSame(CHECKED_EXCEPTION, expected.getCause());
+ }
+ }
+
+ public void testGetUntimed_withGoodAndBadExceptionConstructor() throws Exception {
+ try {
+ get(FAILED_FUTURE_CHECKED_EXCEPTION, ExceptionWithGoodAndBadConstructor.class);
+ fail();
+ } catch (ExceptionWithGoodAndBadConstructor expected) {
+ assertSame(CHECKED_EXCEPTION, expected.getCause());
+ }
+ }
+
// Boring timed-get tests:
public void testGetTimed_success()
@@ -1599,9 +2003,10 @@ public class FuturesTest extends TestCase {
}
public void testGetTimed_interrupted() {
+ SettableFuture<String> future = SettableFuture.create();
Thread.currentThread().interrupt();
try {
- get(immediateFuture("foo"), 0, SECONDS, TwoArgConstructorException.class);
+ get(future, 0, SECONDS, TwoArgConstructorException.class);
fail();
} catch (TwoArgConstructorException expected) {
assertTrue(expected.getCause() instanceof InterruptedException);
@@ -1684,6 +2089,25 @@ public class FuturesTest extends TestCase {
}
}
+ public void testGetTimed_badExceptionConstructor_wrapsOriginalChecked() throws Exception {
+ try {
+ get(FAILED_FUTURE_CHECKED_EXCEPTION, 1, TimeUnit.SECONDS, ExceptionWithBadConstructor.class);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ assertSame(CHECKED_EXCEPTION, expected.getCause());
+ }
+ }
+
+ public void testGetTimed_withGoodAndBadExceptionConstructor() throws Exception {
+ try {
+ get(FAILED_FUTURE_CHECKED_EXCEPTION, 1, TimeUnit.SECONDS,
+ ExceptionWithGoodAndBadConstructor.class);
+ fail();
+ } catch (ExceptionWithGoodAndBadConstructor expected) {
+ assertSame(CHECKED_EXCEPTION, expected.getCause());
+ }
+ }
+
// Boring getUnchecked tests:
public void testGetUnchecked_success() {
@@ -1907,31 +2331,26 @@ public class FuturesTest extends TestCase {
}
}
- public void testNullArguments() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(ListenableFuture.class, Futures.immediateFuture(DATA1));
- tester.setDefault(ListenableFuture[].class,
- new ListenableFuture[] {Futures.immediateFuture(DATA1)});
- tester.setDefault(Future.class, Futures.immediateFuture(DATA1));
- tester.setDefault(Executor.class, MoreExecutors.sameThreadExecutor());
- tester.setDefault(Callable.class, Callables.returning(null));
- tester.setDefault(AsyncFunction.class, new AsyncFunction() {
- @Override
- public ListenableFuture apply(Object input) throws Exception {
- return immediateFuture(DATA1);
- }
- });
+ private static final class ExceptionWithGoodAndBadConstructor extends Exception {
+ public ExceptionWithGoodAndBadConstructor(String message, Throwable cause) {
+ throw new RuntimeException("bad constructor");
+ }
+ public ExceptionWithGoodAndBadConstructor(Throwable cause) {
+ super(cause);
+ }
+ }
- FutureCallback<Object> callback =
- new FutureCallback<Object>() {
- @Override
- public void onSuccess(Object result) {}
- @Override
- public void onFailure(Throwable t) {}
- };
- tester.setDefault(FutureCallback.class, callback);
+ private static final class ExceptionWithBadConstructor extends Exception {
+ public ExceptionWithBadConstructor(String message, Throwable cause) {
+ throw new RuntimeException("bad constructor");
+ }
+ }
- tester.testAllPublicStaticMethods(Futures.class);
+ public void testFutures_nullChecks() throws Exception {
+ new ClassSanityTester()
+ .forAllPublicStaticMethods(Futures.class)
+ .thatReturn(Future.class)
+ .testNulls();
}
private static void failWithCause(Throwable cause, String message) {
diff --git a/guava-tests/test/com/google/common/util/concurrent/InterruptionUtil.java b/guava-tests/test/com/google/common/util/concurrent/InterruptionUtil.java
index e610b20..50d1be0 100644
--- a/guava-tests/test/com/google/common/util/concurrent/InterruptionUtil.java
+++ b/guava-tests/test/com/google/common/util/concurrent/InterruptionUtil.java
@@ -16,6 +16,7 @@
package com.google.common.util.concurrent;
+import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static junit.framework.Assert.fail;
@@ -73,6 +74,7 @@ final class InterruptionUtil {
* Interrupts the current thread after sleeping for the specified delay.
*/
static void requestInterruptIn(final long time, final TimeUnit unit) {
+ checkNotNull(unit);
final Thread interruptee = Thread.currentThread();
new Thread(new Runnable() {
@Override
diff --git a/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java b/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java
index 80b9599..23fc1e8 100644
--- a/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java
+++ b/guava-tests/test/com/google/common/util/concurrent/JSR166TestCase.java
@@ -15,20 +15,15 @@
package com.google.common.util.concurrent;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
import junit.framework.*;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.NoSuchElementException;
-import java.util.PropertyPermission;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.NANOSECONDS;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
@@ -36,6 +31,13 @@ import java.security.Permissions;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.security.SecurityPermission;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.NoSuchElementException;
+import java.util.PropertyPermission;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Base class for JSR166 Junit TCK tests. Defines some constants,
diff --git a/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java b/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java
index 298733f..ab072eb 100644
--- a/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/JdkFutureAdaptersTest.java
@@ -23,7 +23,7 @@ import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor
import static java.util.concurrent.Executors.newCachedThreadPool;
import static java.util.concurrent.TimeUnit.SECONDS;
-import com.google.common.testing.NullPointerTester;
+import com.google.common.testing.ClassSanityTester;
import com.google.common.util.concurrent.FuturesTest.ExecutorSpy;
import com.google.common.util.concurrent.FuturesTest.SingleCallListener;
@@ -206,9 +206,10 @@ public class JdkFutureAdaptersTest extends TestCase {
assertTrue(lateListener.wasRun.await(1, SECONDS));
}
- public void testNullArguments() throws Exception {
- NullPointerTester tester = new NullPointerTester();
- tester.setDefault(Future.class, immediateFuture(DATA1));
- tester.testAllPublicStaticMethods(JdkFutureAdapters.class);
+ public void testAdapters_nullChecks() throws Exception {
+ new ClassSanityTester()
+ .forAllPublicStaticMethods(JdkFutureAdapters.class)
+ .thatReturn(Future.class)
+ .testNulls();
}
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java b/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java
index 367b95a..cb10fc8 100644
--- a/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java
+++ b/guava-tests/test/com/google/common/util/concurrent/ListenableFutureTester.java
@@ -16,6 +16,7 @@
package com.google.common.util.concurrent;
+import static com.google.common.base.Preconditions.checkNotNull;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -28,6 +29,8 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import javax.annotation.Nullable;
+
/**
* Used to test listenable future implementations.
*
@@ -41,7 +44,7 @@ public class ListenableFutureTester {
public ListenableFutureTester(ListenableFuture<?> future) {
this.exec = Executors.newCachedThreadPool();
- this.future = future;
+ this.future = checkNotNull(future);
this.latch = new CountDownLatch(1);
}
@@ -61,7 +64,7 @@ public class ListenableFutureTester {
exec.shutdown();
}
- public void testCompletedFuture(Object expectedValue)
+ public void testCompletedFuture(@Nullable Object expectedValue)
throws InterruptedException, ExecutionException {
assertTrue(future.isDone());
assertFalse(future.isCancelled());
@@ -88,7 +91,7 @@ public class ListenableFutureTester {
} catch (CancellationException expected) {}
}
- public void testFailedFuture(String message)
+ public void testFailedFuture(@Nullable String message)
throws InterruptedException {
assertTrue(future.isDone());
assertFalse(future.isCancelled());
diff --git a/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java b/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java
index 99a6be3..a6f8d2e 100644
--- a/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/MoreExecutorsTest.java
@@ -14,26 +14,54 @@
* limitations under the License.
*/
+/*
+ * Portions of this file are modified versions of
+ * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/tck/AbstractExecutorServiceTest.java?revision=1.30
+ * which contained the following notice:
+ *
+ * Written by Doug Lea with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
package com.google.common.util.concurrent;
import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.util.concurrent.MoreExecutors.invokeAnyImpl;
import static com.google.common.util.concurrent.MoreExecutors.listeningDecorator;
import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
import static java.util.concurrent.TimeUnit.SECONDS;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.truth0.Truth.ASSERT;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.testing.ClassSanityTester;
+import com.google.common.util.concurrent.MoreExecutors.Application;
-import junit.framework.TestCase;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@@ -42,7 +70,11 @@ import java.util.concurrent.atomic.AtomicReference;
*
* @author Kyle Littlefield (klittle)
*/
-public class MoreExecutorsTest extends TestCase {
+public class MoreExecutorsTest extends JSR166TestCase {
+
+ private static final Runnable EMPTY_RUNNABLE = new Runnable() {
+ @Override public void run() {}
+ };
public void testSameThreadExecutorServiceInThreadExecution()
throws Exception {
@@ -202,6 +234,21 @@ public class MoreExecutorsTest extends TestCase {
throwableFromOtherThread.get());
}
+ public void testSameThreadExecutor_shutdownNow() {
+ ExecutorService executor = MoreExecutors.sameThreadExecutor();
+ assertEquals(ImmutableList.of(), executor.shutdownNow());
+ assertTrue(executor.isShutdown());
+ }
+
+ public void testExecuteAfterShutdown() {
+ ExecutorService executor = MoreExecutors.sameThreadExecutor();
+ executor.shutdown();
+ try {
+ executor.execute(EMPTY_RUNNABLE);
+ fail();
+ } catch (RejectedExecutionException expected) {}
+ }
+
public void testListeningDecorator() throws Exception {
ListeningExecutorService service =
listeningDecorator(MoreExecutors.sameThreadExecutor());
@@ -222,6 +269,88 @@ public class MoreExecutorsTest extends TestCase {
*/
}
+ /**
+ * invokeAny(null) throws NPE
+ */
+ public void testInvokeAnyImpl_nullTasks() throws Exception {
+ ListeningExecutorService e = sameThreadExecutor();
+ try {
+ invokeAnyImpl(e, null, false, 0);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(empty collection) throws IAE
+ */
+ public void testInvokeAnyImpl_emptyTasks() throws Exception {
+ ListeningExecutorService e = sameThreadExecutor();
+ try {
+ invokeAnyImpl(e, new ArrayList<Callable<String>>(), false, 0);
+ shouldThrow();
+ } catch (IllegalArgumentException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws NPE if c has null elements
+ */
+ public void testInvokeAnyImpl_nullElement() throws Exception {
+ ListeningExecutorService e = sameThreadExecutor();
+ List<Callable<Integer>> l = new ArrayList<Callable<Integer>>();
+ l.add(new Callable<Integer>() {
+ @Override public Integer call() {
+ throw new ArithmeticException("/ by zero");
+ }
+ });
+ l.add(null);
+ try {
+ invokeAnyImpl(e, l, false, 0);
+ shouldThrow();
+ } catch (NullPointerException success) {
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) throws ExecutionException if no task in c completes
+ */
+ public void testInvokeAnyImpl_noTaskCompletes() throws Exception {
+ ListeningExecutorService e = sameThreadExecutor();
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new NPETask());
+ try {
+ invokeAnyImpl(e, l, false, 0);
+ shouldThrow();
+ } catch (ExecutionException success) {
+ assertTrue(success.getCause() instanceof NullPointerException);
+ } finally {
+ joinPool(e);
+ }
+ }
+
+ /**
+ * invokeAny(c) returns result of some task in c if at least one completes
+ */
+ public void testInvokeAnyImpl() throws Exception {
+ ListeningExecutorService e = sameThreadExecutor();
+ try {
+ List<Callable<String>> l = new ArrayList<Callable<String>>();
+ l.add(new StringTask());
+ l.add(new StringTask());
+ String result = invokeAnyImpl(e, l, false, 0);
+ assertSame(TEST_STRING, result);
+ } finally {
+ joinPool(e);
+ }
+ }
+
private static void assertListenerRunImmediately(ListenableFuture<?> future) {
CountingRunnable listener = new CountingRunnable();
future.addListener(listener, sameThreadExecutor());
@@ -236,4 +365,109 @@ public class MoreExecutorsTest extends TestCase {
count++;
}
}
+
+ public void testAddDelayedShutdownHook_success() throws InterruptedException {
+ TestApplication application = new TestApplication();
+ ExecutorService service = mock(ExecutorService.class);
+ application.addDelayedShutdownHook(service, 2, TimeUnit.SECONDS);
+ verify(service, Mockito.never()).shutdown();
+ application.shutdown();
+ InOrder shutdownFirst = Mockito.inOrder(service);
+ shutdownFirst.verify(service).shutdown();
+ shutdownFirst.verify(service).awaitTermination(2, TimeUnit.SECONDS);
+ }
+
+ public void testAddDelayedShutdownHook_interrupted() throws InterruptedException {
+ TestApplication application = new TestApplication();
+ ExecutorService service = mock(ExecutorService.class);
+ application.addDelayedShutdownHook(service, 2, TimeUnit.SECONDS);
+ when(service.awaitTermination(2, TimeUnit.SECONDS)).thenThrow(new InterruptedException());
+ application.shutdown();
+ verify(service).shutdown();
+ }
+
+ public void testGetExitingExcutorService_executorSetToUseDaemonThreads() {
+ TestApplication application = new TestApplication();
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(
+ 1, 2, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1));
+ assertNotNull(application.getExitingExecutorService(executor));
+ assertTrue(executor.getThreadFactory().newThread(EMPTY_RUNNABLE).isDaemon());
+ }
+
+ public void testGetExitingExcutorService_executorDelegatesToOriginal() {
+ TestApplication application = new TestApplication();
+ ThreadPoolExecutor executor = mock(ThreadPoolExecutor.class);
+ ThreadFactory threadFactory = mock(ThreadFactory.class);
+ when(executor.getThreadFactory()).thenReturn(threadFactory);
+ application.getExitingExecutorService(executor).execute(EMPTY_RUNNABLE);
+ verify(executor).execute(EMPTY_RUNNABLE);
+ }
+
+ public void testGetExitingExcutorService_shutdownHookRegistered() throws InterruptedException {
+ TestApplication application = new TestApplication();
+ ThreadPoolExecutor executor = mock(ThreadPoolExecutor.class);
+ ThreadFactory threadFactory = mock(ThreadFactory.class);
+ when(executor.getThreadFactory()).thenReturn(threadFactory);
+ application.getExitingExecutorService(executor);
+ application.shutdown();
+ verify(executor).shutdown();
+ }
+
+ public void testGetExitingScheduledExcutorService_executorSetToUseDaemonThreads() {
+ TestApplication application = new TestApplication();
+ ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
+ assertNotNull(application.getExitingScheduledExecutorService(executor));
+ assertTrue(executor.getThreadFactory().newThread(EMPTY_RUNNABLE).isDaemon());
+ }
+
+ public void testGetExitingScheduledExcutorService_executorDelegatesToOriginal() {
+ TestApplication application = new TestApplication();
+ ScheduledThreadPoolExecutor executor = mock(ScheduledThreadPoolExecutor.class);
+ ThreadFactory threadFactory = mock(ThreadFactory.class);
+ when(executor.getThreadFactory()).thenReturn(threadFactory);
+ application.getExitingScheduledExecutorService(executor).execute(EMPTY_RUNNABLE);
+ verify(executor).execute(EMPTY_RUNNABLE);
+ }
+
+ public void testGetScheduledExitingExcutorService_shutdownHookRegistered()
+ throws InterruptedException {
+ TestApplication application = new TestApplication();
+ ScheduledThreadPoolExecutor executor = mock(ScheduledThreadPoolExecutor.class);
+ ThreadFactory threadFactory = mock(ThreadFactory.class);
+ when(executor.getThreadFactory()).thenReturn(threadFactory);
+ application.getExitingScheduledExecutorService(executor);
+ application.shutdown();
+ verify(executor).shutdown();
+ }
+
+ public void testPlatformThreadFactory_default() {
+ ThreadFactory factory = MoreExecutors.platformThreadFactory();
+ assertNotNull(factory);
+ // Executors#defaultThreadFactory() may return a new instance each time.
+ assertEquals(factory.getClass(), Executors.defaultThreadFactory().getClass());
+ }
+
+ public void testExecutors_nullCheck() throws Exception {
+ new ClassSanityTester()
+ .forAllPublicStaticMethods(MoreExecutors.class)
+ .thatReturn(Executor.class)
+ .testNulls();
+ }
+
+ private static class TestApplication extends Application {
+ private final List<Thread> hooks = Lists.newArrayList();
+
+ @Override synchronized void addShutdownHook(Thread hook) {
+ hooks.add(hook);
+ }
+
+ synchronized void shutdown() throws InterruptedException {
+ for (Thread hook : hooks) {
+ hook.start();
+ }
+ for (Thread hook : hooks) {
+ hook.join();
+ }
+ }
+ }
}
diff --git a/guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java b/guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java
new file mode 100644
index 0000000..d4da81a
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/PackageSanityTests.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import com.google.common.testing.AbstractPackageSanityTests;
+
+/**
+ * Basic sanity tests for the entire package.
+ *
+ * @author Ben Yu
+ */
+
+public class PackageSanityTests extends AbstractPackageSanityTests {}
diff --git a/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java b/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java
new file mode 100644
index 0000000..4768213
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/RateLimiterTest.java
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2012 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import com.google.common.collect.Lists;
+import com.google.common.testing.NullPointerTester;
+import com.google.common.testing.NullPointerTester.Visibility;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for RateLimiter.
+ *
+ * @author Dimitris Andreou
+ */
+public class RateLimiterTest extends TestCase {
+ /**
+ * The ticker gathers events and presents them as strings.
+ * R0.6 means a delay of 0.6 seconds caused by the (R)ateLimiter
+ * U1.0 means the (U)ser caused the ticker to sleep for a second.
+ */
+ private final FakeTicker ticker = new FakeTicker();
+
+ public void testSimple() {
+ RateLimiter limiter = RateLimiter.create(ticker, 5.0);
+ limiter.acquire(); // R0.00, since it's the first request
+ limiter.acquire(); // R0.20
+ limiter.acquire(); // R0.20
+ assertEvents("R0.00", "R0.20", "R0.20");
+ }
+
+ public void testImmediateTryAcquire() {
+ RateLimiter r = RateLimiter.create(1);
+ assertTrue("Unable to acquire initial permit", r.tryAcquire());
+ assertFalse("Capable of acquiring secondary permit", r.tryAcquire());
+ }
+
+ public void testSimpleRateUpdate() {
+ RateLimiter limiter = RateLimiter.create(5.0, 5, TimeUnit.SECONDS);
+ assertEquals(5.0, limiter.getRate());
+ limiter.setRate(10.0);
+ assertEquals(10.0, limiter.getRate());
+
+ try {
+ limiter.setRate(0.0);
+ fail();
+ } catch (IllegalArgumentException ok) {}
+ try {
+ limiter.setRate(-10.0);
+ fail();
+ } catch (IllegalArgumentException ok) {}
+ }
+
+ public void testSimpleWithWait() {
+ RateLimiter limiter = RateLimiter.create(ticker, 5.0);
+ limiter.acquire(); // R0.00
+ ticker.sleepMillis(200); // U0.20, we are ready for the next request...
+ limiter.acquire(); // R0.00, ...which is granted immediately
+ limiter.acquire(); // R0.20
+ assertEvents("R0.00", "U0.20", "R0.00", "R0.20");
+ }
+
+ public void testOneSecondBurst() {
+ RateLimiter limiter = RateLimiter.create(ticker, 5.0);
+ ticker.sleepMillis(1000); // max capacity reached
+ ticker.sleepMillis(1000); // this makes no difference
+ limiter.acquire(1); // R0.00, since it's the first request
+
+ limiter.acquire(1); // R0.00, from capacity
+ limiter.acquire(3); // R0.00, from capacity
+ limiter.acquire(1); // R0.00, concluding a burst of 5 permits
+
+ limiter.acquire(); // R0.20, capacity exhausted
+ assertEvents("U1.00", "U1.00",
+ "R0.00", "R0.00", "R0.00", "R0.00", // first request and burst
+ "R0.20");
+ }
+
+ public void testWarmUp() {
+ RateLimiter limiter = RateLimiter.create(ticker, 2.0, 4000, TimeUnit.MILLISECONDS);
+ for (int i = 0; i < 8; i++) {
+ limiter.acquire(); // #1
+ }
+ ticker.sleepMillis(500); // #2: to repay for the last acquire
+ ticker.sleepMillis(4000); // #3: becomes cold again
+ for (int i = 0; i < 8; i++) {
+ limiter.acquire(); // // #4
+ }
+ ticker.sleepMillis(500); // #5: to repay for the last acquire
+ ticker.sleepMillis(2000); // #6: didn't get cold! It would take another 2 seconds to go cold
+ for (int i = 0; i < 8; i++) {
+ limiter.acquire(); // #7
+ }
+ assertEvents(
+ "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50", // #1
+ "U0.50", // #2
+ "U4.00", // #3
+ "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50", // #4
+ "U0.50", // #5
+ "U2.00", // #6
+ "R0.00, R0.50, R0.50, R0.50, R0.50, R0.50, R0.50, R0.50"); // #7
+ }
+
+ public void testWarmUpAndUpdate() {
+ RateLimiter limiter = RateLimiter.create(ticker, 2.0, 4000, TimeUnit.MILLISECONDS);
+ for (int i = 0; i < 8; i++) {
+ limiter.acquire(); // // #1
+ }
+ ticker.sleepMillis(4500); // #2: back to cold state (warmup period + repay last acquire)
+ for (int i = 0; i < 3; i++) { // only three steps, we're somewhere in the warmup period
+ limiter.acquire(); // #3
+ }
+
+ limiter.setRate(4.0); // double the rate!
+ limiter.acquire(); // #4, we repay the debt of the last acquire (imposed by the old rate)
+ for (int i = 0; i < 4; i++) {
+ limiter.acquire(); // #5
+ }
+ ticker.sleepMillis(4250); // #6, back to cold state (warmup period + repay last acquire)
+ for (int i = 0; i < 11; i++) {
+ limiter.acquire(); // #7, showing off the warmup starting from totally cold
+ }
+
+ // make sure the areas (times) remain the same, while permits are different
+ assertEvents(
+ "R0.00, R1.38, R1.13, R0.88, R0.63, R0.50, R0.50, R0.50", // #1
+ "U4.50", // #2
+ "R0.00, R1.38, R1.13", // #3, after that the rate changes
+ "R0.88", // #4, this is what the throttling would be with the old rate
+ "R0.34, R0.28, R0.25, R0.25", // #5
+ "U4.25", // #6
+ "R0.00, R0.72, R0.66, R0.59, R0.53, R0.47, R0.41", // #7
+ "R0.34, R0.28, R0.25, R0.25"); // #7 (cont.), note, this matches #5
+ }
+
+ public void testBursty() {
+ RateLimiter limiter = RateLimiter.createBursty(ticker, 1.0, 10);
+ ticker.sleepMillis(10000); // reach full capacity
+ limiter.acquire(11); // all these are served in a burst (10 + 1 by borrowing from the future)
+ limiter.acquire(1); // out of capacity, we have to wait
+ limiter.acquire(1); // and wait
+ ticker.sleepMillis(3000); // fill up 3 permits
+ limiter.acquire(5); // we had 3 ready, thus we borrow 2 permits
+ limiter.acquire(1); // this acquire() will also repay for the previous acquire()
+ assertEvents(
+ "U10.00",
+ "R0.00", // 10 permits grabbed
+ "R1.00", "R1.00", // 1 and 1
+ "U3.00", "R0.00", // 5 grabbed
+ "R3.00" // 1 grabbed
+ );
+ }
+
+ public void testBurstyAndUpdate() {
+ RateLimiter rateLimiter = RateLimiter.create(ticker, 1.0);
+ rateLimiter.acquire(1); // no wait
+ rateLimiter.acquire(1); // R1.00, to repay previous
+
+ rateLimiter.setRate(2.0); // update the rate!
+
+ rateLimiter.acquire(1); // R1.00, to repay previous (the previous was under the old rate!)
+ rateLimiter.acquire(2); // R0.50, to repay previous (now the rate takes effect)
+ rateLimiter.acquire(4); // R1.00, to repay previous
+ rateLimiter.acquire(1); // R2.00, to repay previous
+ assertEvents("R0.00", "R1.00", "R1.00", "R0.50", "R1.00", "R2.00");
+ }
+
+ public void testTimeWrapping() {
+ ticker.instant = Long.MAX_VALUE - TimeUnit.SECONDS.toNanos(1); // 1 second before max value
+ RateLimiter limiter = RateLimiter.create(ticker, 1.0);
+ for (int i = 0; i < 4; i++) {
+ limiter.acquire();
+ }
+ // Without protection from overflow, the last wait value would have been huge,
+ // because "now" would have wrapped into a value near MIN_VALUE, and the limiter would think
+ // that the next request should be admitted far into the future
+ assertEvents("R0.00", "R1.00", "R1.00", "R1.00");
+ }
+
+ public void testTryGate() {
+ RateLimiter limiter = RateLimiter.create(ticker, 5.0);
+ assertTrue(limiter.tryAcquire(0, TimeUnit.SECONDS));
+ assertFalse(limiter.tryAcquire(0, TimeUnit.SECONDS));
+ assertFalse(limiter.tryAcquire(0, TimeUnit.SECONDS));
+ ticker.sleepMillis(100);
+ assertFalse(limiter.tryAcquire(0, TimeUnit.SECONDS));
+ }
+
+ public void testSimpleWeights() {
+ RateLimiter rateLimiter = RateLimiter.create(ticker, 1.0);
+ rateLimiter.acquire(1); // no wait
+ rateLimiter.acquire(1); // R1.00, to repay previous
+ rateLimiter.acquire(2); // R1.00, to repay previous
+ rateLimiter.acquire(4); // R2.00, to repay previous
+ rateLimiter.acquire(8); // R4.00, to repay previous
+ rateLimiter.acquire(1); // R8.00, to repay previous
+ assertEvents("R0.00", "R1.00", "R1.00", "R2.00", "R4.00", "R8.00");
+ }
+
+ public void testInfinity_Bursty() {
+ RateLimiter limiter = RateLimiter.create(ticker, Double.POSITIVE_INFINITY);
+ limiter.acquire(Integer.MAX_VALUE / 4);
+ limiter.acquire(Integer.MAX_VALUE / 2);
+ limiter.acquire(Integer.MAX_VALUE);
+ assertEvents("R0.00", "R0.00", "R0.00"); // no wait, infinite rate!
+
+ limiter.setRate(1.0);
+ limiter.acquire();
+ limiter.acquire();
+ limiter.acquire();
+ assertEvents("R0.00", "R1.00", "R1.00"); // we repay the last request (but that had no cost)
+ // and then we go to 1 second per request mode
+
+ limiter.setRate(Double.POSITIVE_INFINITY);
+ limiter.acquire();
+ limiter.acquire();
+ limiter.acquire();
+ assertEvents("R1.00", "R0.00", "R0.00"); // we repay the last request (1sec), then back to +oo
+ }
+
+ public void testInfinity_WarmUp() {
+ RateLimiter limiter = RateLimiter.create(
+ ticker, Double.POSITIVE_INFINITY, 10, TimeUnit.SECONDS);
+ limiter.acquire(Integer.MAX_VALUE / 4);
+ limiter.acquire(Integer.MAX_VALUE / 2);
+ limiter.acquire(Integer.MAX_VALUE);
+ assertEvents("R0.00", "R0.00", "R0.00");
+
+ limiter.setRate(1.0);
+ limiter.acquire();
+ limiter.acquire();
+ limiter.acquire();
+ assertEvents("R0.00", "R1.00", "R1.00");
+
+ limiter.setRate(Double.POSITIVE_INFINITY);
+ limiter.acquire();
+ limiter.acquire();
+ limiter.acquire();
+ assertEvents("R1.00", "R0.00", "R0.00");
+ }
+
+ /**
+ * Make sure that bursts can never go above 1-second-worth-of-work for the current
+ * rate, even when we change the rate.
+ */
+ public void testWeNeverGetABurstMoreThanOneSec() {
+ RateLimiter limiter = RateLimiter.create(ticker, 1.0);
+ int[] rates = { 1000, 1, 10, 1000000, 10, 1};
+ for (int rate : rates) {
+ int oneSecWorthOfWork = rate;
+ ticker.sleepMillis(rate * 1000);
+ limiter.setRate(rate);
+ long burst = measureTotalTimeMillis(limiter, oneSecWorthOfWork, new Random());
+ // we allow one second worth of work to go in a burst (i.e. take less than a second)
+ assertTrue(burst <= 1000);
+ long afterBurst = measureTotalTimeMillis(limiter, oneSecWorthOfWork, new Random());
+ // but work beyond that must take at least one second
+ assertTrue(afterBurst >= 1000);
+ }
+ }
+
+ /**
+ * This neat test shows that no matter what weights we use in our requests, if we push X
+ * amount of permits in a cool state, where X = rate * timeToCoolDown, and we have
+ * specified a timeToWarmUp() period, it will cost as the prescribed amount of time. E.g.,
+ * calling [acquire(5), acquire(1)] takes exactly the same time as
+ * [acquire(2), acquire(3), acquire(1)].
+ */
+ public void testTimeToWarmUpIsHonouredEvenWithWeights() {
+ Random random = new Random();
+ int maxPermits = 10;
+ double[] qpsToTest = { 4.0, 2.0, 1.0, 0.5, 0.1 };
+ for (int trial = 0; trial < 100; trial++) {
+ for (double qps : qpsToTest) {
+ // Since we know that: maxPermits = 0.5 * warmup / stableInterval;
+ // then if maxPermits == 10, we have:
+ // warmupSeconds = 20 / qps
+ long warmupMillis = (long) ((2 * maxPermits / qps) * 1000.0);
+ RateLimiter rateLimiter = RateLimiter.create(
+ ticker, qps, warmupMillis, TimeUnit.MILLISECONDS);
+ assertEquals(warmupMillis, measureTotalTimeMillis(rateLimiter, maxPermits, random));
+ }
+ }
+ }
+
+ public void testNulls() {
+ NullPointerTester tester = new NullPointerTester()
+ .setDefault(RateLimiter.SleepingTicker.class, ticker);
+ tester.testStaticMethods(RateLimiter.class, Visibility.PACKAGE);
+ tester.testInstanceMethods(RateLimiter.create(ticker, 5.0), Visibility.PACKAGE);
+ }
+
+ private long measureTotalTimeMillis(RateLimiter rateLimiter, int permits, Random random) {
+ long startTime = ticker.instant;
+ while (permits > 0) {
+ int nextPermitsToAcquire = Math.max(1, random.nextInt(permits));
+ permits -= nextPermitsToAcquire;
+ rateLimiter.acquire(nextPermitsToAcquire);
+ }
+ rateLimiter.acquire(1); // to repay for any pending debt
+ return TimeUnit.NANOSECONDS.toMillis(ticker.instant - startTime);
+ }
+
+ private void assertEvents(String... events) {
+ assertEquals(Arrays.asList(events).toString(), ticker.readEventsAndClear());
+ }
+
+ private static class FakeTicker extends RateLimiter.SleepingTicker {
+ long instant = 0L;
+ final List<String> events = Lists.newArrayList();
+
+ @Override
+ public long read() {
+ return instant;
+ }
+
+ void sleepMillis(int millis) {
+ sleepMicros("U", TimeUnit.MILLISECONDS.toMicros(millis));
+ }
+
+ void sleepMicros(String caption, long micros) {
+ instant += TimeUnit.MICROSECONDS.toNanos(micros);
+ events.add(caption + String.format("%3.2f", (micros / 1000000.0)));
+ }
+
+ @Override
+ void sleepMicrosUninterruptibly(long micros) {
+ sleepMicros("R", micros);
+ }
+
+ String readEventsAndClear() {
+ try {
+ return events.toString();
+ } finally {
+ events.clear();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return events.toString();
+ }
+ }
+}
diff --git a/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java b/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java
index 1db434a..3651934 100644
--- a/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/SimpleTimeLimiterTest.java
@@ -183,7 +183,7 @@ public class SimpleTimeLimiterTest extends TestCase {
}
@SuppressWarnings("serial")
- public static class SampleException extends Exception { }
+ public static class SampleException extends Exception {}
public static class SampleImpl implements Sample {
boolean finished;
diff --git a/guava-tests/test/com/google/common/util/concurrent/StripedTest.java b/guava-tests/test/com/google/common/util/concurrent/StripedTest.java
new file mode 100644
index 0000000..0a4a655
--- /dev/null
+++ b/guava-tests/test/com/google/common/util/concurrent/StripedTest.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2011 The Guava Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.common.util.concurrent;
+
+import static com.google.common.collect.Iterables.concat;
+
+import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Ordering;
+import com.google.common.collect.Sets;
+import com.google.common.testing.GcFinalization;
+import com.google.common.testing.NullPointerTester;
+
+import junit.framework.TestCase;
+
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * Tests for Striped.
+ *
+ * @author Dimitris Andreou
+ */
+public class StripedTest extends TestCase {
+ private static List<Striped<?>> strongImplementations() {
+ return ImmutableList.of(
+ Striped.readWriteLock(100),
+ Striped.readWriteLock(256),
+ Striped.lock(100),
+ Striped.lock(256),
+ Striped.semaphore(100, 1),
+ Striped.semaphore(256, 1));
+ }
+
+ private static List<Striped<?>> weakImplementations() {
+ return ImmutableList.of(
+ Striped.lazyWeakReadWriteLock(50),
+ Striped.lazyWeakReadWriteLock(64),
+ Striped.lazyWeakLock(50),
+ Striped.lazyWeakLock(64),
+ Striped.lazyWeakSemaphore(50, 1),
+ Striped.lazyWeakSemaphore(64, 1));
+ }
+
+ private static Iterable<Striped<?>> allImplementations() {
+ return concat(strongImplementations(), weakImplementations());
+ }
+
+ public void testNull() throws Exception {
+ for (Striped<?> striped : allImplementations()) {
+ new NullPointerTester().testAllPublicInstanceMethods(striped);
+ }
+ }
+
+ public void testSizes() {
+ // not bothering testing all variations, since we know they share implementations
+ assertTrue(Striped.lock(100).size() >= 100);
+ assertTrue(Striped.lock(256).size() == 256);
+ assertTrue(Striped.lazyWeakLock(100).size() >= 100);
+ assertTrue(Striped.lazyWeakLock(256).size() == 256);
+ }
+
+ public void testWeakImplementations() {
+ for (Striped<?> striped : weakImplementations()) {
+ WeakReference<Object> weakRef = new WeakReference<Object>(striped.get(new Object()));
+ GcFinalization.awaitClear(weakRef);
+ }
+ }
+
+ public void testStrongImplementations() {
+ for (Striped<?> striped : strongImplementations()) {
+ WeakReference<Object> weakRef = new WeakReference<Object>(striped.get(new Object()));
+ WeakReference<Object> garbage = new WeakReference<Object>(new Object());
+ GcFinalization.awaitClear(garbage);
+ assertNotNull(weakRef.get());
+ }
+ }
+
+ public void testMaximalWeakStripedLock() {
+ Striped<Lock> stripedLock = Striped.lazyWeakLock(Integer.MAX_VALUE);
+ for (int i = 0; i < 10000; i++) {
+ stripedLock.get(new Object()).lock();
+ // nothing special (e.g. an exception) happens
+ }
+ }
+
+ public void testBulkGetReturnsSorted() {
+ for (Striped<?> striped : allImplementations()) {
+ Map<Object, Integer> indexByLock = Maps.newHashMap();
+ for (int i = 0; i < striped.size(); i++) {
+ indexByLock.put(striped.getAt(i), i);
+ }
+
+ // ensure that bulkGet returns locks in monotonically increasing order
+ for (int objectsNum = 1; objectsNum <= striped.size() * 2; objectsNum++) {
+ Set<Object> objects = Sets.newHashSetWithExpectedSize(objectsNum);
+ for (int i = 0; i < objectsNum; i++) {
+ objects.add(new Object());
+ }
+
+ Iterable<?> locks = striped.bulkGet(objects);
+ assertTrue(Ordering.natural().onResultOf(Functions.forMap(indexByLock)).isOrdered(locks));
+
+ // check idempotency
+ Iterable<?> locks2 = striped.bulkGet(objects);
+ assertEquals(Lists.newArrayList(locks), Lists.newArrayList(locks2));
+ }
+ }
+ }
+
+ /**
+ * Checks idempotency, and that we observe the promised number of stripes.
+ */
+ public void testBasicInvariants() {
+ for (Striped<?> striped : allImplementations()) {
+ assertBasicInvariants(striped);
+ }
+ }
+
+ private static void assertBasicInvariants(Striped<?> striped) {
+ Set<Object> observed = Sets.newIdentityHashSet(); // for the sake of weakly referenced locks.
+ // this gets the stripes with #getAt(index)
+ for (int i = 0; i < striped.size(); i++) {
+ Object object = striped.getAt(i);
+ assertNotNull(object);
+ assertSame(object, striped.getAt(i)); // idempotent
+ observed.add(object);
+ }
+ assertTrue("All stripes observed", observed.size() == striped.size());
+
+ // this uses #get(key), makes sure an already observed stripe is returned
+ for (int i = 0; i < striped.size() * 100; i++) {
+ assertTrue(observed.contains(striped.get(new Object())));
+ }
+
+ try {
+ striped.getAt(-1);
+ fail();
+ } catch (RuntimeException expected) {}
+
+ try {
+ striped.getAt(striped.size());
+ fail();
+ } catch (RuntimeException expected) {}
+ }
+}
diff --git a/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java b/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java
index ec850d3..d26ba63 100644
--- a/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java
+++ b/guava-tests/test/com/google/common/util/concurrent/ThreadFactoryBuilderTest.java
@@ -16,7 +16,7 @@
package com.google.common.util.concurrent;
-import static org.junit.contrib.truth.Truth.ASSERT;
+import static org.truth0.Truth.ASSERT;
import com.google.common.testing.NullPointerTester;
@@ -93,11 +93,20 @@ public class ThreadFactoryBuilderTest extends TestCase {
assertTrue(thread.getName().matches("^pool-\\d+-thread-" + threadId + "$"));
}
- public void testNameFormat_custom() {
- final String NAME_FORMAT = "super duper thread #%s";
- ThreadFactory factory = builder.setNameFormat(NAME_FORMAT).build();
- for (int i = 0; i < 10; i++) {
- assertEquals(String.format(NAME_FORMAT, i),
+ public void testNameFormatWithPercentS_custom() {
+ String format = "super-duper-thread-%s";
+ ThreadFactory factory = builder.setNameFormat(format).build();
+ for (int i = 0; i < 11; i++) {
+ assertEquals(String.format(format, i),
+ factory.newThread(monitoredRunnable).getName());
+ }
+ }
+
+ public void testNameFormatWithPercentD_custom() {
+ String format = "super-duper-thread-%d";
+ ThreadFactory factory = builder.setNameFormat(format).build();
+ for (int i = 0; i < 11; i++) {
+ assertEquals(String.format(format, i),
factory.newThread(monitoredRunnable).getName());
}
}
@@ -197,7 +206,7 @@ public class ThreadFactoryBuilderTest extends TestCase {
assertTrue(completed);
}
- public void testNulls() throws Exception {
+ public void testNulls() {
NullPointerTester npTester = new NullPointerTester();
npTester.testAllPublicConstructors(ThreadFactoryBuilder.class);
npTester.testAllPublicStaticMethods(ThreadFactoryBuilder.class);