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 17 package com.google.common.collect; 18 19 import static com.google.common.collect.Lists.newArrayList; 20 import static com.google.common.collect.Lists.newLinkedList; 21 import static com.google.common.collect.testing.testers.CollectionIteratorTester.getIteratorKnownOrderRemoveSupportedMethod; 22 import static java.util.Arrays.asList; 23 import static org.junit.contrib.truth.Truth.ASSERT; 24 25 import com.google.common.annotations.GwtCompatible; 26 import com.google.common.annotations.GwtIncompatible; 27 import com.google.common.base.Function; 28 import com.google.common.base.Predicate; 29 import com.google.common.collect.testing.CollectionTestSuiteBuilder; 30 import com.google.common.collect.testing.TestStringCollectionGenerator; 31 import com.google.common.collect.testing.features.CollectionFeature; 32 import com.google.common.collect.testing.features.CollectionSize; 33 import com.google.common.testing.NullPointerTester; 34 35 import junit.framework.Test; 36 import junit.framework.TestCase; 37 import junit.framework.TestSuite; 38 39 import java.util.Collection; 40 import java.util.Collections; 41 import java.util.List; 42 43 /** 44 * Tests for {@link Collections2}. 45 * 46 * @author Chris Povirk 47 * @author Jared Levy 48 */ 49 @GwtCompatible(emulated = true) 50 public class Collections2Test extends TestCase { 51 @GwtIncompatible("suite") 52 public static Test suite() { 53 TestSuite suite = new TestSuite(Collections2Test.class.getSimpleName()); 54 suite.addTest(testsForFilter()); 55 suite.addTest(testsForFilterAll()); 56 suite.addTest(testsForFilterLinkedList()); 57 suite.addTest(testsForFilterNoNulls()); 58 suite.addTest(testsForFilterFiltered()); 59 suite.addTest(testsForTransform()); 60 suite.addTestSuite(Collections2Test.class); 61 return suite; 62 } 63 64 static final Predicate<String> NOT_YYY_ZZZ = new Predicate<String>() { 65 @Override 66 public boolean apply(String input) { 67 return !"yyy".equals(input) && !"zzz".equals(input); 68 } 69 }; 70 71 static final Predicate<String> LENGTH_1 = new Predicate<String>() { 72 @Override 73 public boolean apply(String input) { 74 return input.length() == 1; 75 } 76 }; 77 78 static final Predicate<String> STARTS_WITH_VOWEL = new Predicate<String>() { 79 @Override 80 public boolean apply(String input) { 81 return asList('a', 'e', 'i', 'o', 'u').contains(input.charAt(0)); 82 } 83 }; 84 85 @GwtIncompatible("suite") 86 private static Test testsForFilter() { 87 return CollectionTestSuiteBuilder.using( 88 new TestStringCollectionGenerator() { 89 @Override public Collection<String> create(String[] elements) { 90 List<String> unfiltered = newArrayList(); 91 unfiltered.add("yyy"); 92 unfiltered.addAll(asList(elements)); 93 unfiltered.add("zzz"); 94 return Collections2.filter(unfiltered, NOT_YYY_ZZZ); 95 } 96 }) 97 .named("Collections2.filter") 98 .withFeatures( 99 CollectionFeature.GENERAL_PURPOSE, 100 CollectionFeature.ALLOWS_NULL_VALUES, 101 CollectionFeature.KNOWN_ORDER, 102 CollectionSize.ANY) 103 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 104 .createTestSuite(); 105 } 106 107 @GwtIncompatible("suite") 108 private static Test testsForFilterAll() { 109 return CollectionTestSuiteBuilder.using( 110 new TestStringCollectionGenerator() { 111 @Override public Collection<String> create(String[] elements) { 112 List<String> unfiltered = newArrayList(); 113 unfiltered.addAll(asList(elements)); 114 return Collections2.filter(unfiltered, NOT_YYY_ZZZ); 115 } 116 }) 117 .named("Collections2.filter") 118 .withFeatures( 119 CollectionFeature.GENERAL_PURPOSE, 120 CollectionFeature.ALLOWS_NULL_VALUES, 121 CollectionFeature.KNOWN_ORDER, 122 CollectionSize.ANY) 123 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 124 .createTestSuite(); 125 } 126 127 @GwtIncompatible("suite") 128 private static Test testsForFilterLinkedList() { 129 return CollectionTestSuiteBuilder.using( 130 new TestStringCollectionGenerator() { 131 @Override public Collection<String> create(String[] elements) { 132 List<String> unfiltered = newLinkedList(); 133 unfiltered.add("yyy"); 134 unfiltered.addAll(asList(elements)); 135 unfiltered.add("zzz"); 136 return Collections2.filter(unfiltered, NOT_YYY_ZZZ); 137 } 138 }) 139 .named("Collections2.filter") 140 .withFeatures( 141 CollectionFeature.GENERAL_PURPOSE, 142 CollectionFeature.ALLOWS_NULL_VALUES, 143 CollectionFeature.KNOWN_ORDER, 144 CollectionSize.ANY) 145 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 146 .createTestSuite(); 147 } 148 149 @GwtIncompatible("suite") 150 private static Test testsForFilterNoNulls() { 151 return CollectionTestSuiteBuilder.using( 152 new TestStringCollectionGenerator() { 153 @Override public Collection<String> create(String[] elements) { 154 List<String> unfiltered = newArrayList(); 155 unfiltered.add("yyy"); 156 unfiltered.addAll(ImmutableList.copyOf(elements)); 157 unfiltered.add("zzz"); 158 return Collections2.filter(unfiltered, LENGTH_1); 159 } 160 }) 161 .named("Collections2.filter, no nulls") 162 .withFeatures( 163 CollectionFeature.GENERAL_PURPOSE, 164 CollectionFeature.ALLOWS_NULL_QUERIES, 165 CollectionFeature.KNOWN_ORDER, 166 CollectionSize.ANY) 167 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 168 .createTestSuite(); 169 } 170 171 @GwtIncompatible("suite") 172 private static Test testsForFilterFiltered() { 173 return CollectionTestSuiteBuilder.using( 174 new TestStringCollectionGenerator() { 175 @Override public Collection<String> create(String[] elements) { 176 List<String> unfiltered = newArrayList(); 177 unfiltered.add("yyy"); 178 unfiltered.addAll(ImmutableList.copyOf(elements)); 179 unfiltered.add("zzz"); 180 unfiltered.add("abc"); 181 return Collections2.filter( 182 Collections2.filter(unfiltered, LENGTH_1), NOT_YYY_ZZZ); 183 } 184 }) 185 .named("Collections2.filter, filtered input") 186 .withFeatures( 187 CollectionFeature.GENERAL_PURPOSE, 188 CollectionFeature.KNOWN_ORDER, 189 CollectionFeature.ALLOWS_NULL_QUERIES, 190 CollectionSize.ANY) 191 .suppressing(getIteratorKnownOrderRemoveSupportedMethod()) 192 .createTestSuite(); 193 } 194 195 public abstract static class FilterChangeTest extends TestCase { 196 protected abstract <E> List<E> newList(); 197 198 public void testFilterIllegalAdd() { 199 List<String> unfiltered = newList(); 200 Collection<String> filtered 201 = Collections2.filter(unfiltered, NOT_YYY_ZZZ); 202 filtered.add("a"); 203 filtered.add("b"); 204 ASSERT.that(filtered).hasContentsInOrder("a", "b"); 205 206 try { 207 filtered.add("yyy"); 208 fail(); 209 } catch (IllegalArgumentException expected) {} 210 211 try { 212 filtered.addAll(asList("c", "zzz", "d")); 213 fail(); 214 } catch (IllegalArgumentException expected) {} 215 216 ASSERT.that(filtered).hasContentsInOrder("a", "b"); 217 } 218 219 public void testFilterChangeUnfiltered() { 220 List<String> unfiltered = newList(); 221 Collection<String> filtered 222 = Collections2.filter(unfiltered, NOT_YYY_ZZZ); 223 224 unfiltered.add("a"); 225 unfiltered.add("yyy"); 226 unfiltered.add("b"); 227 ASSERT.that(unfiltered).hasContentsInOrder("a", "yyy", "b"); 228 ASSERT.that(filtered).hasContentsInOrder("a", "b"); 229 230 unfiltered.remove("a"); 231 ASSERT.that(unfiltered).hasContentsInOrder("yyy", "b"); 232 ASSERT.that(filtered).hasContentsInOrder("b"); 233 234 unfiltered.clear(); 235 ASSERT.that(unfiltered).isEmpty(); 236 ASSERT.that(filtered).isEmpty(); 237 238 unfiltered.add("yyy"); 239 ASSERT.that(unfiltered).hasContentsInOrder("yyy"); 240 ASSERT.that(filtered).isEmpty(); 241 filtered.clear(); 242 ASSERT.that(unfiltered).hasContentsInOrder("yyy"); 243 ASSERT.that(filtered).isEmpty(); 244 245 unfiltered.clear(); 246 filtered.clear(); 247 ASSERT.that(unfiltered).isEmpty(); 248 ASSERT.that(filtered).isEmpty(); 249 250 unfiltered.add("a"); 251 ASSERT.that(unfiltered).hasContentsInOrder("a"); 252 ASSERT.that(filtered).hasContentsInOrder("a"); 253 filtered.clear(); 254 ASSERT.that(unfiltered).isEmpty(); 255 ASSERT.that(filtered).isEmpty(); 256 257 unfiltered.clear(); 258 Collections.addAll(unfiltered, 259 "a", "b", "yyy", "zzz", "c", "d", "yyy", "zzz"); 260 ASSERT.that(unfiltered).hasContentsInOrder( 261 "a", "b", "yyy", "zzz", "c", "d", "yyy", "zzz"); 262 ASSERT.that(filtered).hasContentsInOrder("a", "b", "c", "d"); 263 filtered.clear(); 264 ASSERT.that(unfiltered).hasContentsInOrder("yyy", "zzz", "yyy", "zzz"); 265 ASSERT.that(filtered).isEmpty(); 266 } 267 268 public void testFilterChangeFiltered() { 269 List<String> unfiltered = newList(); 270 Collection<String> filtered 271 = Collections2.filter(unfiltered, NOT_YYY_ZZZ); 272 273 unfiltered.add("a"); 274 unfiltered.add("yyy"); 275 filtered.add("b"); 276 ASSERT.that(unfiltered).hasContentsInOrder("a", "yyy", "b"); 277 ASSERT.that(filtered).hasContentsInOrder("a", "b"); 278 279 filtered.remove("a"); 280 ASSERT.that(unfiltered).hasContentsInOrder("yyy", "b"); 281 ASSERT.that(filtered).hasContentsInOrder("b"); 282 283 filtered.clear(); 284 ASSERT.that(unfiltered).hasContentsInOrder("yyy"); 285 ASSERT.that(filtered); 286 } 287 288 public void testFilterFiltered() { 289 List<String> unfiltered = newList(); 290 Collection<String> filtered = Collections2.filter( 291 Collections2.filter(unfiltered, LENGTH_1), STARTS_WITH_VOWEL); 292 unfiltered.add("a"); 293 unfiltered.add("b"); 294 unfiltered.add("apple"); 295 unfiltered.add("banana"); 296 unfiltered.add("e"); 297 ASSERT.that(filtered).hasContentsInOrder("a", "e"); 298 ASSERT.that(unfiltered).hasContentsInOrder("a", "b", "apple", "banana", "e"); 299 300 try { 301 filtered.add("d"); 302 fail(); 303 } catch (IllegalArgumentException expected) {} 304 try { 305 filtered.add("egg"); 306 fail(); 307 } catch (IllegalArgumentException expected) {} 308 ASSERT.that(filtered).hasContentsInOrder("a", "e"); 309 ASSERT.that(unfiltered).hasContentsInOrder("a", "b", "apple", "banana", "e"); 310 311 filtered.clear(); 312 ASSERT.that(filtered).isEmpty(); 313 ASSERT.that(unfiltered).hasContentsInOrder("b", "apple", "banana"); 314 } 315 } 316 317 public static class ArrayListFilterChangeTest extends FilterChangeTest { 318 @Override protected <E> List<E> newList() { 319 return Lists.newArrayList(); 320 } 321 } 322 323 public static class LinkedListFilterChangeTest extends FilterChangeTest { 324 @Override protected <E> List<E> newList() { 325 return Lists.newLinkedList(); 326 } 327 } 328 329 private static final Function<String, String> REMOVE_FIRST_CHAR 330 = new Function<String, String>() { 331 @Override 332 public String apply(String from) { 333 return ((from == null) || "".equals(from)) 334 ? null : from.substring(1); 335 } 336 }; 337 338 @GwtIncompatible("suite") 339 private static Test testsForTransform() { 340 return CollectionTestSuiteBuilder.using( 341 new TestStringCollectionGenerator() { 342 @Override public Collection<String> create(String[] elements) { 343 List<String> list = newArrayList(); 344 for (String element : elements) { 345 list.add((element == null) ? null : "q" + element); 346 } 347 return Collections2.transform(list, REMOVE_FIRST_CHAR); 348 } 349 }) 350 .named("Collections2.transform") 351 .withFeatures( 352 CollectionFeature.REMOVE_OPERATIONS, 353 CollectionFeature.ALLOWS_NULL_VALUES, 354 CollectionFeature.KNOWN_ORDER, 355 CollectionSize.ANY) 356 .createTestSuite(); 357 } 358 359 @GwtIncompatible("NullPointerTester") 360 public void testNullPointerExceptions() throws Exception { 361 NullPointerTester tester = new NullPointerTester(); 362 tester.testAllPublicStaticMethods(Collections2.class); 363 } 364 } 365