1/*
2 * Copyright (C) 2012 The Guava Authors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.common.collect.testing.google;
18
19import static com.google.common.collect.testing.features.CollectionSize.ZERO;
20import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_KEYS;
21import static com.google.common.collect.testing.features.MapFeature.ALLOWS_NULL_VALUES;
22import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_PUT;
23import static com.google.common.collect.testing.features.MapFeature.SUPPORTS_REMOVE;
24import static com.google.common.truth.Truth.assertThat;
25
26import com.google.common.annotations.GwtCompatible;
27import com.google.common.collect.Multimap;
28import com.google.common.collect.testing.Helpers;
29import com.google.common.collect.testing.features.CollectionSize;
30import com.google.common.collect.testing.features.MapFeature;
31
32import java.util.ArrayList;
33import java.util.Arrays;
34import java.util.Collection;
35import java.util.Collections;
36import java.util.List;
37
38/**
39 * Tests for {@link Multimap#replaceValues(Object, Iterable)}.
40 *
41 * @author Louis Wasserman
42 */
43@GwtCompatible
44public class MultimapReplaceValuesTester<K, V>
45    extends AbstractMultimapTester<K, V, Multimap<K, V>> {
46
47  @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
48  public void testReplaceValuesWithNullValue() {
49    int size = multimap().size();
50    K key = sampleKeys().e0;
51    @SuppressWarnings("unchecked")
52    List<V> values = Arrays.asList(sampleValues().e0, null, sampleValues().e3);
53    multimap().replaceValues(key, values);
54    assertGet(key, values);
55  }
56
57  @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE, ALLOWS_NULL_KEYS})
58  public void testReplaceValuesWithNullKey() {
59    int size = multimap().size();
60    K key = null;
61    @SuppressWarnings("unchecked")
62    List<V> values = Arrays.asList(sampleValues().e0, sampleValues().e2, sampleValues().e3);
63    multimap().replaceValues(key, values);
64    assertGet(key, values);
65  }
66
67  @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE})
68  public void testReplaceEmptyValues() {
69    int size = multimap().size();
70    K key = sampleKeys().e3;
71    @SuppressWarnings("unchecked")
72    List<V> values = Arrays.asList(sampleValues().e0, sampleValues().e2, sampleValues().e3);
73    multimap().replaceValues(key, values);
74    assertGet(key, values);
75    assertEquals(size + values.size(), multimap().size());
76  }
77
78  @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE})
79  public void testReplaceValuesWithEmpty() {
80    int size = multimap().size();
81    K key = sampleKeys().e0;
82    List<V> oldValues = new ArrayList<V>(multimap().get(key));
83    @SuppressWarnings("unchecked")
84    List<V> values = Collections.emptyList();
85    assertEquals(oldValues, new ArrayList<V>(multimap().replaceValues(key, values)));
86    assertGet(key);
87    assertEquals(size - oldValues.size(), multimap().size());
88  }
89
90  @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE})
91  public void testReplaceValuesWithDuplicates() {
92    int size = multimap().size();
93    K key = sampleKeys().e0;
94    List<V> oldValues = new ArrayList<V>(multimap().get(key));
95    List<V> values = Arrays.asList(
96        sampleValues().e0,
97        sampleValues().e3,
98        sampleValues().e0);
99    assertEquals(oldValues, new ArrayList<V>(multimap().replaceValues(key, values)));
100    assertEquals(
101        size - oldValues.size() + multimap().get(key).size(),
102        multimap().size());
103    assertTrue(multimap().get(key).containsAll(values));
104  }
105
106  @CollectionSize.Require(absent = ZERO)
107  @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE})
108  public void testReplaceNonEmptyValues() {
109    List<K> keys = Helpers.copyToList(multimap().keySet());
110    @SuppressWarnings("unchecked")
111    List<V> values = Arrays.asList(sampleValues().e0, sampleValues().e2, sampleValues().e3);
112
113    for (K k : keys) {
114      resetContainer();
115
116      int size = multimap().size();
117      Collection<V> oldKeyValues = Helpers.copyToList(multimap().get(k));
118      multimap().replaceValues(k, values);
119      assertGet(k, values);
120      assertEquals(size + values.size() - oldKeyValues.size(), multimap().size());
121    }
122  }
123
124  @MapFeature.Require({SUPPORTS_PUT, SUPPORTS_REMOVE})
125  public void testReplaceValuesPropagatesToGet() {
126    K key = sampleKeys().e0;
127    Collection<V> getCollection = multimap().get(key);
128    @SuppressWarnings("unchecked")
129    List<V> values = Arrays.asList(sampleValues().e0, sampleValues().e2, sampleValues().e3);
130    multimap().replaceValues(key, values);
131    assertThat(getCollection).has().exactly(
132        sampleValues().e0, sampleValues().e2, sampleValues().e3);
133  }
134
135  @MapFeature.Require(absent = SUPPORTS_REMOVE)
136  @CollectionSize.Require(absent = ZERO)
137  public void testReplaceValuesRemoveNotSupported() {
138    List<V> values = Collections.singletonList(sampleValues().e3);
139    try {
140      multimap().replaceValues(sampleKeys().e0, values);
141      fail("Expected UnsupportedOperationException");
142    } catch (UnsupportedOperationException expected) {
143      // success
144    }
145  }
146
147  @MapFeature.Require(absent = SUPPORTS_PUT)
148  public void testReplaceValuesPutNotSupported() {
149    List<V> values = Collections.singletonList(sampleValues().e3);
150    try {
151      multimap().replaceValues(sampleKeys().e0, values);
152      fail("Expected UnsupportedOperationException");
153    } catch (UnsupportedOperationException expected) {
154      // success
155    }
156  }
157}
158