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