Home | History | Annotate | Download | only in collect
      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