1/* 2 * Copyright (C) 2008 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.CollectionFeature.SUPPORTS_ADD; 20import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_CLEAR; 21import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE; 22import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_REMOVE_ALL; 23import static com.google.common.collect.testing.features.CollectionFeature.SUPPORTS_RETAIN_ALL; 24import static com.google.common.collect.testing.features.CollectionSize.ONE; 25import static com.google.common.collect.testing.features.CollectionSize.ZERO; 26 27import com.google.common.annotations.GwtCompatible; 28import com.google.common.collect.Multiset; 29import com.google.common.collect.Multisets; 30import com.google.common.collect.testing.WrongType; 31import com.google.common.collect.testing.features.CollectionFeature; 32import com.google.common.collect.testing.features.CollectionSize; 33 34import java.lang.reflect.Method; 35import java.util.Collections; 36import java.util.Iterator; 37 38/** 39 * A generic JUnit test which tests multiset-specific write operations. 40 * Can't be invoked directly; please see {@link MultisetTestSuiteBuilder}. 41 * 42 * @author Jared Levy 43 */ 44@GwtCompatible 45public class MultisetWritesTester<E> extends AbstractMultisetTester<E> { 46 /** 47 * Returns the {@link Method} instance for 48 * {@link #testEntrySet_iterator()} so that tests of 49 * classes with unmodifiable iterators can suppress it. 50 */ 51 public static Method getEntrySetIteratorMethod() { 52 return Platform.getMethod( 53 MultisetWritesTester.class, "testEntrySet_iterator"); 54 } 55 56 @CollectionFeature.Require(SUPPORTS_ADD) 57 public void testAddOccurrences() { 58 int oldCount = getMultiset().count(samples.e0); 59 assertEquals("multiset.add(E, int) should return the old count", 60 oldCount, getMultiset().add(samples.e0, 2)); 61 assertEquals("multiset.count() incorrect after add(E, int)", 62 oldCount + 2, getMultiset().count(samples.e0)); 63 } 64 65 @CollectionFeature.Require(absent = SUPPORTS_ADD) 66 public void testAddOccurrences_unsupported() { 67 try { 68 getMultiset().add(samples.e0, 2); 69 fail("unsupported multiset.add(E, int) didn't throw exception"); 70 } catch (UnsupportedOperationException required) {} 71 } 72 73 @CollectionSize.Require(absent = ZERO) 74 @CollectionFeature.Require(SUPPORTS_REMOVE) 75 public void testRemove_occurrences_present() { 76 assertEquals("multiset.remove(present, 2) didn't return the old count", 77 1, getMultiset().remove(samples.e0, 2)); 78 assertFalse("multiset contains present after multiset.remove(present, 2)", 79 getMultiset().contains(samples.e0)); 80 } 81 82 @CollectionFeature.Require(SUPPORTS_REMOVE) 83 public void testRemove_occurrences_absent() { 84 assertEquals("multiset.remove(absent, 0) didn't return 0", 85 0, getMultiset().remove(samples.e3, 2)); 86 } 87 88 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 89 public void testRemove_occurrences_unsupported_absent() { 90 // notice: we don't care whether it succeeds, or fails with UOE 91 try { 92 assertEquals( 93 "multiset.remove(absent, 2) didn't return 0 or throw an exception", 94 0, getMultiset().remove(samples.e3, 2)); 95 } catch (UnsupportedOperationException ok) {} 96 } 97 98 @CollectionFeature.Require(SUPPORTS_REMOVE) 99 public void testRemove_occurrences_0() { 100 int oldCount = getMultiset().count(samples.e0); 101 assertEquals("multiset.remove(E, 0) didn't return the old count", 102 oldCount, getMultiset().remove(samples.e0, 0)); 103 } 104 105 @CollectionFeature.Require(SUPPORTS_REMOVE) 106 public void testRemove_occurrences_negative() { 107 try { 108 getMultiset().remove(samples.e0, -1); 109 fail("multiset.remove(E, -1) didn't throw an exception"); 110 } catch (IllegalArgumentException required) {} 111 } 112 113 @CollectionFeature.Require(SUPPORTS_REMOVE) 114 public void testRemove_occurrences_wrongType() { 115 assertEquals("multiset.remove(wrongType, 1) didn't return 0", 116 0, getMultiset().remove(WrongType.VALUE, 1)); 117 } 118 119 @CollectionFeature.Require(SUPPORTS_CLEAR) 120 public void testEntrySet_clear() { 121 getMultiset().entrySet().clear(); 122 assertTrue("multiset not empty after entrySet().clear()", 123 getMultiset().isEmpty()); 124 } 125 126 @CollectionSize.Require(ONE) 127 @CollectionFeature.Require(SUPPORTS_REMOVE) 128 public void testEntrySet_iterator() { 129 Iterator<Multiset.Entry<E>> iterator = getMultiset().entrySet().iterator(); 130 assertTrue( 131 "non-empty multiset.entrySet() iterator.hasNext() returned false", 132 iterator.hasNext()); 133 assertEquals("multiset.entrySet() iterator.next() returned incorrect entry", 134 Multisets.immutableEntry(samples.e0, 1), iterator.next()); 135 assertFalse( 136 "size 1 multiset.entrySet() iterator.hasNext() returned true " 137 + "after next()", 138 iterator.hasNext()); 139 iterator.remove(); 140 assertTrue( 141 "multiset isn't empty after multiset.entrySet() iterator.remove()", 142 getMultiset().isEmpty()); 143 } 144 145 @CollectionSize.Require(absent = ZERO) 146 @CollectionFeature.Require(absent = SUPPORTS_REMOVE) 147 public void testEntrySet_iterator_remove_unsupported() { 148 Iterator<Multiset.Entry<E>> iterator = getMultiset().entrySet().iterator(); 149 assertTrue( 150 "non-empty multiset.entrySet() iterator.hasNext() returned false", 151 iterator.hasNext()); 152 try { 153 iterator.remove(); 154 fail("multiset.entrySet() iterator.remove() didn't throw an exception"); 155 } catch (UnsupportedOperationException expected) {} 156 } 157 158 @CollectionSize.Require(absent = ZERO) 159 @CollectionFeature.Require(SUPPORTS_REMOVE) 160 public void testEntrySet_remove_present() { 161 assertTrue( 162 "multiset.entrySet.remove(presentEntry) returned false", 163 getMultiset().entrySet().remove( 164 Multisets.immutableEntry(samples.e0, 1))); 165 assertFalse( 166 "multiset contains element after removing its entry", 167 getMultiset().contains(samples.e0)); 168 } 169 170 @CollectionSize.Require(absent = ZERO) 171 @CollectionFeature.Require(SUPPORTS_REMOVE) 172 public void testEntrySet_remove_missing() { 173 assertFalse( 174 "multiset.entrySet.remove(missingEntry) returned true", 175 getMultiset().entrySet().remove( 176 Multisets.immutableEntry(samples.e0, 2))); 177 assertTrue( 178 "multiset didn't contain element after removing a missing entry", 179 getMultiset().contains(samples.e0)); 180 } 181 182 @CollectionSize.Require(absent = ZERO) 183 @CollectionFeature.Require(SUPPORTS_REMOVE_ALL) 184 public void testEntrySet_removeAll_present() { 185 assertTrue( 186 "multiset.entrySet.removeAll(presentEntry) returned false", 187 getMultiset().entrySet().removeAll( 188 Collections.singleton(Multisets.immutableEntry(samples.e0, 1)))); 189 assertFalse( 190 "multiset contains element after removing its entry", 191 getMultiset().contains(samples.e0)); 192 } 193 194 @CollectionSize.Require(absent = ZERO) 195 @CollectionFeature.Require(SUPPORTS_REMOVE_ALL) 196 public void testEntrySet_removeAll_missing() { 197 assertFalse( 198 "multiset.entrySet.remove(missingEntry) returned true", 199 getMultiset().entrySet().removeAll( 200 Collections.singleton(Multisets.immutableEntry(samples.e0, 2)))); 201 assertTrue( 202 "multiset didn't contain element after removing a missing entry", 203 getMultiset().contains(samples.e0)); 204 } 205 206 @CollectionFeature.Require(SUPPORTS_REMOVE_ALL) 207 public void testEntrySet_removeAll_null() { 208 try { 209 getMultiset().entrySet().removeAll(null); 210 fail("multiset.entrySet.removeAll(null) didn't throw an exception"); 211 } catch (NullPointerException expected) {} 212 } 213 214 @CollectionSize.Require(ONE) 215 @CollectionFeature.Require(SUPPORTS_RETAIN_ALL) 216 public void testEntrySet_retainAll_present() { 217 assertFalse( 218 "multiset.entrySet.retainAll(presentEntry) returned false", 219 getMultiset().entrySet().retainAll( 220 Collections.singleton(Multisets.immutableEntry(samples.e0, 1)))); 221 assertTrue( 222 "multiset doesn't contains element after retaining its entry", 223 getMultiset().contains(samples.e0)); 224 } 225 226 @CollectionSize.Require(ONE) 227 @CollectionFeature.Require(SUPPORTS_RETAIN_ALL) 228 public void testEntrySet_retainAll_missing() { 229 assertTrue( 230 "multiset.entrySet.retainAll(missingEntry) returned true", 231 getMultiset().entrySet().retainAll( 232 Collections.singleton(Multisets.immutableEntry(samples.e0, 2)))); 233 assertFalse( 234 "multiset contains element after retaining a different entry", 235 getMultiset().contains(samples.e0)); 236 } 237 238 @CollectionFeature.Require(SUPPORTS_RETAIN_ALL) 239 public void testEntrySet_retainAll_null() { 240 try { 241 getMultiset().entrySet().retainAll(null); 242 // Returning successfully is not ideal, but tolerated. 243 } catch (NullPointerException expected) {} 244 } 245} 246