001/* 002 * Copyright (C) 2012 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.google.common.collect.testing.google; 017 018import static com.google.common.base.Preconditions.checkState; 019import static com.google.common.collect.testing.Helpers.assertContainsAllOf; 020import static com.google.common.collect.testing.features.CollectionSize.ZERO; 021import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS; 022import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES; 023import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT; 024 025import com.google.common.annotations.GwtCompatible; 026import com.google.common.collect.ImmutableSet; 027import com.google.common.collect.Iterators; 028import com.google.common.collect.Lists; 029import com.google.common.collect.Multimap; 030import com.google.common.collect.testing.features.CollectionSize; 031import com.google.common.collect.testing.features.MapFeature; 032import java.util.Collection; 033import java.util.Collections; 034import java.util.Iterator; 035import org.junit.Ignore; 036 037/** 038 * Tests for {@link Multimap#putAll(Object, Iterable)}. 039 * 040 * @author Louis Wasserman 041 */ 042@GwtCompatible 043@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. 044@SuppressWarnings("JUnit4ClassUsedInJUnit3") 045public class MultimapPutIterableTester<K, V> extends AbstractMultimapTester<K, V, Multimap<K, V>> { 046 @CollectionSize.Require(absent = ZERO) 047 @MapFeature.Require(SUPPORTS_PUT) 048 public void testPutAllNonEmptyIterableOnPresentKey() { 049 assertTrue( 050 multimap() 051 .putAll( 052 k0(), 053 new Iterable<V>() { 054 @Override 055 public Iterator<V> iterator() { 056 return Lists.newArrayList(v3(), v4()).iterator(); 057 } 058 })); 059 assertGet(k0(), v0(), v3(), v4()); 060 } 061 062 @CollectionSize.Require(absent = ZERO) 063 @MapFeature.Require(SUPPORTS_PUT) 064 public void testPutAllNonEmptyCollectionOnPresentKey() { 065 assertTrue(multimap().putAll(k0(), Lists.newArrayList(v3(), v4()))); 066 assertGet(k0(), v0(), v3(), v4()); 067 } 068 069 @MapFeature.Require(SUPPORTS_PUT) 070 public void testPutAllNonEmptyIterableOnAbsentKey() { 071 assertTrue( 072 multimap() 073 .putAll( 074 k3(), 075 new Iterable<V>() { 076 @Override 077 public Iterator<V> iterator() { 078 return Lists.newArrayList(v3(), v4()).iterator(); 079 } 080 })); 081 assertGet(k3(), v3(), v4()); 082 } 083 084 @MapFeature.Require(SUPPORTS_PUT) 085 public void testPutAllNonEmptyCollectionOnAbsentKey() { 086 assertTrue(multimap().putAll(k3(), Lists.newArrayList(v3(), v4()))); 087 assertGet(k3(), v3(), v4()); 088 } 089 090 @CollectionSize.Require(absent = ZERO) 091 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES}) 092 public void testPutAllNullValueOnPresentKey_supported() { 093 assertTrue(multimap().putAll(k0(), Lists.newArrayList(v3(), null))); 094 assertGet(k0(), v0(), v3(), null); 095 } 096 097 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES}) 098 public void testPutAllNullValueOnAbsentKey_supported() { 099 assertTrue(multimap().putAll(k3(), Lists.newArrayList(v3(), null))); 100 assertGet(k3(), v3(), null); 101 } 102 103 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES) 104 public void testPutAllNullValueSingle_unsupported() { 105 multimap().putAll(k1(), Lists.newArrayList((V) null)); 106 expectUnchanged(); 107 } 108 109 // In principle, it would be nice to apply these two tests to keys with existing values, too. 110 111 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES) 112 public void testPutAllNullValueNullLast_unsupported() { 113 int size = getNumElements(); 114 115 try { 116 multimap().putAll(k3(), Lists.newArrayList(v3(), null)); 117 fail(); 118 } catch (NullPointerException expected) { 119 } 120 121 Collection<V> values = multimap().get(k3()); 122 if (values.size() == 0) { 123 expectUnchanged(); 124 // Be extra thorough in case internal state was corrupted by the expected null. 125 assertEquals(Lists.newArrayList(), Lists.newArrayList(values)); 126 assertEquals(size, multimap().size()); 127 } else { 128 assertEquals(Lists.newArrayList(v3()), Lists.newArrayList(values)); 129 assertEquals(size + 1, multimap().size()); 130 } 131 } 132 133 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES) 134 public void testPutAllNullValueNullFirst_unsupported() { 135 int size = getNumElements(); 136 137 try { 138 multimap().putAll(k3(), Lists.newArrayList(null, v3())); 139 fail(); 140 } catch (NullPointerException expected) { 141 } 142 143 /* 144 * In principle, a Multimap implementation could add e3 first before failing on the null. But 145 * that seems unlikely enough to be worth complicating the test over, especially if there's any 146 * chance that a permissive test could mask a bug. 147 */ 148 expectUnchanged(); 149 // Be extra thorough in case internal state was corrupted by the expected null. 150 assertEquals(Lists.newArrayList(), Lists.newArrayList(multimap().get(k3()))); 151 assertEquals(size, multimap().size()); 152 } 153 154 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS}) 155 public void testPutAllOnPresentNullKey() { 156 assertTrue(multimap().putAll(null, Lists.newArrayList(v3(), v4()))); 157 assertGet(null, v3(), v4()); 158 } 159 160 @MapFeature.Require(absent = ALLOWS_NULL_KEYS) 161 public void testPutAllNullForbidden() { 162 try { 163 multimap().putAll(null, Collections.singletonList(v3())); 164 fail("Expected NullPointerException"); 165 } catch (NullPointerException expected) { 166 // success 167 } 168 } 169 170 @MapFeature.Require(SUPPORTS_PUT) 171 public void testPutAllEmptyCollectionOnAbsentKey() { 172 assertFalse(multimap().putAll(k3(), Collections.<V>emptyList())); 173 expectUnchanged(); 174 } 175 176 @MapFeature.Require(SUPPORTS_PUT) 177 public void testPutAllEmptyIterableOnAbsentKey() { 178 Iterable<V> iterable = 179 new Iterable<V>() { 180 @Override 181 public Iterator<V> iterator() { 182 return ImmutableSet.<V>of().iterator(); 183 } 184 }; 185 186 assertFalse(multimap().putAll(k3(), iterable)); 187 expectUnchanged(); 188 } 189 190 @CollectionSize.Require(absent = ZERO) 191 @MapFeature.Require(SUPPORTS_PUT) 192 public void testPutAllEmptyIterableOnPresentKey() { 193 multimap().putAll(k0(), Collections.<V>emptyList()); 194 expectUnchanged(); 195 } 196 197 @MapFeature.Require(SUPPORTS_PUT) 198 public void testPutAllOnlyCallsIteratorOnce() { 199 Iterable<V> iterable = 200 new Iterable<V>() { 201 private boolean calledIteratorAlready = false; 202 203 @Override 204 public Iterator<V> iterator() { 205 checkState(!calledIteratorAlready); 206 calledIteratorAlready = true; 207 return Iterators.forArray(v3()); 208 } 209 }; 210 211 multimap().putAll(k3(), iterable); 212 } 213 214 @MapFeature.Require(SUPPORTS_PUT) 215 public void testPutAllPropagatesToGet() { 216 Collection<V> getCollection = multimap().get(k0()); 217 int getCollectionSize = getCollection.size(); 218 assertTrue(multimap().putAll(k0(), Lists.newArrayList(v3(), v4()))); 219 assertEquals(getCollectionSize + 2, getCollection.size()); 220 assertContainsAllOf(getCollection, v3(), v4()); 221 } 222}