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.features.CollectionSize.ZERO;
023import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
024import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
025import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
026
027import com.google.common.annotations.GwtCompatible;
028import com.google.common.collect.ImmutableList;
029import com.google.common.collect.Lists;
030import com.google.common.collect.Multimap;
031import com.google.common.collect.testing.Helpers;
032import com.google.common.collect.testing.features.CollectionSize;
033import com.google.common.collect.testing.features.MapFeature;
034import java.util.Collection;
035import java.util.Iterator;
036import java.util.List;
037import java.util.Map.Entry;
038import org.checkerframework.checker.nullness.qual.Nullable;
039import org.junit.Ignore;
040
041/**
042 * Tester for {@link Multimap#put}.
043 *
044 * @author Louis Wasserman
045 */
046@GwtCompatible
047@Ignore // Affects only Android test runner, which respects JUnit 4 annotations on JUnit 3 tests.
048@SuppressWarnings("JUnit4ClassUsedInJUnit3")
049@ElementTypesAreNonnullByDefault
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    try {
055      multimap().put(k3(), v3());
056      fail("Expected UnsupportedOperationException");
057    } catch (UnsupportedOperationException expected) {
058    }
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 = Helpers.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    try {
115      multimap().put(k1(), null);
116      fail();
117    } catch (NullPointerException expected) {
118    }
119
120    expectUnchanged();
121  }
122
123  @MapFeature.Require({SUPPORTS_PUT, ALLOWS_NULL_KEYS})
124  public void testPutNullKey() {
125    int size = getNumElements();
126
127    multimap().put(null, v3());
128
129    assertGet(null, v3());
130    assertEquals(size + 1, multimap().size());
131  }
132
133  @MapFeature.Require(SUPPORTS_PUT)
134  public void testPutNotPresentKeyPropagatesToGet() {
135    int size = getNumElements();
136    Collection<V> collection = multimap().get(k3());
137    assertEmpty(collection);
138    multimap().put(k3(), v3());
139    assertContains(collection, v3());
140    assertEquals(size + 1, multimap().size());
141  }
142
143  @MapFeature.Require(SUPPORTS_PUT)
144  public void testPutNotPresentKeyPropagatesToEntries() {
145    Collection<Entry<K, V>> entries = multimap().entries();
146    assertFalse(entries.contains(Helpers.mapEntry(k3(), v3())));
147    multimap().put(k3(), v3());
148    assertContains(entries, Helpers.mapEntry(k3(), v3()));
149  }
150
151  @CollectionSize.Require(absent = ZERO)
152  @MapFeature.Require(SUPPORTS_PUT)
153  public void testPutPresentKeyPropagatesToEntries() {
154    Collection<Entry<K, V>> entries = multimap().entries();
155    assertFalse(entries.contains(Helpers.mapEntry(k0(), v3())));
156    multimap().put(k0(), v3());
157    assertContains(entries, Helpers.mapEntry(k0(), v3()));
158  }
159
160  @MapFeature.Require(SUPPORTS_PUT)
161  @CollectionSize.Require(absent = ZERO)
162  public void testPutPresentKeyPropagatesToGet() {
163    List<K> keys = Helpers.copyToList(multimap().keySet());
164    for (K key : keys) {
165      resetContainer();
166
167      int size = getNumElements();
168
169      Collection<V> collection = multimap().get(key);
170      Collection<V> expectedCollection = Helpers.copyToList(collection);
171
172      multimap().put(key, v3());
173      expectedCollection.add(v3());
174      assertEqualIgnoringOrder(expectedCollection, collection);
175      assertEquals(size + 1, multimap().size());
176    }
177  }
178
179  @MapFeature.Require(SUPPORTS_PUT)
180  @CollectionSize.Require(absent = ZERO)
181  public void testPutPresentKeyPropagatesToAsMapGet() {
182    List<K> keys = Helpers.copyToList(multimap().keySet());
183    for (K key : keys) {
184      resetContainer();
185
186      int size = getNumElements();
187
188      Collection<V> collection = multimap().asMap().get(key);
189      assertNotNull(collection);
190      Collection<V> expectedCollection = Helpers.copyToList(collection);
191
192      multimap().put(key, v3());
193      expectedCollection.add(v3());
194      assertEqualIgnoringOrder(expectedCollection, collection);
195      assertEquals(size + 1, multimap().size());
196    }
197  }
198
199  @MapFeature.Require(SUPPORTS_PUT)
200  @CollectionSize.Require(absent = ZERO)
201  public void testPutPresentKeyPropagatesToAsMapEntrySet() {
202    List<K> keys = Helpers.copyToList(multimap().keySet());
203    for (K key : keys) {
204      resetContainer();
205
206      int size = getNumElements();
207
208      Iterator<Entry<K, Collection<V>>> asMapItr = multimap().asMap().entrySet().iterator();
209      Collection<V> collection = null;
210      while (asMapItr.hasNext()) {
211        Entry<K, Collection<V>> asMapEntry = asMapItr.next();
212        if (key.equals(asMapEntry.getKey())) {
213          collection = asMapEntry.getValue();
214          break;
215        }
216      }
217      assertNotNull(collection);
218      Collection<V> expectedCollection = Helpers.copyToList(collection);
219
220      multimap().put(key, v3());
221      expectedCollection.add(v3());
222      assertEqualIgnoringOrder(expectedCollection, collection);
223      assertEquals(size + 1, multimap().size());
224    }
225  }
226}