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