View Javadoc
1   /*
2    * Copyright (C) 2013 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  
17  package com.google.common.collect.testing.google;
18  
19  import static com.google.common.collect.testing.Helpers.assertEmpty;
20  import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_QUERIES;
21  import static com.google.common.collect.testing.features.CollectionFeature.ALLOWS_NULL_VALUES;
22  import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE;
23  import static com.google.common.collect.testing.features.CollectionSize.SEVERAL;
24  import static com.google.common.collect.testing.features.CollectionSize.ZERO;
25  
26  import com.google.common.annotations.GwtCompatible;
27  import com.google.common.annotations.GwtIncompatible;
28  import com.google.common.collect.testing.Helpers;
29  import com.google.common.collect.testing.WrongType;
30  import com.google.common.collect.testing.features.CollectionFeature;
31  import com.google.common.collect.testing.features.CollectionSize;
32  import java.lang.reflect.Method;
33  import java.util.Arrays;
34  import java.util.Collections;
35  import java.util.List;
36  
37  /**
38   * Tests for {@code Multiset#remove}, {@code Multiset.removeAll}, and {@code Multiset.retainAll}
39   * not already covered by the corresponding Collection testers.
40   *
41   * @author Jared Levy
42   */
43  @GwtCompatible(emulated = true)
44  public class MultisetRemoveTester<E> extends AbstractMultisetTester<E> {
45    @CollectionFeature.Require(SUPPORTS_REMOVE)
46    public void testRemoveNegative() {
47      try {
48        getMultiset().remove(e0(), -1);
49        fail("Expected IllegalArgumentException");
50      } catch (IllegalArgumentException expected) {
51      }
52      expectUnchanged();
53    }
54  
55    @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
56    public void testRemoveUnsupported() {
57      try {
58        getMultiset().remove(e0(), 2);
59        fail("Expected UnsupportedOperationException");
60      } catch (UnsupportedOperationException expected) {
61      }
62    }
63  
64    @CollectionFeature.Require(SUPPORTS_REMOVE)
65    public void testRemoveZeroNoOp() {
66      int originalCount = getMultiset().count(e0());
67      assertEquals("old count", originalCount, getMultiset().remove(e0(), 0));
68      expectUnchanged();
69    }
70  
71    @CollectionSize.Require(absent = ZERO)
72    @CollectionFeature.Require(SUPPORTS_REMOVE)
73    public void testRemove_occurrences_present() {
74      assertEquals(
75          "multiset.remove(present, 2) didn't return the old count",
76          1,
77          getMultiset().remove(e0(), 2));
78      assertFalse(
79          "multiset contains present after multiset.remove(present, 2)",
80          getMultiset().contains(e0()));
81      assertEquals(0, getMultiset().count(e0()));
82    }
83  
84    @CollectionSize.Require(SEVERAL)
85    @CollectionFeature.Require(SUPPORTS_REMOVE)
86    public void testRemove_some_occurrences_present() {
87      initThreeCopies();
88      assertEquals(
89          "multiset.remove(present, 2) didn't return the old count",
90          3,
91          getMultiset().remove(e0(), 2));
92      assertTrue(
93          "multiset contains present after multiset.remove(present, 2)",
94          getMultiset().contains(e0()));
95      assertEquals(1, getMultiset().count(e0()));
96    }
97  
98    @CollectionFeature.Require(SUPPORTS_REMOVE)
99    public void testRemove_occurrences_absent() {
100     int distinct = getMultiset().elementSet().size();
101     assertEquals("multiset.remove(absent, 0) didn't return 0", 0, getMultiset().remove(e3(), 2));
102     assertEquals(distinct, getMultiset().elementSet().size());
103   }
104 
105   @CollectionFeature.Require(absent = SUPPORTS_REMOVE)
106   public void testRemove_occurrences_unsupported_absent() {
107     // notice: we don't care whether it succeeds, or fails with UOE
108     try {
109       assertEquals(
110           "multiset.remove(absent, 2) didn't return 0 or throw an exception",
111           0,
112           getMultiset().remove(e3(), 2));
113     } catch (UnsupportedOperationException ok) {
114     }
115   }
116 
117   @CollectionFeature.Require(SUPPORTS_REMOVE)
118   public void testRemove_occurrences_0() {
119     int oldCount = getMultiset().count(e0());
120     assertEquals(
121         "multiset.remove(E, 0) didn't return the old count",
122         oldCount,
123         getMultiset().remove(e0(), 0));
124   }
125 
126   @CollectionFeature.Require(SUPPORTS_REMOVE)
127   public void testRemove_occurrences_negative() {
128     try {
129       getMultiset().remove(e0(), -1);
130       fail("multiset.remove(E, -1) didn't throw an exception");
131     } catch (IllegalArgumentException required) {
132     }
133   }
134 
135   @CollectionFeature.Require(SUPPORTS_REMOVE)
136   public void testRemove_occurrences_wrongType() {
137     assertEquals(
138         "multiset.remove(wrongType, 1) didn't return 0",
139         0,
140         getMultiset().remove(WrongType.VALUE, 1));
141   }
142 
143   @CollectionSize.Require(absent = ZERO)
144   @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_VALUES})
145   public void testRemove_nullPresent() {
146     initCollectionWithNullElement();
147     assertEquals(1, getMultiset().remove(null, 2));
148     assertFalse(
149         "multiset contains present after multiset.remove(present, 2)",
150         getMultiset().contains(null));
151     assertEquals(0, getMultiset().count(null));
152   }
153 
154   @CollectionFeature.Require({SUPPORTS_REMOVE, ALLOWS_NULL_QUERIES})
155   public void testRemove_nullAbsent() {
156     assertEquals(0, getMultiset().remove(null, 2));
157   }
158 
159   @CollectionFeature.Require(value = SUPPORTS_REMOVE, absent = ALLOWS_NULL_QUERIES)
160   public void testRemove_nullForbidden() {
161     try {
162       getMultiset().remove(null, 2);
163       fail("Expected NullPointerException");
164     } catch (NullPointerException expected) {
165     }
166   }
167 
168   @CollectionSize.Require(SEVERAL)
169   @CollectionFeature.Require(SUPPORTS_REMOVE)
170   public void testRemoveAllIgnoresCount() {
171     initThreeCopies();
172     assertTrue(getMultiset().removeAll(Collections.singleton(e0())));
173     assertEmpty(getMultiset());
174   }
175 
176   @CollectionSize.Require(SEVERAL)
177   @CollectionFeature.Require(SUPPORTS_REMOVE)
178   public void testRetainAllIgnoresCount() {
179     initThreeCopies();
180     List<E> contents = Helpers.copyToList(getMultiset());
181     assertFalse(getMultiset().retainAll(Collections.singleton(e0())));
182     expectContents(contents);
183   }
184 
185   /**
186    * Returns {@link Method} instances for the remove tests that assume multisets
187    * support duplicates so that the test of {@code Multisets.forSet()} can
188    * suppress them.
189    */
190   @GwtIncompatible // reflection
191   public static List<Method> getRemoveDuplicateInitializingMethods() {
192     return Arrays.asList(
193         Helpers.getMethod(MultisetRemoveTester.class, "testRemove_some_occurrences_present"));
194   }
195 }