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.SampleElements.Strings.AFTER_LAST;
20import static com.google.common.collect.testing.SampleElements.Strings.AFTER_LAST_2;
21import static com.google.common.collect.testing.SampleElements.Strings.BEFORE_FIRST;
22import static com.google.common.collect.testing.SampleElements.Strings.BEFORE_FIRST_2;
23
24import com.google.common.annotations.GwtCompatible;
25import com.google.common.collect.ImmutableSet;
26import com.google.common.collect.ImmutableSortedSet;
27import com.google.common.collect.Lists;
28import com.google.common.collect.Ordering;
29import com.google.common.collect.Sets;
30import com.google.common.collect.testing.TestCollectionGenerator;
31import com.google.common.collect.testing.TestCollidingSetGenerator;
32import com.google.common.collect.testing.TestSetGenerator;
33import com.google.common.collect.testing.TestStringListGenerator;
34import com.google.common.collect.testing.TestStringSetGenerator;
35import com.google.common.collect.testing.TestStringSortedSetGenerator;
36import com.google.common.collect.testing.TestUnhashableCollectionGenerator;
37import com.google.common.collect.testing.UnhashableObject;
38
39import java.util.Arrays;
40import java.util.Collections;
41import java.util.Comparator;
42import java.util.List;
43import java.util.Set;
44import java.util.SortedSet;
45
46/**
47 * Generators of different types of sets and derived collections from sets.
48 *
49 * @author Kevin Bourrillion
50 * @author Jared Levy
51 * @author Hayward Chan
52 */
53@GwtCompatible
54public class SetGenerators {
55
56  public static class ImmutableSetCopyOfGenerator extends TestStringSetGenerator {
57    @Override protected Set<String> create(String[] elements) {
58      return ImmutableSet.copyOf(elements);
59    }
60  }
61
62  public static class ImmutableSetWithBadHashesGenerator
63      extends TestCollidingSetGenerator
64      // Work around a GWT compiler bug.  Not explicitly listing this will
65      // cause the createArray() method missing in the generated javascript.
66      // TODO: Remove this once the GWT bug is fixed.
67      implements TestCollectionGenerator<Object> {
68    @Override
69    public Set<Object> create(Object... elements) {
70      return ImmutableSet.copyOf(elements);
71    }
72  }
73
74  public static class DegeneratedImmutableSetGenerator
75      extends TestStringSetGenerator {
76    // Make sure we get what we think we're getting, or else this test
77    // is pointless
78    @SuppressWarnings("cast")
79    @Override protected Set<String> create(String[] elements) {
80      return (ImmutableSet<String>)
81          ImmutableSet.of(elements[0], elements[0]);
82    }
83  }
84
85  public static class ImmutableSortedSetCopyOfGenerator
86      extends TestStringSortedSetGenerator {
87    @Override protected SortedSet<String> create(String[] elements) {
88      return ImmutableSortedSet.copyOf(elements);
89    }
90  }
91
92  public static class ImmutableSortedSetHeadsetGenerator
93      extends TestStringSortedSetGenerator {
94    @Override protected SortedSet<String> create(String[] elements) {
95      List<String> list = Lists.newArrayList(elements);
96      list.add("zzz");
97      return ImmutableSortedSet.copyOf(list)
98          .headSet("zzy");
99    }
100  }
101
102  public static class ImmutableSortedSetTailsetGenerator
103      extends TestStringSortedSetGenerator {
104    @Override protected SortedSet<String> create(String[] elements) {
105      List<String> list = Lists.newArrayList(elements);
106      list.add("\0");
107      return ImmutableSortedSet.copyOf(list)
108          .tailSet("\0\0");
109    }
110  }
111
112  public static class ImmutableSortedSetSubsetGenerator
113      extends TestStringSortedSetGenerator {
114    @Override protected SortedSet<String> create(String[] elements) {
115      List<String> list = Lists.newArrayList(elements);
116      list.add("\0");
117      list.add("zzz");
118      return ImmutableSortedSet.copyOf(list)
119          .subSet("\0\0", "zzy");
120    }
121  }
122
123  public static class ImmutableSortedSetExplicitComparator
124      extends TestStringSetGenerator {
125
126    private static final Comparator<String> STRING_REVERSED
127        = Collections.reverseOrder();
128
129    @Override protected SortedSet<String> create(String[] elements) {
130      return ImmutableSortedSet.orderedBy(STRING_REVERSED)
131          .add(elements)
132          .build();
133    }
134
135    @Override public List<String> order(List<String> insertionOrder) {
136      Collections.sort(insertionOrder, Collections.reverseOrder());
137      return insertionOrder;
138    }
139  }
140
141  public static class ImmutableSortedSetExplicitSuperclassComparatorGenerator
142      extends TestStringSetGenerator {
143
144    private static final Comparator<Comparable<?>> COMPARABLE_REVERSED
145        = Collections.reverseOrder();
146
147    @Override protected SortedSet<String> create(String[] elements) {
148      return new ImmutableSortedSet.Builder<String>(COMPARABLE_REVERSED)
149          .add(elements)
150          .build();
151    }
152
153    @Override public List<String> order(List<String> insertionOrder) {
154      Collections.sort(insertionOrder, Collections.reverseOrder());
155      return insertionOrder;
156    }
157  }
158
159  public static class ImmutableSortedSetReversedOrderGenerator
160      extends TestStringSetGenerator {
161
162    @Override protected SortedSet<String> create(String[] elements) {
163      return ImmutableSortedSet.<String>reverseOrder()
164          .addAll(Arrays.asList(elements).iterator())
165          .build();
166    }
167
168    @Override public List<String> order(List<String> insertionOrder) {
169      Collections.sort(insertionOrder, Collections.reverseOrder());
170      return insertionOrder;
171    }
172  }
173
174  public static class ImmutableSortedSetUnhashableGenerator
175      extends TestUnhashableSetGenerator {
176    @Override public Set<UnhashableObject> create(
177        UnhashableObject[] elements) {
178      return ImmutableSortedSet.copyOf(elements);
179    }
180  }
181
182  public static class ImmutableSetAsListGenerator
183      extends TestStringListGenerator {
184    @Override protected List<String> create(String[] elements) {
185      return ImmutableSet.copyOf(elements).asList();
186    }
187  }
188
189  public static class ImmutableSortedSetAsListGenerator
190      extends TestStringListGenerator {
191    @Override protected List<String> create(String[] elements) {
192      Comparator<String> comparator = createExplicitComparator(elements);
193      ImmutableSet<String> set = ImmutableSortedSet.copyOf(
194          comparator, Arrays.asList(elements));
195      return set.asList();
196    }
197  }
198
199  public static class ImmutableSortedSetSubsetAsListGenerator
200      extends TestStringListGenerator {
201    @Override protected List<String> create(String[] elements) {
202      Comparator<String> comparator = createExplicitComparator(elements);
203      ImmutableSortedSet.Builder<String> builder
204          = ImmutableSortedSet.orderedBy(comparator);
205      builder.add(BEFORE_FIRST);
206      builder.add(elements);
207      builder.add(AFTER_LAST);
208      return builder.build().subSet(BEFORE_FIRST_2,
209          AFTER_LAST).asList();
210    }
211  }
212
213  public static class ImmutableSortedSetAsListSubListGenerator
214      extends TestStringListGenerator {
215    @Override protected List<String> create(String[] elements) {
216      Comparator<String> comparator = createExplicitComparator(elements);
217      ImmutableSortedSet.Builder<String> builder
218          = ImmutableSortedSet.orderedBy(comparator);
219      builder.add(BEFORE_FIRST);
220      builder.add(elements);
221      builder.add(AFTER_LAST);
222      return builder.build().asList().subList(1, elements.length + 1);
223    }
224  }
225
226  public static class ImmutableSortedsetSubsetAsListSubListGenerator
227      extends TestStringListGenerator {
228    @Override protected List<String> create(String[] elements) {
229      Comparator<String> comparator = createExplicitComparator(elements);
230      ImmutableSortedSet.Builder<String> builder
231          = ImmutableSortedSet.orderedBy(comparator);
232      builder.add(BEFORE_FIRST);
233      builder.add(BEFORE_FIRST_2);
234      builder.add(elements);
235      builder.add(AFTER_LAST);
236      builder.add(AFTER_LAST_2);
237      return builder.build().subSet(BEFORE_FIRST_2,
238          AFTER_LAST_2)
239              .asList().subList(1, elements.length + 1);
240    }
241  }
242
243  public abstract static class TestUnhashableSetGenerator
244      extends TestUnhashableCollectionGenerator<Set<UnhashableObject>>
245      implements TestSetGenerator<UnhashableObject> {
246  }
247
248  private static Comparator<String> createExplicitComparator(
249      String[] elements) {
250    // Collapse equal elements, which Ordering.explicit() doesn't support, while
251    // maintaining the ordering by first occurrence.
252    Set<String> elementsPlus = Sets.newLinkedHashSet();
253    elementsPlus.add(BEFORE_FIRST);
254    elementsPlus.add(BEFORE_FIRST_2);
255    elementsPlus.addAll(Arrays.asList(elements));
256    elementsPlus.add(AFTER_LAST);
257    elementsPlus.add(AFTER_LAST_2);
258    return Ordering.explicit(Lists.newArrayList(elementsPlus));
259  }
260}
261