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 */ 016 017package com.google.common.collect.testing.google; 018 019import static com.google.common.collect.testing.Helpers.assertContains; 020import static com.google.common.collect.testing.Helpers.assertEmpty; 021import static com.google.common.collect.testing.Helpers.assertEqualIgnoringOrder; 022import static com.google.common.collect.testing.Helpers.copyToList; 023import static com.google.common.collect.testing.Helpers.mapEntry; 024import static com.google.common.collect.testing.features.CollectionSize.ZERO; 025import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS; 026import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES; 027import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT; 028import static com.google.common.collect.testing.google.ReflectionFreeAssertThrows.assertThrows; 029 030import com.google.common.annotations.GwtCompatible; 031import com.google.common.collect.ImmutableList; 032import com.google.common.collect.Lists; 033import com.google.common.collect.Multimap; 034import com.google.common.collect.testing.features.CollectionSize; 035import com.google.common.collect.testing.features.MapFeature; 036import java.util.Collection; 037import java.util.Iterator; 038import java.util.List; 039import java.util.Map.Entry; 040import org.jspecify.annotations.NullMarked; 041import org.jspecify.annotations.Nullable; 042import org.junit.Ignore; 043 044/** 045 * Tester for {@link Multimap#put}. 046 * 047 * @author Louis Wasserman 048 */ 049@GwtCompatible 050@Ignore("test runners must not instantiate and run this directly, only via suites we build") 051// @Ignore affects the Android test runner, which respects JUnit 4 annotations on JUnit 3 tests. 052@SuppressWarnings("JUnit4ClassUsedInJUnit3") 053@NullMarked 054public class MultimapPutTester<K extends @Nullable Object, V extends @Nullable Object> 055 extends AbstractMultimapTester<K, V, Multimap<K, V>> { 056 @MapFeature.Require(absent = SUPPORTS_PUT) 057 public void testPutUnsupported() { 058 assertThrows(UnsupportedOperationException.class, () -> multimap().put(k3(), v3())); 059 } 060 061 @MapFeature.Require(SUPPORTS_PUT) 062 public void testPutEmpty() { 063 int size = getNumElements(); 064 065 assertGet(k3(), ImmutableList.<V>of()); 066 067 assertTrue(multimap().put(k3(), v3())); 068 069 assertGet(k3(), v3()); 070 assertEquals(size + 1, multimap().size()); 071 } 072 073 @MapFeature.Require(SUPPORTS_PUT) 074 @CollectionSize.Require(absent = ZERO) 075 public void testPutPresent() { 076 int size = getNumElements(); 077 078 assertGet(k0(), v0()); 079 080 assertTrue(multimap().put(k0(), v3())); 081 082 assertGet(k0(), v0(), v3()); 083 assertEquals(size + 1, multimap().size()); 084 } 085 086 @MapFeature.Require(SUPPORTS_PUT) 087 public void testPutTwoElements() { 088 int size = getNumElements(); 089 090 List<V> values = copyToList(multimap().get(k0())); 091 092 assertTrue(multimap().put(k0(), v1())); 093 assertTrue(multimap().put(k0(), v2())); 094 095 values.add(v1()); 096 values.add(v2()); 097 098 assertGet(k0(), values); 099 assertEquals(size + 2, multimap().size()); 100 } 101 102 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_VALUES}) 103 public void testPutNullValue_supported() { 104 int size = getNumElements(); 105 106 multimap().put(k3(), null); 107 108 assertGet(k3(), Lists.newArrayList((V) null)); // ImmutableList.of can't take null. 109 assertEquals(size + 1, multimap().size()); 110 } 111 112 @MapFeature.Require(value = SUPPORTS_PUT, absent = ALLOWS_NULL_VALUES) 113 public void testPutNullValue_unsupported() { 114 assertThrows(NullPointerException.class, () -> multimap().put(k1(), null)); 115 116 expectUnchanged(); 117 } 118 119 @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS}) 120 public void testPutNullKey() { 121 int size = getNumElements(); 122 123 multimap().put(null, v3()); 124 125 assertGet(null, v3()); 126 assertEquals(size + 1, multimap().size()); 127 } 128 129 @MapFeature.Require(SUPPORTS_PUT) 130 public void testPutNotPresentKeyPropagatesToGet() { 131 int size = getNumElements(); 132 Collection<V> collection = multimap().get(k3()); 133 assertEmpty(collection); 134 multimap().put(k3(), v3()); 135 assertContains(collection, v3()); 136 assertEquals(size + 1, multimap().size()); 137 } 138 139 @MapFeature.Require(SUPPORTS_PUT) 140 public void testPutNotPresentKeyPropagatesToEntries() { 141 Collection<Entry<K, V>> entries = multimap().entries(); 142 assertFalse(entries.contains(mapEntry(k3(), v3()))); 143 multimap().put(k3(), v3()); 144 assertContains(entries, mapEntry(k3(), v3())); 145 } 146 147 @CollectionSize.Require(absent = ZERO) 148 @MapFeature.Require(SUPPORTS_PUT) 149 public void testPutPresentKeyPropagatesToEntries() { 150 Collection<Entry<K, V>> entries = multimap().entries(); 151 assertFalse(entries.contains(mapEntry(k0(), v3()))); 152 multimap().put(k0(), v3()); 153 assertContains(entries, mapEntry(k0(), v3())); 154 } 155 156 @MapFeature.Require(SUPPORTS_PUT) 157 @CollectionSize.Require(absent = ZERO) 158 public void testPutPresentKeyPropagatesToGet() { 159 List<K> keys = copyToList(multimap().keySet()); 160 for (K key : keys) { 161 resetContainer(); 162 163 int size = getNumElements(); 164 165 Collection<V> collection = multimap().get(key); 166 Collection<V> expectedCollection = copyToList(collection); 167 168 multimap().put(key, v3()); 169 expectedCollection.add(v3()); 170 assertEqualIgnoringOrder(expectedCollection, collection); 171 assertEquals(size + 1, multimap().size()); 172 } 173 } 174 175 @MapFeature.Require(SUPPORTS_PUT) 176 @CollectionSize.Require(absent = ZERO) 177 public void testPutPresentKeyPropagatesToAsMapGet() { 178 List<K> keys = copyToList(multimap().keySet()); 179 for (K key : keys) { 180 resetContainer(); 181 182 int size = getNumElements(); 183 184 Collection<V> collection = multimap().asMap().get(key); 185 assertNotNull(collection); 186 Collection<V> expectedCollection = copyToList(collection); 187 188 multimap().put(key, v3()); 189 expectedCollection.add(v3()); 190 assertEqualIgnoringOrder(expectedCollection, collection); 191 assertEquals(size + 1, multimap().size()); 192 } 193 } 194 195 @MapFeature.Require(SUPPORTS_PUT) 196 @CollectionSize.Require(absent = ZERO) 197 public void testPutPresentKeyPropagatesToAsMapEntrySet() { 198 List<K> keys = copyToList(multimap().keySet()); 199 for (K key : keys) { 200 resetContainer(); 201 202 int size = getNumElements(); 203 204 Iterator<Entry<K, Collection<V>>> asMapItr = multimap().asMap().entrySet().iterator(); 205 Collection<V> collection = null; 206 while (asMapItr.hasNext()) { 207 Entry<K, Collection<V>> asMapEntry = asMapItr.next(); 208 if (key.equals(asMapEntry.getKey())) { 209 collection = asMapEntry.getValue(); 210 break; 211 } 212 } 213 assertNotNull(collection); 214 Collection<V> expectedCollection = copyToList(collection); 215 216 multimap().put(key, v3()); 217 expectedCollection.add(v3()); 218 assertEqualIgnoringOrder(expectedCollection, collection); 219 assertEquals(size + 1, multimap().size()); 220 } 221 } 222}